|
|
曾经看到这样一个帖子
////////////////////////////////////////////////////////////////////////////
----->
十万火急,再不解决老板就要炒人了
我始终算出来是错的,我草他吗!!!
下面是我的方法,请看看是不是有错
//计算出观察矩阵和透视矩阵
D3DXMATRIXA16 m_view;
D3DXMATRIXA16 m_proj;
D3DXMatrixLookAtLH( &m_view, &m_eye, &m_lookat, &m_up );
D3DXMatrixPerspectiveFovLH( &m_proj, m_pi, m_aspect, m_near, m_far );
//初始化m_stand_frustum_point,他是经过视图变换和投影变换后的范体
D3DXVECTOR3 m_stand_frustum_point[8];
m_stand_frustum_point[0] = D3DXVECTOR3(1, 1, 0);
m_stand_frustum_point[1] = D3DXVECTOR3(1, -1, 0);
m_stand_frustum_point[2] = D3DXVECTOR3(-1, 1, 0);
m_stand_frustum_point[3] = D3DXVECTOR3(-1, -1, 0);
m_stand_frustum_point[4] = D3DXVECTOR3(1, 1, 1);
m_stand_frustum_point[5] = D3DXVECTOR3(1, -1, 1);
m_stand_frustum_point[6] = D3DXVECTOR3(-1, 1, 1);
m_stand_frustum_point[7] = D3DXVECTOR3(-1, -1, 1);
D3DXMATRIX iver_view;
D3DXMATRIX iver_proj;
D3DXMATRIX mul_temp;
//计算出观察矩阵和透视矩阵的逆矩阵
D3DXMatrixInverse(&iver_proj, 0, &m_proj);
D3DXMatrixInverse(&iver_view, 0, &m_view);
//把他们相乘得到最终的反算矩阵
D3DXMatrixMultiply(&mul_temp, &iver_proj, &iver_view);
//把最终的范体的每个点乘上反算矩阵,应该得到他们在被进行视图变换和投影变换之前的位置
D3DXVECTOR4 temp;
D3DXVECTOR3 m_frustum_point[8];
for(int i=0; i<8; ++i)
{
D3DXVec3Transform( &temp, &m_stand_frustum_point, &mul_temp );
m_frustum_point.x = temp.x;
m_frustum_point.y = temp.y;
m_frustum_point.z = temp.z;
}
//但是结果根本和我想的不一样,好象X坐标有很大错误,请问为什么?我什么地方错了?
<--------
//////////////////////////////////////////////////////////////////////////////
详细内容请看
http://bbs.gameres.com/showthread.asp?threadid=11636
里面的楼主计算的世界空间的viewfrustum的8个顶点有问题,大家讨论时都把焦点放到了矩阵的计算了,其实我觉得矩阵的计算并没有错误,而是对于m_stand_frustum_point的初始化有问题,因为世界空间的viewfrustum的8个顶点经过视角变换和投影变换后并不是上面所说的范体(x[-1,1],y[-1,1],z[0,1]),而仍然是个锥体(前提是水平视角和垂直视角的比值是1,其他情况可照此类推,关键是m_stand_frustum_point要正确),锥体的尺寸是:前截平面是边长等与2倍眼睛到这个平面的距离的正方形(也就是边长=2*Z-near,Z-near是所能看到的最近距离),后截平面是边长等于2倍眼睛到这个平面的距离的正方形(也就是边长=2*Z-far,Z-far是所能看到的最远距离),前截平面在z=0平面上,后截平面在z=Z-far平面上。
有文章为证,选自dx8.0sdk的帮助文档The Projection Transformation部分。
..........
The following matrix addresses these issues, and it adjusts vertices to account for the aspect ratio of the viewport, making it a good choice for the perspective projection.
w 0 0 0
0 h 0 0
0 0 Q 1
0 0 -QZn 0
In this matrix, Zn is the z-value of the near clipping plane. The variables w, h, and Q have the following meanings. Note that fovw and fovh represent the viewport's horizontal and vertical fields of view, in radians.
w=cot(fovw/2)
h=cot(fovh/2)
Q=Zf/(Zf-Zn)
...................
以上就是D3D中的投影变换,你用一个锥体的8个点乘以上面的投影矩阵试试,和我所说的是不是一致的。
至于为什么最后能得到一个范体,因为在经过投影变换后得到的点的四维齐次坐标[x,y,z,w]经过标准化后就是一个范体了,标准化的过程是这样的:x'=x/w,y'=y/w,z'=z/w,为什么要除以w,大家观察一下上面的投影矩阵,经过投影变换后得到的点的四维齐次坐标[x,y,z,w]的w存放的就是变换前点的z坐标值。其实在D3D中并没有标准化这一步。
下面是修改后的初始化:
m_stand_frustum_point[0] = D3DXVECTOR3(Zn,Zn, 0);
m_stand_frustum_point[1] = D3DXVECTOR3(Zn, -Zn, 0);
m_stand_frustum_point[2] = D3DXVECTOR3(-Zn, Zn, 0);
m_stand_frustum_point[3] = D3DXVECTOR3(-Zn, -Zn, 0);
m_stand_frustum_point[4] = D3DXVECTOR3(Zf, Zf, Zf);
m_stand_frustum_point[5] = D3DXVECTOR3(Zf, -Zf, Zf);
m_stand_frustum_point[6] = D3DXVECTOR3(-Zf, Zf, Zf);
m_stand_frustum_point[7] = D3DXVECTOR3(-Zf, -Zf, Zf);
以上是个人见解,如有错误,请不吝赐教。 |
|