【问题标题】:THREE.js particles not showing up inside a shape三个.js 粒子未显示在形状内
【发布时间】:2021-09-14 15:28:28
【问题描述】:

我一直在尝试修改这个demo。目前粒子被放置在文本几何体中,我的最终目标是相反的。我愿意:

  1. 将文本几何图形替换为长方体、圆锥体和球体。
  2. 用数字替换粒子。

因此,基本上,将数字放在其中一个形状内,并为粒子设置动画以延迟形成下一个形状。

首先,我尝试改变形状,让粒子和其他一切保持原样。然而,由于某种原因,这些粒子没有出现。我不确定为什么不渲染粒子?控制台没有记录错误

另外,将数字作为粒子的最快方法是什么?如果有人能指出我正确的方向,那就太好了。谢谢!

下面是修改后的代码:

// Options
const shapes = [{
      "geoCode": new THREE.ConeGeometry(25, 50, 30),
      "color": 0x11659C,
    },
    {
      "geoCode": new THREE.SphereGeometry(25, 33, 33),
      "color": 0x8F3985,
    },
    {
      "geoCode": new THREE.BoxGeometry(50, 50, 50),
      "color": 0x029894,
    }
  ],
  triggers = document.getElementsByTagName('span'),
  particleCount = 1000,
  particleSize = .3,
  defaultAnimationSpeed = 1,
  morphAnimationSpeed = 18,
  color = '#FFFFFF';

// Renderer
const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Ensure Full Screen on Resize
function fullScreen() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);
}

window.addEventListener('resize', fullScreen, false)

// Scene
const scene = new THREE.Scene();

// Camera and position
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);

camera.position.y = -45;
camera.position.z = 45;

// Lighting
const light = new THREE.AmbientLight(0xFFFFFF, 1);
scene.add(light);

// Particle Vars
const particles = new THREE.Geometry();

const pMaterial = new THREE.PointsMaterial({
  size: particleSize,
});

// Texts
const loader = new THREE.FontLoader();
const typeface = 'https://dl.dropboxusercontent.com/s/bkqic142ik0zjed/swiss_black_cond.json?';

//CONTINUE

loader.load(typeface, (font) => {
  Array.from(shapes).forEach((shape, idx) => {
    shapes[idx].geometry = shapes[idx].geoCode;
    const material = new THREE.MeshLambertMaterial({
      color: shapes[idx].color,
      opacity: .5,
      transparent: true,
      wireframe: true
    });
    const mesh = new THREE.Mesh(shapes[idx].geometry, material);
    //THREE.GeometryUtils.center(shapes[idx].geometry)
    scene.add(mesh);
    shapes[idx].particles = new THREE.Geometry();
    shapes[idx].points = THREE.GeometryUtils.randomPointsInGeometry(shapes[idx].geometry, particleCount);
    createVertices(shapes[idx].particles, shapes[idx].points)
    enableTrigger(shape, idx, triggers[idx]);
  });
});

// Particles
for (var i = 0; i < shapes; i++) {

  const vertex = new THREE.Vector3();
  vertex.x = 0;
  vertex.y = 0;
  vertex.z = 0;
  particles.vertices.push(vertex);
}

function createVertices(emptyArray, points) {
  for (var p = 0; p < particleCount; p++) {
    const vertex = new THREE.Vector3();
    vertex.x = points[p]['x'];
    vertex.y = points[p]['y'];
    vertex.z = points[p]['z'];

    emptyArray.vertices.push(vertex);
  }
}

function enableTrigger(trigger, idx, el) {
  el.setAttribute('data-disabled', false);

  el.addEventListener('click', () => {
    morphTo(shapes[idx].particles, el.dataset.color);
  })

  if (idx == 0) {
    morphTo(shapes[idx].particles, el.dataset.color);
  }
}

const particleSystem = new THREE.Points(
  particles,
  pMaterial
);

particleSystem.sortParticles = true;

// Add the particles to the scene
scene.add(particleSystem);

// Animate
const normalSpeed = (defaultAnimationSpeed / 100),
  fullSpeed = (morphAnimationSpeed / 100)

let animationVars = {
  speed: normalSpeed,
  color: color,
  rotation: 100
}

