본문 바로가기

Three.js

Three.js 한 눈에 보는 Geometry 종류

선행학습

본 Three.js 시리즈는 Node.js에 기반한 코드를 다룹니다. mesh 객체를 화면에 나오게 하는 것 까지는 다음 글에서 참고해주세요.

CONTENTS

이번 글에서 다룰 내용은 Three.js 개발시에 활용 가능한 Geometry(도형)의 모양에 관한 것으로, 공식 문서에서 제시된 코드를 요약된 라이브러리 설명문서 형식으로 기술할 예정입니다.

  1. BoxGeometry 박스
  2. PlaneGeometry 평면
  3. CircleGeometry 원
  4. ConeGeometry 원뿔
  5. CylinderGeometry 실린더
  6. RingGeometry 평면 링
  7. TorusGeometry 도넛 - 토러스
  8. TorusKnotGeometry 매듭 있는 토러스
  9. DodecahedronGeometry 십이면체
  10. OctahedronGeometry 팔면체
  11. TetrahedronGeometry 사면체
  12. IcosahedronGeometry 정십이면체
  13. SphereGeometry 구
  14. ShapeGeometry 사용자 지정 한면 다각형
  15. TubeGeometry 튜브
  16. ExtrudeGeometry 돌출된 형상
  17. LatheGeometry 축회전 형상
  18. BufferGeometry 사용자 지오메트리
  19. TextGeometry 3D 텍스트 객체
  20. [참고] Three.js 도형을 wireframe으로 보기

 


Three.js Geometry 종류와 기본 사용법

1. BoxGeometry 박스

 

const geometry = new THREE.BoxGeometry( 1, 1, 1 ); 
// width(x축 평행 모서리), 기본값 1
// height(y축 평행 모서리), 기본값 1
// dept(z축 평행 모서리), 기본값 1
// (옵션) widthSegments, 기본값 1
// (옵션) heightSegments, 기본값 1
// (옵션) depthSetments, 기본값 1

const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); 
const cube = new THREE.Mesh( geometry, material ); 
scene.add( cube );

 

2. PlaneGeometry 평면

 

const geometry = new THREE.PlaneGeometry( 1, 1 );
// width - x축 
// height - y축 
// (옵션) widthSegments x축 세그먼트 수
// (옵션) heightSegments y축 세그먼트 수

const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
const plane = new THREE.Mesh( geometry, material );
scene.add( plane );

 

3. CircleGeometry 원

 

const geometry = new THREE.CircleGeometry( 5, 32 );
// radius 원의 반지름, 기본값 1
// segments 세그먼트 수. 최소값 3, 기본값 32
// (옵션) thetaStart 첫 세그먼트의 각도 시작점, 기본값 0 (3시 위치)
// (옵션) thetaLength 원형 섹터의 중심 각도(=세타). 기본값은 2*Pi 

const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const circle = new THREE.Mesh( geometry, material );
scene.add( circle );


4. ConeGeometry 원뿔

 

const geometry = new THREE.ConeGeometry( 5, 20, 32 );
// radius 원뿔 밑면 반지름, 기본값 1
// height 원뿔 높이, 기본값 1

// radialSegments — 원뿔 둘레 주변의 분할된 면의 수. 기본값 32
// heightSegments — 원뿔 높이를 따라 있는 면의 행 수. 기본값 1

// (옵션) openEnded — 밑면 열림 여부 bool. 기본값 false(닫힘)
// (옵션) thetaStart — 첫 번째 세그먼트 시작 각도, 기본값 0(3시 위치)
// (옵션) thetaLength — 원형 섹터의 중심 각도(=세타). 기본값 2*Pi

const material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
const cone = new THREE.Mesh( geometry, material );
scene.add( cone );


5. CylinderGeometry 실린더

 

const geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 );
// radiusTop 상단 원통 반지름. 기본값 1
// radiusBottom 바닥 원통 반지름. 기본값 1
// height 실린더 높이. 기본값 1

// radialSegments 원주 주위의 분할된 면의 수. 기본값 32
// heightSegments — 원통 높이를 따라 있는 면의 행 수. 기본값 1

// openEnded — 밑면 열림 여부 bool. 기본값 false(닫힘)
// thetaStart — 첫 번째 세그먼트 시작 각도, 기본값 0(3시 위치)
// thetaLength — 원형 섹터의 중심 각도(=세타). 기본값 2*Pi

const material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
const cylinder = new THREE.Mesh( geometry, material );
scene.add( cylinder );


6. RingGeometry 평면 링

 

const geometry = new THREE.RingGeometry( 1, 5, 32 );
// innerRadius 내반지름. 기본값 0.5
// outerRadius 외반지름. 기본값 1

// thetaSegments 원둘레 모서리 수. 최소값 3. 기본값 32(숫자가 클수록 링이 둥글어짐)
// phiSegments 모서리 내 면분할 횟수. 최소값 1. 기본값 1

// thetaStart 시작 각도. 기본값 0
// thetaLength 중심 각도. 기본값 Math.PI * 2

