Optimising number of Materials/shader variants

Howdy all!

I’ve a reasonably complex scene with a lot of different material permutations which are resulting in a large number of different shaders. In an effort to optimise I’m trying to flatten these down where possible so that if MatA doesn’t have a light map but MatB does, then I can simply add a black texture to MatA which theoretically means if all else is equal, those 2 materials result in 1 shader and less state switching.

Now I could do this all manually, but being lazy I essentially want to determine a set of changes that can be performed on certain materials in the asset registry that will have the biggest impact in reducing the number of shaders created. In an idea world I want to be able to provide my scene artists with a list of changes that says ‘Add a black texture to material X’, ‘disable specular on material Y’ etc.

So my idea thus far, is to filter out a list of Materials from the AssetRegistry app.assets.filter(asset => asset.type === 'material) and then try and determine what variation of material props results in a specific shader. However I wondered if there was already something in the engine/editor that tracked all this info that I could just access and strip out, and if not, if there’s some metric on a materials that tells me what shader variant it creates!

Thx

that’s very smart

Hi @Mark_Lundin,

That’s good thinking! I’ve never attempted to automate this, but thinking now a good starting place is the various _define methods on the StandardMaterial class.

Maybe you can use them to run a custom equals method and find out how similar two materials are based on their chunks, props etc.:

1 Like

@Mark_Lundin - You can run: ‘pc.app.graphicsDevice.programLib.dumpPrograms();’ in Developer Tools console to get a list of all shader variants used - eyeballing the list could help identify extraneous variants - or running a script to diff each variant would probably work.

2 Likes

Nice! Yes that’ll help figure things out. Is there something already tracked that links back to an associated material from a specific program @ray

You’d need to loop over all materials and compare material.shader I think … nothing like this is tracked I believe.

You may be able to do something like: https://github.com/playcanvas/engine/blob/master/src/graphics/program-library.js#L73:L73 - to log which materials are still causing variants to be created.