JOGL中的阴影贴图(纹理矩阵问题)

时间:2013-07-09 21:52:32

标签: java opengl jogl

我正在尝试使用JOGL包装器为OpenGL实现阴影映射技术。我正在关注here的教程,但我无法正确渲染阴影纹理。我相信我的问题在于纹理阴影矩阵的错误使用,或者通常是矩阵的arhitmetic操作。

这是我到目前为止得到的结果(正如你可以看到阴影真的很混乱):

Shadow mapping jogl, problem

从光源的角度来看,深度纹理应该呈现: Depth component

纹理矩阵应该通过跟随矩阵乘法来创建:
Paulsprojects.net,Shadow mapping
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

0 个答案:

没有答案