Alpha预乘-混合与不混合[转]
?
Alpha Blending幾乎是每個3D應用程序的一小部分,但卻很重要。從概念上講,alpha混合用于傳達表面的透明度。通常,消費者應用程序(游戲)傾向于使用RGB來傳達下層表面的顏色,依賴于alpha通道來指示該顏色的“不透明度”。更具體地說,當在管道中啟用alpha混合時,開發人員傾向于使用此表單進行混合:
DestinationColor.rgb = (SourceColor.rgb * SourceColor.a) + (DestinationColor.rgb * (1 - SourceColor.a));在舊的,固定的功能中,這將被稱為“SourceAlpha,InvSourceAlpha”;?也被稱為“后倍增α”。然而,這種形式的alpha混合存在一個嚴重的缺陷:在許多情況下它會導致錯誤的顏色!最簡單的這些情況可以通過一個簡單的雙像素圖像來說明:
?
一個紅色像素,紅色= 1,alpha為1,綠色像素為綠色= 1,alpha為0.10考慮上面的圖像,其分辨率為2x1像素。藝術家想要傳達的是,在綠色像素旁邊有一個紅色的不透明像素,它只會給它背后的物體帶來最輕微的綠色。但是,當我們生成下一個mipmap級別1x1級別時會發生一些有趣的事情。結果可能令人驚訝;?生成的mipmapped紋素是這樣的:
?
RGBA =(0.5,0.5,0,0.55)當我們接近這個mipmap級別時,我們將獲得與使用2x1級別時非常不同的結果 - 完全是因為我們決定使用postmultiplied級別。您可以在以下圖片中看到這一點:
?
?
? 規范圖像測試“mandrill”的三個版本。第一個,原始的mandrill。第二個包含與我們的2x1圖像混合時的mandrill,最后一個與2x1紋理的1x1 mipmap混合。輸入預乘的alpha
使用預乘的alpha,我們在存儲之前首先將紋理組件乘以alpha組件。我們還修改了混合函數,將SourceColor.a更改為One:
DestinationColor.rgb = (SourceColor.rgb * One) + (DestinationColor.rgb * (1 - SourceColor.a));使用預乘的alpha,我們的原始紋理看起來像這樣:
?
我們的2x1紋理,準備好預乘alpha。R =(1,0,0,1),G =(0,0.1,0,0.1)此紋理的1x1 mipmap級別如下所示:
?
我們預乘的alpha紋理的1x1 mipmap。RGBA =(0.5,0.05,0,0.55)這是很多更合理。我們仍然丟失了一些信息(請注意,如果綠色組件足夠小,或者如果我們的精度太低,綠色將完全消失),但我們保留了更高分辨率的mipmap的意圖。為了比較,這里再次是圖像,增加了我們的預乘混合器:
??
?
?
??? 所有版本的mandrill。從上到下的順序,原始的mandrill,原始的mandrill由我們的預乘α2x1覆蓋,后乘α2x1,預乘1x1,最后是后乘1x1。從我們的后乘世界過渡
方便地,從后乘的α管道到利用預乘的α的管道的轉換是微不足道的。在紋理保存時間或資產烘焙時間,甚至加載時間,將每個非alpha通道乘以alpha。那是:
OutputTexture.rgb = InputTexture.rgb * InputTexture.a; OutputTexture.a = InputTexture.a;
并且不要忘記修改“alpha混合啟用”以使用One作為Source Alpha值。如果我們將預乘的alpha插入到原始混合方程中,很容易看到切換到預乘的alpha會給出完全相同的結果:
DestinationColor.rgb = ((SourceColor.rgb * SourceColor.a) * One) + (DestinationColor.rgb * (1 - SourceColor.a));
所以你可能會問:如果結果相同,為什么還要加倍預乘?原因是紋理過濾。從紋理中獲取樣本時,除非已禁用紋理過濾,否則硬件會將相鄰紋理像素混合在一起并返回加權平均值作為結果。使用傳統的后乘法alpha,此結果將不正確。
原文地址:https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre
轉載于:https://www.cnblogs.com/xiaonanxia/p/9448383.html
總結
以上是生活随笔為你收集整理的Alpha预乘-混合与不混合[转]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 轰炸机上面的数字81018代表什么意思?
- 下一篇: 海船船长任职签注在没有离任船长的情况如何