Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Problem with BRDF Shader

Discussion in 'Shaders' started by Balint3DDesign, May 19, 2012.

  1. Balint3DDesign

    Balint3DDesign

    Joined:
    Apr 6, 2011
    Posts:
    110
    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 :
    Code (csharp):
    1. Shader "CTD/DemoBRDF"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Base (RGB)", 2D) = "white" {}
    6.         _Ramp2D ("BRDF Ramp", 2D) = "gray" {}
    7.     }
    8.  
    9.  
    10.     SubShader
    11.     {
    12.         Tags { "RenderType"="Opaque" }
    13.         LOD 200
    14.        
    15.         CGPROGRAM
    16.         #pragma surface surf Ramp
    17.         #pragma target 3.0
    18.  
    19.         sampler2D _MainTex;
    20.         sampler2D _Ramp2D;
    21.  
    22.         struct Input
    23.         {
    24.             float2 uv_MainTex;
    25.         };
    26.  
    27.         half4 LightingRamp (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
    28.         {
    29.                float NdotL = dot(s.Normal, lightDir);
    30.                float NdotE = dot(s.Nornal, viewDir);
    31.  
    32.                //do diffuse wrap here
    33.                float diff = (NdotL * 0.3) + 0.5;
    34.                float2 brdfUV = float2(NdotE * .8, diff);
    35.                float3 BRDF = tex2D(_Ramp2D, brdfUV.xy).rgb;
    36.  
    37.                float4 c;
    38.                c.rgb = BRDF;//float3(diff,diff,diff);
    39.                c.a = s.Alpha;
    40.                return c;
    41.          }
    42.  
    43.          void surf (Input IN, inout SurfaceOutput o)
    44.          {
    45.              half4 c = float4(.5,.5,.5,1);//tex2D (_MainTex, IN.uv_MainTex);
    46.              o.Albedo = c.rgb;
    47.              o.Alpha = c.a;
    48.          }
    49.          ENDCG
    50.      }
    51.      FallBack "Diffuse"
    52. }
    53.  
    54.  
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Line 30says Nornal, not Normal.
     
    Arlert likes this.
  3. Balint3DDesign

    Balint3DDesign

    Joined:
    Apr 6, 2011
    Posts:
    110
    Oooh ...
    This was a really noobish problem :D
    Thanks anyway :)
     
  4. wdcstudios

    wdcstudios

    Joined:
    Apr 18, 2011
    Posts:
    11
    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.
     
  5. boomcrash99

    boomcrash99

    Joined:
    Jul 18, 2012
    Posts:
    8
    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.
     
  6. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    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.
     
  7. boomcrash99

    boomcrash99

    Joined:
    Jul 18, 2012
    Posts:
    8
    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

     
    Last edited: Oct 15, 2013
  8. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    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.

    Code (csharp):
    1. Shader "2D Lookup Lighting" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.         _Lookup ("Lookup", 2D) = "gray" {}
    5.     }
    6.     SubShader {
    7.         Tags { "RenderType"="Opaque" }
    8.         LOD 200
    9.  
    10.         CGPROGRAM
    11.             #pragma surface surf Lookup
    12.  
    13.             sampler2D _MainTex;
    14.             sampler2D _Lookup;
    15.            
    16.             struct Input
    17.             {
    18.                 float2 uv_MainTex;
    19.             };
    20.            
    21.             half4 LightingLookup (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
    22.             {
    23.                 float NdotL = dot(s.Normal, lightDir);
    24.                 float NdotV = dot(s.Normal, viewDir);
    25.                
    26.                 float2 lookupUV = float2(NdotV, NdotL * 0.5 + 0.5);
    27.                 float3 exitRadiance = tex2D(_Lookup, lookupUV).rgb;
    28.                
    29.                 float4 c;
    30.                 c.rgb = s.Albedo * _LightColor0.rgb * (exitRadiance * atten * 2);
    31.                 c.a = s.Alpha;
    32.                 return c;
    33.             }
    34.            
    35.             void surf (Input IN, inout SurfaceOutput o)
    36.             {
    37.                 half4 mainTex = tex2D (_MainTex, IN.uv_MainTex);
    38.                 o.Albedo = mainTex.rgb;
    39.                 o.Alpha = mainTex.a;
    40.             }
    41.         ENDCG
    42.     }
    43.     FallBack "Diffuse"
    44. }
     
  9. boomcrash99

    boomcrash99

    Joined:
    Jul 18, 2012
    Posts:
    8
    Awesome! Thank you so much! It works perfectly
     
  10. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589
    Great rewrite but my model seems to be fully lit (no "shady" areas) from all sides? Guess I try more than a cube :D in the material-preview at least the torus mesh did look pretty neat. Gonna report back with further findings ;)
     
  11. brook0907

    brook0907

    Joined:
    May 27, 2013
    Posts:
    2
    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"
    }
     
  12. ohlin

    ohlin

    Joined:
    Mar 3, 2013
    Posts:
    17
    make sure the render mode: drop down setting is set to important?