Three.js - 3d 물체에 그림자 적용하는 방법

HIHI JIN·2023년 6월 5일

Three.js

목록 보기
6/7
post-thumbnail

Three.js에서 3D 도형에 그림자를 적용하기 위한 3단계
1. 렌더러에 그림자 사용 설정
2. 빛을 받아 그림자를 표현할 물체와 그 그림자를 받을 물체를 특정 코드로 설정
3. 빛 자체에도 그림자 설정을 코드로 추가
기본적으로 도형과 빛이 있어야 그림자가 있으며,
특정 빛에는 그림자 설정이 안됩니다.

도형 세팅

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

import { WEBGL } from './webgl'

if (WEBGL.isWebGLAvailable()) {
  //씬
  const scene = new THREE.Scene()
  scene.background = new THREE.Color(0xffffff)

  //카메라
  const camera = new THREE.PerspectiveCamera(
    120,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  )
  camera.position.set(0, 1, 1.8)
  camera.lookAt(new THREE.Vector3(0, 0, 0))

  //렌더러
  const renderer = new THREE.WebGLRenderer({
    alpha: true,
    antialias: true,
  })
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  //OrbitControls는 카메라 이후 등장필요
  const controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.update()

  //도형
  const geometry = new THREE.SphereGeometry(0.5, 32, 16)
  //const geometry = new THREE.IcosahedronGeometry(0,5,0);
  //const geometry = new THREE.ConeGeometry(0.4,0.7,6)
  const material = new THREE.MeshStandardMaterial({ color: 0x004fff })
  const cube = new THREE.Mesh(geometry, material)
  cube.rotation.y = 0.5
  cube.position.y = 0.2
  scene.add(cube)

  //바닥
  const planeGeometry = new THREE.PlaneGeometry(20, 20, 1, 1)
  const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff })
  const plane = new THREE.Mesh(planeGeometry, planeMaterial)
  plane.rotation.x = -0.5 * Math.PI
  plane.position.y = -0.2
  scene.add(plane)

  //빛
  const pointLight = new THREE.PointLight(0xffffff, 1)
  pointLight.position.set(0, 2, 12)
  scene.add(pointLight)

  //특정 3d 도형에 애니메이션 적용하기
  function render(time) {
    renderer.render(scene, camera)
  }
  requestAnimationFrame(render)

  //반응형 처리
  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  window.addEventListener('resize', onWindowResize)
} else {
  var warning = WEBGL.getWebGLErrorMessage()
  document.body.appendChild(warning)
}

1. 렌더러에 그림자 사용 설정

 //렌더러
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
})
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

//⭐렌더러에 그림자 사용 설정
renderer.shadowMap.enabled = true;

2. 물체에 그림자 설정

 //도형
  const geometry = new THREE.SphereGeometry(0.5, 32, 16)
  //const geometry = new THREE.IcosahedronGeometry(0,5,0);
  //const geometry = new THREE.ConeGeometry(0.4,0.7,6)
  const material = new THREE.MeshStandardMaterial({ color: 0x004fff })
  const cube = new THREE.Mesh(geometry, material)
  cube.rotation.y = 0.5
  cube.position.y = 0.2
  scene.add(cube)
  //⭐그림자를 생성할 도형에 castshadow 설정
  cube.castShadow = true

  //바닥
  const planeGeometry = new THREE.PlaneGeometry(20, 20, 1, 1)
  const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff })
  const plane = new THREE.Mesh(planeGeometry, planeMaterial)
  plane.rotation.x = -0.5 * Math.PI
  plane.position.y = -0.2
  scene.add(plane)
  //⭐그림자를 받아줄 도형에 receiveShadow 설정
  plane.receiveShadow = true

3. 빛에 그림자 설정

//빛
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
  //특정방향으로 빛을 비춘다.
  directionalLight.position.set(-0.5, 1.5, -0.5)
  //각 빛마다 helper옵션을 줄 수 있다. 첫번째 속성은 빛, 두번째 속성은 사이즈, 세번째는 색
  const dlHelper = new THREE.DirectionalLightHelper(
    directionalLight,
    0.2,
    0x0000ff
  )
  scene.add(dlHelper)
  scene.add(directionalLight)
  directionalLight.castShadow = true //⭐빛에 castshadow 설정

4. 그림자 해상도 높이는 방법

//빛
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
  //특정방향으로 빛을 비춘다.
  directionalLight.position.set(-0.5, 1.5, -0.5)
  //각 빛마다 helper옵션을 줄 수 있다. 첫번째 속성은 빛, 두번째 속성은 사이즈, 세번째는 색
  const dlHelper = new THREE.DirectionalLightHelper(
    directionalLight,
    0.2,
    0x0000ff
  )
  scene.add(dlHelper)
  scene.add(directionalLight)
  directionalLight.castShadow = true //빛에 castshadow 설정
  directionalLight.shadow.mapSize.width = 2048 //⭐그림자 해상도 설정, 높을수록 해상도좋다.
  directionalLight.shadow.mapSize.height = 2048 //⭐그림자 해상도 설정, 높을수록 해상도좋다.

const pointLight = new THREE.PointLight(0xffffff, 1)
scene.add(pointLight)
pointLight.position.set(-1, 1, 0.5)
const plhelper = new THREE.PointLightHelper(pointLight, 0.1)
scene.add(plhelper)
//빛에 castshadow 설정
pointLight.castShadow = true //그림자 O

5. 그림자에 블러 효과주는 방법

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
  //특정방향으로 빛을 비춘다.
  directionalLight.position.set(-0.5, 1.5, -0.5)
  //각 빛마다 helper옵션을 줄 수 있다. 첫번째 속성은 빛, 두번째 속성은 사이즈, 세번째는 색
  const dlHelper = new THREE.DirectionalLightHelper(
    directionalLight,
    0.2,
    0x0000ff
  )
  //scene.add(dlHelper)
  scene.add(directionalLight)
  //빛에 castshadow 설정
  directionalLight.castShadow = true //그림자 O
  directionalLight.shadow.mapSize.width = 2048 //그림자 해상도 설정, 높을수록 해상도좋다.
  directionalLight.shadow.mapSize.height = 2048
  directionalLight.shadow.radius = 2
profile
신입 프론트엔드 웹 개발자입니다.

0개의 댓글