Как эффективно конвертировать THREE.Geometry в ArrayBuffer, File или Blob?
Я хотел бы переместить часть своего кода, в котором я создаю объект THREE.Geometry, в веб-рабочий HTML5.
Поскольку я не хочу сериализовать его в строку (для очевидных целей производительности), я хотел бы преобразовать его в переносимый объект, такой как ArrayBuffer, File или Blob, чтобы я мог передать его "по ссылке".
Знаете ли вы эффективный способ преобразования THREE.Geometry в один из этих объектов?
1 ответ
Наиболее эффективным способом является использование существующих геометрических буферов, таких как:
geometryGroup.__vertexArray
geometryGroup.__normalArray
Они созданы в WebGLRenderer.initMeshBuffers
,
Как это устроено:
Создайте Worker и импортируйте three.js, используя
importScripts("/js/lib/mrdoob-three.js-35db421/build/three.js");
В рабочем вы создаете еще один экземпляр геометрии, которую хотите обработать.
Запустить один начальный рендеринг в основном треде
renderer.render(scene, camera);
теперь буферы доступны...Отправить необходимые буферы из основного потока на рабочий
Сделайте тяжелую работу по геометрии на рабочем потоке
Вручную (нет поддержки в 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; }
отправьте буферы обратно в основной поток и обновите там геометрию:
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
это важно.