当前位置:   article > 正文

【Shader进阶】常见的渲染状态RenderSetup——Blend_blendop

blendop

目录

一、BlendOp混合操作

二、Blend混合因子

三、实战

1、BlendOp Sub,Alpha为0.7,混合因子不变情况

四、关于Queue为Transparent时,是否默认关闭深度写入的问题再次进行探讨和说明。

(如有误解,请私信或评论留言,吐槽什么的都可以~)


一、BlendOp混合操作

混合操作
Add    
将混合后的源颜色和混合后的目标颜色相加。默认的混合操作。使用的混合等式是:

O(rgb) = SrcFactor * S(rgb) + DstFactor * D(rgb)

O(a) = SrcFactorA * S(a) + DstFactorA * D(a)

Sub    
用混合后的源颜色值减去混合后的目标颜色。使用的混合等式是:

O(rgb) = SrcFactor * S(rgb) - DstFactor * D(rgb)

O(a) = SrcFactorA * S(a) - DstFactorA * D(a)

RevSub    
用混合后的目标颜色值减去混合后的源颜色。使用的混合等式是:

O(rgb) = DstFactor * D(rgb) - SrcFactor * S(rgb)

O(a) = DstFactorA * D(a) - SrcFactorA * S(a)

Min    
使用源颜色和目标颜色中较小的值,是逐分量比较的。使用的混合等式是:

O(rgba) = ( min( S(r), D(r) ), min(S(g),D(g)), min(S(b),D(b)), min(S(a),D(a)) )

Max    
使用源颜色和目标颜色中较大的值,是逐分量比较的。使用的混合等式是:

O(rgba) = ( max( S(r), D(r) ), max(S(g),D(g)), max(S(b),D(b)), max(S(a),D(a)) )

其他逻辑操作    仅在DirectX 11.1 中支持

二、Blend混合因子

混合因子
One    1
Zero    0
SrcColor    源颜色值(RGBA):当用于混合RGB通道时,混合因子为SrcColor.rgb;当混合A通道时,混合因子为SrcColor.a
SrcAlpha    源颜色的透明度值(A通道)
DstColor    目标颜色值(RGBA):当用于混合RGB通道时,混合因子为DstColor.rgb;当混合A通道时,混合因子为DstColor.a
DstAlpha    目标颜色的透明度值(A通道)
OneMinusSrcScolor    (1 - 源颜色值(RGBA)):当用于混合RGB通道时,混合因子为(1 - 源颜色值(RGBA)).rgb;当混合A通道时,混合因子为(1 - 源颜色值(RGBA)).a
OneMinusSrcAlpha    1 - 源颜色的透明度值(A通道)
OneMinusDstScolor    
(1 - 目标颜色值(RGBA)):当用于混合RGB通道时,混合因子为(1 - 目标颜色值(RGBA)).rgb;当混合A通道时,混合因子为(1 - 目标颜色值(RGBA)).a 

OneMinusDstAlpha    1 - 目标颜色的透明度值(A通道)

三、实战

