我正在尝试使用JOGL包装器为OpenGL实现阴影映射技术。我正在关注here的教程,但我无法正确渲染阴影纹理。我相信我的问题在于纹理阴影矩阵的错误使用,或者通常是矩阵的arhitmetic操作。
这是我到目前为止得到的结果(正如你可以看到阴影真的很混乱):
从光源的角度来看,深度纹理应该呈现:
纹理矩阵应该通过跟随矩阵乘法来创建:
T是纹理矩阵,P1是光的投影矩阵,Vl是光的视图矩阵,Vc是摄像机的视图矩阵。
我使用JAMA工具包进行矩阵乘法。我在gamedev stackexchange上受到this线程的启发。
//----- Atributes (Matrices) ----------
float biasmatrix[] = {
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f
};
Matrix bi = new Matrix(4, 4);
Matrix lp = new Matrix(4, 4);
Matrix lv = new Matrix(4, 4);
Matrix cv = new Matrix(4, 4);
Matrix st = new Matrix(4, 4);
private void initializeMatrices(GL2 gl) {
lightProjectionMatrix = new float[16];
lightViewMatrix= new float[16];
cameraProjectionMatrix= new float[16];
cameraViewMatrix= new float[16];
textureShadowMatrix = new float[16];
// ------------- Camera -------------
//Camera projection matrix
gl.glMatrixMode(GL2.GL_PROJECTION); // choose projection matrix
gl.glLoadIdentity(); // reset projection matrix
glu.gluPerspective(zoomFactor, (float)wwidth/wheight, 1.0f, 100.0f);
//Camera view matrix
gl.glMatrixMode(GL2.GL_MODELVIEW); // choose projection matrix
gl.glLoadIdentity();
glu.gluLookAt(
cameraPosition[0], cameraPosition[1], cameraPosition[2],//Camera position
0.0f, 1.0f, 0.0, // Where to look
0.f, 1.0f, 0.0f); //Positive Z vector
//Get matrices
gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX, cameraProjectionMatrix, 0);
gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, cameraViewMatrix, 0);
// ------------- Light -------------
//Light projection matrix
gl.glMatrixMode(GL2.GL_PROJECTION); // choose projection matrix
gl.glLoadIdentity();
glu.gluPerspective(45.0f, 1.0f, 2.0f, 10.0f);
//Light view matrix
gl.glMatrixMode(GL2.GL_MODELVIEW); // choose projection matrix
gl.glLoadIdentity();
glu.gluLookAt(
lightPosition[0], lightPosition[1], lightPosition[2],//Light position
0.0f, 0.0f, 0.0, // Where to look
0.f, 1.0f, 0.0f); //Positive Z vector
//Get matrices
gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX, lightProjectionMatrix, 0);
gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, lightViewMatrix, 0);
//Store values into JAMA matrices
bi = new Matrix(buildJamaMatrix(biasmatrix));
lp = new Matrix(buildJamaMatrix(lightProjectionMatrix));
lv = new Matrix(buildJamaMatrix(lightViewMatrix));
cv = new Matrix(buildJamaMatrix(cameraViewMatrix));
}
private void calcTextureMatrix(GL2 gl) {
//Do tranformations
st = bi.times(lp).times(lv);
//Transpose
st = st.transpose();
}
//I wrote this function to be able to convert a float[] array, which represents
//the matrix into 4x4 JamaMatrix format
public double[][] buildJamaMatrix(float[] matrix){
double[][] niceMatrix = new double[4][4];
//For every item of a matrix
int i = 0;
//Build row
for (int j = 0; j < 4; j++) {
//Build item
for (int k = 0; k < 4; k++) {
niceMatrix[j][k] = matrix[i];
i++;
}
}
return niceMatrix;
}
public float[] unpackRowFromJamaMatrix(Matrix jamaMatrix, int row){
float[] rowContents = new float[4];
for (int i = 0; i < 4; i++) {
rowContents[i] = (float) jamaMatrix.get(i, row);
}
return rowContents;
}
在获得矩阵并进行arhitmetics之后,我以这种方式使用纹理矩阵(对于所有其他组件--T,R,Q,类似地):
float[] row0 = unpackRowFromJamaMatrix(st,0);
gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR);
gl.glTexGenfv(GL2.GL_S, GL2.GL_EYE_PLANE, row0 , 0);
gl.glEnable(GL2.GL_TEXTURE_GEN_S);
我不知道这对我的故障排除是否有帮助,但初始化后的矩阵如下所示:
Bias matrix -------------
0.5 , 0.0 , 0.0 , 0.0
0.0 , 0.5 , 0.0 , 0.0
0.0 , 0.0 , 0.5 , 0.0
0.5 , 0.5 , 0.5 , 1.0
Light projection matrix -------------
2.4142134189605713 , 0.0 , 0.0 , 0.0
0.0 , 2.4142134189605713 , 0.0 , 0.0
0.0 , 0.0 , -1.5 , -1.0
0.0 , 0.0 , -5.0 , 0.0
Light view matrix -------------
-1.0 , 0.0 , 0.0 , 0.0
0.0 , 0.1961161345243454 , 0.9805806875228882 , 0.0
0.0 , 0.9805806875228882 , -0.1961161345243454 , 0.0
0.0 , 6.463912427534524E-8 , -6.118823528289795 , 1.0
Camera view matrix -------------
1.0 , 0.0 , 0.0 , 0.0
0.0 , 0.7808688282966614 , 0.6246950626373291 , 0.0
0.0 , -0.6246950626373291 , 0.7808688282966614 , 0.0
0.0 , -0.7808688282966614 , -7.027819633483887 , 1.0