Alpha合成如何工作

图片

透明度似乎不是一个有趣的话题。 GIF格式可以让某些像素透过背景发光,这种格式已经发布了30多年。 在过去的二十年中,几乎所有发行的图形设计应用程序都支持创建半透明内容。 这些概念早已不再是新事物。

在我的文章中,我想表明,事实上,数字图像中的透明度比看起来要有趣得多-在我们看来,这是一种看不见的深度和美。

不透明度


如果您曾经看过粉红色的眼镜,那么您会看到与下图类似的内容。 [在原始文章中,许多图像都是交互式的。]尝试移动眼镜,看看它们如何影响通过眼镜可见的图像:


这种眼镜的工作方式如下:它们会错过很多红色,相当数量的蓝色和很少的绿色。 这些点的数学运算可以用三个方程组来表示。 字母R表示运算结果,字母D表示我们要看的点。 RGB索引指示红色,绿色和蓝色成分:

R R = D R × 1.0
R G = D G × 0.7
R B = D B × 0.9

这种彩色玻璃以不同的强度透射背景的红色,绿色和蓝色成分。 换句话说,粉红色眼镜的透明度取决于入射光的颜色。 通常,透明度可能会根据光的波长而变化 ,但是在此简化示例中,我们仅对眼镜如何影响经典RGB组件感兴趣。

模拟普通太阳镜的行为要简单得多,它们通常只是将入射光衰减一些:


这些眼镜仅允许30%的光线通过。 它们的行为可以通过以下方程式描述:

R R = D R × 0.3
R G = D G × 0.3
R B = D B × 0.3

所有三个颜色分量都减小相同的值-入射光的吸收是相同的。 我们可以说墨镜是30%透明(不透明)或70%不透明的。 对象的不透明度决定了它阻止多少颜色。 在计算机图形学中,我们通常处理一个简化的模型,其中仅需要一个值来描述此属性。 不透明度可以在空间上变化。 例如,一列烟越来越高,越来越透明。

在现实世界中,不透明度为100%的对象就是不透明的,它们根本不透光。 数字图像的世界有些不同。 在某些情况下,即使是不透明的固体物体也可以通过一定量的光。

覆盖范围


矢量图形处理使用点,线段,贝塞尔曲线和其他数学图元定义的形状的清晰,无限准确的描述。 当您需要在计算机屏幕上显示图形时,必须将这些无懈可击的实体光栅化为位图:


将矢量形状栅格化为位图

光栅化的最原始方法是检查像素样本在矢量形状内部或外部的位置。 在下面的示例中,您可以拖动三角形,在放大视图中,移动将更加准确。 蓝色轮廓指示原始矢量几何。 如您所见,在移动几何图形时,三角形边缘的梯形看起来很丑,并且闪烁很多:


这种方法的缺点是,我们只对每个显示的像素执行一次检查,结果离散化为两个可能的值之一(内部或外部)。

您可以对每个像素多次采样矢量几何图形,以获得较大的阶跃渐变,并确定某些像素仅部分闭合。 一种可能的解决方案是使用四个采样点代表五个覆盖级别:0、1 ⁄ 4,2⁄4,3⁄4和1:


三角形边缘的质量得到了改善,但是仅五个可能的覆盖级别通常是不够的,我们可以轻松实现更好的结果。 尽管在信号处理领域中将像素视为小方块的观点遭到了反对 ,但在某些情况下,它还是一个有用的模型,可以让我们通过矢量几何来计算确切的像素覆盖率。 直线和正方形的交点始终可以分解为梯形矩形

图片

线段将正方形分为梯形和矩形

您可以轻松计算两个部分的面积,它们的总和除以正方形的面积即可确定像素覆盖率的百分比。 因此,覆盖范围被计算为具有任意精度的准确数字。 在下面的演示中,此方法用于渲染更好的边缘,即使拖动三角形也可以保持平滑:


对于更复杂的形状,例如椭圆或贝塞尔曲线,它们通常分为简单的直线段,可让您以正确的精度计算覆盖率。

