[x3d-public] PBR > freewrl experience
GPU Group
gpugroup at gmail.com
Thu Mar 19 08:02:19 PDT 2020
My experience implementing some of the PBR v4 features in freewrl:
- took 16 days
- I started by defining the PhysicalMaterial, UnlitMaterial and extending
the Material node fields, using Michalis's documetation.
https://github.com/michaliskambi/x3d-tests/wiki/X3D-version-4:-New-features-of-materials,-lights-and-textures#new-x3dmaterialnode-node-with-emissive-and-normalmap-textures
- and internally extended structs in program and shader to hold all the new
fields
- then most of the 2 weeks was getting the information flowing to the
shader without breaking current functionality,
-- appearance.backMaterial - I spent a few days harmonizing
TwoMaterialShader and this new approach
-- for the texture maps I found there ware lots of issues with old code
assuming certain scenarios, and I spent about a week refactoring messy old
code
- I found the khronos glTF sample had some interesting hints beyond
physical, for example they use getter() functions in frag code that
hides/abstracts the issue of whether or not there's a texture map.
https://github.com/KhronosGroup/glTF-Sample-Viewer/tree/master/src/shaders
- see the metallic-roughness.frag
normal = getNormal();
And I refactored the frag shader to use getters like they do.
- I spent a few extra hours reading up on normal maps (which I learned are
in 'tangent space' so need a transform matrix called TBN applied):
https://learnopengl.com/Advanced-Lighting/Normal-Mapping
- normal map normals are expressed in tangent space
Once I had getters, and had all the info flowing to the frag shader, then
it only took a few days to do the metalic-roughness functionality.
If you have a loop where you are applying the lights, you probably have
something like:
diffuse += ...
specular +=
ambient +=
inside the loop.
For metalic-roughness, I found I could replace those 3 with
shade = getPointShade(pointToLight, materialInfo, normal, view);
from the khronos example to make a PBR equivalent light loop.
So in hindsight, it would have been easy to start with the scalar
PhyscialMaterial fields, and I could have added the texturemaps to the
getters() later.
For those implementing for GLES < 3.0 where texture units are in short
supply, the scalar part of PhysicalMaterial should be no problem.
I still have some minor tinkiering to do -when to apply gamma or its
inverse, Michalis has given some answers. And field naming,
textureTransform/textureCoordinate 'channel' field conventions, and I
haven't attempted EnvironmentLight.
Results:
1) PBR physics based rendering via PhysicalMaterial node
- the lighting equations use roughness and metallic with baseColor
- (instead of specular, shininess and diffuseColor)
- and constrain to physics principle of 'conservation of energy'
http://dug9.users.sourceforge.net/web3d/tests/PBR/screenshot_pbr_teapots_view3dscene_freewrl.jpg
http://dug9.users.sourceforge.net/web3d/tests/PBR/metallic_roughness.x3dv
2) extended Material node - supports texture maps for normals, emissive,
diffuse, specularShininess, ambient
http://dug9.users.sourceforge.net/web3d/tests/PBR/screenshot_e_mat_sphere240_view3dscene_freewrl.jpg
http://dug9.users.sourceforge.net/web3d/tests/PBR/sphere_240_fw.x3dv
The PhysicalMaterial node also supports texturemap for metallicRoughness
although I haven't tested.
3) UnlitMaterial - roughed in plumbing but haven't tested thoroughly -
should work and support normal and emissive texture maps
freewrl code samples:
https://sourceforge.net/p/freewrl/git/ci/develop/tree/freex3d/src/lib/opengl/Compositing_Shaders.c
L.1106 MaterialInfo and gamma functions from Khronos glTF example
L.1155 getNormal() and getter() farm starts
L.1300-1340 getting ready for apply_lights_physical
L.1806 apply_lights_physical code with khronos glTF sample functions,
followed by freewrl light loop calling shade = pointShade(...) L.1917
https://sourceforge.net/p/freewrl/git/ci/develop/tree/freex3d/src/lib/scenegraph/Component_Shape.c
L.1417 compile_PhysicalMaterial - organizes into internal structs and flags
for sending to shader
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20200319/6b5a9a66/attachment.html>
More information about the x3d-public
mailing list