Depth Bounds Test (DBT)
Depth Bounds Test(深度范围检测),是Nvdia GeForce 6系列以后显卡的特性(GPU Programming Guide GeForce 8 and 9 Series),并不是DirectX的特性。所以在例如Nsight和Pix的图形分析工具里,是看不到它的设置的。
 
Depth Bounds Test的功能是允许程序员在blend render target前进行额外的像素Discard。这个扩展增加了一个新的逐个fragment 的测试,从逻辑上讲,它是在scissor test的后面,alpha test的前面,DBT会把保存在输入的fragment 坐标(xw,yw)位置的深度值,和用户定义的最大和最小深度值做比较,如果保存的深度值在用户定义的范围外的话,那么这个输入的fragment 会被discard掉,和alpha test不同的是,DBT并不依赖fragment在窗口空间的深度值。
DBT并不依赖从Pixel Shader输出的深度值,而是根据之前保存在render target里的深度位置做判断
  • DBT的逻辑是在 scissor test 后面, alpha testing前面
  • min/max值被clamp在[0, 1]之间,非法值会被转为0
  • DBT会被打开,当下面条件都为真时
    • min < max
    • min > 1 并且 max<1
    • depth值在Shader里被使用
  关于API使用,以CE3为例的话
void CD3D9Renderer::SetDepthBoundTest(float fMin,float fMax,bool bEnable)
{
if(bEnable)
{
m_pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_X,MAKEFOURCC('N','V','D','B'));
m_pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_Z,*(DWORD*)&fMin);
m_pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_W,*(DWORD*)&fMax);
  }
else// disable depth bound test
{
m_pd3dDevice->SetRenderState(D3DRS_ADAPTIVETESS_X,);
}
}

DBT的主要用处有两个,一个例子是在OpenGL extension文档里的例子 可以用来优化stenciled shadow volume 的渲染

  例如,一栈带有衰减等光源,可以在XY窗口空间被边界为矩形,而传统的scissor test,可以把矩形内的 shadow volume 的fragment都discard掉,保证阴影是在光源的windows窗口XY范围外的。
  而stenciled 增长或减少的部分偏离scissor的fragment的时候就无关紧要了,因为光源的照明在scissor区域外的部分,已经可以确实是完全衰减消失的了。
 
  也就是说,scissor test可以把在渲染在scissor外面的 shadow volume fragments 直接discard掉,从而提高了性能,不再需要关注那些衰减的光源最终不会影像的像素。Scissor的优化,可以用在更新渲染用的stenciled shadow volumes的时候(增加或减少stencil buffer),和增加带衰减光源的照明分布的时候。
 
  使用DBT时,我们也可以使用类似的方法,计算出衰减光源的最终照明信息在窗口空间上的Z边界(zmin,zmax),除非像素的深度值在这个范围[zmin, zmax],否则光源的照明可以被预确定是和这个像素是无关的。或者说,被做照明处理的像素在衰减光源足够远的前方或后方,以至于光源在这个像素上的照明完全的衰减没了。而DBT恰好可以做这种测试。
 
  另外一个用处也就是像CE3这种延迟渲染中了,因为光照是转化到屏幕空间进行的,所以在对物体进行光照处理时,可以参考之前的写入的光照深度,屏幕空间上,不在光照深度范围内的像素都DBT裁剪掉。
 
  在CE3.4里,主要还是在一些平面空间处理里使用,这样可以省去alpha test步骤以及额外的像素填充
 
生成SceneDiffuseAcc,使用DBT就可以省去天空部分像素判断和填充了
 
生成AO
CD3D9Renderer::GenerateAO
  1. SetDepthBoundTest(.f,0.9999f,true);

    下雨效果
    CD3D9Renderer::FX_DeferredRainLayer()

constVec4 vDepthBounds =CDeferredShading::Instance().GetLightDepthBounds(rainVolParams.m_vWorldPos, rainVolParams.m_fRadius);
SetDepthBoundTest(max(vDepthBounds.x, fMinZ), min(vDepthBounds.z, fMaxZ),true);

下雪效果
CD3D9Renderer::FX_DeferredSnowLayer()

constVec4 vDepthBounds =CDeferredShading::Instance().GetLightDepthBounds(snowVolParams.m_vWorldPos, snowVolParams.m_fRadius);
SetDepthBoundTest(max(vDepthBounds.x, fMinZ), min(vDepthBounds.z, fMaxZ),true);

