Directx 将两个图像合并(混合)为最终图像,但避免使用当前内容

Directx 将两个图像合并(混合)为最终图像,但避免使用当前内容,directx,alphablending,alpha-transparency,Directx,Alphablending,Alpha Transparency,当分层时,我必须将它们与“空”图像或背景至少结合一次。但没有什么能比得上“空”。它是透明的黑色或透明的白色。即使是完全透明的,也会有一种在显示时通常被忽略的颜色 我想要以下内容: Destination = Image1 + Image2 要做到这一点,我实际上是这样做的: Clear(Destination, 0); // Clear it with transparent black Blend Image1 over Destination Blend Image2 over Desti

当分层时,我必须将它们与“空”图像或背景至少结合一次。但没有什么能比得上“空”。它是透明的黑色或透明的白色。即使是完全透明的,也会有一种在显示时通常被忽略的颜色

我想要以下内容:

Destination = Image1 + Image2
要做到这一点,我实际上是这样做的:

Clear(Destination, 0); // Clear it with transparent black
Blend Image1 over Destination
Blend Image2 over Destination
虽然目的地是透明的黑色,但黑色有助于最终结果,这也是我想要避免的。我可以用透明白色清除目标,但它只在本例中起作用,并且在较暗的图像中产生同样的问题

我理解为什么结果是这样的:directx混合公式设置如下:

BlendOp = Add;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;

在这个公式中根本不考虑目的地的alpha(DestAlpha)。在其他地方渲染之前,如何实现将两个图像混合在一起的日常问题?

好吧,正常的混合操作无法实现这一点,但也许您可以编写一个适当的着色器来进行混合。将在额外纹理上渲染为渲染目标,并在pixelshader中设置该纹理。现在分支写入的alpha值,如果背景alpha为零,则写入imagecolor,否则该像素上已写入图像,您可以在着色器中执行正常的alpha混合。使用此分支可以检测像素是否为空或之前写入,然后防止黑色产生任何影响。希望这有帮助:)

让我举一个小例子来说明我的意思:

float4 targetColor = tex2D(backgroundSampler,screen.TexCoord);
float4 diffuse = tex2D(imageSampler,image.TexCoord);
// overwrite black background
if (targetColor.a == 0.0) {
  return diffuse;
}
// do alphablending
return targetColor*(1-diffuse.a)+diffuse*(diffuse.a);

我不确定,你是否可以用固定的函数管道来解决这个问题。为什么图像在额外的缓冲区中合成而不是直接在目标背景上合成很重要?你想实现什么?这个额外的缓冲区是需要的,因为它是作为像素着色器的输入提供的。它不一定需要在固定的函数管道中完成,但混合公式仍然是固定的。顺便说一句,我使用的是DirectX9。我不喜欢在一个单独的pixelshader中组合两个缓冲区,因为这会引入大量开销。是的,这会起作用,但会使引擎更加复杂。特别是如果我使用多通道着色器创建效果,我必须在每次通道后进行混合。我想到的唯一其他解决方案是使用预乘alpha和加法混合,但这会使结果曝光过度。这种方法的另一个问题是:如果我有透明的重叠几何体,我会得到错误的结果,因为固定函数混合公式会用于重叠像素。