我正在测试我的项目(http://agentscript.org)使用Three.js,第一个测试看起来很慢:
https://asx-vqnhxlahpe.now.sh/test.html?three0
(注意:网站可能需要一段时间,一段时间不使用后"睡觉")
这显然是由于我的使用方式太多,每个代理一个.
renderer.info.render
Object {calls: 10002, vertices: 60090, faces: 20000, points: 0}
我相信使用BufferGeometry可以解决这个问题,但我不知道如何使用它仍然能够访问每个代理,以便我的步/动画功能可以修改(移动,旋转)它们.
我该怎么做?
我意识到我可以简单地使用我自己的Shader,并计划这样做,但我更愿意先使用一个或两个中间解决方案.
您希望减少代理模拟中的绘制调用次数,并使相对容易的工作变得简单.您可以通过将代理集合表示为来完成此操作THREE.Points
.
// geometry var geometry = new THREE.BufferGeometry(); // attributes var positions = new Float32Array( numAgents * 3 ); // 3 values per vertex var rotations = new Float32Array( numAgents * 1 ); // 1 values per vertex for ( var i = 0; i < numAgents; i ++ ) { positions[ i ] = 0; positions[ i + 1 ] = 0; positions[ i + 2 ] = 0; rotations[ i ] = 2 * Math.PI * Math.random(); } geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); geometry.addAttribute( 'rotation', new THREE.BufferAttribute( rotations, 1 ) ); // material var material = new THREE.PointsMaterial( { color: 0xff0000, size: 4, map: null } ); // points points = new THREE.Points( geometry, material ); scene.add( points );
这将在单个绘图调用中呈现,您可以更新CPU上的位置并将数据推送到每帧的GPU.您应该能够轻松地渲染100,000个代理.
小提琴:http://jsfiddle.net/730ffn4x/
如果要将点表示为带方向的箭头,则需要提供带有箭头图像的纹理和ShaderMaterial
用于旋转每个点的自定义.
InstancedBufferGeometry
如果每个代理必须表示为a,则是合适的Mesh
.这是 @MartinSchuhfuß的一个很好的例子,它类似于你想要做的.
对于激烈的模拟,您将使用GPGPU.请参阅three.js示例.在GPGPU中,模拟完全在GPU上运行,而CPU通常只做最少的工作.
three.js r.84