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

ThreeJS - 3D Bar and Progress Bar

[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개

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

게시글 목록

번호 제목
16893
16890
16889
16888
16887
16886
16885
16884
16883
16882
16881
16880
16871
16870
16868
16863
16861
16856
16852
16834
16833
16829
16827
16826
16823
16822
16819
16818
16817
16806