Opengl Depth Value Transformation
来源:互联网 发布:宁波ug编程培训学校 编辑:程序博客网 时间:2024/06/05 16:33
出自 http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm
老是忘记。。于是干脆直接粘到这里方便自己找。
Why is my depth buffer precision so poor?
The depth buffer precision in eye coordinates is strongly affected by the ratio of zFar to zNear, the zFar clipping plane, and how far an object is from the zNear clipping plane.
You need to do whatever you can to push the zNear clipping plane out and pull the zFar plane in as much as possible.
To be more specific, consider the transformation of depth from eye coordinates
xe, ye, ze, we
to window coordinates
xw, yw, zw
with a perspective projection matrix specified by
glFrustum(l, r, b, t, n, f);
and assume the default viewport transform. The clip coordinates of zc and wc are
zc = -ze* (f+n)/(f-n) - we* 2*f*n/(f-n)
wc = -ze
Why the negations? OpenGL wants to present to the programmer a right-handed coordinate system before projection and left-handed coordinate system after projection.
and the ndc coordinate:
zndc = zc / wc = [ -ze * (f+n)/(f-n) - we * 2*f*n/(f-n) ] / -ze
= (f+n)/(f-n) + (we / ze) * 2*f*n/(f-n)
The viewport transformation scales and offsets by the depth range (Assume it to be [0, 1]) and then scales by s = (2n-1) where n is the bit depth of the depth buffer:
zw = s * [ (we / ze) * f*n/(f-n) + 0.5 * (f+n)/(f-n) + 0.5 ]
Let's rearrange this equation to express ze / we as a function of zw
ze / we = f*n/(f-n) / ((zw / s) - 0.5 * (f+n)/(f-n) - 0.5)
= f * n / ((zw / s) * (f-n) - 0.5 * (f+n) - 0.5 * (f-n))
= f * n / ((zw / s) * (f-n) - f) [*]
Now let's look at two points, the zNear clipping plane and the zFarclipping plane:
zw = 0 => ze / we = f * n / (-f) = -n
zw = s => ze / we = f * n / ((f-n) - f) = -f
In a fixed-point depth buffer, zw is quantized to integers. The next representable z buffer depth away from the clip planes are 1 and s-1:
zw = 1 => ze / we = f * n / ((1/s) * (f-n) - f)
zw = s-1 => ze / we = f * n / (((s-1)/s) * (f-n) - f)
Now let's plug in some numbers, for example, n = 0.01, f = 1000 and s = 65535 (i.e., a 16-bit depth buffer)
zw = 1 => ze / we = -0.01000015
zw = s-1 => ze / we = -395.90054
Think about this last line. Everything at eye coordinate depths from -395.9 to -1000 has to map into either 65534 or 65535 in the z buffer. Almost two thirds of the distance between the zNear andzFar clipping planes will have one of two z-buffer values!
To further analyze the z-buffer resolution, let's take the derivative of [*] with respect to zw
d (ze / we) / d zw = - f * n * (f-n) * (1/s) / ((zw / s) * (f-n) - f)2
Now evaluate it at zw = s
d (ze / we) / d zw = - f * (f-n) * (1/s) / n
= - f * (f/n-1) / s [**]
If you want your depth buffer to be useful near the zFar clipping plane, you need to keep this value to less than the size of your objects in eye space (for most practical uses, world space).
- Opengl Depth Value Transformation
- OpenGL Transformation
- OpenGL Transformation
- OpenGL Transformation
- OpenGL Normal Vector Transformation
- OpenGL Transformation Thinking
- DX & OpenGL 's depth
- 在Shader修改Depth Value
- OpenGL笔记之矩阵变换(Matrix Transformation)
- OpenGL笔记之矩阵变换(Matrix Transformation)
- OpenGL Transformation and Matrix Storage Detail
- OpenGL笔记之矩阵变换(Matrix Transformation)
- OpenGL笔记之矩阵变换(Matrix Transformation)
- OpenGL笔记之矩阵变换(Matrix Transformation)
- OpenGL学习脚印: 模型变换(model transformation)
- OpenGL学习脚印: 视变换(view transformation)
- OpenGL学习脚印: 模型变换(model transformation)
- OpenGL学习脚印: 视变换(view transformation)
- c++的文件读写
- hdu1392Surround the Trees 凸包
- 期末二
- 8086 CPU 寻址方式
- 总结:复合数据对象
- Opengl Depth Value Transformation
- VS2010编译错误:fatal error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x
- 逆向常用断点设置列表
- 三、初学Java多线程:使用Runnable接口创建线程
- 研发漫画之二:救火还需纵火犯
- Android TouchDelegate
- C#枚举类型 标志枚举
- 策略模式
- 软工实验报告二