如何有效地将THREE.Geometry转换为ArrayBuffer,File或Blob?

时间:2022-05-11 19:32:13

I'd like to move a piece of my code in which i build a THREE.Geometry object to a HTML5 Web Worker.

我想移动一段我的代码,在其中我构建一个THREE.Geometry对象到HTML5 Web Worker。

Since i don't want to serialize it to a string (for obvious performance purposes), i'd like to convert it to a Transferable Object like ArrayBuffer, File or Blob so i can pass it "by reference".

由于我不想将其序列化为字符串(出于明显的性能目的),我想将其转换为可传输对象,如ArrayBuffer,File或Blob,因此我可以“通过引用”传递它。

Do you know a efficient way to convert a THREE.Geometry to one of those objects ?

您是否知道将THREE.Geometry转换为其中一个对象的有效方法?

1 个解决方案

#1


5  

The most efficient way is to use the existing geometry buffers such as:

最有效的方法是使用现有的几何缓冲区,例如:

geometryGroup.__vertexArray
geometryGroup.__normalArray

They are created in WebGLRenderer.initMeshBuffers.

它们是在WebGLRenderer.initMeshBuffers中创建的。

How it works:

这个怎么运作:

  1. Create a Worker and import three.js using importScripts("/js/lib/mrdoob-three.js-35db421/build/three.js");

    创建一个Worker并使用importScripts导入three.js(“/ js / lib / mrdoob-three.js-35db421 / build / three.js”);

  2. In the worker you create another instance of the geometry you want to process.

    在worker中,您可以创建要处理的几何体的另一个实例。

  3. Trigger one initial rendering in the main thred renderer.render(scene, camera); now the buffers are available...

    在主渲染渲染器(场景,摄像机)中触发一个初始渲染;现在缓冲区可用了......

  4. Send the required buffers from the main thread to the worker

    将所需的缓冲区从主线程发送到worker

  5. Do the hard work on the geometry at the worker thread

    在工作线程上对几何进行艰苦的工作

  6. Manually (there is no support for that in threejs) fill the required buffers (see WebGLRenderer.setMeshBuffers) e.g.:

    手动(在threejs中没有支持)填充所需的缓冲区(参见WebGLRenderer.setMeshBuffers)例如:

    var vertexArray = new Float32Array(vertexBuffer);
    var normalArray = new Float32Array(normalBuffer);
    
    var vertices : Array = geometry.vertices;
    var obj_faces : Array = geometry.faces;
    
    var offset = 0;
    var offset_normal = 0;
    
    for (f in 0...obj_faces.length) {
    
        var face = obj_faces[ f ];
    
        var v1 = vertices[ face.a ];
        var v2 = vertices[ face.b ];
        var v3 = vertices[ face.c ];
        var v4 = vertices[ face.d ];
    
        vertexArray[ offset ]     = v1.x;
        vertexArray[ offset + 1 ] = v1.y;
        vertexArray[ offset + 2 ] = v1.z;
    
        vertexArray[ offset + 3 ] = v2.x;
        vertexArray[ offset + 4 ] = v2.y;
        vertexArray[ offset + 5 ] = v2.z;
    
        vertexArray[ offset + 6 ] = v3.x;
        vertexArray[ offset + 7 ] = v3.y;
        vertexArray[ offset + 8 ] = v3.z;
    
        vertexArray[ offset + 9 ]  = v4.x;
        vertexArray[ offset + 10 ] = v4.y;
        vertexArray[ offset + 11 ] = v4.z;
    
        offset += 12;
    }
    
  7. send the buffers back to the main thread and update the geometry there:

    将缓冲区发送回主线程并在那里更新几何体:

    var geometryGroup = mesh.geometry.geometryGroupsList[0];
    
    var _gl = renderer.context;
    _gl.bindBuffer(_gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
    _gl.bufferData(_gl.ARRAY_BUFFER, transferVertexArray, _gl.DYNAMIC_DRAW );
    

If you are doing complex operations on geometries this works well. Understanding how the buffers are created and used by WebGLRenderer is important.

如果您在几何上进行复杂的操作,那么效果很好。了解WebGLRenderer如何创建和使用缓冲区非常重要。

#1


5  

The most efficient way is to use the existing geometry buffers such as:

最有效的方法是使用现有的几何缓冲区,例如:

geometryGroup.__vertexArray
geometryGroup.__normalArray

They are created in WebGLRenderer.initMeshBuffers.

它们是在WebGLRenderer.initMeshBuffers中创建的。

How it works:

这个怎么运作:

  1. Create a Worker and import three.js using importScripts("/js/lib/mrdoob-three.js-35db421/build/three.js");

    创建一个Worker并使用importScripts导入three.js(“/ js / lib / mrdoob-three.js-35db421 / build / three.js”);

  2. In the worker you create another instance of the geometry you want to process.

    在worker中,您可以创建要处理的几何体的另一个实例。

  3. Trigger one initial rendering in the main thred renderer.render(scene, camera); now the buffers are available...

    在主渲染渲染器(场景,摄像机)中触发一个初始渲染;现在缓冲区可用了......

  4. Send the required buffers from the main thread to the worker

    将所需的缓冲区从主线程发送到worker

  5. Do the hard work on the geometry at the worker thread

    在工作线程上对几何进行艰苦的工作

  6. Manually (there is no support for that in threejs) fill the required buffers (see WebGLRenderer.setMeshBuffers) e.g.:

    手动(在threejs中没有支持)填充所需的缓冲区(参见WebGLRenderer.setMeshBuffers)例如:

    var vertexArray = new Float32Array(vertexBuffer);
    var normalArray = new Float32Array(normalBuffer);
    
    var vertices : Array = geometry.vertices;
    var obj_faces : Array = geometry.faces;
    
    var offset = 0;
    var offset_normal = 0;
    
    for (f in 0...obj_faces.length) {
    
        var face = obj_faces[ f ];
    
        var v1 = vertices[ face.a ];
        var v2 = vertices[ face.b ];
        var v3 = vertices[ face.c ];
        var v4 = vertices[ face.d ];
    
        vertexArray[ offset ]     = v1.x;
        vertexArray[ offset + 1 ] = v1.y;
        vertexArray[ offset + 2 ] = v1.z;
    
        vertexArray[ offset + 3 ] = v2.x;
        vertexArray[ offset + 4 ] = v2.y;
        vertexArray[ offset + 5 ] = v2.z;
    
        vertexArray[ offset + 6 ] = v3.x;
        vertexArray[ offset + 7 ] = v3.y;
        vertexArray[ offset + 8 ] = v3.z;
    
        vertexArray[ offset + 9 ]  = v4.x;
        vertexArray[ offset + 10 ] = v4.y;
        vertexArray[ offset + 11 ] = v4.z;
    
        offset += 12;
    }
    
  7. send the buffers back to the main thread and update the geometry there:

    将缓冲区发送回主线程并在那里更新几何体:

    var geometryGroup = mesh.geometry.geometryGroupsList[0];
    
    var _gl = renderer.context;
    _gl.bindBuffer(_gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
    _gl.bufferData(_gl.ARRAY_BUFFER, transferVertexArray, _gl.DYNAMIC_DRAW );
    

If you are doing complex operations on geometries this works well. Understanding how the buffers are created and used by WebGLRenderer is important.

如果您在几何上进行复杂的操作,那么效果很好。了解WebGLRenderer如何创建和使用缓冲区非常重要。