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 are updating our Terms of Service for all Unity subscription plans, effective October 13, 2022, to create a more streamlined, user-friendly set of terms. Please review them here: unity.com/legal/terms-of-service.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice
  4. Join us on Thursday, September 29, for a day with Unity's SRP teams here on the forum or on Reddit, and discuss topics around URP, HDRP, and the Scriptable Render Pipeline in general.
    Dismiss Notice

Question [SOLVED] How do I eliminate all smoothness/Fresnel [specular] from the standard shader?

Discussion in 'Shaders' started by dogs_R_cool, Aug 14, 2022.

  1. dogs_R_cool

    dogs_R_cool

    Joined:
    Mar 14, 2016
    Posts:
    12
    I have noticed recently that Unity's standard shader seems to have a base level of smoothness that cannot be eliminated even when setting the smoothness value to zero or hard overriding the value in the shader itself (this remains the case regardless of the smoothness source), which means that all surface shaders have a slight sheen to them and a small amount of Fresnel lighting, which is especially noticeable at acute angles or when standing on a large flat plane.
    Ordinarily this wouldn't be a huge problem, but I am using a palette limiter which makes these small differences in colour extremely obvious and potentially confusing.
    I looked all over for a solution and couldn't seem to find anything, until I revisited this page of the Unity docs and noticed that the example shader seems not to have the persistent shine. So I copied the code and compared it to the standard shader and, sure enough, the sheen is gone and the colour is the same at all angles. Below are some examples of the standard shader compared to the example one from the docs, with and without post-processing:

    standard_vs_example_multi.png

    Problem solved right? Just use the example shader from the docs! Unfortunately that shader only comes with support for a single directional light and no other light types. :mad:
    So I'm left with two choices: follow some huge in-depth tutorial on adding support for multiple lights and all the other things that the standard shader affords, or find out how to remove the unwanted smoothness from the standard shader and keep everything else the same.
    The latter seems more sensible to me, so how do I go about doing that? How do I eliminate the smoothness/Fresnel from the standard shader?
     
  2. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,427
    If you want to kill it for good, place a reflection probe and instead of having it capture the environment point it to a pure black texture.
     
  3. dogs_R_cool

    dogs_R_cool

    Joined:
    Mar 14, 2016
    Posts:
    12
    Damn this is so close to working. Good call.
    If I place a black reflection probe I actually get the inverse problem; at acute angles surfaces tend towards black instead of white. Playing around with the colour of the probe produces some good results. If I match the probe colour with that of the surface I can totally remove all angle-dependent colour differences and artifacting. Unfortunately this only works for one colour at a time, and obviously I have a scene full of differently coloured and textured objects. Might work as a stopgap, but not a scalable solution.
    This does seem to reveal that it's actually reflections that are the problem, not Fresnel or smoothness.
     
  4. dogs_R_cool

    dogs_R_cool

    Joined:
    Mar 14, 2016
    Posts:
    12
    SOLVED: It was the specular all along.
    I had a look at this page on surface shader lighting examples and had a good long look at the different custom lighting implementations and in particular the simple specular model which looked like something I could read and manipulate. So I brought it into my project and removed all specular calculations while still maintaining light attenuation support and voila:

    NoSpecularWithShadowSupport_multi.png

    Full parity with the example shader. No colour aberration at acute angles. Full light and shadow support.

    This is what the shader code looks like:
    Code (CSharp):
    1. Shader "Custom/DiffuseWithoutSpecular"
    2. {
    3.   Properties
    4.   {
    5.       _Color ("Color", Color) = (1,1,1,1)
    6.       _MainTex ("Albedo (RGB)", 2D) = "white" {}
    7.   }
    8.   SubShader
    9.   {
    10.       Tags { "RenderType"="Opaque" }
    11.       LOD 200
    12.  
    13.       CGPROGRAM
    14.       // Custom no specular lighting model with full multi-shadow support
    15.       #pragma surface surf NoSpecular fullforwardshadows
    16.       // Use shader model 3.0 target, to get nicer looking lighting
    17.       #pragma target 3.0
    18.  
    19.  
    20.       half4 LightingNoSpecular (SurfaceOutput s, half3 lightDir, half atten) {
    21.         half diff = max (0, dot (s.Normal, lightDir));
    22.         return half4 ((s.Albedo * _LightColor0.rgb * diff) * atten, s.Alpha);
    23.       }
    24.  
    25.       struct Input
    26.       {
    27.           float2 uv_MainTex;
    28.       };
    29.  
    30.       sampler2D _MainTex;
    31.       fixed4 _Color;
    32.  
    33.       void surf (Input IN, inout SurfaceOutput o)
    34.       {
    35.           fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    36.           o.Albedo = c.rgb;
    37.           o.Alpha = c.a;
    38.       }
    39.       ENDCG
    40.   }
    41.   FallBack "Diffuse"
    42. }
    43.  
     
unityunity