[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相对应,如下图所 ...
随机推荐
- Shopping(hdu 3768)
题意:给你一个无向图,求从0号点开始遍历所有的指定点再回到0号点的最短路径 #include<cstdio> #include<iostream> #include<qu ...
- stm32——Flash读写
stm32——Flash读写 一.Flash简介 通过对stm32内部的flash的读写可以实现对stm32的编程操作. stm32的内置可编程Flash在许多场合具有十分重要的意义.如其支持ICP( ...
- 菜鸟学Linux命令:cat命令 查看文件内容
cat命令的用途是连接文件或标准输入并打印. 这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. Linux下查看文件内容的方式很多:vi ...
- Unity3D入门之GUI基础以及常用GUI控件使用(2)
1.GUI基础 (1)GUI部分是每帧擦除重绘的,只应该在OnGUI中绘制GUI,按钮:GUILayout.Button(“Hello”); 只读标签:GUILayout.Label() (2)修改控 ...
- win32_11gR2_database安装教程
- JSON浅总
我们在以前的学习中了解到XML是一种结构化的数据表示方式,一种可扩展标记语言!可以把XML理解成一个微型的结构化的小的数据库,保存一些小型的数据和传输数据,有严格的显示限制.但是XML语句有些冗长和繁 ...
- Intent实现页面跳转和传值
*Intent称为意图,是Android各大组件连接的桥梁 1.Activity页面跳转 同一个包内 Intent intent = new Intent(); intent.setClass(Mai ...
- Hark的数据结构与算法练习之冒泡排序
算法说明: 冒泡排序实际上是使用的最多的排序,逻辑是循环然后对相邻的数字进行比较,并交换数据. 例如有一个数组int[] arrayData = { 2, 3, 1, 5, 6, 7, 4, 65, ...
- Linux常用命令_(安装包管理)
rpm命令: RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm -ivh rpm包安装rpm包rpm -Uvh rp ...
- login控件重载登陆方法
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...