DirectX渲染到纹理alpha混合

时间:2015-01-13 18:58:29

标签: windows-phone-8 directx

问题如下:我将精灵渲染到纹理,然后我将纹理渲染到屏幕上。简单吧?但是,当我这样做时,每次精灵渲染时,它都会覆盖它覆盖的每个像素,与其像素的alpha值无关。例如:

enter image description here

在这里你可以看到两个带有文字" ABC"的精灵。首先在右上角渲染,第二个在Y顶部渲染。如您所见,第二个覆盖了第一个精灵的那些不应该被背景颜色覆盖的像素。当我这样做,但不是将其渲染为纹理,然后将该纹理渲染到屏幕,我将精灵直接渲染到屏幕,结果是预期的,第二个精灵只覆盖应该被覆盖的像素。

所以,我不太确定那里发生了什么,因为所有渲染目标都启用了Alpha混合,并且屏幕和纹理渲染的深度测试已关闭。我在Windows Phone 8上使用DirectX11 - XAML与DirectX互操作。

编辑:稍微重述一下问题:让我说清除纹理为红色,所以当我将它渲染到屏幕时,我有红色屏幕。现在我将完全透明(颜色0,0,0,0)纹理渲染为所述红色纹理。我希望没有变化,在渲染到屏幕后,我会得到红屏。这不是这种情况,因为当我渲染透明精灵时,它实际上将(0,0,0,0)颜色写入纹理,并且我得到一个带透明窗口的红色纹理。因此,在将其渲染到屏幕后,我可以看到彩色屏幕被清除。发生了什么事?

1 个答案:

答案 0 :(得分:2)

您最后的评论表明了这个问题。我假设两者源纹理和中间渲染目标都有一个alpha通道,对吗?如果是这样,您需要为颜色 Alpha通道使用正确的混合方程。通常,直接混合到后缓冲区的标准方程式省略了正确的alpha通道混合,因为通常忽略后缓冲区alpha。我怀疑在你的情况下,颜色通道正在被正确混合,但最后渲染的精灵正在将其alpha值直接写入中间纹理。结果,这些像素是完全透明的,即使它们应该保持不透明,因为先前的绘制使它们变得不透明。当您随后将此纹理渲染到后缓冲区时,相同的颜色Alpha混合会导致这些像素对最终图像没有任何贡献。

这是标准alpha混合渲染到具有透明度的纹理的正确设置:

// dest.rgb = dest.rgb * (1 - src.a) + src.rgb * src.a
SrcBlend = SRC_ALPHA
DestBlend = INV_SRC_ALPHA
BlendOp = ADD

// dest.a = 1 - (1 - dest.a) * (1 - src.a), with some rearranging
SrcBlendAlpha = INV_DEST_ALPHA
DestBlendAlpha = ONE
BlendOpAlpha = ADD

另外,不要忘记在渲染之前将中间目标清除为透明(不常见的是不透明的黑色),假设您希望渲染后纹理的某些部分是透明的