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

ThreeJS - 3D Bar and Progress Bar

· 2년 전 · 1034 · 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개

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

게시글 목록

번호 제목
17927
17926
17922
17921
17915
17910
17907
17892
17888
17879
17878
17874
17873
17872
17871
17870
17869
17868
17866
17865
17864
17863
17862
17859
17856
17845
17835
17834
17826
17823