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

Issue receiving shadow on transparent object

Discussion in 'Shaders' started by mineas312, Aug 4, 2021.

  1. mineas312

    mineas312

    Joined:
    Aug 4, 2021
    Posts:
    4
    Hi, I am trying to create 2D billboard grass that could be shaded. Texture contains pixels that are transparent and not. I want to shadow appear only on not transparent pixels but i get strange outcome. If I look on other objects they are also shaded:
    upload_2021-8-4_18-44-36.png
    Looking at sky works well:
    upload_2021-8-4_18-46-19.png
    Shader code:
    Code (CSharp):
    1. Shader "PixelEngine/Grass"
    2.  
    3. {
    4.  
    5.     Properties
    6.  
    7.     {
    8.  
    9.         _MainTex("Texture", 2D) = "white" {}
    10.  
    11.         _Normal("Normal", Vector) = (0.0, 0.0, 0.0, 0.0)
    12.  
    13.         _Position("Normal", Vector) = (0.0, 0.0, 0.0, 0.0)
    14.  
    15.         _Color("Color", Color) = (1.0, 1.0, 1.0, 1.0)
    16.  
    17.  
    18.  
    19.         _SemiShadowThreshold("Semi-Shadow Threshold", Range(0.0, 1.0)) = 0.4
    20.  
    21.         _SemiShadowColor("Semi-Shadow Color", Color) = (0.5, 0.5, 0.5, 0.5)
    22.  
    23.  
    24.  
    25.         _ShadowThreshold("Shadow Threshold", Range(0.0, 1.0)) = 0.0
    26.  
    27.         _ShadowColor("Shadow Color", Color) = (0.0, 0.0, 0.0, 0.0)
    28.  
    29.     }
    30.  
    31.     SubShader
    32.  
    33.     {
    34.  
    35.         Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout" "LightMode"="ForwardBase" }
    36.  
    37.         Blend SrcAlpha OneMinusSrcAlpha
    38.  
    39.         AlphaToMask On
    40.  
    41.         Pass
    42.  
    43.         {
    44.  
    45.             CGPROGRAM
    46.  
    47.             #pragma vertex vert
    48.  
    49.             #pragma fragment frag
    50.  
    51.             #pragma multi_compile_fwdbase
    52.  
    53.             #pragma multi_compile_instancing
    54.  
    55.  
    56.  
    57.             #include "UnityCG.cginc"
    58.  
    59.             #include "AutoLight.cginc"
    60.  
    61.  
    62.  
    63.             uniform fixed4 _LightColor0;
    64.  
    65.  
    66.  
    67.             uniform sampler2D _MainTex;
    68.  
    69.             uniform float4 _MainTex_ST;
    70.  
    71.  
    72.  
    73.             uniform fixed4 _Color;
    74.  
    75.             uniform fixed4 _ShadowColor;
    76.  
    77.             uniform fixed4 _SemiShadowColor;
    78.  
    79.             uniform fixed _ShadowThreshold;
    80.  
    81.             uniform fixed _SemiShadowThreshold;
    82.  
    83.  
    84.  
    85.             UNITY_INSTANCING_BUFFER_START(Props)
    86.  
    87.              
    88.  
    89.             UNITY_DEFINE_INSTANCED_PROP(float3, _Normal)
    90.  
    91.             UNITY_DEFINE_INSTANCED_PROP(float3, _Position)
    92.  
    93.  
    94.  
    95.             UNITY_INSTANCING_BUFFER_END(Props)
    96.  
    97.  
    98.  
    99.             struct vertexInput
    100.  
    101.             {
    102.  
    103.                 float4 vertex : POSITION;
    104.  
    105.                 float2 uv : TEXCOORD0;
    106.  
    107.                 float3 normal : NORMAL;
    108.  
    109.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    110.  
    111.             };
    112.  
    113.  
    114.  
    115.             struct vertexOutput
    116.  
    117.             {
    118.  
    119.                 float4 pos : SV_POSITION;
    120.  
    121.                 float2 uv : TEXCOORD0;
    122.  
    123.                 float3 worldPos : TEXCOORD1;
    124.  
    125.                 float3 normal : TEXCOORD2;
    126.  
    127.  
    128.  
    129.                 LIGHTING_COORDS(3, 4)
    130.  
    131.                 UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if you want to access instanced properties in fragment Shader.
    132.  
    133.             };
    134.  
    135.  
    136.  
    137.             vertexOutput vert(vertexInput v)
    138.  
    139.             {
    140.  
    141.                 vertexOutput o;
    142.  
    143.  
    144.  
    145.                 UNITY_SETUP_INSTANCE_ID(v);
    146.  
    147.                 UNITY_TRANSFER_INSTANCE_ID(v, o); // necessary only if you want to access instanced properties in the fragment Shader.
    148.  
    149.  
    150.  
    151.                 o.pos = mul(UNITY_MATRIX_P,
    152.  
    153.                     mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    154.  
    155.                     + float4(v.vertex.x, v.vertex.y, 0.0, 0.0));
    156.  
    157.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    158.  
    159.                 o.normal = normalize(UnityObjectToWorldNormal(UNITY_ACCESS_INSTANCED_PROP(Props, _Normal)));
    160.  
    161.                 o.worldPos = mul(unity_ObjectToWorld, v.vertex);
    162.  
    163.  
    164.  
    165.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    166.  
    167.  
    168.  
    169.                 return o;
    170.  
    171.             }
    172.  
    173.  
    174.  
    175.             fixed4 frag (vertexOutput i) : SV_Target
    176.  
    177.             {
    178.  
    179.                 UNITY_SETUP_INSTANCE_ID(i); // necessary only if any instanced properties are going to be accessed in the fragment Shader.
    180.  
    181.  
    182.  
    183.                 // Calculate light
    184.  
    185.                 float attenuation = LIGHT_ATTENUATION(i);
    186.  
    187.                 fixed3 lightDir;
    188.  
    189.                 if(_WorldSpaceLightPos0.w == 0.0)
    190.  
    191.                 {
    192.  
    193.                     lightDir = normalize(_WorldSpaceLightPos0.xyz);
    194.  
    195.                 }
    196.  
    197.                 else
    198.  
    199.                 {
    200.  
    201.                     float3 objToLight = _WorldSpaceLightPos0.xyz - i.worldPos;
    202.  
    203.                     lightDir = normalize(objToLight);
    204.  
    205.                 }
    206.  
    207.  
    208.  
    209.                 // Calculate shadow
    210.  
    211.                 fixed3 diffuse = saturate(dot(lightDir, i.normal)) * attenuation;
    212.  
    213.  
    214.  
    215.                 // Color ramp
    216.  
    217.                 fixed4 color;
    218.  
    219.                 color = diffuse.r <= _SemiShadowThreshold ? _SemiShadowColor : _Color;
    220.  
    221.                 color = diffuse.r <= _ShadowThreshold ? _ShadowColor : color;
    222.  
    223.  
    224.  
    225.                 // Add light color
    226.  
    227.                 color = color * _LightColor0;
    228.  
    229.  
    230.  
    231.                 // Apply grass texture and light color
    232.  
    233.                 color = fixed4(color.rgb, tex2D(_MainTex, i.uv).a);
    234.  
    235.                 return color;
    236.  
    237.             }
    238.  
    239.             ENDCG
    240.  
    241.         }
    242.  
    243.     }
    244.  
    245.     Fallback "VertexLit"
    246.  
    247. }
    248.  
    249.  
    250.  

    Maybe someone will advise me how to do that better. I am trying to achive simillar results to that shown in this video (but shadow receiving got me):
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    You need a shadow caster pass for this shader that uses
    clip(color.a - 0.5)
    . Unity's directional shadows cast onto the camera depth texture, which is generated by rendering opaque objects with a shadow caster pass from the camera's view.
     
    tomasz_gamigo likes this.
  3. tomasz_gamigo

    tomasz_gamigo

    Joined:
    Jul 21, 2022
    Posts:
    1
    Hey bgolus what would you suggest to someone less experienced in code, working in shader graph and also experiencing no shadows on objects using alpha masks?

    upload_2022-9-1_14-15-51.png

    upload_2022-9-1_14-17-20.png