To give a brief explanation, what I’m trying to smoothly transition from one camera to another. The first camera’s scene is rendered to a texture, which is displayed in front of the second camera, and then faded out to provide a smooth transition. The transition is blended using a second grayscale texture that provides the transition effect we desire.Said transition texture might look something like this:

I’m not very well experienced at writing shaders, but I put together something rather basic using a Cutoff range to control the current state of the transition. The shader is as follows:
Shader "Custom/TransitionShader" {
Properties {
_Cutoff ("Cutoff", Range (0,1)) = 0.5
_MainTex ("Base (RGB)", 2D) = "white" {}
_AlphaTex ("Mask", 2D) = "white" {}
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
LOD 200
CGPROGRAM
#pragma surface surf Lambert alpha
sampler2D _MainTex;
sampler2D _AlphaTex;
float _Cutoff;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
float d = tex2D (_AlphaTex, IN.uv_MainTex).r; //Doesn't matter what color we take since it's greyscale
o.Albedo = c.rgb;
if(d > _Cutoff)
o.Alpha = 1;
else
o.Alpha = 0;
}
ENDCG
}
Fallback "Diffuse"
}
So that works, but there’s two issues.
- The cutoff is a hard edge; either it displays or it doesn’t. What I really want is a soft cutoff, like scale the alpha from a +/- range from the cutoff using a second range. So for example, So if cutoff is 0.6, and cutoff range is 0.1, a grayscale value of 0.5 should give alpha of 0, and a grayscale value of 0.7 should give alpha of 1. I’m not sure how I’d math this one out though.
- This shader takes in lighting from the environment, which it shouldn’t since the rendertexture is already lit. Most things I’ve seen on the subject suggest I shouldn’t be using a cg surface shader if I don’t want lighting, or I could specify my own lighting, but I don’t really understand either option. Again I’m pretty dumb with shaders.
Any idea how I could handle these issues?
Edit:
I’ve solved the blending issue with the relatively simple (in hindsight) code:
float r = _Cutoff * (1 + _CutoffRange * 2) - _CutoffRange;
o.Alpha = (d - r) * (1 / (_CutoffRange));
Now just to figure out how to do an unlit cg surface shader…
Edit2:
I’ve resolved all the issues. For reference, here’s the final shader:
Shader "Custom/TransitionShader" {
Properties {
_Cutoff ("Cutoff", Range (0,1)) = 0.5
_CutoffRange ("Cutoff Range", Range (0,1)) = 0.1
_MainTex ("Base (RGB)", 2D) = "white" {}
_AlphaTex ("Mask", 2D) = "white" {}
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
LOD 200
Lighting OFF
CGPROGRAM
#pragma surface surf Unlit alpha noambient novertexlights nodirlightmap nolightmap noforwardadd
half4 LightingUnlit (SurfaceOutput s, half3 dir, half atten) {
fixed4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
sampler2D _MainTex;
sampler2D _AlphaTex;
half _Cutoff;
half _CutoffRange;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
half d = tex2D (_AlphaTex, IN.uv_MainTex).r;
o.Albedo = c.rgb;
half r = _Cutoff * (1 + _CutoffRange * 2) - _CutoffRange;
o.Alpha = (d - r) * (1 / (_CutoffRange));
}
ENDCG
}
Fallback "Diffuse"
}
Feel free to point out any bad looking code. Here’s how it looks in motion: