DirectX11 混合例子

来源:互联网 发布:淘宝店是什么意思 编辑:程序博客网 时间:2024/06/05 09:57

混合例子

1. 屏蔽颜色写入

假设我们希望原始目标像素保持不变,即不被任何其他数值覆盖,也不与当前的光栅化源像素进行混合。当我们希望屏蔽后台缓冲区、只向深度/模板缓冲区写入数据时,该算法非常有用。要实现这一算法,可将源像素混合系数设为D3D11_BLEND_ZERO,目标混合系数设为D3D11_BLEND_ONE,混合运算符设为D3D11_BLEND_OP_ADD。使用一方案,混合方程可简化为:

这里写图片描述

还有一种方法可以实现相同的结果,就是将D3D11_RENDER_TARGET_BLEND_DESC::RenderTargetWriteMask设置为0,这样就不会写入任何颜色通道。

2. 加法

假设我们希望将源像素和目标像素相加(参见下图)。要实现这一算法,可将源混合系数设为D3D11_BLEND_ONE,目标混合系数设为D3D11_BLEND_ONE,混合运算符设为D3D11_BLEND_OP_ADD。使用一方案,混合方程可简化为:

这里写图片描述

这里写图片描述
(将源颜色和目标颜色相加。由于颜色叠加,所以创建后的图像比原始图像的亮度要高一些。)

3. 减法

当把D3D11_BLEND_OP_ADD替换为D3D11_BLEND_OP_SUBTRACT或D3D11_BLEND_OP_REV_SUBTRACT时,可以实现源像素和目标像素的减法运算(参见下图)。
这里写图片描述
(从目标颜色中减去源颜色。由于颜色削减,所以创建后的图像比原始图像的亮度要低一些。)

4. 乘法

假设我们要将源像素和目标像素相乘(参见下图)。要实现这一算法,可将源混合系数设为D3D11_BLEND_ZERO,目标混合系数设为D3D11_BLEND_SRC_COLOR,混合运算符设为D3D11_BLEND_OP_ADD。使用一方案,混合方程可简化为:
这里写图片描述

这里写图片描述
(将源颜色和目标颜色相乘。)

5. 透明度

我们可以使用源alpha分量as控制源像素的不透明度(例如,当alpha为0.0时表示0%不透明,为0.4时表示40%不透明,为1.0时表示100%不透明)。不透明和透明之间的关系可以简单地表示为T =1 − A,其中A表示不透明度,T表示透明度。例如,当某物的不透明度为0.4时,它的透明度为1 − 0.4 = 0.6。现在,我们希望根据源像素的不透明度来混合源像素和目标像素。要实现一算法,可将源混合系数设为D3D11_BLEND_SRC_ALPHA,目标混合系数设为D3D11_BLEND_INV_SRC_ALPHA,混合运算符设为D3D11_BLEND_OP_ADD。使用这一方案,混合方程可简化为:

这里写图片描述

例如,当as = 0.25时,表示源像素的不透明度为25%, 或者说源像素的透明度为75%。那么,当源像素和目标像素混合之后,我们最终得到的颜色应该是由25%的源像素和75%的目标像素组成(源像素将“挡住”一部分目标像素)。综上所述,此时的混合方程为:

这里写图片描述

但需要注意的是,此时物体的绘制顺序非常重要。我们需要遵守如下规则:

首先绘制非透明物体。然后,根据透明物体与摄像机之间的距离进行排序,按照从后向前的顺序绘制透明物体。

之所以要按照从后向前的顺序进行绘制,是为了让前面的物体和后面的物体进行混合。如果一个物体是透明的,那么我们就会透过这个物体看到它后面的其他物体。所以,必须将透明物体后面的所有物体先绘制出来,然后才能将透明的源像素和后台缓冲区中的目标像素进行混合。对于屏蔽颜色写入的混合方程来说,绘制顺序并不重要,因为它只是简单地阻止源像素向后台缓冲区的写入操作。对于加法减法和透明度的混合方程,我们必须先绘制非透明物体,再绘制透明物体;因为我们需要在混合之前将所有的非透明几何体存入后台缓冲区。不过,我们不需要对透明物体进行排序,因为这些运算满足交换律。也就是,从后台缓冲区中的某个像素颜色B开始执行n次加/减/乘法运算,最终得到的混合颜色是一样的,与顺序无关:

这里写图片描述

6. 混合与深度缓冲

当使用加/减/乘法混合时会出现一个与深度测试相关的问题。这里,我们仅以加法混合为例进行说明,同样的情况也适用于减法和乘法混合。当我们使用加法混合来渲染一个粒子系统S时,每个粒子是否相互遮挡并不重要;我们只需要把粒子的颜色简单地累加起来 (参见图9.5)。我们并不希望对S中的每个粒子进行深度测试。在这一情景中,如果不按照从后向前的顺序绘图,那么当S中的某个粒子被另一个粒子遮挡时,该粒子将无法通过深度测试,它的像素片段将被丢弃,也就是说该粒子的像素颜色不会累加到最终的混合颜色中。我们应该在渲染S时禁用深度写入功能,使粒子的深度信息不写入深度缓冲区。在禁用深度写入功能之后,由加法混合生成的粒子深度信息不会写入到深度缓冲区;所以,当S中的一个粒子被其他粒子遮挡时,该粒子依然可以通过深度测试并绘制到后台缓冲区中。注意,我们只在绘制S时禁用深度写入功能(以便于使用加法混合绘制该粒子系统),而深度读取和深度测试功能依然有效。非透明物体(在绘制透明物体之前)仍然可以遮挡位于它后面的透明物体。例如,当你在一堵墙的后面绘制一个透明物体时,该物体不会显示出来,因为它被墙体挡住了。我们会在下一章讲解有关深度写入和深度测试的设置方法。

这里写图片描述
(当使用加法混合时,火焰中心的亮度比火焰边缘的亮度高,因为中间的粒子较多,它们彼此重叠并累加在一起。随着粒子逐渐散开,亮度会逐渐衰减,因为当重叠在一起的粒子越来越少时,累加值会相应降低。)

0 0