Search Unity

Standard Shader with Anisotropic Blend

Discussion in 'Shaders' started by Harrison_Hough, Feb 22, 2017.

  1. Harrison_Hough

    Harrison_Hough

    Joined:
    Dec 3, 2015
    Posts:
    43
    Hey Guys,

    I'm trying to make a shader that uses UnityStandard (specular or metatalic) surface shader lighting but that allows blending (additively) with an custom Anisotropic lighting setup. The idea is that you could have a slider/value that determines how much Anisotropic light to add on top of the standed lighting, if that makes any sense.

    Currently I have what you see below. What seems to be happening is that the second pass (anisotropic) is being ignored/overriden by the first (Unity StandardSpecular) pass. The Weird thing is that in the Unity Inspector window when I adjust the Aniso Strength it seems to work correct but not in the game/scene view.

    I'm also not entirely sure that it's even possible to do this. Any info would be a great help!

    Code (CSharp):
    1.  
    2. Shader "Custom/AnisoBlend" {
    3.     Properties {
    4.         _Color("Color", Color) = (1,1,1,1)
    5.         _MainTex("Albedo (RGB)", 2D) = "white" {}
    6.         _BumpMap("Normal Map", 2D) = "Bump"{}
    7.         _BumpScale("Normal Power", Float) = 1.0
    8.         _SpecularMap("Specular (R) Gloss (G) Anisotropic Mask (B)", 2D) = "gray" {}
    9.         _SpecularPower("Specular Power", float) = 1.0
    10.         _SpecularColor("Specular Color", Color) = (1,1,1,1)
    11.         _CustomOffset("Anisotropic Highlight Offset", Range(-1,1)) = 0.0
    12.         _Glossiness("Gloss Power", float) = 128.0
    13.         _AnisoStrength("Aniso Strength", float) = 1
    14.     }
    15.     SubShader {
    16.         Tags { "RenderType"="Opaque" }
    17.         LOD 200
    18.        
    19.         CGPROGRAM
    20.         // Physically based Standard lighting model, and enable shadows on all light types
    21.         #pragma surface surf StandardSpecular fullforwardshadows
    22.  
    23.         // Use shader model 3.0 target, to get nicer looking lighting
    24.         #pragma target 3.0
    25.  
    26.         sampler2D _MainTex, _SpecularMap, _BumpMap;
    27.  
    28.         struct Input {
    29.             float2 uv_MainTex;
    30.         };
    31.  
    32.         half _Glossiness, _BumpScale;
    33.         fixed4 _SpecColor2;
    34.         fixed4 _Color;
    35.  
    36.         void surf (Input IN, inout SurfaceOutputStandardSpecular o) {
    37.             // Albedo comes from a texture tinted by color
    38.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    39.             o.Albedo = c.rgb;
    40.            
    41.             fixed4 s = tex2D(_SpecularMap, IN.uv_MainTex) * _SpecColor2;
    42.             o.Specular = s.rgb;
    43.             o.Smoothness = _Glossiness;
    44.             o.Alpha = c.a;
    45.             o.Normal = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_MainTex), _BumpScale);
    46.         }
    47.         ENDCG
    48.  
    49.             //Aniso Pass
    50.  
    51.             CGPROGRAM
    52.             // Physically based Standard lighting model, and enable shadows on all light types
    53. #pragma surface surf Custom
    54.  
    55.             // Use shader model 3.0 target, to get nicer looking lighting
    56. #pragma target 3.0
    57.  
    58.             struct SurfaceOutputCustom
    59.         {
    60.             fixed3 Albedo;
    61.             fixed3 Normal;
    62.             fixed3 Emission;
    63.             half Specular;
    64.             fixed Gloss;
    65.             fixed Alpha;
    66.             fixed CustomMask;
    67.  
    68.         };
    69.  
    70.         struct Input {
    71.             float2 uv_MainTex;
    72.         };
    73.  
    74.         sampler2D _MainTex, _SpecularMap, _BumpMap;
    75.         float _CustomOffset, _SpecularPower, _Glossiness, _AnisoStrength;
    76.         fixed4 _SpecularColor, _Color;
    77.         half _BumpScale;
    78.  
    79.         void surf(Input IN, inout SurfaceOutputCustom o) {
    80.             // Albedo comes from a texture tinted by color
    81.             fixed4 a = tex2D(_MainTex, IN.uv_MainTex);
    82.             o.Albedo = lerp(a.rgb, a.rgb*_Color.rgb, 0.5);
    83.  
    84.             fixed3 spec = tex2D(_SpecularMap, IN.uv_MainTex).rgb;
    85.             o.Specular = spec.r;
    86.             o.Gloss = spec.g;
    87.             o.CustomMask = spec.b;
    88.             o.Alpha = a.a;
    89.             o.Normal = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_MainTex), _BumpScale);
    90.         }
    91.  
    92.         inline fixed4 LightingCustom(SurfaceOutputCustom s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    93.         {
    94.             s.Normal = normalize(s.Normal);
    95.             fixed3 h = normalize(normalize(lightDir) + normalize(viewDir));
    96.             float NdotL = saturate(dot(s.Normal, lightDir));
    97.  
    98.             fixed HdotA = dot(s.Normal, h);
    99.             float aniso = max(0, sin(radians((HdotA + _CustomOffset) * 180)));
    100.  
    101.             float spec = saturate(dot(s.Normal, h));
    102.             spec = saturate(pow(lerp(spec, aniso, s.CustomMask), s.Gloss * _Glossiness) * s.Specular);
    103.             spec = spec * _SpecularPower;
    104.  
    105.             fixed4 c;
    106.             c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL * _Color) + (_LightColor0.rgb * spec * _SpecularColor * NdotL)) * (atten * 2);
    107.             c.a = s.Alpha;
    108.  
    109.             return c * _AnisoStrength;
    110.         }
    111.         ENDCG
    112.     }
    113.     FallBack "Diffuse"
    114. }
    115.  
    116.  
     
  2. Harrison_Hough

    Harrison_Hough

    Joined:
    Dec 3, 2015
    Posts:
    43
    So I have tried another approach but still having problems.
    Basically with this approach I plan to use an custom lighting function and in that get the standard lighting from "UnityPBSLighting.cginc" and then calculate the Aniso lighting and add it on top of that.
    The Problem is that I need the LightDir (Light direction) and Atten (Attenuation) to be able to calculate the Anisotropic lighting but Unity's PBS lighting function doesnt have those values.

    Anyways heres the code for that.
    Code (CSharp):
    1. Shader "Custom/LightBlend" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    6.         _SpecularMap("Specular", 2D) = "white" {}
    7.         _AnisoLevel("Aniso Level",Range(0,1)) = 0.0
    8.         _Gloss("Gloss Multiplier", float) = 128.0
    9.     }
    10.     SubShader {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.        
    14.         CGPROGRAM
    15.         // Physically based Standard lighting model, and enable shadows on all light types
    16.         #pragma surface surf Custom fullforwardshadows
    17.  
    18.         // Use shader model 3.0 target, to get nicer looking lighting
    19.         #pragma target 3.0
    20.  
    21.         #include "UnityPBSLighting.cginc"
    22.  
    23.         sampler2D _MainTex, _SpecularMap;
    24.  
    25.         half _Glossiness;
    26.         half _Metallic;
    27.         fixed4 _Color;
    28.         float _AnisoLevel, _Gloss;
    29.         inline half4 LightingCustom(SurfaceOutputStandardSpecular s, half3 viewDir, UnityGI gi )
    30.         {
    31.             half4 light = LightingStandardSpecular(s, viewDir, gi);
    32.  
    33.             //Anisotropic lighting --- requires lightDir and atten (like in Blinn Phong Model)
    34.  
    35.  
    36.             fixed3 h = normalize(normalize(lightDir) + normalize(viewDir));
    37.             float NdotL = saturate(dot(s.Normal, lightDir));
    38.  
    39.             fixed HdotA = dot(s.Normal, h);
    40.             float aniso = max(0, sin(radians((HdotA + _CustomOffset) * 180)));
    41.  
    42.             float spec = saturate(dot(s.Normal, h));
    43.             spec = saturate(pow(lerp(spec, aniso, s.CustomMask), s.Gloss * _Glossiness) * s.Specular);
    44.             spec = spec * _SpecularPower;
    45.  
    46.             fixed4 c;
    47.             c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL * _Color) + (_LightColor0.rgb * spec * _SpecularColor * NdotL)) * (atten * 2);
    48.             c.a = s.Alpha;
    49.  
    50.  
    51.             //blend (additive) Aniso lighiting to standard
    52.             light += c * _anisoLevel;
    53.  
    54.             return light;
    55.         }
    56.  
    57.         inline void LightingCustom_GI(
    58.             SurfaceOutputStandardSpecular s,
    59.             UnityGIInput data,
    60.             inout UnityGI gi)
    61.         {
    62.             LightingStandardSpecular_GI(s, data, gi);
    63.         }
    64.  
    65.        
    66.  
    67.         struct Input {
    68.             float2 uv_MainTex;
    69.         };
    70.  
    71.        
    72.  
    73.         void surf (Input IN, inout SurfaceOutputStandardSpecular o) {
    74.             // Albedo comes from a texture tinted by color
    75.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    76.             o.Albedo = c.rgb;
    77.  
    78.             fixed4 s = tex2D(_SpecularMap, IN.uv_MainTex);
    79.             o.Specular = s.rgb;
    80.             o.Smoothness = _Glossiness;
    81.             o.Alpha = c.a;
    82.         }
    83.         ENDCG
    84.     }
    85.     FallBack "Diffuse"
    86. }
    87.  
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Sure it does, the standard lighting function needs that data too. It's just in the UnityGI value.

    Well, the attenuation is for sure, and the direction used to be but I can't remember if it is still or not. They might be calculating it from _WorldSpaceLightPos0.
     
  4. Harrison_Hough

    Harrison_Hough

    Joined:
    Dec 3, 2015
    Posts:
    43
    Right I thought that might be the case, I just havent been able to work out how to access / reference it.
    Thanks! I'll keep playing around with it and see what I can work out