[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相对应,如下图所 ...
随机推荐
- rdesktop remember
整个地球都知道rdesktop,有了它,我们可以从Solaris或者Linux使用Windows,当然Windows要开启Windows Terminal Service.虽然也有基于GTK+的tsc ...
- 【学习笔记】移动Web手册(PPK力作)
又是好久没写博客了,最近把近半年的总结,全部总结到博客园吧.先写最近的一个移动端的学习笔记.毕竟移动端开发了一段时间,就写一写读<移动web手册>中,对我感触比较深的几个点—— 一.浏览器 ...
- 学习Hadoop整体理解
HDFS是Hadoop的核心模块之一,围绕HDFS是什么.HDFS的设计思想和HDFS的体系结构三方面来介绍. Hadoop的设计思想受到Google公司的GFS设计思想的启示,基于一种开源的理念实现 ...
- w
w --help -f 开启或关闭显示用户从何处登入系统. -h 不显示各栏位的标题信息列. -l 使用详细格式列表,此为预设值. -s 使用简洁格式列表,不显示用户登入时间,终端机阶段作业和程序所耗 ...
- Merge和Rebase在Git中的区别
git命令Merge和Rebase的区别 git merge 会生成一个新得合并节点,而rebase不会 比如: D---E test / A---B---C---F master 使用merge合并 ...
- 【Python】【解决】UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 1: ordinal not in range(128)
1.问题描述 今天在升级Ubuntu到14.04,使用命令行启动软件更新器,进行版本升级,结果开始升级就异常退出了,具体打印如下: $update-manager -d 正在检查新版 Ubuntu 使 ...
- WinForm下窗体标题栏上有“帮助”按钮
将FormBorderStyle设置为Sizable. 最大化和最小化设置为false helpbutton 设置为true
- 基于C#语言利用Microsoft.office.introp.excel操作Excel总结
终于解决了质量评估测试软件在任意装有excel(2010以下版本)的电脑上正常使用的问题!!!!!!!!!! 可到http://www.microsoft.com/en-sa/download/con ...
- 在python包管理中使用easy_install软件的步骤
本文主要介绍的是让python包管理变得更加容易的实际应用方法,就是运用easy_install这一软件,下面是文章的具体介绍. easy_install让python包管理变得 如果你想对Pytho ...
- Bitset[HDU2051]
Bitset Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...