使用WebGL和glMatrix转换3D对象

时间:2019-06-05 11:55:00

标签: javascript webgl

我想在WebGl中分别转换两个3D对象,现在我的代码仅更改相机的位置和旋转。我正在使用glMatrix进行矢量数学运算。“缓冲区”是包含对象数据的数组。 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
}

1 个答案:

答案 0 :(得分:1)

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

一个典型的程序是

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

请注意,“计算模型视图矩阵”部分通常分为scene graph或至少部分分隔。场景图会返回“世界矩阵”,然后将它们与视图矩阵以代码或着色器的形式组合。