본문 바로가기

3D Project/3D 인터랙티브 웹

[3D 인터랙티브 웹] 3D 구 모델링하기, OrbitControls(카메라 컨트롤러)

[프로젝트 셋업] 

 1.  webpack 개발 환경 세팅 - 3D를 웹에 불러오기 위한 첫번째 단계

(참고 사이트 2개)

Webpack | 개념 / 필수 개발 환경 세팅 1 (velog.io)

 

Webpack | 개념 / 필수 개발 환경 세팅 1

프론트엔드 개발을 위한 웹팩 설정Node.js 미리 설치되어 있어야 함. HTML+CSS+JS 기초다양한 모듈들을 하나의 js 파일로 만들어줌.보통 작업을 할 때, index.html을 만들고 index.js 파일을 만듦.index.htmlinde

velog.io

웹팩(Webpack) 밑바닥부터 설정하기 (tistory.com)

 

웹팩(Webpack) 밑바닥부터 설정하기

최근 웹팩을 설정해서 과제를 제출했다. 웹팩을 '활용'했다고 하기에는 사용한 기능이 빙산에 일각에 불과한데, 이마저도 대부분을 페어로부터 배웠다,,, 혼자 해보면 정말 못할 것 같아서, 다시

365kim.tistory.com

 

Webpack.config.js

//node에서 제공하는 path 모듈을 활용. path는 파일 경로 조작에 활용됨.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  devtool: 'inline-source-map',
  //개발 서버 설정
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    watchFiles:['src/**/*'],
    compress: true,
    port: 3000,
  },
  //Webpack 플러그인 설정
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: 'src/index.html'
    })
  ],
  //출력 설정
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  //modules 옵션은 모듈을 찾을 때 검색을 시작할 디렉토리를 지정
  resolve: {
    modules: ['node_modules'],
    extensions: ['.js', '.json']
  },
  //모듈 로더 설정 - 파일을 어떻게 처리할지에 대한 규칙
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader','css-loader']
      },
      // less loader
      {
        test: /\.less$/i,
        use: ['style-loader','css-loader','less-loader']
      },
    ]
  },
};

 

2. 필요한 라이브러리 설치 및 Three.js 초기세팅

package.json - 필요한 라이브러리

{
  "name": "threejsweb",
  "version": "1.0.0",
  "description": "3d interactive web by javascript",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve --open",
    "build": "webpack --mode production"
  },
  "author": "Ryu Hyeri + Coloso",
  "dependencies": {
    "mathjs": "^11.8.0",
    "pretendard": "^1.3.6",
    "three": "^0.132.2"
  },
  "devDependencies": {
    "@babel/core": "^7.21.8",
    "@babel/preset-env": "^7.21.5",
    "babel-loader": "^9.1.2",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.7.3",
    "html-webpack-plugin": "^5.5.1",
    "less": "^4.1.3",
    "less-loader": "^11.1.0",
    "style-loader": "^3.3.2",
    "webpack": "^5.66.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.6.0"
  }
}

 

index.js - Three.js의 초기세팅(renderer, scene, camera 세팅하기)

import "./study/style.less";
import * as THREE from "three";

//three.js의 기본 오브젝트들
//renderer, scene, camera, light, mesh

let renderer, scene, camera;

// THREE.js의 초기세팅
function init() {
    const canvas = document.createElement("canvas");
    document.body.appendChild(canvas);

    //renderer 스크린 크기에 맞게 세팅
    renderer = new THREE.WebGLRenderer({canvas:canvas})
    renderer.setSize(window.innerWidth, window.innerHeight)

    //렌더링할 수 있는 Scene Object 생성(장면 단위로 화면을 렌더링함)
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera();

    const light = new THREE.DirectionalLight();
    //Scene 안에 빛과 모델링 포함
    scene.add(light);

    render(); //초기세팅 끝난 후 렌더함수 호출

}

//지속적으로 화면을 렌더링(초당 60번정도 호출)
function render() {
    renderer.render(scene. camera);
    requestAnimationFrame(render); //반복적으로 호출
}

init();

 

3. 3D 도형 모델링 - 간단한 도형 띄우기

  1. Geometry Object 생성 -> 형태 결정
  2. Material Object 생성 -> texture(색과 질감) 결정
  3. Mesh Object 생성 -> 1+2 합쳐서 화면에 띄우기
import "./study/style.less";
import * as THREE from "three";

//three.js의 기본 오브젝트들
//renderer, scene, camera, light, mesh

let renderer, scene, camera;

// THREE.js의 초기세팅
function init() {
    const canvas = document.createElement("canvas");
    document.body.appendChild(canvas);

    //renderer 스크린 크기에 맞게 세팅
    renderer = new THREE.WebGLRenderer({canvas:canvas, antialias:true});
    renderer.setSize(window.innerWidth, window.innerHeight);

    //렌더링할 수 있는 Scene Object 생성(장면 단위로 화면을 렌더링함)
    scene = new THREE.Scene();

   
    //camera와 모델링의 위치가 같으면 정상적으로 렌더링 안됨 -> 카메라 위치 바꾸기
    camera = new THREE.PerspectiveCamera();
    camera.fov = 75;//카메라의 화각, 시야각이 더 넓어질수록 더 많은 화면을 담으려고함
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
    camera.position.set(0, 0, 5);
    // camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight);
    // camera.position.set(0,0,10); //z값이 커질수록 카메가 원점에서(구와) 더 멀리 떨어져있는 효과가 나타남


    const light = new THREE.DirectionalLight();
    //Scene 안에 빛과 모델링 포함
    light.position.set(1,1,1); //빛의 방향을 바꾸기 위해서는 빛의 위치를 바꿔야함
    scene.add(light);

    //구 형태의 모델링, material -> 빛을 받는 부분을 자연스럽게 render
    const sphere_geometry = new THREE.SphereGeometry();
    const material = new THREE.MeshPhongMaterial();
    const sphere = new THREE.Mesh(sphere_geometry, material)
    scene.add(sphere);

    render(); //초기세팅 끝난 후 렌더함수 호출


}

//지속적으로 화면을 렌더링(초당 60번정도 호출)
function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render); //반복적으로 호출
}

init();

 

3D 구 모델링 결과

 

[ OrbitControls 적용하기 ] - 사용자가 마우스로 3D 공간을 회전 및 이동할 수 있게 해주는 도구

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls" //1단계 - import
 
let renderer, scene, camera, controls;
 
function init () {
 
//생략 ,,, 
 
 controls = new OrbitControls(camera, canvas)
 controls.enablePan = false; //마우스 으론쪽 Panning 비활성화, 도형 이동 비활성화
 controls.enableDamping = true; //부드러운 움직임 적용
 
//생략 
 
 render()
 
}
 
function render() {
    renderer.render(scene, camera);
    controls.update(); //컨트롤러 초당 60번 업데이트
    requestAnimationFrame(render); //반복적으로 호출
}

init();