Problem with BRDF Shader

Hi !
I wanted to make a BRDF shader but i ran into trouble .
Used tihs tutorial to make the shader : http://www.youtube.com/watch?v=_Y_0cgWu5bQ
I wrote everything right in the shader but i get a error : Program ‘SurfShaderInternalFunc’, expression left of . “Normal” is not a struct or array at line 30 .
And i can’t understand what is causing this error .

Here is the shader :

Shader "CTD/DemoBRDF" 
{
	Properties 
    {
		_MainTex ("Base (RGB)", 2D) = "white" {}
        _Ramp2D ("BRDF Ramp", 2D) = "gray" {}
	}


	SubShader 
    {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Ramp
        #pragma target 3.0

		sampler2D _MainTex;
        sampler2D _Ramp2D;

		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.Nornal, viewDir);

               //do diffuse wrap here
               float diff = (NdotL * 0.3) + 0.5;
               float2 brdfUV = float2(NdotE * .8, diff);
               float3 BRDF = tex2D(_Ramp2D, brdfUV.xy).rgb;

               float4 c;
               c.rgb = BRDF;//float3(diff,diff,diff);
               c.a = s.Alpha;
               return c;
         }

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

Line 30says Nornal, not Normal.

1 Like

Oooh …
This was a really noobish problem :smile:
Thanks anyway :slight_smile:

if you clamp your “BRDF Ramp” texture maps you can change.

float diff = (NdotL * 0.3) + 0.5;

float2 brdfUV = float2(NdotE * .8, diff)

to

float diff = (NdotL * 0.5) + 0.5;

float2 brdfUV = float2(NdotE, diff)

That will allow you to use the whole texture map.

I’m fairly new to shaders and am using the same tutorial. I have the shader working as scripted, but like it to display the actual texture of the object with the lighting effect. I have the texture assigned to the _MainTex in the inspector, but the mesh displays as white with the lighting effect.

Sounds like your are missing an actual assignment of that texture sample to the albedo output.
Since we cannot ask our spirits for clairvoyance you should post your code in here to get it fixed.

K, I did the same tutorial, and the code is the same as above, minus the error. What I think might be happening is that the Ramp2D texture is either the only texture displaying or is displaying over the MainTexture.
Thanks

I re-wrote this shader because it had a number of issues. In addition to some clearer names for almost everything, this version:

  • Takes albedo from the base texture into account
  • Takes light colour and attenuation into account
  • Uses the full range of the lookup texture, as pointed out by WDC Studios (remember to set your lookup texture WrapModes to Clamp)
  • Doesn’t require Shader Model 3.0 (wasn’t actually necessary before)

I think it’s worth noting that although the lookup texture encodes a type of BRDF, it can only express very simple functions that vary exclusively by N•L and N•V. A full BRDF is a four-dimensional function, whereas this shader only uses two. The important characteristic of this shader is that it allows you to paint a lookup texture rather than having to define lighting entirely analytically. This means you can mess about a lot more than with traditional lighting models, although it’s easy to get ridiculous results. Sorry for your broken references, but I feel this is kind of important.

Shader "2D Lookup Lighting" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Lookup ("Lookup", 2D) = "gray" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

		CGPROGRAM
			#pragma surface surf Lookup

			sampler2D _MainTex;
			sampler2D _Lookup;
			
			struct Input 
			{
				float2 uv_MainTex;
			};
			
			half4 LightingLookup (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
			{
				float NdotL = dot(s.Normal, lightDir);
				float NdotV = dot(s.Normal, viewDir);
				
				float2 lookupUV = float2(NdotV, NdotL * 0.5 + 0.5);
				float3 exitRadiance = tex2D(_Lookup, lookupUV).rgb;
				
				float4 c;
				c.rgb = s.Albedo * _LightColor0.rgb * (exitRadiance * atten * 2);
				c.a = s.Alpha;
				return c;
			}
			
			void surf (Input IN, inout SurfaceOutput o) 
			{
				half4 mainTex = tex2D (_MainTex, IN.uv_MainTex);
				o.Albedo = mainTex.rgb;
				o.Alpha = mainTex.a;
			}
		ENDCG
	} 
	FallBack "Diffuse"
}

Awesome! Thank you so much! It works perfectly

Great rewrite but my model seems to be fully lit (no “shady” areas) from all sides? Guess I try more than a cube :smile: in the material-preview at least the torus mesh did look pretty neat. Gonna report back with further findings :wink:

I did similar adjustment to the brdf shader. Now I have another shadow problem …
The objects with this shader cast shadows, but won’t receive any shadows with point/spot lights (directional lights work.)

I’m in Unity Pro. Render Mode is set to be Important. Deferred Rendering.
How can I make this shader receive shadows??Does anyone have any ideas about where I did wrong?

Here is the code…
Shader “Custom/BRDFSHADER” {
Properties {
_MainTex (“Base (RGB)”, 2D) = “white” {}
_Color (“Base Color”, Color) = (1.0, 1.0, 1.0, 1.0)
_TexOpacity (“Base Opacity”, Range(0, 1.0)) = 1.0
_Ramp2D (“BRDF Ramp”, 2D) = “gray”{}
_NdotL (“NdotL Multiplier”, Float) = 0
_NdotV (“NdotV Multiplier”, Float) = 0
}
SubShader {
Tags { “RenderType”=“Opaque” }
LOD 200

CGPROGRAM
#pragma surface surf Ramp
#pragma target 3.0
#include “UnityCG.cginc”
#include “AutoLight.cginc”
#include “Lighting.cginc”

sampler2D _MainTex;
sampler2D _Ramp2D;
float _NdotL;
float _NdotV;
float _TexOpacity;

struct Input {
float2 uv_MainTex;
};

half4 LightingRamp (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
float NdotL = dot(s.Normal, lightDir);
float NdotV = dot(s.Normal, viewDir);

//diffuse wrap
float diff = (NdotL * _NdotL) + 0.5; //[-0.5,0.5] to [0, 1]
float rim = (NdotV * _NdotV) + 0.5; //NdotV*c
float2 brdfUV = float2(rim, diff);
float3 BRDF = tex2D(_Ramp2D, brdfUV.xy).rgb;

float4 c;
c.rgb = BRDF * atten * 2 * _LightColor0.rgb;
c.a = s.Alpha;
return c;
}

void surf (Input IN, inout SurfaceOutput o) {

half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = lerp(float3(1,1,1), c.rgb, _TexOpacity);
o.Alpha = c.a;
}
ENDCG
}
FallBack “Diffuse”
}

make sure the render mode: drop down setting is set to important?