- 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