-
-
Notifications
You must be signed in to change notification settings - Fork 35.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
WebGPURenderer: Use world space normal approach #29312
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
|
||
const transformedNormal = modelNormalMatrix.mul( normal ); | ||
|
||
return cameraViewMatrix.transformDirection( transformedNormal ); |
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.
What is the reason you are using transformDirection()
here?
That method is designed to be applied to vectors such as the tangent or bi-tangent, not the normal. We use the normalMatrix
when transforming normal vectors.
Using transformDirection()
will be correct only if the camera has uniform scale (the typical use case), but what is the point of doing it this way?
What is it about this approach that is making the code faster?
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.
mesh.normalMatrix
is a view space matrix, this should be called normalViewMatrix
as I updated in TSL.
modelNormalMatrix.mul( normal )
will convert the normals to world space, and transformDirection()
to view space. I could use mul().normalize()
instead of transformDirection()
but I don't see much advantage in that.
What is it about this approach that is making the code faster?
This doesn't use CPU-computed viewMatrices, so we don't need to update GPU buffers every frame since the global matrix doesn't always change.
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.
modelNormalMatrix
is not the same as mesh.normalMatrix
.
I used matrix3.getNormalMatrix( object.matrixWorld )
instead of matrix3.getNormalMatrix( object.modelViewMatrix )
, this is a normal world space matrix.
mesh.normalMatrix
is a view space matrix and should be have the suffix NormalViewMatrix
in TSL context, it is not used in this code, you can access it using highPrecisionModelNormalViewMatrix
, with the approach mentioned in #29299 (comment) updated.
I believe the following explanation would be the same as the one mentioned above.
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.
The view matrix is assumed to be orthogonal and have uniform scale. Plus, we normalize the result after applying the matrix transform.
Consequently, normal vectors can be transformed with the same matrix as direction vectors.
Thus, it is OK to use transformDirection()
, instead of the normal matrix, to transform the normal from world space to view space.
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.
tldr; This looks OK to me.
Related issue: #29299 (comment)
Description
@WestLangley the approach here rendered as expected in your example and E2E testing, and maintains the performance related in the previous PR.