OpenGL Normal Matrix

时间:2012-06-09 14:20:24

标签: android opengl-es opengl-es-2.0

我一直在尝试使用OpenGL ES 2.0为Android创建简单的漫反射照明着色器,并从OpenGL 4.0着色语言食谱中获取知识,但它并没有说明正常的矩阵,我很确定问题来自于它,因为我一直在使用的“模型”在WebGL中工作得很好,我可以使用那些我找不到Java的glMatrix库。

我不确定如何从模型视图矩阵中获取正常矩阵但是我只读了倒置的3x3模型视图矩阵的转置,太糟糕了Android Matrix类只允许你使用4x4矩阵(对吧?)所以我'我一直在着色器中拆分矩阵,这可能是我出错的地方。

所以我所做的只是这样:

    float[] nMatrix = new float[4 * 4];
    Matrix.invertM(nMatrix, 0, mvMatrix, 0);
    Matrix.transposeM(nMatrix, 0, nMatrix, 0);

    glUniformMatrix4fv(shader.getUniformPointer("nMatrix"), 1, false, nMatrix, 0);

然后在我的顶点着色器中执行此操作:

tNorm = normalize(mat3(nMatrix) * vNormal).xyz;

其余代码基本上来自本书,结果在下面

enter image description here

正如你所看到的那样,立方体的某些方面很暗,我相信即使我不知道任何Android GL调试器,我也能得到所有法线,但如果你知道一个,请随时告诉我它

所以问题是,如何从我的模型视图矩阵中正确获取正常矩阵?

2 个答案:

答案 0 :(得分:3)

我找不到Java中的Matrix库来帮助您解决这个问题。

但是,只要您的modelView矩阵不包含非均匀比例,您就可以安全地使用modelView矩阵而不是normalMatrix。

这可以帮助您入门并确保您的问题不会隐藏在其他地方。

答案 1 :(得分:0)

这可能很有用

  

glm库的一些有用mat3函数的端口

package com.CosmicCreations;

public class Mat3x3 {
public static float determinant(float []m){
return 
        + m[0] * (m[4] * m[8] - m[7] * m[5])
        - m[3] * (m[1] * m[8] - m[7] * m[2])
        + m[6] * (m[1] * m[5] - m[4] * m[2]);
}
public static void Mat3(float []m4, float[]m){
m[0]=m4[0]; m[1]=m4[1]; m[2]=m4[2];
m[3]=m4[4]; m[4]=m4[5]; m[5]=m4[6];
m[6]=m4[8]; m[7]=m4[9]; m[8]=m4[10];
}
/*
    Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
    Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
    Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
    Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
    Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
    Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
    Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
    Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
    Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
    Inverse /= Determinant;
 */
public static void inverse(float []m, float[] Inverse, int offset){

float Determinant = Mat3x3.determinant(m);
Inverse[offset+0] = + (m[4] * m[8] - m[7] * m[5])/ Determinant;
Inverse[offset+3] = - (m[3] * m[8] - m[6] * m[5])/ Determinant;
Inverse[offset+6] = + (m[3] * m[7] - m[6] * m[4])/ Determinant;
Inverse[offset+1] = - (m[1] * m[8] - m[7] * m[2])/ Determinant;
Inverse[offset+4] = + (m[0] * m[8] - m[6] * m[2])/ Determinant;
Inverse[offset+7] = - (m[0] * m[7] - m[6] * m[1])/ Determinant;
Inverse[offset+2] = + (m[1] * m[5] - m[4] * m[2])/ Determinant;
Inverse[offset+5] = - (m[0] * m[5] - m[3] * m[2])/ Determinant;
Inverse[offset+8] = + (m[0] * m[4] - m[3] * m[1])/ Determinant;
}
public static void transpose(float []m, int offset, float[]result){
result[0] = m[offset+0];
result[1] = m[offset+3];
result[2] = m[offset+6];

result[3] = m[offset+1];
result[4] = m[offset+4];
result[5] = m[offset+7];

result[6] = m[offset+2];
result[7] = m[offset+5];
result[8] = m[offset+8];
}
}

它应该像这样使用 -

// Invert + transpose of mvmatrix
    float []temp = new float[18];
    Mat3x3.Mat3(mMVMatrix, temp);
    Mat3x3.inverse(temp, temp, 9);
    Mat3x3.transpose(temp, 9, normalMatrix);