Unexpected "NdotL" shader behavior - light cutoff

I’m trying to build a BRDF shader, and I’m starting with something very basic - simply mapping NdotL to the RGB in the lighting function. However, when I do this, materials with the shader show a fullbright area and then an immediate sharp transition to full dark, instead of the smooth gradient one would expect.

Worse, the fullbright area doesn’t always correspond to the position of the light - it seems semi-random. I suspect this to be some kind of Unity bug because if I select an object that causes a GUI overlay to appear in the editor window, then the shader appears as it should for a brief moment, but returns to the broken version as soon as I mouse over the editor window.

Code below, and screenshots of the broken version and the way it looks when I get the editor to display it correctly.

Anyone have any ideas?

Thanks.

Shader "CookbookShaders/BRDF" {
	Properties {
		_EmissiveColor ("Emissive", color) = (1,1,1,1)
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Ramp
		#pragma target 3.0

		float4 _EmissiveColor;
		
		struct Input {
			float2 uv_MainTex;
			 
		};
		
		half4 LightingRamp(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
		{
			float NdotL = dot(s.Normal, lightDir);
			float NdotE = dot(s.Normal, viewDir);
						
			float4 c;
			c.rgb = float3(NdotL,NdotL,NdotL);
			c.a = s.Alpha;
			
			return c;
		}

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = _EmissiveColor; //float4(.5,.5,.5,1);//tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

The shader when malfunctioning:

The shader when I can trick Unity into displaying it correctly for half a second:

Unity’s forward renderer only handles one directional real-time light in the first pass. All per-pixel point and spot lights are rendered using additional passes. If you don’t have a directional light in your scene, Unity still runs the first pass because it does all sorts of things in addition to that directional light. The way it takes the directional light out, though, is by setting its colour to black.

As written, your shader doesn’t take light colour (_LightColor0.rgb) into account, so it renders white lights instead of whatever colour your light is. In the case of the non-existent directional light, it renders white instead of black.

The seemingly arbitrary direction you’re getting is just that: Unity doesn’t bother filling in proper light information because it assumes that you’re going to multiply the result by black anyway.

Additionally, if you’re following the instructions I think you are then you should just go to this thread and take my version from the end. I’ll be happy to answer any questions about that version in that thread.

Wow, great information - thanks so much for taking the time. I’ll definitely head on over to that other thread. Thanks again!