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

Incorrect Tangent/Bitangent export #936

Open
RowanGryder opened this issue Feb 22, 2021 · 12 comments · Fixed by #938
Open

Incorrect Tangent/Bitangent export #936

RowanGryder opened this issue Feb 22, 2021 · 12 comments · Fixed by #938
Assignees
Milestone

Comments

@RowanGryder
Copy link

Hello,

I've been experiencing an issue for some time now where using the Export Tangents option on the 3Ds Max exporter gives good Tangents but artifact heavy Bitangents. In the past I've just left this option unchecked and used smoothing groups and slight model tweaks as a workaround to at least give a adequate result. Unfortunately I've finally found an example where none of these previous workarounds fixe the smoothing issues present.

Using the debug textures it can be seen when exporting without tangents the tangents and bitangents appear faceted/flat shaded. Exporting with tangents gives a nice smooth result for the tangent result but an artifact filled bitangent result which ruins the smoothing in random places.
Example:
https://user-images.githubusercontent.com/23561431/108782674-035e5980-753a-11eb-8032-e5f62161a791.png

Closeup:
https://user-images.githubusercontent.com/23561431/108782636-f0e42000-7539-11eb-83a8-327f52c01078.png

I also did some testing with exporting with tangents from blender and found it gave perfect tangent and bitangent.

@pandaGaume
Copy link
Contributor

pandaGaume commented Feb 23, 2021

Hi Guy's,
Thanks to let us know about this case.
Could you share a very simple scene which highlight this behavior?

However i'm a bit confuse about your explanation with bitangent while there is no bitangent information into Babylon file and/or GLTF 2.0.
According to the GLTF 2.0 specification (and similar as open-gl ref)

Implementation note: When normals and tangents are specified, client implementations should compute the bitangent by taking the cross product of the normal and tangent xyz vectors and multiplying against the w component of the tangent: bitangent = cross(normal, tangent.xyz) * tangent.w.

In any case, i believe the problem is arround this line, which may compute an incorrect W for the tangent ( maybe an issue about floating point rounding).
But again, i need a test case.
Pointing the line you may also try to fix it yourself and make a PR.
You may try to change the getW function to something like this

        private int GetW(IPoint3 normal, IPoint3 tangent, IPoint3 bitangent)
        {
            if (Math.Abs(bitangent.X) <= Tools.Epsilon && Math.Abs(bitangent.Y) <= Tools.Epsilon && Math.Abs(bitangent.Z) <= Tools.Epsilon)
            {
                // default value for w is 1
                return 1;
            }

            //Cross product bitangent = w * normal ^ tangent
            float x = normal.Y * tangent.Z - normal.Z * tangent.Y;
            float y = normal.Z * tangent.X - normal.X * tangent.Z;
            float z = normal.X * tangent.Y - normal.Y * tangent.X;

            // Speaking in broadest terms, if the dot product of two non-zero vectors is positive, 
            // then the two vectors point in the same general direction, meaning less than 90 degrees. 
            // If the dot product is negative, then the two vectors point in opposite directions, 
            // or above 90 and less than or equal to 180 degrees.
            var dot = bitangent.X * x + bitangent.Y * y + bitangent.Z * z;
            return dot < 0 ? -1 : 1;
        }

G.

@pandaGaume pandaGaume added 3dsmax need repro We need a repro to be able to fix labels Feb 23, 2021
@RowanGryder
Copy link
Author

Hey,

Your speculation about it stemming from setting the tangent W makes sense; however I haven't had much success with my continued testing.
Here's a zip with the max, fbx, glb, and normal map of the model I've been testing with.
TangentErrorTestFiles.zip

@pandaGaume
Copy link
Contributor

pandaGaume commented Feb 26, 2021

this is what i get when force W = 1;

image

And with the new W calculation

image

Any thoughts ??

Let me know if this one is better..

test.zip

@RowanGryder
Copy link
Author

When comparing my previous results it looks like forcing W=1 is closer but still showing some areas of faceting. The new W calculation looks near-identical to exporting without tangents; lots of faceting within single smoothing groups.

Here's my close up comparison of your W=1 image with the blender export.
TestingComparison_001

Here's the .blend and glb export from blender.
TangentExportErrorTest_BlenderFiles.zip

@pandaGaume
Copy link
Contributor

pandaGaume commented Mar 2, 2021

Hey,
Seem two case here.
The artifat issue showed in your picture , which has been solved with the new W calculation and with the right bittangent direction according to your blender export (check the color which mean the direction of the vector).

