OpenGL 透视投影 齐次裁剪空间 深度缓存

来源:互联网 发布:软件测试工程师职责 编辑:程序博客网 时间:2024/05/17 05:02

转载自:http://blog.csdn.net/zhuyingqingfen/article/details/45721643

对于从事三维方面的 ,透视投影公式应该不陌生,如下:

glFrustum函数公式为:


glPerspetive为:



经过透视投影 (正射投影也一样)变换, 能够把点 从 观察空间(相机坐标系)转换到 齐次裁剪空间坐标系又叫规则观察体(Canonical View Volume)如下图)。这个转化后的空间体 不仅独立于 把三维场景转换为二维屏幕空间的投影类型(透视、正射),也独立于屏幕的分辨率(Resolution) 以及长宽比(Aspect Ratio).

The term "homogeneous" means that these coordinates should not necessarily be considered to be true Cartesian positions until they are divided by their fourth coordinate.




齐次裁剪空间坐标系(范围  -1<=x <=1,-1<=y<=1,-1<=z <=1, )是左手坐标系,为什么? 其实也很好理解,如上图 , A和B点经过投影变换后其x坐标是一样的(不再是投影平截体中的那种相对关系), 而近裁剪面上的点的z坐标经过投影变换后变为-1 , 而远裁剪面上的z坐标为1 ,所以齐次裁剪空间坐标系的z轴的正方向正好和相机坐标系中的z轴正方向是相反的。

经过透视投影后,每个顶点的x和y坐标还要除以其z坐标,这个除法是产生透视收缩的方法。


假设相机坐标系中的一点 P_V,经过透视变换后为P_H(分量分别为P_Hx,P_Hy,P_Hz,1)

P_Hz = - P_Vz  *  (far+near)/(far-near) - 2far*near/(far-near)

P_Hw = -P_Vz。


经过透视投影后 (除以变换后的w分量,即相当于除以 观察坐标系中的-z坐标)

P_Hz' = (far+near)/(far-near)  + (2far*near)/(P_Vz  *(far-near))


当P_Vz = -near(注意是负数,看上图便知) 时候 P_Hz' = -1

当P_Vz = -far 的时候,P_Hz'=1


从上面求 P_Hz的公式中也可以看到,深度缓冲的值并不是线形的,随着z值(相机坐标系)的增大,精度迅速降低),这也是为什么远处两个邻近的物体会发生闪烁的原因,也就是深度冲突 。



所以,事实上是透视投影变换由两步组成:  
1)  用透视变换矩阵把顶点从视锥体中变换到裁剪空间的CVV中。  
2)  CVV裁剪完成后进行透视除法。


另外多边形裁剪就是用这个规则体(齐次裁剪空间坐标系)完成的。


引用OpenGL Shader 4.0 CookBook 中一句话(第7章shadow)

In clip coordinates (after perspective division) the z coordinate ranges from
-1 to 1. It is the viewport transformation that (among other things) converts
the depth to a range between zero and one. Incidentally, if so desired, we can
configure the viewport transformation to use some other range for the depth
values (say between 0 and 100) via the function glDepthRange.


Of course, the x and y components also need to be biased between zero and one because
that is the appropriate range for texture access.
We can use the following "bias" matrix to alter our clip coordinates.

This matrix will scale and translate our coordinates such that the x, y, and z components range from 0 to 1 (after perspective division)

因为经过透视除法后顶点的w分量是1  那么范围是 -1 到1 的x 映射到 0 到 1 上 就是 x‘ = (x+1)/2 = x/2 + 0.5 

0 0
原创粉丝点击