Depth Bias 以及 Ogre材质中的depth_bias
Posted czaoth
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Depth Bias 以及 Ogre材质中的depth_bias相关的知识,希望对你有一定的参考价值。
通过给多边形增加一个z方向深度偏移(depth bias,z_bias),使3D空间的共面多边形看起来好像并不共面,以便它们能够被正确渲染。这种技术是很有用的,例如,我们要渲染投射在墙上的阴影,这时候墙和阴影共面,如果没有深度偏移,先渲染墙,再渲染阴影,由于depth test,阴影可能不能正确显示。我们给墙设置一个深度偏移,使它增大,例如z增加0.01,先渲染墙,再渲染阴影,则墙和阴影可以正确的显示。
Depth-bias操作在clipping之后进行实施,所以depth-bias对几何clipping没有影响。另外需要注意的是:对一个给定体元(primitive),bias值是一个常量,在进行差值操作之前,它施加在每个顶点上。偏移操作都是32位浮点运算,还有Bias不能施加在点以及线体元上(除了线框模式的线段)。
Polygons that are coplanar in your 3-D space can be made to appear as if they are not coplanar by adding a z-bias to each one.
This is a technique commonly used to ensure that shadows in a scene are displayed properly. For instance, a shadow on a wall will likely have the
same depth value as the wall does. If you render the wall first and then the shadow, the shadow might not be visible, or depth artifacts might be
visible. You can reverse the order in which you render the coplanar objects in hopes of reversing the effect, but depth artifacts are still likely.
An application can help ensure that coplanar polygons are rendered properly by adding a bias to the z-values that the system uses when
rendering the sets of coplanar polygons.
To add a z-bias to a set of polygons, call the IDirect3DDevice9::SetRenderState method just before rendering them, setting the State parameter to
D3DRS_DEPTHBIAS, and the Value parameter to a value between 0-16 inclusive.
A higher z-bias value increases the likelihood that the polygons you render will be visible when displayed with other coplanar polygons.
Offset = m * D3DRS_SLOPESCALEDEPTHBIAS + D3DRS_DEPTHBIAS
where m is the maximum depth slope of the triangle being rendered.
m = max(abs(delta z / delta x), abs(delta z / delta y))
The units for the D3DRS_DEPTHBIAS and D3DRS_SLOPESCALEDEPTHBIAS render states depend on whether z-buffering or w-buffering is enabled. The application must provide suitable values.
The bias is not applied to any line and point primitive. However, this bias needs to be applied to triangles drawn in wireframe mode.
// RenderStates
D3DRS_SLOPESCALEDEPTHBIAS :
Used to determine how much bias can be applied to co-planar primitives to reduce z-fighting. The default value is 0.
bias = (max * D3DRS_SLOPESCALEDEPTHBIAS) + D3DRS_DEPTHBIAS.
where max is the maximum depth slope of the triangle being rendered:max = max(abs(delta z / delta x), abs(delta z / delta y))
D3DRS_DEPTHBIAS : A floating-point value that is used for comparison of depth values. SeeDepth Bias (Direct3D 9). The default value is 0.
// Caps
D3DPRASTERCAPS_DEPTHBIAS
D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
上面对depth bias进行了说明,包括D3D中如何使用渲染状态来设置depth bias,下面对Ogre材质中设置depth bias进行说明:
depth_bias
设置此渲染通路的深度值的偏向。可用于使共面的多边形中的一个位于其它之上。例如:印制花纹图案。
格式: depth_bias <constant_bias> [<slopescale_bias>]
深度偏向值最终由偏向常数(constant_bias)*最小可观察的深度(minObservableDepth)+最大坡度(maxSlope)*坡度偏向(slopescale_bias)共同决定,即: ( constant_bias * minObservableDepth + maxSlope * slopescale_bias)。坡度偏向与多边形到镜头的角度有关,形成相应的偏向值,但是在一些时间比较早的硬件上,这被忽略了。偏向常数是形成最小深度值的一个因素,所以1的价值就在于一点一点地缓慢地推进深度。
与D3D参考文档中说的最终的depth bias值的计算不同,那就是多乘以了一个minObservableDepth(对于D3D渲染系统,该值为:-1 / 250000.f)。
而最终的深度值
depth = depth - (constant_bias * minObservableDepth + maxSlope * slopescale_bias)
depth_bias 1表示深度值向前移动一个刻度。当两个面共顶点时,depth_bias 1即可将其移到上面。如果不共顶点,数据精度会导致计算的深度存在偏差(距离相机越近深度偏差越大,同样的距离差在相机很近时对应了较大的深度差),这种情况下至少要depth_bias 2 2才能移到上层。
下面分别看下Ogre中对于D3D渲染系统和GL渲染系统,设置depth bias渲染状态实现:
D3D渲染系统如下
- void D3D9RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias)
- {
- if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0)
- {
- // Negate bias since D3D is backward
- // 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;
- HRESULT hr = __SetRenderState(D3DRS_DEPTHBIAS, FLOAT2DWORD(constantBias));
- if (FAILED(hr))
- OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting constant depth bias",
- "D3D9RenderSystem::_setDepthBias");
- }
- if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
- {
- // Negate bias since D3D is backward
- slopeScaleBias = -slopeScaleBias;
- HRESULT hr = __SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FLOAT2DWORD(slopeScaleBias));
- if (FAILED(hr))
- OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting slope scale depth bias",
- "D3D9RenderSystem::_setDepthBias");
- }
- }
GL渲染系统
- void GLRenderSystem::_setDepthBias(float constantBias, float slopeScaleBias)
- {
- if (constantBias != 0 || slopeScaleBias != 0)
- {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glEnable(GL_POLYGON_OFFSET_POINT);
- glEnable(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(-slopeScaleBias, -constantBias);
- }
- else
- {
- glDisable(GL_POLYGON_OFFSET_FILL);
- glDisable(GL_POLYGON_OFFSET_POINT);
- glDisable(GL_POLYGON_OFFSET_LINE);
- }
- }
这样就很清楚了设置depth bias的过程,所以就能理解对于Ogre中最终的深度值为需要减去这个偏移,而显示在前面。如果为负数,那么就相当于真正加上了一个便宜,深度值增加,导致靠后!
另外一个关于depth_bias属性:
iteration_depth_bias
用于通道多次迭代时,设置附加的偏移值。如果需迭代三次,第一次偏移为depth_bias,第二次为depth_bais+ iteration_depth_bias,第三次为depth_bais+ iteration_depth_bias*2
格式: iteration_depth_bias <bias_per_iteration>
以上是关于Depth Bias 以及 Ogre材质中的depth_bias的主要内容,如果未能解决你的问题,请参考以下文章
如何在UE4材质中判断物体是否开启了渲染Custom Depth Pass?