Search Unity

Resolved Shadow caster billboard to camera

Discussion in 'Shaders' started by mineas312, Dec 21, 2021.

  1. mineas312

    mineas312

    Joined:
    Aug 4, 2021
    Posts:
    4
    Shadow caster code:
    Code (CSharp):
    1. Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest" "LightMode" = "ShadowCaster" }
    2.     Blend SrcAlpha OneMinusSrcAlpha
    3.     AlphaToMask On
    4.     Pass
    5.     {
    6.         CGPROGRAM
    7.         #pragma vertex vert
    8.         #pragma fragment frag
    9.         #pragma multi_compile_instancing
    10.      
    11.         #include "UnityCG.cginc"
    12.  
    13.         struct appdata
    14.         {
    15.             float4 vertex : POSITION;
    16.             float2 uv : TEXCOORD0;
    17.             UNITY_VERTEX_INPUT_INSTANCE_ID
    18.         };
    19.  
    20.         struct v2f
    21.         {
    22.             float2 uv : TEXCOORD0;
    23.             float4 pos : SV_POSITION;
    24.         };
    25.  
    26.         uniform sampler2D _MainTex;
    27.         uniform float4 _MainTex_ST;
    28.  
    29.         UNITY_INSTANCING_BUFFER_START(Props)
    30.         UNITY_DEFINE_INSTANCED_PROP(float4, _Pos)
    31.         UNITY_INSTANCING_BUFFER_END(Props)
    32.  
    33.         v2f vert (appdata v)
    34.         {
    35.             v2f o;
    36.             UNITY_SETUP_INSTANCE_ID(v);
    37.  
    38. float3 vpos = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
    39. float4 worldCoord = float4(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23, 1);
    40. float4 viewPos = mul(UNITY_MATRIX_V, worldCoord) + float4(vpos, 0);
    41. float4 outPos = mul(UNITY_MATRIX_P, viewPos);
    42.  
    43.             o.pos = outPos;
    44.             o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    45.             return o;
    46.         }
    47.  
    48.         fixed4 frag (v2f i) : SV_Target
    49.         {
    50.             fixed4 tex = tex2D(_MainTex, i.uv);
    51.             clip(tex.a - 0.1);
    52.  
    53.             return 0;
    54.         }
    55.         ENDCG
    56.     }

    Could someone tell me how to make shadow caster billboard effect rotate towards camera, not the caster itself? It causes visual glitches like this:
    upload_2021-12-21_1-32-21.png
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    You need to calculate the orientation in world space using a view matrix that is always for the main camera itself. For example
    UNITY_MATRIX_V
    is the current view matrix being used for rendering. You’d need to use something like:
    Code (csharp):
    1. worldCoord.xyz += mul((float3x3)unity_CameraToWorld, vpos);
    2. float4 outPos = mul(UNITY_MATRIX_VP, worldCoord);
     
    mineas312 likes this.
  3. mineas312

    mineas312

    Joined:
    Aug 4, 2021
    Posts:
    4
    Now I understand that my technique is wrong. The shadow looks properly only if sprite is shaded from behind (no zwrite):
    upload_2021-12-22_2-17-18.png
    But from the other side:
    upload_2021-12-22_2-17-48.png

    My question now is: How is it possible to shade billboard grass?
    Should I take another approach or just make a little change?

    Also if you could guys recommend any good tutorials to learn more complex shaders with problems like this. T

    My code:

    Code (ShaderLab):
    1. Shader "Engine/GrassShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _Color ("Color", Color) = (0, 1.0, 0, 1)
    7.         _Normal("Normal", Vector) = (0.0, 0.0, 0.0, 0.0)
    8.         _Pos("Normal", Vector) = (0.0, 0.0, 0.0, 0.0)
    9.         _SemiShadow("Semi Shadow", Color) = (0, 0.6, 0, 1)
    10.         _SemiShadowThreshold("Semi Shadow Threshold", Float) = 0.4
    11.         _Shadow("Shadow", Color) = (0, 0.3, 0, 1)
    12.         _ShadowThreshold("Shadow Threshold", Float) = 0.2
    13.         _TestTex("TestTex", 2D) = "white" {}
    14.     }
    15.     SubShader
    16.     {
    17.         Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest" "LightMode"="ForwardBase" }
    18.         Blend SrcAlpha OneMinusSrcAlpha
    19.         AlphaToMask On
    20.         Pass
    21.         {
    22.             CGPROGRAM
    23.             #pragma vertex vert
    24.             #pragma fragment frag
    25.             #pragma multi_compile_instancing
    26.             #pragma multi_compile_fwdbase
    27.  
    28.             #define FORWARD_BASE_PASS
    29.  
    30.             #include "UnityCG.cginc"
    31.             #include "UnityLightingCommon.cginc"
    32.             #include "AutoLight.cginc"
    33.             #include "Lighting.cginc"
    34.  
    35.             struct appdata
    36.             {
    37.                 float4 vertex : POSITION;
    38.                 float2 uv : TEXCOORD0;
    39.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    40.             };
    41.  
    42.             struct v2f
    43.             {
    44.                 float2 uv : TEXCOORD0;
    45.                 float4 pos : SV_POSITION;
    46.                 float3 normal : NORMAL;
    47.                 float3 worldPos : TEXCOORD1;
    48.                 SHADOW_COORDS(2)
    49.             };
    50.            
    51.             uniform sampler2D _TestTex;
    52.             uniform float4 _TestTex_ST;
    53.  
    54.             uniform sampler2D _MainTex;
    55.             uniform float4 _MainTex_ST;
    56.             uniform float3 _Color;
    57.             uniform float3 _SemiShadow;
    58.             uniform float _SemiShadowThreshold;
    59.             uniform float3 _Shadow;
    60.             uniform float _ShadowThreshold;
    61.  
    62.             UNITY_INSTANCING_BUFFER_START(Props)
    63.             UNITY_DEFINE_INSTANCED_PROP(float4, _Normal)
    64.             UNITY_DEFINE_INSTANCED_PROP(float4, _Pos)
    65.             UNITY_INSTANCING_BUFFER_END(Props)
    66.  
    67.             v2f vert (appdata v)
    68.             {
    69.                 v2f o;
    70.                 UNITY_SETUP_INSTANCE_ID(v);
    71.  
    72.                 float3 vpos = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
    73.                 float4 worldCoord = float4(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23, 1);
    74.                 float4 viewPos = mul(UNITY_MATRIX_V, worldCoord) + float4(vpos, 0);
    75.                 float4 outPos = mul(UNITY_MATRIX_P, viewPos);
    76.                
    77.                 o.worldPos = mul(unity_ObjectToWorld, v.vertex);
    78.  
    79.                 o.pos = outPos;
    80.                 o.normal = normalize(UnityObjectToWorldNormal(UNITY_ACCESS_INSTANCED_PROP(Props, _Normal)));
    81.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    82.                 TRANSFER_SHADOW(o)
    83.                 return o;
    84.             }
    85.  
    86.             fixed4 frag (v2f i) : SV_Target
    87.             {
    88.                 fixed4 tex = tex2D(_MainTex, i.uv);
    89.                 clip(tex.a);
    90.                
    91.                 UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
    92.  
    93.                 float diffuse = dot(i.normal, _WorldSpaceLightPos0.xyz) * atten;
    94.                 float3 cel = diffuse < _ShadowThreshold ? _Shadow : (diffuse < _SemiShadowThreshold ? _SemiShadow : _Color);
    95.                 fixed4 col = fixed4(cel * _LightColor0, tex.a);
    96.  
    97.                 #if defined(FORWARD_BASE_PASS)
    98.                     col += float4(max(0, ShadeSH9(float4(i.normal, 1))).rgb, 0.0);
    99.                 #endif
    100.  
    101.                 return col;
    102.             }
    103.             ENDCG
    104.         }
    105.        
    106.         Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest" "LightMode" = "ShadowCaster" }
    107.         Blend SrcAlpha OneMinusSrcAlpha
    108.         AlphaToMask On
    109.         Pass
    110.         {
    111.             CGPROGRAM
    112.             #pragma vertex vert
    113.             #pragma fragment frag
    114.             #pragma multi_compile_instancing
    115.            
    116.             #include "UnityCG.cginc"
    117.  
    118.             struct appdata
    119.             {
    120.                 float4 vertex : POSITION;
    121.                 float2 uv : TEXCOORD0;
    122.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    123.             };
    124.  
    125.             struct v2f
    126.             {
    127.                 float2 uv : TEXCOORD0;
    128.                 float4 pos : SV_POSITION;
    129.             };
    130.  
    131.             uniform sampler2D _MainTex;
    132.             uniform float4 _MainTex_ST;
    133.  
    134.             UNITY_INSTANCING_BUFFER_START(Props)
    135.             UNITY_DEFINE_INSTANCED_PROP(float4, _Pos)
    136.             UNITY_INSTANCING_BUFFER_END(Props)
    137.  
    138.             v2f vert (appdata v)
    139.             {
    140.                 v2f o;
    141.                 UNITY_SETUP_INSTANCE_ID(v);
    142.  
    143.                 float3 vpos = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
    144.                 float4 worldCoord = float4(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23, 1);
    145.                 worldCoord.xyz += mul((float3x3)unity_CameraToWorld, vpos);
    146.                 float4 outPos = mul(UNITY_MATRIX_VP, worldCoord);
    147.  
    148.                 o.pos = outPos;
    149.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    150.                 return o;
    151.             }
    152.  
    153.             fixed4 frag (v2f i) : SV_Target
    154.             {
    155.                 fixed4 tex = tex2D(_MainTex, i.uv);
    156.                 clip(tex.a - 0.1);
    157.  
    158.                 return 0;
    159.             }
    160.             ENDCG
    161.         }
    162.     }
    163. }
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    That just looks like you like the look of the grass with shadow casting disabled. Regardless of how you’re rendering the grass, there should be an option to disable the shadow casting, either on the component or the script function being used.
     
    mineas312 likes this.
  5. mineas312

    mineas312

    Joined:
    Aug 4, 2021
    Posts:
    4
    Oh, I forgot to disable shadow casting in script, right. Thanks alot!