const material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );


7. TorusGeometry 도넛 - 토러스

 

const geometry = new THREE.TorusGeometry( 10, 3, 16, 100 );
// radius - 전체 중심에서 튜브 중심까지의 반경. 기본값 1
// tube — 튜브의 반경. 기본값 0.4
// radialSegments — 튜브 둘레를 따라 분할된 면수. 기본값 12
// tubularSegments — 원둘레를 따라 분할된 (모서리) 면수. 기본값 48
// arc — 중심 각도. 기본값 Math.PI * 2. 숫자 줄이면 도넛이 잘린다.

const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const torus = new THREE.Mesh( geometry, material );
scene.add( torus );


8. TorusKnotGeometry 매듭 있는 토러스

 

const geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 );
// radius - 도넛 모양의 반경. 기본값 1
// tube — 큐브의 반경. 기본값 0.4

// tubularSegments — 원둘레(모서리) 분할 면수. 기본값 64
// radialSegments — 튜브 둘레 분할 면수. 기본값 8

// p — 형상이 회전 대칭 축 주위를 감는 횟수. 기본값 2 -> 긴로프 정리하느라 감아둘 때처럼 감김
// q — 형상이 도넛 모양 내부의 원 주위를 감는 횟수. 기본값 3 -> 많이 감으면 용수철됨


const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const torusKnot = new THREE.Mesh( geometry, material );
scene.add( torusKnot );


9. DodecahedronGeometry 십이면체

 

const geometry = new THREE.DodecahedronGeometry(10, 0)
// radius 반지름. 기본값 1
// detail 정점의 수. 기본값 0. 0보다 커지면 더이상 12면체가 아니게 됨. 구가 됨.

 


10. OctahedronGeometry 팔면체

 

const geometry = new THREE.OctahedronGeometry(10, 0)
// radius 반지름. 기본값 1
// detail 정점의 수. 기본값 0. 0보다 커지면 더이상 8면체가 아니게 됨. 구가 됨.


11. TetrahedronGeometry 사면체

 

const geometry = new THREE.TetrahedronGeometry(10, 0)
// radius 반지름. 기본값 1
// detail 정점의 수. 기본값 0. 0보다 커지면 더이상 4면체가 아니게 됨. 구가 됨.

 


12. IcosahedronGeometry 정십이면체

 

const geometry = new THREE.IcosahedronGeometry(10, 0)
// radius 반지름. 기본값 1
// detail 정점의 수. 기본값 0. 0보다 커지면 더이상 20면체가 아니게 됨. 구가 됨.


13. SphereGeometry 구

 

const geometry = new THREE.SphereGeometry( 15, 32, 16 );
// radius — 구 반지름. Default is 1.

// widthSegments — 수평 세그먼트의 수. 최소값 3, 기본값 32(오렌지 껍질 세로썰기 수)
// heightSegments — 수직 세그먼트의 수. 최소값 2, 기본값 16(세로썰기 내 면 분할수)

// phiStart — 수평 시작 각도. 기본값 0
// phiLength — 수평 스위프 각도 크기. 기본값 Math.PI * 2. Y축 기준 반구만들때 사용
// thetaStart — 수직 시작 각도. 기본값 0
// thetaLength — 수직 스위프 각도 크기. 기본값 Math.PI. Z축 기준 반구만들때 사용

const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );


14. ShapeGeometry 사용자 한면 다각형

 

const heartShape = new THREE.Shape();

const x = 0, y = 0;
heartShape.moveTo( x + 5, y + 5 );
heartShape.bezierCurveTo( x + 5, y + 5, x + 4, y, x, y );
heartShape.bezierCurveTo( x - 6, y, x - 6, y + 7,x - 6, y + 7 );
heartShape.bezierCurveTo( x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19 );
heartShape.bezierCurveTo( x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7 );
heartShape.bezierCurveTo( x + 16, y + 7, x + 16, y, x + 10, y );
heartShape.bezierCurveTo( x + 7, y, x + 5, y + 5, x + 5, y + 5 );

const geometry = new THREE.ShapeGeometry( heartShape );
// shapes 모양 array 또는 단일 shape 객체
// curveSegments 분할 세그먼트 수. 기본값 12

const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );


15. TubeGeometry 튜브

 

class CustomSinCurve extends THREE.Curve {
	constructor( scale = 1 ) {
		super();
		this.scale = scale;
	}
	getPoint( t, optionalTarget = new THREE.Vector3() ) {
		const tx = t * 3 - 1.5;
		const ty = Math.sin( 2 * Math.PI * t );
		const tz = 0;
		return optionalTarget.set( tx, ty, tz ).multiplyScalar( this.scale );
	}
}
const path = new CustomSinCurve( 10 );

const geometry = new THREE.TubeGeometry( path, 20, 2, 8, false );
// path — Curve 기본 클래스 에서 상속되는 3D 경로. 기본값은 2차 베지어 곡선
// tubularSegments — 튜브 세그먼트 수. 기본값 64
// radius — Float - 튜브 반지름. 기본값 1
// radialSegments — Integer - 횡단면을 구성하는 세그먼트의 수. 기본값 8
// closed — Boolean 튜브가 닫혀 있는지 여부. 기본값 false

