threejs+dat.gui实现可调参数的逼真风雪模拟系统代码

代码语言:html

所属分类:粒子

代码描述:threejs+dat.gui实现可调参数的逼真风雪模拟系统代码,可设置重力、速度、密度、数量、风速、随机值等模拟现实中的风雪效果。

代码标签: three dat.gui 风雪 下雪 模拟

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">

  
  
  
<style>
* {
  margin: 0;
  padding: 0;
}

html,
body {
  overflow: hidden;
  background-color: black;
}

.webgl {
  position: fixed;
  top: 0;
  left: 0;
  outline: none;
}

.image {
  position: absolute;
  display: flex;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}

img {
  object-fit: cover;
  object-position: 50% 50%;
  width: 100%;
  height: auto;
}
</style>



</head>

<body>
  <div class="image">
  <img src="//repo.bfw.wiki/bfwrepo/image/5df0355083a46.png" />
</div>
<canvas class="webgl"></canvas>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.126.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.126.js"></script>
  <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script>
      <script>



/**
 * Base
 */

// Debug
const gui = new dat.GUI();
gui.width = 400;

// Canvas
const canvas = document.querySelector('canvas.webgl');

// Scene
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);


/**
 * Particles
 */

const parameters = {};
parameters.count = 2000;
parameters.randomness = 0.5;
parameters.randomnessPower = 3;
parameters.sizeMin = 1.0;
parameters.sizeMax = 4.0;
parameters.opacityMin = 0.1;
parameters.opacityMax = 0.4;
parameters.gravity = 25.0;

let geometry = null;
let material = null;
let points = null;

let wind = {
  current: 0,
  force: 0.1,
  target: 0.1,
  min: 0.1,
  max: 0.2,
  easing: 0.005 };


// Add wind vars to GUI
gui.add(wind, 'min').min(0).max(1).step(0.005).name('Wind Speed Min');
gui.add(wind, 'max').min(0).max(1).step(0.005).name('Wind Speed Max');

const generateSnow = () =>
{
  if (points !== null)
  {
    geometry.dispose();
    material.dispose();
    scene.remove(points);
  }

  /**
   * Geometry
   */
  geometry = new THREE.BufferGeometry();

  const positions = new Float32Array(parameters.count * 3);
  const scales = new Float32Array(parameters.count * 1);
  const randomness = new Float32Array(parameters.count * 3);
  const speeds = new Float32Array(parameters.count * 3);
  const rotations = new Float32Array(parameters.count * 3);
  const opacities = new Float32Array(parameters.count * 1);

  for (let i = 0; i < parameters.count; i++)
  {
    const i3 = i * 3;

    // Position
    positions[i3] = (Math.random() - 0.5) * 12;
    positions[i3 + 1] = (Math.random() - 0.5) * 12;
    positions[i3 + 2] = (Math.random() - 0.5) * 12;

    // Randomness
    const randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1) * parameters.randomness;
    const randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1) * parameters.randomness;
    const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1) * parameters.randomness;

    // Random Positioning
    randomness[i3 + 0] = randomX;
    randomness[i3 + 1] = randomY;
    randomness[i3 + 2] = randomZ;

    // Random Positioning
    opacities[i3 + 0] = Math.random() * (parameters.opacityMax - parameters.opacityMin) + parameters.opacityMin;

    // Scale
    scales[i] = Math.random() * (parameters.sizeMax - parameters.sizeMin) + parameters.sizeMin;

    // Speeds
    speeds[i3 + 0] = 1 + Math.random();
    speeds[i3 + 1] = Math.random() * (0.06 - 0.05) + 0.05;
    speeds[i3 + 2] = Math.random() * (0.2 - 0.05) + 0.05;

    // Rotations
    rotations[i3 + 0] = Math.random() * 2 * Math.PI;
    rotations[i3 + 1] = Math.random() * 20;
    rotations[i3 + 2] = Math.random() * 10;
  }

  geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
  geometry.setAttribute('aScale', new THREE.BufferAttribute(scales, 1));
  geometry.setAttribute('aRandomness', new THREE.BufferAttribute(randomness, 3));
  geometry.setAttribute('aSpeed', new THREE.BufferAttribute(speeds, 3));
  geometry.setAttribute('aRotation', new THREE.BufferAttribute(rotations, 3));
  geometry.setAttribute('aOpacity', new THREE.BufferAttribute(opacities, 1));


  /**
   * Textures
   */
  const textureLoader = new THREE.TextureLoader();
  const particleTexture = textureLoader.load('https://assets.codepen.io/122136/snowflake_1.png');


  /**
   * Material
   */
  material = new THREE.ShaderMaterial({
    depthWrite: false,
    blending: THREE.AdditiveBlending,
    vertexColors: true,
    vertexShader: `
      precision mediump float;

      attribute vec4 aPosition;
      attribute float aOpacity;
      attribute float aScale;
      attribute vec3 aRotation;
      attribute float aSize;
      attribute vec3 aSpeed;

      uniform .........完整代码请登录后点击上方下载按钮下载查看

网友评论0