Replacement Shader for _CameraNormalsTexture

Hi,

I was wondering, how the internal _CameraNormalsTexture is generated? I was looking for a replacement shader in the builtin shader collection, but coudn’t find it. The closest I found was Hidden/Internal-CombineDepthNormals. However, this shader only uses the _CameraNormalsTexture to pack depth and normals, instead of actually generating the fullscreen normal buffer.

Anyone knows, where to find it?

Thanks,
Martin

Isn’t generated only on lighting prepass in deferred ?

Yes, you are right.

Normals are written in prepassbase directly.
I assumed, the normal buffer was generated using shader replacement.

Thx

If you check the replacement shader examples in unity site, you will see the actual shader is there.

I think, Charkes was right.

The Camera-DepthNormalTexture.shader from the builtin collection generates the _CameraDepthNormalsTexture, which contains view space normals and depth. But I’m interested in world space normals, as they are generated for the _CameraNormalsTexture in deferred path.

I looked at the compiled output of a standard surface shader and to me it seems, normals are written directly inside prepassbase.

v2f_surf vert_surf (appdata_full v) {
  v2f_surf o;
  o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
  o.normal = mul((float3x3)_Object2World, SCALED_NORMAL);
  return o;
}
fixed4 frag_surf (v2f_surf IN) : COLOR {
  Input surfIN;
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  o.Normal = IN.normal;
  surf (surfIN, o);
  fixed4 res;
  res.rgb = o.Normal * 0.5 + 0.5;
  res.a = o.Specular;
  return res;
}

Or am I missing something?

Ok, I took the relevant bits from the compiled shader.

In case anyone needs it. Replacement shader for world space normals in 0-1 range.
Tested in Unity 4 and it gives me the exact same result as the builtin _CameraNormalsTexture in deferred path.

Shader "redPlant/WorldNormal" 
{
  Properties 
  {
    _BumpMap ("Normalmap", 2D) = "bump" {}
  }
  SubShader 
  {
    Tags { "RenderType"="Opaque" }
    Pass {
      
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #include "UnityCG.cginc"

      sampler2D _BumpMap;
      float4 _BumpMap_ST;

      struct v2f 
      {
        float4 pos : SV_POSITION;
        float2 uv : TEXCOORD0;
	      float3 TtoW0 : TEXCOORD1;
	      float3 TtoW1 : TEXCOORD2;
	      float3 TtoW2 : TEXCOORD3;
      };

      v2f vert (appdata_tan v)
      {
        v2f o;
        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
        o.uv = TRANSFORM_TEX (v.texcoord, _BumpMap);

        TANGENT_SPACE_ROTATION;
	      o.TtoW0 = mul(rotation, _Object2World[0].xyz * unity_Scale.w);
	      o.TtoW1 = mul(rotation, _Object2World[1].xyz * unity_Scale.w);
	      o.TtoW2 = mul(rotation, _Object2World[2].xyz * unity_Scale.w);

        return o;
      }

      fixed4 frag (v2f i) : COLOR0
      { 
        fixed3 normal = UnpackNormal(tex2D(_BumpMap, i.uv));
        
	      fixed3 normalWS;
	      normalWS.x = dot(i.TtoW0, normal);
	      normalWS.y = dot(i.TtoW1, normal);
	      normalWS.z = dot(i.TtoW2, normal);
        
        fixed4 color;  
        color.xyz = normalWS * 0.5 + 0.5;
        color.a = 1.0;

        return color; 
      }
      ENDCG
    }
  } 
}