그림자가 다르게 표현됩니다
138
投稿した質問数 8
강의 코드를 그대로 따라하면 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();
回答 1
0
안녕하세요, 인프런 AI 인턴입니다. 김혜빈님께서 질문하신 내용에 대해 답변드리겠습니다.
Three.js에서 여러 개의 물체에 대해 그림자를 자연스럽게 표현하려면 몇 가지 사항을 점검해볼 필요가 있습니다.
조명 설정: SpotLight와 같은 특정 조명은 setup에 따라 그림자를 다르게 표현할 수 있습니다. 강의와 다르게 표현되는 이유는 조명 위치 및 각도 설정이 다를 수 있기 때문입니다. 그림자가 강의와 같이 모두 동일하게 나오도록 하려면, 각도나 위치를 조정하여 조명 광원을 더 넓게 설정하거나, 추가적인 조명을 사용할 수 있습니다.
그림자 속성 확인: 각 Mesh가
castShadow와receiveShadow속성을 올바르게 설정했는지 확인하세요. 그림자는 일반적으로 빛과 대상 객체 모두에castShadow속성이 필요하고, 지표면과 같은 받는 면에는receiveShadow속성이 필요합니다.장면 내 요소들의 구성: 현재 장면의 구성 요소가 어떤 방식으로 배치되어 있는지 확인해보세요. 적절한 그림자를 위해, 조명이 충분히 모든 물체에 닿을 수 있도록 배치해야 합니다.
빛의 강도: 빛의 강도를 더 높이거나, 총 사용 가능한 그림자 맵의 해상도를 올려 물체에 그림자가 고르게 드리워지는지 확인하세요.
아래 링크를 참조하여 추가적인 도움 받으실 수 있습니다:
해당 페이지에서 비슷한 질문 및 답변을 잘 정리해두었다고 하니 참고해보시면 좋겠습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
box3.position.x 위치
0
38
1
리액트/next.js와 같이 사용하는 강의 계획은 없으신가요?
0
81
1
소스코드 파일이 강의랑 같나요?
0
119
2
materials 배열에 있는 top, bottom ... 들에 대해서
0
118
0
gltf 포맷 사용
0
243
1
점프 애니메이션 stop
0
127
2
사양에 따른 다른 결과
0
112
1
중복 질문 삭제
0
160
1
혹시 이 빛의 범위를 조절할 수 있는 방법이 있나요?
0
124
1
gltf.scene.children 이 없는데도 모델이 화면에 떠요
0
101
2
GLF파일 export한 후에 three.js에서 렌더링 된 모델에는 텍스처 적용이 안되어있습니다..!
0
160
1
일반 유리, 강화 유리 강의에서 Glass 객체의 position X를 -1, 1로 설정한 이유를 모르겠어요
0
77
0
setAnimationLoop 위치가...
0
99
1
얼굴 그릴 때 붓이 깔끔하게 칠해지지 않고 얼룩덜룩해요
0
135
1
블렌더 texture paint 시 미러모드
0
164
0
DragControls의 인자값을 바꾸지 않았는데 에러가 안떠요!
0
104
1
blender 에서 색칠하기 편 Texter paint slot추가없음
0
966
2
fin 버전도 그냥 실행이 안돼요
0
289
2
자바스크립트 실행이 안되는 것 같아요
0
380
1
모니터 해상도에 따라 mesh의 크기가 변할 수 있나요?
0
238
1
live server와 localhost:8080
0
345
1
material에 canvas 를 texture 로 넣는방법이 궁금해요
0
270
1
모바일 조이스틱은 어떻게 만들 수 있을까요?
0
208
1
징검다리 예제에서 SpotLight가 동작 오류
0
303
2

