During the last few months, I was working with the Web3D Consortium to bring many material and lighting upgrades to the next version of X3D and of course to our Castle Game Engine.
I’m proud to officially announce the first results of this work, including implementation of many new rendering features in Castle Game Engine!
The initial documentation is summarized on this page – “X3D version 4: New features of materials, lights and textures”. With time, more documentation will appear in CGE, and of course X3D v4 specification will also eventually be available as a definite reference of this. The examples are in my x3d-tests repository, in pbr/ subdirectory.
New features:
-
Physically-based rendering (PBR) using the new
PhysicalMaterial
node.
-
Ability to render glTF models with physical materials. Test it by opening any glTF 2.0 sample model with any engine tool. You can e.g. try view3dscene from snapshots.
-
Much enhanced classic (Phong) lighting model thanks to the enhanced
Material
node with lots of new fields for textures (emissiveTexture
, normalTexture
, specularShininessTexture
, ambientTexture
),
-
More natural “unlit” rendering using the new UnlitMaterial
node (very useful for 2D games, and better than previous approach of “Material with only emissiveColor non-zero”, see Why is UnlitMaterial useful for the detailed reasoning),
-
Image-based lighting using EnvironmentLight
node. This is in-progress now (not yet working).
All of this is implemented in CGE. We get latest X3D features in this area, while also becoming a reference implementation of these X3D concepts.
Backward compatibility
This change also pushed many fixes to the existing lighting shaders, to be pretty and 100% correct (in regards to both X3D 3 and X3D 4). This means:
-
SeparateDiffuseTexture is now always “on”. This means that X3D Appearance.texture
multiplies only diffuse factor (in Phong shading). So the emissiveColor
or specularColor
are not affected by the Appearance.texture
.
This was always (in all X3D versions, past and future) required.
Note that Gouraud shading continues to work as before, because in Gouraud shading there’s technically no other choice: Appearance.texture
must multiply everything (the whole result of lighting calculation).
-
Using Material with only emissiveColor non-zero behaves now 100% correctly, following X3D equations.
Previous it was not only an “optimized case of Material”, it also changed the behavior: Appearance.texture
was multiplied with emissiveColor
(as opposed to multiplying it by diffuseColor). Even when SeparateDiffuseTexture was true, even when Phong shading was used.
It’s no longer the case.
Bottom line:
-
Appearance.texture
now always multiplies diffuse factor of the Material, if possible (IOW in Phong shading). Only in Gouraud shading it behaves differently (as then it has to multiply everything).
-
Use UnlitMaterial
instead of Material
to have unlit shapes. In case of UnlitMaterial
, Appearance.texture
always multiplies the emissiveColor. Other things (Color nodes) also behave more naturally for unlit case.
So it’s simple now:
- When using
Material
(Phong lighting model) -> Appearance.texture
multiplies diffuseColor
- When using
UnlitMaterial
-> Appearance.texture
multiplies emissiveColor
- When using
PhysicalMaterial
-> Appearance.texture
multiplies baseColor
Color
and ColorRGBA
nodes are also correct now. They replace the diffuseColor
in case of Material
— always. Previously, in case of only emissiveColor non-zero they were multiplied and by emissive factor, which was contradicting 2 points of spec. Now they replace the diffuse factor, always (whether “only emissiveColor is non-zero” or not).