使用 WebGL 和 glMatrix 翻译 3D 对象 [英] Translating 3D objects with WebGL and glMatrix

查看:27
本文介绍了使用 WebGL 和 glMatrix 翻译 3D 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to translate two 3D objects separately in WebGl, right now my code changes only the position and rotation of the camera. I'm using glMatrix for vector math."buffers" is an array with the object data. buffers[0] and buffers[1] are two separate objects. The translation and rotation are done in drawScene function

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
}

推荐答案

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

Your code should be structured to compute matrices for each object separately

一个典型的程序是

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 循环之外有这个

In your case you have this outside the for each object loop

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

这实际上是在计算相机矩阵.要得到视图矩阵取逆

That's computing a camera matrix really. To get view matrix take the inverse

m4.invert(modelViewMatrix, modelViewMatrix);

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

Then inside your loop start with that matrix

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]);

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

Honestly I'd rename your matrices like this

   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]);

您可能会发现这篇文章很有帮助

请注意,计算模型视图矩阵"部分通常被分成一个场景图 或至少部分分离.场景图返回世界矩阵",然后在代码或着色器中与视图矩阵组合.

Note that often the "compute modelView matrix" part is separated into a scene graph or at least partially separated. the scene graph returns "world matrices" which are then combined with the view matrix either in code or in the shader.

这篇关于使用 WebGL 和 glMatrix 翻译 3D 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