그림자 추가
/* Renderer 만들기 : html에 캔버스 미리 만들기 */
const canvas = document.querySelector("#three-canvas");
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);
// 그림자 설정
renderer.shadowMap.enabled = true;
// renderer.shadowMap.type = THREE.PCFShadowMap;
// renderer.shadowMap.type = THREE.BasicShadowMap;
// renderer.shadowMap.type = THREE.PCFSoftShadowMap;
렌더러에서 그림자가 설정될 수 있게 세팅해줘야 한다.
조명, 각각의 물체에서도 그림자를 설정해줘야 그림자가 설정된다.
renderer.shadowMap.type 설정
- THREE.js에서 renderer.shadowMap.type 설정은 그림자의 품질과 렌더링 성능에 영향을 주는 옵션이다.
- 이 속성은 그림자가 어떻게 렌더링될지를 결정한다.
- 각 옵션은 그림자의 디테일 수준과 성능에 차이가 있다.
THREE.BasicShadowMap
- 기본적인 그림자 맵이다.
- 속도가 가장 빠르지만, 그림자가 뚜렷하지 않고 저해상도로 표현된다.
- 대형 그림자나 정밀한 그림자 표현이 필요하지 않은 경우 적합하다.
- 3D이면서 픽셀 아트처럼 사용할 경우 적합하며 shadow.mapSize의 속성 크기를 줄여 조정하기도 한다.
THREE.PCFShadowMap
- Percentage Closer Filtering (PCF) 방식으로 렌더링한다.
- 그림자가 부드럽게 보이며, 기본 그림자 맵보다 디테일이 향상된다.
- 다만 성능이 약간 저하될 수 있다.
THREE.PCFSoftShadowMap
- PCF 방식에 추가적인 소프트 처리를 적용하여, 그림자가 매우 부드럽게 표현된다.
- 가장 높은 품질의 그림자를 제공하지만, 성능이 더 많이 요구된다.
이러한 옵션을 선택할 때는 필요한 그림자 품질과 렌더링 성능을 고려해야 한다.
그림자는 기본적으로 두 가지를 세팅을 해준다. (CastShadow , Receive Shadow)
/* Light 만들기 */
// AmbientLight : 전체적으로 은은하게 깔아주는 조명
const ambientLight = new THREE.AmbientLight("white", 0.5);
scene.add(ambientLight);
// DirectionalLight : 태양광 같은 조명
const light = new THREE.DirectionalLight("red", 0.5);
light.position.x = -5;
light.position.y = 3;
scene.add(light);
// lightHelper: 조명을 시각적으로 확인하는 법
const lightHelper = new THREE.DirectionalLightHelper(light);
scene.add(lightHelper);
// 조명에 그림자 설정
light.castShadow = true; // 그림자를 만들 수 있는 조명이되는 것
light.shadow.mapSize.width = 1024; // 기본값 512
light.shadow.mapSize.height = 1024;
light.shadow.camera.near = 1;
light.shadow.camera.far = 30;
// light.shadow.radius = 15; // 기본값인 THREE.PCFShadowMap에서만 적용, 그림자의 가장자리 부드러움을 조절
/* Mesh 만들기 : Geometry + Material */
const plane = new THREE.Mesh(planeGeometry, material1); // 평면 바닥에 깔기
const box = new THREE.Mesh(boxGeometry, material2);
const sphere = new THREE.Mesh(sphereGeometry, material3);
plane.rotation.x = -Math.PI * 0.5;
box.position.set(1, 1, 0);
sphere.position.set(-1, 1, 0);
// 물체에 그림자 설정
plane.receiveShadow = true;
box.castShadow = true;
box.receiveShadow = true;
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(plane, box, sphere);
CastShadow, 다른 물체의 그림자가 생기게 영향을 줄 건지
Receive Shadow, 그 영향을 받아서 나한테 그림자가 그려지게 할 건지
plane에 그림자를 생기게 하려면 box, sphere에 CastShadow = true를 해줘야 한다. (바닥이기 때문에 그림자를 생기게 할 필요가없어 CastShadow = true를 해주지 않아도 된다. )
plane는 그 영향을 받아서 그림자를 그려야 되니까 receiveShadow = true 를 해주면 된다.
box, sphere도 서로의 물체가 그림자가 생길 거리에 있고 그림자 영향을 받고 싶다면 receiveShadow = true 를 해주면 된다.
light.castShadow = true;
- 그림자를 만들 수 있는 조명이 되는 것
- 특정 광원이 장면에서 그림자를 투사하도록 한다.
- 즉, 이 광원이 빛을 비추는 모든 오브젝트에 그림자가 생길 수 있게 한다.
- 이 설정이 없으면 광원은 단순히 빛만 비출 뿐, 그림자를 생성하지 않는다.
- 만약 광원에 light.castShadow = true;가 되어 있어도, 장면에 있는 오브젝트들에 object.castShadow = true; 설정이 없으면 아무런 그림자가 생기지 않는다.
- 반대로, object.castShadow = true;가 되어 있어도 광원이 castShadow = true;가 아니면 그림자가 생기지 않는다.
light.shadow.mapSize = true;
- 그림자가 매끄럽지 않을 때 shadow.mapSize = true; 설정해 주기
- 그림자 맵의 해상도를 설정하는 속성
- 그림자의 선명도와 품질을 결정하는 중요한 요소이다.
- 해상도는 width와 height로 설정되며, 예를 들어 shadow.mapSize.width = 1024 및 shadow.mapSize.height = 1024처럼 사용할 수 있다.
- 높은 mapSize를 설정하면 그림자가 더 선명하고 자연스러워지지만, 성능에 부담을 줄 수 있다.
- 반대로 낮은 값을 사용하면 성능이 향상되지만, 그림자가 픽셀화되어 보이거나 뭉개진 느낌을 줄 수 있다.
- 보통, 화면에 보이는 오브젝트의 크기와 디테일을 고려하여 적절한 mapSize 값을 설정하는 것이 좋다. (보통 1024 ~ 2048로 세팅한다.)
light.shadow.radius
- 기본값인 THREE.PCFShadowMap에서만 적용한다.
- 그림자의 가장자리 부드러움을 조절하는 속성
- 이 값이 클수록 그림자의 가장자리가 더 부드럽고 흐릿해지며, 경계선이 퍼지면서 부드러운 느낌이 들어 더욱 자연스러운 효과를 줄 수 있다.
- 작은 값일수록 그림자 가장자리가 선명하고 날카롭게 보인다.
light.shadow.camera.near, light.shadow.camera.far
조명의 그림자 범위 정하기
object.castShadow = true;
- 설정은 특정 광원(light)이 그림자를 투사하도록 만드는 것이다.
- 이를 통해 광원이 물체에 그림자를 생성할 수 있다.
THREE.js에서 그림자를 구현할 때는 고려할 사항
- 카메라 설정
- 그림자가 투사될 범위와 품질에 영향을 미친다.
- 림자의 범위를 조절하려면 광원의 그림자 카메라(light.shadow.camera) 속성들을 설정해야 한다.
- 받는 객체 설정
- 그림자가 투사되는 객체(object.receiveShadow = true;)가 그림자를 받을 수 있게 설정되어야 한다.
- 렌더러 설정
- 렌더러에서 그림자 맵을 활성화 해야 한다
- (renderer.shadowMap.enabled = true;).
이러한 설정이 모두 맞아야 최종 장면에서 그림자가 정상적으로 나타난다.
object.receiveShadow = true;
- 3D 그래픽에서 오브젝트가 다른 오브젝트로부터 그림자를 받는 기능을 말한다.
- 이 설정이 활성화되면, 해당 오브젝트가 빛에 의해 투사된 다른 오브젝트의 그림자를 받을 수 있다.
- 이를 통해 현실감 있는 장면을 만들 수 있다.
- 예를 들어, 바닥이나 벽과 같은 오브젝트가 주변 오브젝트의 그림자를 받을 수 있도록 설정하면, 빛의 방향과 강도에 따라 보다 자연스러운 그림자 효과를 줄 수 있다.
- 리시브 쉐도우는 보통 렌더링 엔진에서 오브젝트마다 개별적으로 활성화하거나 비활성화할 수 있으며, 사용되는 경우 성능에 영향을 줄 수 있다.
- 따라서 중요한 오브젝트에만 이 옵션을 적용하는 것이 좋다.
'Frontend > Three.js' 카테고리의 다른 글
조명, SpotLight_스포트라이트 효과_무대 조명이나 손전등과 같은 빛을 표현 (0) | 2024.11.10 |
---|---|
조명, PointLight _ 특정 지점에서 빛이 모든 방향으로 퍼져나가는 조명 효과_ 전구나 촛불 같은 광원을 표현 (0) | 2024.11.10 |
조명, Light 애니메이션 (0) | 2024.11.03 |
삼각함수를 이용해 원형적인 움직임을 구현하기 (0) | 2024.11.03 |
시간 흐름 측정, getDelta()와 getElapsedTime() (0) | 2024.11.03 |