Scene graph

25418 단어 three.jsjs3D3D

씬 그래프는 Scene또는 다수의 Mesh, Light, Group, object3D, Camera로 이루어진 트리 구조와 유사하다.


Scene은 씬 그래프의 최상위 노드로서 배경색(background color),안개 등의 요소를
Scene에 포함된 객체들 또한 부모/자식의 트리 구조로 이루어지며 이는 각 객체의 유래와 방향성을 나타낸다. 쉽게 말해 자식 객체의 위치와 방향이 부모 기준이다.

3D object가 3차워 공간 상에 놓여지기 위해서 위치, 회전, 크기가 필요하다

코드

   
    import * as THREE from '../build/three.module.js';
    import { OrbitControls } from '../examples/jsm/controls/OrbitControls.js';

    class App {
        constructor() {
            const divContainer = document.querySelector("#webgl-container");
            this._divContainer = divContainer;

            const renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setPixelRatio(window.devicePixelRatio);
            divContainer.appendChild(renderer.domElement)
            this._renderer = renderer;

            const scene = new THREE.Scene();
            this._scene = scene;

            this._setupCamara();
            this._setupLight();
            this._setupModel();
            this._setupControls();

            window.onresize = this.resize.bind(this);
            this.resize();

            requestAnimationFrame(this.render.bind(this));
        }

    _setupCamara() {
        const width = this._divContainer.clientWidth;
        const height = this._divContainer.clientHeight;
        const camera = new THREE.PerspectiveCamera(
        75,
        width / height,
        0.1,
        100
        );

        camera.position.z = 25;
        this._camara = camera;
    }

    _setupLight() {
        const color = 0xffffff;
        const intensity = 1;
        const light = new THREE.DirectionalLight(color, intensity)
        light.position.set(-1, 2, 4);
        this._scene.add(light);
    }
    _setupControls() {
        new OrbitControls(this._camara, this._divContainer);
    }

    _setupModel() {
      // 구모양 생성
        const solarSystem = new THREE.Object3D();
        this._scene.add(solarSystem);

        const radius = 1;
        const widthSegments =12;
        const heightSegments = 12;
        const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);
// 태양의 재질 생성
        const sunMaterial = new THREE.MeshPhongMaterial({
            emissive: 0xffff00, flatShading: true});
// sunMesh와 earth Mesh를 solar system 자식
        const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial);
        sunMesh.scale.set(3, 3, 3);
        solarSystem.add(sunMesh);
// 지구의 재질 생성
        const earthOrbit = new THREE.Object3D();
        solarSystem.add(earthOrbit);

        const earthMaterial = new THREE.MeshPhongMaterial({
            color: 0x2233ff, emissive:0x112244, flatShading: true});

        const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial);
        earthOrbit.position.x = 10;
        earthOrbit.add(earthMesh);
//moonOrbit은 earthOrbit의 자식으로 earthOrbit의 x축의 거리 2
        const moonOrbit = new THREE.Object3D();
        moonOrbit.position.x = 2;
        earthOrbit.add(moonOrbit);

        const moonMaterial = new THREE.MeshPhongMaterial({
            color: 0x888888, emissive:0x222222, flatShading: true});

        const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial);
      // 지구의 절반 크기로 표현
        moonMesh.scale.set(0.5, 0.5, 0.5);
        moonOrbit.add(moonMesh);

        this._solarSystem = solarSystem;
        this._earthOrbit = earthOrbit;
        this._moonOrbit = moonOrbit;

    }

    resize() {
        const width = this._divContainer.clientWidth;
        const height = this._divContainer.clientHeight;

        this._camara.aspect = width / height;
        this._camara.updateProjectionMatrix();

        this._renderer.setSize(width, height);
    }

    render(time) {
        this._renderer.render(this._scene, this._camara);
        this.update(time);
        requestAnimationFrame(this.render.bind(this));
    }
    update(time) {
        time *= 0.001; //second unit
        
        this._solarSystem.rotation.y = time / 2;
      //지구에 대한 earthOrbit을 y축으로 회전
        this._earthOrbit.rotation.y = time * 2;
        this._moonOrbit.rotation.y = time * 5;
    }
    }

    window.onload = function() {
        new App();
    }

setupModel

좋은 웹페이지 즐겨찾기