본문 바로가기
FrontEnd/HTML, CSS

three.js 입문 (ing)

by 위그든씨 2023. 9. 30.
  • Three.js 는 크게 Scene, Camera, Render 로 나뉨
  • Scene : 렌더링 할 모든 객체와 광원을 저장하는 공간. (Scene이 없다면 어떠한 객체도 표시 못함)
  • Camera: Scene 객체를 어떻게 촬영하여 보여줄 것인지 결정
  • Render: Scene과 Camera 객체를 넘겨 받아 렌더링 한다. 

 

  1. three.js 불러오기
    • Option1 :install with NPM and a build tool
npm init

# three.js
npm install --save three

# vite
npm install --save-dev vite

npx vite
  •  Option2: import from a CDN
<script type="importmap">
  {
    "imports": {
      "three": "https://unpkg.com/three@<version>/build/three.module.js",
      "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/"
    }
  }
</script>

<script type="module">
  import * as THREE from 'three';
</script>

 

2. Scene 생성

  • 렌더링 할 모든 객체와 광원을 저장하는 공간.
let scene = new THREE.Scene();

// scene.background = new THREE.Color("skyblue"); //Scene의 배경색을 설정


const mesh = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1, 5, 5, 5),
    new THREE.MeshBasicMaterial({ color: 0xff0000 })
);

//const geometry = new THREE.BoxGeometry(1, 1, 1);
//const material = new THREE.MeshBasicMaterial({ color: 'rgb(255, 0, 0)' });
//const mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);

//씬에는 메쉬라는 것과 카메라를 담아줘야 함. 
//메쉬는 geometry, material 의 조합인데 geometry는 몸체(화면에 보여줄). material은 꼬리(몸체 속성) 처럼 생각하면 됨.

3. Camera 생성

  • Scene 객체를 어떻게 촬영하여 보여줄 것인지 결정
  • 아래는 카메라 종류
    1. PerspectiveCamera:
      • 3D 장면을 렌더링하기 위한 일반적인 카메라입니다.
      • 원근법을 사용하여 멀리 있는 객체가 작게 보이고 가까이 있는 객체가 크게 보이는 시각적 효과를 제공합니다.
    2. OrthographicCamera:
      • 원근법이 적용되지 않는 평면적인 뷰를 만들기 위한 카메라입니다. (1인칭 게임에 사용 .RTS 게임)
      • 멀리 있는 객체와 가까이 있는 객체가 동일한 크기로 렌더링됩니다.
    3. CubeCamera:
      • 주로 큐브맵(cubemap) 렌더링에 사용되는 카메라입니다.
      • 한 번에 여러 방향에서 뷰를 렌더링하여 큐브맵 텍스처를 생성합니다.
    4. ArrayCamera:
      • 여러 카메라를 배열로 그룹화하여 사용할 수 있는 카메라입니다.
      • 한 번에 여러 시점에서 렌더링을 수행할 수 있습니다.
    5. StereoCamera:
      • 스테레오 3D 렌더링을 지원하는 카메라입니다.
      • 두 개의 하위 카메라를 사용하여 왼쪽 및 오른쪽 눈을 동시에 렌더링합니다.
    6. VRPerspectiveCamera 및 VROrthographicCamera:
      • 가상 현실(VR) 애플리케이션을 위한 카메라입니다.
      • VR 환경에서 3D 장면을 렌더링하고 사용자의 시점과 상호 작용을 지원합니다.
const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height);

scene.add(camera) 	//카메라 생성 후 이것도 씬에 꼭 넣어줘야 함. (안 넣어도 작동은 되지만 이후 버그 유발 가능)

// constructor PerspectiveCamera(fov?: number | undefined, aspect?: number | undefined, near?: number | undefined, far?: number | undefined): THREE.PerspectiveCamera

// @remarks — Together these define the camera's viewing frustum.

// @param fov — Camera frustum vertical field of view. Default 50.

