Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 最小化三个.js绘图的数量_Performance_Three.js - Fatal编程技术网

Performance 最小化三个.js绘图的数量

Performance 最小化三个.js绘图的数量,performance,three.js,Performance,Three.js,我正在测试在我的项目()中使用Three.js,第一个测试似乎很慢: (注意:网站可能需要一段时间,在一段时间不使用后会“休眠”) 这显然是由于我的使用方式太多画,每个代理一个。 renderer.info.render 对象{调用:10002,顶点:60090,面:20000,点:0} 我相信使用BufferGeometry可以解决这个问题,但我不知道如何使用BufferGeometry,并且仍然能够访问每个代理,以便我的step/animate功能可以修改(移动、旋转)它们 我该怎么做

我正在测试在我的项目()中使用Three.js,第一个测试似乎很慢:

(注意:网站可能需要一段时间,在一段时间不使用后会“休眠”)

这显然是由于我的使用方式太多画,每个代理一个。

renderer.info.render
对象{调用:10002,顶点:60090,面:20000,点:0}

我相信使用BufferGeometry可以解决这个问题,但我不知道如何使用BufferGeometry,并且仍然能够访问每个代理,以便我的step/animate功能可以修改(移动、旋转)它们

我该怎么做


我意识到我可以简单地使用我自己的着色器,并计划这样做,但我更喜欢先有一两个中间解决方案

你是对的,在你的情况下使用缓冲区几何体会有很大帮助

这是我想到的:首先,我们将有一个表示箭头的小助手类:

// the base-shape of the arrow, two triangles
const arrowVertices = new Float32Array([
  -1,-1,0, 0,0,0, 0,2,0,
  0,2,0, 0,0,0, 1,-1, 0
]);

// some helper-variables
const v3 = new THREE.Vector3();
const m4 = new THREE.Matrix4();

class Arrow {
  constructor(buffer, offset) {
    this.numVertices = 6;
    this.buffer = buffer;
    this.offset = offset;
    this.heading = 0;
    this.position = new THREE.Vector3();
  }

  update() {
    m4.makeRotationZ(this.heading)
        .setPosition(this.position);

    for (let i = 0; i < this.numVertices; i++) {
      v3.fromArray(arrowVertices, i * 3);
      v3.applyMatrix4(m4a);
      v3.toArray(this.buffer, this.offset + i * 3);
    }
  }
}

此技术的主要缺点是需要手动处理箭头顶点的所有变换。对于只有6个顶点的简单箭头,这应该不是什么大问题,而且它的性能可能比每个箭头使用网格要好。但是,我建议您再看一看实例化几何体,它可以在顶点着色器中完成上述更新方法中发生的所有操作,从而以更少的开销执行更好的操作。

在您的情况下,实例化是减少几何体和绘制调用的最佳方法
Three.js
支持通过
ANGLE\u instanced\u数组进行实例化
扩展

看看这个-

这里还有一个关于如何在
Three.js
-


您希望减少代理模拟中的绘制调用数量,并使某些功能相对容易地工作。您可以通过将代理集合表示为
三个.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 );
//几何体
var geometry=new THREE.BufferGeometry();
//属性
变量位置=新的Float32Array(numAgents*3);//每个顶点3个值
变量旋转=新Float32Array(numAgents*1);//1每个顶点的值
对于(变量i=0;i
这将在一次绘制调用中呈现,您可以更新CPU上的位置,并在每一帧将数据推送到GPU。您应该能够轻松地呈现100000个代理

小提琴:

如果要将点表示为带方向的箭头,则需要为纹理提供箭头图像和自定义
着色器材质来旋转每个点

如果每个代理必须表示为
网格
,则
InstancedBufferGeometry
是合适的。通过@MartinSchuhfuß,这与您想要做的类似

对于密集模拟,您将使用GPGPU。在GPGPU中,模拟完全在GPU上运行,CPU通常只做很少的工作


three.js r.84

您使用的是three.js的哪个版本?什么类型的几何体?以下是源代码:我正在使用three@0.82.1. 每个代理的几何体只是两个三角形,使它们看起来像省道。我通过添加一个新网格,指向单个几何体和材质(红色),在场景中实例化代理。注意:取消选中答案,因为对话非常精彩,出于某种原因,因此不会通知我。我还计划尝试其他答案之一,以确保我真正理解它。谢谢你的耐心!和帮助。@backspaces您特别要求使用
BufferGeometry
的中间解决方案,该解决方案性能良好,不需要自定义着色器。回答完问题后,请不要更改。如果你需要更多的帮助,写一篇新的帖子。太好了!谢谢使用renderer.info.render确实显示了一个绘图。调用:1,顶点:195000,面:65000,点:0。它看起来像是他的RawShaderMaterial(为了避免三个建筑矩阵,他对矩阵使用了单一的一致性)。那么有没有一种方法可以使用实例化,这样就不需要着色器了?我并不介意这样做,只是为了评估我展示的模型的三个.js策略:许多独立的“代理”都有自己的x、y和z旋转。Oops,忘记完成第一个注释,应该是:它看起来像他的RawShaderMaterial(为了避免三个构建矩阵,他使用一个统一的矩阵)单个三角形是否定位/旋转。。首先要尝试一下。下面是three.js对象的预览,它将实例化功能与常规着色器挂钩。它可能会变成三个,但api需要重新编写。着色器块确实需要进行monkey修补,但您可以参考此模式,甚至按原样使用此模式,但添加一个方法以在实例索引处设置mat4属性。(现在只能通过构造才能使用)@MartinSchuhfuß发现扩展着色器并不太复杂,但笨重且粗糙。“材质”使用了一些未记录的特性,这让它变得轻而易举。查找
材质。定义
材质。customDepthMaterial
材质。customDistanceMaterial
之前,我对渲染器进行了大量修改,以使其工作正常,但现在完全可以完全从外部执行。Noob问题:THREE.BufferGeometry是否需要使用ShaderMaterial?或者它可以不使用着色器,使用标准的三渲染吗?threejs中的所有几何体都会转换为缓冲几何体,因此有没有一个不使用着色器的实例?我发现
// 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 );