2014-02-18 95 views
1

我創建了一個簡單的場景,其中一個立方體平行於x軸移動。一切都按預期工作,直到我圍繞Y軸旋轉相機。然後立方體跟隨此旋轉並平行於屏幕移動(相機座標系中的X軸)。WebGL:物體根據當前相機方向移動

再次進行初始設置:

  • 相機在[0,2,10]看着[0,0,0]
  • 立方體最初放置在[0,0,0],沿移動[-10,10]之間的x軸

爲什麼我的相機移動會影響立方體的方向?

Before camera rotation around y-axis

After camera rotation around y-axis

下面是一些相關的代碼。我希望看到更多,不要猶豫,問。我正在使用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); 
}; 

對不起,在這裏張貼所有這些代碼。如果您有任何想法,請告訴我!

回答

3

我懷疑你在你自己的問題回答了你的問題:

與立方體平行於X軸移動一個簡單的場景......然後立方體遵循此旋轉和平行移動到屏幕(相機座標中的x軸)。

像這樣的事情發生讓我相信你應用的轉換操作到模型視圖矩陣,不是你的模型矩陣,並從你的代碼,我認爲我是對的:

MAT4 .translate(mvMatrix,mvMatrix,position);

要解決這個問題,您需要將模型和視圖矩陣分開,將轉換應用於模型矩陣,然後將結果乘以視圖。讓我知道事情的後續!

如果你還在用矩陣混淆,給這個讀:

http://solarianprogrammer.com/2013/05/22/opengl-101-matrices-projection-view-model/

+0

好吧,這聽起來很有道理。但是我使用了lookAt(),它返回一個mvMatrix。什麼是隻得到視圖矩陣的美國方式? Thx到目前爲止! – TimV

+2

我有點困惑。你能指出我在哪裏閱讀那個lookAt()返回一個模型視圖矩陣?我的理解是,lookAt()的大部分實現將返回一個視圖矩陣,然後在稍後的步驟中將其與模型矩陣相乘。 – redsoxfantom

+0

OMG,我想我現在需要在地上有一個深洞來隱藏。當然,lookAt()只創建一個視圖矩陣。知道這一點,我現在在10秒內糾正了一切。非常感謝!你救了我的一天! – TimV

相關問題