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

Remove Specular Highlights and Reflections from custom shader

Discussion in 'Shaders' started by Guedez, May 10, 2019.

  1. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    I've made a custom shader, and of course, it does not have the tickbox for Specular Highlights and Reflections.
    How do I remove it?

    Maybe what I want to remove is not the Specular Highlights, it's this ugly ass glare that makes my grass look like plastic regardless of metalic and smooth values

    upload_2019-5-10_17-48-57.png
    upload_2019-5-10_17-49-58.png
    upload_2019-5-10_17-50-17.png

    The shader
    Code (CSharp):
    1. Shader "Guedez/Terrain/AtlasShader" {
    2.     Properties{
    3.         _ALBH("Albedo(3) + Height (Array)", 2DArray) = "" {}
    4.         _NRSM("Normal(2) + Smooth + Metalic (Array)", 2DArray) = "" {}
    5.         _P___("Parallax + (3) (RGB)", 2D) = "black" {}
    6.     }
    7.     SubShader {
    8.         Tags{ "RenderType" = "Opaque" }
    9.         LOD 200
    10.  
    11.         CGPROGRAM
    12.         #pragma surface surf Standard fullforwardshadows vertex:vert
    13.         #pragma require 2darray
    14.         #pragma target 3.5
    15.         #include "UnityStandardUtils.cginc"
    16.         #pragma multi_compile HAS_HEIGHT _
    17.         #pragma multi_compile HAS_SECOND_TEXTURE HAS_THIRD_TEXTURE _
    18.  
    19.         struct appdata
    20.         {
    21.             float4 vertex    : POSITION;  // The vertex position in model space.
    22.             float3 normal    : NORMAL;    // The vertex normal in model space.
    23.             float4 texcoord  : TEXCOORD0; // The first UV coordinate.
    24.             float4 texcoord1 : TEXCOORD1; // The second UV coordinate.
    25.             float4 texcoord2 : TEXCOORD2; // The third UV coordinate.
    26.             float4 texcoord3 : TEXCOORD3; // The fourfth UV coordinate.
    27.             float4 texcoord4 : TEXCOORD4; // The fifth UV coordinate. // requires Unity 2018.2+
    28.             //float4 texcoord5 : TEXCOORD5; // The sixth UV coordinate. // requires Unity 2018.2+
    29.             //float4 texcoord6 : TEXCOORD6; // The seventh UV coordinate. // requires Unity 2018.2+
    30.             //float4 texcoord7 : TEXCOORD7; // The eigthieth UV coordinate. // requires Unity 2018.2+ // maximum amount of channels supported
    31.             float4 tangent   : TANGENT;   // The tangent vector in Model Space (used for normal mapping).
    32.             float4 color     : COLOR;     // Per-vertex color
    33.         };
    34.  
    35.         struct Input {
    36.             float4 vertex    : POSITION;
    37.             float4 tangent   : TANGENT;
    38.             float4 color : COLOR;
    39.             float2 tc0;
    40.             #if HAS_SECOND_TEXTURE
    41.                 float2 tc1;
    42.             #endif
    43.             #if HAS_THIRD_TEXTURE
    44.                 float2 tc1;
    45.                 float2 tc2;
    46.             #endif
    47.             float _MainTexture;
    48.             float _MainTexture2;
    49.             float _MainTexture3;
    50.             float3 viewDir;
    51.         };
    52.        
    53.         void vert (inout appdata v, out Input o) {
    54.             UNITY_INITIALIZE_OUTPUT(Input,o);
    55.             o.tc0 = v.texcoord.xy;
    56.             o._MainTexture = (int)v.texcoord3.x;
    57.             #if HAS_SECOND_TEXTURE
    58.             o.tc1 = v.texcoord1.xy;
    59.             o._MainTexture2 = (int)v.texcoord3.y;
    60.             #endif
    61.             #if HAS_THIRD_TEXTURE
    62.             o.tc1 = v.texcoord1.xy;
    63.             o.tc2 = v.texcoord2.xy;
    64.             o._MainTexture2 = (int)v.texcoord3.y;
    65.             o._MainTexture3 = (int)v.texcoord4.x;
    66.             #endif
    67.         }
    68.  
    69.         sampler2D _P___;
    70.         UNITY_DECLARE_TEX2DARRAY(_ALBH);
    71.         UNITY_DECLARE_TEX2DARRAY(_NRSM);
    72.        
    73.         float3 packNormal(fixed2 pnormal){
    74.             //pnormal.rg = pow(pnormal.rg, 0.5);
    75.             fixed3 normal;
    76.             normal.x = (pnormal * 2) - 1;
    77.             normal.y = 0;
    78.             normal.z = sqrt(1 - normal.x*normal.x);
    79.             return normalize (normal);
    80.             //return UnpackNormal(float4(1, pnormal.x, pnormal.x, pnormal.y));
    81.         }
    82.  
    83.         void surf(Input IN, inout SurfaceOutputStandard o) {
    84.             fixed4 albh = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc0, IN._MainTexture));
    85.             IN.tc0 += ParallaxOffset(albh.a, tex2D(_P___, fixed2(IN._MainTexture+0.5f, +0.5f)).r, IN.viewDir);
    86.             albh = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc0, IN._MainTexture));
    87.             fixed4 nrsm = pow(UNITY_SAMPLE_TEX2DARRAY(_NRSM, float3(IN.tc0 , IN._MainTexture)),0.5);
    88.             fixed3 normal = packNormal(nrsm.rg);
    89.             #if HAS_SECOND_TEXTURE
    90.                 fixed4 albh2 = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc1, IN._MainTexture2));
    91.                 IN.tc1 += ParallaxOffset(albh2.a, tex2D(_P___, fixed2(IN._MainTexture2+0.5f, +0.5f)).r, IN.viewDir);
    92.                 albh2 = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc1, IN._MainTexture2));
    93.                 fixed4 nrsm2 = pow(UNITY_SAMPLE_TEX2DARRAY(_NRSM, float3(IN.tc1 , IN._MainTexture2)),0.5);
    94.                 fixed3 normal2 = packNormal(nrsm2.rg);
    95.             #endif
    96.             #if HAS_THIRD_TEXTURE
    97.                 fixed4 albh2 = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc1, IN._MainTexture2));
    98.                 IN.tc1 += ParallaxOffset(albh2.a, tex2D(_P___, fixed2(IN._MainTexture2+0.5f, +0.5f)).r, IN.viewDir);
    99.                 albh2 = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc1, IN._MainTexture2));
    100.                 fixed4 nrsm2 = pow(UNITY_SAMPLE_TEX2DARRAY(_NRSM, float3(IN.tc1 , IN._MainTexture2)),0.5);
    101.                 fixed3 normal2 = packNormal(nrsm2.rg);
    102.  
    103.                 fixed4 albh3 = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc2, IN._MainTexture3));
    104.                 //IN.tc2 += ParallaxOffset(albh3.a, tex2D(_P___, fixed2(IN._MainTexture3+0.5f, +0.5f)).r, IN.viewDir);
    105.                 albh3 = UNITY_SAMPLE_TEX2DARRAY(_ALBH, float3(IN.tc2, IN._MainTexture3));
    106.                 fixed4 nrsm3 = pow(UNITY_SAMPLE_TEX2DARRAY(_NRSM, float3(IN.tc2 , IN._MainTexture3)),0.5);
    107.                 fixed3 normal3 = packNormal(nrsm3.rg);
    108.             #endif
    109.             #if HAS_SECOND_TEXTURE              
    110.                 IN.color.r = (log(IN.color.r*3+1)/log(4))/2;
    111.                 float dif = -((1 - IN.color.r) * albh.a - IN.color.r * albh2.a)*50+0.5;
    112.                 float lerp2 = clamp(dif, 0, 1);
    113.                 albh = lerp(albh, albh2, lerp2);
    114.                 nrsm.ab = lerp(nrsm.ab, nrsm2.ab, lerp2);
    115.                 normal = lerp(normal, normal2, lerp2);
    116.                 //albh.rgb = IN.color.rrr;
    117.             #endif
    118.             #if HAS_THIRD_TEXTURE      
    119.                 float4 color = IN.color;
    120.                 IN.color.r = color.r-(color.g*color.a);
    121.                 IN.color.r = (log(IN.color.r*3+1)/log(4))/2;
    122.                 float dif = -((1 - IN.color.r) * albh.a - IN.color.r * albh2.a)*50+0.5;
    123.                 float lerp2 = clamp(dif, 0, 1);
    124.                 albh = lerp(albh, albh2, lerp2);
    125.                 nrsm.ab = lerp(nrsm.ab, nrsm2.ab, lerp2);
    126.                 normal = lerp(normal, normal2, lerp2);
    127.  
    128.                 IN.color.g = color.g-(color.g*color.b);
    129.                 IN.color.g = (log(IN.color.g*3+1)/log(4))/2;
    130.                 dif = -((1 - IN.color.g) * albh.a - IN.color.g * albh3.a)*50+0.5;
    131.                 lerp2 = clamp(dif, 0, 1);
    132.                 albh = lerp(albh, albh3, lerp2);
    133.                 nrsm.ab = lerp(nrsm.ab, nrsm3.ab, lerp2);
    134.                 normal = lerp(normal, normal3, lerp2);
    135.                 //albh.rgb = IN.color.rrr;
    136.                 //albh.g = IN.color.g-IN.color.b;
    137.                 //albh.r = IN.color.r-IN.color.a;
    138.             #endif
    139.             o.Albedo = albh.rgb;
    140.             o.Normal = normal;
    141.             o.Metallic = nrsm.a;
    142.             o.Smoothness = nrsm.b;
    143.             o.Alpha = 1;
    144.         }
    145.         ENDCG
    146.     }
    147.         FallBack "Diffuse"
    148. }
    149.  
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Maybe try using the Lambert or Blinn shading model with your Surface Shader instead of Standard?

    Real world objects do have that "sheen" to them, but it can look weird, especially when you don't use a normal map. So a simpler shading model may be more appropriate.
     
  3. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    I want to disable one feature, not all of them
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    If you use the built in Standard shader and disable both specular and reflections, I believe you’ll find it still has the sheen. It’s part of the Standard shader’s diffuse shading model. Unfortunately there’s no built in shading model with out the sheen, but with physically based specular & reflections. Well, technically the Standard shader when running on some mobile devices doesn’t have the sheen as it falls back to a Blinn-Phong shading model.

    You could switch to using StandardSpecular, set the specular to black, and the smoothness to 1.0, but then it’s identical to Lambert.
     
    ProjectileVomitTV likes this.
  5. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    I was stumbling through the lighting shader sources and I've manged to add the LightingStandard function to my shader, but it seems the sheen is made in the UNITY_BRDF_PBS function and I can't figure out where's the source to that is
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    UnityStandardBRDF.cginc

    UNITY_BRDF_PBS is a macro which points to different functions depending on the platform. On PC the function is BRDF1_Unity_PBS. The sheen comes from the DisneyDiffuse function.
     
    Guedez and hippocoder like this.
  7. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    Setting the parameter in the DisneyDiffuse nv to 1 solved the issue.
    Before:
    upload_2019-5-12_15-16-30.png
    After:
    upload_2019-5-12_15-16-57.png

    Edit:
    More specifically, find this line
    half diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;

    and change to
    half diffuseTerm = DisneyDiffuse(1, nl, lh, perceptualRoughness) * nl;