66651
๐Ÿ‘€
66651
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (57)
    • note (28)
    • log (13)
    • error (9)
    • etc (7)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • ํƒœ๊ทธ
  • ๋ฐฉ๋ช…๋ก

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
66651

๐Ÿ‘€

note

[Three.js] GIS Developer ๋‹˜์˜ Three.js ๊ฐ•์ขŒ - 5

GIS Developer ๋‹˜์˜ Three.js ๊ฐ•์ขŒ : https://www.youtube.com/watch?v=Oe4n0vyrSiU

 

 

 

์นด๋ฉ”๋ผ (Camera)

Camera๋ฅผ ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค (Camera๋Š” object 3D๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค

- PerspectiveCamera : ๊ฐ€๊นŒ์ด ์žˆ๋Š” ๋ฌผ์ฒด๊ฐ€ ๋ฉ€๋ฆฌ ์žˆ๋Š” ๋ฌผ์ฒด๋ณด๋‹ค ์ƒ๋Œ€์ ์œผ๋กœ ํฌ๊ฒŒ ๋ณด์ด๋„๋ก ์›๊ทผ๊ฐ์„ ํ‘œํ˜„ํ•ด์„œ ๋ Œ๋”๋งํ•œ๋‹ค. fovy, aspect, zNear, zFar๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ด ์ธ์ž๋“ค์„ ํ†ตํ•ด ์ ˆ๋‘์ฒด๊ฐ€ ๊ตฌ์„ฑ๋œ๋‹ค. (์ ˆ๋‘์ฒด ์•ˆ์— ์กด์žฌํ•˜๋Š” ๋ฌผ์ฒด๊ฐ€ ์นด๋ฉ”๋ผ๋ฅผ ํ†ตํ•ด ๋ณด์—ฌ์ง€๊ฒŒ ๋œ๋‹ค) zNear์™€ zFar ๊ฑฐ๋ฆฌ ์‚ฌ์ด๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š”๋‹ค. 

- OrthographicCamera : ๋ฌผ์ฒด๊ฐ„์˜ ์›๊ทผ๊ฐ์—†์ด ๋ฌผ์ฒด์˜ ํฌ๊ธฐ ํฌ๊ธฐ๋Œ€๋กœ ๋ Œ๋”๋งํ•œ๋‹ค. zLeft, xRight, yTop, yBottom, zNear, zFar๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค.

 

 

// 07-camera.js
import * as THREE from '../build/three.module.js';
import {OrbitControls} from '../examples/jsm/controls/OrbitControls.js';
import {RectAreaLightUniformsLib} from '../examples/jsm/lights/RectAreaLightUniformsLib.js';
import {RectAreaLightHelper} from '../examples/jsm/helpers/RectAreaLightHelper.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._setupCamera();
		this._setupLight();
		this._setupModel();
		this._setupControls();

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

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

	_setupControls() {
		new OrbitControls(this._camera, this._divContainer);
	}

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

		// PerspectiveCamera(์ ˆ๋‘์ฒด์˜ ๋†’์ด ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ๊ฐ๋„, ์ ˆ๋‘์ฒด์˜ ๊ฐ€๋กœ ๊ธธ์ด๋ฅผ ์„ธ๋กœ ๊ธธ์ด๋กœ ๋‚˜๋ˆˆ ๋น„์œจ, ์นด๋ฉ”๋ผ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ ์•ž์ชฝ, ์นด๋ฉ”๋ผ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ ๋’ค์ชฝ)
		const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100);

		// OrthographicCamera(์ˆ˜ํ‰์ถ• ์™ผ์ชฝ์— ๋Œ€ํ•œ ์ขŒํ‘œ๊ฐ’, ์ˆ˜ํ‰์ถ• ์˜ค๋ฅธ์ชฝ์— ๋Œ€ํ•œ ์ขŒํ‘œ๊ฐ’, ์ˆ˜์ง์ถ• ์œ„์ชฝ์— ๋Œ€ํ•œ ์ขŒํ‘œ๊ฐ’, ์ˆ˜์ง์ถ• ์•„๋ž˜์ชฝ์— ๋Œ€ํ•œ ์ขŒํ‘œ๊ฐ’, ์นด๋ฉ”๋ผ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ ์•ž์ชฝ, ์นด๋ฉ”๋ผ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ ๋’ค์ชฝ)
		// aspect : ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๊ฐ€ ํ‘œ์‹œ๋˜๋Š” DOM ์š”์†Œ ํฌ๊ธฐ์— ๋Œ€ํ•œ ์ข…ํšก๋น„๋ฅผ ์ ์šฉ
		/* const aspect = window.innerWidth / window.innerHeight;
		const camera = new THREE.OrthographicCamera(aspect * -1, aspect * 1, 1, -1, 0.1, 100);
		camera.zoom = 0.15; */

		//camera.position.z = 2;
		// ์นด๋ฉ”๋ผ์˜ ์œ„์น˜
		camera.position.set(7, 7, 0);
		// ์นด๋ฉ”๋ผ๊ฐ€ ๋ฐ”๋ผ๋ณด๋Š” ์œ„์น˜
		camera.lookAt(0, 0, 0);
		this._camera = camera;
	}

	_setupLight() {
		RectAreaLightUniformsLib.init();
		const light = new THREE.RectAreaLight(0xffffff, 10, 6, 1);
		light.position.set(0, 5, 0);
		light.rotation.x = THREE.Math.degToRad(-90);

		const helper = new RectAreaLightHelper(light);
		this._scene.add(helper);
		this._lightHelper = helper;

		this._scene.add(light);
		this._light = light;
	}

	_setupModel() {
		const groundGeometry = new THREE.PlaneGeometry(10, 10);
		const groundMaterial = new THREE.MeshStandardMaterial({
			color: '#2c3e50',
			roughness: 0.5,
			metalness: 0.5,
			side: THREE.DoubleSide,
		});

		const ground = new THREE.Mesh(groundGeometry, groundMaterial);
		ground.rotation.x = THREE.Math.degToRad(-90);
		this._scene.add(ground);

		const bigSphereGeometry = new THREE.SphereGeometry(1.5, 64, 64, 0, Math.PI);
		const bigSphereMaterial = new THREE.MeshStandardMaterial({
			color: '#ffffff',
			roughness: 0.1,
			metalness: 0.2,
		});

		const bigSphere = new THREE.Mesh(bigSphereGeometry, bigSphereMaterial);
		bigSphere.rotation.x = THREE.Math.degToRad(-90);
		this._scene.add(bigSphere);

		const torusGeometry = new THREE.TorusGeometry(0.4, 0.1, 32, 32);
		const torusMaterial = new THREE.MeshStandardMaterial({
			color: '#9b59b6',
			roughness: 0.5,
			metalness: 0.9,
		});

		for (let i = 0; i < 8; i++) {
			const torusPivot = new THREE.Object3D();
			const torus = new THREE.Mesh(torusGeometry, torusMaterial);
			torusPivot.rotation.y = THREE.Math.degToRad(45 * i);
			torus.position.set(3, 0.5, 0);
			torusPivot.add(torus);
			this._scene.add(torusPivot);
		}

		const smallSphereGeometry = new THREE.SphereGeometry(0.3, 32, 32);
		const smallSphereMaterial = new THREE.MeshStandardMaterial({
			color: '#e74c3c',
			roughness: 0.2,
			metalness: 0.5,
		});

		const smallSpherePivot = new THREE.Object3D();
		const smallSphere = new THREE.Mesh(smallSphereGeometry, smallSphereMaterial);
		smallSpherePivot.add(smallSphere);
		smallSpherePivot.name = 'smallSpherePivot';
		smallSphere.position.set(3, 0.5, 0);
		this._scene.add(smallSpherePivot);

		// target : ์นด๋ฉ”๋ผ์˜ ์œ„์น˜๋ฅผ ์กฐ์ ˆํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ
		// Object3D๋กœ ์ƒ์„ฑํ–ˆ๊ธฐ๋•Œ๋ฌธ์— ํ™”๋ฉด์ƒ์— ๋ Œ๋”๋ง๋˜์ง€๋Š” ์•Š์ง€๋งŒ scene์˜ ๊ตฌ์„ฑ์š”์†Œ๋กœ ์ž๋ฆฌ์žก๋Š”๋‹ค.
		const targetPivot = new THREE.Object3D();
		const target = new THREE.Object3D();
		targetPivot.add(target);
		targetPivot.name = 'targetPivot';
		target.position.set(3, 0.5, 0);
		this._scene.add(targetPivot);
	}

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

		if (this._camera instanceof THREE.PerspectiveCamera) {
			// PerspectiveCamera
			this._camera.aspect = aspect;
		} else {
			// OrthographicCamera
			this._camera.left = aspect * -1;
			this._camera.right = aspect * 1;
		}

		this._camera.updateProjectionMatrix();

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

	render(time) {
		this._renderer.render(this._scene, this._camera);
		this.update(time);
		requestAnimationFrame(this.render.bind(this));
	}

	update(time) {
		time *= 0.001; // second unit

		const smallSpherePivot = this._scene.getObjectByName('smallSpherePivot');
		if (smallSpherePivot) {
			smallSpherePivot.rotation.y = THREE.Math.degToRad(time * 50);

			// ์นด๋ฉ”๋ผ์˜ ์œ„์น˜๊ฐ€ ์ž‘์€ ๊ตฌ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋„๋ก
			const smallSphere = smallSpherePivot.children[0];
			smallSphere.getWorldPosition(this._camera.position);

			// target์ด ์ž‘์€ ๊ตฌ๋ณด๋‹ค ์•ž์„œ๋„๋ก
			const targetPivot = this._scene.getObjectByName('targetPivot');
			if (targetPivot) {
				targetPivot.rotation.y = THREE.Math.degToRad(time * 50 + 10);

				const target = targetPivot.children[0];
				const pt = new THREE.Vector3();

				target.getWorldPosition(pt);

				// ์นด๋ฉ”๋ผ์˜ ์‹œ์„ ์ด ์ž‘์€ ๊ตฌ์˜ ๋‹ค์Œ ์œ„์น˜(target์˜ ์œ„์น˜)๋ฅผ ํ–ฅํ•˜๋„๋ก
				this._camera.lookAt(pt);
			}

			if (this._light.target) {
				const smallSphere = smallSpherePivot.children[0];
				smallSphere.getWorldPosition(this._light.target.position);

				if (this._lightHelper) {
					this._lightHelper.update();
				}
			}
		}

	}
}

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

 

 

 

