Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Is there a way to access uv coordinates in a custom lighting model?

Discussion in 'Shaders' started by g_mister, Dec 8, 2012.

  1. g_mister

    g_mister

    Joined:
    Dec 5, 2012
    Posts:
    12
    Im trying to do this in a BRDF shader I've written and basically what I want to is have a different ramp texture used based on the mask texture provided.

    This is my code:

    Code (csharp):
    1.  Shader "Learning/BRDF_FULL_MASK"
    2.     {
    3.    
    4.     Properties {
    5.    
    6.         _Color ("Main Color", Color) = (1,1,1,1)
    7.         _SpecColor ("Specular Color", Color) = (1,1,1,1)
    8.         _Shininess ("Specualr Power", Range(-1,2)) = 0.5
    9.        
    10.         _MainTex ("Main Texture", 2D) = "white" {}
    11.         _BumpMap ("Normal Texture", 2D) = "white" {}
    12.         _MaskTex ("Mask (RGBA)", 2D) = "white" {}
    13.        
    14.         _Ramp_RED ("Shading Ramp 1", 2D) = "gray" {}
    15.         _Ramp_GREEN ("Shading Ramp 2", 2D) = "gray" {}
    16.         _Ramp_BLUE ("Shading Ramp 3", 2D) = "gray" {}
    17.    
    18.     }
    19.    
    20.     SubShader {
    21.    
    22.         Tags {"RenderType" = "Opaque"}
    23.    
    24.         CGPROGRAM
    25.         #pragma surface surf BRDF_FULL
    26.         #pragma target 3.0
    27.        
    28.         float _Shininess;
    29.         float4 _Color;
    30.         sampler2D _MainTex, _MaskTex, _BumpMap, _Ramp_RED, _Ramp_GREEN, _Ramp_BLUE;
    31.        
    32.         struct Input {
    33.             float2 uv_MainTex;
    34.             float2 uv_BumpMap;
    35.         };
    36.        
    37.         struct SurfaceOutputCustom {
    38.            
    39.             fixed3 Albedo;
    40.    
    41.             fixed3 Normal;
    42.    
    43.             fixed3 Emission;
    44.    
    45.             half Specular;
    46.    
    47.             fixed Gloss;
    48.    
    49.             fixed Alpha;
    50.            
    51.             float2 uv_MaskTex;
    52.    
    53.         };
    54.        
    55.         half4 LightingBRDF_FULL (SurfaceOutputCustom s, half3 lightDir, half3 viewDir, half3 atten)
    56.         {
    57.                
    58.             //Get the dot product of the sirface normal and light direction
    59.             half NdotL = dot (s.Normal, lightDir);
    60.             half NdotE = dot (s.Normal, viewDir);
    61.            
    62.             //Normalize diffuse
    63.             half diff = NdotL * 0.3 + 0.5;
    64.            
    65.             //BRDF
    66.             float2 brdfUV = float2 (NdotE * 0.8, diff);
    67.             float3 rBRDF = tex2D(_Ramp_RED, s.uv_MaskTex).rgb;
    68.             float3 gBRDF = tex2D(_Ramp_GREEN, s.uv_MaskTex).rgb;
    69.             float3 bBRDF = tex2D(_Ramp_BLUE, s.uv_MaskTex).rgb;
    70.                
    71.             //Specular
    72.             //half3 h = normalize(lightDir + viewDir);
    73.             //float _Shininess = max (0, dot(s.Normal, h));
    74.             //float _SpecColor = pow (_Shininess, 48.0);
    75.            
    76.             float3 m = tex2D(_MaskTex, brdfUV).rgb;
    77.        
    78.             //half4 c = tex2D (_MainTex, IN.uv_MainTex);
    79.        
    80.             float3 res = m;
    81.            
    82.             if (m.r >= .1) res = rBRDF.rgb;
    83.        
    84.             else if (m.g >= .1) res = gBRDF.rgb;
    85.        
    86.             else if (m.b >= .1) res = bBRDF.rgb;
    87.        
    88.             half4 c;
    89.             //c.rgb = (s.Albedo * _LightColor0.rgb * BRDF + _LightColor0.rgb * _SpecColor) * (NdotL * atten * 2);
    90.             c.rgb = (s.Albedo * _LightColor0.rgb * res) * (atten * 2);
    91.             c.a = s.Alpha;
    92.             return c;
    93.        
    94.         }
    95.        
    96.         void surf (Input IN, inout SurfaceOutput o)
    97.         {
    98.             //Handle textures
    99.             //Handle Diffuse map
    100.             fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    101.             //Handle Normal map
    102.             float3 bump = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
    103.            
    104.             //Apply textures
    105.             //Apply Diffuse texture
    106.             o.Albedo = tex.rgb * _Color.rgb;
    107.             //Apply Normal map
    108.             o.Normal = bump.rgb;
    109.            
    110.             //Specular
    111.             o.Specular = _Shininess;
    112.             o.Gloss = tex.a;
    113.        
    114.         }
    115.        
    116.         ENDCG
    117.    
    118.     }
    119.    
    120.     Fallback "Diffuse"
    121.    
    122.     }
    and this is the result I get from that:



    and the shader mask:

    http://answers.unity3d.com/storage/temp/5573-sheep_mask.png

    I think my problem is that I can't get uv coordinates calculated inside the custom lighting model. Is this possible? If it isn't what is a way to make this shader work?

    p.s.
    The model isn't mine, I got it here.
     
  2. g_mister

    g_mister

    Joined:
    Dec 5, 2012
    Posts:
    12
    Made some progress I think, still getting errors though. I found this post

    http://forum.unity3d.com/threads/14...n-in-custom-surface-shader-lighting-functions

    where MADmarine states that you can build your own structs to use in a custom lighting model. Awesome! So I did that, SurfaceOutputCustom, and now I get the error Shader error in 'Learning/BRDF_FULL_MASK': Program 'SurfShaderInternalFunc', incompatible type for parameter #1 ("s") at line 121. I'm pretty sure it has something to do with my SurfaceOutputCustom struct, but I don't know what.

    Any help is much appreciated!

    Thanks!

    p.s. I've updated my code in the above post for you all to see everything.
     
  3. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    I haven't done this, but maybe you should follow MADmarine's advice and "and replace any reference to SurfaceOutput with your struct", i.e. also in function "surf".
     
  4. g_mister

    g_mister

    Joined:
    Dec 5, 2012
    Posts:
    12
    Thanks for that Martin Kraus, that did fix the error I was seeing. Although the shader still isn't behaving the way I would like it to.

    This is the shader mask and how I would like the ramps to be applied to the model:



    Any suggestions would be wonderful, I'm not sure if I'm going about this the right way.