Code Less, Create More!

Simple but useful code snippets for 3D Graphic Developers

Three.js

Three.js를 하나의 HTML 파일로 실행하는 간단한 Boilerplate 예제

데브엑스 2023. 4. 8. 20:16
반응형

보일러플레이트 코드는 신규 또는 실험적인 프로젝트를 빠르게 시작하기에 좋은 방법입니다. 간단한 보일러플레이트 코드를 사용하면 기본 설정 코드를 처음부터 작성하지 않아도 되므로 시간이 절약되고 오류가 줄어듭니다. 보일러플레이트 코드를 시작점으로 사용해서 이를 기반으로 프로젝트를 구축할 수 있습니다.

Three.js의 보일러플레이트 코드는 일반적으로 렌더러, 카메라 및 장면과 같은 Three.js 장면을 만드는 데 필요한 기본 구성 요소를 포함합니다. 또한 Cube 또는 Sphere와 같은 기본적인 객체를 포함할 수 있으며, 이를 수정하거나 커스텀 3D 모델로 교체할 수 있습니다.

HTML과 Javascript를 사용하는 보일러플레이트 코드는 하나의 단일 HTML 파일로 시작할 수 있어서 편리합니다. 이를 통해 파일 구성을 간단하게 유지하면서도 새로운 Three.js 프로젝트를 빠르게 시작할 수 있습니다.

이 방식의 보일러플레이트 코드는 HTML 파일 내에 모든 Three.js 코드와 HTML 코드를 포함합니다. 이를 통해 별도의 Javascript 파일이나 CSS 파일을 추가하지 않아도 Three.js 장면을 만들 수 있습니다. 보일러플레이트 코드를 단일 HTML 파일로 시작할 때, 코드의 구성과 유지보수에 대한 고민을 줄일 수 있습니다. 또한 프로젝트의 초기 버전을 간단하게 유지하면서 Three.js의 기본적인 기능을 테스트하고 실험해볼 수 있습니다. 

그러나 외부 파일을 로드해야하는 경우, 보안 문제로 인해 서버를 통해 파일을 제공해야합니다. 이 경우, 단일 HTML 파일에 Three.js 코드와 HTML 코드만 포함되며, 모든 외부 파일은 서버에서 로드됩니다.

1. Three.js 시작하기

Three.js는 웹에서 3D 그래픽과 애니메이션을 만들수 있는 강력한 자바스크립트 라이브러리입니다. Three.js를 처음 사용해보거나 간단한 예제를 빠르게 만들고 싶다면, 다음과 같은 간단한 보일러플레이트 코드를 사용할 수 있습니다.
먼저, 원하는 이름으로 새로운 HTML 파일을 생성하고 threejs-boilerplate.html이라고 지정합니다. HTML 파일을 열어서 아래의 코드를 추가합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js Boilerplate</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
    <script>
        // Create the scene
        const scene = new THREE.Scene();
        scene.background = new THREE.Color( 0xaaaaff );
        
        // Create the camera
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

        // Create the light
        const light = new THREE.DirectionalLight( 0xffffff );
        light.position.set( 0, 0.5, 1 );
        scene.add( light );

        // Create the renderer
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        
        // Create a cube
        const geometry = new THREE.BoxGeometry();
        const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);
        
        // Position the camera
        camera.position.z = 5;
        
        // Animate the cube
        function animate() {
            requestAnimationFrame(animate);
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;
            renderer.render(scene, camera);
        }
        animate();
    </script>
</body>
</html>

이 코드는 Three.js 장면을 만드는 데 필요한 기본 구성 요소를 포함하고 있습니다. HTML 파일에서 Three.js 라이브러리를 로드하고, 장면, 카메라, 렌더러를 만들고, 큐브를 만들어 장면에 추가합니다.

마지막으로, 애니메이션을 렌더링하는 함수를 만들어 호출합니다. 이 함수는 브라우저에게 애니메이션을 반복적으로 그리도록 요청합니다.

이 보일러플레이트 코드를 실행하면, 초록색 큐브가 회전하는 Three.js 장면이 표시됩니다. 이 예제 코드를 시작점으로 사용하여 Three.js의 다양한 기능을 시험해 볼 수 있습니다.

