图形混合概念

Posted tiantian-t

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图形混合概念相关的知识,希望对你有一定的参考价值。

alpha混合与porter/duff

稍微接触过一点图形相关应用的人应该都会知道alpha混合,再深入一点就应该会看到porter, duff两位神人的名字,他们是最早在SIGGRAPH上提出图形混合概念的前辈。

对于alpha混合,最简单的说法是Src*alpha + Dst*(1-alpha),至少这是我第一次了解到的alpha算法,但事实上porter, duff提出的混合远比这个复杂。因为每次都会忘记他们提出的那12个混合方式是怎么来的,所以在这里整理一次。

首先,一个大前提,以下porter/duff公式是针对预乘(premultiplied)后的结果的。什么是预乘?假设一个像素点,用RGBA四个分量来表示,记做(R,G,B,A),那预乘后的像素就是(R*A,G*A,B*A, A),这里A的取值范围是[0,1]。所以,预乘就是每个颜色分量都与该像素的alpha分量预先相乘。可以发现,对于一个没有透明度,或者说透明度为1的像素来说,预乘不预乘结果都是一样的。

为什么要用预乘方式来表示像素?主要是这样会使公式更简单。而且实际上,在实际运算过程中,使用预乘像素进行运算在某些情况下效率会更高。但预乘会对运算精度有一定影响。关于预乘的种种内容,这里不讨论,有兴趣可以自行研究。

开始讨论porter/duff混合公式之前,先定义几个符号

C - 表示像素的颜色,即(RGBA)的RGB部分,C是color的缩写

A - 表示像素的透明度,A即alpha

s  - 表示两个混合像素的源像素,s即source

d - 表示两个混合像素的目标像素,d即destination

r - 表示两个像素混合后的结果,r即result

F - 表示作用于C或A上的因子,F即factor

有了这个符号之后,可以开始用它们来描述porter/duff混合公式了,如下,

Cr = Cs*Fs + Cd*Fd

Ar = As*Fs + Ad*Fd

对于12种不同的混合方式,仅仅是Fs与Fd的取值不同,比如最为常见的SRC_OVER混合方式,

Fs = 1, Fd = (1-As)

所以

Cr = Cs + Cd*(1-As)

Ar = As + Ad*(1-Ad)

我们之前提到的Src*alpha + Dst*(1-alpha)其实就是SRC_OVER的一种特殊情况,即目标像素的alpha为1的情况。你可能决定这两个公式长得还有点区别,别忘了porter/duff公式是以预乘方式来讨论的,展开成非预乘之后就是

Cr = Cs*As + Cd*Ad*(1-As)

如果Ad = 1,那就和之前的公式一样了。对于通常的GUI应用,因为最终的背景一定是alpha为1的,所以使用这个公式就足够了。但是,对于OSD与video叠加的情况,由于OSD的最终背景很可能是半透明的,如果再使用这个简化过的公式,可能就会造成结果不正确了。这种时候 就必须按照porter/duff公式严格计算。

下面是12种porter/duff混合的具体定义,

1. CLEAR

Fs = Fd = 0

2. SRC

Fs = 1 Fd = 0

3. DST

Fs = 0 Fd = 1

4. SRC OVER

Fs = 1 Fd = (1-As)

5. DST OVER

Fs = (1-Ad) Fd = 1

6. SRC IN

Fs = Ad Fd = 0

7. DST IN

Fs = 0 Fd = As

8. SRC OUT

Fs = (1-Ad) Fd = 0

9. DST OUT

Fs = 0 Fd = (1-As)

10.SRC ATOP

Fs = Ad Fd = (1-As)

11.DST ATOP

Fs = (1-Ad) Fd = As

12.XOR

Fs = (1-Ad) Fd = (1-As)

 

其实除了第1和第12条,其它都是两两相对的,很好理解。

以上是关于图形混合概念的主要内容,如果未能解决你的问题,请参考以下文章

图形学计算机图形学知识点提纲7

OpenGL 混合功能

虚拟现实和混合现实概念学习

Direct2D开发:纹理混合

与核心图形的加法混合

qt里面混合二维图形和文字