我創建了一個簡單的場景,其中一個立方體平行於x軸移動。一切都按預期工作,直到我圍繞Y軸旋轉相機。然後立方體跟隨此旋轉並平行於屏幕移動(相機座標系中的X軸)。WebGL:物體根據當前相機方向移動
再次進行初始設置:
- 相機在[0,2,10]看着[0,0,0]
- 立方體最初放置在[0,0,0],沿移動[-10,10]之間的x軸
爲什麼我的相機移動會影響立方體的方向?
下面是一些相關的代碼。我希望看到更多,不要猶豫,問。我正在使用glMatrix進行矢量和矩陣運算。
主繪圖程序:
// Clear the canvas before we start drawing on it.
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Use the full window (minus border)
canvas.width = window.innerWidth - 16;
canvas.height = window.innerHeight - 16;
// Set viewport
gl.viewport(0, 0, canvas.width, canvas.height);
// Reset the perspective matrix
cam.aspectRatio = canvas.width/canvas.height;
mat4.perspective(perspectiveMatrix, cam.fovy, cam.aspectRatio, cam.nearPlane, cam.farPlane);
// Create the mvMatrix
mat4.lookAt(mvMatrix, cam.position, cam.poi, cam.up);
// Draw all objects
for (i = 0; i < ObjectStack.length; i++) {
ObjectStack[i].draw();
}
相機旋轉:
// Rotation via yaw and pitch (FPS-style)
this.rotateYP = function (yaw, pitch) {
// Rotation speed
var rotSpeed = 0.5;
yaw *= rotSpeed;
pitch *= rotSpeed;
// Update rotation
var quatYaw = quat.create();
quat.setAxisAngle(quatYaw, this.up, degToRad(yaw));
var quatPitch = quat.create();
quat.setAxisAngle(quatPitch, this.right, degToRad(pitch));
var quatCombined = quat.create();
quat.multiply(quatCombined, quatYaw, quatPitch);
// Update camera vectors
var tmp = vec3.create();
vec3.subtract(tmp, this.poi, this.position);
vec3.transformQuat(tmp, tmp, quatCombined);
vec3.add(tmp, this.position, tmp);
this.setPOI(tmp);
};
我setPOI()方法(POI =興趣點):
this.setPOI = function (poi) {
// Set new poi
vec3.copy(this.poi, poi);
// Set new view vector
vec3.subtract(this.view, poi, this.position);
vec3.normalize(this.view, this.view);
// Set new right vector
vec3.cross(this.right, this.view, [0.0, 1.0, 0.0]);
vec3.normalize(this.right, this.right);
// Set new up vector
vec3.cross(this.up, this.right, this.view);
vec3.normalize(this.up, this.up);
};
爲對象繪製方法立方體:
this.draw = function() {
// Save current mvMatrix
mvPushMatrix();
// Object movement
mat4.translate(mvMatrix, mvMatrix, position);
// Object rotation
//mat4.mul(mvMatrix, mvMatrix, orientation);
// Object scaling
// ...
// Set shader
setShader();
// Bind the necessary buffers
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer);
gl.vertexAttribPointer(positionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, normalsBuffer);
gl.vertexAttribPointer(normalAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.vertexAttribPointer(texCoordAttribute, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
// Set active texture
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, cubeTexture);
gl.uniform1i(gl.getUniformLocation(ShaderStack[shader], "uSampler"), 0);
// Send the triangles to the graphics card for drawing
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
gl.bindTexture(gl.TEXTURE_2D, null);
// Clean up the changed mvMatrix
mvPopMatrix();
};
最後上面使用的setShader():
function setShader() {
var shaderProgram = ShaderStack[shader];
gl.useProgram(shaderProgram);
var pUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
gl.uniformMatrix4fv(pUniform, false, perspectiveMatrix);
var mvUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
gl.uniformMatrix4fv(mvUniform, false, mvMatrix);
var normalMatrix = mat4.create();
mat4.invert(normalMatrix, mvMatrix);
mat4.transpose(normalMatrix, normalMatrix);
var nUniform = gl.getUniformLocation(shaderProgram, "uNormalMatrix");
gl.uniformMatrix4fv(nUniform, false, normalMatrix);
normalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(normalAttribute);
positionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(positionAttribute);
texCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(texCoordAttribute);
};
對不起,在這裏張貼所有這些代碼。如果您有任何想法,請告訴我!
好吧,這聽起來很有道理。但是我使用了lookAt(),它返回一個mvMatrix。什麼是隻得到視圖矩陣的美國方式? Thx到目前爲止! – TimV
我有點困惑。你能指出我在哪裏閱讀那個lookAt()返回一個模型視圖矩陣?我的理解是,lookAt()的大部分實現將返回一個視圖矩陣,然後在稍後的步驟中將其與模型矩陣相乘。 – redsoxfantom
OMG,我想我現在需要在地上有一個深洞來隱藏。當然,lookAt()只創建一個視圖矩陣。知道這一點,我現在在10秒內糾正了一切。非常感謝!你救了我的一天! – TimV