对于矢量图形的高质量渲染,更重要的是对于文本渲染,部分覆盖的概念至关重要。 如果截取本文的屏幕截图并仔细考虑,您会发现字形的几乎所有边缘仅部分覆盖像素:


在文本呈现中积极使用部分覆盖

具有对象的不透明度并用单个像素覆盖它,您可以将它们组合为一个值。

阿尔法


对象的不透明度及其像素覆盖率的乘积称为alpha

= ×

不透明度为60%的对象(占像素面积的30%)在此像素中的alpha值为18%。 自然地,当对象是透明的或完全不覆盖像素时,此像素中的alpha值为0。相乘后,不透明度和涂层之间的差异消失,从某种意义上说,“ alpha”和“ opacity”的概念被用作同义词是有道理的。

Alpha通常表示为位图图像的第四通道。 红色,绿色和蓝色的通常值由一个alpha值补充,形成四个RGBA值。

在将alpha值存储在内存中时,通常会只使用一些位。 在覆盖不透明对象边缘的像素的情况下,根据屏幕的像素密度,似乎4位甚至3位就足够了:


但是,不透明度也会影响alpha值,因此,在平滑更改透明度的某些情况下,低位深度可能是灾难性的。 下图显示了从不透明的黑色到白色的渐变,这表明低位深度会导致非常强烈的颜色变化:


显然,位数越多越好,并且alpha 8通常使用8的位深度来匹配颜色分量的精度,这就是为什么许多RGBA缓冲区每个像素占用32位的原因。 还值得注意的是,与通常使用非线性变换编码的颜色分量不同,alpha是线性存储的-编码值0.5对应于alpha值0.5。

说到Alpha,我们完全忽略了所有其他颜色分量,但是除了阻止背景颜色之外,像素本身还可以添加一点颜色。 这个想法很简单-半透明的粉红色物体会阻挡部分传入的背景光,并发出或反射一点粉红色的光:


请注意,它的行为不像彩色玻璃。 玻璃只是以不同的亮度阻挡了部分背景照明。 如果您通过粉红色的玻璃看一个完全黑色的物体,那么它的黑色将保持不变,因为黑色的物体不发光也不反射任何光。 但是,半透明的粉红色物体会添加自己的灯光。 如果将其放在黑色物体上,则结果将为粉红色。 这种行为的一个很好的类似物是悬浮在空气中的细小物质,例如雾,烟,雾或一些有色粉末。

渲染Alpha通道要困难一些-完全透明的对象在定义上是不可见的,因此要区分对象,我们需要使用两个技巧。 棋盘背景显示图像的哪些部分是透明的。 此模式用于许多图形应用程序:


象棋图案显示透明的碎片。

图片下方的四个小方块告诉我们,我们看到了图片的红色,绿色,蓝色和Alpha成分。 在某些情况下,直接查看alpha通道值很有用,而显示它们的最简单方法是使用灰色阴影:


在不同的表面上显示RGB和A值

灰色阴影越亮,alpha值越高,即纯黑色对应于0%的alpha,纯白色对应于100%的alpha。 小方块表示图像的RGB和A分量分为两部分。

alpha组件本身并不是特别有用,但是当我们谈论合成时,它变得非常重要。

简单合成


一个操作几乎无法实现2D渲染的效果,并且要创建最终结果,我们使用了一种将各种图像组合在一起的合成过程。 例如,可以通过合成五个单独的元素来创建一个简单的“取消”按钮:


取消按钮的合成元素

合成通常分几个阶段进行,每个阶段将两个图像进行组合。 合成中使用的前景图像通常称为 。 通常将合成时使用的叠加有源的背景图像称为destination

我们将从在不透明的背景上进行合成开始,因为这是非常常见的情况。 您在屏幕上看到的所有内容最终都会通过在不透明的目标位置上进行合成而叠加。

