Three.js 循环通过顶点时未完全绘制粒子球体

Three.js 循环通过顶点时未完全绘制粒子球体,three.js,Three.js,我画了一个球体,有三个粒子。这很有效 但是,我通过循环这些点来设置动画(重新定位它们)。当我使用小于50的widthSegments时效果很好(WidthSegment是第二个参数)。任何超过50的都将停止绘制 供参考: SphereGeometry(radius, widthSegments, heightSegments) 这很好: let geometry = new THREE.SphereGeometry(30, 50, 20); 并产生这样的效果: 例如,如果我使用100个片段,

我画了一个球体,有三个粒子。这很有效

但是,我通过循环这些点来设置动画(重新定位它们)。当我使用小于50的widthSegments时效果很好(WidthSegment是第二个参数)。任何超过50的都将停止绘制

供参考:

SphereGeometry(radius, widthSegments, heightSegments)
这很好:

let geometry = new THREE.SphereGeometry(30, 50, 20);
并产生这样的效果:

例如,如果我使用100个片段,我将得到以下结果:

然而,这只发生在我通过循环点来改变它们的位置时

它仍然会设置现有点的动画。但其他的都不行

//与音频api相关
设AudioContext=window.AudioContext | | window.webkitadiocontext,
ctxAudio=新的AudioContext(),
sampleRate=ctxAudio.sampleRate,
audio=document.getElementById(“声音”),
audioSrc=ctxAudio.createMediaElementSource(音频),
Analyzer=ctxAudio.createAnalyzer(),
bufferLength=分析仪频率B计数,
dataArray=新的Uint8Array(缓冲区长度);
Analyzer.fftSize=2048*2;
分析仪.平滑时间常数=0.75;
音频SRC.连接(分析仪);
audioSrc.connect(ctxAudio.destination);
//设置渲染器
让renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
//定义场景中的对象
让几何=新的三个。球墨法(30,100,20);
let loader=new THREE.TextureLoader();
loader.crossOrigin=true;
让particlexture=loader.load('https://threejs.org/examples/textures/particle2.png');
让材质=新的三点材质({
颜色:0x20C9BD,
尺寸:1,
透明:是的,
混合:3.可加性贷款,
地图:particlexture,
depthWrite:false
});
设点=新的三个点(几何体、材质);
让场景=新的三个。场景();
让摄像头=新的三个透视摄像头(75,window.innerWidth/window.innerHeight,0.11000);
//布景
场景。添加(点);
摄像机位置z=100;
//将默认球体复制到向量中
const def=新的3.Vector3;
for(设i=0;iparticle.set(dx,dy,dz);//这实际上与three.js关系不大,但与webaudio API关系更大

创建FFT大小为2048的分析器时,将获得1024个频率单元(请参见
analyzer.frequencyBinCount
),但几何体有1902个顶点。因此,对于索引为1024到1901的顶点,
dataArray[i]
未定义,所有计算都解析为
NaN
。现在您将向量设置为
vector。set(NaN,NaN,NaN)
和three.js不知道该如何处理,因此不会渲染点

所以如果你用

let fftValue = (dataArray[i] / 255.0) || 0;
let dx = def[i].x * fftValue + def[i].x;
let dy = def[i].y * fftValue + def[i].y;
let dz = def[i].z * fftValue + def[i].z;
particle.set(dx, dy, dz);
或者更简单:

let fftValue = (dataArray[i] / 255.0) || 0;
geometry.vertices[i]
  .copy(def)
  .multiplyScalar(1 + fftValue)

你应该没事。

啊,是的,ofc…我怎么没想到呢!谢谢你的帮助。完全不相关的,当用javascript做这样的事情时,让
data*inv255
而不是除以255会做同样的事情吗?我猜主要是这样。我想“JS引擎应该足够聪明,可以对这两种情况都一视同仁”…但事情发生了:–被吹走了,谢谢@pailhead:D@MartinSchuhfuß如果我想利用所有点怎么办?比如如果点的数量大于frequencyBinCount。但是仍然想制作所有点的动画。假设我们可以制作1000个点的动画,但是有2000个。我如何反向循环数据?给它一个好的效果也许你会问另一个问题?