详细介绍Z-Buffer与W-Buffer

简介:

Depth-Buffer(深度缓存)有两种:Z-Buffer 和 W-Buffer,这里讨论这两种深度缓存的区别,以及如何在两者之间转换。
w 的含义
3D空间点的坐标是(x,y,z),为了使矩阵乘法具有平移变换的功效,我们用4D空间中的点(x,y,z,w)来表示3D空间中的点(x',y',z'),这两个不同空间点之间的关系是:

x' = x / w
y' = y / w
z' = z / w

像这样用四维空间点表示三维空间点,或者说用 n + 1 维空间点表示 n 维空间点的方法叫做 “齐次坐标表示法”。

实际使用中,在模型->世界转换、世界->视图转换过程中,w 通常保持不变,总是等于一,这样,齐次坐标的前三个分量就是对应3D空间点的三个坐标分量。但是,经过投影变换后,w 将得到一个比例值,比如,一般的透视投影变换矩阵是:

| W  0  0  0 |
| 0  H  0  0 |
| 0  0  Q  1 |
| 0  0 -QZn 0 |

其中  Zn = 近裁剪面 z 坐标
Zf = 远裁剪面 z 坐标
W = 2 * Zn / 视口宽度
H = 2 * Zn / 视口高度
Q = Zf / (Zf - Zn)

将点(x,y,z,1)乘以此矩阵,w 便不再是一,而对应的3D空间点坐标(x / w,y / w,z / w)将出现一个缩放效果。同时,因为 w 的值通常与 z 坐标成正比(比如经过上面这个矩阵的变换,w 的值其实就是 z 坐标的值),所以经过投影变换,物体会产生近大远小的效果。

Z-Buffer 与 W-Buffer 的区别
简单的说,z-buffer 与 w-buffer 的区别就是前者保存的是点的 z 坐标,而后者保存的是点的 w 坐标。

具体的说,两者因为保存的值有不同的含义,所以表现出来的实际效果也会有差别。

z-buffer 保存的是经过投影变换后的 z 坐标,前面说过,投影后物体会产生近大远小的效果,所以距离眼睛比较近的地方,z 坐标的分辨率比较大,而远处的分辨率则比较小,换句话说,投影后的 z 坐标在其值域上,对于离开眼睛的物理距离变化来说,不是线性变化的(即非均匀分布),这样的一个好处是近处的物体得到了较高的深度分辨率,但是远处物体的深度判断可能会出错。

w-buffer 保存的是经过投影变换后的 w 坐标,而 w 坐标通常跟世界坐标系中的 z 坐标成正比,所以变换到投影空间中之后,其值依然是线性分布的,这样无论远处还是近处的物体,都有相同的深度分辨率,这是它的优点,当然,缺点就是不能用较高的深度分辨率来表现近处的物体。

从硬件实现角度来说,几乎所有的硬件3D加速卡都支持 z-buffer,而 w-buffer 的支持没有 z-buffer 那么广泛。另外,早期的 Direct3D 版本看起来也不支持 w-buffer。

Z-Buffer 与 W-Buffer 之间的转换
根据上面的矩阵变换,可以很容易的导出将 w-buffer 转换成 z-buffer 的公式:

zDepth = Q * ( wDepth - Zn ) / wDepth
= Zf / ( Zf - Zn ) * ( wDepth - Zn ) / wDepth

这个转换公式有什么用处?举个例子:3DS MAX 使用的是 w-buffer,如果从 3DS MAX 中导出深度信息到 Direct3D 中,作为预渲染的背景使用,就有可能用到上面这个转换。当然,如果在 D3D 中使用 w-buffer,问题就不大了,但是如果使用 z-buffer,不经过这样的转换,渲染结果就会出错。

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/geniusalex/archive/2010/04/26/1940510.html

目录
相关文章
|
存储 Java 索引
43 # buffer 的应用
43 # buffer 的应用
66 0
|
2月前
|
JavaScript 前端开发 网络协议
Buffer
【10月更文挑战第23天】
36 3
|
7月前
|
存储 算法 关系型数据库
Buffer Pool
Buffer Pool
65 1
|
存储 缓存 算法
Buffer
Buffer
257 0
Buffer
|
存储 SQL 缓存
写缓冲(change buffer),这次彻底懂了!!!
一次了解缓冲池(buffer pool)。
596 0
写缓冲(change buffer),这次彻底懂了!!!
|
SQL 缓存 算法
缓冲池(buffer pool),这次彻底懂了!!!
缓冲池(buffer pool)是一种常见的降低磁盘访问的机制。
3989 0
缓冲池(buffer pool),这次彻底懂了!!!