본문 바로가기
개발/three.js

[three.js] 공간속에서 움직이는 구체 만들기

by 밤즈라라2 2025. 1. 5.
728x90
반응형

 

본 내용은 아래 강의에서 공부한 내용입니다. 강의가 정말 좋으니 추천드립니당..

https://www.inflearn.com/users/258264/@coding11

 

코딩일레븐님의 소개 - 인프런

인프런 코딩일레븐님의 소개 페이지 입니다. - 코딩일레븐님 소개 | 인프런

www.inflearn.com

 

 

 

 

 

* OrbitControls가 마우스 이벤트를 처리

카메라를 따라 궤도를 회전합니다.

 

 

 

클릭하면서 회전시키면 안에 있는 구체도 회전하고, 바깥의 이미지도 회전한다.

side: THREE.FrontSide,
side: THREE.BackSide,

 

이 개념을 잘 이해해야한다.. 아래의 설명을 보면 좀 더 이해하기 쉽다.

THREE.FrontSide

  • 구체의 바깥쪽 표면에만 텍스처가 보입니다
  • 마치 공을 위에서 감싸는 것처럼 텍스처가 적용됩니다
  • 구체 안쪽에서 보면 텍스처가 보이지 않습니다
  • 예시: 만약 달을 만든다면, 달의 표면 텍스처를 바깥쪽에서 보이게 하기 위해 FrontSide를 사용합니다

THREE.BackSide

  • 구체의 안쪽 표면에만 텍스처가 보입니다
  • 마치 방 안에 서있는 것처럼, 안쪽에서 밖을 보는 방식으로 텍스처가 적용됩니다
  • 구체 바깥쪽에서 보면 텍스처가 보이지 않습니다
  • 예시: 360도 파노라마 이미지를 보여주는 방을 만들 때, 관찰자가 방 안에서 주변을 볼 수 있도록 BackSide를 사용합니다

 


let WIDTH = window.innerWidth;
let HEIGHT = window.innerHeight;

let scene, camera, renderer;
let controls;

const init = () => {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(60, WIDTH / HEIGHT, 0.1, 1000);
    camera.position.set(400, 250, 0);

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(WIDTH, HEIGHT);
    renderer.setClearColor(0x000000); //배경 컬러
    document.body.appendChild(renderer.domElement);

    //카메라 컨트롤
    controls = new OrbitControls(camera, renderer.domElement);
    //구 밖으로 스크롤 못하게
    controls.minDistance = 200;
    controls.maxDistance = 400;
    controls.enableDamping = true;

    {
        const imageLoader = new THREE.TextureLoader();
        // imageLoader.load("./image/room.jpg", (data) => {
            imageLoader.load("./image/bg.jpg", (data) => {
            const material = new THREE.MeshBasicMaterial({
                map: data,
                //BackSide 구 안에다가 매핑/ FrontSide: 구 밖에서 매핑 (얜 그래서 동그라미에 덮으면 동그라미에 쏙 들어감)
                // side: THREE.BackSide,
                side: THREE.FrontSide,
            });
            const geometry = new THREE.SphereGeometry(100, 32, 32);
            const roomMesh = new THREE.Mesh(geometry, material);
            scene.add(roomMesh);
        });
    }

    {
        const imageLoader = new THREE.TextureLoader();
        imageLoader.load("./image/room.jpg", (data) => {
            // imageLoader.load("./image/bg.jpg", (data) => {
            const material = new THREE.MeshBasicMaterial({
                map: data,
                //BackSide 구 안에다가 매핑/ FrontSide: 구 밖에서 매핑 (얜 그래서 동그라미에 덮으면 동그라미에 쏙 들어감)
                side: THREE.BackSide,
                // side: THREE.FrontSide,
            });
            const geometry = new THREE.SphereGeometry(400, 32, 32);
            const roomMesh = new THREE.Mesh(geometry, material);
            scene.add(roomMesh);
        });
    }
    renderer.render(scene, camera);
};

const animate = () => {
    camera.lookAt(scene.position);
    camera.updateProjectionMatrix();

    controls.update();
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
};

const stageResize = () => {
    WIDTH = window.innerWidth;
    HEIGHT = window.innerHeight;

    renderer.setSize(WIDTH, HEIGHT);
    camera.aspect = WIDTH / HEIGHT;
};

init();
animate();
window.addEventListener("resize", stageResize);
728x90
반응형