Recently, @yorgunkirmizi reached out to discuss how textures, shaders, texture coordinates, and all that type of stuff works in IFC. We've made some serious progress deciphering what is and isn't possible, and so I thought I'd open this thread so that others can also get involved or at least keep tabs on the progress.
As far as we can tell, textures is one of the more famous but unsupported aspects of IFC. The FZKViewer has some preliminary texture support, as in, for one of the types of textures, Jakob Beetz has managed to get it to show up on a primitive object. The BlenderBIM Add-on supports external references, which is a bit of a cheat to get arbitrarily complex textures, materials, and lighting, since it defers the texture definition outside IFC. So we want to do better and support it properly, which also includes providing test cases for the rest of the industry so they can catch up too.
For contrast, let's start with a how a representation is styled with a surface colour:
IfcShapeRepresentation --> IfcFacetedBrep <-- IfcStyledItem --> IfcSurfaceStyle --> IfcSurfaceStyleShading
The IfcSurfaceStyleShading
includes basic viewport colours, diffuse component, specular component, and some transmission data. Think of it as your principled shader with some flashbacks to still allow "phong" to be chosen as a shader type.
For textures, instead of using an IfcSurfaceStyleShading
, we use IfcSurfaceStyleWithTextures
instead. This then lets us stack a series of IfcSurfaceTexture
textures. Think of this stack as the various nodes that combine to create your colour mixes, diffuse maps, specular maps, bump maps, and so on.
IfcShapeRepresentation --> IfcFacetedBrep <-- IfcStyledItem --> IfcSurfaceStyle --> IfcSurfaceStyleWithTextures -> IfcSurfaceTexture (L[1:?])
There are three types of IfcSurfaceTexture
: Blobs, Images, and Pixels. These are three different ways to reference your raw image data. Either an embedded blob, a URI pointing to an image, or an array of pixel RGBs. Regardless of which imaging reference you choose, all IfcSurfaceTexture
s share the same ability to combine in the stack with various effects and reference texture coordinates.
In theory, there seems to be enough flexibility with the parameters to record any texture system, like Cycles or Eevee nodes, or establishing your own convention. However, IFC's texturing capabilities were derived from ISO/IES 19775-1.2:2008 X3D Architecture and base components Edition 2, Part 1. So the default is to support how shaders work in X3D. In short: to understand textures in IFC, you first need to understand how shaders work in X3D.
There are some documents you want to read first:
-
Read all the IFC docs on the classes mentioned above. Especially IfcSurfaceTexture. You won't fully understand yet how IfcSurfaceTexture works though until you read the rest of the documents in this list.
-
https://www.web3d.org/documents/specifications/19775-1/V3.2/ the X3D spec, see clause 18, Texturing Component, then read that entire section, with a focus on the MultiTexture node.
-
https://castle-engine.io/x3d_multi_texturing.php after you think you understand how the MultiTexture node works, verify your knowledge of it by reading this page. It's a goldmine of knowledge.
-
https://github.com/castle-engine/demo-models/tree/master/multi_texturing - this repository contains sample X3D code of test cases for each of the different shading combinations
-
https://castle-engine.io/view3dscene.php - this demo viewer in theory lets you recreate the demo files. The results I got were different from the benchmark screenshot, so I've reached out for help from the author.
-
https://github.com/blender/blender-addons/tree/blender-v2.79b-release/io_scene_x3d thanks to @Gorgious for discovering this gem, Blender already has an X3D importer / exporter. However, from what I can tell, they do not support MultiTexture, which is the key bit of the puzzle to understand how textures work in IFC. However, it does cover code for pixel textures and UV maps that we can probably reuse.
@yorgunkirmizi and I have been working through this exercise:
-
Understanding the X3D specification and test cases
-
Recreating the test cases in Blender, to understand how this seemingly dated standard is reflected in more modern rendering engines. We will create node trees for each of the base cases, describing what is and isn't possible.
-
Converting these test cases to IFC test cases, showing how you can recreate both the X3D definitions and the Blender material node trees in IFC.
-
Identifying where the existing IFC textures fall short, and whether or not any existing solutions in the X3D world may help.
-
Creating typical basic material setups that a designer might use, such as a basic diffuse map, all the maps from a PBR workflow, and showing how these are represented in IFC.
-
Clearly documenting where it falls short. Obvious scenarios that come to mind are procedural textures, blackbody colour temperatures, RGB curves, and SSS. Some of these can be supported fairly easily by simply describing new conventions (e.g. just add SSSMAP and done!) to bring it up to more recent standards. For others, we might fall back to external definitions, or define a render engine specific convention.
7 . Write code! Make it happen! Textures! Yeah!
We've just finishing up on step 2, and made a start on step 3.