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>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值