Custom vertex shader doesn't write to camera depth normals texture.

I’m attempting to write a custom vertex shader, but I’m finding that unlike the standard shader, my shader does not write to the camera depth normals texture. (UpdateDepthNormalsTexture step in the frame debugger)

It is my understanding that the UpdateDepthNormalsTexture works using a built-in replacement shader called “Hidden/Internal-DepthNormalsTexture”
Looking at that built-in shader I see that it has a subshader with Tags { “RenderType”=“Opaque” }
My subshader has the same RenderType, so I would expect it to work with the replacement shader.

The DepthNormalsTexture is used by the SSAO script so the SSAO ends up ignoring objects in front of the camera using my custom shader.

My question is, how can I get my custom shader to render to the depth normals texture?


Shader "Custom/WrappedDiffuse" {

	Properties {
		_Tint ("Tint", Color) = (1, 1, 1, 1)
		_MainTex ("Texture", 2D) = "white" {}
		_WrapTex("Wrap Texture", 2D) = "white" {}
		_WrapShift("Wrap Shift", Range(-1, 1)) = 0
		_BumpMap("Normals", 2D) = "bump" {}
		_BumpScale("Bump Scale", Float) = 1

	SubShader {

		Pass {
			Tags {
				"RenderType" = "Opaque"
				"Queue" = "Geometry"
				"LightMode" = "ForwardBase"


			#pragma vertex MyVertexProgram
			#pragma fragment MyFragmentProgram

			#include "UnityPBSLighting.cginc"

			float4 _Tint;
			float _BumpScale;
			sampler2D _MainTex;
			sampler2D _WrapTex;
			float _WrapShift;
			sampler2D _BumpMap;
			float4 _MainTex_ST;

			struct VertexData {
				float4 position : POSITION;
				float3 normal : NORMAL;
				float2 uv : TEXCOORD0;

			struct Interpolators {
				float4 position : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 normal : TEXCOORD1;

			Interpolators MyVertexProgram (VertexData v) {
				Interpolators i;
				i.position = mul(UNITY_MATRIX_MVP, v.position);
				i.normal = UnityObjectToWorldNormal(v.normal);
				i.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return i;

			float3 InitializeFragmentNormal(inout Interpolators i) {
				float3 texNormal;
				texNormal.xy = tex2D(_BumpMap, i.uv).wy * 2 - 1;
				texNormal.xy *= _BumpScale;
				texNormal.z = sqrt(1 - saturate(dot(texNormal.xy, texNormal.xy)));
				texNormal = UnpackScaleNormal(tex2D(_BumpMap, i.uv), _BumpScale);
				texNormal = texNormal.xzy;
				texNormal = normalize(texNormal);
				return texNormal;

			float4 MyFragmentProgram (Interpolators i) : SV_TARGET {
				i.normal = i.normal + InitializeFragmentNormal(i);
				float3 lightDir =;
				float3 lightColor = _LightColor0.rgb;
				float3 albedo = tex2D(_MainTex, i.uv).rgb * _Tint.rgb;
				float dotProd = dot(lightDir, i.normal);
				dotProd = (dotProd + 1) / 2;
					dotProd += _WrapShift;
					dotProd = max(0.05, dotProd);
					dotProd = min(0.95, dotProd);
				float2 wrapPosition = float2(dotProd, 0);
				float3 wrap = tex2D(_WrapTex, wrapPosition).rgb;
				float3 diffuse =
					albedo * lightColor * wrap;
				return float4(diffuse, 1);
	Fallback "Diffuse"

It seems that as of Unity 5.5, when using a replacement shader you not only need a subshader with a matching RenderType, the material the shader is applied to also has to have a RenderType tag set to the proper value.
To do this, go to a material in the inspector and change the inspector to “Debug” mode. Each material will have a “String Tag Map” list that allows you to specify a set of key value pairs for the material.
Add a tag with the key “RenderType” and the value “Opaque” or whatever RebderType your shader is meant for. The material should now work properly with replacement shaders like the one used to render the depth-normals texture.

If you don’t want to have to do this for every material that uses your shader, you can write a custom view for your shader that sets the RenderType automatically.
If you look at the editor for the standard shader you’ll notice at the top a “Rendering Mode” drop-down menu. This drop-down adds and removes tags from the String Tag Map for you and has a default value. Your custom view could work like that.