当source的alpha值为100%时,source是不透明的,应完全覆盖目标。 如果Alpha值为0%,则源是完全透明的,不会以任何方式影响目标。 25%的alpha值允许对象发出25%的光并使75%的背景光通过,依此类推:


将具有不同alpha值的紫色源合成为黄色目标

您已经了解了所有内容-在不透明背景上进行Alpha合成的简单情况-只是目标颜色和源颜色之间的线性插值。 在下面的图形中,滑块控制源的Alpha值,红色,绿色和蓝色图形显示RGB分量的值。 R的结果只是源S和目标D的混合:


可以通过以下方程式描述此处发生的情况。 如前所述,索引表示分量,即S A是源中的alpha值,而D G是目标中的绿色值:

R R = S R × S A + D R × (1 − S A )

R G = S G × S A + D G × (1 − S A )

R B = S B × S A + D B × (1 − S A )

红色,绿色和蓝色分量的方程式外观相同,因此您可以简单地使用RGB索引并将它们组合为一行:

R RGB = S RGB × S A + D RGB × (1 − S A )

此外,由于目标是不透明的并且已经阻挡了所有背景光,因此我们知道结果的alpha值始终为1:

R A = 1

在不透明的背景上合成很简单,但是功能上却非常有限。 在许多情况下,需要更可靠的解决方案。

中间缓冲区


下图显示了将三个不同的层(分别标记为A,B和C)合成的两步过程。符号⇨表示“通过合成叠加”:


三层两阶段合成的结果

首先,我们通过合成使B与C重叠,然后将A与它们重叠以得到最终的图像。 在以下示例中,我们将做一些不同的事情。 首先,我们将通过合成来连接最上面的两个图层,然后将结果覆盖在最后一个目标位置:


三层以不同顺序进行两阶段合成的结果

您可能想知道这种情况在实践中是否会出现,但实际上这很常见。 许多非平凡的合成操作和渲染效果(例如遮罩和模糊)都需要通过仅包含部分合成结果的中间缓冲区。 这个概念有不同的名称:离屏传递,透明层或侧面缓冲区,但通常它们基于同一思想。

对我们来说更重要的是,几乎所有具有透明度的图像都可以被看作是某些渲染的部分结果,这些渲染随后将通过在最后一个目标上进行合成而被叠加:


将按钮部分合成到缓冲区中

我们需要了解如何用具有相同颜色和不透明度的一个图像(A⇨B)代替半透明图像A和B的合成。 让我们开始计算最终缓冲区的alpha值。

合并Alpha值


您可能还不清楚如何结合两个对象的不透明度,但是如果我们谈论透明度,则谈论此任务会更容易。

假设一定量的光穿过第一个对象,然后穿过第二个对象。 如果第一个对象的透明度为80%,则它将通过80%的入射光。 同样,透明度为60%的第二个对象将允许60%的光通过,这使我们获得了60%×80%=原始光的48%。 您可以在原始文章中尝试透明性; 不要忘记,滑块控制光路径中对象的透明度,而不是对象的不透明度:


自然,当第一个或第二个对象不透明时,没有任何光线穿过它们,甚至另一个完全透明。

如果对象D具有透明度D T ,而对象S具有透明度S T ,则这两个对象的最终一般透明度R T等于它们的乘积:

R T = D T ×S T

但是,透明度只是一个单位减去alpha,因此替换为我们提供了以下内容:

