使用 WebGL 和 glMatrix 转换 3D 对象

Translating 3D objects with WebGL and glMatrix

我想在 WebGl 中分别平移两个 3D 对象,现在我的代码仅更改相机的位置和旋转。我正在使用 glMatrix 进行矢量数学运算。"buffers" 是一个包含对象数据的数组。 buffers[0] 和 buffers[1] 是两个独立的对象。平移和旋转在 drawScene 函数中完成

function drawScene(gl, programInfo, buffers, deltaTime) {
    gl.clearColor(0.0, 0.0, 0.0, 1.0);  // Clear to black, fully opaque
    gl.clearDepth(1.0);                 // Clear everything
    gl.enable(gl.DEPTH_TEST);           // Enable depth testing
    gl.depthFunc(gl.LEQUAL);            // Near things obscure far things
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    var fieldOfView = 45 * Math.PI / 180; 
    var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    var zNear = 0.1;
    var zFar = 100.0;
    var projectionMatrix = mat4.create();

    mat4.perspective(projectionMatrix,fieldOfView,aspect,zNear,zFar);

    modelViewMatrix = mat4.create();

    // Camera Movement
    mat4.translate(modelViewMatrix,modelViewMatrix,[-0.0 + cubeTranslate, 0.0, -6.0]);
    mat4.rotate(modelViewMatrix,modelViewMatrix,cubeRotation,[0, 0, 1]);



    for( i = 0; i < 2; i++ ){

        var numComponents = 3;
        var type = gl.FLOAT;
        var normalize = false;
        var stride = 0;
        var offset = 0;
        gl.bindBuffer(gl.ARRAY_BUFFER, buffers[i].position);
        gl.vertexAttribPointer(
            programInfo.attribLocations.vertexPosition,
            numComponents,
            type,
            normalize,
            stride,
            offset);
        gl.enableVertexAttribArray(
            programInfo.attribLocations.vertexPosition);

        var numComponents = 4;
        var type = gl.FLOAT;
        var normalize = false;
        var stride = 0;
        var offset = 0;
        gl.bindBuffer(gl.ARRAY_BUFFER, buffers[i].color);
        gl.vertexAttribPointer(
            programInfo.attribLocations.vertexColor,
            numComponents,
            type,
            normalize,
            stride,
            offset);
        gl.enableVertexAttribArray(
            programInfo.attribLocations.vertexColor);


        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers[i].indices);

        gl.useProgram(programInfo.program);


        gl.uniformMatrix4fv(
            programInfo.uniformLocations.projectionMatrix,
            false,
            projectionMatrix);
        gl.uniformMatrix4fv(
            programInfo.uniformLocations.modelViewMatrix,
            false,
            modelViewMatrix);


        var vertexCount = 36;
        var type = gl.UNSIGNED_SHORT;
        var offset = 0;
        gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);

    }
    cubeRotation += deltaTime;
    cubeTranslate += 0.01
}

您的代码应该构造为分别为每个对象计算矩阵

一个典型的程序是

renderloop
  set viewport
  clear
  compute projection matrix
  compute view matrix
  for each object
    use program for object
    set buffers and attributes (or vertex array object)
    compute a modelView matrix
    set uniforms 
    draw

在你的情况下,你在 for each object 循环之外有这个

mat4.translate(modelViewMatrix,modelViewMatrix,[-0.0 + cubeTranslate, 0.0, -6.0]);
mat4.rotate(modelViewMatrix,modelViewMatrix,cubeRotation,[0, 0, 1]);

这真的是在计算相机矩阵。要获得视图矩阵,请取反

m4.invert(modelViewMatrix, modelViewMatrix);

然后在你的循环中从那个矩阵开始

for each object

     const mat = mat4.clone(modelViewMatrix);

     // now do something specific for each this object
     // for example
     mat4.translate(mat, mat, [objectNdx, 0, 0]);

老实说,我会像这样重命名你的矩阵

   camera = mat4.create();

    // Camera Movement
    mat4.translate(camera,camera,[-0.0 + cubeTranslate, 0.0, -6.0]);
    mat4.rotate(camera,camera,cubeRotation,[0, 0, 1]);

    view = mat4.create();
    mat4.invert(view, camera);

    modelViewMatrix = mat4.create();

    for( i = 0; i < 2; i++ ){

        mat4.copy(modelViewMatrix, view);

        // now manipulate the matrix in ways specific to this model
        // example
        mat4.translate(modelViewMatrix, modelViewMatrix, [i, 0, 0]);

您可能会发现 this article helpful

请注意,通常 "compute modelView matrix" 部分被分隔为 scene graph 或至少部分分隔。场景图 returns "world matrices" 然后在代码或着色器中与视图矩阵结合。