Skinned Mesh Shader Optimizations and C++ changes to support - #6256
naitro2010 wants to merge 8 commits into
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
Is there a way to make a release build for this pull request with GitHub actions that I can download and test? I've only tested with a local build so far. Thanks :) |
There is a full, downloadable build at the bottom? |
|
I just merged the latest changes from develop because the newer LLSD parsing integration test failed to pass. |
|
Apparently GitHub is having internal server errors when downloading dependencies now 😢 |
|
@naitro2010 there is a green checkbox near the commit, click it, it will show a list of 'checks', that's the build, open any OS specifc one and go to summary. Artifacts are at the bottom of the summary. https://github.com/secondlife/viewer/actions/runs/34837962086 |
|
@akleshchev Thanks :) I'll test with the release build on Windows now. |
|
Note that it's ReleaseOS, not Release, but the difference should be negligible for shaders. |
|
I just tested and it seems like avatar and skinned mesh rendering works on Windows without any issues. |
|
Basically you moved some repeating math from gpu to make it one-time on cpu? Sadly shaders are not in my wheelhouse and I have no idea how to test skinning either. |
|
@Geenz Please take a look. |
cosmic-linden
left a comment
There was a problem hiding this comment.
Just starting to review this.
As a general note, math calculations done in C++ in lieu of a shader should be done via glm when possible, but I'm not yet sure if that's applicable here.
Have you tried running Develop > Render Tests > Frame Profile and checking the log for objectSkinV run time? Intuitively, I would think this could make an impact assuming the code is correct (as avatars can have many vertices), but it could be interesting to know.
| index = max(index, vec4( 0.0)); | ||
|
|
||
| w *= 1.0/(w.x+w.y+w.z+w.w); | ||
| vec4 w = fract(weight4)*2.0; |
There was a problem hiding this comment.
I don't really understand why this factor of two is multiplied here. Looks like a new factor of 0.5 is applied in LLFace::getGeometryVolume and Primitive::upload which this is trying to compensate for. See also pbrmetallicroughnessV.glsl, which is another shader which makes use of weight4.
There was a problem hiding this comment.
Thanks for reviewing my changes. :)
I think the scaling I added in primitive.cpp might be a bug.
weight4 in getGLTFTransform is using a different format for the actual weights.
objectSkinV uses the integer portion for the index and the fractional portion for the weight.
getGLTFTransform splits the two into joints and weights.
It is a bit confusing to have the same input used in two different shaders with different data formats.
Reverting the changes in primitive.cpp seemed to work with normal meshes. I'm going to test with a GLTF PBR mesh next.
There was a problem hiding this comment.
I just reverted the changes to primitive.cpp and everything seems to still work ok with a local build.
Please let me know if everything else looks good and when another ReleaseOS build is ready.
Thanks :)
There was a problem hiding this comment.
Also, the factor of 0.5 is for floating point precision with weights close to 1.0 on the GPU in case it rounds up. I don't know if it is needed on most GPUs though.
There was a problem hiding this comment.
in case it rounds up
Why would it round up? And why would that fix only be relevant to certain GPUs?
There was a problem hiding this comment.
It could round up if the precision on the GPU is different than fp32 and the weight is really close to 1.0.
There might be some other cases where it could also have rounding errors accumulate.
If it works without the scaling factor on all CPUs and GPUs it probably isn't needed.
I have run into issues with floating point precision before which is why I added the scaling factor for the fractional portion.
It might be better to have the joints be integers like in pbrmetallicroughnessV.glsl instead of using the integer portion of the floating point weights. It would also make it so the scaling is no longer potentially required.
I'll make two local builds and use the Frame Profiler to compare.
Thanks :)
There was a problem hiding this comment.
If the GPU precision is lower than on CPU, I doubt a factor of two would fix it. Based on what I'm reading, floating point precision on the GPU can differ by multiple digits. And even if it only differed by one digit, I don't think your factor of two workaround is going to address that (best case, it will decrement the floating-point exponent and have no impact on precision at all). I think it would be best to not include that alleged workaround unless we have a bug report which it fixes.
There was a problem hiding this comment.
I just tested with normalization to 1.0 and it caused the skinned mesh to explode.
I just updated the C++ code to normalize to 0.9999 instead of 1.0 for the fractional portion and everything worked ok without the extra scaling factor in the shader.
I'm going to try to do some A/B testing now and see what the frame profiler says.
Thanks :)
…ormat and have a joints array for the integer portion
Description
This PR moves some processing that used to run on the GPU for every skinned vertex into a precomputed step on the CPU to hopefully improve frame rates with lots of visible avatars.
Here is the linked issue: #6255
Checklist
Please ensure the following before requesting review:
Additional Notes
This is my first time creating a pull request for Second Life.
Please let me know if I can do anything to improve the next pull requests I make or if there are any code quality issues that I can fix.
I mostly wrote these changes to improve the frame rate for my new version of the viewer with Stereo 3D Virtual Reality rendering that I've been working on but I think they might help with normal rendering too.
I don't have a large number of different GPUs to test on so I'm leaving this pull request as a draft until more people are able to test it on their hardware.