간단히 Cube를 생성해 회전시키는 보일러플레이트의 실행화면

2. 웹 브라우저에서 로컬 HTML 파일 열기

위의 예제는 로컬 파일 시스템에서 HTML 파일을 열어 웹 브라우저에서 쉽게 로드할 수 있습니다.
코드가 3D 모델이나 텍스처와 같은 외부 파일을 로드하지 않기 때문에 브라우저는 이러한 리소스를 로드하기 위해 서버에 추가 요청을 보낼 필요가 없습니다. 전체 코드가 HTML 파일 내에 포함되어 있으므로, 웹 서버를 통해 제공받을 필요 없이 파일 시스템에서 직접 실행할 수 있습니다.

그러나 3D 모델이나 텍스처와 같은 외부 파일을 로드할 때는 Same-Origin Policy 보안 제한이 적용되기 때문에 이를 염두에 두어야 합니다. 이는 HTML 파일과 같은 도메인에 호스팅되지 않은 경우 브라우저가 외부 리소스의 로딩을 차단할 수 있음을 의미합니다. 이러한 보안 제한을 피하려면, 로컬 파일 시스템에서 위치한 경우에도 HTML 파일과 모든 외부 리소스를 웹 서버에서 제공하는 것이 좋습니다. 이렇게 하면 브라우저가 외부 리소스의 로딩을 차단하지 않고 코드가 다른 웹 브라우저 및 플랫폼에서 일관되게 작동함을 보장할 수 있습니다.

3. Three.js HTML 파일에서 외부 파일 로드하기

외부에 저장된 3D 모델이나 텍스처 파일을 로드해야 하는 경우, Three.js 클래스와 메서드를 추가로 사용하여 이를 장면에 로드해야 합니다.
3D 모델을 로드하려면 THREE.GLTFLoader 클래스를 사용할 수 있습니다. 이 로더는 .glb 및 .gltf를 비롯한 다양한 3D 모델 형식을 처리할 수 있습니다. 다음은 3D 모델을 로드하고 장면에 추가하는 예제 코드입니다:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js Boilerplate</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/three@0.138.0/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.138.0/examples/js/loaders/GLTFLoader.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.138.0/examples/js/loaders/RGBELoader.js"></script>
    <script>
        // Create the scene
        const scene = new THREE.Scene();
        scene.background = new THREE.Color( 0x00aaff );
        
        const light = new THREE.DirectionalLight( 0xffffff );
        light.position.set( 0, 0.5, 1 );
        scene.add( light );
        
        // Create the camera
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        
        // Create the renderer
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        
        // Tone mapping for environment map
        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 3;
        
        // Load the 3D model
        const loader = new THREE.GLTFLoader();
		//const modelUrl = "./DamagedHelmet.glb";

        // If server of external asset allows CORS, it can be loaded from a local file.
		const modelUrl = "https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/DamagedHelmet/glTF-Binary/DamagedHelmet.glb";
		
        let model = null;
        loader.load(modelUrl, function (gltf) {
            scene.add(gltf.scene);
			model = gltf.scene;

			const bbox = new THREE.Box3().setFromObject(scene);			
			const bsize = bbox.getSize(new THREE.Vector3());
			const radius = bsize.length();
			// Position the camera to view entire model.
			camera.position.z = radius;
        });        
        
        // create environment map for background and reflection 
		const envmap = new THREE.RGBELoader()
            .setPath('https://threejs.org/examples/textures/equirectangular/')
            .load('royal_esplanade_1k.hdr', function ( texture ) {
                texture.mapping = THREE.EquirectangularReflectionMapping;

                scene.background = texture;
                scene.environment = texture;
            });
                    
        // Animate the scene
        function animate() {
            requestAnimationFrame(animate);

            if (model) {
                model.rotation.y += 0.01;
            }

            renderer.render(scene, camera);
        }
        animate();
    </script>
</body>
</html>

이 코드에서는 THREE.GLTFLoader 클래스를 사용하여 modelUrl의 glTF 파일을 로드합니다. 로드가 완료되면 로드된 3D 모델이 장면에 추가됩니다. 로드하는 동안 에러가 발생하면 콘솔에 에러 메시지가 출력됩니다

