테스트 사이트 - 개발 중인 베타 버전입니다

ThreeJS - 3D Bar and Progress Bar

· 2년 전 · 1032 · 1

[code]

import * as THREE from "https://cdn.skypack.dev/three@0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";
import {createNoise2D} from "https://cdn.skypack.dev/simplex-noise@4.0.0";

console.clear();

let scene = new THREE.Scene();
scene.background = new THREE.Color(0x7f7f7f);
let camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 1000);
camera.position.set(-5, 10, 10).setLength(20);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
})

let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

let light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(0.75, 0.5, 1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));

scene.add(new THREE.GridHelper());

class ProgressBar extends THREE.Sprite{
  constructor(_progress){
    super();
    this.scale.set(2, 0.1);
    this.material = new THREE.SpriteMaterial({
      onBeforeCompile: shader => {
        shader.uniforms.progress = _progress;
        shader.fragmentShader = `
          #define ss(a, b, c) smoothstep(a, b, c)
          uniform float progress;
          ${shader.fragmentShader}
        `.replace(
          `outgoingLight = diffuseColor.rgb;`,
          `outgoingLight = diffuseColor.rgb;
            vec3 backColor = mix(vec3(0), vec3(0, 0.5, 0), progress);
            float pb = step(progress, vUv.x);
            outgoingLight.rgb = mix(vec3(0, 1, 0), backColor, pb);
          `
        );
        console.log(shader.fragmentShader);
      }
    });
    this.material.defines = {"USE_UV" : ""};
    this.center.set(0.5, 0);
  }
}

class ProgressObject extends THREE.Object3D{
  constructor(height){
    const rand = Math.random() * 100;
    const noise = createNoise2D();
    super();
    let _progress = {value: 0.5};
    let og = new THREE.BoxGeometry().translate(0, 0.5, 0);
    let om = new THREE.MeshLambertMaterial();
    let o = new THREE.Mesh(og, om);
    o.scale.y = height;
    
    let lg = new THREE.EdgesGeometry(new THREE.BoxGeometry());
    lg.translate(0, 0.5, 0);
    lg.scale(1, height, 1);
    let lm = new THREE.LineBasicMaterial({color: new THREE.Color(Math.random() * 0xffffff).multiplyScalar(0.5).addScalar(0.5)});
    let l = new THREE.LineSegments(lg, lm);
    
    let pbar = new ProgressBar(_progress);
    pbar.position.y = height * 1.1;
    
    this.add(o, l, pbar);
    
    this.update = val => {
      _progress.value = noise(val, 0.25) * 0.5 + 0.5;
      o.scale.y = height * _progress.value;
    }
  }
}

let tmu = THREE.MathUtils;
let POs = new Array(5).fill().map(o => {
  let po = new ProgressObject(tmu.randInt(2, 5));
  po.position.x = tmu.randInt(-5, 4) + 0.5;
  po.position.z = tmu.randInt(-5, 4) + 0.5;
  scene.add(po);
  return po
})

let clock = new THREE.Clock();

renderer.setAnimationLoop(() => {
  controls.update();
  let t = clock.getElapsedTime() * 0.5;
  POs.forEach(po => {po.update(t)});
  renderer.render(scene, camera);
});

[/code]

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 1개

오 좋타 이걸로 뭘 응용해볼까요?

게시글 목록

번호 제목
17657
17655
17654
17653
17652
17651
17650
17642
17633
17632
17631
17630
17628
17624
17623
17620
17618
17617
17614
17612
17611
17610
17609
17608
17607
17604
17603
17602
17600
17594