使 OpenGL polygonOffset 和 DirectX9 depthBias 表现相同
Making OpenGL polygonOffset and DirectX9 depthBias behave the same
对于同时支持 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 中使用非常小的值。但是,我似乎找不到 how 小。
我注意到在 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
完全相同的结果?
我没有在任何地方找到确切的数字,但通过试验我发现要在 OpenGL 和 DirectX 中获得大致相同的效果,我需要除以 3500000
,而不是 250000
上面提到过。
如果有人知道确切的数字或为什么会这样,我很想听听,但出于实际目的,我认为这个结论对我有用。
如果您查看 OpenGL 多边形偏移等式和等效的 Direct3D 9 渲染状态,您会发现它们是相同的,除了 OpenGL 有一个与实现相关的常量值术语。如果我们假设值为 1,则方程式会变得相同。
这里明显的问题是:当值不为 1 时会发生什么?
不幸的是,OpenGL 似乎没有提供查询它的方法,所以你唯一能做的就是调整参数直到找到有效的东西,然后在出现边缘情况时再调整它们,永远不要假设对你有用的东西也会对其他人有用。
Direct3D 的值始终为 1 的假设也不一定始终有效。
底线是,在任何情况下,多边形偏移都不是 100% 可靠的修复 z-fighting 的方法。您是否尝试过其他方法,例如将贴花沿表面法线推出 epsilon?
对于同时支持 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 中使用非常小的值。但是,我似乎找不到 how 小。
我注意到在 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
完全相同的结果?
我没有在任何地方找到确切的数字,但通过试验我发现要在 OpenGL 和 DirectX 中获得大致相同的效果,我需要除以 3500000
,而不是 250000
上面提到过。
如果有人知道确切的数字或为什么会这样,我很想听听,但出于实际目的,我认为这个结论对我有用。
如果您查看 OpenGL 多边形偏移等式和等效的 Direct3D 9 渲染状态,您会发现它们是相同的,除了 OpenGL 有一个与实现相关的常量值术语。如果我们假设值为 1,则方程式会变得相同。
这里明显的问题是:当值不为 1 时会发生什么?
不幸的是,OpenGL 似乎没有提供查询它的方法,所以你唯一能做的就是调整参数直到找到有效的东西,然后在出现边缘情况时再调整它们,永远不要假设对你有用的东西也会对其他人有用。
Direct3D 的值始终为 1 的假设也不一定始终有效。
底线是,在任何情况下,多边形偏移都不是 100% 可靠的修复 z-fighting 的方法。您是否尝试过其他方法,例如将贴花沿表面法线推出 epsilon?