![[ThreeJS] 자주쓰이는 속성과 클래스 정리Note](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6chf3%2FbtsDp96jaZZ%2FBB8uzOEiXF6syDmvzdy2kK%2Fimg.png)
조명
전 포스팅에서는 Material 클래스를 선언할때 조명 설정없이도 3D객체를 나타낼 수 있는 BasicMaterial로 선언하였다.
하지만 주로 쓰이는 클래스는 < MeshStandardMaterial >라는 클래스이다.
이 BasicMaterial을 제외한 나머지 Material클래스들은 조명이 없으면 시각화되지 않는다.
이를 해결하기 위해 우리는 조명이라고 불리는 'Light'를 설정해주어야한다.
Light는 아래와 같이 DirectionalLight 클래스로 선언하고 인자로 빛의 색, 광원의 밝기를 받는다.
const directionalLight = new THREE.DirectionalLight("white", 10);directionalLight.castShadow = true; //빛이 그림자를 드리울 수 있게함directionalLight.position.set(0, 3, 2); //객체의 x,y,z 좌표값을 설정함. 즉, 조명의 위치를 설정함.directionalLight.lookAt(0, 0, 0); // 조명이 어느 좌표에서 쏘이는지 설정scene.add(directionalLight);
Scene에 배치된 카메라를 드래그와 함께 움직이기
드래그와 함께 카메라를 움직여 3D객체를 다각도에서 보기 위해 필요한 클래스는 OrbitControls(camera,renderer.domElement)이다. 아래의 코드의 첫 줄과 같이 따로 모듈을 import 해주어야한다.
같이 사용되는 메서드는 아래와 같다.
- .update()
- requestAnimationFrame(render)
requestAnimationFrame(render) 메서드는 아래의 코드와 같이 render라는 함수안에서 renderer과 함께 재귀적으로 실행되어야한다.
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";const orbitControls = new OrbitControls(camera, renderer.domElement);orbitControls.update();const render = () => { renderer.render(scene, camera); requestAnimationFrame(render);};
그림자
Mesh.castShadow = true; /*빛이 그림자를 드리울 수 있게 함*/Mesh.receiveShadow = true; /*그림자를 받을 수 있게 함*/
하지만 어떤 3D객체에 코드를 적용을 시켜도 아래의 그림과 같이 그림자가 나타나지 않는다.

왜냐하면 renderer가 그림자를 허용하고 있지 않기 때문이다. 아래의 코드를 적용하면 그림자가 나타난다.
const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.shadowMap.type = THREE.PCFSoftShadowMap; /*그림자 타입 설정*/renderer.shadowMap.enabled = true; /*render클래스로 선언된 renderer가 그림자를 허용하는지*/

회전
아래의 코드를 보면 floor.rotation.x = -Math.PI / 2 를 볼 수 있다.
말 그대로 x축을 180º/2 → 90º 회전시킨것이다.
const floorGeometry = new THREE.PlaneGeometry(20, 20);const floorMaterial = new THREE.MeshStandardMaterial({ color: "gray" });const floor = new THREE.Mesh(floorGeometry, floorMaterial);floor.rotation.x = -Math.PI / 2; /*이 부분*/floor.receiveShadow = true;floor.castShadow = true;scene.add(floor);
객체 하나를 만들고 Scene에 추가하기까지..
카메라와 조명이 설정되어있다고 가정하고 나열한다.
1. Geometry 설정
2. Material 설정
3. Mesh 에 Geometry,Material 를 인자로 넣기
3-1. 각종 조건이나 메서드
4. Scene에 추가
아래는 그 예시 코드이다.
const cylinderGeometry = new THREE.CylinderGeometry(1, 1, 2);const cylinderMaterial = new THREE.MeshStandardMaterial({ color: "orange" });const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);cylinder.position.set(-3, 1, 0);cylinder.castShadow = true;cylinder.receiveShadow = true;scene.add(cylinder);
GLTF 모델파일 로드
const gltfLoader = new GLTFLoader();const gltf = await gltfLoader.loadAsync("/dancer.glb");const characeter = gltf.scene;const animationClips = gltf.animations;characeter.position.y = 0.8;characeter.scale.set(0.01,0.01,0.01);characeter.castShadow = true;characeter.receiveShadow = true;/*여기까지만 하면 그림자 x객체의 children을 타고 내려가면서 객체의 모든 속성에 shadow 속성 부여해야함그 메소드가 traverse()*/characeter.traverse(obj => { if(obj.isMesh){ obj.castShadow = true; obj.receiveShadow = true; }})console.log(gltf);scene.add(characeter);
const gltfLoader = new GLTFLoader();/*동기*/gltfLoader.load("/dancer.glb", (gltf) => { const characeter = gltf.scene characeter.position.y = 0.8; characeter.scale.set(0.01,0.01,0.01); scene.add(characeter);});/*비동기*/const gltf = await gltfLoader.loadAsync("/dancer.glb");const characeter = gltf.scene;characeter.position.y = 0.8;characeter.scale.set(0.01,0.01,0.01);scene.add(characeter);
Animations
AnimationMixer 인스턴스를 사용해서 mixer 선언.
ClipAction 메서드를 통해 특정 Animation 사용할 수 있음.
action.play() 로 실행.
setLoop의 인자로 올 수 있는 3가지
1. LoopOnce
2. LoopPingPong
3. LoopRepeat
const mixer = new THREE.AnimationMixer(characeter);const action = mixer.clipAction(animationClips[3]);action.setLoop(THREE.LoopRepeat);action.setDuration(10); action.setEffectiveWeight(2);action.play();const clock = new THREE.Clock();const render = () => { renderer.render(scene, camera); requestAnimationFrame(render); orbitControls.update(); if (mixer){ mixer.update(clock.getDelta()); /* render()안에서 시간의 흐름에 따라 동작할 수 있게 해야함*/ }};
action.setDuration( <int> ) : Animation 절대적 속도 조절
aciont.setEffectiveTimeScale( <int>) : Animation 상대적 속도 조절. default는 1
action.setEffectiveWeight( <int> ): 인자의 크기가 클수록 모델의 Animation 동작이 확실해짐

'FrontEnd > 3D Web' 카테고리의 다른 글
[R3F] About R3F's Hooks (0) | 2024.08.22 |
---|---|
[R3F] Migration - ThreeJs to R3F (0) | 2024.08.16 |
[ThreeJS] ThreeJS 기본 구성 요소 (0) | 2024.01.11 |
[ThreeJS] ThreeJS 환경 세팅 (0) | 2024.01.10 |
안녕하세요? 개발자입니다.