Three.js星空粒子特效

效果

在这里插入图片描述

代码

  • 只渲染固定个数与区域的粒子保证性能
  • 初始化时确定每个粒子偏移向量方向,操作帧动画时做三维向量偏移
  • 超过规定区域时还原,实现无限粒子移动
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        background-color: #000000;
        margin: 0px;
        overflow: hidden;
        background-image: radial-gradient(
          ellipse farthest-corner at center top,
          #23233f 0%,
          #000000 60%
        );
      }
    </style>
  </head>
  <body>
    <script type="module">
      import * as THREE from "./node_modules/three/build/three.module.js";
      import { OrbitControls } from "./node_modules/three/examples/jsm/controls/OrbitControls.js";

      const { scene, camera, renderer } = initScene();

      let pointScene = null;
      const total = 1000;
      const height = 160;
      const width = 160;
      const depth = 160;

      (function () {
        creartStarPoints();
        render();
      })();

      function creartStarPoints() {
        const geometry = new THREE.Geometry();
        for (let i = 0; i < total; i++) {
          const vertex = new THREE.Vector3();
          const x = Math.random() * width - width * 0.5;
          const y = Math.random() * height - height * 0.5;
          const z = Math.random() * depth - depth * 0.5;

          vertex.x = x;
          vertex.y = y;
          vertex.z = z;

          vertex.origin = new THREE.Vector3();
          vertex.origin.x = x;
          vertex.origin.y = y;
          vertex.origin.z = z;

          vertex.direction = new THREE.Vector3();
          vertex.direction.x = Math.random() - 0.5;
          vertex.direction.y = Math.random() - 0.5;
          vertex.direction.z = Math.random() - 0.5;
          geometry.vertices.push(vertex);
        }

        const material = new THREE.PointsMaterial({
          size: 0.2,
          color: 0x00ffff,
          fog: true,
        });
        const points = new THREE.Points(geometry, material);
        pointScene = points;
        scene.add(points);
      }

      function render() {
        renderer.render(scene, camera);
        pointScene.geometry.vertices.forEach((item) => {
          item.x -= item.direction.x * 0.2;
          item.y -= item.direction.y * 0.2;
          item.z -= item.direction.z * 0.2;
          if (item.x > width || item.x < -width) item.x = item.origin.x;
          if (item.y > width || item.y < -width) item.y = item.origin.y;
          if (item.z > width || item.z < -width) item.z = item.origin.z;
        });
        pointScene.geometry.verticesNeedUpdate = true;
        requestAnimationFrame(render);
      }

      function initScene() {
        const scene = new THREE.Scene();
        scene.fog = new THREE.Fog(0x23233f, 1, 300000);

        const camera = new THREE.PerspectiveCamera(
          70,
          window.innerWidth / window.innerHeight,
          1,
          100000
        );
        camera.position.set(50, 50, 50);
        const renderer = new THREE.WebGLRenderer({
          antialias: true,
          alpha: true,
        });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        const controls = new OrbitControls(camera, renderer.domElement);
        scene.add(new THREE.AxesHelper(100));
        window.onresize = () => {
          renderer.setSize(window.innerWidth, window.innerHeight);
          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();
        };
        return {
          scene,
          camera,
          renderer,
        };
      }
    </script>
  </body>
</html>
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值