Search Unity

UNITY_LIGHTMODEL_AMBIENT equal to half the expected value?

Discussion in 'Shaders' started by cjddmut, Nov 21, 2013.

  1. cjddmut

    cjddmut

    Joined:
    Nov 19, 2012
    Posts:
    179
    I'm starting to learn how to write shaders so when playing around with a shader I was writing I noticed something odd. My ambient light was a lot darker than I expected.

    I set the ambient light in the render settings to full red (255, 0, 0) and the built in diffuse shader correctly display the object (in a lightless world) as bright red. However, my object was displaying as a darker red. I did some testing and realized that it was exactly half as red. I don't understand why this is? Here's a sample shader showing what I am doing.

    Code (csharp):
    1.  
    2. Shader "test/AmbientOnly"
    3. {
    4.     SubShader
    5.     {  
    6.         Pass
    7.         {  
    8.             CGPROGRAM
    9.  
    10.             #pragma vertex vert
    11.             #pragma fragment frag
    12.  
    13.             // base structs
    14.             struct vertexInput
    15.             {
    16.                 float4 vertex : POSITION;
    17.             };
    18.  
    19.             struct vertexOutput
    20.             {
    21.                 float4 pos : SV_POSITION;
    22.                 float4 color : COLOR;
    23.             };
    24.  
    25.             // vertex function
    26.             vertexOutput vert(vertexInput v)
    27.             {
    28.                 vertexOutput output;
    29.  
    30.                 float3 colorFinal = UNITY_LIGHTMODEL_AMBIENT;
    31.  
    32.                 // Debug purposes
    33.                 if (colorFinal.r == 0.5)
    34.                 {
    35.                     // When I place the ambient light to full red only (255, 0, 0) then this triggers and it turn it green.
    36.                     colorFinal.r = 0;
    37.                     colorFinal.g = 1;
    38.                 }
    39.                 else
    40.                 {
    41.                     // Otherwise I double the values and it turns the appropriate color.
    42.                     colorFinal *= 2;
    43.                 }
    44.  
    45.                 output.color = float4(colorFinal, 1.0);
    46.                 output.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    47.                 return output;
    48.             }
    49.  
    50.             // fragment function
    51.             float4 frag(vertexOutput i) : COLOR
    52.             {
    53.                 return i.color;
    54.             }
    55.  
    56.         ENDCG
    57.         }
    58.     }
    59.  
    60.     // Fallback "Diffuse"
    61. }
    62.  
    As this shader shows, I will make the object bright green if it detects the ambient light being at half (which is FULL in the render settings) otherwise will double the values. Once doubled it correctly matches the built in shader.

    I'd like to just understand why this is! Thanks!
     
    Last edited: Nov 21, 2013
  2. shaderbytes

    shaderbytes

    Joined:
    Nov 11, 2010
    Posts:
    900
    Well I cant say why its half .. but I can say from having dabbled with shaders a little bit and having looked at many examples that light calculation results always seem to get multiplied by 2.. like its some sort of standard. I do it in my shaders as well, perhaps someone clever knows the actual reason .. anyone?
     
  3. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    It is indeed multiplied by 2, just need to account for that. perhaps an early unity oversight that stayed for compatibility.
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    All lighting values in Unity are multiplied by 2.

    It was an early thing to allow for overbrightening, and it's had to stay in for compatibility reasons. I think Aras mentioned it may get removed in the next major release (Unity 5) but that it'll have to stay in for this cycle at least so that it stays consistent.
     
  5. cjddmut

    cjddmut

    Joined:
    Nov 19, 2012
    Posts:
    179
    Cool, thanks for the information. Will keep in mind!
     
  6. Trung-Hieu

    Trung-Hieu

    Joined:
    Feb 18, 2013
    Posts:
    37
    Actually, the _LightColor0 in my case need to multiply by 3, not 2. And by the way, where is the documentation that specify the multiplier for light color ?
     
  7. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    There is no documentation, just the built-in shader code - everything is multiplied by 2.