Search Unity

Standard shader with halfLambert lighting.

Discussion in 'Shaders' started by thorham3011, Jul 17, 2020.

  1. thorham3011

    thorham3011

    Joined:
    Sep 7, 2017
    Posts:
    25
    How can I use halfLambert lighting (or any custom lighting) while also being able to still use the smoothness and metallic properties?

    When I implement a custom lighting model for this using a simple surface shader, I can't use smoothness and metallic anymore. Is there any way to add them to the lighting model?
     
  2. thorham3011

    thorham3011

    Joined:
    Sep 7, 2017
    Posts:
    25
    Solved it by going through the builtin shader source code. Put the code below in a .cginc file (for example standardShader.cginc), include the file in a surface shader and change the lighting model to Standard1 like so:

    Code (csharp):
    1.  
    2. #include "standardShader.cginc"
    3.  
    4. #pragma surface surf Standard1 fullforwardshadows
    5. #pragma target 3.0
    6.  
    Include file:

    Code (csharp):
    1. #include "UnityPBSLighting.cginc"
    2.  
    3. half4 UNITY_BRDF_PBS1(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness, float3 normal, float3 viewDir, UnityLight light, UnityIndirect gi)
    4. {
    5.     float perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness);
    6.     float3 halfDir = Unity_SafeNormalize(float3(light.dir) + viewDir);
    7.  
    8.     half nv = abs(dot(normal, viewDir));
    9.     float nl = nv; // saturate(dot(normal, light.dir));
    10.     float nh = saturate(dot(normal, halfDir));
    11.     half lh = saturate(dot(light.dir, halfDir));
    12.  
    13.     half diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;
    14.     float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
    15.  
    16.     roughness = max(roughness, 0.002);
    17.  
    18.     float V = SmithJointGGXVisibilityTerm(nl, nv, roughness);
    19.     float D = GGXTerm(nh, roughness);
    20.     float specularTerm = V * D * UNITY_PI;
    21.  
    22.     specularTerm = max(0, specularTerm * nl);
    23.  
    24.     half surfaceReduction;
    25.  
    26.     surfaceReduction = 1.0 / (roughness * roughness + 1.0);
    27.  
    28.     specularTerm *= any(specColor) ? 1.0 : 0.0;
    29.  
    30.     half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity));
    31.     half3 color = diffColor * (gi.diffuse + light.color * diffuseTerm)
    32.         + specularTerm * light.color * FresnelTerm(specColor, lh)
    33.         + surfaceReduction * gi.specular * FresnelLerp(specColor, grazingTerm, nv);
    34.  
    35.     return half4(color, 1);
    36. }
    37.  
    38. inline half4 LightingStandard1(SurfaceOutputStandard s, float3 viewDir, UnityGI gi)
    39. {
    40.     s.Normal = normalize(s.Normal);
    41.  
    42.     half oneMinusReflectivity;
    43.     half3 specColor;
    44.  
    45.     s.Albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, specColor, oneMinusReflectivity);
    46.  
    47.     half outputAlpha;
    48.  
    49.     s.Albedo = PreMultiplyAlpha(s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
    50.  
    51.     half4 c = UNITY_BRDF_PBS1(s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
    52.  
    53.     c.a = outputAlpha;
    54.  
    55.     return c;
    56. }
    57.  
    58. inline void LightingStandard1_GI(SurfaceOutputStandard s, UnityGIInput data, inout UnityGI gi)
    59. {
    60.     Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo, s.Metallic));
    61.     gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal, g);
    62. }
    63.