const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );


16. ExtrudeGeometry 돌출된 형상

- 경로나 모양에서 돌출된 형상을 만듭니다(2D 면 -> 3D돌출). 면과 돌출된 면에 별도의 재질을 사용하려는 경우 여러 재질을 사용할 수 있습니다. 첫 번째 재질이 얼굴에 적용됩니다. 두 번째 재료는 측면에 적용됩니다.

 

 

const length = 12, width = 8;

const shape = new THREE.Shape();
shape.moveTo( 0,0 );
shape.lineTo( 0, width );
shape.lineTo( length, width );
shape.lineTo( length, 0 );
shape.lineTo( 0, 0 );

const extrudeSettings = {
    curveSegments: 12, //곡선 점 수. 기본값 12
	steps: 2, // 돌출된 스플라인의 깊이를 따라 세그먼트를 세분화하는 점 수. 기본값 1 
	depth: 16.0, // 돌출 깊이. 기본값 1
	bevelEnabled: true, // 모양에 bevel 적용할건지. 기본값 true
	bevelThickness: 1, // 베벨 높이. 기본값 0.2
	bevelSize: 1, // 베벨 크기. 기본값 0.1. 숫자 커질수록 객체 덩치가 커짐
	bevelOffset: 0, // 베벨 경사 시작점과 모양 윤곽선 간의 거리. 기본값 0
	bevelSegments: 1, // 베벨면의 분할 수. 기본값 3
    // extrudePath - THREE.Curve. 돌출시 따라갈 3D 스플라인 경로. 경로설정시 베벨 X.
    // UVGenerator - Object. UV 제너레이터 기능을 제공하는 객체
};

const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
// shape 모양 | 모양 배열
// options 매개변수 객체

const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );

 


17. LatheGeometry 축대칭 형상

- 축 대칭으로 메쉬 만드는 지오메트리. Y축으로 회전함

 

 

const points = [];
for ( let i = 0; i < 10; i ++ ) {
	points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
}

const geometry = new THREE.LatheGeometry( points );
// points — Vector2 배열. 각 점의 x 좌표는 0보다 커야 함. 기본값 단순한 다이아몬드 모양을 만드는 (0,-0.5), (0.5,0) 및 (0,0.5)의 배열
// segments — 원주 세그먼트 수. 기본값 12
// phiStart — 회전 시작 각도(라디안 단위). 기본값 0
// phiLength — 회전값. 라디안(0 ~ 2PI). 기본값 2PI(닫힌 선반)

const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const lathe = new THREE.Mesh( geometry, material );
scene.add( lathe );


18. BufferGeometry 사용자 지오메트리

- 사용자가 직접 꼭짓점(Vertices)을 지정하여 Geometry를 만들 때 사용. 각 점들의 x, y, z 좌표값은 Float32Array 인스턴스에 넣어 전달한다.

 

// < 커스텀 segment 1개 만들기 >
// 빈 인스턴스 생성
const geometry = new THREE.BufferGeometry();

// 꼭지점들 좌표값 입력
const vertices = new Float32Array([
    1.0, 1.0, 1.0, // 첫번째 점의 x, y, z
   -1.0, 1.0, 1.0, // 두번째 점의 x, y, z
   -1.0,-1.0, 1.0  // 세번째 점의 x, y, z
])

// 배열값 3개가 1개 점의 좌표를 나타내므로 두번째 매개변수에 3을 씀
// 생성해둔 geometry를 옮겨가면서 말뚝 심는 모양새
geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );

const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
const mesh = new THREE.Mesh( geometry, material );

 

19. TextGeometry 3D 텍스트 객체

import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';

const loader = new FontLoader();
loader.load( 'fonts/helvetiker_regular.typeface.json', function ( font ) {
	const geometry = new TextGeometry( 'Hello three.js!', {
		font: font, // THREE.font 폰트
		size: 80, // 사이즈. 기본값 100
		height: 5, // Extrude 두께. 기본값 50 
		curveSegments: 12, // 커브의 점수. 기본값 12
		bevelEnabled: true, // 베벨 적용 여부. 기본값 false
		bevelThickness: 10, // 베벨 두께. 기본값 10
		bevelSize: 8, // 베벨 사이즈. 기본값 8. 객체 전체 덩치가 커짐
		bevelOffset: 0, // 객체 외곽선으로부터 베벨 시작점까지 거리. 기본값 0
		bevelSegments: 5 // 베벨 구간의 면 나눔 수. 기본값 3
	} );
} );

 

20. [참고] Three.js 도형을 Wireframe으로 보기

- 위 지오메트리들을 화면상에 띄울 때 material 인스턴스에 아래와 같이 'wireframe: true'를 넣어주면 도형을 이루는 구조선들만 보이게 된다.

 

const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })