解决 Unity Canvas 相机 RenderTarget 渲染颜色透明度异常的问题
问题
重现场景
新建一个
Canvas-RT
,Canvas Render Mode
改为Screen Space - Camera
。
![0017f22d7245876d03de0af19fb8efad.png](https://img-blog.csdnimg.cn/img_convert/0017f22d7245876d03de0af19fb8efad.png)
为
Canvas-RT
添加一个RawImage-Origin
对象,修改颜色透明度为120
。
![9d8f4622933c1cddd3437acdb0d29001.png](https://img-blog.csdnimg.cn/img_convert/9d8f4622933c1cddd3437acdb0d29001.png)
修改
Camera-RT
中的Target Texture
, 改为RT
纹理。
![52048f5e723a705cc8f17bcadf9bbec8.png](https://img-blog.csdnimg.cn/img_convert/52048f5e723a705cc8f17bcadf9bbec8.png)
再新建一个
Canvas
,并添加一个RawImage-RT
,Texture
使用RT
。
![8e4bf392cc29fdfd1d06c1cdf8f884cb.png](https://img-blog.csdnimg.cn/img_convert/8e4bf392cc29fdfd1d06c1cdf8f884cb.png)
为
Canvas
添加一个RawImage-Compare
对象,修改颜色透明度为120
。
![2b0e86fe04ed11fc5bb81a6f44709416.png](https://img-blog.csdnimg.cn/img_convert/2b0e86fe04ed11fc5bb81a6f44709416.png)
在
Game View
中对比,发现颜色不同。
![df7e59b98a2ed74b3dabcec64a28304a.png](https://img-blog.csdnimg.cn/img_convert/df7e59b98a2ed74b3dabcec64a28304a.png)
分析
UI-Default.shader
先在 https://unity.cn/releases 中下载内置 shader
![8b7e31096aba8dbd52270d20eecf2355.png](https://img-blog.csdnimg.cn/img_convert/8b7e31096aba8dbd52270d20eecf2355.png)
找到 UI-Default.shader
, 这里对需要的关键代码做出截取。
Blend One OneMinusSrcAlpha
fixed4 frag(v2f IN) : SV_Target
{
half4 color = IN.color * (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd);
color.rgb *= color.a;
return color;
}
混合因子为
One
OneMinusSrcAlpha
输出颜色结果为
(c.r*t.r*c.a*t.a, c.g*t.g*c.a*t.a, c.b*t.b*c.a*t.a, c.a*t.a)
渲染过程
原图
RawImage-Origin
的纹理texture
为默认白色(1,1,1,1)
,颜色color
的值为(1,1,1,0.5)
经
UI-Default.shader
中的frag
输出为(0.5,0.5,0.5,0.5)
相机
Camera-RT
的clearcolor
为(0,0,0,0)
,shader
的混合因子为Blend One OneMinusSrcAlpha
第2步得到的颜色与第三步混合的结果为
(0.5,0.5,0.5,0.5)
, 此结果为RT
的纹理展示图
RawImage-RT
中的纹理texture
为第4步的中RT
的纹理,颜色color
的值为(1,1,1,1)
经
UI-Default.shader
中的frag
输出为(0.25,0.25,0.25,0.5)
相机
Main Camera
的clearcolor
为(0,0,0,0)
,shader
的混合因子为Blend One OneMinusSrcAlpha
,混合输出为(0.25,0.25,0.25,0.5)
![8be3dcee2c0d89d01a8d1d0914a73cfc.png](https://img-blog.csdnimg.cn/img_convert/8be3dcee2c0d89d01a8d1d0914a73cfc.png)
解决
预期为第二步的结果。究其原因,是在第6步的时候,RT
的纹理 RGB
已经乘上了透明度,在此步骤计算颜色值时,又再乘了纹理的透明度,导致最终输出颜色异常。
针对此方案,只需对 RawImage-RT
的 shader
进行修改,去掉乘以纹理的透明度,关键代码改成如下所示
color.rgb *= IN.color.a;
特别要注意混合模式,若混合因子为
Blend SrcAlpha OneMinusSrcAlpha
时,与相机混合时,结果会多乘以Alpha
。
小结
当颜色显示出现异常时,可以从以下两个方式着手分析。
混合模式
frag 颜色计算
希望对大家所帮助,欢迎关注白玉无冰。欢迎留言讨论。
点击“阅读原文”查看精选导航
“点赞“ ”在看” 鼓励一下▼