OpenGL到DirectX的翻译 - alpha混合

时间:2012-07-31 19:18:13

标签: c++ opengl directx alphablending

我正在尝试将OpenGL渲染器转换为DirectX9。它似乎主要起作用,但两者似乎并不同意alpha混合的设置。在OpenGL中,我正在使用:

glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

并且从未实际设置GL_DEST_ALPHA,因此它是默认设置。这很好用。转换为DirectX,我得到:

device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);

应该做同样的事情,但完全没有。我能得到的最接近的是:

device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

几乎正确,但如果几何体自身重叠,则前面的alpha会覆盖后面的alpha,并使更远的面不可见。为了记录,我正在进行的其他可能相关的渲染状态是:

device->SetRenderState(D3DRS_LIGHTING, FALSE);
device->SetRenderState(D3DRS_ZENABLE, TRUE);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

在这一点上,我觉得我只是随意改变状态,看看哪种组合能产生最好的结果,但是没有什么比OpenGL更好。不知道我在这里缺少什么...

1 个答案:

答案 0 :(得分:1)

正确执行Alpha混合本身。否则,每个粒子看起来都很奇怪。一些颗粒的某些部分未被绘制的原因是它们位于其他颗粒的透明部分之后。

要解决此问题,您有两种选择:

  1. 关闭粒子的ZWriteEnable。这样,在粒子之后绘制的每个对象都将位于其前面。如果你的对象实际上应该在粒子后面并且之后被绘制,这可能会导致问题。

  2. 启用粒子的alpha测试。 Alpha测试是一种从目标中移除透明像素(给定特定阈值)的技术。这包括ZBuffer。

  3. 顺便说一下。在渲染透明对象时,几乎总是需要对对象进行排序以解决ZBuffer问题。以上解决方案适用于某些特殊情况。