인프런 커뮤니티 질문&답변
그림자가 다르게 표현됩니다
작성
·
137
·
수정됨
0
강의 코드를 그대로 따라하면 mesh 색이 어두운 회색으로 표현되고 그림자가 생기지 않는 문제가 있습니다.
그래서 SpotLight의 위치와 강도를 조정했더니 그림자는 나타나는데 강의영상처럼 모든 집에대한 그림자가 동일하게 나오는 것이 아니라 맨 처음 집에 대한 그림자만 선명히 나타납니다!


빛을 한방향에서만 쏘기 때문에 저 처럼 표현되는게 맞는 것 같은데, 강의영상처럼 모두 동일한 그림자를 표현하려면 어떻게 해야할까요..?
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js';
import { House } from './House';
import gsap from 'gsap';
// ----- 주제: 스크롤에 따라 움직이는 3D 페이지
// Renderer
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; // 그림자 설정, mesh도 함께 설정해야함
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 그림자 부드럽게
// Scene
const scene = new THREE.Scene();
scene.background = new THREE.Color('white'); // 백그라운드 하얀색
// Camera
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(-5, 2, 25);
scene.add(camera);
// Light
const ambientLight = new THREE.AmbientLight('white', 2);
scene.add(ambientLight);
const spotLight = new THREE.SpotLight('white', 500);
spotLight.position.set(-5, 10, 30);
// 그림자 설정
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024; // 그림자 퀄리티 조정(성능에 크게 영향을 미치지 않는 정도)
spotLight.shadow.mapSize.height = 1024; // 그림자 퀄리티 조정(성능에 크게 영향을 미치지 않는 정도)
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 1000;
scene.add(spotLight);
const spotLightHelper = new THREE.SpotLightHelper(spotLight, 'red');
scene.add(spotLightHelper);
// --- (2) HemisphereLight 추가 ---
// const hemiLight = new THREE.HemisphereLight('white', 'white', 2);
// scene.add(hemiLight);
const gltfLoader = new GLTFLoader();
// Mesh
const floorMesh = new THREE.Mesh(
new THREE.PlaneGeometry(100, 100),
new THREE.MeshStandardMaterial({
color: 'white',
roughness: 0.4, // 필요에 따라 조절
metalness: 0.2, // 필요에 따라 조절
toneMapped: false,
}) // 강의에는 MeshStandartMaterial 사용했는데, 이거 사용시 floorMesh가 하얀색이 아닌 회색으로 보여서 변경
);
floorMesh.rotation.x = -Math.PI / 2; // 180//2 = 90도
floorMesh.receiveShadow = true; // floorMesh에 그림자가 그려지기 때문에 recieveShadow 사용
scene.add(floorMesh);
// 하우스를 통해 그림자가 만들어져야 하므로 -> castShadow
const houses = [];
houses.push(
new House({
gltfLoader,
scene,
modelSrc: '/models/house.glb',
x: -5,
z: 20,
height: 2,
})
);
houses.push(
new House({
gltfLoader,
scene,
modelSrc: '/models/house.glb',
x: 7,
z: 10,
height: 2,
})
);
houses.push(
new House({
gltfLoader,
scene,
modelSrc: '/models/house.glb',
x: -10,
z: 0,
height: 2,
})
);
houses.push(
new House({
gltfLoader,
scene,
modelSrc: '/models/house.glb',
x: 10,
z: -10,
height: 2,
})
);
houses.push(
new House({
gltfLoader,
scene,
modelSrc: '/models/house.glb',
x: -5,
z: -20,
height: 2,
})
);
// 그리기
const clock = new THREE.Clock();
function draw() {
const delta = clock.getDelta();
renderer.render(scene, camera);
renderer.setAnimationLoop(draw);
spotLightHelper.update();
}
let currentSection = 0;
function setSection() {
// console.log('setSection 실행!'); // setSection 스크롤할때마다 실행됨
const newSection = Math.round(window.scrollY / window.innerHeight); // 0,1,2,3,4
if (currentSection !== newSection) {
console.log('animation!'); // section값이 바뀔때만 애니메이션이 동작하도록
gsap.to(camera.position, {
duration: 1,
x: houses[newSection].x,
z: houses[newSection].z + 5,
});
currentSection = newSection;
}
}
function setSize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
}
// 이벤트
window.addEventListener('scroll', setSection);
window.addEventListener('resize', setSize);
draw();
퀴즈
페이지 스크롤에 따라 3D 장면이 반응하도록 하는 핵심 원리는 무엇인가요?
스크롤에 따라 모델 색상 바꾸기
스크롤 위치에 따라 카메라 애니메이션하기
스크롤에 따라 모델 숨기거나 보여주기
스크롤에 따라 광원 강도 조절하기
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 김혜빈님께서 질문하신 내용에 대해 답변드리겠습니다.
Three.js에서 여러 개의 물체에 대해 그림자를 자연스럽게 표현하려면 몇 가지 사항을 점검해볼 필요가 있습니다.
조명 설정: SpotLight와 같은 특정 조명은 setup에 따라 그림자를 다르게 표현할 수 있습니다. 강의와 다르게 표현되는 이유는 조명 위치 및 각도 설정이 다를 수 있기 때문입니다. 그림자가 강의와 같이 모두 동일하게 나오도록 하려면, 각도나 위치를 조정하여 조명 광원을 더 넓게 설정하거나, 추가적인 조명을 사용할 수 있습니다.
그림자 속성 확인: 각 Mesh가
castShadow와receiveShadow속성을 올바르게 설정했는지 확인하세요. 그림자는 일반적으로 빛과 대상 객체 모두에castShadow속성이 필요하고, 지표면과 같은 받는 면에는receiveShadow속성이 필요합니다.장면 내 요소들의 구성: 현재 장면의 구성 요소가 어떤 방식으로 배치되어 있는지 확인해보세요. 적절한 그림자를 위해, 조명이 충분히 모든 물체에 닿을 수 있도록 배치해야 합니다.
빛의 강도: 빛의 강도를 더 높이거나, 총 사용 가능한 그림자 맵의 해상도를 올려 물체에 그림자가 고르게 드리워지는지 확인하세요.
아래 링크를 참조하여 추가적인 도움 받으실 수 있습니다:
해당 페이지에서 비슷한 질문 및 답변을 잘 정리해두었다고 하니 참고해보시면 좋겠습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.





