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.
![alt text][1]![alt text][2]
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?
[1]: /storage/temp/176593-without-shader.png
[2]: /storage/temp/176594-with-shader.png
↧