๊ทธ๋ฆผ์ž(Shadow)

: Three.js๋Š” ๋™์ ์œผ๋กœ ๊ทธ๋ฆผ์ž๋ฅผ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ํ…์Šค์ณ ๋งตํ•‘์„ ํ†ตํ•ด ๊ทธ๋ฆผ์ž๋ฅผ ์œ„ํ•œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด ํ…์Šค์ณ ๋งตํ•‘ ์ด๋ฏธ์ง€๋ฅผ ์ด์šฉํ•ด ๊ทธ๋ฆผ์ž๋ฅผ ์‹œ๊ฐํ™”ํ•œ๋‹ค.

: Three.js ์—์„œ ๊ทธ๋ฆผ์ž๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Renderer, light, model ๊ฐ์ฒด์˜ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค.

// renderer
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.shadowMap.enabled = true;

// light
const light = new THREE.DirectionalLight(0xffffff, 0.5);
light.castShadow = true;

// model
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.receiveShadow = true;
ground.castShadow = true;

: Three.js ์—์„œ ๊ทธ๋ฆผ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ด‘์›์€ DirectionalLight, PointLight, SpotLight๋‹ค.

๊ทธ๋ฆผ์ž๋ฅผ ์ง€์›ํ•˜๋Š” ๊ด‘์›์€ ๋ชจ๋‘ shadow๋ผ๋Š” ์†์„ฑ์„ ๊ฐ–๊ณ  ์ด shadow ์†์„ฑ์—๋Š” camera ์†์„ฑ์ด ์กด์žฌํ•œ๋‹ค. ์ด camera๊ฐ€ ๊ทธ๋ฆผ์ž์— ๋Œ€ํ•œ ํ…์Šค์ณ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค.

