-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement glTF extension KHR_materials_clearcoat #12006
Conversation
@jjhembd The |
Fix over in #12007 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jjhembd! I tested this out and it is looking good when compared to the reference implementation. I have a few comments.
As a quick follow-up to this PR, I would suggestion moving the developer examples for these PBR extensions into a single streamlined showcase example.
*/ | ||
float computeDirectSpecularStrength(vec3 normal, vec3 lightDirection, vec3 viewDirection, vec3 halfwayDirection, float roughness) | ||
{ | ||
float NdotL = clamp(dot(normal, lightDirection), 0.001, 1.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you're preventing a divide by 0 error within the above function with this clamp, right?
Can we move that logic to the respective function so its more obvious what's happening?
Thanks @jjhembd! Thanks for explaining and writing up the additional issue. When running locally, I'm seeing quite a few failing tests due to the error |
@ggetz sorry I missed that! I fixed both this and another shader compile error. All tests now run through locally for me. |
All good! Thanks @jjhembd. This all looks good to me. |
Description
This PR implements the glTF extension KHR_materials_clearcoat in physically-based rendering of models.
How it works (and how it affects the code)
Parsing the extension at load time
When the glTF is loaded,
GltfLoader
reads factors and loads textures from the extension. See the newloadClearcoat
method, which is very similar to theloadSpecular
method from #11970. The factors and textures are then attached to the material. See the updates to theMaterial
class inModelComponents
.Processing the extension properties in the pipeline
In
MaterialPipelineStage
, ifmaterial.clearcoat
is defined, its properties are processed by the new methodprocessClearcoatUniforms
, which is very similar toprocessSpecularUniforms
.The clearcoat extension, if used, will extend the metallic roughness model. As a result, the check for the extension usually takes place inside the same code branch that handles metallic-roughness processing.
Using the extension in the shader
In
MaterialStageFS
, the clearcoat "factor" and roughness are retrieved from uniforms and/or textures. See the newsetClearcoat
function. The clearcoat surface normal defaults to the geometry normal, ignoring the normal map from the underlying surface. This makes the clearcoat smooth by default. If a user provides a normal map for the clearcoat itself, this is loaded in the new methodgetClearcoatNormalFromTexture
. See also the changes to theczm_modelMaterial
struct.The clearcoat is rendered as a layer on top of the base layer. The clearcoat layer modifies the reflection from the base layer below due to transmission losses. It also adds its own specular reflection. See the rewritten
computePbrLighting
function inLightingStageFS
, as well as the newaddClearcoatReflection
function in the same file.Since the reflection from the clearcoat layer itself is specular only, the functions for direct and image-based lighting (in
pbrLighting.glsl
andImageBasedLightingStageFS.glsl
had to be significantly refactored to separate the diffuse and specular components. This refactoring makes for a messy code diff, but the end result is unchanged for materials without a clearcoat.Other changes
v
becomesviewDirection
,l
becomeslightDirection
, etc).czm_maximumComponent
to find the largest component of a vector (this is used several times in PBR calculations).czm_pbrParameters
, since all information was simply copied from theczm_modelMaterial
. Relevant functions now input the material directly. Constructor methodsczm_defaultPbrMaterial
,czm_pbrMetallicRoughnessMaterial
andczm_pbrSpecularGlossinessMaterial
were also removed.yUpToZUp
for IBL texture lookups is now applied on the CPU, rather than constructing and applying it in the fragment shader.MaterialPipelineStageSpec
to use async/await.Issue number and link
Resolves #11995. Resolves #12008.
Testing plan
Load the development Sandcastle glTF PBR Clearcoat and toggle through the testing models, comparing to the rendering in the reference implementation.
Author checklist
CONTRIBUTORS.md
CHANGES.md
with a short summary of my change