Hello. Currently in my project I’m hitting a high fragment fill rate. However the performance hit only happens when I enable MSAA. I think that kind of is expected as MSAA is known to be a heavy performance tanker. However I don’t think it should tank my performance this much. It doesn’t matter if I enable 2x, 4x or even 8x, the impact is minimal between the three options but always half’s my performance no matter the option I choose.
I do have a sneeky suspicion I have a massive amount of fragment overdraw (I am using Lods and Instance culling so that isn’t the problem and without MSAA my scene is very optimized). Most likely due to the fact I very heavy foliage and forestry. I was thinking that a depth pre-pass for the opaque, alpha and instances would work to reduce fragment count but am not really sure how to do this. I know you have to run empty fragment shaders that only output depth but where do I begin and how do I get this working inside panda3d.
Or maybe I should alternate to a different Anti-Aliasing technique? I do like MSAA and its quality but maybe it isn’t the best option for the project I am building (Large open world game). (Heard good things about SMAA. Maybe FXAA would be good enough for my project)
It’s possible you are indeed fill rate bound. Using front-to-back rendering rather than back-to-front could help, but that requires using binary (or multisample) alpha rather than alpha blending. Simplifying your fragment shader (fewer lights, fewer textures, etc.) is an alternative since it reduces the amount of work needed to be done per fragment. Ensure your textures have mipmapping enabled as well, which improves fragment shader performance significantly.
A depth pre-pass could be worth experimenting with, but there are some caveats with transparency to consider. I think you would set this up by having another display region on the window with its own camera (matching the main camera) and with initial states on those cameras, disabling color write on the first camera (and lighting, etc.) and disabling depth write on the second one (and with an M_less_equal depth test function).
This would work well if all of the leaves were obscured by a fully opaque object, but leaves (or other objects with transparency) obscuring each other are more difficult. To get the benefits of a depth pre-pass for these you would need to use alpha testing on the leaves to ensure that only the areas with >0.9 alpha are rendered to the depth buffer (a la M_dual), but determining the alpha requires running the whole fragment shader for each fragment. You’d have to have a simplified fragment shader that does only the minimum necessary to determine the alpha value.
Another thing to consider is making the leaf geometry slightly more complicated so that there is less area of the leaves that is fully transparent.
Because of the difficult interaction between this technique and transparent objects, which is exactly where you need it, my preference would be for trying to optimize your fragment shaders, and using M_multisample transparency mode when you’re using multisampling, which does not require back-to-front rendering. Failing that, other transparency algorithms may be worth considering.
After developing some kind of hacky depth pre pass, I do indeed get a performance boost! (about 10% - 20% with MSAA!) But from my research of testing and external sources, I have learned that alpha pre depth passes are NOT the way too go. They are a performance trap! On average I either lose or wouldn’t gain any performance at all. the discard keyword along with texture fetches absolutely kills performance (even with MBinary used). However MSAA still was a bit too expensive for me. I have switched to FXAA , which to be honest, is kind of perfect for my project. My post processing highly warps the scene with an oil paining filter (Kuwahura filter) that kind of blends edges automatically.
I did also have to tweak my tree models to be put into two separate nodes. the opaque trunk, and the transparent leaves so I can include the opaque part of the tree into my depth pre pass. Also it turns out my trees had to much wasted alpha space that also degraded performance (you were right!).
Also something else I noticed is that it was only worth doing the depth pre pass when multithreading was enabled. I assume it’s because the draw call cost outweighed the actual savings from the pass when in single threaded. Probably because my scene doesn’t actually have that many nodes (yet) and has a lot of hardware instancing (low draw call count). I reckon as I scale the project, it would give back bigger and bigger gains.
p.s:
Sorry for the long response. I just wanted to be more in depth incase anyone else is looking for some answers and experience in the forums (as I didn’t see any other post talk about this).