Directx9 里面的 shadowmap的例子 有些不懂 求指教D3DXMATRIXA16 g_amInitObjWorld[NUM_OBJ] {D3DXMATRIX
Directx9 里面的 shadowmap的例子 有些不懂 求指教 D3DXMATRIXA16 g_amInitObjWorld[NUM_OBJ] = { D3DXMATRIXA16( 3.5f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ), D3DXMATRIXA16( 0.43301f, 0.25f, 0.0f, 0.0f, -0.25f, 0.43301f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 5.0f, 1.33975f, 0.0f, 1.0f ), D3DXMATRIXA16( 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 0.8f, 0.0f, -14.5f, -7.1f, 0.0f, 1.0f ), ............. } ... g_Obj[i].m_mWorld = g_amInitObjWorld[i]; ..... ........ D3DXMATRIXA16 m; D3DXMatrixRotationY( &m, D3DX_PI * fElapsedTime / 4.0f ); D3DXMatrixMultiply( &g_Obj[1].m_mWorld, &g_Obj[1].m_mWorld, &m ); D3DXMatrixRotationY( &m, -D3DX_PI * fElapsedTime / 4.0f ); D3DXMatrixMultiply( &g_Obj[2].m_mWorld, &g_Obj[2].m_mWorld, &m ); ....................
mLightView = g_Obj[2].m_mWorld; D3DXVECTOR3 vPos( mLightView._41, mLightView._42, mLightView._43 ); // Offset z by -2 so that it's closer to headlight D3DXVECTOR4 vDir = D3DXVECTOR4( 0.0f, 0.0f, -1.0f, 1.0f ); // In object space, car is facing -Z mLightView._41 = mLightView._42 = mLightView._43 = 0.0f; // Remove the translation D3DXVec4Transform( &vDir, &vDir, &mLightView ); // Obtain direction in world space vDir.w =0.0f; // Set w 0 so that the translation part below doesn't come to play D3DXVec4Normalize( &vDir, &vDir ); vPos.x += vDir.x * 4.0f; // Offset the center by 4 so that it's closer to the headlight vPos.y += vDir.y * 4.0f; vPos.z += vDir.z * 4.0f; vDir.x += vPos.x; // vDir denotes the look-at point vDir.y += vPos.y; vDir.z += vPos.z; D3DXVECTOR3 vUp( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH( &mLightView, &vPos, ( D3DXVECTOR3* )&vDir, &vUp );
这是在shadowmap.cpp中的OnFrameRender()函数里的一部分。
g_Obj[2]是一个汽车的3D模型.
大体的意思就是求 以车头灯为视点的观察矩阵
不明白的地方如下:
1,D3DXVECTOR3 vPos( mLightView._41, mLightView._42, mLightView._43 ); 此时的vpos获得的值是不是车在世界坐标系下的位置
2, D3DXVec4Transform( &vDir, &vDir, &mLightView ); 此时的vDir是不是已经是 是世界坐标系下的汽车的朝向
3, vPos.x += vDir.x * 4.0f; // Offset the center by 4 so that it's closer to the headlight
vPos.y += vDir.y * 4.0f;
vPos.z += vDir.z * 4.0f;
求解释,我明白是向量的加法 但是想象不出为什么 这么会使得vPos离车头更近
[解决办法] 1 vPos得到的是光源在世界坐标系中的位置向量
2 vDir得到的是世界坐标系中前灯的朝向向量
3 vPos经过向量加法,相当于在世界坐标系中,从光源朝车灯的一个位移。目的是在世界空间中把光源放到车灯位置上。因为vPos在1中是已经变换到世界空间中的光源位置,而vDir是世界空间中汽车的朝向。在模型空间中,汽车的中心点应该在原点,而光源也应该在原点。这样的一个位移保证了它们在世界空间中的一个一致性的位移。
[解决办法] vpos是车的“参考点”在世界坐标系中的位置,参考点也许在车中心。这要看建立模型时候车上那一个点在模型空间原点。对于光源的处理,正是通过沿着车头方向移动光源来实现的。
关于w,你可能笔误了,应该是w设置成0,而不是1。因为vDir是个向量,而不是一个点。通过w表示向量是一种齐次坐标表示。在齐次表示中,对于向量,w必须是0。对于点,w必须是1。
直观上来讲,只有对点可以有位移,对于向量(方向),位移对他来说没有意义。w为0,避免的变换矩阵的位移component对该向量起作用,这一点,你代码中的注释说的很清楚了:
vDir.w =0.0f; // Set w 0 so that the translation part below doesn't come to play
通过齐次坐标表示一个方向向量,w是0。既是数学上的要求,也是工程上的必然。关于其次坐标在游戏中的使用,你可以参考文章:
http://blog.csdn.net/popy007/article/details/1797121
[解决办法] D3DXVECTOR4 vDir = D3DXVECTOR4( 0.0f, 0.0f, -1.0f, 1.0f ); // In object space, car is facing -Z
mLightView._41 = mLightView._42 = mLightView._43 = 0.0f; // Remove the translation
D3DXVec4Transform( &vDir, &vDir, &mLightView ); // Obtain direction in world space
vDir在定义的时候w是1.0,我认为是一种概念上的忽略以及代码上的方便:)在第2行它已经把mLightView的translation去掉了,所以就算是w=1,对结果也没有影响。
在变换完vDir后,它马上把vDir的w变成了0,从而避免normalize单位化的时候,把w也算进去。最后
vDir.x += vPos.x; // vDir denotes the look-at point
它把vDir当作了一个点来用。。。这完全是基于代码上的便利性——对方向作位移是什么意思?把它当个点用就有意义了,但是,这违背了该变量的名字vDir(ection)。因此,从可读性角度来说,这段代码不是很好。
[解决办法] 引用: 引用:D3DXVECTOR4 vDir = D3DXVECTOR4( 0.0f, 0.0f, -1.0f, 1.0f ); // In object space, car is facing -Z mLightView._41 = mLightView._42 = mLightView._43 = 0.0f; // Remove th…… 对,这就是shadowmap原理。shadowmap是很多高级阴影技术的雏形。
[解决办法] http://blog.csdn.net/pizi0475