添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

So i am trying to make some particles follow a path I’ve managed to this but the particles seem to be duplicated twice so there are a few particles in the middle of the screen that do not move that should not be there I’ve also noticed the animation rotation of the “particle box” jumps … here is a code pen

i am trying to create one of these particle paths from this example but with the above path as you can see It’s not going to well

Issue 1:

Several clouds are created and added to the scene by code like this:

for (var i = 0; i < parameterse.length; i++) {
     particles = new THREE.Points(geometryParticle, materials[i]);
     scene.add(particles);

However, as they all recycle the same variable, at the end, particles refers only to the last cloud. So, when you move particles only one of the cloud is moved.

Issue 2:

Try the following idea for turning the cloud. Remove these lines (or just comment them):

axis.crossVectors( up, tangent ).normalize();
radians = Math.acos( up.dot( tangent ) );
particles.quaternion.setFromAxisAngle( axis, radians );
if (object instanceof THREE.Points) { 
      object.rotation.y = time * (i < 1 ? i + 2 : -(i + 1));
      object.rotation.x = time2 * (i < 1 ? i + 2 : -(i + 1));
      object.rotation.z = time * (i < 1 ? i + 2 : -(i + 1));

add just this line:

particles.rotation.y = Math.atan2( tangent.x, tangent.z );
              

In case you want to move all clouds, here is the whole animate function (not optimal, as I tried to make minimal changes to code).

function animate() {
   fraction +=0.0004;
   if (fraction > 1) fraction = 0;
   newPosition = pointsPath.getPoint(fraction);
   tangent = pointsPath.getTangent(fraction);
   for (var i = 0; i < scene.children.length; i++) {
       var object = scene.children[i];
       if (object instanceof THREE.Points) { 
          object.position.copy(newPosition);
          object.rotation.y = Math.atan2( tangent.x, tangent.z );
   for (var i = 0; i < materials.length; i++) { 
       var color = parameterse[i][0];
       var h = ((360 * (color[0] + time)) % 360) / 360;
       materials[i].color.setHSL(h, color[1], color[2]);  
   requestAnimationFrame(animate);
   renderer.render(scene, camera);

Here is the result:

https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/5/1522007f82ab903af739afdace6379ae85947456.mp4 tangent = pointsPath.getTangent(fraction); for (var i = 0; i < scene.children.length; i++) { var object = scene.children[i]; if (object instanceof THREE.Points) { object.position.copy(newPosition); object.rotation.y = Math.atan2( tangent.x, tangent.z ); for (var i = 0; i < materials.length; i++) { var color = parameterse[i][0]; var h = ((360 * (color[0] + time)) % 360) / 360; materials[i].color.setHSL(h, color[1], color[2]); requestAnimationFrame(animate); renderer.render(scene,

thanks for replying
Would there be a way to like rotate each particle at different rates ?

Currently rotation it taken from the path direction and is set here:

object.rotation.y = Math.atan2( tangent.x, tangent.z );

If you want every cloud to rotate in its own way, you have to calculate its rotation property. Here is an example of crazy clouds:

object.rotation.x = 3*Math.cos(i-6*fraction);
object.rotation.y = 7*Math.sin(i+6*fraction);

If you want to rotate individual points in the cloud, then you have to calculate their positions in the attribute buffer.

UI_UNICORN:

i am trying to create one of these particle paths from this example but with the above path as you can see

@akella has a really good video about it:

You use getPoint to get a position along the path, this is completely sufficient. You need to have shorter clouds. Then place every cloud on its own position long the curve, so, newPosition and tangent must be recalculated for each cloud. All clouds’ positions are based on t but with different offset (thus the left cloud is at position t, the next cloud is a little bit ahead of time, the next to the next is more ahead of time and so on). This is a simplified illustration of 5 clouds on a path.

image950×315 36.8 KB

And here is what it looks like as animation:

https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/7/6/764a7c7f54cfd4ba055034884d755b7573ad45f4.mp4

Good luck with your project!

The full JS code of the last video, that I posted, is at the bottom. As a general advice, not related to your questions, try to keep the code tidy and well formatted. This is very helpful for debugging and understanding the fabrics of what the code does. There are several code formatting styles, any of them is better than having no style.

As for the code, there is no need to calculate different positions in different variables. This can be done on-the-fly in the cycle where clouds have their rotation set. Like this:

for (var i = 0; i < scene.children.length; i++) {
   // get position and tangent of i-th cloud
   newPosition = pointsPath.getPoint((fraction+i/50)%1);
   tangent = pointsPath.getTangent((fraction+i/50)%1);
   var object = scene.children[i];
   if (object instanceof THREE.Points) { 
        var time = Date.now() * 0.0009;
        // set position of i-th cloud
        object.position.copy(newPosition);
        // set rotation of i-th cloud
        object.rotation.y = Math.atan2( tangent.x, tangent.z );
        object.rotation.z = time * (i < 1 ? i + 2 : -(i + 1));
   }  // if
} // for
Show the full source code
import * as THREE from "https://jokertattoo.co.uk/game-lesson-1/js/three.module.js";
            import TWEEN from "https://jokertattoo.co.uk/game-lesson-1/js/tween.esm.js";
            import { RGBELoader } from "https://jokertattoo.co.uk/game-lesson-1/js/RGBELoader.js";
            import { OrbitControls } from "https://jokertattoo.co.uk/game-lesson-1/js/OrbitControls.js";
            import { GLTFLoader } from "https://jokertattoo.co.uk/game-lesson-1/js/GLTFLoader.js";
            import { RoughnessMipmapper } from "https://jokertattoo.co.uk/game-lesson-1/js/RoughnessMipmapper.js";
            import { CSS2DRenderer, CSS2DObject } from "https://jokertattoo.co.uk/game-lesson-1/js/CSS2DRenderer.js";
            var container, controls;
            var camera, scene, renderer, loaderGL, time, mixer, mixer2, mixer3, mixer4, mixer6, mixer7, mixer8, mixer9, clock, labelRenderer;
            var raycaster, mouse, tween;
            var model, model2, model3, model4, model5, model6, model7, model8, model9;
            var cubefix, cube, cube2, cube3, cube4, cube5, character, Characterm, Monster0, score, gltfPlayer, gltfMonster, isZoomed, gltfC1, gltfC2, gltfC3, gltfC4, gltfC5;
            var action, action3, action0, action2, action4, action5, action6;
            var nearFog, farFog, densityFog, colorFog, colorFog2;
            var hotspotLabel1, hotspotLabel2, hotspotLabel3, hotspotLabel4;
            var materials = [],
                parameters;
            var mouseX = 0,
                mouseY = 0;
            var timerAnimate;
            var CH0, CH, CH3, CH4;
			 var game_loader_count = 0;
			 var observer, text, checkText, partcount, StartButton, ButtonStart;
			var fov, aspect, near, far;
			 var fraction, pointsPath, char, axis, up, newPosition, tangent, radians, particles, loaderSprite;
var materials = [];
var parameterse =[];
 init();
            animate();
            function init() {
  renderer = new THREE.WebGLRenderer({antialias: true});
 renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(devicePixelRatio);
document.body.appendChild(renderer.domElement); 
               var pmremGenerator = new THREE.PMREMGenerator(renderer);
                pmremGenerator.compileEquirectangularShader();
 	  fov = { value: 45};
     aspect = window.innerWidth / window.innerHeight;
     near = { value: 1};
     far = { value: 10000};
				   camera = new THREE.PerspectiveCamera(fov.value, aspect, near.value, far.value);
   camera.position.set(-8, 10, 25.1);
 camera.lookAt(0,0,0);
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x000000);
    fraction = 0;
   up = new THREE.Vector3( 0,0,1 );
   axis = new THREE.Vector3( );
  pointsPath = new THREE.CurvePath();
const curve = new THREE.CatmullRomCurve3( [
		new THREE.Vector3(  0,   0, -0 ),
	new THREE.Vector3(  -2, 0,  7 ),
	new THREE.Vector3( -8, 0, 12 ),
  new THREE.Vector3(  -14, 0,  8 ),
	new THREE.Vector3( 10, 0, 5 ),
  new THREE.Vector3( -5, 0, -14 ),
  new THREE.Vector3(  5, 0,  -15 ),
 new THREE.Vector3(  0,   0, -0 ),
  const bezierLine = new THREE.CubicBezierCurve3(
    //originals
	new THREE.Vector3(  13,   0, -1 ),
	new THREE.Vector3(  500, 0,  100 ),
	new THREE.Vector3( -14, 0, -73 ),
 new THREE.Vector3(  0,   0, 0 ),
  const bezierLine2 = new THREE.CubicBezierCurve3(
		new THREE.Vector3(  0,   0, -1 ),
	new THREE.Vector3(  -50, 0,  10 ),
	new THREE.Vector3( -14, 0, -73 ),
    new THREE.Vector3(  0,   0, 0 ),
    pointsPath.add(curve);
 // pointsPath.add(bezierLine2);
 const material = new THREE.MeshNormalMaterial();
  const coneGeom = new THREE.ConeGeometry(1, 2, 10);
  coneGeom.translate(0, 24.5, 0);
  const cone = new THREE.Mesh(coneGeom, material);
  const cylinder = new THREE.CylinderGeometry(0.4, 0.6, 3, 10);
  cylinder.merge(cone.geometry, cone.matrix);
  cylinder.scale(0.5, 0.5, 0.5);
  char = new THREE.Mesh(cylinder, material);
        max = 2,
        high = Math.floor(Math.random() * (max - min) + min);
for (var i = 0; i < partcount; i++) { var x =  (Math.random() * 2 - 1) * 1; var y = (Math.random() * 2 - 1) * 1; var z = (Math.random() * 2 - 1) * 2;
vertices.push(x, y, z); }
geometryParticle.setAttribute("position", new THREE.Float32BufferAttribute(vertices, 3));
parameterse = [ [[0.8, 0, 0.5], sprite1, 1], [[0.8, 0, 0.5], sprite1, 2], [[0.8, 0, 0.5], sprite1, 1], [[0.8, 0, 0.5], sprite1, 2], [[0.8, 0, 0.5], sprite1, 3], ];
for (var i = 0; i < parameterse.length; i++) { var color = parameterse[i][2]; var sprite = parameterse[i][1]; var size = parameterse[i][2];
materials[i] = new THREE.PointsMaterial({ size: size, map: sprite, blending: THREE.AdditiveBlending,
      depthWrite: false, transparent: true, fog: false, toneMapped: false}); 
      materials[i].toneMapped = false; materials[i].color.setHSL(color[0], color[1], color[2]);
particles = new THREE.Points(geometryParticle, materials[i]);
// particles.rotation.x = Math.random() 
 scene.add(particles);
	color: 0x9132a8
    const points = pointsPath.curves.reduce((p, d)=> [...p, ...d.getPoints(60)], []);
    const geometry2 = new THREE.BufferGeometry().setFromPoints( points );
    var liner = new THREE.Line( geometry2, material2 );
     scene.add(liner);
     clock = new THREE.Clock();
  const axesHelper = new THREE.AxesHelper( 0.5 );
  axesHelper.translateX(1);
  scene.add( axesHelper );
  controls = new OrbitControls(camera, renderer.domElement);
                controls.enableKeys = false;
                controls.enableZoom = false;
                controls.enableDamping = true;
                controls.maxPolarAngle = 1.4;
                controls.minPolarAngle = 1.2;
                controls.dampingFactor = 0.04;
                controls.autoRotate = false;
                controls.rotateSpeed = 0.015;
                controls.minDistance = 2;
				controls.enabled = false;
function animate() {
fraction +=0.0004;
//   if (fraction > 1) fraction = 0;
   for (var i = 0; i < scene.children.length; i++) {
        newPosition = pointsPath.getPoint((fraction+i/50)%1);
   tangent = pointsPath.getTangent((fraction+i/50)%1);
     var object = scene.children[i];
       if (object instanceof THREE.Points) { 
   const pos = object.position.copy(newPosition);
         var time = Date.now() * 0.0009;
             object.rotation.y = Math.atan2( tangent.x, tangent.z );
      object.rotation.z = time * (i < 1 ? i + 2 : -(i + 1));
   for (var i = 0; i < materials.length; i++) { 
       var color = parameterse[i][0];
       var h = ((360 * (color[0] + time)) % 360) / 360;
       materials[i].color.setHSL(h, color[1], color[2]);