1. 程式人生 > >【翻譯】第七章節:順序無關的透明度(關於順序無關的混合)

【翻譯】第七章節:順序無關的透明度(關於順序無關的混合)

轉載地址:http://www.omuying.com/article/95.aspx

本部落格中還有篇詳解,可以去看看那篇先做了解。

在《透明度》章節中,我們討論並解決了在著色器上呈現透明度一些標準的問題,如果你還沒有閱讀這個章節,那麼你應該先去閱讀它。

順序無關的混合

在《透明度》章節中,我們知道,混合的結果取決於三角形的呈現順序(尤其是 alpha 混合),如果三角形不是按從背面到前面的呈現方式,這樣可能會導致渲染問題,術語“order-independent transparency”一詞描述各種技術來避免這個問題,其中的一個技術便是“order-independent”混合,即使用一個不依賴於三角形柵格化順序的混合公式,他們是:加法(additive )blending 和乘法(multiplicative) blending。

我們不可能(至少很難)說是照片以何種順序拍攝。additive blending 的特點可以依據《透明度》章節的混合公式:

1 float4 result = SrcFactor * fragment_output + DstFactor * pixel_color;

其中 SrcFactor 和 DstFactor 由 Unity 的語法決定:

1 Blend {code for SrcFactor} {code for DstFactor}

對於 additive blending,DstFactor 必須是 One,SrcFactor 的值不能取決於幀緩衝區裡面的畫素顏色,它可以是 One、SrcColor、SrcAlpha、 OneMinusSrcColor 或者 OneMinusSrcAlpha。

Shader "Cg shader using additive blending" 
{
   SubShader 
   {
      Tags { "Queue" = "Transparent" } 
      // draw after all opaque geometry has been drawn在所有不透明幾何物體後繪製
      Pass 
      { 
         Cull Off // draw front and back faces
         ZWrite Off // don't write to depth buffer 
         // in order not to occlude other objects
         Blend SrcAlpha One // additive blending
 
         CGPROGRAM 
 
         #pragma vertex vert 
         #pragma fragment frag
 
         float4 vert(float4 vertexPos : POSITION) : SV_POSITION 
         {
            return mul(UNITY_MATRIX_MVP, vertexPos);
         }
 
         float4 frag(void) : COLOR 
         {
            return float4(1.0, 0.0, 0.0, 0.3); 
         }
         ENDCG  
      }
   }
}

Multiplicative Blending

multiplicative blending 使用的例子是在攝影中使用多個均勻(uniform)的灰色濾波器:攝像機濾波器的順序對於影象的衰減是無關緊要的,在三角形的柵格化方面,影象對應於在三角形柵格化之前幀緩衝區中的內容,而濾波器對應於三角形。

可以像下面的格式來指定 multiplicative blending:

1 Blend {code for SrcFactor} {code for DstFactor}

對於 SrcFactor  必須是 Zero,並且 DstFactor  必須取決於片段顏色,所以可能的值是 SrcColor、SrcAlpha、OneMinusSrcColor 或者 OneMinusSrcAlpha。典型的例子是 DstFactor 使用 OneMinusSrcAlpha 來表示用片段的 alpha 分量來指定不透明背景的衰減:

最後,我們可以在一個著色器中使用兩個 Pass 來合併 multiplicative blending(指定背景的衰減)和 additive blending(給三角形新增顏色),如果忽略三角形網格本身的顏色衰減,這可以被認為是一種近似小不透明體(small opacities)的 alpha 混合,即小的 alpha 值。

Shader "Custom/Blending1"
{
SubShader
{
Tags{ "Queue" = "Transparent" }
// draw after all opaque geometry has been drawn
Pass
{
Cull Off // draw front and back faces
ZWrite Off // don't write to depth buffer 
   // in order not to occlude other objects
Blend Zero OneMinusSrcAlpha // multiplicative blending 
// for attenuation by the fragment's alpha

CGPROGRAM
#pragma vertex vert 
#pragma fragment frag

float4 vert(float4 vertexPos : POSITION) : SV_POSITION
{
return mul(UNITY_MATRIX_MVP, vertexPos);
}

float4 frag(void) : COLOR
{
return float4(0.0, 0.0, 1.0, 0.3);
}
ENDCG
}
Pass
{
Cull Off // draw front and back faces
ZWrite Off // don't write to depth buffer 
  // in order not to occlude other objects
Blend SrcAlpha One // additive blending to add colors
CGPROGRAM
#pragma vertex vert 
#pragma fragment frag
float4 vert(float4 vertexPos : POSITION) : SV_POSITION
{
return mul(UNITY_MATRIX_MVP, vertexPos);
}
float4 frag(void) : COLOR
{
return float4(0.0, 0.0, 1.0, 0.5);
}
ENDCG
}
}
}

去掉第二個通道的註釋,效果如圖所示: