【问题标题】:Combine (Blend) two images to a final image, but avoid current content将两个图像合并(混合)为最终图像,但避免当前内容
【发布时间】:2012-12-10 15:06:13
【问题描述】:

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

我想要以下内容:

Destination = Image1 + Image2

为此,我实际上是这样做的:

Clear(Destination, 0); // Clear it with transparent black
Blend Image1 over Destination
Blend Image2 over Destination

虽然 Destination 是透明的黑色,但黑色有助于最终结果,这是我想避免的。我可以用透明的白色清除目的地,但它只在这个例子中有效,并且对较暗的图像产生同样的问题。

我明白为什么结果是这样的:directx 混合公式是这样设置的:

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

目的地的 alpha (DestAlpha) 在这个公式中根本没有考虑。我可以做些什么来解决这个日常问题,即在将两张图像渲染到其他地方之前将它们混合在一起?

【问题讨论】:

  • 我不确定,您是否可以使用固定功能管道解决此问题。为什么重要的是,图像是在一个额外的缓冲区中而不是直接在目标背景上组成的?你想达到什么目标?
  • 需要这个额外的缓冲区,因为它是作为像素着色器的输入。
  • 不一定需要在固定功能管道中完成,但AFAIK混合公式仍然是固定的。顺便说一句,我正在使用 DirectX9。我不喜欢将两个缓冲区合并到一个单独的像素着色器中,因为这会带来很多开销。

标签: directx alphablending alpha-transparency


【解决方案1】:

Afaik 您无法通过正常的混合操作来实现这一点,但也许您可以编写一个适当的着色器来为您进行混合。您在一个额外的纹理上作为渲染目标进行渲染,并在像素着色器中设置这个纹理。现在您将写入的 alpha 值分支,如果 background-alpha 为零,则写入图像颜色,否则在该像素上已经写入图像,您可以在着色器中进行正常的 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);

【讨论】:

  • 是的,这会起作用,但会使引擎变得更加复杂。特别是如果我使用多通道着色器创建效果,我必须在每次通道后进行混合。
  • 我想到的唯一其他解决方案是使用预乘 alpha 和加法混合,但这会使结果过度曝光。
  • 这种方法的另一个问题:如果我有重叠的透明几何体,我会得到错误的结果,因为固定函数混合公式将用于重叠像素。
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2011-01-20
相关资源
最近更新 更多