0
\$\begingroup\$

Let's say I have this very simple pixel shader (cbuffers and other stuff omitted)

float4 PS(VertexOut pin, uniform bool useLighting) : SV_Target {
    float4 retColor = gDiffuseMap.Sample( sampler0, pin.Tex );
if (useLighting) {
    retColor = retColor * float4(gAmbientLight, 1.0f);
}
    return retColor;
}

and two techniques such as

technique11 TexTech {
    pass P0 {
        SetVertexShader( CompileShader( vs_4_0, VS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader( ps_4_0, PS(false)));
    }
}

technique11 TexLitTech {
    pass P0 {
        SetVertexShader( CompileShader(vs_4_0, VS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PS(true)));
    }
}

The way I understand it, the useLighting condition is evaluated during compile-time and each technique will have its own version of the pixel shader function without any branching. That means the useLighting condition wouldn't have any runtime penalties. Is that correct? So it's kind of like C preprocessing?

Why can the pin variable just be left out like that in the CompileShader call? It makes sense, of course, I'm just wondering if this is some special HLSL or Effect Framework syntax?

\$\endgroup\$
  • \$\begingroup\$ Because i'm not familiar with Directx hlsl i would make a statement that is based on reasoning and might not be true so anyone can correct me if i'm wrong. In this case you used it (and because i believe directx is very good at this) the uniform will be optimized out by the shader compiler.The dx runtime can realize that you don't change the uniform and the shaders can be optimized properly. However if you change the uniform from outside by setting the uniform the shaders can't be optimized and the branching will be there. Pin can't be optimized because it contains the vertex position. \$\endgroup\$ – Raxvan Jan 4 '15 at 9:43
  • \$\begingroup\$ What do you mean with setting it from the outside? I'm a noob at this, but from my understanding you use constant buffers (cbuffer) in HLSL where you would use uniforms in GLSL. So I'm not sure HLSL's uniform is the same thing as in GLSL...? \$\endgroup\$ – PaulK Jan 4 '15 at 11:21
  • \$\begingroup\$ Also I know pin can't be optimized because it's the argument of the entry-point function. What I meant is the syntax in the CompilerShader call where you pass the entry-point PS and the compiler automagically figures out the true/false should go into useLighting. How does that work? \$\endgroup\$ – PaulK Jan 4 '15 at 11:24
0
\$\begingroup\$

Officially the uniform keyword indicates it is constant throughout the execution. All uniform variables to a shader must be resolved at compile-time.

The HLSL compiler using the legacy Effects profile will generate 3 shaders in this case:

  • A vs_4_0 profile vertex shader using the VS entry-point
  • A ps_4_0 profile pixel shader using the PS entry-point holding the useLighting to be false.
  • A ps_4_0 profile pixel shader using the PS entry-point holding the useLighting to be true.
\$\endgroup\$
  • \$\begingroup\$ This is only half right. Uniform variables obviously don’t need to be known at compile time. However, when their value is set by a technique, then the multiple compilation you describe will happen. \$\endgroup\$ – sam hocevar Jan 5 '15 at 22:34
  • \$\begingroup\$ The Effects system performs no dynamic compilation based on selected technique. The technique element provides all the information that the HLSL compiler uses at build-time to generate the shader blobs. To be fair, only 'uniform shader inputs' are required at build-time since you can set 'uniform globals' at runtime. \$\endgroup\$ – Chuck Walbourn Jan 6 '15 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.