[three.js] step2 브라우저 창 사이즈 변경 대응, 고해상도 표현, 애니메이션 효과, dat.gui 활용

원지·2023년 5월 25일
0

💻 브라우저의 창 사이즈 변경될 경우

function setSize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    //변경된 값을 카메라에 적용
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.render(scene, camera);
  }

  window.addEventListener("resize", setSize);

브라우저의 창 사이즈가 변경됐을 때, 카메라의 aspect를 window.innerWidth / window.innerHeight로 바꾸고 변경된 값을 updateProjectionMatrix통해 적용합니다. updateProjectionMatrix는 카메라의 파라미터값이 변하는 것을 적용하기 위해 꼭 필요합니다.

💻 고해상도로 표현하는 방법

console.log(window.devicePixelRatio);
renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);

devicePixelRatio는 픽셀을 구성하는데 필요한 물리적 픽셀 수를 나타냅니다. 만약 devicePixelRatio(dPR)이 6이면, 100px의 이미지를 표현하기 위해 실제로는 600px의 이미지를 사용하고 있는 것입니다. 따라서 renderer의 해상도를 높이고 싶을 경우 setPixelRatio를 통해 dPR을 변경할 수 있습니다.

💻 배경색 변경

배경색은 renderer 또는 scene에서 변경 가능합니다. 다만, 적용 우선순위는 scene이 더 높기 때문에 renderer와 scene에서 동시에 배경색을 설정할 경우 scene에서 설정한 값만 적용됩니다.

📍 renderer에서 변경할 경우

const renderer = new THREE.WebGL1Renderer({
    canvas,
    antialias: true,
    //alpha 배경색을 투명하게
    alpha: true,
  });
  //배경 투명도 조절
  renderer.setClearAlpha(0.5);
  //배경색 변경
  renderer.setClearColor(0x00ff00);
  renderer.setClearColor("#00ff00");

renderer의 파라미터로 alpha값을 넣거나 setClearAlpha를 통해 배경의 투명도를 조절할 수 있고 setClearColor로 배경의 색을 변경할 수 있습니다.

📍 scene에서 변경할 경우

scene.background = new THREE.Color("blue");

background를 통해 scene의 색을 변경할 수 있습니다.

💻 애니메이션 효과

📍 requestAnimationFrame

function draw() {
    mesh.rotation.y += 0.1;
    mesh.rotation.y += THREE.MathUtils.degToRad(1);
    
    renderer.render(scene, camera);

    window.requestAnimationFrame(draw);
  }

draw();

window.requestAnimationFrame()은 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 합니다. 이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받습니다.

📍 three.js clock + getElapsedTime

const clock = new THREE.Clock();
  
  function draw() {
    const time = clock.getElapsedTime();

    mesh.rotation.y = time;
    mesh.position.y += 0.01;
    if (mesh.position.y > 3) {
      mesh.position.y = 0;
    }
    renderer.render(scene, camera);
    renderer.setAnimationLoop(draw);
  }

draw();

requestAnimationFrame의 경우 기기의 성능에 따라 애니메이션 횟수가 달리 적용될 수 있습니다. 이를 방지하기 위해 three.js에서 제공하는 clock을 이용해 애니메이션 성능을 보정합니다.
three.js의 Clock()을 이용해 clock 객체를 만들고 getElapsedTime을 통해 실행시점으로부터의 총 경과시간을 이용해 애니메이션을 적용합니다.

📍 three.js clock + getDelta

const clock = new THREE.Clock();
  
  function draw() {
    const delta = clock.getDelta();

    mesh.rotation.y += delta;
    mesh.position.y += 0.01;
    if (mesh.position.y > 3) {
      mesh.position.y = 0;
    }
    renderer.render(scene, camera);

    renderer.setAnimationLoop(draw);
  }

draw();

getDelta()는 draw함수가 실행되는 시간의 간격을 가져옵니다. 단, getElapsedTime와 동시에 사용할 경우 오류가 발생할 수 있으니 주의해야합니다.

📍 자바스크립트 내장 기능을 이용할 경우

let oldTime = Date.now();
  function draw() {
    const newTime = Date.now();
    const deltaTime = newTime - oldTime;
    oldTime = newTime;

    mesh.rotation.y += deltaTime * 0.01;
    mesh.position.y += 0.01;
    if (mesh.position.y > 3) {
      mesh.position.y = 0;
    }
    renderer.render(scene, camera);

    renderer.setAnimationLoop(draw);
  }

💻 dat.GUI 활용

dat.GUI는 값을 GUI를 통해 변경해 기능을 테스트해볼 수 있는 자바스크립트 기반의 라이브러리입니다.

const gui = new dat.GUI();
  gui.add(mesh.position, "y", -5, 5, 0.01).name("y 위치");
  gui.add(mesh.position, "z").min(-10).max(3).step(0.01).name("메쉬의 Z 위치");
  gui.add(camera.position, "x", -10, 10, 1).name("카메라 X");

gui.add(객체, 객체의 속성값, 최소값, 최댓값, 값의 변화폭)로 간단하게 객체의 위치, 크기 등을 변경할 수 있습니다.

0개의 댓글