[Zz] DX depth buffer
声明:本文完全翻译自DX SDK Documentation
depth buffer,通常被称为z-buffer或者w-buffer,是设备的一个属性,用来存储深度信息,被D3D使用。当D3D渲染一个场景到target surface的时候,它会使用depth-buffer surface上的数据,来决定被rasterized三角面片的pixel间的遮挡关系。
当depth buffer被开启,rendering surface上的每一个点都会被检测。depth buffer上的值可以是点的z坐标值,也可以是在投影空间中齐次坐标的w值。用z坐标的叫z-buffer,用w坐标值的角z-buffer。它们各有优缺点。
在深度测试开始的时候,depth buffer上的深度值被设置为场景中的最大值。rendering surface上的颜色值被设置为背景色或者背景纹理颜色。场景中的每一个三角面片都会被检测它是否跟当前的(x,y)坐标相交,如果相交,z或者w值会被检测是否比depth buffer中对应的值小,如果小,它就会被写入到depth buffer中,三角面片的颜色值会被写入到当前点的rendering surface上。
我们可以通过改变渲染状态D3DRS_ZFUNC的值,来改变D3D的比较方法,以影响depth buffer的值和render-target surface。
市面上的几乎所有减速器都支持z-buffering,使z-buffer是如今最常见的depth buffer类型。然而,无所不在的z-buffer有它的缺点。产生的z值往往不是平均分布在z-buffer 范围内(典型的是,0.0~1.0,包括0跟1)。特别的是,far跟near clipping plane非常影响z值的分布。在支持最普遍的16位depth buffer中,很容易引起远处应该被隐藏的物体显示在rendering surface上。
w-buffering就不存在这个问题,它的值会均匀分布。尤其,far跟near clipping planes的比率不再会影响w值的分布,使程序可以支持非常大的比值。当然,z-buffering不是完美的,它会引起近处本该隐藏的物体显现。另一个缺点是,w-buffering需要硬件支持,并没有z-buffering支持的那么普遍。
在渲染的时候,z-buffering是有overhead的。
Querying for Depth Buffer Support(D3D9)
如同任何特性,程序使用的驱动可能并不支持所有类型的depth buffering。总是要检查驱动的能力,尽管大部分驱动支持z-based buffering,但是并不一定支持w-based buffering。如果你尝试打开一个不支持的特性,驱动并不会崩溃。驱动可能fall back到一个它支持的depth buffering。
在创建设备之前,你可以使用D3D对象检查一下所支持的depth buffering。如果D3D对象告诉说,它支持depth buffering,那么它创建的任何设备都会支持的。
// The following example assumes that pCaps is a valid pointer to an
// initialized D3DCAPS9 structure
if(FAILED(m_pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal,
pCaps->DeviceType,
AdapterFormat,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D16)))
return E_FAIL;
同样,我们可以检测depth-stencil的支持情况。
// Reject devices that cannot create a render target of RTFormat while
// the back buffer is of RTFormat and the depth-stencil buffer is
// at least 8 bits of stencil
if(FAILED(m_pD3D->CheckDepthStencilMatch(pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, RTFormat, D3DFMT_D24S8)))
return E_FAIL;
Create a Depth Buffer
depth buffer是设备的一个属性。要创建一个被D3D管理的depth buffer,对D3DPRESENT_PARAMETERS结构体进行恰当设置。
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
通过设置EnableAutoDepthStencil = TRUE,我们命令D3D管理程序的depth buffer。AutoDepthStencilFormat = D3DFMT_D16 必须是一个有效并支持的depth buffer 格式。D3DFMT_D16是一个16位的depth buffer。
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3dDevice ) ) ) return E_FAIL;
如上代码会创建一个,创建depth buffer的设备。
depth buffer会自动被设为设备的render target。当设备重设后,depth buffer会被自动释放并重新创建,以新的大小。
要创建一个新的depth buffer surface,使用IDirect3DDevice9::CreateDepthStencilSurface。
要将新的depth buffer设置到设备上,用IDirect3DDevice9::SetDepthStencilSurface。
要使用depth buffer在我们程序中,我们需要打开 depth buffer。
Enabling Depth Buffering
在创建好depth buffer后,如果要打开depth buffer,我们可以调用IDirect3DDevice9::SetRenderState方法。设置render state的D3DRS_ZENABLE。
D3DZB_FALSE
Disable depth buffering.
D3DZB_TRUE
Enable z-buffering.
D3DZB_USEW
Enable w-buffering.
Retrieving a Depth Buffer
获取一个指向depth buffer surface的指针。
LPDIRECT3DSURFACE9 pZBuffer;
m_d3dDevice->GetDepthStencilSurface( &pZBuffer );
Clearing Depth Buffer
许多C++程序在渲染新的frame前都会清理depth buffer。我们可以显式地清理depth buffer通过调用IDirect3DDevice9::Clear,指明D3DCLEAR_ZBUFFER标签,同时,我们可以指定一个任意深度值。
Changing Depth Buffer Write Access
默认情况下,D3D是允许写depth buffer。不过,我们可以disable这个写的权限,来获得某些特效。
通过调用IDirect3DDevice9::SetRenderState,用参数D3DRS_ZWRITEENABLE,值为0。
Changing Depth Buffer Comparison Functions
默认情况下,在rendering surface上进行深度测试时,如果相应的深度值(z/w)小于depth buffer上的,D3D系统就会更新render-target上相应的点。我们可以更改深度值的比较方法。
通过调用IDirect3DDevice9::SetRenderState,用参数D3DRS_ZFUNC,值为D3DCMPFUNC枚举类型中一个。
[Zz] DX depth buffer的更多相关文章
- D3D depth buffer的预览
在使用D3D开发游戏的过程中,很多情况下都会用到depth buffer来完成特定的效果,比如DOF,Shadows,SSAO等等.在这些情况下我们就可能需要预览depth buffer来确定它是正确 ...
- 从depth buffer中构建view-space position
观察透视投影矩阵: 对于x和y,矩阵变换只是一个缩放系数,那么逆变换就是缩放系数的倒数,所以 设Xndc Yndc为NDC空间中的XY坐标,Xview Yview Zview为view space中的 ...
- 测试不同格式下depth buffer的精度
这篇文章主要是参考MJP的“Attack of The Depth Buffer”,测试不同格式下depth buffer的精度. 测试的depth buffer包含两类: 一是非线性的depth b ...
- Cesium 中由 Logarithmic Depth Buffer 引起的模型显示不完整的问题
当 Cesium 单个模型过长时,会遇到某些视角模型显示不完整的问题,如下图所示: 经过在官方论坛上询问,该问题由 viewer.scene.logarithmicDepthBuffer 开启造成,关 ...
- Depth Buffer
Up until now there is only one type of output buffer you've made use of, the color buffer. This chap ...
- Vulkan SDK 之 Depth Buffer
深度缓冲是可选的,比如渲染一个3D的立方体的时候,就需要用到深度缓冲.Swapchain就算有多个images,此时深度缓冲区也只需要一个.vkCreateSwapchainKHR 会创建所有需要的i ...
- depth/stencil buffer的作用 ----------理解模板缓存 opengl
在D3D11中,有depth/stencil buffer,它们和framebuffer相对应,如下图所示,framebuffer中一个像素,有相对应的depth buffer和stencil buf ...
- 【D3D12学习手记】4.3.8 Create the Depth/Stencil Buffer and View
我们现在需要创建深度/模板缓冲区. 如§4.1.5所述,深度缓冲区只是一个2D纹理,用于存储最近的可见对象的深度信息(如果使用模板(stencil),则也会存储模板信息). 纹理是一种GPU资源,因此 ...
- Directx11教程(48) depth/stencil buffer的作用
原文:Directx11教程(48) depth/stencil buffer的作用 在D3D11中,有depth/stencil buffer,它们和framebuffer相对应,如下图所 ...
随机推荐
- 记录远程桌面登录者的IP和MAC
WINDOWS 2003 远程桌面不能记录登陆IP真是件头痛的事,本方法可以记录登陆者IP,具体的操作步骤如下: 1.建立一个存放日志的目录,如C盘下建立一个RDP的目录“C:/RDP”. 2.然后在 ...
- 仓鼠找sugar(洛谷 3398)
题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...
- 为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?为什么在类体内可以定义将静态成员声明为其所属类的类型呢 ?
static的成员变量,不是存储在Bar实例之中的,因而不会有递归定义的问题. 类声明: class Screen: //Screen类的声明 1 类定义: class Screen{ //Scree ...
- php 面向对象的方式访问数据库
<body> <?php //面向对象的方式访问数据库 //造对象 $db = new MySQLi("localhost","root",& ...
- Android文件Apk下载变ZIP压缩包解决方案
[root@ conf]# pwd /alidata/server/nginx/conf [root@ conf]# vi mime.types application/vnd.android.pac ...
- [原]网站跨站点脚本,Sql注入等攻击的处理
从360安全论坛里找到的一段代码,经过整理封装,直接在站点Global.asax文件或写一个HttpModule来拦截恶意请求即可: http://bbs.webscan.360.cn/forum.p ...
- poj 3517 约瑟夫环
最简单的约瑟夫环,虽然感觉永远不会考约瑟夫环,但数学正好刷到这部分,跳过去的话很难过 直接粘别人分析了 约瑟夫问题: 用数学方法解的时候需要注意应当从0开始编号,因为取余会等到0解. 实质是一个递推, ...
- 修改ViewPager调用setCurrentItem时,滑屏的速度
原文摘自: 修改ViewPager调用setCurrentItem时,滑屏的速度 在使用ViewPager的过程中,有需要直接跳转到某一个页面的情况,这个时候就需要用到ViewPager的setCur ...
- 代码实现UI控件
参考 Android 用纯代码实现复杂界面
- matlab练习程序(透视投影,把lena贴到billboard上)
本练习程序是受到了这个老外博文的启发,感觉挺有意思,就尝试了一下.他用的是opencv,我这里用的是matlab. 过去写过透视投影,当时是用来做倾斜校正的,这次同样用到了透视投影,不过更有意思,是将 ...