Как эффективно конвертировать THREE.Geometry в ArrayBuffer, File или Blob?

Я хотел бы переместить часть своего кода, в котором я создаю объект THREE.Geometry, в веб-рабочий HTML5.

Поскольку я не хочу сериализовать его в строку (для очевидных целей производительности), я хотел бы преобразовать его в переносимый объект, такой как ArrayBuffer, File или Blob, чтобы я мог передать его "по ссылке".

Знаете ли вы эффективный способ преобразования THREE.Geometry в один из этих объектов?

1 ответ

Решение

Наиболее эффективным способом является использование существующих геометрических буферов, таких как:

geometryGroup.__vertexArray
geometryGroup.__normalArray

Они созданы в WebGLRenderer.initMeshBuffers,

Как это устроено:

  1. Создайте Worker и импортируйте three.js, используя importScripts("/js/lib/mrdoob-three.js-35db421/build/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 это важно.

Другие вопросы по тегам