- Home /
 
How to make a Diffused Shader on top of a Vertex Shader? For Billboard Sprites to show in front of 3D Meshes.
I'm basically trying to make a shader where Sprites won't be clipped by 3D meshes but still have a Diffused look to them (interact with lights).
Currently I'm trying to use a Diffuse shader, grab its texture with GrabPass and modify it with bgolus' VerticalZDepthBillboard shader from here
It semi-works but the Sprite loses its pixel perfectness and the alpha channel is gone (the sprite now has a solid background where it should be transparent).

Here is my shader code:
 Shader "Custom/BillboardVerticalZDepthSpriteDiffuse"
 {
     Properties
     {
         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
         _Color ("Tint", Color) = (1,1,1,1)
         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
         [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
         [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
         [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
         [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
     }
  
     SubShader
     {
         Tags{
             "Queue" = "Transparent"
             "IgnoreProjector" = "True"
             "RenderType" = "Transparent"
             "DisableBatching" = "True"
 
             /// Diffuse
             "PreviewType"="Plane"
             "CanUseSpriteAtlas"="True"
         }
  
         ZWrite Off
         Blend One OneMinusSrcAlpha
 
         // Diffuse
         Cull Off
         Lighting Off
 
         // Diffuse program
         CGPROGRAM
         #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
         #pragma multi_compile_local _ PIXELSNAP_ON
         #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
         #include "UnitySprites.cginc"
 
         struct Input
         {
             float2 uv_MainTex;
             fixed4 color;
         };
 
         void vert (inout appdata_full v, out Input o)
         {
             v.vertex = UnityFlipSprite(v.vertex, _Flip);
 
             #if defined(PIXELSNAP_ON)
             v.vertex = UnityPixelSnap (v.vertex);
             #endif
 
             UNITY_INITIALIZE_OUTPUT(Input, o);
             o.color = v.color * _Color * _RendererColor;
         }
 
         void surf (Input IN, inout SurfaceOutput o)
         {
             fixed4 c = SampleSpriteTexture (IN.uv_MainTex) * IN.color;
             o.Albedo = c.rgb * c.a;
             o.Alpha = c.a;
         }
         ENDCG
 
         // Grab Diffused screen data texture
         GrabPass
         {
             "_DiffusedTex"
         }
 
         Pass
         {
             Blend SrcAlpha OneMinusSrcAlpha
             
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             // make fog work
             #pragma multi_compile_fog
  
             #include "UnityCG.cginc"
  
             struct appdata
             {
                 float4 vertex : POSITION;
                 float2 grabPos : TEXCOORD0;
             };
  
             struct v2f
             {
                 float4 pos : SV_POSITION;
                 float2 grabPos : TEXCOORD0;
                 UNITY_FOG_COORDS(1)
             };
  
             sampler2D _DiffusedTex;
             float4 _MainTex_ST;
  
             float rayPlaneIntersection( float3 rayDir, float3 rayPos, float3 planeNormal, float3 planePos)
             {
                 float denom = dot(planeNormal, rayDir);
                 denom = max(denom, 0.000001); // avoid divide by zero
                 float3 diff = planePos - rayPos;
                 return dot(diff, planeNormal) / denom;
             }
  
             v2f vert(appdata v)
             {
                 v2f o;
                 o.pos = UnityObjectToClipPos(v.vertex);
                 
                 v.grabPos = ComputeGrabScreenPos(o.pos); // get correct texture coordinates
                 o.grabPos = v.grabPos.xy;
  
                 // billboard mesh towards camera
                 float3 vpos = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
                 float4 worldCoord = float4(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23, 1);
                 float4 viewPos = mul(UNITY_MATRIX_V, worldCoord) + float4(vpos, 0);
  
                 o.pos = mul(UNITY_MATRIX_P, viewPos);
  
                 // calculate distance to vertical billboard plane seen at this vertex's screen position
                 float3 planeNormal = normalize(float3(UNITY_MATRIX_V._m20, 0.0, UNITY_MATRIX_V._m22));
                 float3 planePoint = unity_ObjectToWorld._m03_m13_m23;
                 float3 rayStart = _WorldSpaceCameraPos.xyz;
                 float3 rayDir = -normalize(mul(UNITY_MATRIX_I_V, float4(viewPos.xyz, 1.0)).xyz - rayStart); // convert view to world, minus camera pos
                 float dist = rayPlaneIntersection(rayDir, rayStart, planeNormal, planePoint);
  
                 // calculate the clip space z for vertical plane
                 float4 planeOutPos = mul(UNITY_MATRIX_VP, float4(rayStart + rayDir * dist, 1.0));
                 float newPosZ = planeOutPos.z / planeOutPos.w * o.pos.w;
  
                 // use the closest clip space z
                 #if defined(UNITY_REVERSED_Z)
                 o.pos.z = max(o.pos.z, newPosZ);
                 #else
                 o.pos.z = min(o.pos.z, newPosZ);
                 #endif
  
                 UNITY_TRANSFER_FOG(o,o.vertex);
                 return o;
             }
  
             fixed4 frag(v2f i) : SV_Target
             {
                 fixed4 col = tex2D(_DiffusedTex, i.grabPos);
                 UNITY_APPLY_FOG(i.fogCoord, col);
  
                 return col;
             }
             ENDCG
         }
     }
         
     Fallback "Transparent/VertexLit"
 }
 
               
                 
                screen-shot-2021-01-06-at-91825-pm.png 
                (46.8 kB) 
               
 
              
               Comment
              
 
               
              Your answer
 
             Follow this Question
Related Questions
Shader: 1 Base Texture Overlaid by 1 Transparent Texture. 0 Answers
Shader: get back scene pixel color? 1 Answer
Changing Texture From a Point? 0 Answers
Unity Advanced Shader Help 0 Answers
viewDir changes with o.Normal 1 Answer