Three.js Animation Loop

강정우·2025년 1월 2일
0

three.js

목록 보기
4/24
post-thumbnail

Animation Loop

Animation Loop 는 앞서 폭죽 구현 관련 포스팅에서 봤던 기본기가 있으면 훨씬 이해하기가 쉽다.
즉, 지금 우리는 Obrbit Control 로 객체를 욺직이든 말든 계속하여 Frame 이 refresh 되며 animate 함수를 초당 모니터 주사율에 맞춰 호출하고 있다. 이는 아주 기본적인 렌더링을 함에도 불구하고 생각보다 메모리를 많이 잡아먹는다.

Frame Rate Independence

import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import Stats from 'three/addons/libs/stats.module.js'

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 1.5

const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
})

new OrbitControls(camera, renderer.domElement)

const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshNormalMaterial({ wireframe: true })

const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

const stats = new Stats()
document.body.appendChild(stats.dom)

const clock = new THREE.Clock()
let delta

function animate() {
  requestAnimationFrame(animate)

  delta = clock.getDelta()

  cube.rotation.x += delta
  cube.rotation.y += delta

  renderer.render(scene, camera)

  stats.update()
}

animate()

따라서 우리는 이 코드를 사용자가 수정을 할 때만, 즉, onDemand 로 바꿀 필요가 있다.

onDemand

import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 1.5

const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.render(scene, camera)
})

const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('change', () => {
  renderer.render(scene, camera)
})

const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshNormalMaterial({ wireframe: true })

const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

renderer.render(scene, camera)

onChangeCallback 함수 이용하기

컨트롤러와 window 의 resize 이벤트에 renderer.render(scene, camera) 코드를 넣어서 사용자가 마우스로 OrbitControl 을 하거나 혹은 브라우저 창을 resize 를 할 때 다시 그리도록 코드를 수정하였다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글