박철순
Three.js 지오메트리(Geometry) #2 본문
https://threejs.org/manual/#ko/primitives을 통해 다양한 형태를 확인할 수 있습니다.
* https://threejs.org/manual/#ko/custom-buffergeometry 사용자 지정 Geometry
* 이 글 또한 Youtube. GIS DEVELOPER 님의 영상을 보고, 공부한 부분을 적어둔 내용입니다.
#1 ShapeGeometry()
Shape() 메소드를 통해 선을 그릴 수 있습니다.
canvas의 라인그리는 원리랑 똑같이, moveTo(x, y)로 원하는 좌표에서 시작을 하고,
lineTo(x,y)로 해당 좌표까지 이동하여 선을 그린 뒤, 모든 작업이 끝났으면 ClosePath()로 그리는 것을 멈추면 됩니다.
_setupModel() {
const shape = new THREE.Shape();
shape.moveTo(1, 1);
shape.lineTo(1, -1);
shape.lineTo(-1, -1);
shape.lineTo(-1, 1);
shape.closePath();
const geometry = new THREE.BufferGeometry();
const points = shape.getPoints();
geometry.setFromPoints(points);
/* const geometry = new THREE.ShapeGeometry(shape);
const fillMaterial = new THREE.MeshPhongMaterial({ color: 0x515151 });
const cube = new THREE.Mesh(geometry, fillMaterial);
면 채워진 Shape
*/
const material = new THREE.LineBasicMaterial({ color: 0xffff00 });
const line = new THREE.Line(geometry, material);
this._scene.add(line);
}
곡선을 그릴 때는 bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)를 통해 그리시면 됩니다.
cp1x,cp1y는 첫 번째 제어점, cp2x,cp2y는 두 번째 제어점, 마지막 x,y는 점.
* 자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo
Adobe Illustrator의 펜툴 쓰는 법과 유사합니다.
#2 TubeGeometry()
TubeGeometry(커브경로,큐브의 진행 방향 분할 수 46,원통의 반지름 크기 1, 원통에 대한 분할 수 8, 밑,윗면 유무 false)
_setupModel() {
class CustomSinCurve extends THREE.Curve {
constructor(scale) {
super();
this.scale = scale;
}
getPoint(t) {
const tx = t * 3 - 1.5;
const ty = Math.sin(2 * Math.PI * t);
const tz = 0;
return new THREE.Vector3(tx, ty, tz).multiplyScalar(this.scale);
}
}
const path = new CustomSinCurve(4);
const geometry = new THREE.TubeGeometry(path, 10);
const fillMaterial = new THREE.MeshPhongMaterial({ color: 0x515151 });
const cube = new THREE.Mesh(geometry, fillMaterial);
const lineMeterial = new THREE.LineBasicMaterial({ color: 0xffff00 });
const line = new THREE.LineSegments(
new THREE.WireframeGeometry(geometry),
lineMeterial
);
const group = new THREE.Group();
group.add(cube);
group.add(line);
this._scene.add(group);
this._cube = group;
}
#3 LathGeometry()
LathGeometry(회전 시킬 좌표, 분할수 12,원통의 반지름 크기 1, 시작각도 0, 연장각도 2𝝅)
첫번째 인자의 회전 시킬 좌표값으로 회전된 형태를 반환함. 분할수가 높을수록 원에 가깝다.
_setupModel() {
const points = [];
for (let i = 0; i < 10; i++) {
points.push(new THREE.Vector2(Math.sin(i * 0.2) * 3 + 3, (i - 5) * 0.8));
}
const geometry = new THREE.LatheGeometry(points);
const fillMaterial = new THREE.MeshPhongMaterial({ color: 0x515151 });
const cube = new THREE.Mesh(geometry, fillMaterial);
const lineMeterial = new THREE.LineBasicMaterial({ color: 0xffff00 });
const line = new THREE.LineSegments(
new THREE.WireframeGeometry(geometry),
lineMeterial
);
const group = new THREE.Group();
group.add(cube);
group.add(line);
this._scene.add(group);
this._cube = group;
}
#4 ExtrudeGeometry()
평면 Shape에 깊이값을 부여해주고, Mesh에 윗면과 밑면을 비스듬하게 처리해줌. (beveling)
ExtrudeGeometry(어떤선을 쓸 지(shape), 설정값(settings))
설정값(Settings) -
steps : 깊이 방향의 분할 수
depath : 깊이 값
bevelEnabled : beveling 처리를 할 지 유무값
bevelThickness : beveling 두께값
bevelSize : shape의 외곽선으로 부터 얼마나 멀리 beveling
bevelSegments : beveling 단계수
_setupModel() {
const shape = new THREE.Shape();
const x = -2.5;
const y = -5;
shape.moveTo(x + 2.5, y + 2.5);
shape.bezierCurveTo(x + 2.5, y + 2.5, x + 2, y, x, y);
shape.bezierCurveTo(x - 3, y, x - 3, y + 3.5, x - 3, y + 3.5);
shape.bezierCurveTo(x - 3, y + 5.5, x - 1.5, y + 7.7, x + 2.5, y + 9.5);
shape.bezierCurveTo(x + 6, y + 7.7, x + 8, y + 4.5, x + 8, y + 3.5);
shape.bezierCurveTo(x + 8, y + 3.5, x + 8, y, x + 5, y);
shape.bezierCurveTo(x + 3.5, y, x + 2.5, y + 2.5, x + 2.5, y + 2.5);
const extrudeSettings = {
steps: 2, // ui: steps
depth: 4, // ui: depth
bevelEnabled: true, // ui: bevelEnabled
bevelThickness: 2, // ui: bevelThickness
bevelSize: 1, // ui: bevelSize
bevelSegments: 5, // ui: bevelSegments
};
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const fillMaterial = new THREE.MeshPhongMaterial({ color: 0x515151 });
const cube = new THREE.Mesh(geometry, fillMaterial);
const lineMeterial = new THREE.LineBasicMaterial({ color: 0xffff00 });
const line = new THREE.LineSegments(
new THREE.WireframeGeometry(geometry),
lineMeterial
);
#5 TextGeometry()
해당 메소드는 .ttf 와 같은 폰트 데이터를 three.js 에서 사용 할 수 있는 포맷으로 변경해서 사용해야함. (형식은 JSON)
인터넷을 통해 변환이 가능.
폰트를 사용하기 위해서는 new Three.FontLoader() 클래스를 사용 한 후, 비동기 함수로 호출해야함.
TextGeometry(3차원 매쉬로 생성할 텍스트값, 설정값(Object))
설정값(Settings) -
font : load를 통해 불러온 font 데이터
size : textMesh의 크기
height : 깊이값 (두께)
curveSegments : 하나의 커브를 구성하는 점의 갯수
bevelEnabled : beveling 처리를 할 지 유무값
bevelThickness : beveling 두께값
bevelSize : shape의 외곽선으로 부터 얼마나 멀리 beveling
bevelSegments : beveling 단계수
_setupModel() {
const fontLoader = new FontLoader();
async function loadFont(that) {
const url = "../../examples/fonts/helvetiker_regular.typeface.json";
const font = await new Promise((resolve, reject) => {
fontLoader.load(url, resolve, undefined, reject);
});
const geometry = new TextGeometry("GIS", {
font: font,
size: 10, // ui: size
height: 5, // ui: height
curveSegments: 12, // ui: curveSegments
bevelEnabled: true, // ui: bevelEnabled
bevelThickness: 0.15, // ui: bevelThickness
bevelSize: 0.3, // ui: bevelSize
bevelSegments: 5, // ui: bevelSegments
});
const fillMaterial = new THREE.MeshPhongMaterial({ color: 0x515151 });
const cube = new THREE.Mesh(geometry, fillMaterial);
const lineMeterial = new THREE.LineBasicMaterial({ color: 0xffff00 });
const line = new THREE.LineSegments(
new THREE.WireframeGeometry(geometry),
lineMeterial
);
const group = new THREE.Group();
group.add(cube);
group.add(line);
that._scene.add(group);
that._cube = group;
}
loadFont(this);
}
'Javascript > three.js' 카테고리의 다른 글
Three.js 재질(material) #1 (0) | 2022.04.16 |
---|---|
Three.js Scene Graph(씬그래프) (0) | 2022.04.15 |
Three.js OrbitControls을 마우스 컨트롤 (0) | 2022.04.13 |
Three.js 지오메트리(Geometry) #1 (0) | 2022.04.13 |
Three.js (0) | 2022.04.13 |