The other point is the faceting which come to another reason related to the vertices optimisation.
You can decide to optimize vertices for a given mesh by setting a Babylon property
image
Once done, the mesh DO NOT duplicate the vertices (which lead to faceting). This is what blender exporter do.
Result :
image

I will doing a PR for the first point, the second point is a missinformation about the behavior of the exporter. We may update the documentation accordingly.

Here the result
test.zip

@pandaGaume pandaGaume self-assigned this Mar 3, 2021
@pandaGaume pandaGaume removed the need repro We need a repro to be able to fix label Mar 3, 2021
@thomlucc thomlucc added this to the 5.0 milestone Mar 4, 2021
@RowanGryder
Copy link
Author

RowanGryder commented Mar 9, 2021

Hey again,

Thank you for the work fixing this; the [Try to optimize vertices] is a good callout. I had a chance to experiment with the change and unfortunately still seems the calculation of W is still causing artifacts which a few small ones can be seen in the screenshot you shared:
TangentBitangentErrors_New_001

As well as some new areas:
TangentBitangentErrors_New_002

Here are the max and glb files from my testing;
TangentExportErrorTest_New.zip

Thanks again, super appreciate the help!

@pandaGaume
Copy link
Contributor

pandaGaume commented Mar 9, 2021

Haha, well spotted.. I'll have a look on it this week. I guess it's happen when tangent are not set or with a length of nearly zero... we maybe better build the W using UV instead of the tangent/normal/bitangent comparaison.

    Point3 mapNormal = CrossProduct(uv[1] - uv[0], uv[2] - uv[1]);
    w = mapNormal.z < 0 ? -1 : 1;

However, as your Blender export reference (first picture is blender export showing tangent) is showing also an artifat for the tangent and then bi-tangent (a way smaller) I need to be sure about the input data and also that the viewer is correctly rendering the tangent.
image
As you can see (second picture is Babylon Export showing tangent), it's implies vertices with inverted tangent at the edge.
image
Could you verify the tangent inputs ?
I will investigate on my side.

@pandaGaume pandaGaume reopened this Mar 9, 2021
@pandaGaume
Copy link
Contributor

regarding the second exemple, i have better result with the new W method based on UV instead of already calculated bi-tangent.
However because i do not know how you setting up the tangent, i can not decide if this correct or not using your model.
image
Here the generated glb
test.zip
please advice.

@RowanGryder
Copy link
Author

Hey,
If I'm understanding correctly the tangents/bitangents are being set off the vertex normals and UVs (Please let me know if there's something I'm misunderstanding). For the normals, I set smoothing groups (based off UV seams with a few additional manual splits) so nothing particularly unique there. This leads me to believe that it has something to do with the UV unwrap. The areas with the most significant artifacts have definitely been on areas where the UV islands have been straightened/rectangularly flattened.

Looking at your latest test it seems there are a lot of areas where things seem inverted. The chamfers look flipped as do the different sides of the screw heads. I'll attach the glb export from blender since it is a good reference of exactly what it looks like in every other editor.
NewTestComparison_PBR

Comparing the tangents and bitangents that blender outputs it looks like there is a basis flip happening? Most obvious part is on the cylinder bitangent where there's a clear edge with teal and pink color. This kind of edge should only show up on UV seams but there isn't one there.
NewTestComparison_Tan
NewTestComparison_Bitan

Here's the glb from blender
BlenderExportGLB.zip

@thomlucc thomlucc added the bug label May 20, 2021
@pandaGaume
Copy link
Contributor

@RowanGryder hope you're well.
I will get back on this topic, so could you help me in providing a very simple scene (very few vertices, then i can edit manually the numerical values) which reproduce this behavior.
Thanks.
G.

@pandaGaume
Copy link
Contributor

@RowanGryder any news? i will close the issue if not. Regards.

@RowanGryder
Copy link
Author

@pandaGaume Sorry for the delay.
I've been doing more experiments and have found resetting Xform just prior to export seems to give consistent working results (yeah I'm kicking myself). I haven't yet directly compared to a blender export yet however so I'm not sure if it's exactly the same, though not sure if it actually matters? One thing this has me wondering though is if there is a way to keep meshes that need to maintain local orientations intact. This is the primary reason for why I didn't try rest Xform in the first place; I needed to maintain local orientations for animations.

So this all has me wondering if, assuming my speculation is correct and that it is caused by non-zeroed transforms, is it possible to do this automatically on export while maintaining local orientations in the max file?

Kind regards,

@thomlucc thomlucc modified the milestones: 6.0, Future Sep 22, 2022
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.

3 participants