How to Declare Global Constant in CG?

I am trying to declare a global (ie, not local to a function) constant in a shader. In my actual use for this, I want to declare a global constant in a cginc file so that other shaders can reference it. However, it seems that no matter what I initialize my constant to, it is always treated as the default value for the type.

NVidia’s CG tutorial seems to imply that it should be possible to have globally scoped constants, but in their code snippet, you can’t tell if their constant is global or local.

Here is a simple example to demonstrate the problem.

Shader "Custom/ConstantTest"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
       
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
           
            const fixed4 SPECIAL_COLOR = fixed4(1, 0, 0, 1);
           
            struct v2f
            {
                float4 pos : POSITION;
            };
           
            v2f vert(appdata_base input)
            {
                v2f output;
                output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
                return output;
            }
           
            fixed4 frag(v2f input) : COLOR
            {
                //If I return the color as a constant, it just
                //shows up as black, regardless of the color
                //I have set the constant to.
                return SPECIAL_COLOR;
               
                //If I return a "magic number" like this it
                //works, the cube is red.
                //return fixed4(1, 0, 0, 1);
               
                //If I make the constant local scope, it works
                //and the cube is red.
                //const fixed4 SPECIAL_COLOR = fixed4(1, 0, 0, 1);
                //return SPECIAL_COLOR;
            }
            ENDCG
        }
    }
}

As you can see, I have a global constant color declared as the color red. However, when I put this shader on an object, it shows up as all black instead of all red.

I can make this work by just returning a “magic number” in my fragment shader, or by declaring and using a locally scoped constant in the fragment shader. However, I would like to get this to work with a global constant since in my actual use for this, I would like multiple shaders to be able to access a single constant.

How do you declare a global constant in CG?

Must be static…

static const fixed4 SPECIAL_COLOR = fixed4(1, 0, 0, 1);
5 Likes

Awesome, it works! Thank you so much! I guess I was just used to not needing the static keyword for global constants in C#.

CG is much more like C/C++ than C#.
C/C++ have the concept of instance consts as well as static consts, so you need the static keyword to let it know which one you mean. C# you only get one kind of const - static.

1 Like