// @param aspect — Camera frustum aspect ratio. Default 1. 
// aspect 는 보통 (canvas의 폭/canvas 높이) 

// @param near — Camera frustum near plane. Default 0.1.

// @param far — Camera frustum far plane. Default 2000.

4. Renderer생성 - 

  • 만들어진 Scene과 Camera를 받아와서 화면에 render 해줌
  • renderer를 통해 캔버스의 크기 조정 가능
    • Three.js의 renderer.setSize()를 사용하면 Three.js 렌더러가 크기를 자동으로 조정하고 렌더링에 대응할 수 있지만, HTML  내에서 캔버스의 크기를 직접 설정하면 Three.js 렌더러는 캔버스 크기 변경을 감지하지 못하고 문제가 발생할 수 있음. 일반적으로 Three.js를 사용할 때는 renderer.setSize()를 사용하여 캔버스 크기를 조정하는 것이 좋음
const canvas = document.querySelector('canvas.webgl');

const renderer = new THREE.WebGLRenderer({
    canvas:canvas
});

renderer.setSize(800, 600); //렌더러가 canvas 크기 조정

renderer.render(scene, camera);	//씬과 카메라를 받아와 렌더링 해줌
  • 위와 같이 쭉 이어 왔다면 에러는 발생하지 않겠지만 만들어둔 mesh는 보여지지 않을 것임. 카메라의 위치와 메쉬의 위치를 정하지 않았기 때문.
mesh.position.x = 1
mesh.position.y = 1
mesh.position.z = 1

// mesh.position.set(1,1,1)


camera.position.x = 1
camera.position.y = 1 
camera.position.y = 1 
// camera.postion.set(1,1,1) 

//mesh의 position을 변경하면 우리가 x,y,z축에 따라 이동을 하지만 
//카메라의 위치를 변경할 경우에는 카메라가 x,y,z축에 따라 이동을 하는 것이므로 우리 눈에 보여지는 mesh는 카메라에 준 값과 반대 돼서 보임

 

5.  rotation과 scale을 통해 모형 변경 가능

6. window.requestAnimationFrame() 을 이용해서 재귀 로직을 짜면 애니메이션 효과 주기 가능 .

7. THREE.Group() 을 통해 그룹을 만들면 여러 매쉬를 하나의 묶음으로 만들어서 조작 가능

const group = new THREE.Group();	//group 생성 
group.scale.y = 2;
group.rotation.y = 0.2;
scene.add(group);		// 그룹 생성 후 씬에 담아주기

const cube1 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
cube1.position.x = -1.5;
group.add(cube1);		// 매시를 만들어서 원하는 그룹에 넣기 

const cube2 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
cube2.position.x = 0;
group.add(cube2);		// 매시를 만들어서 원하는 그룹에 넣기


const clock = new THREE.Clock();	//THREE.Clock

const tick = () => {
    const elapsedTime = clock.getElapsedTime();		// 경과시간

    group.rotation.y = Math.PI * elapsedTime;		//속성을 변경하면 그 그룹 전체에 적용됨 (group.children[idx] 로도 개별 접근 가능)
    group.position.x = Math.cos(elapsedTime);		//삼각함수를 이용하면 범위 내 좌표 이동도 가능 
    group.position.y = Math.sin(elapsedTime);

    camera.lookAt(group.position);					// Vector 값을 이용한 카메라 위치 조정

    window.requestAnimationFrame(tick);				//재귀
    renderer.render(scene, camera);
};

 

'FrontEnd > HTML, CSS' 카테고리의 다른 글

three.js 공부하기 전 용어 정리  (0) 2023.09.29
[html,css] canvas animation (ing)  (0) 2023.09.27
canvas 정리  (0) 2023.09.27
[css] linear-gradient  (0) 2023.09.27
[css] min(),max(),clamp() : css 함수를 통한 반응형 웹  (0) 2023.09.26