DirectX中的Photoshop“屏幕”模式

4

编辑:问题已经解决,请参考文章结尾。

如何在DirectX 8中实现Photoshop中的“屏幕”混合模式?

我在这个主题上找到的信息(http://www.ziggyware.com/readarticle.php?article_id=228):

Result = 1(1 – destination) * (1 – source)
Result = 1(1 – source – destination + destination * source)
Result = 11 + source + destination – destination * source
Result = source + destination – destination * source
Result = destination + source – source * destination
Result = destination + source * (1 – destination)

Now that we have the math worked out, we simply have to set the blend modes:

BlendOperation = Add
DestinationBlend = One
SourceBlend = InvDestColor

我认为DirectX混合状态必须是:

pD3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);

这正确吗?(我的结果不对)

示例项目:链接 镜像

Photoshop 结果:

http://img192.imageshack.us/img192/7015/photoshopf.jpg

DirectX 中我的结果:

http://img193.imageshack.us/img193/2969/directx.jpg

解决问题: 公式没有考虑图像的 alpha 通道,要修复它,您需要将图像背景设置为纯黑色,并将不透明度设置为 100%。


问题已解决。忘记添加解决方案 - 顶部的图像必须没有透明度,而是有纯黑色背景。 - kFk
2个回答

2

以下这行代码是错误的:

pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);

你的意图可能是要说明alpha混合器应该执行ADD操作,但D3DTSS_COLOROP设置并不影响最终混合器,它只是设置纹理组合器。你将其设置为向从纹理中采样的颜色添加某些内容(先前/后续阶段的结果或类似内容),这是错误的。应该使用D3DTOP_SELECTARG1或默认的D3DTOP_MODULATE来完成任务。

你需要写的是:

pD3DDevice->SetRenderState(D3DBLENDOP, D3DBLENDOP_ADD);

谢谢。在DirectX8中,正确的渲染状态是D3DRS_BLENDOP。我已经修复了我的测试项目,但结果与Photoshop仍然不同。您可以在标题中看到屏幕截图和示例项目。 - kFk
正如您提供的页面所写,您需要将图像以预乘alpha表示。 - Suma

0

数学似乎正确,你设置DirectX函数的方式应该可以工作。

我的建议是:

  1. 使用在Photoshop中使用的相同图像,这样你就知道它是否能正确生成纯白色(可能存在问题)。
  2. 检查你是否可以使用其他混合模式,并且它们会生成正确的输出。

    • 如果你已经完成了上述两个步骤,则请忽略此建议。

谢谢。我已将屏幕截图添加到标题中。 - kFk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接