Search Unity

Normals Stacking?

Discussion in '2D' started by Krileon, Mar 21, 2015.

  1. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    I've modified the default diffuse sprite shader to support normals, but if I've 2 sprites on top of one another the normals appear to stack. When there's a lot of my characters on top of one another (they don't collide with each other on purpose) it gives almost a ghosting like affect. Any idea what I may have done wrong? Below is a screenshot of what's going on as well as my shader. The light is just a standard point light with default settings.



    Code (CSharp):
    1. Shader "Sprites/Bumped"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _BumpMap ("Sprite Normal", 2D) = "bump" {}
    7.         _Color ("Tint", Color) = (1,1,1,1)
    8.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    9.     }
    10.  
    11.     SubShader
    12.     {
    13.         Tags
    14.         {
    15.             "Queue"="Transparent"
    16.             "IgnoreProjector"="True"
    17.             "RenderType"="Transparent"
    18.             "PreviewType"="Plane"
    19.             "CanUseSpriteAtlas"="True"
    20.         }
    21.  
    22.         Cull Off
    23.         Lighting Off
    24.         ZWrite Off
    25.         Fog { Mode Off }
    26.         Blend SrcAlpha OneMinusSrcAlpha
    27.  
    28.         CGPROGRAM
    29.         #pragma surface surf Lambert vertex:vert
    30.         #pragma multi_compile DUMMY PIXELSNAP_ON
    31.  
    32.         sampler2D _MainTex;
    33.         sampler2D _BumpMap;
    34.         fixed4 _Color;
    35.  
    36.         struct Input
    37.         {
    38.             float2 uv_MainTex;
    39.             float2 uv_BumpMap;
    40.             fixed4 color;
    41.         };
    42.        
    43.         void vert (inout appdata_full v, out Input o)
    44.         {
    45.             #if defined(PIXELSNAP_ON) && !defined(SHADER_API_FLASH)
    46.             v.vertex = UnityPixelSnap (v.vertex);
    47.             #endif
    48.             v.normal = float3(0,0,-1);
    49.             v.tangent = float4(1, 0, 0, -1);
    50.            
    51.             UNITY_INITIALIZE_OUTPUT(Input, o);
    52.             o.color = v.color * _Color;
    53.         }
    54.  
    55.         void surf (Input IN, inout SurfaceOutput o)
    56.         {
    57.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * IN.color;
    58.             o.Albedo = c.rgb * c.a;
    59.             o.Alpha = c.a;
    60.             o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    61.         }
    62.         ENDCG
    63.     }
    64.  
    65. Fallback "Sprites/Diffuse"
    66. }
    I use the below script to add the normals to the sprites. It has a small amount of GC (pretty insignificant IMO.. couple bytes) if anyone is wondering how I'm setting the normals. The OnUpdate is optional with the animation parameter. Be sure you append _Normal to your sprite names and use that as the name for the normal as it uses a hashtable to match the current sprite to a normal.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SetSpriteNormal : MonoBehaviour
    5. {
    6.     public Texture2D[] normals;
    7.     public bool animated;
    8.  
    9.     private SpriteRenderer spriteRenderer;
    10.     private string spriteName;
    11.     private Hashtable textures;
    12.  
    13.     void Start()
    14.     {
    15.         spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
    16.  
    17.         textures = new Hashtable();
    18.  
    19.         foreach ( Texture2D normal in normals ) {
    20.             textures.Add( normal.name.Replace( "_Normal", "" ), normal );
    21.         }
    22.  
    23.         setNormal();
    24.     }
    25.    
    26.     void Update()
    27.     {
    28.         if ( animated ) {
    29.             setNormal();
    30.         }
    31.     }
    32.  
    33.     void setNormal()
    34.     {
    35.         spriteName = spriteRenderer.sprite.name;
    36.  
    37.         if ( textures.Contains( spriteName ) ) {
    38.             spriteRenderer.material.SetTexture( "_BumpMap", (Texture2D) textures[spriteName] );
    39.         }
    40.     }
    41. }