Manually setting colors in fragment shader results in incorrect results

Hi, I discovered an oddity while using GL calls to draw lines. GL.Color sets the current vertex colors, which are in turn read by my shader and used as the final color in the fragment shader. Except that my lines were turning out the wrong color! After taking screenshots and comparing RGB values, I dug a bit deeper and ended up with some confusing results. Below are two cubes. The one on the left has the built in Unlit shader applied with the following values for it’s color: (0, 126, 255), or a Hex value of 007DFFFF.

The second cube has this shader applied:

// Unlit shader. Simplest possible colored shader.
// - no lighting
// - no lightmap support
// - no texture

Shader "Unlit/UnlitTest" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
}

SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 100
   
    Pass {  
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #pragma multi_compile_fog
           
            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
            };

            struct v2f {
                float4 vertex : SV_POSITION;
                UNITY_FOG_COORDS(0)
            };

            fixed4 _Color;
           
            v2f vert (appdata_t v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
           
            fixed4 frag (v2f i) : COLOR
            {
                fixed4 col = _Color;
                UNITY_APPLY_FOG(i.fogCoord, col);
                UNITY_OPAQUE_ALPHA(col.a);
                return fixed4(0, 0.49, 1, 1);
            }
        ENDCG
    }
}

}

This is just the unlit shader, except I manually set the color to be the desired color, in 0-1 RGB values. (0/255 =0, 126/255 = 0.49, 255/255 = 1). As far as I can tell, the two cubes should be the exact same color. If you change the test to be pure red, green or blue, then the two cubes are the same, so I’m not sure what’s going on here.

Thanks for any help,
Erik

If you’re using gamma color space this will work as you’re expecting, but in linear color space a value of ~0.5 (or 126/255) is closer to ~0.73 or ~186/255 in gamma sRGB space.

Inversely a gamma value of 126/255 is going to be closer to 0.2 in linear. Unity has built in functions for converting between the two color spaces.

fixed3 linearColor = GammaToLinearSpace(gammaColor);

fixed3 gammaColor = LinearToGammaSpace(linearColor);

So in your case you want to do something like this:

fixed3 color = GammaToLinearSpace(fixed3(0.0/255.0, 126.0/255.0, 255.0/255.0));

When setting color values for materials, vertex colors, or GL commands Unity automatically handles the conversion from gamma space for you.

3 Likes

Exactly what I needed, thanks @bgolus !