0
\$\begingroup\$

I have a GLSL ES 3.0 shader and in certain scenario, I want to read from two textures instead of one and do a lerp between them.

However, I am not sure what is a better solution.

Use standard runtime if like:

vec4 res = vec4(0);
if (enable2Tex){
   res = mix(texture2d(s1, tx), texture2d(s2, tx), t)
}
else {
   res = texture2d(s1, tx);
}

or should I create two versions of the same shader like:

vec4 res = vec4(0);

#ifdef ENABLE_2_TEX
   res = mix(texture2d(s1, tx), texture2d(s2, tx), t)
#else
   res = texture2d(s1, tx);
#endif

and switch between two shaders in code?

\$\endgroup\$
3
  • 1
    \$\begingroup\$ That sounds like a question you can answer by trying each method you've proposed, and measuring which gives you better performance (or is more convenient to work with) in your specific use cases. There may be some games that use one of these methods, some that use a different method, and some that mix methods for different purposes, depending on that game's specific needs. You are the expert in your own game's needs, so there is no one more qualified to choose the best method for those needs than you yourself. \$\endgroup\$
    – DMGregory
    Jan 18, 2022 at 18:05
  • \$\begingroup\$ ...by trying each method you've proposed, and measuring which gives you better performance... This is problematic for mobile phones which performance can vary significantly (or based on used GPU at least), so I was thinking that maybe someone has some insight or prior knowledge of this problem \$\endgroup\$ Jan 18, 2022 at 18:09
  • 1
    \$\begingroup\$ What you just said explains why "someone" will not have a conclusive answer for you for the general case. The performance can vary significantly depending on your target hardware, whether you're CPU or draw call or vertex or sampling or blending or fill rate bound, etc., and the person who knows or can determine those details for your game is... you. \$\endgroup\$
    – DMGregory
    Jan 18, 2022 at 18:12

1 Answer 1

1
\$\begingroup\$

You should create two versions of the same shader.

Branching based on non-uniform variables means that the GPU must either perform different operations at the same time (and therefore break parallelism), or “flatten the branch” and maintain parallelism by performing the operations for both branches and then discarding one result. Branching based on uniform variables means that the GPU must flatten the branch. Both of these approaches result in reduced GPU performance. For any type of dynamic branching, the GPU must allocate register space for the worst case. If one branch is much more costly than the other, this means that the GPU wastes register space. This can lead to fewer invocations of the shader program in parallel, which reduces performance. In general, if your code branches on uniform values and both branches have roughly similar workloads, then the impact on GPU performance is likely to be small. However, you should always profile your application and consider the advantages and disadvantages case-by-case.

Note: Dynamic branching can also lead to large shader programs, because the code for all conditions is compiled into the same shader program. However, the effect of these larger files on load times and Memory usage is usually less significant than the impact of shader variants.

Source: Unity Documentation

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .