【ShaderLab学习】AlphaTest & AlphaBlend理解[2]

【ShaderLab学习】AlphaTest & AlphaBlend理解[2]AlphaBlend 透明混合使用当前片元的透明度作为混合因子 与已存储在颜色缓冲中的颜色值进行混合 得到新的颜色 需要注意的是 透明度混合需要关闭深度写入 这时候要注意物体的渲染顺序 源颜色 当前片元颜色 sourcecolor 用 S 或者 SrcColor 表示目标颜色 颜色缓冲中的颜色 destinationc 用 D 或者 DstColor 表示官方文档 https docs

Alpha Blend

透明混合使用当前片元的透明度作为混合因子,与已存储在颜色缓冲中的颜色值进行混合,得到新的颜色。需要注意的是,透明度混合需要关闭深度写入,这时候要注意物体的渲染顺序。

  • 源颜色(当前片元颜色)source colorS或者SrcColor表示
  • 目标颜色(颜色缓冲中的颜色)destination colorD或者DstColor表示

官方文档:

https://docs.unity3d.com/Manual/SL-Blend.html

语义:

首先,需要正确设置渲染队列:

Tags { "Queue"="Transparent" } 

其次,需要关闭ZWrite

ZWrite Off 

然后,可以指定混合函数,如:

Blend SrcAlpha OneMinusSrcAlpha 
语义 描述
Blend Off 关闭混合
Blend SrcFactor DstFactor 开启混合,并设置混合因子。源颜色(片元颜色)乘以SrcFactor。而目标颜色(颜色缓存中的颜色)乘以DstFactor,将两者相加后存入颜色缓存。
Blend SrcFactor DstFactor,SrcFactorA DstFactorA 和上面一样,只是使用不同的混合因子来混合透明通道
BlendOp BlendOperation 不是把源颜色和目标颜色简单相加后混合,而是使用BlendOperation对它们进行其他操作

Blend operations 常用混合操作

Add 将源和目标添加在一起。
Sub 从源中减去目标。
RevSub 从目标中减去源。
Min 使用较小的源和目标。
Max 使用较大的源和目标。

Blend factors 混合因子

One 1 – 使用它让源或目标颜色完全通过
Zero The 0 – 使用此值删除源或目标值
SrcColor 源的Color(RGB)值
SrcAlpha 源的Alpha(a)值
DstColor 目标的Color(RGB)值
DstAlpha 目标的Alpha(a)值
OneMinusSrcColo 1 – source color.
OneMinusSrcAlpha 1 – source alpha.
OneMinusDstColor 1 – destination color.
OneMinusDstAlpha 1 – destination alpha.

最常见的混合类型:

Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency 最常用的透明度混合 Blend One OneMinusSrcAlpha // Premultiplied transparency 预乘透明度 Blend One One // Additive 叠加的 Blend OneMinusDstColor One // Soft Additive 软叠加  Blend DstColor Zero // Multiplicative Blend DstColor SrcColor // 2x Multiplicative 两倍相乘 (2X Multiply)  BlendOp Min //变暗 BlendOp Max //变亮 

测试

Shader代码如下:

