Saturday, March 5, 2022

threejs rain


each raindrop is a vector
Vector3 {x: 2.0756558940764194, y: -88.44726970939564, z: -72.53420307492986, velocity: 0}

//main.js

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { SpotLight } from 'three';

// Setup

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#bg'),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.z = 1;
camera.rotation.x = 1.02;
camera.rotation.y = 0.1584;
camera.rotation.z = -0.2511;

renderer.render(scene, camera);

const pointLight = new THREE.PointLight(0x062d89, 5, 500, 1.7);
pointLight.position.set(200, 300, 100);

const ambientLight = new THREE.AmbientLight(0x555555);
scene.add(pointLight, ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight)

const lightHelper = new THREE.PointLightHelper(pointLight);
scene.add(lightHelper);

const dustCloud = []

const smokeTexture = new THREE.TextureLoader().load('smoke particle.png');

for (let i = 0; i < 25; i++) {
  const smoke = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(500, 500),
    new THREE.MeshStandardMaterial({
      map: smokeTexture,
      transparent: true
    })
  )

  smoke.position.set(
    Math.random() * 800 - 400,
    500,
    Math.random() * 500 - 400
  )

  smoke.rotation.x = 1.16;
  smoke.rotation.y = 0.12;
  smoke.rotation.z = Math.random() * 360;
  smoke.material.opacity = 0.6;

  scene.add(smoke)
  dustCloud.push(smoke)
}

const rainDrops = []

for (let j = 0; j < 1000; j++) {
  const rainDrop = new THREE.Vector3(
    Math.random() * 400 - 200,
    Math.random() * 500 - 250,
    Math.random() * 400 - 200
  )

  rainDrop.velocity = 0;
  rainDrops.push(rainDrop);
}

let rainGeo = new THREE.BufferGeometry().setFromPoints(rainDrops);

const rainDropMaterial = new THREE.PointsMaterial({
  color: 0xaaaaaa,
  size: 1,
  transparent: true
})

let rain = new THREE.Points(
  rainGeo,
  rainDropMaterial
)

scene.add(rain)

function animate() {
  requestAnimationFrame(animate);

  dustCloud.forEach(p => {
    p.rotation.z -= 0.002;
  })

  if (Math.random() > 0.93 || pointLight.power > 100) {
    if (pointLight.power < 100) {
      pointLight.position.set(
        Math.random() * 400,
        300 + Math.random() * 200,
        100
      );
    }
    pointLight.power = 50 + Math.random() * 500;
  }

  scene.remove(rain)

  rainDrops.forEach(p => {
    p.velocity -= 0.1 + Math.random() * 0.1;
    p.y += p.velocity;

    if (p.y < -200) {
      p.y = 200;
      p.velocity = 0;
    }
  })

  rainGeo = new THREE.BufferGeometry().setFromPoints(rainDrops);

  rain = new THREE.Points(
    rainGeo,
    rainDropMaterial
  )

  scene.add(rain)

  renderer.render(scene, camera);
}

animate()

reference:

No comments:

Post a Comment