-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Use MODELVIEW_MATRIX
when on double precision
#75462
Use MODELVIEW_MATRIX
when on double precision
#75462
Conversation
…abled This commit updates the double precision vertex transform code from using the MODEL_MATRIX to now use the MODELVIEW_MATRIX instead. This can be made possible by transforming the MODELVIEW_MATRIX back into model space (ie, same space as the MODEL_MATRIX) and then using it as if it were the MODEL_MATRIX. With this in place we now properly handle VERTEX transformations that a Material Shader might do, such as billboard-ing.
Maybe could be tested with the scene from this post too, which also contains decals, animated meshes, multimeshes and triplanar mapped materials #58516 (no time to do this test right now) |
I have a feeling that this is essentially forcing single precision. Does it still work fine when you are several thousands of units away from the world origin? |
It does. On the first demo (https://user-images.githubusercontent.com/37230465/228559865-947ef102-f430-45b4-b437-7b3ebc8b16a4.mp4) you can see at 0:15 that I move 10_000_000_000_000 units away from the origin on the X axis and everything continues to work as expected. |
4.0 stable (single precision) 4.1.dev (double precision, with this fix) 4.1.dev (double precision, without this fix) TLDR (or rather TLDW lol): Single precision has a very noticeable flicker when far from the origin (as expected), which isn´t the case with neither of the double precision versions (with and without this fix). |
Managed to get World Triplanar Mapping working with emulated doubles! I mentioned on Rocket.Chat an approach to fix that using some GDScript to compute a "clamped-uv-texture-sized world position", which does work, but requires some user effort to implement. After giving it some more thought, I managed to get it working by essentially using a origin shifted VERTEX when computing the UV World Position. That way we still have our UVs sampled in World space, but with the full range of precision that a float between 0 and 1 has. scene shader: As you can see, I introduced a new builtin called "VERTEX_POSITION_WORLD", which is used when computing the UV Triplanar Position. As for the results themselves: With the fix:Screenshot: Video Demo: Without the fix:Video Demo: Would love to hear some feedback! |
I think it's fine, but smaller and separate commits tend to be reviewed faster in my experience. |
Glad to know that, I'll open another PR then. |
World triplanar was expectedly broken in this case, but it's nice you found a way to make it work. I wonder if it's possible to use the same fix when doing triplanar with custom shader code (although I use triplanar with an extra transform since things are moving, I don't use world directly). |
It should be possible, given that the Material Shader itself is using the 'VERTEX_POSITION_WORLD" to compute the UV pos. |
I dont have a ready-made minimal project where I use this. Here is an occurrence of it: https://github.com/Zylann/solar_system_demo/blob/bdbaf5edc622e0cd2cae2cb6fed078d29eb9abe6/solar_system/materials/planet_ground.gdshader#L105 |
Wow! |
Created the PR for the World Triplanar Mapping stuff: #75577 Also @Zylann I think I managed to solve your use case pretty well! Basically, the hint sets the TRIPLANAR_MATRIX value, which in turn is used to compute the TRIPLANAR_POSITION, using the emulated doubles if double precision is enabled. |
Thanks for this. I've tested it locally and it works great. |
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.
After some careful thought and testing this seems fine.
I am hesitant because it adds a couple extra matrix multiplies (if the modelview
matrix is never used it gets compiled out, same with the read_model_matrix
). However, this is a nice solution to the problem that requires no changes on the user's end. Users will understand that enabling double precision comes with a cost.
Initially I was concerned about losing precision, but this doesn't actually have a big impact on precision for two reasons:
- The origin of the
model_matrix
is thrown away even though it is used in the billboarding calculation, the original origin is still used - The positions from particles are single precision anyway
One possibility for improvement would be to add a usage_define MODELVIEW_MATRIX_USED
and then only use this hack when the modelview matrix is referenced in a user shader. This would save some performance when not billboarding.
Thanks! And congrats for your first merged Godot contribution 🎉 |
Cherry-picked for 4.0.3. |
MODELVIEW_MATRIX
when on double precision
Description
This commit updates the double precision vertex transform code to use the MODELVIEW_MATRIX instead of the MODEL_MATRIX.
This is done by transforming the MODELVIEW_MATRIX back into model space and then using it as if it were the MODEL_MATRIX.
With this in place we now properly handle VERTEX transformations that a Material Shader might do, such as billboard-ing.
This also fixes #75433.
Comparisons
(All done using godotengine/godot-demo-projects#894)
With this fix + double precision
https://user-images.githubusercontent.com/37230465/228559865-947ef102-f430-45b4-b437-7b3ebc8b16a4.mp4
It does jitter quite a bit on the farthest setting, but that happens regardless of this fix, so it doesn't seem like a regression.
Without this fix + double precision
https://user-images.githubusercontent.com/37230465/228562053-12cbea3c-2387-4985-b39e-25959011434d.mp4
Same jittering, but effects like billboarding stops working.