DirectX投影变换矩阵的原理与推导,齐次裁剪空间的应用举例

来源:互联网 发布:润和软件工资待遇 编辑:程序博客网 时间:2024/06/02 20:08

DirectX Geometry Pipeline的投影变换不是D3DXMatrixShadow或者几何书上的投影变换。
几何书上的投影变换是这样的:

分别是平行投影和透视投影,把空间中的三维物体变成二维平面上的图形。
而DirectX Geometry Pipeline的投影变换是这样的:

上图分别是 Perspective CameraOrthographic Camera 的视景体1(图中的坐标架代表摄像机坐标系),不同的视景体决定了不同的投影类型,常见的是透视投影和正投影。DirectX Geometry Pipeline的投影变换是把视景体都变成DirectX规定的长方体 H(齐次裁剪空间):
这里写图片描述
w>0:2
齐次坐标

P=(x,y,z,w)Hx/w[1,1]y/w[1,1]z/w[0,1]x[w,w]y[w,w]z[0,w]

前者是三维到二维的变换,后者是三维到三维的变换;
后者去掉深度信息(z坐标)就相当于前者;
前者补上深度信息可以得到后者。

Perspective Camera

现在来求 把Perspective Camera的视景体变成DirectX规定的长方体的透视矩阵,
思路是先计算三维到二维的透视投影,再加上深度向量。
这里写图片描述
E是透视投影线的汇聚点,P’ 位于投影平面上,该平面过点Q,法向是N(单位法向量)朝右,
由质点几何易知P’的齐次坐标为((PQ)NE+(QE)NP,(PE)N)
深度向量 d=((PQ)NN,0).

要还原P’的深度信息,只需 把P’的位置坐标加上深度向量d 即可

((PQ)NE+(QE)NP(PE)N,1)+((PQ)NN,0)=

((PQ)NE+(QE)NP(PE)N+(PQ)NN,1)

((PQ)NE+(QE)NP+(PE)N(PQ)NN,(PE)N)

但是因为含有(PE)N(PQ)NN,无法写成对 (P,1)的线性变换。这样我们不得不放弃使用真正的深度值了。

深度缓冲区是用来进行深度测试,处理物体的遮挡的。只要能保持相对深度关系,即使不是真正的深度值也没有关系。
如果我们把P’的齐次坐标和深度向量 d 直接相加:

((PQ)NE+(QE)NP,(PE)N)+((PQ)NN,0)=

((PQ)NE+(QE)NP+(PQ)NN,(PE)N)=

[P(NE+(QE)NI+NN)QN(E+N),PNEN]=

(P,1)[NE+(QE)NI+NNQN(E+N)NEN](1)

得到的这个矩阵叫 伪透视矩阵,它把[0,+)的实际深度值映射成[0,1],如下图:
这里写图片描述

zn 代表近裁剪平面(相对摄像机原点)的位置,x代表实际深度值(到近裁剪平面的距离),f(x)代表伪深度值。可见,太远的深度值会产生精度上的问题。
对于Perspective Camera的视景体,伪透视矩阵 把[0,zfzn]的深度值映射成[0,zfznzf].

现在把 E=(0,0,0),N=(0,0,1),Q=(0,0,zn)=znN 代入,伪透视矩阵 =

[znI+NNznNN0]=zn0000zn0000zn+1zn0010(2)

假设w、h分别代表近裁剪平面的宽度和高度,那么上面这个伪透视矩阵就把Perspective Camera的视景体变成了whzfznzf的长方体,不过,摄像机坐标架的位置还没变。

接下来要做的就是把这个whzfznzf的长方体变成DirectX规定的”宽2高2深1“的长方体,并且把摄像机坐标架平移到下图所示的位置。
这里写图片描述
所以,s=zfzfzn

zn0000zn0000zn+1zn00102w00002h0000sszn0001=

2znw00002znh0000sszn0010M(s=zfzfzn)(3)

这就是DirectX Perspective Camera的透视矩阵。它的第3行第4列的元素是1,所以若P=(x,y,z,1)是摄像机坐标系中的点,则PM=(x,y,z,z). 这样就能直接用变换后点的 w 坐标当做深度信息,而不用z/z。即 w-based depth buffer, or w-buffer3.
所以,虽然上面矩阵乘以任意的非零常数 得到的也都是透视矩阵,但是见脚注4。

Orthographic Camera

2w00002h00001zfznzn1zfzn0001(4)

先缩放,再平移。



摄像机投影之后,下一步见脚注5。
参考读物《计算机图形学与几何造型导论》一本有趣的书,翻译得也很流畅。


最后说一下齐次裁剪空间的应用:
  齐次裁剪空间的概念不光是理解DirectX投影变换的前提,还可以用它做很多有意思的事情,比如:你可能需要从某个位置某个角度摄像机的渲染结果中“抠出”某块区域(portal)内的像,用来渲染平面镜成像、虫洞(portal rendering),也可以用来渲染小地图(正投影摄像机)等。
 “抠出”是个形象的说法,不是真的去抠图,其实是把摄像机第一次的渲染结果Render to Texture,作为第二次渲染时 portal 的shader resource,用portal 的纹理坐标去采样,而 portal 的纹理坐标哪里来?就是从齐次裁剪空间来的:
这里写图片描述
(uv)=12[(xy)+(0.50.5)]

还有,3D程序的鼠标拾取算法:先根据鼠标的屏幕位置坐标构造摄像机空间的射线,再求交。


  1. Perspective Camera的视景体是一个四棱台,由垂直于z轴的远、近裁剪平面,过x轴 相对xoz平面对称的两个平面,过y轴 相对yoz平面对称的两个平面 围成;
    Orthographic Camera的视景体是一个长方体,由”近、远、上、下、左、右“六个面围成;z轴正向朝远,x轴正向朝右,y轴正向朝上,且长方体沿z轴旋转对称。 ↩
  2. Viewports and Clipping (Direct3D 9) ↩
  3. Depth Buffers (Direct3D 9)
    https://www.mvps.org/directx/articles/using_w-buffers.htm ↩
  4. A W-Friendly Projection Matrix ↩
  5. Viewports and Clipping (Direct3D 9) ↩
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩子老说头疼怎么办 孩子总是否定自己怎么办 孩子总是否定别人怎么办 老师屏蔽家长该怎么办 初二学生学疲劳怎么办 孩子不愿补英语怎么办 培训班孩子不学怎么办 小孩不想去学校怎么办 讨厌父母的性格怎么办 老师揪孩子耳朵怎么办 老师整天骂孩子怎么办 教师被学生骂怎么办 幼儿园学生骂老师怎么办 学生骂老师外号怎么办 小孩上课很多嘴怎么办 学生老玩手机怎么办 和校长有了矛盾怎么办 家长打了我怎么办 小朋友不想去幼儿园怎么办 小朋友不想上幼儿园怎么办 高中老师打学生家长怎么办 老师偏心学生该怎么办? 老师能打孩子怎么办 有的幼儿打老师怎么办? 孩子特别怕老师怎么办 孩子跟老师认生怎么办 和搭班老师不合怎么办 学生厌学了老师怎么办 孩子很怕我怎么办 斗米报名之后怎么办 孩子鼻子长疮怎么办 六年级孩子不爱学习怎么办 孩子不要爱学习怎么办? 孩子说不愿意读书怎么办 孩子三天没吃饭怎么办 孩子三天不吃饭怎么办 初中学生不爱学习怎么办 孩子写字头歪怎么办 学习习惯差该怎么办 孩子沉迷网络游戏家长怎么办 二年级贪玩厌学怎么办