OpenGL ES 2.0和Android:normalMatrix应该有哪些尺寸?

时间:2015-04-08 11:00:45

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

我正在学习OpenGL ES 2.0,没有学过OpenGL或OpenGL ES 1.x。

我正在对我的modelViewMatrix应用非均匀缩放,因此教程告诉我需要采取特殊步骤来计算normalMatrix。在我的应用程序中,modelViewMatrix的维度为4x4。

  1. 有些教程说,对于normalMatrix,我需要简单地计算转置(反向(modelViewMatrix))。

  2. 其他说明我需要先取得modelViewMatrix的左上角3x3子矩阵,然后计算转置(逆(子矩阵))。

  3. 有什么区别吗?它们会导致相同的结果吗?

    现在我正在使用方法1,然后在顶点着色器中我在应用转换后提取vec3:

    vec3 vNormalEyespace = vec3(normalMatrix * vec4(vertexNormal, 1.0));
    

    我怀疑这是因为I see strange effects in my diffuse lighting。我正在考虑尝试方法2,但android.opengl.Matrix类不提供反转或转置3x3矩阵的方法......

    我在renderFrame()中的实际代码如下:

      final float[] normalMatrix=new float[16];
      final float[] unscaledModelViewMatrix=modelViewMatrix_Vuforia.getData();
      Matrix.invertM(normalMatrix, 0, unscaledModelViewMatrix, 0);
      Matrix.transposeM(normalMatrix, 0, normalMatrix, 0);
      // pass the normalMatrix to the shader
      GLES20.glUniformMatrix4fv(normalMatrixHandleBottle, 1, false, normalMatrix, 0);
    

1 个答案:

答案 0 :(得分:1)

3x3矩阵足以转换法线。

使用对位置的同质坐标进行操作的4x4矩阵的主要目的是它们可以表达翻译。应用于3成员矢量的3x3矩阵可以表达翻译。您可以轻松确认,因为它始终将原点映射回原点。

由于法线是向量而不是位置,我们特别指出想要将模型视图矩阵的平移部分应用于它们。它们描述了方向,并且在应用翻译时方向不会改变。

因此,最干净的方法是使用3x3矩阵作为法线,并将其设置为模型视图矩阵的左上角3x3元素的反转置。

如果您在模型视图矩阵中只有旋转和均匀缩放(不适用于您的特定情况),人们有时会使用与位置相同的模型视图矩阵。哪个是正确的,只要不应用翻译部分。这可以通过将乘法的w分量设置为零来进行乘法:

vec3 transformedNormal = (modelViewMatrix * vec4(originalNormal, 0.0)).xyz

w分量为零时,编码平移的矩阵元素对结果没有影响,这对应于仅使用矩阵的左上角3x3部分。只要这与矩阵的逆转置相同,这就是旋转和均匀缩放的情况,这是一个有效的捷径。