Reputation: 33
I'm new to shader coding in Unity (and indeed shaders in general). I've recently been trying to create a basic fog effect by sampling the depth texture and using that to mix between the rendered view and a constant colour, however I'm having trouble getting the information from the depth texture.
From what I understand, the following code should simply display the depth texture in screen space on whatever object has this material applied, however my test object simply shows unshaded flat grey. I've done a couple other tests too and what I think is happening is that when I try to sample from the depth texture, it always returns a fixed4 of 0.5s but I don't understand why.
I know I'm probably making some hilarious noob error here, but I am a noob so any help would be appreciated. Thanks
Shader "Hidden/Atmosphere"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Scale ("Scale", float) = 1
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
GrabPass{"_Post"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 ScreenPos : TEXCOORD0;
float4 vertex : SV_POSITION;
};
float _Scale;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.ScreenPos = ComputeScreenPos(o.vertex);
return o;
}
sampler2D _Post;
sampler2D _CameraDepthTexture;
fixed4 frag (v2f i) : SV_Target
{
float2 ScreenspaceUV = i.ScreenPos.xy/ i.ScreenPos.w;
//fixed4 col = tex2D(_Post, ScreenspaceUV);
fixed4 col = tex2D(_CameraDepthTexture, ScreenspaceUV);
//col = fixed4(i.ScreenPos.x/i.ScreenPos.w, i.ScreenPos.y/i.ScreenPos.w, 0, 1);
//col.rgb = 1 - col.rgb;
return col;
}
ENDCG
}
}
}
Upvotes: 1
Views: 9268
Reputation: 11
I was trying to achieve the exact same effect and I was having the exact same issue.
First step is to set the main camera depthTextureMode to DepthTextureMode.Depth. To do so, write in the Awake method of your script the following code:
if(Camera.main.depthTextureMode != DepthTextureMode.Depth)
Camera.main.depthTextureMode = DepthTextureMode.Depth;
Now if you hit play, the objects that use your custom shader will not appear in the camera. It turns out that if you are using custom shaders you have to define an additional ShadowCaster pass to write into that depthTexture.
Second step is to add this pass into your custom shader as a seperate Pass (!!not the shader that you are using for rendering the fog. The one that the objects in scene use!!).
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
Fog {Mode Off}
ZWrite On ZTest LEqual Cull Off
Offset 1, 1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
};
v2f vert( appdata_base v )
{
v2f o;
TRANSFER_SHADOW_CASTER(o)
return o;
}
float4 frag( v2f i ) : SV_Target
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
And you should be good to go.
!!And an important notice!! if your shader's render queue is above 2500 the object will not affect the depthTexture so you won't see it!!
https://forum.unity.com/threads/custom-shader-not-writing-to-depth-buffer.1048934/ https://forum.unity.com/threads/multiple-cameras-depth-buffer-incorrect-in-shader.763802/
Upvotes: 1