Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[solved] Accessing Fog parameters in CG shader

Discussion in 'Shaders' started by Lex-DRL, Jun 4, 2014.

  1. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
    In my custom CG code, how can I get scene's fog color (the one set in render settings) and grayscale fog mask, calculated according to the selected "fog mode"?

    I'm writing additive-multiply shader. So far, I didn't find a way to make native ShaderLab's fog work correctly (the one that's specified via Fog statement).
    So I'd like to disable it completely and manually apply it in my CG code.
     
  2. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    AFAIK there are no built-in shader variables that get the fog color like the ambient color, you have to feed it to the shader yourself using setColor, even the globalfog screen effect from the pro packages does this

    you can find the color in script via RenderSettings.fogColor

    EDIT: WRONG! read comment below
     
    Last edited: Jun 4, 2014
  3. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    It's only mentioned in passing, but it's in the documentation:
    Code (CSharp):
    1. uniform half4 unity_FogColor;
     
    Lex-DRL and kebrus like this.
  4. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    I stand corrected! Thx
     
  5. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
    Thanks guys.
    There's also unity_FogColor and unity_FogStart in the same example. Is there any explanation about these two variables? Why are they half4? "start" and "end" variables should be simple scalar, shouldn't they?
    There's no mention about these variables in any of default cginc files.
     
  6. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I think that's the only place they're mentioned in the manual. My guess is that they are actually scalar values, which is why only the first component gets used in that example. You could test the other ones yourself pretty easily.
     
  7. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
  8. Lex-DRL

    Lex-DRL

    Joined:
    Oct 10, 2011
    Posts:
    139
    I did it!
    If someone would face the same task in the future, here's the code of the shader implementing Exp2 fog:
    Code (CSharp):
    1. Shader "DRL/testFog-My" {
    2. Properties {
    3.     _MainTex ("Base (RGB)", 2D) = "black" {}
    4. }
    5.  
    6. SubShader {
    7.     Tags { "RenderType" = "Opaque" }
    8.     Cull off
    9.     Lighting Off
    10.     Blend SrcAlpha OneMinusSrcAlpha
    11.     Fog {Mode Off}
    12.  
    13.     Pass {
    14.         CGPROGRAM
    15.         #pragma target 2.0
    16.         #pragma vertex vert
    17.         #pragma fragment frag
    18.         //#pragma exclude_renderers d3d11 xbox360 ps3 flash d3d11_9x
    19.      
    20.         #include "UnityCG.cginc"
    21.      
    22.         uniform fixed3 unity_FogColor;
    23.         uniform half unity_FogDensity;
    24.         sampler2D _MainTex;
    25.      
    26.         struct vertexInput {
    27.             float4 vertex : POSITION;
    28.             float2 texcoord : TEXCOORD0;
    29.         };
    30.      
    31.         struct v2f {
    32.             float4 scrPos : SV_POSITION;
    33.             half2 srcUVs: TEXCOORD0;
    34.             half2 fogDepth: TEXCOORD1; // linear depth in x and depth multiplied by density in y
    35.         };
    36.      
    37.      
    38.      
    39.         v2f vert (vertexInput v)
    40.         {
    41.             v2f o;
    42.             o.scrPos = mul(UNITY_MATRIX_MVP, v.vertex);
    43.             //o.srcUVs = TRANSFORM_TEX(v.texcoord, _MainTex);
    44.             o.srcUVs = v.texcoord;
    45.          
    46.             o.fogDepth.x = length(mul (UNITY_MATRIX_MV, v.vertex).xyz);
    47.             o.fogDepth.y = o.fogDepth.x * unity_FogDensity;
    48.          
    49.             return o;
    50.         }
    51.      
    52.         fixed4 frag (v2f i) : COLOR
    53.         {
    54.             fixed3 clr = tex2D(_MainTex, i.srcUVs).rgb;
    55.          
    56.             // Exp2 mode:
    57.             float fogAmt = i.fogDepth.y * i.fogDepth.y;
    58.             fogAmt = exp(-fogAmt);
    59.          
    60.             clr = lerp(unity_FogColor, clr, fogAmt);
    61.          
    62.             return fixed4(
    63.                 clr,
    64.                 1.0
    65.             );
    66.         }
    67.         ENDCG
    68.     }
    69. }
    70.  
    71. }
    I need to mention, that unity_FogColor is declared as fixed3, not fixed4. This is done on purpose, to make it slightly more efficient, since this shader is opaque. Keep it in mind if you're going to use it in transparent shader.

    Also, the above trouble is still there. For some reason, the shader fails to compile if I replace the last return statement with:
    Code (CSharp):
    1. return fixed4(
    2.     fogAmt,
    3.     fogAmt,
    4.     fogAmt,
    5.     1.0
    6. );
    So "debug code" (visualising the fog itself) won't work. But the actual code works and it's fine for me.
     
    MR_Fancy_Pants likes this.