深度偏移用来解决共面情况下出现闪烁的问题

通过给多边形增加一个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渲染系统如下

  1. void D3D9RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias)
  2. {
  3. if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0)
  4. {
  5. // Negate bias since D3D is backward
  6. // D3D also expresses the constant bias as an absolute value, rather than
  7. // relative to minimum depth unit, so scale to fit
  8. constantBias = -constantBias / 250000.0f;
  9. HRESULT hr = __SetRenderState(D3DRS_DEPTHBIAS, FLOAT2DWORD(constantBias));
  10. if (FAILED(hr))
  11. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting constant depth bias",
  12. "D3D9RenderSystem::_setDepthBias");
  13. }
  14. if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
  15. {
  16. // Negate bias since D3D is backward
  17. slopeScaleBias = -slopeScaleBias;
  18. HRESULT hr = __SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FLOAT2DWORD(slopeScaleBias));
  19. if (FAILED(hr))
  20. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting slope scale depth bias",
  21. "D3D9RenderSystem::_setDepthBias");
  22. }
  23. }

GL渲染系统

  1. void GLRenderSystem::_setDepthBias(float constantBias, float slopeScaleBias)
  2. {
  3. if (constantBias != 0 || slopeScaleBias != 0)
  4. {
  5. glEnable(GL_POLYGON_OFFSET_FILL);
  6. glEnable(GL_POLYGON_OFFSET_POINT);
  7. glEnable(GL_POLYGON_OFFSET_LINE);
  8. glPolygonOffset(-slopeScaleBias, -constantBias);
  9. }
  10. else
  11. {
  12. glDisable(GL_POLYGON_OFFSET_FILL);
  13. glDisable(GL_POLYGON_OFFSET_POINT);
  14. glDisable(GL_POLYGON_OFFSET_LINE);
  15. }
  16. }

这样就很清楚了设置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的更多相关文章

  1. 转:Ogre的MaterialSystem分析

    1. Mesh .SubMesh.SubEntity和Entity 所有的Mesh对象是由SubMesh构成的,每个SubMesh代表了Mesh对象的一部分,该部分只能使用一种Meterial.如果一 ...

  2. 有关UnrealEngine材质编辑器中的Custom节点的一些小贴士

    PS:本文写于2017.2.1日,使用版本为4.13.第二次更新时间为2017.3.15增加了四.一些材质编辑器中的奇怪的技巧: 一.前言在Unreal中材质编辑器提供了Custom节点,作为HLSL ...

  3. 在Ogre中加载自己的资源包

    转自:http://www.cnblogs.com/minggoddess/archive/2011/02/19/1958472.html 由于数据保护的需要,一款游戏一般都会有自己独有的资源包,这样 ...

  4. [转]unity3d中创建双面材质

    在其它三维软件中设置好的双面材质导入到unity3d中就失去了效果,不过我们可以通过自定义材质来在unity3d中实现双面材质的效果.步骤如下:1.在资源库中新建一新shader:代码如下: Shad ...

  5. Ogre参考手册(五)3.2 合成器

    3.2 合成器Compositor 合成器框架是Ogre用于全屏后处理的API.你可以通过脚本而不是API定义合成器.你可以很容易为视口实例化合成器. 合成器基础 无论是要替换还是要与主渲染窗口混合, ...

  6. 转:OGRE 渲染通路(Pass)

    一个渲染通路就是几何问题里的一次渲染:一个带有一整套渲染属性的渲染API的一次调用.一个技术可以包含有1到16个渲染通路,当然,渲染通路用得越多,技术在渲染的时候开销越大. 为了清楚识别使用的到底是哪 ...

  7. Ogre 学习记录

    http://www.cppblog.com/richardhe/articles/55722.html 1: 设计初衷 它设计初衷是完全跨平台的.抽象的接口隐藏了平台相关的细节. 它设计初衷是大幅度 ...

  8. [比较老的文章]三维渲染引擎 OGRE 与 OSG 的比较综述

    1 .引言随着计算机可视化.虚拟现实技术的飞速发展,人们对实时真实感渲染以及场景复杂度提出了更高的要求.传统的直接使用底层图形接口如OpenGL.DirectX开发图形应用的模式越来越暴露出开发复杂性 ...

  9. z-fighting在unity中的解决方式

    如果在画面中,发现有画面闪烁的问题.那么大多数情况下是z-fighting引起的, 解决方案: 1, 在每个场景中,找到那个MainCamera,然后在Inspector上,找到MainCamera的 ...

随机推荐

  1. C#:安装Windows服务,动态指定服务名及描述

    Installer.cs>> public Installer() { InitializeComponent(); /* 服务未注册前,System.Configuration.Conf ...

  2. Lab_1_SysOps_Compute_Linux_v2.5

    System Operations - Lab 1: Creating Elastic Compute Cloud (Amazon EC2) Instances (Linux) - 2.5 ===== ...

  3. JavaScript中 Promise的学习以及使用

    今天一个哥们发过来一段js代码,没看懂,就顺便学习了一下,代码如下  Promise.resolve('zhangkai').then(value => {console.log(value)} ...

  4. A*算法入门

    来源:http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx 在看下面这篇文章之前,先介绍几个理论知识,有助于理解A*算法. 启发式搜索 ...

  5. 磁盘IO的性能指标

    磁盘IO的性能单位: bps (byte/s)   每秒钟 byte 数 kbps = bps / 1024 mbps = kbps / 1024 相关计算可以参考下面代码:  https://git ...

  6. System.Web.HttpCompileException (0x80004005): (0): error CS0016: 未能写入输出文件

    重新系统后,iis asp.net站点老是出现: System.Web.HttpCompileException (0x80004005): (0): error CS0016: 未能写入输出文件“c ...

  7. unity3d c#脚本定义Transform

    Transform n = Instantiate(newobject,transform.position,transform.rotation) as Transform;Instantiate返 ...

  8. QQ粘性布局

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  9. 按钮打开链接,按钮click代码

    procedure TForm1.GotoURL(sURL:String);begin    with dde do    begin        ServiceApplication:='C:\P ...

  10. JavaScript 面向对象与原型

    ECMAScript有两种开发模式:1.函数式(过程化);2.面向对象(OOP); 一 创建对象1.普通的创建对象 ? 1 2 3 4 5 6 7 8 9 // 创建一个对象,然后给这个对象新的属性和 ...