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. Dismiss Notice

Question Vert/Frag Shader with Shadows and simple Lightning? (InstancedIndirect)

Discussion in 'Shaders' started by FE-Games, Apr 14, 2021.

  1. FE-Games

    FE-Games

    Joined:
    Jul 1, 2020
    Posts:
    15
    Hello,
    iam new in making shaders and i only need simple things, here is my current shader.
    The whole shader is self made using several examples on the net.

    Code (CSharp):
    1. Shader "Instanced/InstancedVertexShader" {
    2.  
    3.     CGINCLUDE
    4.     #pragma vertex vert
    5.     #pragma fragment frag
    6.     StructuredBuffer<fixed4> positionBuffer;
    7.     StructuredBuffer<fixed4> colorBuffer;
    8.     ENDCG
    9.  
    10.     SubShader {
    11.         Tags {"RenderType"="Opaque" "IgnoreProjector"="True" "DisableBatching"="True"}
    12.         //"Queue"="Transparent"
    13.         Blend SrcAlpha OneMinusSrcAlpha
    14.         LOD 80
    15.  
    16.         Pass {
    17.             Tags {"LightMode"="ForwardBase"}
    18.             Cull Off
    19.             ZWrite Off
    20.             CGPROGRAM
    21.             #include "UnityCG.cginc"
    22.            
    23.             #pragma multi_compile_fwdbase
    24.             #include "AutoLight.cginc"
    25.        
    26.            
    27.             struct v2f
    28.             {
    29.                 fixed4 vertex : SV_POSITION;
    30.                 fixed4 color : COLOR0;
    31.                
    32.                 float2 uv : TEXCOORD0;
    33.                 float4 _ShadowCoord : TEXCOORD1;
    34.             };
    35.            
    36.             float4 ComputeScreenPos (float4 p)
    37.             {
    38.                 float4 o = p * 0.5;
    39.                 return float4(o.x + o.w, o.y*_ProjectionParams.x + o.w, p.zw);  
    40.             }
    41.  
    42.             v2f vert(appdata_base v, uint instanceID : SV_InstanceID) {
    43.                
    44.                 fixed4 data = positionBuffer[instanceID];  
    45.                 fixed4 color = colorBuffer[instanceID];
    46.                 fixed3 localPosition = v.vertex.xyz * data.w;
    47.                 fixed3 worldPosition = data.xyz + localPosition;
    48.                 fixed3 worldNormal = v.normal;
    49.                                
    50.                 v2f o;
    51.                 o.vertex = mul(UNITY_MATRIX_VP, fixed4(worldPosition, 1.0f));
    52.                 o.color = color;
    53.                
    54.                 o._ShadowCoord = ComputeScreenPos(o.vertex);
    55.            
    56.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    57.                 return o;
    58.             }
    59.            
    60.             fixed4 frag (v2f i) : SV_Target
    61.             {
    62.                 float attenuation = SHADOW_ATTENUATION(i);
    63.                 return i.color * attenuation;
    64.             }
    65.             ENDCG
    66.         }
    67.     }
    68. }

    So the problem is, when i use "Fallback VertexLit", the shadow seem to little for the whole instanced objekt.

    I need to solve the following problems:
    - Receive Shadows
    - Cast Shadows
    - Uses Light (Only One Directional and some Point Lights if possible)
    - Transparency with shadows?

    Currently transparency works and i can change color and position of the objekts.

    Unfortunately, I don't know much about shaders, but I need this shader and want to learn.

    I would be very happy if someone can help me understand better.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    I'd recommend looking at Unity's example Surface shader here:
    https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedIndirect.html

    That will be capable of all of the things listed above, and you can look at the generated code if you want to see what the individual vertex fragment shader passes the Surface Shader generates looks like.

    However...
    That throws a wrench in things.

    Transparent objects can cast shadows, but Surface Shaders set to be transparent won't generate appropriate shadow caster passes to do so. Also Unity does not support transparent shadows, it can only emulate them with alpha tested shadows. The built in Standard shader goes a step further and uses dithered alpha tested shadows, but that's something you'd have to write manually. I'd recommend Catlike Coding if you want to read up more on that topic.
    https://catlikecoding.com/unity/tutorials/rendering/

    The TLDR version is Unity's built in lighting system requires multiple different shader passes. So if you need to support shadow casting you need a shadow casting pass that reads and uses the same data as your custom forward base pass. If you want to support multiple point lights you need a forward add pass that also uses that data.

    But a bigger problem is Unity does not support transparent objects receiving shadows. Full stop. If an object is transparent, it will not receive shadows, at all. You can work around this with some custom scripts and shaders if you only need to support a single directional light. I linked to a project (and the specific files that are useful for this goal) here:
    https://forum.unity.com/threads/no-shadows-visible-on-transparency-shaders.9909/page-3#post-4914971
    To use those you'll want to not use a Surface Shader, so I'd recommend the Catlike Coding tutorials again so you can better understand what you're doing.
     
  3. FE-Games

    FE-Games

    Joined:
    Jul 1, 2020
    Posts:
    15
    Okay thank you for this.
    I got Lightning and Skybox Reflections and some other things working now.
    But one thing is still buggy.

    I have a solid object generated by Graphics.DrawMeshIndirect but the shadow is way too small, how can I fix it?
    UsePass "VertexLit/SHADOWCASTER" makes the shadow but i doent seems to work for DrawMeshObjekts.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,238
    No idea, what does the shadow caster code look like? What exactly does the shadow look like? Like how "way too small" is it? Is it not working at all and only shadowing from the world pivot small, or not taking instance scale into account too small, or you have the lights' normal bias cranked up to max too small?
     
  5. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,068
  6. FE-Games

    FE-Games

    Joined:
    Jul 1, 2020
    Posts:
    15