-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
Vertex and attribute compression #81138
Conversation
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
Outdated
Show resolved
Hide resolved
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
Outdated
Show resolved
Hide resolved
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
Outdated
Show resolved
Hide resolved
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
Outdated
Show resolved
Hide resolved
4eb1d5f
to
514387f
Compare
Pushed an update to address comments and CI issues. Should be ready for substantive review now. |
514387f
to
22de3d2
Compare
22de3d2
to
15f8715
Compare
Thanks for the reviews AThousandShips! Just pushed another version with docs and fixes for CI. This PR should be ready to go now. I don't expect to find any performance regressions in my final testing. One catch, I am away on holidays from September 7 to 19. So if we merge this anytime soon I won't be around to jump on bugs. So we may want to merge this the week of the 18th so that I can be available to fix any bugs that arise. While I have done my best to test extensively, it is inevitable that bugs will appear from such a large change to a fundamental system |
Changing
I think this kind of error can be fixed by changing |
d5cdf86
to
dca3376
Compare
I’ll take a glance. |
5984030
to
d16ca71
Compare
Yes, but you may not be able to rebuild everything. If the user is consuming a library from NuGet, then they can't rebuild that library, they can only wait for the library to be updated. Updating the library will make it incompatible with older versions of Godot, so the author may not want to do that.
Maybe not for C++, but C# still needs it. If the compat method won't be registered, then we need to add a C# method manually to |
I think this may be acceptable for now, since we don't want to block this PR on an infrastructural issue. So if we can work around it with a @raulsntos Could you give us a diff of what a |
This diff adds compat methods for diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs b/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs
index 48b47b166a8..aa03c3f97f1 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Compat.cs
@@ -44,6 +44,16 @@ partial class Geometry3D
}
}
+partial class ImporterMesh
+{
+ /// <inheritdoc cref="AddSurface(Mesh.PrimitiveType, Godot.Collections.Array, Godot.Collections.Array{Godot.Collections.Array}, Godot.Collections.Dictionary, Material, string, ulong)"/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void AddSurface(Mesh.PrimitiveType primitive, Godot.Collections.Array arrays, Godot.Collections.Array<Godot.Collections.Array> blendShapes, Godot.Collections.Dictionary lods, Material material, string name, uint flags)
+ {
+ AddSurface(primitive, arrays, blendShapes, lods, material, name, (ulong)flags);
+ }
+}
+
partial class MeshInstance3D
{
/// <inheritdoc cref="CreateMultipleConvexCollisions(MeshConvexDecompositionSettings)"/>
@@ -106,6 +116,13 @@ partial class SurfaceTool
{
AddTriangleFan(vertices, uvs, colors, uv2S, normals, new Godot.Collections.Array<Plane>(tangents));
}
+
+ /// <inheritdoc cref="Commit(ArrayMesh, ulong)"/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ArrayMesh Commit(ArrayMesh existing, uint flags)
+ {
+ return Commit(existing, (ulong)flags);
+ }
}
partial class Tree
|
a77075b
to
0534b28
Compare
Updated to:
As far as I know, this should be good once I squash the commits. To keep things easy to review (and avoid accidentally deleting necessary compat methods) I have left this in multiple PRs @raulsntos can you confirm that the C# compat looks acceptable now? @dsnopek Can you confirm again that the GDExtension compatibility is still fine? |
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.
Looking at just the GDExtension compatibility bits, this looks good to me!
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 C# compat look good to me.
0534b28
to
effdccb
Compare
…mat. This allows Godot to automatically compress meshes to save a lot of bandwidth. In general, this requires no interaction from the user and should result in no noticable quality loss. This scheme is not backwards compatible, so we have provided an upgrade mechanism, and a mesh versioning mechanism. Existing meshes can still be used as a result, but users can get a performance boost by reimporting assets.
effdccb
to
51ed3ae
Compare
This should be ready to go now. I have tested extensively including:
And with all three renderers. In the current state I haven't caught any issues to be aware of. One big thing to make users aware of is that we are switching to a new mesh format version. This means that when they run existing scenes they will get a warning that their mesh has been upgraded to a new version and then need to re-save or re-import the mesh. |
Thanks! |
This scheme is backwards compatible so old meshes will continue to work.
Users can get a performance boost by reimporting assets
The rationale behind this PR can be found here: https://files.godot.foundation/s/259N9YQEPcBZwMx
In short, the main reason behind making this PR is bandwidth reduction (passing less data around the GPU per draw call). Bandwidth reduction is valuable in two cases:
From our perspective, reducing bandwidth also has the added benefit that we can now confirm that we are not generally bandwidth bound (i.e. we aren't boundwidth bound in all scenes) which means we can focus our next performance improvements elsewhere (VGPRs / instructions).
Usage notes
After merging this PR all meshes will automatically start using a slightly different vertex attribute layout:
This is the recommended layout for mobile devices as it means that shadow passes and tiling passes only ever have to read vertex positions and it doesn't hurt performance on Desktop.
The renderer will automatically use this layout even if the mesh doesn't. To accommodate that, I have added a mesh format version number so we can perform automatic upgrades between versions. This avoids the issue we had last summer when integrating octahedral compression. Three things to note about this though:
In addition to the vertex layout change, we also introduced optional compression for vertices, normals, tangents, and UVs. The importers will automatically detect if the mesh is a candidate for compression and apply the appropriate flags. For UVs, we can compress them as long as they are all within the 0-1 range. While this is technically a lossy compression, there won't be a visible difference on textures with a size smaller than 65536 pixels, so it is safe to apply). For vertices we do two things:
I implemented this compression scheme in a way that does not require additional shader variants, so there will be no effect on shader compile time. However, this means that there are more calculations in the shader, and VGPR usage may be affected on some compilers.
When the compression flags are not used, the vertex format remains the same as it was before this PR.
Performance
So far I have tested on my laptop using an integrated GPU and an NVidia 3050m. There is no difference when using the forward+ renderer, a slight improvement when using the compatibility renderer, and about a 10% improvement when using the mobile renderer. This is likely due to the fact that I had to refactor the mobile renderer to pass the necessary data.
On the TPS demo on integrated graphics, I am seeing an improvement from ~17 FPS to ~20FPS (Forward+).
Using the Synty Vikings demo When using the mobile renderer, I get an increase from 40 ms per frame to 37 ms per frame.
Running the TPS demo on mobile (Pixel 7 and Pixel 1) I see no performance difference (likely because both are instruction bound, not bandwidth bound).
More performance testing is needed before merging. But so far, in all cases the performance is either the exact same or slightly better.Todos:
Add additional optimization by de-interleaving vertex positions (this won't be backwards compatible and so we need to add version identifiers to mesh dataAdd a setting to force disable optimization on an imported mesh. Generally, the auto-detection works quite well. But it relies on the mesh having both proper normals and tangents. If the mesh has improper tangents, the result is also bad.In the end this setting wasn't needed. The issue came from a scene with non-continuous UVs, so the generated tangents were bogus. The solution was to allow GLTFs to respect the "ensure tangents" setting. Previously tangents were always generated if not supplied.more performance testing with heavier scenes on mobile devices (especially scenes with more shadows).