- Home /
Transparency shader
I want to postprocess a camera by simply applying a transparency multiplier. I am expecting the output texture to be the same as the input if the alpha multiplier is 1, but this is not what I get: first pic without shader, 2nd with shader and alpha=1. 

Here is how I use the shader:
public class CameraPostProcessing : MonoBehaviour
{
[SerializeField, Tooltip("Material to apply as post processing.")]
private Material material;
[SerializeField, Tooltip("The camera to apply material on.")]
private Camera assetCamera;
[Range(0, 1), Tooltip("The alpha channel multiplier.")]
public float AlphaMultiplier;
RenderTextureDescriptor mainrtdesc;
RenderTexture tmpRt;
private void OnPreRender()
{
if (material.GetFloat("_Alpha") != AlphaMultiplier)
{
material.SetFloat("_Alpha", AlphaMultiplier);
}
mainrtdesc = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.ARGB32);
tmpRt = RenderTexture.GetTemporary(mainrtdesc);
assetCamera.targetTexture = tmpRt;
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination, material);
}
private void OnPostRender()
{
assetCamera.targetTexture = null;
RenderTexture.ReleaseTemporary(tmpRt);
}
And here is my shader:
Shader "Custom/Transparency" {
Properties {
_MainTex ("Main Texture", 2D) = "white" {}
_Alpha("Alpha Multiplier", Range(0,1)) = 0.5
}
SubShader {
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Lighting Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float _Alpha;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv = v.texcoord;
return o;
}
half4 frag (v2f i) : COLOR
{
half4 color = tex2D(_MainTex, i.uv);
color.w = color.w * _Alpha;
return color;
}
ENDCG
}
}
}
I tried to test the material with the shader like so, where the camera simply sets its background color into a render texture that I use as input:
[Test]
public void Ensures_TransparencyMaterial_CalculatesCorrectColor_When_SemiTransparent()
{
//Arrange
var transparency = .5f;
mat.SetFloat("_Alpha", transparency);
camera.backgroundColor = Color.blue;
camera.Render();
//Act
Graphics.Blit(src, temp, mat);
dst.ReadPixels(new Rect(0, 0, 1, 1), 0, 0);
//Assert
Assert.AreEqual(new Color(0, 0, 1, transparency), dst.GetPixel(0, 0));
}
but this also fails, the resulting color is fully opaque.
Is my shader wrong?
is my post-processing approach wrong?
Answer by g-augview · Mar 22, 2021 at 12:07 AM
I modified my shader to include the background texture like so:
Shader "PostProcessing/AlphaBlend"
{
Properties
{
_MainTex("Main Texture", 2D) = "white" {}
_BackgroundTex("Background Texture", 2D) = "white" {}
_Alpha("Alpha Multiplier", Range(0,1)) = 0.5
}
SubShader{
Tags{ "PreviewType" = "Plane" }
Pass {
ZWrite Off
Lighting Off
ColorMask RGBA
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _BackgroundTex;
float _Alpha;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
float4 frag(v2f_img i) : COLOR
{
float4 color = tex2D(_MainTex, i.uv);
color.a = color.a * _Alpha;
float4 backgroundColor = tex2D(_BackgroundTex, i.uv);
float4 output = (color.a * color + (1-color.a) * backgroundColor);
output.a = 1;
return output;
}
ENDCG
}
}
}
and set the background texture in OnRenderImage.
Your answer
Follow this Question
Related Questions
Use stencil buffer to hide objects with same shader? 1 Answer
Post effect shader similar to "Shannara Chronicles" intro's edge smoke effect 0 Answers
Weird Transparency behaviour when using ShaderGraph in LWRP and setting alpha to 1 0 Answers
transparent object, so everything behind it appears in grayscale 1 Answer