09. 3d 물체에 그림자 적용하는 방법 – Three.js 강좌

three.js 그림자 적용한 3d 예시

안녕하세요. 저번 영상에서는 빛에 대해 다뤄봤는데, 이번 영상에서는 그림자를 다뤄볼게요. Three.js에서 3D 도형에 그림자를 적용하기 위해서는 크게 3단계가 필요합니다. 렌더러에 그림자 사용 설정하고, 빛을 받아 그림자를 표현할 물체와 그 그림자를 받을 물체를 특정 코드로 설정해야 합니다. 마지막으로 빛 자체에도 그림자 설정을 코드로 추가해 주면 됩니다. 기본적으로 도형과 빛이 있어야 그림자가 있겠죠?! 그런데, 저번 영상에서 설명 드린것럼 특정 빛에는 그림자 설정이 안됩니다. 이건 직접 코딩하면서 알아볼게요.

*디자인 베이스 강좌는 Mac OS를 기준으로 해서 윈도우 사용자와 일부 차이가 있을 수 있습니다. 윈도우 사용자분들은 영상에서 커맨드(Cmd)라는 단축키 대신 컨트롤(Ctrl)을, 옵션(Option) 대신 알트(Alt)를 눌러주세요.

그림자 표현을 위한 3단계

three.js 그림자를 적용하기 위한 3단계
three.js 그림자를 적용하기 위한 3단계

01. Renderer에 그림자 사용 설정

렌더러 하단에 ShadowMap.enabled의 불리언 값을 true로 설정해야 합니다.

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

02. 빛을 받아 그림자를 표현할 물체와 그 그림자를 받을 물체에 특정 코드로 설정

그림자를 만들(표현 할) 도형에 castShadow를 적용하고, 그림자를 받을 도형에 receiveShadow를 적용해야 합니다.

three.js 빛과 그림자 원리
three.js 빛과 그림자 원리
//3D
const geometry = new THREE.IcosahedronGeometry(0.5,0);
const material = new THREE.MeshStandardMaterial({
    color: 0x004fff
});
const cube = new THREE.Mesh(geometry, material);
cube.rotation.y = 0.5;
cube.position.y = 0.5;
scene.add(cube);
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);
plane.receiveShadow = true; // 그림자를 받을 도형

03. 빛에 그림자 표현

마지막으로 빛에도 castShadow를 설정해야 합니다. 그림자의 해상도와 블러 정도를 조절 할 수 있습니다. 단, three.js에서 제공하는 빛 중에 AmbientLight, RectAreaLight 등의 빛에는 그림자를 표현할 수 없습니다.

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(-1.5, 2, 1);
const dlHelper = new THREE.DirectionalLightHelper(directionalLight, 0.2, 0x0000ff);
scene.add(dlHelper);
scene.add(directionalLight);
directionalLight.castShadow = true; // 그림자 O
directionalLight.shadow.mapSize.width = 2048; // 그림자의 해상도
directionalLight.shadow.mapSize.height = 2048; // 그림자의 해상도
directionalLight.shadow.radius = 8; // 그림자의 블러