【问题标题】:How to efficiently convert THREE.Geometry to ArrayBuffer, File or Blob?如何有效地将 THREE.Geometry 转换为 ArrayBuffer、File 或 Blob?
【发布时间】:2013-07-03 08:15:46
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript performance three.js web-worker arraybuffer


    【解决方案1】:

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

    geometryGroup.__vertexArray
    geometryGroup.__normalArray
    

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

    它是如何工作的:

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

    2. 在工作器中,您可以创建要处理的几何图形的另一个实例。

    3. 在主线程renderer.render(scene, camera); 中触发一次初始渲染,现在缓冲区可用...

    4. 将所需的缓冲区从主线程发送到工作线程

    5. 在工作线程中对几何体进行艰苦的工作

    6. 手动(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. 将缓冲区发送回主线程并在那里更新几何:

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

    如果您正在对几何图形进行复杂的操作,则此方法效果很好。了解WebGLRenderer 如何创建和使用缓冲区很重要。

    【讨论】:

    • 不错且完整的答案,似乎值得赏金。
    • 我不确定我不应该直接在数组缓冲区上做艰苦的工作,而是在工作人员之外(来自那些数组)构建一个正确的 THREE.Geometry
    • for (f in 0...obj_faces.length) { 究竟是如何工作的?根据谷歌浏览器,这是无效的语法,你在 2013 年写答案时想到了哪些浏览器?
    猜你喜欢
    • 2022-10-16
    • 2021-08-24
    • 2022-12-19
    • 2017-10-24
    • 2020-09-22
    • 2018-11-03
    • 2018-04-09
    • 1970-01-01
    • 2013-02-26
    相关资源
    最近更新 更多