์ด ์นด๋ฉ”๋ผ์˜ ์ ˆ๋‘์ฒด๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๊ฐ์ฒด(๊ทธ๋ฆผ์ž)๋Š” ๋ชจ๋‘ ์ž˜๋ ค๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ๋ฆผ์ž๋ฅผ ์œ„ํ•œ ์นด๋ฉ”๋ผ์˜ ์ ˆ๋‘์ฒด๋ฅผ ์ข€ ๋” ํฌ๊ฒŒ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

: ๊ทธ๋ฆผ์ž๋Š” ํ…์Šค์ณ ๋งตํ•‘ ์ด๋ฏธ์ง€๋ฅผ ์ด์šฉํ•ด ํ‘œํ˜„๋˜๋Š”๋ฐ, ์ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ€๋กœ์™€ ์„ธ๋กœ ํฌ๊ธฐ๊ฐ€ 512๋‹ค. ์ด ํฌ๊ธฐ๋ฅผ ๋” ํฌ๊ฒŒํ•˜๋ฉด ๊ทธ๋ฆผ์ž์˜ ํ’ˆ์งˆ์ด ํ–ฅ์ƒ๋œ๋‹ค.

 

: ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ทธ๋ฆผ์ž์˜ ๊ฒฝ๊ณ„๊ฐ€ ์„ ๋ช…ํ•˜์ง€ ์•Š๊ณ  ๋ธ”๋Ÿฌ๋ง ์ฒ˜๋ฆฌ๊ฐ€ ๋  ํ•„์š”๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋Š” shadow์˜ radius์˜ ๊ฐ’์„ ํ†ตํ•ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

