- Home /
Modifying a Projector shader to 'project' opacity onto transparent mesh
Hello everyone! So I created a basic unlit shader that gives me a square of full opacity on a transparent terrain mesh as you can see below:
It is a modified Unlit surface shader:
Shader "Custom/FadingTerrainShader"
{
Properties
{
_Position("Position", Vector) = (.0, .0, .0)
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 worldPos : uv;
};
uniform float3 _Position;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldPos = mul (unity_ObjectToWorld, v.vertex);
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float x_fade = 0.0;
float z_fade = 0.0;
float fade_factor = 0.5;
x_fade = clamp(i.worldPos.x, -10.0, 10.0);
x_fade = 1 - ((abs(x_fade) - 8.0) * fade_factor);
z_fade = clamp(i.worldPos.z, -10.0, 10.0);
z_fade = 1 - ((abs(z_fade) - 8.0) * fade_factor);
col.a = clamp(x_fade * z_fade, 0, 1);
return col;
}
ENDCG
}
}
}
However I'm trying to figure out a way to achieve a similar result with a projector, which would allow me a lot more flexibility than having to use the world coordinates to define edge fading, like the shader above does. This is what I've currently been able to get to with a projector:
Shader "Projector/NewProjector" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_ShadowTex ("Cookie", 2D) = "" {}
_FalloffTex ("FallOff", 2D) = "" {}
}
Subshader {
Pass {
ZWrite Off
Blend DstColor SrcColor
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 uvShadow : TEXCOORD0;
float4 uvFalloff : TEXCOORD1;
float4 pos : SV_POSITION;
};
float4x4 unity_Projector;
float4x4 unity_ProjectorClip;
v2f vert (float4 vertex : POSITION)
{
v2f o;
o.pos = UnityObjectToClipPos (vertex);
o.uvShadow = mul (unity_Projector, vertex);
o.uvFalloff = mul (unity_ProjectorClip, vertex);
return o;
}
fixed4 _Color;
sampler2D _ShadowTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
fixed4 res = float4(_Color.r, _Color.g, _Color.b, texS.a) * texS;
return res;
}
ENDCG
}
}
}
The GIF above shows the projector working on Standard surface shaders for the trees and ground, however I cannot figure out how to turn the black regions into transparent ones. I appreciate any input you might have that could help me create this effect that would allow me to turn it into a square and place this spotlight anywhere on the mesh to reveal it. Thanks!! -- Cade
I should also mention that I am looking to also allow the cutout/transparency effect of tree branches to still work, but just fade to 0 when the projector area moves away - I have definitely been struggling with this since I am not very experienced with shaders :(