AlpbaBlend 细节

AlphaBlend细节

https://www.khronos.org/opengl/wiki/Blending

Alpha Blend 的计算只有一种形式,而且可以分别针对RGB和Alpha单独给出Blend的模式,对AlphaBlend总共需要4个参数
* Orgb = srgb * Srgb + drgb * Drgb
* Oa = sa * Sa + da * Da

The same goes for the two subtraction equations. This separates the RGB component computation from the alpha computation. So there are 4 possible blending parameters.

 void glBlendFuncSeparate(GLenum srcRGB​, GLenum dstRGB​, GLenum srcAlpha​, GLenum dstAlpha​)

The srcRGB​ value specifies the srgb parameter. dstRGB​ specifies drgb. srcAlpha​ is for sa, while dstAlpha​ specifies da.

AlphaPremultiply

If the result is the same, why bother with pre-multiplied alpha? The reason is texture filtering. When you take samples from a texture, unless you have disabled texture filtering, the hardware is blending neighboring texels together and returning a weighted average as a result.

在纹理点采样的情况下,普通的AlphaBlend跟AlphaPremultiply是一样的。关键就在对纹理filter的时候,只有AlphaPremultiply才能得到正确的结果。

普通的AlphaBlend

普通AlphaBlend的形式是,这同时也被称为 post-multipled alpha,但是它会导致错误的颜色
DestinationColor.rgb = (SourceColor.rgb * SourceColor.a) + (DestinationColor.rgb * (1 - SourceColor.a));

给定一张2个像素的纹理图
2x1-rg-post

图1. 左边是一个像素Alpha为1的红色(1,0,0,1),右边是一个像素Alpha为0.1的绿色(0,1,0,0.1)

如果这个时候,我们想计算这个2x1纹理的下一级mip的1x1纹理,那么我们使用普通的AlphaBlend就会得到

在这里插入图片描述

图2. RGBA=(0.5, 0.5, 0, 0.55)

通过图1和图2的比较,我们可以看到当我们计算mip的时候,结果就完全不对了。如果我们使用普通的AlphaBlend做图片想相乘的时候得到如图3所示结果。

(a) 正常的mandrill.png
(b) mandrill与2x1的图通过相乘Blend得到
(c) mandrill与普通AlphaBlend计算得mip的1x1的图通过相乘Blend得到

Alpha-Premultiply

https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre


在 Alpha-premultiply 下,我们首先要输入纹理的 rgb 与它的 alpha 乘到一块儿,并把 SourceColor.a 变成 1 。

DestinationColor.rgb = (SourceColor.rgb * One) + (DestinationColor.rgb * (1 - SourceColor.a));

2x1-rg-pre.png

图3.准备做alpha-premultiply的2x1像素的纹理,左边(1, 0, 0, 1),右边(0, 0.1, 0, 0.1)

在这里插入图片描述

图4.通过alpha-premultiply计算得到的1x1像素的mip纹理,RGBA=(0.5, 0.05, 0, 0.55)

如果我们使用普通的AlphaBlend做图片想相乘的时候得到如图所示结果。

(a) 正常的mandrill.png
(b) mandrill与2x1的图通过相乘Blend得到
(c) mandrill与Alpha Premultiplied计算得mip的1x1的图通过相乘Blend得到

所以我们看到,只要做了filtering,那么只有Alpha Premultiplied才能得到正确的表现效果。

SoftAddition

在游戏中,如果我们需要把UI单独的绘制到一个RenderTexture上,再把这个RenderTexture作为一个半透明的纹理绘制到Backbuffer中,那么就需要关注这个临时的RenderTexture的Alpha值了。

正常的AlphaBlend流程,我们不需要关注Backbuffer的Alpha到底是怎么样的值,因为这个Alpha根本不会参与任何运算。但是如果需要使用到这一Alpha值的时候,就需要确保这个Alpha值的区间是[0,1]。

那么一个可行的Alpha的Blend模式就是

Blend x x, OneMinusDstAlpha One

这样可以保证Alpha值的区间

引用

[1] https://www.khronos.org/opengl/wiki/Blending

[2]https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值