龙书中拾取例子解析

来源:互联网 发布:写轻小说的软件 编辑:程序博客网 时间:2024/05/22 13:52

前几天看到龙书拾取的例子,以为点击了屏幕上一点,则这点转到视图空间就是

(这里的P为投影矩阵)




百思不得其解.

结果是我理解错误,也许是龙书误导了,它说投影平面在z=1处,


但是我认为投影平面跟GL一样,还是在近平面,不然推出来的各种投影矩阵公式中就没有n了,也许我们说的投影平面根本就不是同一个意思- -!!!



所以澄清下,点击了屏幕上一点,转到视图空间中,这点位于(0,0,0)到(Vx,Vy,Vz)的射线所在的直线上,所以这点不一定是(Vx,Vy,Vz)


好吧,下面来详细整个拾取过程,

首先,我们知道在窗口个点击一点后,它的坐标是二维的(Sx,Sy),那么这个二维坐标在标准设备坐标空间中就确定了一条从(Px,Py,0)到(Px,Py,1)的一条线段(其实更准确表述应该是确定了从(PxPw,PyPw,0,Pw)到(PxPw,PyPw,Pw,Pw)这条线段,因为Pw并不一定等于1),这条线段转到视图空间中就变成了一条从(Vx/n,Vy/n,n)到(Vx/f,Vx/f,f)的一条线段,点(Vx,Vy,1)位于这条线段所在的直线上



下面给出整个推导过程


先看(Sx,Sy)转(Px,Py)的过程

视口变换矩阵为


所以


注意这里已经假设Pw=1了

这样在标准设备坐标空间中就确定了一条从(Px,Py,0)到(Px,Py,1)的一条线段.




再看D3DXMatrixPerspectiveFovLH这个函数推导出的视图变换矩阵


则(Vx,Vy,Vz,1)到(Px,Py,Pz,Pw)的转换为


由于前面的推导公式 已经假设Pw=1了所以这里Vz=1.但是龙书由此就说Vz=1为投影平面,实在令人蛋疼啊!~~~



则可以得到


Vx=Px / P_00

Vy=Py / P_11

Vz=1


其中

P_00=cot(θ/2)/aspect

P_11=cot(θ/2)


再将


代入上式

则可得



最后看下龙书里的一段代码

d3d::Ray CalcPickingRay(int x,int y){float px = 0.0f;float py = 0.0f;D3DVIEWPORT9 vp;Device->GetViewport(&vp);D3DXMATRIX proj;Device->GetTransform(D3DTS_PROJECTION,&proj);px=(((2.0f*x)/vp.Width)-1.0f)/proj(0,0);py=(((-2.0f*y)/vp.Height)+1.0f)/proj(1,1);d3d::Ray ray;ray._origin = D3DXVECTOR3(0.0f,0.0f,0.0f);ray._direction=D3DXVECTOR3(px,py,1.0f);return ray;}


原创粉丝点击