当对象旋转时,法线旋转方向错误

时间:2015-08-17 14:48:15

标签: matrix 3d webgl quaternions gl-matrix

我在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轴旋转圆环,法线指向正确的方向:
Rotating the torus only around the Y-axis
围绕两个轴旋转圆环。法线遍布整个地方:
Rotating around two axes

我正在使用glMatrix v2.3.2进行所有矩阵和四元数运算。

更新的 似乎仅围绕Z轴旋转(通过将quat.setAxisAngle的输入轴明确设置为[0,0,1],或使用quat.rotateZ)也会导致法线以相反方向旋转。登记/> 将axis的z分量归零无济于事。

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

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

1 个答案:

答案 0 :(得分:6)

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