Skip to content
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

Support vertex tangents #15692

Closed
donmccurdy opened this issue Feb 1, 2019 · 13 comments · Fixed by #15749
Closed

Support vertex tangents #15692

donmccurdy opened this issue Feb 1, 2019 · 13 comments · Fixed by #15749

Comments

@donmccurdy
Copy link
Collaborator

via @ondys


A simple cube mode with normal map that simulates flat shading:
normal_map_flat-20190201T224012Z-001.zip

The cube has smooth geometry normals (no normal seams on cube edges) + a normal map that simulates flat shading.

threejs flat babylonjs flat
three_js babylon_js

Babylon.js rendering seems to work correctly but three.js produces a weird looking result (cesium viewer also seem to work correctly)

For comparison, if normal map is set to a constant value (128, 128, 255), the resulting geometry is smooth for both three.js and babylon.js:

threejs smooth babylonjs smooth
three_js_smooth babylon_js_smooth

Cube with constant normal map is here:
normal_map_smooth-20190201T224029Z-001.zip

@Mugen87 Mugen87 added the Bug label Feb 4, 2019
@donmccurdy
Copy link
Collaborator Author

Testing with MeshNormalMaterial, the vertex normals look right, but the normalMap difference persists:

vertex normals only with normalMap
screen shot 2019-02-04 at 9 41 40 am screen shot 2019-02-04 at 9 40 33 am

@WestLangley
Copy link
Collaborator

Please see if you can get the OP to provide an example with a plane only.

@ondys
Copy link
Contributor

ondys commented Feb 4, 2019

OP here.
Could the issue be that the GLTF contains custom tangents that are being ignored? I looked at the normal mapping code here and it looks like three.js is computing the tangents in the shader .. but maybe I'm looking at a wrong shader.

@donmccurdy
Copy link
Collaborator Author

threejs does compute tangents in the shader, ignoring custom tangents in the model, yes. I'm not sure how to isolate whether that is the cause... omitting the tangents, will babylonjs still render correctly?

@ondys
Copy link
Contributor

ondys commented Feb 4, 2019

When I delete the tangent attribute, it introduces some color variance on the cube faces but the result still looks much "flatter" compared to three.js (see image below). Looking at the three.js code, it doesn't look like the algorithm for generating tangents corresponds to the Mikktspace algorithm prescribed by GLTF spec (in case tangents are not present). Specifically, in Three.js, tangents seem to be completely independent on vertex normals which would explain the results from above. If that's the case, the best solution would be to add support for tangent attribute to Three.js otherwise it would be rather challenging to use GLTF normal mapping.

image

@WestLangley
Copy link
Collaborator

Could the issue be that the GLTF contains custom tangents that are being ignored?

Yes. three.js ignores attribute tangents.

@WestLangley
Copy link
Collaborator

Related: #15428

@ondys
Copy link
Contributor

ondys commented Feb 4, 2019

Yeah, seems to be the same issues (tangents nor propagated to Three.js from GLTF and Three.js not using tangents attached to the geometry). It would be nice if this could get fixed to make three.js GLTF compliant.

@donmccurdy
Copy link
Collaborator Author

I have a branch (dev...donmccurdy:feat-attribute-tangents-v2) that appears to be working. The DamagedHelmet example (it had similar issues in the past, which we solved differently) looks fine as well. But it will take some time to test this change more thoroughly, and at the moment I don't have much bandwidth, so it could be a while before I can get to a PR.

without normal map with normal map
screen shot 2019-02-07 at 11 56 26 am screen shot 2019-02-07 at 11 56 51 am

@donmccurdy donmccurdy changed the title Normal map rendering incorrectly Support vertex tangents Feb 7, 2019
@WestLangley
Copy link
Collaborator

Vertex tangents are 4-component, no? It appears you are treating them as 3-component.

@mrdoob mrdoob added this to the rXX milestone Feb 7, 2019
@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Feb 7, 2019

@WestLangley see the table under the glTF • Meshes section – the w component is a sign value (+1/-1) that can be ignored except in calculation of the binormal, to my understanding. The vertex attribute is a vec4, but vTBN only (directly) depends on the .xyz components.

@WestLangley
Copy link
Collaborator

The vertex attribute is a vec4, but vTBN only (directly) depends on the .xyz components.

I would say the matrix depends on .xyzw, but I see you are, in fact, using the 4th component to set the correct bi-tangent vector, which was my concern.

Since your vTBN matrix will be interpolated in the fragment shader, and will no longer be orthonormal, it may be preferable to pass varyings vec3 vNormal, vec3 vTangent, and vec3 vBitangent, instead, and construct the orthonormal TBN matrix in the fragment shader.

However it is typically done is fine...

And thanks for this! :-)

@ondys
Copy link
Contributor

ondys commented Feb 15, 2019

Thanks Don and everyone else for adding this feature so quickly!

@mrdoob mrdoob removed this from the rXX milestone Apr 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants