OpenGL ES 2.0的一个Android:应该normalMatrix有哪些方面? [英] OpenGL ES 2.0 an Android: What dimensions should the normalMatrix have?

查看:455
本文介绍了OpenGL ES 2.0的一个Android:应该normalMatrix有哪些方面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习的OpenGL ES 2.0,而无需了解到OpenGL或OpenGL ES的1.x的。

我申请的非均匀缩放到我的modelViewMatrix,所以教程,告诉我,我需要采取特殊的步骤来计算normalMatrix。在我的应用程序modelViewMatrix具有尺寸4x4的。


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


  2. 其他指令说我需要首先把我modelViewMatrix左上角3x3的子矩阵,然后计算转(逆(子矩阵))。


有什么区别吗?他们是否会导致同样的结果?

现在我使用方法1,然后在顶点着色器将我改造后的提取VEC3:

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

我怀疑这是因为我看到我的漫射照明奇怪的效果。我在想尝试方法2,但android.opengl.Matrix类不提供反转或调换的3x3矩阵的方法...

在renderFrame()我的实际code是如下:

 最终浮动[] = normalMatrix新的浮动[16];
  最终浮动[] = unscaledModelViewMatrix modelViewMatrix_Vuforia.getData();
  Matrix.invertM(normalMatrix,0,unscaledModelViewMatrix,0);
  Matrix.transposeM(normalMatrix,0,normalMatrix,0);
  //传递normalMatrix到shader
  GLES20.glUniformMatrix4fv(normalMatrixHandleBottle,1,假,normalMatrix,0);


解决方案

一个3x3矩阵,就足以改变法线。

使用对位置上齐次坐标操作的4x4矩阵的主要目的是,他们可以前preSS翻译。适用于3名成员组成的向量能的不可以前preSS翻译一个3x3矩阵。您可以轻松地确认,因为它的起源始终映射又回到了原点。

由于法线向量,而不是位置,我们特地做的不可以要应用该模型视图矩阵给他们翻译的部分。他们描述的方向,并且当施加一个翻译方向不会改变。

因此​​,清洁方法是使用了法线一个3×3矩阵,并且将其设置为模型视图矩阵的左上方的3×3单元的逆转。

在那里你只需要在模型视图矩阵旋转和均匀缩放(这并不适用于您的具体情况)的情况下,人们有时会使用相同的模型视图矩阵,他们也使用的位置。这是正确的,只要不施加翻译部分。这可以通过对乘法向量的是W 分量设置为零来完成:

  VEC3 transformedNormal =(modelViewMatrix * vec4(originalNormal,0.0))。XYZ

随着是W 分量为零,矩阵元素连接code翻译对结果没有任何影响,与此相对应只使用顶级矩阵的左侧的3x3一部分。只要这是相同的基体中,这是旋转和均匀缩放的情况下的逆转置,这是一个有效的捷径。

I am learning OpenGL ES 2.0, without ever having learned OpenGL or OpenGL ES 1.x.

I'm applying non-uniform scaling to my modelViewMatrix, so the tutorials tell me that I need to take special steps to compute a normalMatrix. In my application the modelViewMatrix has dimension 4x4.

  1. Some tutorials say that for the normalMatrix I need to simply calculate transpose(inverse(modelViewMatrix)).

  2. Other instructions say that I need to first take the upper left 3x3 sub-matrix of my modelViewMatrix and then compute transpose(inverse(submatrix)).

Is there any difference? Do they lead to the same result?

Right now I'm using method 1, and then in the vertex shader I extract a vec3 after applying the transformation:

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

I am doubting this because I see strange effects in my diffuse lighting. I'm thinking about trying method 2, but the android.opengl.Matrix class does not offer methods for inverting or transposing 3x3 matrices...

My actual code in renderFrame() is as follows:

  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);

解决方案

A 3x3 matrix is enough to transform the normals.

The primary purpose of using 4x4 matrices that operate on homogenous coordinates for positions is that they can express translations. A 3x3 matrix applied to a 3-member vector can not express translations. You can easily confirm that because it will always map the origin back to the origin.

Since normals are vectors, and not positions, we specifically do not want to apply the translation part of the modelview matrix to them. They describe directions, and directions do not change when a translation is applied.

So the cleanest approach is to use a 3x3 matrix for normals, and set it to the inverse-transpose of the top-left 3x3 elements of the modelview matrix.

In the case where you only have rotations and uniform scaling in the modelview matrix (which does not apply to your specific situation), people sometimes use the same modelview matrix that they also use for the positions. Which is correct, as long as the translation part is not applied. This can be done by setting the w component of the vector to zero for the multiplication:

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

With the w component being zero, the matrix elements that encode the translation have no effect on the result, and this corresponds to using only the top-left 3x3 part of the matrix. As long as this is the same as the inverse-transpose of the matrix, which is the case for rotations and uniform scaling, this is a valid shortcut.

这篇关于OpenGL ES 2.0的一个Android:应该normalMatrix有哪些方面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