// 08-shadow.js
import * as THREE from '../build/three.module.js';
import {OrbitControls} from '../examples/jsm/controls/OrbitControls.js';
import {RectAreaLightUniformsLib} from '../examples/jsm/lights/RectAreaLightUniformsLib.js';
import {RectAreaLightHelper} from '../examples/jsm/helpers/RectAreaLightHelper.js';

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

		const renderer = new THREE.WebGLRenderer({antialias: true});
		renderer.setPixelRatio(window.devicePixelRatio);
		// ๊ทธ๋ฆผ์ž ๋งต ํ™œ์„ฑํ™”
		renderer.shadowMap.enabled = true;
		divContainer.appendChild(renderer.domElement);
		this._renderer = renderer;

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

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

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

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

	_setupControls() {
		new OrbitControls(this._camera, this._divContainer);
	}

	_setupCamera() {
		const width = this._divContainer.clientWidth;
		const height = this._divContainer.clientHeight;
		const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 100);
		//camera.position.z = 2;
		camera.position.set(7, 7, 0);
		camera.lookAt(0, 0, 0);
		this._camera = camera;
	}

	_setupLight() {
		// ํ™”๋ฉด์„ ๋ฐํžˆ๊ธฐ ์œ„ํ•ด ๊ด‘์› ์ถ”๊ฐ€
		const auxLight = new THREE.DirectionalLight(0xffffff, 0.5);
		auxLight.position.set(0, 5, 0);
		auxLight.target.position.set(0, 0, 0);
		this._scene.add(auxLight.target);
		this._scene.add(auxLight);

		// DirectionalLight
		/* const light = new THREE.DirectionalLight(0xffffff, 0.5);
		light.position.set(0, 5, 0);
		light.target.position.set(0, 0, 0);
		this._scene.add(light.target); */

		// PointLight
		/* const light = new THREE.PointLight(0xffffff, 0.7);
		light.position.set(0, 5, 0); */

		// SpotLight
		const light = new THREE.SpotLight(0xffffff, 0.5);
		light.position.set(0, 5, 0);
		light.target.position.set(0, 0, 0);
		light.angle = THREE.Math.degToRad(30);
		light.penumbra = 0.2;
		this._scene.add(light.target);

		// ๊ทธ๋ฆผ์ž๊ฐ€ ์ž˜๋ฆฌ๋Š” ํ˜„์ƒ ํ•ด๊ฒฐ : ๊ทธ๋ฆผ์ž๋ฅผ ์œ„ํ•œ ์นด๋ฉ”๋ผ์˜ ์ ˆ๋‘์ฒด๋ฅผ ์ข€ ๋” ํฌ๊ฒŒ ํ•ด์คŒ
		light.shadow.camera.top = light.shadow.camera.right = 6;
		light.shadow.camera.bottom = light.shadow.camera.left = -6;

		// ๊ทธ๋ฆผ์ž์˜ ํ’ˆ์งˆ ํ–ฅ์ƒ
		light.shadow.mapSize.width = light.shadow.mapSize.height = 1024;
		// ๊ทธ๋ฆผ์ž์˜ ์™ธ๊ณฝ์„ ๋ธ”๋Ÿฌ๋ง ์ฒ˜๋ฆฌ
		light.shadow.radius = 1;

		const cameraHelper = new THREE.CameraHelper(light.shadow.camera);
		this._scene.add(cameraHelper);

		this._scene.add(light);
		this._light = light;
		// ๊ทธ๋ฆผ์ž ํ™œ์„ฑํ™” ์—ฌ๋ถ€
		light.castShadow = true;
	}

	_setupModel() {
		const groundGeometry = new THREE.PlaneGeometry(10, 10);
		const groundMaterial = new THREE.MeshStandardMaterial({
			color: '#2c3e50',
			roughness: 0.5,
			metalness: 0.5,
			side: THREE.DoubleSide,
		});

		const ground = new THREE.Mesh(groundGeometry, groundMaterial);
		ground.rotation.x = THREE.Math.degToRad(-90);
		// ๊ทธ๋ฆผ์ž๋ฅผ ๋ฐ›์•„์„œ ํ‘œํ˜„ํ• ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€
		ground.receiveShadow = true;
		this._scene.add(ground);

		//const bigSphereGeometry = new THREE.SphereGeometry(1.5, 64, 64, 0, Math.PI);
		const bigSphereGeometry = new THREE.TorusKnotGeometry(1, 0.3, 128, 64, 2, 3);
		const bigSphereMaterial = new THREE.MeshStandardMaterial({
			color: '#ffffff',
			roughness: 0.1,
			metalness: 0.2,
		});

		const bigSphere = new THREE.Mesh(bigSphereGeometry, bigSphereMaterial);
		//bigSphere.rotation.x = THREE.Math.degToRad(-90);
		bigSphere.position.y = 1.6;
		// ๊ทธ๋ฆผ์ž๋ฅผ ๋ฐ›์•„์„œ ํ‘œํ˜„ํ• ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€
		bigSphere.receiveShadow = true;
		// ๊ทธ๋ฆผ์ž๋ฅผ ์ „๋‹ฌํ• ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€
		bigSphere.castShadow = true;
		this._scene.add(bigSphere);

		const torusGeometry = new THREE.TorusGeometry(0.4, 0.1, 32, 32);
		const torusMaterial = new THREE.MeshStandardMaterial({
			color: '#9b59b6',
			roughness: 0.5,
			metalness: 0.9,
		});

		for (let i = 0; i < 8; i++) {
			const torusPivot = new THREE.Object3D();
			const torus = new THREE.Mesh(torusGeometry, torusMaterial);
			torusPivot.rotation.y = THREE.Math.degToRad(45 * i);
			torus.position.set(3, 0.5, 0);
			torus.receiveShadow = true;
			torus.castShadow = true;
			torusPivot.add(torus);
			this._scene.add(torusPivot);
		}

		const smallSphereGeometry = new THREE.SphereGeometry(0.3, 32, 32);
		const smallSphereMaterial = new THREE.MeshStandardMaterial({
			color: '#e74c3c',
			roughness: 0.2,
			metalness: 0.5,
		});

		const smallSpherePivot = new THREE.Object3D();
		const smallSphere = new THREE.Mesh(smallSphereGeometry, smallSphereMaterial);
		smallSpherePivot.add(smallSphere)
		smallSpherePivot.name = 'smallSpherePivot';
		smallSphere.position.set(3, 0.5, 0);
		this._scene.add(smallSpherePivot);
	}

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

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

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

	render(time) {
		this._renderer.render(this._scene, this._camera);
		this.update(time);
		requestAnimationFrame(this.render.bind(this));
	}

	update(time) {
		time *= 0.001; // second unit

		const smallSpherePivot = this._scene.getObjectByName('smallSpherePivot');
		if (smallSpherePivot) {
			smallSpherePivot.rotation.y = THREE.Math.degToRad(time * 50);

			if (this._light.target) {
				const smallSphere = smallSpherePivot.children[0];
				smallSphere.getWorldPosition(this._light.target.position);

				if (this._lightHelper) {
					this._lightHelper.update();
				}
			}

			// PointLight
			if (this._light instanceof THREE.PointLight) {
				const smallSphere = smallSpherePivot.children[0];
				smallSphere.getWorldPosition(this._light.position);
			}
		}
	}
}

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

 

 

 

 

 

์ €์ž‘์žํ‘œ์‹œ
    'note' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [์ œ์ฃผ์ฝ”๋”ฉ๋ฒ ์ด์Šค์บ ํ”„] JavaScript 2๋ถ€
    • [์ œ์ฃผ์ฝ”๋”ฉ๋ฒ ์ด์Šค์บ ํ”„] JavaScript 1๋ถ€
    • [Three.js] GIS Developer ๋‹˜์˜ Three.js ๊ฐ•์ขŒ - 4
    • [Three.js] GIS Developer ๋‹˜์˜ Three.js ๊ฐ•์ขŒ - 3
    66651
    66651
    always awake

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”