-
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_anisotropy #11988
Conversation
Thank you for the pull request, @jjhembd! ✅ We can confirm we have a CLA on file for you. |
Image comparisonsAll images captured from the glTF PBR Anisotropy Sandcastle "Barn lamp" test datasetWith extension enabled. Notice the stretching of the specular reflection perpendicular to the brush marks in the metal. Anisotropy strength testAnisotropy disc testThe discs in each square are not visible without the extension. |
@@ -721,6 +723,19 @@ describe( | |||
verifyRender(model, true); | |||
}); | |||
|
|||
it("renders model with the KHR_materials_anisotropy extension", async function () { |
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.
I'm getting the following error when running this test:
RuntimeError: Fragment shader failed to compile. Compile log: ERROR: 0:467: 'normalTexCoords' : undeclared identifier
ERROR: 0:467: 'computeTangent' : no matching overloaded function found
ERROR: 0:467: '=' : dimension mismatch
ERROR: 0:467: '=' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'
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.
This was an error in my test dataset. For this extension, either tangents or a normal map are required.
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.
Got it. Can we catch this early and provide a better error message?
Thanks @jjhembd! I left a few comments, but overall this looks close. |
Thanks for the feedback @ggetz! I think I addressed everything. |
@jjhembd All TODO's have been completed and this is ready to merge, correct? |
@ggetz Yes, the only comment I haven't addressed is your question about whether we can catch a problem with a glTF that is not according to spec. I looked at this, but it is non-trivial. We often ask users to run problematic models through the glTF-Validator. Would that be appropriate for this case, or do we want CesiumJS to identify model problems? |
OK to skip this if it blows up the scope of this PR. Better error messages for models that do not conform to spec is something we've mentioned before, but I understand there's a trade off in terms of effort and performance. |
Merge #11970 first!
Description
This PR implements the glTF extension KHR_materials_anisotropy 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 newloadAnisotropy
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.anisotropy
is defined, its properties are processed by the new methodprocessAnisotropyUniforms
, which is very similar toprocessSpecularUniforms
. The sine and cosine of theanisotropyRotation
factor are pre-computed, and combined withanisotropyStrength
into onevec3
uniform.The anisotropy 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
The orientation of the anisotropic effect is defined relative to the "tangent" vector on the surface. The tangent vector is aligned in the direction of increasing
u
coordinate in the normal map. These tangent vectors are either supplied as a vertex attribute, or computed via derivatives of the normal map texture coordinates.We already had code using and/or computing tangent vectors, but discarded the information early once the normals were prepared. To preserve the tangent information for anisotropic calculations, a new
NormalInfo
struct is defined, and returned from the newgetNormalInfo
function. Along the way, some of the tangent calculations were broken down into smaller functions to enable re-use for both the isotropic and anisotropic cases. ThesetAnisotropy
function then stores the relevant anisotropic information on the material. See also the corresponding changes to theczm_modelMaterial
andczm_pbrParameters
structs.The actual anisotropic lighting calculations can be found in
pbrLighting
andImageBasedLightingStageFS
. They only modify the specular reflection component of the final color.Note that the implementation in
ImageBasedLightingStageFS
is complete only for the case of supplied environment maps intextureIBL
. TheproceduralIBL
function will require a more significant rewrite as part of a wider IBL update, so the anisotropy calculation can be incorporated at that stage.Other changes
GeometryPipelineStage
(done while tracing back normal calculations)MaterialPipelineStage
ImageBasedLightingStageFS
. See Normalization error in image-based lighting #11994Issue number and link
Resolves #11976. Resolves #11994.
Testing plan
Load the development Sandcastle glTF PBR Anisotropy and toggle through the 4 testing models, comparing to the rendering in the reference implementation.
Author checklist
CONTRIBUTORS.md
CHANGES.md
with a short summary of my changeOther TODO: