선행학습
본 Three.js 시리즈는 Node.js에 기반한 코드를 다룹니다. mesh 객체를 화면에 나오게 하는 것 까지는 다음 글에서 참고해주세요.
CONTENTS
이번 글에서 다룰 내용은 Three.js 개발시에 활용 가능한 Geometry(도형)의 모양에 관한 것으로, 공식 문서에서 제시된 코드를 요약된 라이브러리 설명문서 형식으로 기술할 예정입니다.
- BoxGeometry 박스
- PlaneGeometry 평면
- CircleGeometry 원
- ConeGeometry 원뿔
- CylinderGeometry 실린더
- RingGeometry 평면 링
- TorusGeometry 도넛 - 토러스
- TorusKnotGeometry 매듭 있는 토러스
- DodecahedronGeometry 십이면체
- OctahedronGeometry 팔면체
- TetrahedronGeometry 사면체
- IcosahedronGeometry 정십이면체
- SphereGeometry 구
- ShapeGeometry 사용자 지정 한면 다각형
- TubeGeometry 튜브
- ExtrudeGeometry 돌출된 형상
- LatheGeometry 축회전 형상
- BufferGeometry 사용자 지오메트리
- TextGeometry 3D 텍스트 객체
- [참고] 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 사용자 한면 다각형
- 바로가기: https://threejs.org/docs/#api/ko/geometries/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 })
'Three.js' 카테고리의 다른 글
Three.js 객체의 이동, 리사이즈, 회전 | position, scale, rotation (0) | 2023.12.22 |
---|---|
Three.js 반응형 canvas + 전체화면 만들기 (0) | 2023.12.20 |
Node.js로 Three.js 시작하기 (0) | 2023.12.19 |