-
-
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
BufferAttribute: Support (de)normalization in accessors. #22874
Conversation
Another place where denormalization is currently required is the new morph target implementation. three.js/src/renderers/webgl/WebGLMorphtargets.js Lines 18 to 30 in 3f1dce3
Buffer attribute data might be normalized so it's necessary to denormalized the data for the morph texture. I'm glad this issue is discussed since putting normalization/denormalization all over the code base is not ideal. I think |
We should establish this as a policy and clean up all places in the code base that access the |
I prefer (3), as well, so dealing with reading and writing bufferAttribute data is consistently handled -- that's what I would have advocated for.
BufferGeometryUtils mergeVertices probably doesn't work correctly at the moment with normalized attributes. And I would think this would make merging multiple geometries easier, as well, when they don't share a common My only question is what, if any, performance implication does this have when using the getters and setters? With and without the normalized field set? |
Will try to benchmark that – assuming the difference in a tight loop is small, and |
Option 3 is how I was thinking of solving this problem when I first noticed it and I think it's the most elegant and straight forward. I've only done a cursory look at the PR but at a glance it looks right. I would think the docs should be updated, as well, to communicate that the values passed into these functions get / set the non-quantized values as you'd use in a shader rather than the values that are necessarily directly stored in the buffer. |
This looks great to me. Any chance we can get it updated and merged? It will also fix |
I regret that this is +200 LOC in the main build, and also a breaking change if someone is already handling normalized attributes correctly. I guess the 2nd part is probably OK since this is a common gotcha. Any ideas to trim down the size though? We could omit the |
@Mugen87 Since we decided to go with this approach, should we go ahead and merge this? |
@elalish Merging the PR is fine. I just want to defer the merge to @mrdoob since he should make the final design decision. I'm not sure how he thinks about #24087. @donmccurdy It would be great if you could include
The |
Clean up WebGLMorphtargets.js BufferAttribute: Add normalization support for u32, i32, and UintClampedArray
af2d7e4
to
c6a80f9
Compare
I think this is ready for review. I'm still happy to refactor it other ways, but note the prior discussion in #24087. |
I think we should merge this in the next release. Users are complaining about three-mesh-bvh not supporting normalized positions when it's really an issue with three.js (see gkjohnson/three-mesh-bvh#448) I feel the approach in this PR is clean and can be improved in the future if needed. This issue is becoming more and more noticeable with common compression tools like gltf-transform now producing normalized data for values that are typically not, like positions. Thanks for addressing this @donmccurdy 😁 |
Thanks! |
Added to the migration guide: https://github.com/mrdoob/three.js/wiki/Migration-Guide#143--144 |
FYI @hybridherbst — with this change you should have better luck using meshopt compression and raycasting in r144. |
Ooh, thanks for pinging me! That's great :) |
Indeed; I'm waiting with bated breath to pull in the new version once it's out. |
Hello @donmccurdy, since |
Most uses of getX, getY, and getZ will not need to change. GLTFExporter does not yet support |
* BufferAttribute: Support (de)normalization in accessors. Clean up WebGLMorphtargets.js BufferAttribute: Add normalization support for u32, i32, and UintClampedArray * Revert changes to MathUtils * Clean up Color.js
* BufferAttribute: Support (de)normalization in accessors. Clean up WebGLMorphtargets.js BufferAttribute: Add normalization support for u32, i32, and UintClampedArray * Revert changes to MathUtils * Clean up Color.js
* BufferAttribute: Support (de)normalization in accessors. Clean up WebGLMorphtargets.js BufferAttribute: Add normalization support for u32, i32, and UintClampedArray * Revert changes to MathUtils * Clean up Color.js
* BufferAttribute: Support (de)normalization in accessors. Clean up WebGLMorphtargets.js BufferAttribute: Add normalization support for u32, i32, and UintClampedArray * Revert changes to MathUtils * Clean up Color.js
Related:
Currently normalized attributes do not work correctly with raycasting, and perhaps other logic. There are a few possible way to fix that, narrowly or broadly:
Mesh.raycast
VectorX.fromBufferAttribute
vector.fromBufferAttribute
is not consistent withattribute.getX
BufferAttribute
getters/settersattribute.array
directly. Avoiding direct access toattribute.array
is already necessary for code that intends to support interleaved attributes, so a similar rule for normalized attributes seems reasonable.As shown in this PR, (3) does require some more code than the alternatives. Do we have a preference among these?
Sample model, with normalized and interleaved position attribute:
DH.glb.zip
/cc @gkjohnson