Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Resolved Shader looks different in scene view. Is it okay and can be used cross-platform?

Discussion in 'Shaders' started by davidelucard, Jul 29, 2020.

  1. davidelucard

    davidelucard

    Joined:
    Oct 30, 2019
    Posts:
    2
    Hi, I'm learning how to write shaders and for my game I need a simulation of volume on 2D sprite.

    I came up with this shader:

    Code (CSharp):
    1. Shader "Custom/Basic Toon"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    6.         _NormalTex("Normal Sprite", 2D) = "bump" {}
    7.         _Color("Tint", Color) = (1,1,1,1)
    8.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    9.             [HDR]
    10.         _AmbientColor("Ambient Color", Color) = (0.4,0.4,0.4,1)
    11.     }
    12.  
    13.         SubShader
    14.         {
    15.             Tags
    16.             {
    17.                 "Queue" = "Transparent"
    18.                 "IgnoreProjector" = "True"
    19.                 "RenderType" = "Transparent"
    20.                 "PreviewType" = "Plane"
    21.                 "CanUseSpriteAtlas" = "True"
    22.                 "LightMode" = "ForwardBase"
    23.                 "PassFlags" = "OnlyDirectional"
    24.             }
    25.  
    26.             Cull Off
    27.             Lighting On
    28.             ZWrite Off
    29.             Blend One OneMinusSrcAlpha
    30.  
    31.             Pass
    32.             {
    33.             CGPROGRAM
    34.                 #pragma vertex vert
    35.                 #pragma fragment frag
    36.                 #pragma multi_compile _ PIXELSNAP_ON
    37.                 #include "UnityCG.cginc"
    38.             #include "Lighting.cginc"
    39.  
    40.                 struct appdata_t
    41.                 {
    42.                     float3 texcoord : TEXCOORD0;
    43.                     float3 normal : NORMAL;
    44.                     float4 vertex   : POSITION;
    45.                     float4 color    : COLOR;
    46.                     float4 tangent: TANGENT;
    47.                     float2 uv : TEXCOORD1;
    48.                 };
    49.  
    50.                 struct v2f
    51.                 {
    52.                     float3 texcoord  : TEXCOORD0;
    53.                     half3 tspace0 : TEXCOORD1;
    54.                     half3 tspace1 : TEXCOORD2;
    55.                     half3 tspace2 : TEXCOORD3;
    56.                     float2 uv : TEXCOORD4;
    57.                     float4 vertex   : SV_POSITION;
    58.                     fixed4 color : COLOR;
    59.                 };
    60.  
    61.                 fixed4 _Color;
    62.  
    63.                 v2f vert(appdata_t IN)
    64.                 {
    65.                     v2f OUT;
    66.                     OUT.vertex = UnityObjectToClipPos(IN.vertex);
    67.                     OUT.texcoord = IN.texcoord;
    68.                     OUT.color = IN.color * _Color;
    69.                     #ifdef PIXELSNAP_ON
    70.                     OUT.vertex = UnityPixelSnap(OUT.vertex);
    71.                     #endif
    72.                     half3 wNormal = UnityObjectToWorldNormal(IN.normal);
    73.                     half3 wTangent = UnityObjectToWorldDir(IN.tangent.xyz);
    74.                     half tangentSign = IN.tangent.w * unity_WorldTransformParams.w;
    75.                     half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
    76.                     OUT.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
    77.                     OUT.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
    78.                     OUT.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
    79.                     OUT.uv = IN.uv;
    80.                     return OUT;
    81.                 }
    82.  
    83.                 sampler2D _MainTex;
    84.                 sampler2D _AlphaTex;
    85.                 float _AlphaSplitEnabled;
    86.  
    87.                 fixed4 SampleSpriteTexture(float2 uv)
    88.                 {
    89.                     fixed4 color = tex2D(_MainTex, uv);
    90.  
    91.     #if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    92.                     if (_AlphaSplitEnabled)
    93.                         color.a = tex2D(_AlphaTex, uv).r;
    94.     #endif
    95.  
    96.                     return color;
    97.                 }
    98.  
    99.                 sampler2D _NormalTex;
    100.                 float4 _AmbientColor;
    101.  
    102.                 fixed4 frag(v2f IN) : SV_Target
    103.                 {
    104.                     half3 tnormal = UnpackNormal(tex2D(_NormalTex, IN.uv));
    105.                     half3 worldNormal;
    106.                     worldNormal.x = dot(IN.tspace0, tnormal);
    107.                     worldNormal.y = dot(IN.tspace1, tnormal);
    108.                     worldNormal.z = dot(IN.tspace2, tnormal);
    109.                     float3 normal = normalize(worldNormal);
    110.                     float NdotL = dot(_WorldSpaceLightPos0, normal);
    111.                     float lightIntensity = NdotL > 0 ? 1 : 0;
    112.                     float4 light = lightIntensity * _LightColor0;
    113.                     fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;
    114.                     c.rgb *= c.a;
    115.                     return c * (_AmbientColor + light);
    116.                 }
    117.             ENDCG  
    118.             }
    119.         }
    120. }
    So it looks different in Scene and Game views. Does anybody know how can I fix it? Btw, this is literally the first time I'm trying writing shaders so I know it's bad and the solution maybe easy, thanks. upload_2020-7-29_12-48-21.png
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,975
    Here are the two key lines that are the problem.
    Code (csharp):
    1. float4 light = lightIntensity * _LightColor0;
    2. // ...
    3. return c * (_AmbientColor + light);
    The light color is affecting the alpha. Specifically the
    _AmbientColor
    &
    _LightColor0
    both have an w component of 1.0, meaning that last line is multiplying the alpha by 2.0, which can do weird things to the resulting blended color value.

    What you should be doing is instead:
    Code (csharp):
    1. float3 light = lightIntensity * _LightColor0.rgb;
    2. // ...
    3. return fixed4(c.rgb * (_AmbientColor.rgb + light), c.a);
     
    davidelucard likes this.
  3. davidelucard

    davidelucard

    Joined:
    Oct 30, 2019
    Posts:
    2
    Wow, thank you so much!

    I spent a lot of time trying to figure it out and had no idea that was the problem. Now I'll make sure to keep alpha in 0 to 1 range.

    Thank you so much again! Now everything looks perfect : )
     
unityunity