延迟光照着色
CDeferredShading::LightPass

  1. Vec4 pDepthBounds =GetLightDepthBounds( pDL );
    rd->SetDepthBoundTest( pDepthBounds.x, pDepthBounds.z,true);

    IBL的延迟着色
    CDeferredShading::DeferredCubemapPass

  1. Vec4 pDepthBounds =GetLightDepthBounds( pDL );
    rd->SetDepthBoundTest( pDepthBounds.x, pDepthBounds.z,true);

    屏幕空间反射
    CDeferredShading::ScreenSpaceReflectionPass

  1. rd->SetDepthBoundTest(0.0f,0.9999f,true);

    CDeferredShading::DirectionalOcclusionPass()

  2. CDeferredShading::DirectionalOcclusionPass()

    阴影处理
    CDeferredShading::ShadowLightPasses()

  1. Vec4 pDepthBounds =GetLightDepthBounds(&light );
    rd->SetDepthBoundTest( pDepthBounds.x, pDepthBounds.z,true);

    为了在绘制里可以忽略天空部分
    void CDeferredShading::Render()

 
LPV光照
CRELightPropagationVolume::DeferredApply()
if(CRenderer::CV_r_DeferredShadingDepthBoundsTest )
{
constVec4 pDepthBounds =CDeferredShading::Instance().GetLightDepthBounds( rRendSettings.m_pos, m_fDistance );
rd->SetDepthBoundTest(pDepthBounds.x, pDepthBounds.z,true);// skip sky only for GI
}

修改方法也比较简单,关闭CV_r_DeferredShadingDepthBoundsTest,或在shader里添加clip来discard掉像素,或用alpha test替代,但这两种方法在移动平台上忌讳的,所以需要进一步测试才有结果了

关于Depth Bounds Test (DBT)和在CE3的运用的更多相关文章

  1. (转)Shadow Map & Shadow Volume

    转自:http://blog.csdn.net/hippig/article/details/7858574 shadow volume 这个术语几乎是随着 DOOM3 的发布而成为FPS 玩家和图形 ...

  2. D3D9 GPU Hacks (转载)

    D3D9 GPU Hacks I’ve been trying to catch up what hacks GPU vendors have exposed in Direct3D9, and tu ...

  3. 引擎设计跟踪(九.14.3.2) Deferred shading的后续实现和优化

    最近完成了deferred shading和spot light的支持, 并作了一部分优化. 之前forward shading也只支持方向光, 现在也支持了点光源和探照光. 对于forward sh ...

  4. 阴影锥(shadow volume)原理与展望

    转记:找了不少关于shadow volume原理的资料,还是这个帖子讲解的一目了然,转帖在这里,方便查阅.引用链接:http://blog.donews.com/yyh/archive/2005/05 ...

  5. [LeetCode] Minimum Depth of Binary Tree 二叉树的最小深度

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  6. [LeetCode] Maximum Depth of Binary Tree 二叉树的最大深度

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  7. leetcode 111 minimum depth of binary tree

    problem description: Given a binary tree, find its minimum depth. The minimum depth is the number of ...

  8. frame和bounds

    - frame 是一个以**父视图**为坐标系的位置- bounds 是一个以**自身**为坐标系的位置- 如果改变了bounds 那么会影响子控件的显示位置

  9. 【leetcode】Minimum Depth of Binary Tree

    题目简述: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along th ...

随机推荐

  1. mysql 指定端口

    mysql -P3307 -uemove -h180. -p #-P是指定端口

  2. Linux中获取当前程序的绝对路径

    代码如下: char current_absolut_path[MAX_SIZE] = ""; memset(current_absolut_path,,MAX_SIZE); // ...

  3. hdu 4666:Hyperspace(最远曼哈顿距离 + STL使用)

    Hyperspace Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tota ...

  4. oracle中merge的详解

    Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作. 当然是update还是insert是依据于你的指定的条件判断的 ...

  5. 如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)

    Laravel  和 Laravel  的邮件发送使用方式完全一致.Laravel  的邮件发送中文文档在:http: 邮箱为例,展示如何用 Laravel 内置的邮件发送类来发送邮件. 配置 修改邮 ...

  6. HDU 1796 How many integers can you find 容斥入门

    How many integers can you find Problem Description   Now you get a number N, and a M-integers set, y ...

  7. 小甲鱼PE详解之区块表(节表)和区块(节)(PE详解04)

    到此为止,小甲鱼和大家已经学了许多关于 DOS header 和 PE header 的知识.接下来就该轮到SectionTable (区块表,也成节表).(视频教程:http://fishc.com ...

  8. <select>在chrome浏览器下背景透明问题

    在上篇文章<只用CSS美化选择框>运用了背景透明的技巧来美化选择框,但在chrome浏览器下遇到了跟ie.ff不一样的透明效果,下面重现一下: 在一个大的div(背景红色)内放置一个sel ...

  9. Android 一个app启动另一个app

    最近,一个app启动另一个app,这个玩法挺火的嘛,有没有试过更新QQ到5.1版本,QQ的健康里面就可以添加其他app,实现从QQ跳转到其他app应用.这个挺好玩的,一下子带来了多少流量啊. 一.先来 ...

  10. HTML-Canvas01

    画直线: var c = document.getElementById("myCanvas"); //不要忘写document var ctx = c.getContext(&q ...