Hello folks!
Recently we seen some users experiencing issues with limited keyword count. As result we decided it might be a could time to revisit this problem again.
So for some who do not know about the global keywords limit, here is quick explanation.
Basically when you declare any new keyword in shader (etc. multi_compile, shader_feature) or with scripting API (etc. Shader.EnableKeyword, Material.EnableKeyword…) we actually assign unique index from 0 to 255 and store it as global dictionary between the name and index. This allows us to store enabled keywords as bitmask, this way increasing all keyword related operations significantly. However as some of you already aware it restricts project from having more than 256 unique keywords across all the shader. Usually it is not that easy to hit the cap, but that is not the case once you start to rely on third party packages.
For this reason we were thinking about possible solutions for this issue and we decided it would be great to get feedback from you guys.
1) Increase keyword count to 1024. Well this is actually the simplest solution and we already did this multiple times before.
Advantages - we do not break the old functionality.
Disadvantage - this affects keyword related performance, but we seen regression only if project actually uses more keywords.
2) Make keyword completely local. It means every shader can have 256 unique keywords. However functions that modify keywords globally (etc. Shader.EnableKeyword, CommandBuffer.EnableShaderKeyword), must be removed or changed to simulate old functionality by patching local map.
Advantages - we keep shader variant API intact, we get completly get rid of global keywords.
Disadvantage - functions that change keywords globally must be removed or has to get very heavy internal change (That might not work exactly same in all cases as it would be simulated with local keywords).
3) Add local keywords as additional functionality on current system. So basically hybrid mode to support local and global keywords at the same time. Idea is to leave 192 keywords for global and 64 for local per shader.
Advantages - we keep old functionality intact.
Disadvantage - we have to introduce new shader API that would allow specifying which keywords as local.
Current idea is to deprecate multi_compile/shader_feature and introduce new unified pragma generate_variants that would have some additional options.
For example:
#pragma multi_compile A B == #pragma generate_variants nostrip global A B == #pragma generate_variants nostrip A B
#pragma shader_feature A B == #pragma generate_variants strip global A B == #pragma generate_variants A B
#pragma generate_variants strip local A B
#pragma generate_variants nostrip local A B
We currently have option 3 implemented, but not publicly available. The option 2 still requires a bit investigation, because it would require fundamental changes of keyword system.