1
\$\begingroup\$

I am trying to build an infinite fog shader. This fog is applied on a 3D plane.
For the moment I have a Z-Depth Fog. And I encounter some issues.

As you can see in the screenshot, there are two views.
The green color is my 3D plane. The problem is in the red line. It seems that the this line depends of my camera which is not good because when I rotate my camera the line is affected by my camera position and rotation.

enter image description here

I don't know where does it comes from and how to have my fog limit not based on the camera position.

Shader

Pass {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform float4      _FogColor;
            uniform sampler2D   _CameraDepthTexture;
            float               _Depth;
            float               _DepthScale;

            struct v2f {
                float4 pos : SV_POSITION;
                float4 projection : TEXCOORD0;
                float4 screenPosition : TEXCOORD1;
            };

            v2f vert(appdata_base v) {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.projection = ComputeGrabScreenPos(o.pos);
                o.screenPosition = ComputeScreenPos(o.pos);
                return o;
            }
            sampler2D _GrabTexture;

            float4 frag(v2f IN) : COLOR {
                float3 uv = UNITY_PROJ_COORD(IN.projection);
                float depth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, uv));
                depth = LinearEyeDepth(depth);
                return saturate((depth - IN.screenPosition.w + _Depth) * _DepthScale);
            }
        ENDCG
    }


Next I want to rotate my Fog to have an Y-Depth Fog but I don't know how to achieve this effect.


It seems that this is caused by _CameraDepthTexture, that's why depth is calculated with the camera position.
But I don't know how to correct it... It seems that there is no way to get the depth from another point. Any idea ?

Here is another example. In green You can "see" the object and the blue line is for me the fog as it should be.

enter image description here

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Well this can't be solved in a single rendering pass, you need to render your scene from another point of view (different camera) to a separate off-screen render buffer in a different pass and then convert this buffer into a texture and bind it to _CameraDepthTexture.

I don't know how this is done in unity, but practically speaking, you should create a new camera that renders to an off-screen buffer, separately from your main camera point of view, this will let you render the scene twice; once from each camera, the new depth camera will render the scene into the off-screen buffer, the main camera will then render to main frame buffer and use the off-screen buffer as a texture for the plane.

The new camera position might "follow" some constraint depending on how you want the fog to look like, (e.g. its position might be aligned to the world z-axis or perpendicular on some plane. which is something not very clear in the example)

\$\endgroup\$
3
  • \$\begingroup\$ Ok, thanks a lot for your answer, I was wondering if a new camera was necessary but it seems that it is... I thought that if I played with some matrix in the shader to change the point of view of the position it would work. \$\endgroup\$
    – MaT
    Jun 19, 2013 at 11:31
  • \$\begingroup\$ this has to do of how the rendering pipeline works in order to reach your fragment shader stage and apply your texture, the depth buffer should have been already calculated/rendered, hence you will need a separate rendering pass. \$\endgroup\$
    – concept3d
    Jun 19, 2013 at 11:53
  • \$\begingroup\$ Ok, I will try with another camera. \$\endgroup\$
    – MaT
    Jun 19, 2013 at 13:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .