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 have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Sprite Diffuse without shadows

Discussion in 'Shaders' started by apeMike, Aug 14, 2015.

  1. apeMike

    apeMike

    Joined:
    Jan 31, 2015
    Posts:
    11
    hi,

    I've used Sprite Default but it's not reacting to fog and ambiant etc... so I've used Sprite Diffuse but...

    I'd like the sprite not to get darker when not directly facing the light source.

    So I'd like a shader that reacts to ambient light etc... and fog but not getting darker if not facing a light source.

    I was planning to modify the standard unity shaders but I have no experience in doing this so if anyone has a tip / idea that would be welcome.

    Thanks,
     
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,448
    I guess the easiest way to get there is to download the Unity built-in shaders, copy "DefaultResourcesExtra/Sprites-Diffuse.shader" to your project and implement a custom lighting model.

    The surface shader examples page features a Diffuse shader example that you can use as foundation. Take a look at the 2nd Diffuse example, it shows how to implement the custom lighting model. Notice the LightingSimpleLambert function, which you want to copy to your shader.

    Code (CSharp):
    1. #pragma surface surf SimpleLambert
    2.  
    3. half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
    4.   half NdotL = dot (s.Normal, lightDir);
    5.   half4 c;
    6.   c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
    7.   c.a = s.Alpha;
    8.   return c;
    9. }
    The following line in the example makes that the surfaces' illumination depend on the angle between the surface normal direction and light direction:
    Code (CSharp):
    1. half NdotL = dot (s.Normal, lightDir);
    Click here for a dot-product refresher.

    If you want to remove that behavior and illuminate the surface with full intensity always, you can get rid of the NdotL term and use 1 instead:
    Code (CSharp):
    1. half NdotL = 1;
    This is equal to when the surface normal and light direction are parallel and point into opposite directions.

    There might be other approaches how to achieve this effect, but I believe, even though it's a bit of a text here, the modifications to get the custom lighting model in are not too difficult.

    Hope it helps!


    PS:
    I'm not sure if the following line in the example is correct when using Unity 5:
    Code (CSharp):
    1. c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
    I think in Unity 5, you do not multiply by 2. If your sprite is too bright, change that line to:
    Code (CSharp):
    1. c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten);
     
  3. apeMike

    apeMike

    Joined:
    Jan 31, 2015
    Posts:
    11
    thanks Peter77 for this nice start of solution.

    so far, as I understood you, I've made this shader :

    Code (CSharp):
    1. Shader "apelab/Sprites/Diffuse"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags
    13.         {
    14.             "Queue"="Transparent"
    15.             "IgnoreProjector"="True"
    16.             "RenderType"="Transparent"
    17.             "PreviewType"="Plane"
    18.             "CanUseSpriteAtlas"="True"
    19.         }
    20.  
    21.         Cull Off
    22.         Lighting Off
    23.         ZWrite Off
    24.         Blend One OneMinusSrcAlpha
    25.  
    26.         CGPROGRAM
    27.         #pragma surface surf SimpleLambert vertex:vert nofog keepalpha
    28.         #pragma multi_compile _ PIXELSNAP_ON
    29.  
    30.         sampler2D _MainTex;
    31.         fixed4 _Color;
    32.  
    33.         struct Input
    34.         {
    35.             float2 uv_MainTex;
    36.             fixed4 color;
    37.         };
    38.    
    39.         void vert (inout appdata_full v, out Input o)
    40.         {
    41.             #if defined(PIXELSNAP_ON)
    42.             v.vertex = UnityPixelSnap (v.vertex);
    43.             #endif
    44.        
    45.             UNITY_INITIALIZE_OUTPUT(Input, o);
    46.             o.color = v.color * _Color;
    47.         }
    48.  
    49.  
    50.         half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
    51.             half4 c;
    52.             c.rgb = s.Albedo * _LightColor0.rgb * atten;
    53.             c.a = s.Alpha;
    54.             return c;
    55.         }
    56.    
    57.         void surf (Input IN, inout SurfaceOutput o)
    58.         {
    59.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color;
    60.             o.Albedo = c.rgb * c.a;
    61.             o.Alpha = c.a;
    62.         }
    63.         ENDCG
    64.     }
    65.  
    66. Fallback "Transparent/VertexLit"
    67. }
    68.  
    but the sprite now turns very bright when standing straight and normal when facing down.

    I've tried to remove the attenuation or to multiply it by .5 but there's always a variation of light intensity when I rotate the sprite that I want to get rid of.
     
    Last edited: Aug 17, 2015