(Alpha为0.7)

  1. Shader "Unlit/BlendShaderTest"
  2. {
  3. Properties
  4. {
  5. _MainTex("Texture", 2D) = "white" {}
  6. _Alpha("Alpha", Range(0,1)) = 1
  7. }
  8. SubShader
  9. {
  10. Tags{
  11. "Queue" = "Transparent" //必須是透明通道才可混合
  12. }
  13. BlendOp Add //相加混合
  14. Blend SrcAlpha OneMinusSrcAlpha //RGB和A通道混合因子均为源Alpha、1-源Alpha
  15. //BlendOp Add相加混合对应如下两个公式分别为RGB混合公式和A混合公式
  16. //
  17. //O(rgb) = SrcFactor * S(rgb) + DstFactor * D(rgb)
  18. //代入因子为 输出RGB = 源Alpha值 * 源RGB值 - (1-源Alpha值) * 目标RGB值 [源是指当前片元着色器输出的颜色值、目标是指颜色缓冲区本身存在的值]
  19. //假如_Alpha为0.3,片元着色器输出(1,0,0,0.3),目标颜色值为(1,1,1,1)
  20. //公式为 输出RGB = (1,0,0) * 0.3 + (1-0.3) * (1,1,1) = (0.3+0.7, 0.7, 0.7) = (1, 0.7, 0.7)
  21. //简单理解为削弱0.7倍片元着色器输出颜色值,削弱0.3倍颜色缓冲区颜色值,再将相加混合,形成新的RGB值,至此完成RGB混合
  22. //O(a) = SrcFactorA * S(a) + DstFactorA * D(a) [Alpha值混合同理]
  23. //输出Alpha值 = 源Alpha值 * 源Alpha值 - (1-源Alpha值) * 目标Alpha值
  24. //其实,当没有Alpha混合因子时,可以直接用 O(rgba) = SrcFactor * S(rgba) + DstFactor * D(rgba) 来运算混合后的RGBA
  25. //假如我混合因子为:Blend SrcAlpha OneMinusSrcAlpha 1 0
  26. //此时后两个数值显式指明Alpha混合因子为1和0,代入公式可得知是为了忽略目标Alpha值对混合的影响
  27. Pass
  28. {
  29. CGPROGRAM
  30. #pragma vertex vert
  31. #pragma fragment frag
  32. #include "UnityCG.cginc"
  33. struct appdata
  34. {
  35. float4 vertex : POSITION;
  36. float2 uv : TEXCOORD0;
  37. };
  38. struct v2f
  39. {
  40. float2 uv : TEXCOORD0;
  41. float4 vertex : SV_POSITION;
  42. };
  43. sampler2D _MainTex;
  44. float4 _MainTex_ST;
  45. fixed _Alpha;
  46. v2f vert(appdata v)
  47. {
  48. v2f o;
  49. o.vertex = UnityObjectToClipPos(v.vertex);
  50. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  51. return o;
  52. }
  53. fixed4 frag(v2f i) : SV_Target
  54. {
  55. fixed4 col = tex2D(_MainTex, i.uv);
  56. col.a = _Alpha; //片元着色器输出即为源颜色
  57. return col;
  58. }
  59. ENDCG
  60. }
  61. }
  62. }

1、BlendOp Sub,Alpha为0.7,混合因子不变情况

很明显变暗了,因为先削弱源颜色0.3倍,再减去目标颜色削弱0.7倍后的颜色值,整体上RGBA都会变小。(其他情况自行测试),用的最普遍的情况还是BlendOp Add,混合因子也是SrcAlpha OneMinusSrcAlpha。

四、关于Queue为Transparent时,是否默认关闭深度写入的问题再次进行探讨和说明。

结论:深度写入默认是开启的,不因其他因素而影响!途中发现一些比较好复习以前透明章节的内容,下面来说明。

两个透明物体,一个红色和一个原色,并【开启了深度写入】有如下两种情况:

物体相交并穿插,按照透明物体是根据离摄像机越远的越先渲染原则,红色的箱子先渲染,原色箱子后渲染,因此红色部分渲染出来了,再到原色前半部分渲染~即这一部分会渲染,后半部分因为无法通过深度测试,无法渲染出来。

物体相交并穿插,但很明显,原色离摄像机最远,先渲染原色,再渲染红色,注意!!注意!!是开启了深度写入的!

此时,原色最靠近摄像机的前端,如下圈出来的部分,这部分的深度先进行写入了深度缓冲区!导致红色被遮挡的部分无法渲染,从而出现了看似两个物体属于不透明物体的遮挡情况,实际上它们是透明物体。

下图能够更加清晰地证明它们是一个透明物体,

这一部分的原色箱子的深度先写入,导致红色部分无法渲染。

但不影响上方这部分,即使是先渲染了原色箱子,但是由于原色箱子这部分的深度值,比红色箱子更大(我理解深度值为与摄像机的距离,只要有比深度缓冲区的深度值小,就能够渲染这个片元),所以红色箱子这部分(深度值更小)能够正常渲染出来并混合原色箱子,呈现出透明效果!

(如有误解,请私信或评论留言,吐槽什么的都可以~)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/96795
推荐阅读
相关标签
  

闽ICP备14008679号