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

Global fog and transparent shaders

Discussion in 'Shaders' started by Poupi, Feb 17, 2012.

  1. Poupi

    Poupi

    Joined:
    Jan 11, 2012
    Posts:
    110
    Hi there !

    We're experiencing a strange issue with the Global Fog image effect.



    Top : without global fog, one particle system is rendered with a transparent shader, the other with a basic diffuse shader.
    Bottom : with global fog. The particle system rendered with the transparent shader is hidden by the global fog, despite the position of the emitter.

    Any idea for fixing this ?
     
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Transparent shaders rarely write to the depth buffer, so fog in post process doesn't take their results into account.

    Unfortunately, writing to the depth buffer won't fix this issue, because fog won't be applied properly for the transparent parts of your particles. I'm not sure how this is dealt with.
     
  3. brn

    brn

    Joined:
    Feb 8, 2011
    Posts:
    320
    The issue that you are encountering is as Daniel describes. Its quite an over site of the older Image effect system implementation.

    But the great news is ( I could hug the Devs at unity for doing this) that the Image effects in the latest 3.5 release can now be applied before transparent passes. Even cooler is that they now allow for Max and Min blend modes.

    This means in 3.5 it should be possible to draw your particles after the fog. With a bit of extra work put into your particle shaders you can get them to blend with the fog pretty well. Infact many very cool effects can be done.

    The unity Devs were pretty quiet about this feature, but its huge in my opinion.
     
  4. jdelong

    jdelong

    Joined:
    Jan 1, 2012
    Posts:
    21
    Are you sure? How would you do this? I really want to use the crease image effect as it makes my game look really nice but the fact that it draws over my particles kind of ruins the whole look. I'm basically clueless about shaders.
     
  5. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,878
    thats what the documents say.
     
  6. jdelong

    jdelong

    Joined:
    Jan 1, 2012
    Posts:
    21
    Works beautifully. This is so awesome! Thanks Unity devs, you rock.
     
  7. Xaurrien

    Xaurrien

    Joined:
    Jul 2, 2012
    Posts:
    20
    Hello,

    I don't understand how to add the attribute ImageEffectOpaque to the OnRenderImage function :confused:.

    I have opened the file GlobalFog.js and I have found the OnRenderImage function but if I add the line "@script ImageEffectOpaque" inside the OnRenderImage function, it produces a syntax error. :(

    I have tried to add "@script ImageEffectOpaque" in the beginning of the file GlobalFog.js but all my particles systems and my 3d text meshes are still hidden by the fog. :(

    I think that I don't use the attribute ImageEffectOpaque correctly. Do you know how to use it?
     
  8. GeorgeRigato

    GeorgeRigato

    Joined:
    Jul 5, 2012
    Posts:
    58
    Same problem here. Got no experience with shaders. Anyone got a more detailed solution?

    Gonna try to solve it anyway right now.

    Thanks.
     
  9. ywq

    ywq

    Joined:
    Aug 22, 2012
    Posts:
    15
    here is my modified globalfog.It works transparent objects fine.
    Code (csharp):
    1.  
    2.  
    3.  
    4.  
    5. Shader "Hidden/MyGlobalFogShader" {
    6. Properties {
    7.     _MainTex ("Base (RGB)", 2D) = "black" {}
    8. }
    9.  
    10. CGINCLUDE
    11.  
    12.     #include "UnityCG.cginc"
    13.  
    14.     uniform sampler2D _MainTex;
    15.     uniform sampler2D _CameraDepthTexture;
    16.    
    17.     uniform float _GlobalDensity;
    18.     uniform float4 _FogColor;
    19.     uniform float4 _StartDistance;
    20.     uniform float4 _Y;
    21.     uniform float4 _MainTex_TexelSize;
    22.    
    23.     // for fast world space reconstruction
    24.    
    25.     uniform float4x4 _FrustumCornersWS;
    26.     uniform float4 _CameraWS;
    27.     struct v2f {
    28.         float4 pos : POSITION;
    29.         float2 uv : TEXCOORD0;
    30.         float4 interpolatedRay : TEXCOORD1;
    31.         float2 uv2: TEXCOORD2;
    32.     };
    33.     bool eq(float a,float b)
    34.     {
    35.         return abs(a-b) < 0.01;
    36.     }
    37.     v2f vert( appdata_img v )
    38.     {
    39.         v2f o;
    40.         float xx = v.texcoord.x;
    41.         float yy = v.texcoord.y;
    42.  
    43.         float2 uv = v.texcoord.xy;
    44.         o.uv = uv;
    45.         #if UNITY_UV_STARTS_AT_TOP
    46.         if (_MainTex_TexelSize.y < 0)
    47.         {
    48.             uv.y = 1-uv.y;
    49.         }
    50.         else
    51.         {
    52.             yy = 1 - yy;
    53.         }
    54.         #endif
    55.        
    56.         int index = (int)floor(xx+yy*2 + 0.5);
    57.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    58.        
    59.         o.uv2 = uv;
    60.        
    61.         o.interpolatedRay = _FrustumCornersWS[(int)index];
    62.         o.interpolatedRay.w = index;
    63.        
    64.         return o;
    65.     }
    66.    
    67.     float ComputeFogForYAndDistance (in float3 camDir, in float3 wsPos)
    68.     {
    69.         float fogInt = saturate(length(camDir) * _StartDistance.x-1.0) * _StartDistance.y; 
    70.         float fogVert = max(0.0, (wsPos.y-_Y.x) * _Y.y);
    71.         fogVert *= fogVert;
    72.         return  (1-exp(-_GlobalDensity*fogInt)) * exp (-fogVert);
    73.     }
    74.    
    75.     half4 fragAbsoluteYAndDistance (v2f i) : COLOR
    76.     {
    77.         float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));
    78.         float4 wsDir = dpth * i.interpolatedRay;
    79.         float4 wsPos = _CameraWS + wsDir;
    80.         return lerp(tex2D(_MainTex, i.uv), _FogColor, ComputeFogForYAndDistance(wsDir.xyz,wsPos.xyz));
    81.     }
    82.  
    83.     half4 fragRelativeYAndDistance (v2f i) : COLOR
    84.     {
    85.         float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));
    86.         float4 wsDir = dpth * i.interpolatedRay;
    87.         return lerp(tex2D(_MainTex, i.uv), _FogColor, ComputeFogForYAndDistance(wsDir.xyz, wsDir.xyz));
    88.     }
    89.  
    90.     half4 fragAbsoluteY (v2f i) : COLOR
    91.     {
    92.         float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));
    93.         float4 wsPos = (_CameraWS + dpth * i.interpolatedRay);
    94.         float fogVert = max(0.0, (wsPos.y-_Y.x) * _Y.y);
    95.         fogVert *= fogVert;
    96.         fogVert = (exp (-fogVert));
    97.         return lerp(tex2D( _MainTex, i.uv ), _FogColor, fogVert);              
    98.     }
    99.  
    100.     half4 fragDistance (v2f i) : COLOR
    101.     {
    102.         float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));      
    103.         float4 camDir = ( dpth * i.interpolatedRay);
    104.         float fogInt = saturate(length( camDir ) * _StartDistance.x - 1.0) * _StartDistance.y; 
    105.         return lerp(_FogColor, tex2D(_MainTex, i.uv), exp(-_GlobalDensity*fogInt));            
    106.     }
    107.  
    108. ENDCG
    109.  
    110. SubShader {
    111.     Pass {
    112.         ZTest Always Cull Off ZWrite Off
    113.         Fog { Mode off }
    114.  
    115.         CGPROGRAM
    116.  
    117.         #pragma vertex vert
    118.         #pragma fragment fragAbsoluteYAndDistance
    119.         #pragma fragmentoption ARB_precision_hint_fastest
    120.        
    121.         ENDCG
    122.     }
    123.  
    124.     Pass {
    125.         ZTest Always Cull Off ZWrite Off
    126.         Fog { Mode off }
    127.  
    128.         CGPROGRAM
    129.  
    130.         #pragma vertex vert
    131.         #pragma fragment fragAbsoluteY
    132.         #pragma fragmentoption ARB_precision_hint_fastest
    133.        
    134.         ENDCG
    135.     }
    136.  
    137.     Pass {
    138.         ZTest Always Cull Off ZWrite Off
    139.         Fog { Mode off }
    140.  
    141.         CGPROGRAM
    142.  
    143.         #pragma vertex vert
    144.         #pragma fragment fragDistance
    145.         #pragma fragmentoption ARB_precision_hint_fastest
    146.        
    147.         ENDCG
    148.     }
    149.  
    150.     Pass {
    151.         ZTest Always Cull Off ZWrite Off
    152.         Fog { Mode off }
    153.  
    154.         CGPROGRAM
    155.  
    156.         #pragma vertex vert
    157.         #pragma fragment fragRelativeYAndDistance
    158.         #pragma fragmentoption ARB_precision_hint_fastest
    159.        
    160.         ENDCG
    161.     }
    162. }
    163.  
    164. Fallback off
    165.  
    166. }
    167.  
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. public class MyGlobalFog : MonoBehaviour {
    5.  
    6.     void Start () {
    7.     }
    8.     [ImageEffectOpaque]
    9.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    10.     {
    11.         DrawFog(source, destination);
    12.     }
    13.     //fog script
    14.     public enum FogMode
    15.     {
    16.         AbsoluteYAndDistance = 0,
    17.         AbsoluteY = 1,
    18.         Distance = 2,
    19.         RelativeYAndDistance = 3,
    20.     }
    21.     public bool bEnableFog = true;
    22.     public FogMode fogMode = FogMode.AbsoluteYAndDistance;
    23.  
    24.     private float CAMERA_NEAR = 0.5f;
    25.     private float CAMERA_FAR = 50.0f;
    26.     private float CAMERA_FOV = 60.0f;
    27.     private float CAMERA_ASPECT_RATIO = 1.333333f;
    28.  
    29.     public float startDistance = 200.0f;
    30.     public float globalDensity = 1.0f;
    31.     public float heightScale = 100.0f;
    32.     public float height = 0.0f;
    33.  
    34.     public Color globalFogColor = Color.grey;
    35.  
    36.     public Shader fogShader;
    37.     private Material fogMaterial = null;
    38.  
    39.     void DrawFog(RenderTexture source, RenderTexture destination)
    40.     {
    41.         if (!bEnableFog)
    42.         {
    43.             Graphics.Blit(source, destination);
    44.             return;
    45.         }
    46.         if (fogMaterial == null)
    47.         {
    48.             fogMaterial = new Material(fogShader);
    49.         }
    50.         CAMERA_NEAR = camera.nearClipPlane;
    51.         CAMERA_FAR = camera.farClipPlane;
    52.         CAMERA_FOV = camera.fieldOfView;
    53.         CAMERA_ASPECT_RATIO = camera.aspect;
    54.  
    55.         Matrix4x4 frustumCorners = Matrix4x4.identity;
    56.         //Vector4 vec;
    57.         //Vector3 corner;
    58.  
    59.         float fovWHalf = CAMERA_FOV * 0.5f;
    60.  
    61.         Vector3 toRight = camera.transform.right * CAMERA_NEAR * Mathf.Tan(fovWHalf * Mathf.Deg2Rad) * CAMERA_ASPECT_RATIO;
    62.         Vector3 toTop = camera.transform.up * CAMERA_NEAR * Mathf.Tan(fovWHalf * Mathf.Deg2Rad);
    63.  
    64.         Vector3 topLeft = (camera.transform.forward * CAMERA_NEAR - toRight + toTop);
    65.         float CAMERA_SCALE = topLeft.magnitude * CAMERA_FAR / CAMERA_NEAR;
    66.  
    67.         topLeft.Normalize();
    68.         topLeft *= CAMERA_SCALE;
    69.  
    70.         Vector3 topRight = (camera.transform.forward * CAMERA_NEAR + toRight + toTop);
    71.         topRight.Normalize();
    72.         topRight *= CAMERA_SCALE;
    73.  
    74.         Vector3 bottomRight = (camera.transform.forward * CAMERA_NEAR + toRight - toTop);
    75.         bottomRight.Normalize();
    76.         bottomRight *= CAMERA_SCALE;
    77.  
    78.         Vector3 bottomLeft = (camera.transform.forward * CAMERA_NEAR - toRight - toTop);
    79.         bottomLeft.Normalize();
    80.         bottomLeft *= CAMERA_SCALE;
    81.  
    82.         frustumCorners.SetRow(0, topLeft);
    83.         frustumCorners.SetRow(1, topRight);
    84.         frustumCorners.SetRow(2, bottomRight);
    85.         frustumCorners.SetRow(3, bottomLeft);
    86.  
    87.         fogMaterial.SetMatrix("_FrustumCornersWS", frustumCorners);
    88.         fogMaterial.SetVector("_CameraWS", camera.transform.position);
    89.         fogMaterial.SetVector("_StartDistance", new Vector4(1.0f / startDistance, (CAMERA_SCALE - startDistance)));
    90.         fogMaterial.SetVector("_Y", new Vector4(height, 1.0f / heightScale));
    91.  
    92.         fogMaterial.SetFloat("_GlobalDensity", globalDensity * 0.01f);
    93.         fogMaterial.SetColor("_FogColor", globalFogColor);
    94.         CustomGraphicsBlit(source, destination, fogMaterial, (int)fogMode);
    95.     }
    96.  
    97.     static void CustomGraphicsBlit(RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
    98.     {
    99.         Graphics.Blit(source, dest, fxMaterial, passNr);
    100.         /*
    101.         RenderTexture.active = dest;
    102.  
    103.         fxMaterial.SetTexture("_MainTex", source);
    104.  
    105.         GL.PushMatrix();
    106.         GL.LoadOrtho();
    107.  
    108.         fxMaterial.SetPass(passNr);
    109.  
    110.         GL.Begin(GL.QUADS);
    111.  
    112.         GL.MultiTexCoord2(0, 0.0f, 0.0f);
    113.         GL.Vertex3(0.0f, 0.0f, 3.0f); // BL
    114.  
    115.         GL.MultiTexCoord2(0, 1.0f, 0.0f);
    116.         GL.Vertex3(1.0f, 0.0f, 2.0f); // BR
    117.  
    118.         GL.MultiTexCoord2(0, 1.0f, 1.0f);
    119.         GL.Vertex3(1.0f, 1.0f, 1.0f); // TR
    120.  
    121.         GL.MultiTexCoord2(0, 0.0f, 1.0f);
    122.         GL.Vertex3(0.0f, 1.0f, 0.0f); // TL
    123.  
    124.         GL.End();
    125.         GL.PopMatrix();
    126.         */
    127.     }
    128. }
    129.  
    130.  
    131.  
    132.  
    133.  
     
    Last edited: Oct 14, 2013
    AnomalusUndrdog likes this.
  10. Bren

    Bren

    Joined:
    Aug 28, 2008
    Posts:
    191
    This solution doesn't seem to work at all for me in either 3 or 4. No fog. :confused:

    Too bad, because it looked so promising! Does it work for anyone else? Any ideas why?
     
  11. turi

    turi

    Joined:
    Dec 11, 2008
    Posts:
    22
    Hi Bren,
    just write @ImageEffectOpaque in the line just before the function OnRenderImage of the GlobalFog.js script. It should work. Also take a look at the EdgeDetectEffectNormals.js script , @ImageEffectOpaque is present there in the right location.

    Turi
     
    Recluse likes this.
  12. Vijay-Poduval

    Vijay-Poduval

    Joined:
    May 30, 2013
    Posts:
    2
    Thanks. That worked !!!
     
  13. bobbyhutson

    bobbyhutson

    Joined:
    Apr 8, 2013
    Posts:
    1
    make sure its the global fog shader file and not the js file you are editing, I just got it to work but made this mistake at first. I just copied and pasted the sample provided in this thread over the original in monodevelop.
     
  14. sgoodrow

    sgoodrow

    Joined:
    Sep 28, 2012
    Posts:
    150
    Does anyone know what was meant by this, or have any ideas about this? I am somewhat savvy with shaders, but am pretty new to particle effects. What is the idea behind this?
     
  15. gian-reto-alig

    gian-reto-alig

    Joined:
    Apr 30, 2013
    Posts:
    756
    I also try to find a fix for this GlobalFog Problem. I actually managed to make my particle Effects irgnore the GlobalFog by adding the attribute to the js OnRender Function:

    Code (csharp):
    1.  
    2.         @ImageEffectOpaque
    3.     function OnRenderImage (source : RenderTexture, destination : RenderTexture) { 
    4.  
    But now I have an unwanted side effect: all particle effects seem to ignore opaque geometry now... they are always drawn on top.

    All I do is comment / uncomment the @ImageEffectOpaque attribute in the GlobalFog.js file to make it appear / disappear.

    Anyone got an idea what is going on here?


    Thanks

    Gian-Reto
     
  16. stevesan

    stevesan

    Joined:
    Aug 14, 2011
    Posts:
    65
    Having the exact same problem. Same with transparent geometry, such as glass windows. It seems like @ImageEffectOpaque attrib causes it to clear the depth buffer, thus allowing trans geom to draw over opaque stuff it's not supposed to?
     
  17. stevesan

    stevesan

    Joined:
    Aug 14, 2011
    Posts:
    65
    Ah, I fixed the issues using @ywq's modifications. Mainly, add @ImageEffectOpaque (makes it render fog before transparent things), and also very important is his mod to the CustomGraphicsBlit function - or rather, do NOT use that. I think using Graphics.Blit properly copies over the depth buffer, thus avoiding the issue of transparent stuff drawing over everything. This should solve @gian-reto alig's problem.
     
  18. Bidds

    Bidds

    Joined:
    Jul 31, 2013
    Posts:
    9
    @ywq,

    Your reworked version did solve my sorting issue, however, with your code, the fog is not drawn correctly when the camera is rolled (rotated along its Z axis). Here are some shots to illustrate...

    When the camera is not rotated, the fog is drawn correctly.
    $screenshot2.png

    Here the camera is rotated along its Z Axis. Note the fog is drawn on the right hand side of the screen, not aligned with the horizon.
    $screenshot3.png

    Do you (or does anyone else) have any suggestions on how to get this fog script to align with the horizon?

    Cheers!
     
    Last edited: Jan 22, 2014
  19. Bidds

    Bidds

    Joined:
    Jul 31, 2013
    Posts:
    9
    Hi all,

    I've actually managed to fix this after being pointed in the right direction by a helpful soul on Twitter. The issue was quite simple in the end; the bottom two frustum corners in ywq's script were reversed. Swapping these back around solved the rotation issue.

    Since I also had to exclude the Flash renderer to get it to work without errors, here are my two modified versions of ywq's scripts. They work 100% perfectly for me. :)

    AlphaSortedGlobalFog.shader
    Code (csharp):
    1.     Shader "Hidden/AlphaSortedGlobalFog" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "black" {}
    4.     }
    5.      
    6.     CGINCLUDE
    7.      
    8.         #include "UnityCG.cginc"
    9.         #pragma exclude_renderers flash
    10.      
    11.         uniform sampler2D _MainTex;
    12.         uniform sampler2D _CameraDepthTexture;
    13.        
    14.         uniform float _GlobalDensity;
    15.         uniform float4 _FogColor;
    16.         uniform float4 _StartDistance;
    17.         uniform float4 _Y;
    18.         uniform float4 _MainTex_TexelSize;
    19.        
    20.         // for fast world space reconstruction
    21.         uniform float4x4 _FrustumCornersWS;
    22.         uniform float4 _CameraWS;
    23.         struct v2f {
    24.             float4 pos : POSITION;
    25.             float2 uv : TEXCOORD0;
    26.             float4 interpolatedRay : TEXCOORD1;
    27.             float2 uv2: TEXCOORD2;
    28.         };
    29.         bool eq(float a,float b)
    30.         {
    31.             return abs(a-b) < 0.01;
    32.         }
    33.         v2f vert( appdata_img v )
    34.         {
    35.             v2f o;
    36.             float xx = v.texcoord.x;
    37.             float yy = v.texcoord.y;
    38.      
    39.             float2 uv = v.texcoord.xy;
    40.             o.uv = uv;
    41.             #if UNITY_UV_STARTS_AT_TOP
    42.             if (_MainTex_TexelSize.y < 0)
    43.             {
    44.                 uv.y = 1-uv.y;
    45.             }
    46.             else
    47.             {
    48.                 yy = 1 - yy;
    49.             }
    50.             #endif
    51.            
    52.             int index = (int)floor(xx+yy*2 + 0.5);
    53.             o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    54.            
    55.             o.uv2 = uv;
    56.            
    57.             o.interpolatedRay = _FrustumCornersWS[(int)index];
    58.             o.interpolatedRay.w = index;
    59.            
    60.             return o;
    61.         }
    62.        
    63.         float ComputeFogForYAndDistance (in float3 camDir, in float3 wsPos)
    64.         {
    65.             float fogInt = saturate(length(camDir) * _StartDistance.x-1.0) * _StartDistance.y;
    66.             float fogVert = max(0.0, (wsPos.y-_Y.x) * _Y.y);
    67.             fogVert *= fogVert;
    68.             return  (1-exp(-_GlobalDensity*fogInt)) * exp (-fogVert);
    69.         }
    70.        
    71.         half4 fragAbsoluteYAndDistance (v2f i) : COLOR
    72.         {
    73.             float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));
    74.             float4 wsDir = dpth * i.interpolatedRay;
    75.             float4 wsPos = _CameraWS + wsDir;
    76.             return lerp(tex2D(_MainTex, i.uv), _FogColor, ComputeFogForYAndDistance(wsDir.xyz,wsPos.xyz));
    77.         }
    78.      
    79.         half4 fragRelativeYAndDistance (v2f i) : COLOR
    80.         {
    81.             float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));
    82.             float4 wsDir = dpth * i.interpolatedRay;
    83.             return lerp(tex2D(_MainTex, i.uv), _FogColor, ComputeFogForYAndDistance(wsDir.xyz, wsDir.xyz));
    84.         }
    85.      
    86.         half4 fragAbsoluteY (v2f i) : COLOR
    87.         {
    88.             float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));
    89.             float4 wsPos = (_CameraWS + dpth * i.interpolatedRay);
    90.             float fogVert = max(0.0, (wsPos.y-_Y.x) * _Y.y);
    91.             fogVert *= fogVert;
    92.             fogVert = (exp (-fogVert));
    93.             return lerp(tex2D( _MainTex, i.uv ), _FogColor, fogVert);              
    94.         }
    95.      
    96.         half4 fragDistance (v2f i) : COLOR
    97.         {
    98.             float dpth = Linear01Depth(UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv2)));      
    99.             float4 camDir = ( dpth * i.interpolatedRay);
    100.             float fogInt = saturate(length( camDir ) * _StartDistance.x - 1.0) * _StartDistance.y;
    101.             return lerp(_FogColor, tex2D(_MainTex, i.uv), exp(-_GlobalDensity*fogInt));            
    102.         }
    103.      
    104.     ENDCG
    105.      
    106.     SubShader {
    107.         Pass {
    108.             ZTest Always Cull Off ZWrite Off
    109.             Fog { Mode off }
    110.      
    111.             CGPROGRAM
    112.      
    113.             #pragma vertex vert
    114.             #pragma fragment fragAbsoluteYAndDistance
    115.             #pragma fragmentoption ARB_precision_hint_fastest
    116.            
    117.             ENDCG
    118.         }
    119.      
    120.         Pass {
    121.             ZTest Always Cull Off ZWrite Off
    122.             Fog { Mode off }
    123.      
    124.             CGPROGRAM
    125.      
    126.             #pragma vertex vert
    127.             #pragma fragment fragAbsoluteY
    128.             #pragma fragmentoption ARB_precision_hint_fastest
    129.            
    130.             ENDCG
    131.         }
    132.      
    133.         Pass {
    134.             ZTest Always Cull Off ZWrite Off
    135.             Fog { Mode off }
    136.      
    137.             CGPROGRAM
    138.      
    139.             #pragma vertex vert
    140.             #pragma fragment fragDistance
    141.             #pragma fragmentoption ARB_precision_hint_fastest
    142.            
    143.             ENDCG
    144.         }
    145.      
    146.         Pass {
    147.             ZTest Always Cull Off ZWrite Off
    148.             Fog { Mode off }
    149.      
    150.             CGPROGRAM
    151.      
    152.             #pragma vertex vert
    153.             #pragma fragment fragRelativeYAndDistance
    154.             #pragma fragmentoption ARB_precision_hint_fastest
    155.            
    156.             ENDCG
    157.         }
    158.     }
    159.      
    160.     Fallback off
    161.      
    162.     }
    AlphaSortedGlobalFog.cs
    Code (csharp):
    1.     using UnityEngine;
    2.     using System.Collections;
    3.     [ExecuteInEditMode]
    4.     [AddComponentMenu("Image Effects/Fog/AlphaSortedGlobalFog")]
    5.  
    6.     public class AlphaSortedGlobalFog : MonoBehaviour {
    7.      
    8.         void Start () {
    9.         }
    10.         [ImageEffectOpaque]
    11.         void OnRenderImage(RenderTexture source, RenderTexture destination)
    12.         {
    13.             DrawFog(source, destination);
    14.         }
    15.         //fog script
    16.         public enum FogMode
    17.         {
    18.             AbsoluteYAndDistance = 0,
    19.             AbsoluteY = 1,
    20.             Distance = 2,
    21.             RelativeYAndDistance = 3,
    22.         }
    23.         public bool bEnableFog = true;
    24.         public FogMode fogMode = FogMode.AbsoluteYAndDistance;
    25.      
    26.         private float CAMERA_NEAR = 0.5f;
    27.         private float CAMERA_FAR = 50.0f;
    28.         private float CAMERA_FOV = 60.0f;
    29.         private float CAMERA_ASPECT_RATIO = 1.333333f;
    30.      
    31.         public float startDistance = 200.0f;
    32.         public float globalDensity = 1.0f;
    33.         public float heightScale = 100.0f;
    34.         public float height = 0.0f;
    35.      
    36.         public Color globalFogColor = Color.grey;
    37.      
    38.         public Shader fogShader;
    39.         private Material fogMaterial = null;
    40.      
    41.         void DrawFog(RenderTexture source, RenderTexture destination)
    42.         {
    43.             if (!bEnableFog)
    44.             {
    45.                 Graphics.Blit(source, destination);
    46.                 return;
    47.             }
    48.             if (fogMaterial == null)
    49.             {
    50.                 fogMaterial = new Material(fogShader);
    51.             }
    52.             CAMERA_NEAR = camera.nearClipPlane;
    53.             CAMERA_FAR = camera.farClipPlane;
    54.             CAMERA_FOV = camera.fieldOfView;
    55.             CAMERA_ASPECT_RATIO = camera.aspect;
    56.      
    57.             Matrix4x4 frustumCorners = Matrix4x4.identity;
    58.             //Vector4 vec;
    59.             //Vector3 corner;
    60.      
    61.             float fovWHalf = CAMERA_FOV * 0.5f;
    62.      
    63.             Vector3 toRight = camera.transform.right * CAMERA_NEAR * Mathf.Tan(fovWHalf * Mathf.Deg2Rad) * CAMERA_ASPECT_RATIO;
    64.             Vector3 toTop = camera.transform.up * CAMERA_NEAR * Mathf.Tan(fovWHalf * Mathf.Deg2Rad);
    65.      
    66.             Vector3 topLeft = (camera.transform.forward * CAMERA_NEAR - toRight + toTop);
    67.             float CAMERA_SCALE = topLeft.magnitude * CAMERA_FAR / CAMERA_NEAR;
    68.      
    69.             topLeft.Normalize();
    70.             topLeft *= CAMERA_SCALE;
    71.      
    72.             Vector3 topRight = (camera.transform.forward * CAMERA_NEAR + toRight + toTop);
    73.             topRight.Normalize();
    74.             topRight *= CAMERA_SCALE;
    75.      
    76.             Vector3 bottomRight = (camera.transform.forward * CAMERA_NEAR + toRight - toTop);
    77.             bottomRight.Normalize();
    78.             bottomRight *= CAMERA_SCALE;
    79.      
    80.             Vector3 bottomLeft = (camera.transform.forward * CAMERA_NEAR - toRight - toTop);
    81.             bottomLeft.Normalize();
    82.             bottomLeft *= CAMERA_SCALE;
    83.        
    84.             frustumCorners.SetRow(0, topLeft);
    85.             frustumCorners.SetRow(1, topRight);
    86.             frustumCorners.SetRow(2, bottomLeft);
    87.             frustumCorners.SetRow(3, bottomRight);
    88.      
    89.             fogMaterial.SetMatrix("_FrustumCornersWS", frustumCorners);
    90.             fogMaterial.SetVector("_CameraWS", camera.transform.position);
    91.             fogMaterial.SetVector("_StartDistance", new Vector4(1.0f / startDistance, (CAMERA_SCALE - startDistance)));
    92.             fogMaterial.SetVector("_Y", new Vector4(height, 1.0f / heightScale));
    93.      
    94.             fogMaterial.SetFloat("_GlobalDensity", globalDensity * 0.01f);
    95.             fogMaterial.SetColor("_FogColor", globalFogColor);
    96.             CustomGraphicsBlit(source, destination, fogMaterial, (int)fogMode);
    97.         }
    98.      
    99.         static void CustomGraphicsBlit(RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
    100.         {
    101.             Graphics.Blit(source, dest, fxMaterial, passNr);
    102.         }
    103.     }
    Thanks again to ywq for fixing the fog in the first place!

    Bidds
     
    twobob likes this.
  20. sgoodrow

    sgoodrow

    Joined:
    Sep 28, 2012
    Posts:
    150
    Having done all of this, how do you guys go about fading your particles/transparent materials?
     
    CathChapo101 likes this.
  21. Stephan-Tanguay

    Stephan-Tanguay

    Joined:
    Jan 27, 2011
    Posts:
    21
    Tried out the above script, the Y position moves with the camera, in the script Unity provides y is a gobal position and does not move with the camera. Any way to fix this, or anyone else have this issue.
     
  22. vOwl

    vOwl

    Joined:
    Jul 6, 2013
    Posts:
    8
    I tried the "AlphaSortedGlobalFog" Script+Shader on my Oculus Rift projekt. Using on one camera the effect works fine, but after activating the script on the second camera (eye) the effect completly disappears.
    any ideas?
     
  23. Charles-Van-Norman

    Charles-Van-Norman

    Joined:
    Aug 10, 2010
    Posts:
    86
    I'm having a different but similar issue -- GlobalFog overwrites the outline in Toony/BasicOutline.shader. I've tried doing the render opaque thing, and also Tags {"Queue" = "Overlay" } for the outline shader with Tags {"Queue" = "Background" } for the fog shader, nothing seems to work -- the outlines are still overwritten by the fog.

    Help! How can I use global fog, but still have clear black outlines against it?
     
  24. Acreates

    Acreates

    Joined:
    Dec 12, 2016
    Posts:
    41
    This is still occurring in the latest Unity as of 10/01/2018. Any particle with alpha that is activated at about 200meters away from the camera while Global Fog is on will not appear. Hopefully someone at Unity can fix this asap.