jnsmalm / pixi3d

The 3D renderer for PixiJS. Seamless integration with 2D applications.
https://pixi3d.org
MIT License
759 stars 44 forks source link

Skinning with many joints doesn't work on old weak devices #58

Closed jnsmalm closed 3 years ago

jnsmalm commented 3 years ago

Maybe writing the joint matrices to a texture should be default?

Unwarped commented 3 years ago

Would the texture have to be updated every frame? What sort of CPU/GPU impact could this have? I would like to see this as an option but I know that would probably add some complexity supporting both. Multiple shaders etc.

jnsmalm commented 3 years ago

Yes, the texture have to be updated each frame. Pixi3D actually already supports storing joint matrix data in a texture for vertex skinning, otherwise it wouldn't work well to animate characters on a older mobile devices as they don't support enough vertex uniforms. Both Three.js and Babylon.js seems to store joint matrix data in a texture by default, so I think I Pixi3D can do that as well.

jnsmalm commented 3 years ago

This has now been changed to prefer floating point textures, and will use vertex uniforms as a backup. If the vertex uniforms can't handle the amount of joints, it will write to debug object and vertex skinning will be disabled for that mesh.

Unwarped commented 3 years ago

This is using approximately 25% increased GPU usage over the old version in my tests on Surface Pro 6. How can I set it manually to use the old method? Thanks!

jnsmalm commented 3 years ago

How did you measure this?

Unwarped commented 3 years ago

Hey jnsmalm. Just from watching GPU in task manager going from 18-20% on old version up to about 24-26% (about 25% jump). Not the end of the world I know. Just alternating this build and one from a 1 or 2 back. It's a 2D isometric demo I've been playing around with that has about a dozen animated 3D mesh characters on top.

Unwarped commented 3 years ago

Changing line 11,516 in my pixi3D.js build to if (standard_material_matrix_texture_1.StandardMaterialMatrixTexture.isSupported(renderer) && 1 == 2) { seems to bring the numbers back down as a hack test.

jnsmalm commented 3 years ago

Not sure what the GPU in task manager actually measures. I render many skinned meshes and the performance seems to be exactly the same (using textures or uniforms) with this tool: https://github.com/mrdoob/stats.js/ I have tested both on Mac M1, iPhone 12 and an older weaker Android.

Unwarped commented 3 years ago

Yes I understand I see what you mean thanks jnsmalm. How would you feel about a global PIXI variable to optionally enable/disable this behavior?

I abandoned my use of BabylonJS unfortunately as every little thing seemed to increase GPU usage until my simple demo with every optimization available was using 80% GPU and making my computer burning hot!

I admire how well Pixi3D is running with my project and don't want to add any unnecessary overhead. Many thanks for your responses and continued work on this project.

jnsmalm commented 3 years ago

Thanks for helping out with feedback, I'll see what I can do.

jnsmalm commented 3 years ago

Added a setting: PIXI.settings.PREFER_UNIFORMS_WHEN_UPLOADING_SKIN_JOINTS = true. Hope it helps.

Unwarped commented 3 years ago

This works beautifully. Thank you for taking the time to add this jnsmalm I really appreciate it! :)