Shader "Custom/l2xin/T_AlphaBlend" { 
    Properties { 
    _MainTex ("Albedo (RGB)", 2D) = "white" { 
   } } SubShader { 
    Tags { 
    "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} Pass { 
    Tags { 
    "LightMode"="ForwardBase" } //Alpha Blend Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; struct a2v{ 
    float4 vertex : POSITION; float4 texcoord: TEXCOORD0; }; struct v2f{ 
    float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(a2v v){ 
    v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag(v2f i) :SV_Target{ 
    fixed4 texColor = tex2D(_MainTex, i.uv); return texColor; } ENDCG } } FallBack "Diffuse" } 

Blend SrcAlpha OneMinusSrcAlpha(最常用的半透明效果)

Blend SrcAlpha OneMinusSrcAlpha

更多展示效果

转自:风宇冲Unity3D教程学院 http://blog.sina.com.cn/s/blog_471132920101d8z5.html

在树叶使用的Shader中添加Blend代码

  • Blend zero one:仅显示背景的RGB部分,无Alpha透明通道处理。
    Blend zero one

  • Blend one zero: 仅显示贴图的RGB部分,无Alpha透明通道处理。 A通道为0即本应该透明的地方也渲染出来了。
    在这里插入图片描述

  • Blend one one:贴图和背景叠加,无Alpha透明通道处理。仅仅是颜色rgb数值的叠加更趋近于白色即(1,1,1)了。
    在这里插入图片描述

  • Blend SrcAlpha zero:仅仅显示贴图,贴图含Alpha透明通道处理。但是贴图中的透明部分,即下图黑色部分没有颜色来显示,因为源颜色乘以alpha值0,为0;而混合目标的颜色乘以zero 0,也是0。所以透明部分显示的颜色为(0,0,0)
    在这里插入图片描述

  • Blend SrcAlpha OneMinusSrcAlpha:
    最终颜色 = 源颜色 * 源透明值 + 目标颜色*(1 – 源透明值)
    最常用的透明混合方式。贴图alpha值高的部分,显示得实,而混合的背景很淡。而alpha值高的部分,贴图显示得淡,而背景现实得实。
    在这里插入图片描述






后记-AlphaTest和AlphaBlend性能

Unity的官方文档中,提到了它们的性能问题——https://docs.unity3d.com/Manual/SL-ShaderPerformance.html

Fixed function AlphaTest or it’s programmable equivalent, clip(), has different performance characteristics on different platforms:

  • Generally it’s a small advantage to use it to cull out totally transparent pixels on most platforms.
  • However, on PowerVR GPUs found in iOS and some Android devices, alpha testing is expensive. Do not try to use it as “performance optimization” there, it will be slower.

总结一下,就是使用Alpha Test看似更简单,但其实在大多数平台上,相比与Alpha Blending,只有一点小小的性能提升。但是!!!在iOS和某些Android设备上,由于它们使用了PowerVR GPUs,因此Alpha Test的性能消耗反而会更大。因此,一个忠告就是,尽可能使用Alpha Blending,而不要使用Alpha Test

我们会觉得很奇怪,没有关闭深度缓存,不需要计算混合颜色,仅仅调用来discard舍弃fragment不是非常简单的事吗?为什么在移动平台上反而效率更低呢?有句话叫,“简单粗暴”,可以用在这里。性能下降的原因就是它太粗暴了!(我乱说的你不要当真。。。)

好啦,言归正传~原因呢,就是之前提到的两遍检验。由于我经验有限,只能依靠强大的谷歌来找答案。我找到了这里、这里。总结一下,就是PowerVR GPUs使用了一种叫做“Deferred Tile-Based-Rendering”的技术。这种技术里有一个优化阶段,就是为了减少overdraw它会在调用fragment shader前判断哪些Tile是会被真正渲染的。也就说我们之前说的在FS之前做的“Depth Test”。但是,由于Alpha Test在fragment shader里使用了clip函数改变了fragment是否被渲染的结果,因此,GPUs就无法使用上述的优化策略了。也就是说,只要在完成了所有的fragment shader处理后,GPUs才知道哪些fragments会被真正渲染到屏幕上,这样,原先那些可以减少overdraw的优化就都无效了。

这一段摘自乐乐女神的博客:https://blog.csdn.net/candycat1992/article/details/。我也没有理解到位,总之结论是尽可能使用Alpha Blending就对了。。


参考

  • 蛮牛https://docs.unity3d.com/Manual/SL-Blend.html
  • 风宇冲http://blog.sina.com.cn/s/blog_471132920101d8z5.html
  • 冯乐乐https://blog.csdn.net/candycat1992/article/details/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210901.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:38
下一篇 2026年3月18日 下午11:39


相关推荐

  • 身份验证错误 要求的函数不受支持 Windows远程桌面连接

    身份验证错误 要求的函数不受支持 Windows远程桌面连接PhpStorm绝对是PHP开发最好的开发工具。之前好好的能远程桌面连接到服务器,但是今天来就不能连接上了,并提示:身份验证错误。要求的函数不受支持。猜想可能是Windows又更新了什么鬼,后面查询资料知道是由于CredSSP加密Oracle修正的原因,这里我整理了下解决方案,希望能帮到你。微软给出解决方案:https://support.microsoft.com/zh-…

    2022年6月11日
    533
  • OpenClaw.ai 大模型接入实战指南

    OpenClaw.ai 大模型接入实战指南

    2026年3月12日
    4
  • 信用卡行为评分风险等级_信用卡综合评分标准

    信用卡行为评分风险等级_信用卡综合评分标准WOE&IVwoe全称叫WeightofEvidence,常用在风险评估、授信评分卡等领域。IV全称是Informationvalue,可通过woe加权求和得到,衡量自变量对应变量的预测能力。虽然网上到处都是神经网络、xgboost的文章,但当下的建模过程中(至少在金融风控领域)并没有完全摆脱logistic模型,原因大致有以下几点:logistic模型客群变化的敏感度不如其他高…

    2025年6月13日
    9
  • 清空ComboBox控件

    清空ComboBox控件清空 ComboBox 控件内容 ComboBox SP485 SelectedInde 1 ComboBox SP485 Items Clear ComboBox SP485 Text 注意第三句 一定要有否则不能选择但界面有残存文字特此记录以防遗忘 by anlog2021 年 4 月 9 日 09 点 05 分

    2026年3月19日
    2
  • 群晖|半洗白后moments正常显示人像、主题、预览「建议收藏」

    群晖|半洗白后moments正常显示人像、主题、预览「建议收藏」Moments不工作群晖重装6.2.3之后,发现moments不能正常工作了,不管是人物还是主题都是空白,还会显示有XXX张照片待发现,但会停在这儿。这如何能忍,网络上找到替换文件大法,没啥用,这台虚拟机内黑群晖只能暂时放下。想到自己还有台裸机安装的黑群晖,尝试后moments正常工作。替换ffmpeg为第三方替换的目的是为了能够正确的生成预览图、视频等。dsm版本及内核uname-a#LinuxvmDSM3.10.105#25426SMPTueMay1204:53:1

    2022年5月6日
    1.6K
  • 制作QQ微信支付宝三合一收款码

    制作QQ微信支付宝三合一收款码

    2021年11月5日
    62

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号