I try to create a shader decal. The result is a transparent object with no image decal. I use simple URP project.
I use a PNG file for the decal and this shader, any idea why this does not work?
Shader "Custom/Decals001" {
//show these to the inspector
Properties{
//[HDR] _Color ("Tint", Color) = (0, 0, 0, 1)
_Color ("Tint", Color) = (0, 0, 0, 1.5)
_MainTex ("Texture", 2D) = "white" {}
_Clip ("Clip", Range(0,1)) = 0.5
}
SubShader{
//set tags for material is completely transparent
Tags{ "RenderType"="Transparent" "Queue"="Transparent-400" "DisableBatching"="True"}
//Blend via alpha
Blend SrcAlpha OneMinusSrcAlpha
//don't write to zbuffer because I have semitransparency, I think this ZWrite can be the reason
//ZWrite Off
Pass{
CGPROGRAM
//include useful shader functions
#include "UnityCG.cginc"
//define vertex and fragment shader functions
#pragma vertex vert
#pragma fragment frag
//texture and transforms of the texture
sampler2D _MainTex;
float4 _MainTex_ST;
//tint of the texture
fixed4 _Color;
float _Clip;
sampler2D_float _CameraDepthTexture;
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 position : SV_POSITION;
float4 screenPos : TEXCOORD0;
float3 ray : TEXCOORD1;
};
//the vertex shader function
v2f vert(appdata v)
{
v2f o;
//use vertex positions from object space to clip space
float3 worldPos = mul(unity_ObjectToWorld, v.vertex);
o.position = UnityWorldToClipPos(worldPos);
//get the ray between the camera to the vertex
o.ray = worldPos - _WorldSpaceCameraPos;
//screen position
o.screenPos = ComputeScreenPos(o.position);
return o;
}
float3 getProjectedObjectPos(float2 screenPos, float3 worldRay)
{
//get depth from a depth texture
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
depth = Linear01Depth(depth) * _ProjectionParams.z;
//get a ray thats 1 long on the axis from the camera
worldRay = normalize(worldRay);
//the 3rd row of the view matrix has the camera forward vector and dot product direction
worldRay /= dot(worldRay, -UNITY_MATRIX_V[2].xyz);
// object space positions
float3 worldPos = _WorldSpaceCameraPos + worldRay * depth;
float3 objectPos = mul(unity_WorldToObject, float4(worldPos, 1.0 - _Clip )).xyz;
//change scard pixels +-0.5, i used _Clip
clip(_Clip - abs(objectPos));
//return objectPos
objectPos += 0.0+_Clip;
return objectPos;
}
//the fragment shader function
fixed4 frag(v2f i) : SV_TARGET
{
//screenspace by uv
float2 screenUv = i.screenPos.xy / i.screenPos.w;
float2 uv = getProjectedObjectPos(screenUv, i.ray).xz;
//read the texture color by uv coordinate
fixed4 col = tex2D(_MainTex, uv);
//multiply the texture color with tint color
col *= _Color;
//return the final color
return col;
}
ENDCG
}
}
}