function animate() {
  particleSystem.rotation.y += animationVars.speed;
  particles.verticesNeedUpdate = true;

  camera.position.z = animationVars.rotation;
  camera.position.y = animationVars.rotation;
  camera.lookAt(scene.position);

  particleSystem.material.color = new THREE.Color(animationVars.color);

  window.requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

animate();

function morphTo(newParticles, color = '#FFFFFF') {

  TweenMax.to(animationVars, 2, {
    ease: Linear.easeNone,
    color: color
  });

  particleSystem.material.color.setHex(color);

  for (const i = 0; i < particles.vertices.length; i++) {
    TweenMax.to(particles.vertices[i], 2, {
      ease: Elastic.easeOut.config(0.1, .3),
      x: newParticles.vertices[i].x,
      y: newParticles.vertices[i].y,
      z: newParticles.vertices[i].z
    })
  }
}
body {
  font-family: 'Titillium Web', sans-serif;
  margin: 0;
  overflow: hidden;
}

.triggers {
  bottom: 20px;
  color: white;
  left: 50%;
  position: absolute;
  text-align: center;
  transform: translateX(-50%);
  width: 100%;
  z-index: 10;
}

.triggers span {
  cursor: pointer;
  display: inline-block;
  font-size: 14px;
  margin: 0 20px;
  padding: 2px 4px;
  transition: opacity 0.5s, color 0.5s;
}

.triggers span[data-disabled="true"] {
  opacity: 0.3;
  pointer-events: none;
}

.triggers span:hover {
  color: red;
}
<div class="triggers">
  <span data-disabled="true" data-color="#3D8CD0">CLICK</span>
  <span data-disabled="true" data-color="#D32A7B">TO</span>
  <span data-disabled="true" data-color="#2AD37A">SWITCH</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js" type="text/javascript"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/GeometryUtils.js" type="text/javascript"></script>

编辑:现在渲染粒子,更新代码在这里 --> Fiddle

【问题讨论】:

    标签: javascript html css three.js particle-system


    【解决方案1】:

    抱歉,我实际上能够修复不渲染的粒子。我正在迭代 shapes 而不是 particleCount

    // Particles
    for (var i = 0; i < shapes; i++) {
                        ^^^^^^
      let vertex = new THREE.Vector3();
      vertex.x = 0;
      vertex.y = 0;
      vertex.z = 0;
      particles.vertices.push(vertex);
    }
    

    下面是加载粒子的更新代码。

    // Options
    const shapes = [{
          "geoCode": new THREE.ConeGeometry(25, 50, 30),
          "color": 0x11659C,
        },
        {
          "geoCode": new THREE.SphereGeometry(25, 33, 33),
          "color": 0x8F3985,
        },
        {
          "geoCode": new THREE.BoxGeometry(50, 50, 50),
          "color": 0x029894,
        }
      ],
      triggers = document.getElementsByTagName('span'),
      particleCount = 1000,
      particleSize = 3,
      defaultAnimationSpeed = 1,
      morphAnimationSpeed = 18,
      color = '#FFFFFF';
    
    // Renderer
    const renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    // Ensure Full Screen on Resize
    function fullScreen() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
    
      renderer.setSize(window.innerWidth, window.innerHeight);
    }
    
    window.addEventListener('resize', fullScreen, false)
    
    // Scene
    const scene = new THREE.Scene();
    
    // Camera and position
    const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
    
    camera.position.y = -45;
    camera.position.z = 45;
    
    // Lighting
    const light = new THREE.AmbientLight(0xFFFFFF, 1);
    scene.add(light);
    
    // Particle Vars
    const particles = new THREE.Geometry();
    
    const pMaterial = new THREE.PointsMaterial({
      size: particleSize,
    });
    
    // Texts
    const loader = new THREE.FontLoader();
    const typeface = 'https://dl.dropboxusercontent.com/s/bkqic142ik0zjed/swiss_black_cond.json?';
    
    //CONTINUE
    
    loader.load(typeface, (font) => {
      Array.from(shapes).forEach((shape, idx) => {
        shapes[idx].geometry = shapes[idx].geoCode;
        const material = new THREE.MeshLambertMaterial({
          color: shapes[idx].color,
          opacity: .5,
          transparent: true,
          wireframe: true
        });
        const mesh = new THREE.Mesh(shapes[idx].geometry, material);
        //THREE.GeometryUtils.center(shapes[idx].geometry)
        scene.add(mesh);
        shapes[idx].particles = new THREE.Geometry();
        shapes[idx].points = THREE.GeometryUtils.randomPointsInGeometry(shapes[idx].geometry, particleCount);
        createVertices(shapes[idx].particles, shapes[idx].points)
        enableTrigger(shape, idx, triggers[idx]);
      });
    });
    
    // Particles
    for (var i = 0; i < particleCount; i++) {
    
      const vertex = new THREE.Vector3();
      vertex.x = 0;
      vertex.y = 0;
      vertex.z = 0;
      particles.vertices.push(vertex);
    }
    
    function createVertices(emptyArray, points) {
      for (var p = 0; p < particleCount; p++) {
        const vertex = new THREE.Vector3();
        vertex.x = points[p]['x'];
        vertex.y = points[p]['y'];
        vertex.z = points[p]['z'];
    
        emptyArray.vertices.push(vertex);
      }
    }
    
    function enableTrigger(trigger, idx, el) {
      el.setAttribute('data-disabled', false);
    
      el.addEventListener('click', () => {
        morphTo(shapes[idx].particles, el.dataset.color);
      })
    
      if (idx == 0) {
        morphTo(shapes[idx].particles, el.dataset.color);
      }
    }
    
    let particleSystem = new THREE.Points(
      particles,
      pMaterial
    );
    
    particleSystem.sortParticles = true;
    
    // Add the particles to the scene
    scene.add(particleSystem);
    
    // Animate
    const normalSpeed = (defaultAnimationSpeed / 100),
      fullSpeed = (morphAnimationSpeed / 100)
    
    let animationVars = {
      speed: normalSpeed,
      color: color,
      rotation: 100
    }
    
    function animate() {
      particleSystem.rotation.y += animationVars.speed;
      particles.verticesNeedUpdate = true;
    
      camera.position.z = animationVars.rotation;
      camera.position.y = animationVars.rotation;
      camera.lookAt(scene.position);
    
      particleSystem.material.color = new THREE.Color(animationVars.color);
    
      window.requestAnimationFrame(animate);
      renderer.render(scene, camera);
    }
    
    animate();
    
    function morphTo(newParticles, color = '#FFFFFF') {
    
      TweenMax.to(animationVars, 2, {
        ease: Linear.easeNone,
        color: color
      });
    
      particleSystem.material.color.setHex(color);
    
      for (let i = 0; i < particles.vertices.length; i++) {
        TweenMax.to(particles.vertices[i], 2, {
          ease: Elastic.easeOut.config(0.1, .3),
          x: newParticles.vertices[i].x,
          y: newParticles.vertices[i].y,
          z: newParticles.vertices[i].z
        })
      }
    }
    body {
      font-family: 'Titillium Web', sans-serif;
      margin: 0;
      overflow: hidden;
    }
    
    .triggers {
      bottom: 20px;
      color: white;
      left: 50%;
      position: absolute;
      text-align: center;
      transform: translateX(-50%);
      width: 100%;
      z-index: 10;
    }
    
    .triggers span {
      cursor: pointer;
      display: inline-block;
      font-size: 14px;
      margin: 0 20px;
      padding: 2px 4px;
      transition: opacity 0.5s, color 0.5s;
    }
    
    .triggers span[data-disabled="true"] {
      opacity: 0.3;
      pointer-events: none;
    }
    
    .triggers span:hover {
      color: red;
    }
    <div class="triggers">
      <span data-disabled="true" data-color="#3D8CD0">CLICK</span>
      <span data-disabled="true" data-color="#D32A7B">TO</span>
      <span data-disabled="true" data-color="#2AD37A">SWITCH</span>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js" type="text/javascript"></script>
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/GeometryUtils.js" type="text/javascript"></script>

    注意这篇文章只有粒子不渲染的解决方案。我将接受回答我应该如何用数字替换粒子的帖子。

    【讨论】:

      猜你喜欢
      • 2019-05-15
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多