Three.JS-沿随机方向围绕点旋转的粒子,形成球体
我有一个粒子系统,所有的粒子都被放置在相同的坐标上,一个接一个,在随机的方向上,它们(应该)开始围绕场景的中心旋转,形成一个球体 到目前为止,我一直努力实现的是一组矢量3对象(粒子),它们一个接一个地开始沿着Z轴围绕中心旋转,只是根据当前角度计算它们的正弦和余弦 我的数学不是很好,我甚至不知道该找什么 以下是我写的:Three.JS-沿随机方向围绕点旋转的粒子,形成球体,three.js,particle-system,Three.js,Particle System,我有一个粒子系统,所有的粒子都被放置在相同的坐标上,一个接一个,在随机的方向上,它们(应该)开始围绕场景的中心旋转,形成一个球体 到目前为止,我一直努力实现的是一组矢量3对象(粒子),它们一个接一个地开始沿着Z轴围绕中心旋转,只是根据当前角度计算它们的正弦和余弦 我的数学不是很好,我甚至不知道该找什么 以下是我写的: var scene = new THREE.Scene(); let container = document.getElementById('container'),
var scene = new THREE.Scene();
let container = document.getElementById('container'),
loader = new THREE.TextureLoader(),
renderer,
camera,
maxParticles = 5000,
particlesDelay = 50,
radius = 50,
sphereGeometry,
sphere;
loader.crossOrigin = true;
function init() {
let vw = window.innerWidth,
vh = window.innerHeight;
renderer = new THREE.WebGLRenderer();
renderer.setSize(vw, vh);
renderer.setPixelRatio(window.devicePixelRatio);
camera = new THREE.PerspectiveCamera(45, vw / vh, 1, 1000);
camera.position.z = 200;
camera.position.x = 30;
camera.position.y = 30;
camera.lookAt(scene.position);
scene.add(camera);
let controls = new THREE.OrbitControls(camera, renderer.domElement);
let axisHelper = new THREE.AxisHelper(50);
scene.add(axisHelper);
container.appendChild(renderer.domElement);
window.addEventListener('resize', onResize, false);
}
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function draw() {
sphereGeometry = new THREE.Geometry();
sphereGeometry.dynamic = true;
let particleTexture = loader.load('https://threejs.org/examples/textures/particle2.png'),
material = new THREE.PointsMaterial({
color: 0xffffff,
size: 3,
transparent: true,
blending: THREE.AdditiveBlending,
map: particleTexture,
depthWrite: false
});
for ( let i = 0; i < maxParticles; i++ ) {
let vertex = new THREE.Vector3(radius, 0, 0);
vertex.delay = Date.now() + (particlesDelay * i);
vertex.angle = 0;
sphereGeometry.vertices.push(vertex);
}
sphere = new THREE.Points(sphereGeometry, material);
scene.add(sphere);
}
function update() {
for ( let i = 0; i < maxParticles; i++ ) {
let particle = sphereGeometry.vertices[i];
if ( Date.now() > particle.delay ) {
let angle = particle.angle += 0.01;
particle.x = radius * Math.cos(angle);
if ( i % 2 === 0 ) {
particle.y = radius * Math.sin(angle);
} else {
particle.y = -radius * Math.sin(angle);
}
}
}
sphere.geometry.verticesNeedUpdate = true;
}
function render() {
update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
init();
draw();
render();
var scene=new THREE.scene();
让container=document.getElementById('container'),
loader=新的三个.TextureLoader(),
渲染器,
摄像机,
最大粒子数=5000,
particlesDelay=50,
半径=50,
旋光法,
球体;
loader.crossOrigin=true;
函数init(){
设vw=window.innerWidth,
vh=窗内高度;
renderer=new THREE.WebGLRenderer();
渲染器。设置大小(vw、vh);
renderer.setPixelRatio(window.devicePixelRatio);
摄像机=新的三视角摄像机(45,vw/vh,11000);
摄像机位置z=200;
摄像机位置x=30;
摄像机位置y=30;
摄像机。注视(场景。位置);
场景。添加(摄影机);
let controls=新的三个.OrbitControls(摄影机、渲染器.doElement);
设axisHelper=new-THREE.axisHelper(50);
添加(axisHelper);
container.appendChild(renderer.domeElement);
addEventListener('resize',onResize,false);
}
函数onResize(){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
renderer.setSize(window.innerWidth、window.innerHeight);
}
函数绘图(){
球面测量法=新的三点几何();
sphereGeometry.dynamic=真;
让particlexture=loader.load('https://threejs.org/examples/textures/particle2.png'),
材料=新的三点材料({
颜色:0xffffff,
尺寸:3,
透明:是的,
混合:3.可加性贷款,
地图:particlexture,
depthWrite:false
});
for(设i=0;iparticle.delay){
让角度=粒子。角度+=0.01;
粒子x=半径*数学cos(角度);
如果(i%2==0){
粒子y=半径*数学sin(角度);
}否则{
particle.y=-半径*Math.sin(角度);
}
}
}
sphere.geometry.verticesNeedUpdate=true;
}
函数render(){
更新();
渲染器。渲染(场景、摄影机);
请求动画帧(渲染);
}
init();
draw();
render();
如果您想看现场直播,这里是JSFIDLE:
编辑:
...
for ( let i = 0; i < maxParticles; i++ ) {
let particle = sphereGeometry.vertices[i];
if ( Date.now() > particle.delay ) {
particle.applyAxisAngle(particle.rotationAxis, 0.01);
}
}
...
谁能帮我一下吗
提前谢谢 希望每个粒子围绕特定的随机轴旋转。可以让它们在3D空间中跟随a,也可以使用THREE.js旋转矩阵 现在,所有粒子都围绕向量(0,0,1)旋转。由于粒子从x轴开始,因此希望它们都围绕y-z平面(0,y,z)中的随机向量旋转。这可以在创建顶点期间定义:
vertex.rotationAxis = new THREE.Vector3(0, Math.random() * 2 - 1, Math.random() * 2 - 1);
vertex.rotationAxis.normalize();
现在,您可以对每个粒子调用THREE.Vector3.applyAxisAngle(axis,angle)
方法,其中每个粒子的随机旋转轴都是您在每次更新中创建的:
particle.applyAxisAngle(particle.rotationAxis, 0.01);
总而言之,它应该是这样的:
绘制():
...
for ( let i = 0; i < maxParticles; i++ ) {
let vertex = new THREE.Vector3(radius, 0, 0);
vertex.delay = Date.now() + (particlesDelay * i);
vertex.rotationAxis = new THREE.Vector3(0, Math.random() * 2 - 1, Math.random() * 2 - 1);
vertex.rotationAxis.normalize();
sphereGeometry.vertices.push(vertex);
}
...
。。。
for(设i=0;i
更新():
...
for ( let i = 0; i < maxParticles; i++ ) {
let particle = sphereGeometry.vertices[i];
if ( Date.now() > particle.delay ) {
particle.applyAxisAngle(particle.rotationAxis, 0.01);
}
}
...
。。。
for(设i=0;iparticle.delay){
粒子应用轴角(粒子旋转轴,0.01);
}
}
...
Hi@micnil,你的解决方案很有魅力,非常感谢你的帮助:)我添加了一个指向工作示例的链接,以备其他人需要。@micnil你能帮我澄清一下吗?我一直在研究这个例子,因为它产生了一个非常酷的效果,我计划构建一个“黑洞”场景。具有随机y和z值的向量3的顶点旋转轴如何导致粒子沿随机方向旋转?我已经戳了JSFIDLE好几天了,我仍然不明白是什么造成了粒子形成球体的这种效果。我知道applyAxisAngle
是产生这种效果的魔法,但是,我不明白为什么为每个粒子的rotationAxis
调整y和z可以做到这一点。@AlexFallenstedt基本上我创建了一个粒子可以旋转的向量。在没有图片和数字的评论中用文字解释有点困难。但是想想你小提琴的这个版本:尝试按“运行”几次,您将看到粒子在其旋转轴发生变化时的行为。@AlexFallenstedt可能更清楚:,查看粒子如何始终与旋转轴成直角。这将消除许多混淆。谢谢@micnil.)