Help: lighting on objects behind my opaque shader gets drawn in front of it

The purpose of this shader is to do a regular Reflective Bumped Diffuse, but then draw some glowing windows over the top of it. The glowing windows have their own RGB color, and I want them to be drawn at a different scale than the Diffuse, Specular, and Normal maps so they don’t repeat visibly.

It got this far along. As you can see, the shader mostly works as intended. There’s only one Subshader and two passes, which I think is pretty good all things considered.

Unfortunately, the shader as written does not display correctly in Deferred Rendering mode, which my game takes advantage of. (I figured out that it was even working at all when I noticed that the texture seemed to work in the Material Preview window, just not in-game.) I tried adding “LightMode” = “ForwardBase” in an attempt to force the shader to use Forward Rendering. (If there’s a more elegant way to do this, let me know.)

Unfortunately, it just doesn’t look right. As you can see from the third screenshot, occluded objects in the distance are visible through the wall. I don’t know how to fix this. I also don’t know the proper way to do what I am trying to do, this is just the closest I’ve been able to get it so far.

Any help would be greatly appreciated. Thanks.

  • There was an issue with the fog being drawn twice, which I fixed by adding Fog { Mode Off } to the start of the second pass.
  • I haven’t figured out what’s causing the extra lighting yet.
  • According to the docs, Unity - Manual: ShaderLab: assigning tags to a Pass , LightMode tags “must” be inside a Pass, not just inside the SubShader. This confuses me, since adding the tag “LightMode” = “ForwardBase” was the only thing that got this thing working in Deferred Lighting mode in the first place. (Presumably by forcing the shader to be drawn with Forward Lighting.) Is there no easier way to force this, per-object?

Managed to get it working!

Shader "Custom/Reflective Bumped Lights" 
{
    Properties 
	{
        _MainTex ("Base (RGB) RefStrength (A)", 2D) = "white" {}
        _Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect }
        _BumpMap ("Normalmap", 2D) = "bump" {}
        _Light ("Light map (RGB)", 2D) = "black" {}
    }
 
    SubShader 
	{
        Tags { "RenderType"="Opaque"}
        LOD 300
                               
        CGPROGRAM
        #pragma surface surf Lambert
 
        sampler2D _MainTex;
        sampler2D _BumpMap;
        sampler2D _Light;
        samplerCUBE _Cube;

		#pragma target 3.0
 
        struct Input 
		{
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float2 uv_Light;
            float3 worldRefl;
            INTERNAL_DATA
        };
 
        void surf (Input IN, inout SurfaceOutput o) 
		{
			// get actual window texture
            fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);

			// get bump mapping
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));

			// get reflection from cubemap
            float3 worldRefl = WorldReflectionVector (IN, o.Normal);
            fixed4 reflcol = texCUBE (_Cube, worldRefl) * tex.a;

			// get the light info
			float4 lightcol = tex2D(_Light, IN.uv_Light);

            o.Albedo = tex.rgb + lightcol.rgb;
            o.Emission = reflcol.rgb + lightcol.rgb;
            o.Alpha = reflcol.a;
        }
        ENDCG
	}
    FallBack "Reflective/Bumped Diffuse"
}

Big thanks to Tenebrous from the Unity IRC channel! He did it a more traditional way, using all one pass, and he used every optimization trick in the book to just barely squeeze it into the instructions limit.

Thanks again! :smile: Best community ever!