使OpenGL polygonOffset和DirectX9 depthBias的行为相同

时间:2018-03-30 12:25:19

标签: directx-9 depth-buffer

对于支持OpenGL和DirectX9的多平台引擎,我正在添加对贴花的支持。在OpenGL中,我可以设置glPolygonOffset(-1.0f, -1.0f)来修复墙和贴花之间的z-fighting。我希望DirectX版本的行为完全相同,所以我称之为:

float offsetFloat = -1.0f;
DWORD offsetDWord = *((DWORD*)&offsetFloat);
device->SetRenderState(D3DRS_DEPTHBIAS, offsetDWord);
device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, offsetDWord);

但是,这给了我极大的深度偏差。我似乎需要在DirectX9中使用极小的值。但是,我似乎无法找到如何小。

我注意到在OGRE引擎的源代码中它们除以250000,但尽管有评论我还不太清楚这个数字的来源。而且,由于某种原因,他们只将常数除以?

// D3D also expresses the constant bias as an absolute value, rather than 
// relative to minimum depth unit, so scale to fit
constantBias = -constantBias / 250000.0f;
__SetRenderState(D3DRS_DEPTHBIAS, FLOAT2DWORD(constantBias));

slopeScaleBias = -slopeScaleBias;
__SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FLOAT2DWORD(slopeScaleBias));

所以我的问题是:我需要传递给DirectX9以获得与glPolygonOffset完全相同的结果?

2 个答案:

答案 0 :(得分:1)

如果您查看 OpenGL 多边形偏移等式和等效的 Direct3D 9 渲染状态,您会发现它们是相同的,除了 OpenGL 有一个表示依赖于实现的常量值的术语。如果我们假设该值为 1,则方程确实变得相同。

这里明显的问题是:当值不是 1 时会发生什么?

不幸的是,OpenGL 似乎没有提供查询它的方法,所以你唯一能做的就是摆弄参数,直到找到有用的东西,然后在出现边缘情况时再摆弄它们,永远不要假设什么是有效的因为你会为其他人工作。

Direct3D 的值始终为 1 的假设也不一定始终适用。

最重要的是,在任何情况下,多边形偏移都不是修复 z-fighting 的 100% 稳健方法。您是否尝试过其他方法,例如将您的贴花沿表面法线推出一个 epsilon?

答案 1 :(得分:0)

我没有在任何地方找到确切的数字,但通过实验我已经发现要在OpenGL和DirectX中获得大致相同的效果,我需要除以3500000,而不是{{1} }如上所述。

如果有人知道确切的数字或为什么会这样,我很乐意听到,但出于实际目的,我认为这个结论对我有用。