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:
这个怎么运作:
-
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”);
-
In the worker you create another instance of the geometry you want to process.
在worker中,您可以创建要处理的几何体的另一个实例。
-
Trigger one initial rendering in the main thred
renderer.render(scene, camera);
now the buffers are available...在主渲染渲染器(场景,摄像机)中触发一个初始渲染;现在缓冲区可用了......
-
Send the required buffers from the main thread to the worker
将所需的缓冲区从主线程发送到worker
-
Do the hard work on the geometry at the worker thread
在工作线程上对几何进行艰苦的工作
-
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; }
-
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:
这个怎么运作:
-
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”);
-
In the worker you create another instance of the geometry you want to process.
在worker中,您可以创建要处理的几何体的另一个实例。
-
Trigger one initial rendering in the main thred
renderer.render(scene, camera);
now the buffers are available...在主渲染渲染器(场景,摄像机)中触发一个初始渲染;现在缓冲区可用了......
-
Send the required buffers from the main thread to the worker
将所需的缓冲区从主线程发送到worker
-
Do the hard work on the geometry at the worker thread
在工作线程上对几何进行艰苦的工作
-
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; }
-
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如何创建和使用缓冲区非常重要。