【问题标题】:Normals rotates wrong way when object is rotated物体旋转时法线旋转错误
【发布时间】:2015-11-10 06:26:44
【问题描述】:

我正在 WebGL 中渲染一个简单的圆环。旋转顶点可以正常工作,但法线有问题。当围绕单个轴旋转时,它们保持正确的方向,但是当围绕第二个轴的旋转增加时,法线开始以错误的方式旋转,直到其中一个旋转为 180°,然后法线以完全相反的方向旋转他们应该。 我认为问题在于用于旋转的四元数,但我无法确定问题所在。

这是我项目的一个(稍作修改,但仍然显示问题)jsfiddle:https://jsfiddle.net/dt509x8h/1/
在小提琴的 html 部分有一个 div 包含来自 obj 的所有数据-我正在阅读以生成环面的文件(尽管分辨率较低)。

顶点着色器:

attribute vec4 aVertexPosition;
attribute vec3 aNormalDirection;

uniform mat4 uMVPMatrix;
uniform mat3 uNMatrix;

varying vec3 nrm;

void main(void) {
    gl_Position = uMVPMatrix * aVertexPosition;
    nrm = aNormalDirection * uNMatrix;
}

片段着色器:

varying vec3 nrm;

void main(void) {
    gl_FragColor = vec4(nrm, 1.0);
}

更新矩阵(输入时运行):

mat4.perspective(pMatrix, Math.PI*0.25, width/height, clipNear, clipFar); //This is actually not run on input, it is just here to show the creation of the perspective matrix
mat4.fromRotationTranslation(mvMatrix, rotation, position);
mat3.normalFromMat4(nMatrix, mvMatrix);

mat4.multiply(mvpMatrix, pMatrix, mvMatrix);

var uMVPMatrix = gl.getUniformLocation(shaderProgram, "uMVPMatrix");
var uNMatrix = gl.getUniformLocation(shaderProgram, "uNMatrix");
gl.uniformMatrix4fv(uMVPMatrix, false, mvpMatrix);
gl.uniformMatrix3fv(uNMatrix, false, nMatrix);

创建旋转四元数(鼠标移动时调用):

var d = vec3.fromValues(lastmousex-mousex, mousey-lastmousey, 0.0);
var l = vec3.length(d);
vec3.normalize(d,d);
var axis = vec3.cross(vec3.create(), d, [0,0,1]);
vec3.normalize(axis, axis);

var q = quat.setAxisAngle(quat.create(), a, l*scale);
quat.multiply(rotation, q, rotation);

仅围绕 Y 轴旋转圆环,法线指向正确的方向:

围绕两个轴旋转圆环。法线到处都是:

我将glMatrix v2.3.2 用于所有矩阵和四元数运算。

更新: 似乎仅围绕 Z 轴旋转(通过将quat.setAxisAngle 的输入轴显式设置为[0,0,1],或使用quat.rotateZ)也会导致法线向相反方向旋转。
axis 的 z 分量归零没有帮助。

更新2: 旋转quat.rotateX(q, q, l*scale); quat.rotateY(q, q, l*scale); quat.multiply(rotation, q, rotation); 似乎是正确的,但是一旦引入围绕 Z 的旋转,z 法线就会开始移动。
使用 x 或 y 鼠标值的差异而不是 l 会导致所有法线移动,因此对 x 和 y 使用大不相同的 scale 值也是如此。

更新 3: 将着色器中的乘法顺序更改为 uNMatrix * aNormalDirection 会导致法线始终以错误的方式旋转。

【问题讨论】:

  • 片段着色器中不应该是uNMatrix * aNormalDirection;吗?
  • @WacławJasper 我也是这么认为的,但是在阅读了一下之后,似乎有些人将法线矩阵放在左边和some on the right,这取决于它是如何创建的。无论如何,更改顺序会导致每次旋转都反转为法线。
  • 这可能意味着其中一个标志在某处被翻转。也许您的normalDirection 指向错误的方式?或者也许将模型视图矩阵传递给顶点着色器并将法线矩阵计算为transpose(inverse(modelView)) 以查看是否有效?或者发布一个完整的可运行示例,我可以看看。
  • 我确实尝试过翻转法线以及从模型视图计算法线矩阵。早上我会放一些可运行的代码。
  • @WacławJasper 现在有一个指向 JSfiddle 的链接

标签: matrix 3d webgl quaternions gl-matrix


【解决方案1】:

就我而言,问题在于我如何从 .obj 文件加载数据。 我已经反转了所有顶点的 z 位置,但法线是从未反转的顶点生成的。
使用非倒置 z 位置和翻转法线矩阵乘法解决了这些问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    相关资源
    最近更新 更多