前话:
三维空间到三维空间的所有可行的投影都可以通过一个适当的4×4可逆矩阵和齐次坐标来实现。如果这个矩阵并不可逆,当它的秩为3,它可以从三维空间投影到二维平面上。每个可行的从三维空间到二维平面都可以用一个秩为3的4×4矩阵来实现。为了找到一个任意的物体在一个任意的平面上由于一个任意的光源(可能位于无限远处)照射所造成的阴影,需要找到一个表示这个投影的矩阵,把它与矩阵堆栈的顶部矩阵相乘,并用阴影颜色绘制物体。
绘制阴影的步骤:
1、获得光照的位置(lightpostion);
2、获得绘制阴影的所在平面;
3、计算一个阴影矩形;
4、绘制阴影前,将当前矩阵乘以阴影矩阵,然后渲染模型。
计算阴影矩阵的函数:
/****************************************************************************
SetShadowMatrix()
Calculates the shadow projection matrix based on the light position and plane
*****************************************************************************/
void SetShadowMatrix(GLfloat destMat[16], float lightPos[4], float plane[4])
{
GLfloat dot;
// dot product of plane and light position
dot = plane[0] * lightPos[0] + plane[1] * lightPos[1] + plane[1] * lightPos[2] + plane[3] * lightPos[3];
// first column
destMat[0] = dot - lightPos[0] * plane[0];
destMat[4] = 0.0f - lightPos[0] * plane[1];
destMat[8] = 0.0f - lightPos[0] * plane[2];
destMat[12] = 0.0f - lightPos[0] * plane[3];
// second column
destMat[1] = 0.0f - lightPos[1] * plane[0];
destMat[5] = dot - lightPos[1] * plane[1];
destMat[9] = 0.0f - lightPos[1] * plane[2];
destMat[13] = 0.0f - lightPos[1] * plane[3];
// third column
destMat[2] = 0.0f - lightPos[2] * plane[0];
destMat[6] = 0.0f - lightPos[2] * plane[1];
destMat[10] = dot - lightPos[2] * plane[2];
destMat[14] = 0.0f - lightPos[2] * plane[3];
// fourth column
destMat[3] = 0.0f - lightPos[3] * plane[0];
destMat[7] = 0.0f - lightPos[3] * plane[1];
destMat[11] = 0.0f - lightPos[3] * plane[2];
destMat[15] = dot - lightPos[3] * plane[3];
} // end SetShadowMatrix()