3D 모델과 텍스쳐 파일은 아래의 경로에서 다운로드 할 수 있습니다.

https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/DamagedHelmet/glTF-Binary/DamagedHelmet.glb

 

GitHub - KhronosGroup/glTF-Sample-Models: glTF Sample Models

glTF Sample Models. Contribute to KhronosGroup/glTF-Sample-Models development by creating an account on GitHub.

github.com

https://github.com/mrdoob/three.js/blob/r138/examples/textures/equirectangular/royal_esplanade_1k.hdr

 

GitHub - mrdoob/three.js: JavaScript 3D Library.

JavaScript 3D Library. Contribute to mrdoob/three.js development by creating an account on GitHub.

github.com

두번째 예제가 제대로 실행된다면 아래 그림처럼 3D 모델이 자동으로 회전하는 화면을 볼 수 있습니다. 두번째 예제는 웹서버에서 실행되기 때문에 예제 파일의 이름을 index.html로 지정하면 localhost:8000 의 URL로 바로 열리게 됩니다.

외부 파일로 3D 모델을 로드해서 회전시키는 실행 화면

이 예제 코드를 시작점으로 사용하여 Three.js의 다양한 추가 기능을 시도해 볼 수 있습니다.

4. 간단한 웹 서버

HTML 파일에 3D 모델이나 텍스처와 같은 외부 파일을 로드하려면 HTML 파일을 웹 서버에서 제공해야 합니다.

HTML 파일을 웹 서버에서 제공하려면, 컴퓨터에 로컬 웹 서버를 설치하거나 호스팅 서비스를 사용하여 웹 사이트를 온라인에서 호스팅할 수 있습니다. 여러 가지 선택지가 있으며, 필요에 따라 무료 또는 유료 옵션을 선택할 수 있습니다.

예를 들어, 단순한 독립형 명령 줄 웹 서버를 다운로드할 수 있습니다. TinyWeb를 사용하는 것이 그 중 하나입니다. TinyWeb

 

Installing

Installing TinyWeb To install TinyWeb server just create a shortcut in Startup menu with the following properties: Targetc:\www\bin\tiny.exe c:\www\root Start Inc:\www\log c:\www\bin\tiny.exe is the path to TinyWeb executable, c:\www\root is the path to ww

www.ritlabs.com

Python을 설치해 두었다면 간단하게 빠르며 가벼운 HTTP 서버 모듈을 사용할 수 있습니다.

# execute python module
python -m SimpleHTTPServer
# or the Python 3 equivalent
python3 -m http.server

Node.js도 HTTP 서버 모듈을 제공합니다.

# install module system-wide
npm install http-server -g

# run server with www-root-directory and port-number
http-server www-root-directory -p 8000

로컬 웹 서버를 사용하는 경우, URL은 http://localhost:8000/threejs-boilerplate.html과 같은 형태로 사용합니다. 이를 통해 서버에서 외부 파일을 로드하고 Three.js 코드에서 사용할 수 있습니다.

결론 

보일러플레이트 코드를 잘 활용하면 새로운 프로젝트를 만드는 데 드는 시간과 노력을 절약할 수 있으며, 창의적인 측면에 집중할 수 있습니다. 또한 잘 구성된 코드 구조와 최선의 관행을 고려한 견고한 기반 위에 프로젝트를 구축할 수 있도록 도와줍니다.

하지만 보일러플레이트 코드는 단순한 시작점일 뿐이며, 프로젝트를 개발하면서 특정 요구 사항에 맞게 코드를 수정하거나 커스터마이즈해야 합니다. 조명, 재질 또는 텍스처와 같은 추가 구성 요소를 추가하여 더욱 현실적이고 몰입감 있는 장면을 만들어야 할 수도 있습니다.

결론적으로, 간단한 보일러플레이트 코드를 사용하면 새로운 Three.js 프로젝트를 빠르게 시작할 수 있으며, 프로젝트를 더 빠르고 효율적으로 시작할 수 있도록 도와줍니다.

반응형