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

ThreeJS - 3D Bar and Progress Bar

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

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

게시글 목록

번호 제목
17819
17818
17817
17816
17814
17811
17810
17809
17808
17803
17799
17798
17797
17795
17794
17793
JavaScript JSON Beautify
17790
17789
17786
17774
17760
17755
17750
17729
17722
17714
17708
17686
17676
17666