1-R A =(1- D A )×(1- S A

该表达式可以扩展为:

1-R A = 1-D A -S A + D A ×S A

并像这样简化它:

R A = D A + S A -D A ×S A

可以将其简化为两种相似类型之一:

R A = S A + D A ×(1-S A

R A = D A + S A ×(1-D A

很快,我们将看到第二个更常用。 还值得注意的是,所得的alpha值不取决于对象的相对顺序-即使交换了源和目标,所得像素的不透明度也是相同的。 这是很合逻辑的。 穿过两个物体的光应以相同的方式从恒星的任何一侧,从正面或从背面衰减。

颜色组合


计算alpha并不是那么困难,所以让我们尝试了解RGB分量的计算。 源图像的颜色为S RGB ,但其不透明度S A仅在最终结果中考虑以下两个值的乘积:

RGB ×S A

目标图像的颜色为D RGB ,不透明度使其发出光D RGB ×D A ,但是,部分光被图像S的不透明度所阻挡,因此目标的所有影响都相等:

D RGB ×D A ×(1-S A

来自S和D的光的总贡献等于它们的和:

S RGB ×S A + D RGB ×D A ×(1-S A

同样,合并图层的贡献等于其颜色乘以其不透明度:

R RGB ×R A

我们希望这两个值匹配:

R RGB ×R A = S RGB ×S A + D RGB ×D A ×(1-S A

是什么使我们得出最终方程:

R A = S A + D A ×(1-S A

R RGB =(S RGB ×S A + D RGB ×D A ×(1-S A ))/ R A

看看第二个方程有多复杂! 请注意,要获得结果的RGB值,我们需要除以alpha值。 但是,对于下一个合成阶段,将再次需要乘以alpha值,因为当前操作的结果将成为下一个操作的新源或目标。 这简直是​​丑陋的。

让我们再回到R RGB的几乎最终形式:

R RGB ×R A = S RGB ×S A + D RGB ×D A ×(1-S A

源,目标结果乘以其alpha分量。 这使我们了解像素的颜色和Alpha“喜欢”在一起,因此我们需要退后一步,重新考虑存储颜色信息的方式。

预乘alpha


回想一下我们讨论过的不透明度-如果对象是部分不透明的,那么它对结果的贡献也将是部分不透明的。 预乘alpha(“乘以alpha的预乘”)的概念实现了这一想法。 顾名思义,RGB分量的值已预先乘以alpha分量。 让我们从没有预乘的颜色开始:

(1.00,0.80,0.30,0.40)

预先乘以alpha可以得到以下结果:

(0.40、0.32、0.12、0.40)

让我们一次查看几个像素。 下图显示了如何在不先乘以alpha的情况下存储颜色信息:


图像中的RGB和A信息,无需事先相乘

请注意,从图像中的绿色和蓝色毛刺可以看出,alpha为0的区域可以具有任意的RGB值。 在通过alpha进行初步乘法的情况下,颜色信息还存储像素不透明度值:


预乘图像中的RGB和A信息

预乘Alpha有时称为关联Alpha,而非预乘Alpha有时称为纯Alpha或非关联Alpha。

当颜色的alpha分量为0时,预乘将重置所有其他分量,无论其值如何:

(0.0、0.0、0.0、0.0)

在预乘alpha的情况下,只有一种完全透明的颜色,这很迷人。

对颜色分量进行这种处理的优势将逐渐为您所认识,但是在返回合成示例之前,让我们看一下预乘alpha如何帮助解决其他一些渲染问题。

筛选


高斯模糊是创建有趣的散焦背景或降低某些UI元素内容背景部分高频度的一种流行方法。 正如我们将看到的,预乘alpha对创建正确外观的模糊至关重要。

我们将分析的图像是通过用1%不透明蓝色填充背景而创建的,在该背景上绘制了不透明红色圆圈。 首先,让我们看一个没有预乘的示例。 我将RGB通道与alpha通道分开,以了解发生了什么。 箭头指示模糊操作:


无需事先乘法即可模糊内容

最终结果具有丑陋的蓝色光晕。 发生这种情况是因为在模糊过程中,蓝色背景泄漏到了红色区域,然后才在合成过程中向其中添加了alpha权重。

将颜色预乘以alpha时,结果是正确的:


模糊预乘的内容

由于预乘,图像的蓝色减少到其原始强度的1%,因此对模糊圆圈的颜色的影响非常小。

插补


渲染像素与目标完美匹配的图像是一项简单的任务,因为我们需要在样本之间执行微不足道的一对一映射。当没有简单的映射时,例如由于旋转,缩放或断字,就会出现问题。下图显示了红色轮廓指示的旋转图像的像素不再与目的地匹配:


destination

, destination, — « » (nearest-neighbor interpolation), .

destination. . ( ), , . source destination, :


该解决方案非常实用,并且像素具有整体颜色,但是质量是不可接受的。最好使用双线性插值法,它可以计算采样图像的四个最近像素的加权平均值:


, , , «» . , [ ], — .

, premultiplied alpha , :


只是完美-我们摆脱了所有的色彩融合,牙齿无处可见

最终,与模糊和插值相关的问题密切相关。需要半透明颜色的任何组合而没有先将颜色乘以alpha的任何操作都可能产生错误的结果。

正确的合成


让我们回到合成。我们确定了一个几乎导出的方程式:

R RGB ×R A = S RGB ×S A + D RGB ×D A ×(1-S A

如果您想象使用预乘Alpha的颜色,那么所有这些不舒服的乘法都会消失,因为Alpha已经成为颜色值的一部分。然后我们得到以下内容:

R RGB = S RGB + D RGB ×(1-S A

让我们看一下alpha方程:

R A = S A + D A ×(1-S A

红色,绿色,蓝色和alpha通道的系数是相同的,因此我们可以用一个方程式表示整个表达式,而请记住,每个分量都经过相同的运算:

R = S + D×(1-S A

了解预乘alpha如何使事情变得容易。当我们分析方程式的组件时,它们都就位。该操作会遮盖部分背景光并添加新的光:

R = S + D×(1-S A

这种混合操作被称为信号源切换,切换或正常切换,毫无疑问,它是最常见的合成模式。在此模式下,您在我的网站上看到的几乎所有内容都是混杂的。

关联性


对预alpha乘以的颜色执行的一个重要的source-over属性是此操作关联性多亏了他,在复杂的混合方程式中,我们可以将括号完全任意放置。下面显示的所有成分均相同:

R = (((A⇨B)⇨C)⇨D)⇨E

R = (A⇨B)⇨(C⇨(D⇨E))

R = A⇨(B⇨(C⇨(D⇨E)))

, . , , , .

source-over, . .

-


1984年7月,Thomas Porter和Tom Duff发表了原始文章“ Compositing Digital Images”作者不仅首先介绍了预乘alpha的概念并推导了合成源方程,而且还提出了一个完整的alpha合成操作族,尽管它们非常有用,但其中很多鲜为人知。新函数也称为运算符,因为它们像加法或乘法一样,对输入值执行操作以创建输出值。

结束


在以后的示例中,我们将使用交互式演示演示各种混合模式的操作。目标图像将是黑色的“俱乐部”符号,源图像将是红色的“蠕虫”符号。您可以将心脏拖到图像上方,并观察重叠形状在不同的合成运算符下的行为。注意角落的小地图。一些混合模式非常具有破坏性,并且容易引起混淆。小型地图始终显示简单的源代码合成的结果,从而简化了理解:


R = S + D×(1-S A

R = S×(1-D A)+ D

destination-over, , «» source-over — destination source , destination source. , destination-over , , .

Out


source-out destination-out source destination:


R = S × (1 − D A )

R = D × (1 − S A )

Destination-out, - destination.

In


源输入和目标输入运算符本质上是掩盖运算符:


R = S×D A

R = D×S A

它们使创建非平凡几何图形的复杂交点变得十分容易,而无需解决相对困难的矢量轮廓交点的计算。

在上


运算符source-atopdestination-atop允许您将新内容叠加在现有内容上,同时沿目标路径对其进行遮盖:


R = S×D A + D×(1-S A

R = S×(1-D A)+ D×S A

异或


XOR运算符(xor)存储源,或目标,以及它们的重叠区域消失:


R = S×(1-D A)+ D×(1-S A

源,目的地,清除


最后三种经典的合成模式非常无聊。Source,也称为copy,仅采用颜色来源。同样,它会destination忽略颜色源并仅返回destination操作员clear只需清除所有内容:


R = S

R = D

R = 0

这些模式的适用性受到限制。使用clear它,您可以刷新已填充的缓冲区,但是可以通过简单地用零填充内存来优化此操作。另外,在某些情况下,由于不需要任何混合,而只是用源信息替换缓冲区的内容,因此在计算上source 可能更经济。

波特达夫在行动


与个别操作员打交道之后,让我们看看如何将它们组合在一起。在下面的示例中,我们将绘制海洋徽标,而无需使用遮罩或复杂的几何形状。蓝色轮廓显示正在创建的简单几何图形。您可以通过单击图像的右侧来完成各个步骤,然后单击左侧可以返回:


当然,我们绝没有义务放弃遮罩和修剪轮廓,但是我们经常忘记像Porter-Duff合成模式这样的工具,尽管在它们的帮助下创建一些视觉效果要容易得多。

经营者


-, , . Source F S destination, F D :

R = S×F S + D×F D

F S 0, 1, D A 1 − D A , F D 0, 1, S A 1 − S A . source destination , , , . :

01个D A1 − D A
0clearsourcesource-insource-out
1个destinationdestination-over
S Adestination-indestination-atop
1 − S Adestination-outsource-oversource-atopxor

. , .


, F S , F D 1. plus , lighter plus-lighter :

R = S + D

source destination:


由操作员实施的附加照明plus

正确地以绿色和红色形成黄色,而以绿色和蓝色形成青色。黑色表示没有操作;它不会以任何方式更改颜色值,因为将数字加零不会更改任何内容。

剩余的三个运算符没有特别的名称,因为它们没有用。它们只是遮罩和混合的组合。

还值得注意的是,预乘alpha允许我们以source-over意外的方式使用运算符让我们再次看一下等式:

R = S + D×(1-S A

如果我们设法使光源中的Alpha值等于零,那么如果RGB通道中存在非零值,则无需使用运算符就可以实现加性照明plus


, source-over

, — . , , , - , , . , , plus .

到目前为止,我们正在讨论的所有元素都已很好地结合在一起。现在,让我们摘下粉红色眼镜,讨论使用alpha合成时需要考虑的一些问题。

组不透明度


让我们看一下仅由六个基元组成的简单药丸图:


使用简单的形状绘制药丸

如果要求我们绘制不透明度为50%的药丸,那么我们可能会试图在每个绘制操作中将不透明度简单地分成两半,但这将是一个错误的决定:




, . , , , :




, .


将几何封面转换为单个alpha值会带来不舒服的后果。请考虑以下情况:矢量几何图形的两个理想匹配的边缘(如下图所示,具有橙色和蓝色轮廓)被渲染为位图。在理想的世界中,结果应该看起来像这样,因为每个像素都是完全封闭的:


具有正确覆盖率的理想渲染结果,

但是,如果我们首先渲染橙色几何图形,然后渲染蓝色几何图形,那么在最终图像中,白色背景仍然会渗入边框像素中:


两阶段合成的结果

将涂层存储在alpha通道中后,其所有几何信息都将丢失,我们无法以任何方式对其进行恢复。蓝色几何图形只是与缓冲区的某些内容混合在一起,但是不知道由红色像素表示的几何图形必须与之匹配。当几何形状彼此精确叠加时,此问题尤其明显。在下图中,在黑色圆圈的上方绘制了一个白色圆圈。尽管两个圆半径和位置完全相同,但深色边缘仍然很明显


,

, , . in/out, , .

8- - 256 , 2 16次。正如我们在上面看到的,在减少coverage值的位深度的同时,您仍然可以获得令人满意的结果,因此在实践中,您可以使用较小的比例尺。

还值得注意的是,通常无需使用巨大的位图就可以相对轻松地避免此类问题。例如,您可以简单地在彼此上方绘制两个正方形,而不是绘制两个重叠的圆,然后对结果进行遮罩以形成一个圆。

线性值


如果您重新了解了色彩空间,则可以记住,大多数色彩空间都是非线性地对色彩值进行编码的,因此必须进行初步的线性化才能执行正确的数学运算。完成此阶段后,合成结果如下:注意彼此重叠的部分的淡黄色调:


模糊红色圆圈是通过使用线性值在绿色背景上合成而叠加的,

但是在大多数情况下,合成并非如此。Web和大多数图形软件的标准方法是直接混合非线性值:


作曲家使用非线性值将模糊的红色圆圈叠加在绿色背景上。

请注意,绿色叠加层上红色的区域要暗得多。它们远非理想,但在某些情况下,错误的操作深深植根于理解我们如何感知色彩。例如,来自sRGB空间的50%不透明灰色看起来完全像是纯黑色,其中不透明度50%与白色背景混合在一起:


没有线性化的情况下

白色背景上合成两种颜色在下图中,将源图像和目标图像的sRGB颜色进行线性化,然后转换回非线性编码以进行显示。这些颜色的实际外观如下:


两种颜色的构成在白色背景的线性化

我们有一个不符合我们的期望的差异。使用此方法获得视觉均匀性的唯一方法是使用线性值选择所有颜色,但这与每个人习惯的方法有很大不同。具有线性值的50%灰度在sRGB空间的73.5%上看起来像灰度。

此外,在使用预乘alpha时,需要特别小心。预乘法必须使用线性执行,即 在编码为非线性之前。因此,线性化步骤将正确地以正确的线性值结束,该线性值先前已乘以alpha。

预乘Alpha和位深度


尽管预乘alpha在合成,过滤和插值方面很有用,但它并不是“灵丹妙药”,但也有其缺点。其中最严重的是可以想象得到的颜色位深度的减少。想象一下一个值为150的8位编码,它预先乘以alpha 20%。初步乘以alpha之后,我们得到

四舍五入(150×0.2)= 30

如果我们重复相同的过程,其值为151,则会得到:

四舍五入(151×0.2)= 30

尽管初始值有所不同,但编码后的值将相同。实际上,在乘以alpha之后,将148、149、150、151和152的值编码为30,并且丢失了这五种唯一颜色之间的原始差异:


预乘以20%的alpha值

会将各种8位值减小为1,当然,alpha 越小,其效果越具有破坏性。在初步乘以alpha后,在8位RGBA值的各种组合的256 4个(大约43亿)可能的范围中,只有25.2%保留唯一的表示形式。实际上,我们从32位范围中损失了几乎2位。

要在不同的颜色空间之间转换颜色,有时需要反转预乘,即将值除以alpha分量以获得原始颜色亮度。因为如上所述,编码是非线性执行的,所以需要此步骤。预乘法的存在降低了颜色表示的准确性,并且颜色空间之间的转换可能是不完善的。

在实践中,减小位深度很少是重要的,尤其是在合成中。 alpha值越低,颜色越不可见,并且对合成的影响也越小。最终,如果您追求精确的色彩操作,则不会使用它们的8位表示法-为此,格式更适合浮点数

补充阅读


Alpha通道的概念是由Pixar工作室联合创始人Elvy SmithEd Catmell创建的。史密斯(Smith)的文章“阿尔法和数字合成的历史描述了发明的历史和“阿尔法”的名称,以及这些概念如何演变并逐渐取代电影制作中的口罩概念

为了理解alpha的含义,我强烈建议您阅读Andrew Glassner的“解释Alpha”。本文提供了一个严格但很容易获得的数学推导式α,以衡量不透明度和覆盖率之间的相互作用。

有关预乘alpha的详细讨论,请参见埃里克·海恩斯 Eric Haines)的“ GPU更喜欢预乘”本文不仅提供了关于缺少初步乘法(尤其是在3D渲染中)的问题的出色概述,还提供了有关该主题的许多其他文章的链接。

总结


-, , -, , .

, , RGB-, . 2D-.

, , , , .

Source: https://habr.com/ru/post/zh-CN468067/


All Articles