我正在学习OpenGL ES 2.0,没有学过OpenGL或OpenGL ES 1.x。
我正在对我的modelViewMatrix应用非均匀缩放,因此教程告诉我需要采取特殊步骤来计算normalMatrix。在我的应用程序中,modelViewMatrix的维度为4x4。
有些教程说,对于normalMatrix,我需要简单地计算转置(反向(modelViewMatrix))。
其他说明我需要先取得modelViewMatrix的左上角3x3子矩阵,然后计算转置(逆(子矩阵))。
有什么区别吗?它们会导致相同的结果吗?
现在我正在使用方法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);
答案 0 :(得分:1)
3x3矩阵足以转换法线。
使用对位置的同质坐标进行操作的4x4矩阵的主要目的是它们可以表达翻译。应用于3成员矢量的3x3矩阵可以不表达翻译。您可以轻松确认,因为它始终将原点映射回原点。
由于法线是向量而不是位置,我们特别指出不想要将模型视图矩阵的平移部分应用于它们。它们描述了方向,并且在应用翻译时方向不会改变。
因此,最干净的方法是使用3x3矩阵作为法线,并将其设置为模型视图矩阵的左上角3x3元素的反转置。
如果您在模型视图矩阵中只有旋转和均匀缩放(不适用于您的特定情况),人们有时会使用与位置相同的模型视图矩阵。哪个是正确的,只要不应用翻译部分。这可以通过将乘法的w
分量设置为零来进行乘法:
vec3 transformedNormal = (modelViewMatrix * vec4(originalNormal, 0.0)).xyz
当w
分量为零时,编码平移的矩阵元素对结果没有影响,这对应于仅使用矩阵的左上角3x3部分。只要这与矩阵的逆转置相同,这就是旋转和均匀缩放的情况,这是一个有效的捷径。