Search Unity

How to implement standard specular into a custom lighting model surface shader

Discussion in 'Shaders' started by djweinbaum, Mar 15, 2017.

  1. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    I'd like to do a surface shader with a custom lighting model but still implement the standard specular behaviour where reflection probes are picked up. I'd also like to implement the standard gi. Basically I want the standard shader but with access to a custom lighting function. Could anyone point me in the right direction?

    Code (CSharp):
    1. Shader "Eastshade 2/Standard" {
    2.     Properties {
    3.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.         LOD 200
    8.        
    9.         CGPROGRAM
    10.         #pragma surface surf Custom
    11.         #pragma target 3.0
    12.  
    13.         sampler2D _MainTex;
    14.  
    15.         struct Input {
    16.             float2 uv_MainTex;
    17.         };
    18.  
    19.         struct SurfaceOutputCustom {
    20.             fixed3 Albedo;
    21.             fixed3 Normal;
    22.             fixed3 Emission;
    23.             fixed Specular;
    24.             fixed Gloss;
    25.             fixed Alpha;
    26.         };
    27.  
    28.         half4 LightingCustom_Deferred(SurfaceOutputCustom s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal) {
    29.  
    30.             half4 c = half4(s.Albedo, s.Alpha);
    31.             outDiffuseOcclusion = half4(s.Albedo, 0);
    32.             outSpecSmoothness = half4(s.Specular, s.Specular, s.Specular, s.Gloss);
    33.             outNormal = half4(s.Normal * 0.5 + 0.5, 1);
    34.             //maybe I put the spec here?
    35.             return c;
    36.         }
    37.  
    38.         inline void LightingCustom_GI( SurfaceOutputCustom s, UnityGIInput data, inout UnityGI gi ) {
    39.             //maybe I put the spec here?
    40.         }
    41.  
    42.         void surf (Input IN, inout SurfaceOutputCustom o) {
    43.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * .25;
    44.             o.Albedo = c.rgb;
    45.             o.Emission = 0;
    46.             o.Specular = 0;
    47.             o.Gloss = 0;
    48.             o.Alpha = 1;
    49.         }
    50.         ENDCG
    51.     }
    52.     FallBack "Diffuse"
    53. }
     
  2. djweinbaum

    djweinbaum

    Joined:
    Nov 3, 2013
    Posts:
    533
    So I've been working on this for a few days, and I've figured out the answer. I'm going to post it here in case anyone else is searching for the answer. I looked at the "LightingStandard_Deferred" and "LightingStandard_GI" functions which you can find in UnityPBSLighting.cginc in the built-in shaders. You can copy much of the code from those functions into your custom lighting functions in your surface shader. Be sure to include:

    Code (CSharp):
    1. #include "UnityPBSLighting.cginc"
    Your shader will likely require different implementation, but my two lighting functions look like this:

    Code (CSharp):
    1. half4 LightingTranslucent_Deferred(SurfaceOutputCustom s, half3 viewDir, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal) {
    2.     half4 c = UNITY_BRDF_PBS (s.Albedo, s.Specular, 0, s.Gloss, s.Normal, viewDir, gi.light, gi.indirect);
    3.     c *= _Color * 2;
    4.     c.rgb += UNITY_BRDF_GI (s.Albedo, s.Specular, 0, s.Gloss, s.Normal, viewDir, s.Occlusion, gi);
    5.  
    6.     outDiffuseOcclusion = half4(s.Albedo, s.Occlusion);
    7.     outSpecSmoothness = half4(s.Specular, s.Specular, s.Specular, s.Gloss);
    8.     outNormal = half4(s.Normal * 0.5 + 0.5, 1 - (s.Translucent* 1.5));
    9.  
    10.      return c;
    11. }
    12.  
    13. inline void LightingTranslucent_GI( SurfaceOutputCustom s, UnityGIInput data, inout UnityGI gi ) {
    14.     #if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
    15.          gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal);
    16.     #else
    17.           Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Gloss, data.worldViewDir, s.Normal, lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo, s.Specular));
    18.            gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal, g);
    19.       #endif
    20. }
     
  3. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    LightingTranslucent_Deferred(SurfaceOutputCustom s, half3 viewDir, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal)

    What do each parameter do?

    Also Rider VS and Code can't find definition of any of the shader stuff, what do you use to decypher all that?