threejs-syntax-geometries について
threejs-syntax-geometriesは、メッシュデータを作成・管理する開発者向けのThree.jsジオメトリリファレンスです。BufferGeometry、属性、組み込み形状、インスタンス化、リソース管理を解説します。
主な機能
- 01BufferGeometryとBufferAttributeのAPI
- 02組み込みジオメトリ一覧
- 03カスタムパスと押し出し
- 04InstancedMeshの使用方法
- 05ジオメトリの更新と破棄
活用シーン
- 01カスタムメッシュの作成
- 02組み込みプリミティブの選択
- 03反復オブジェクトの効率的な描画
- 04頂点データの安全な更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ impertio-studio/ three.js-claude-skill-package --skill threejs-syntax-geometriesインストール後、Claude Code で/threejs-syntax-geometriesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitkeepreferences/anti-patterns.mdexamples.mdmethods.md詳細
threejs-syntax-geometries
クイックリファレンス
BufferGeometry:主なプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
attributes | Object | {} | 名前付きの BufferAttribute インスタンスを格納するハッシュマップ |
index | BufferAttribute | null | null | インデックス付き描画に使用するインデックスバッファ |
morphAttributes | Object | {} | モーフターゲット属性の配列 |
morphTargetsRelative | Boolean | false | true の場合、モーフデータは相対オフセットになります |
groups | Array | [] | 複数マテリアル用の { start, count, materialIndex } |
drawRange | Object | { start: 0, count: Infinity } | 描画するジオメトリの範囲 |
boundingBox | Box3 | null | null | キャッシュされます。computeBoundingBox() を呼び出すまでは null です |
boundingSphere | Sphere | null | null | キャッシュされます。computeBoundingSphere() を呼び出すまでは null です |
BufferGeometry:主なメソッド
| メソッド | 戻り値 | 説明 |
|---|---|---|
setAttribute(name, attr) | this | 名前付き属性を追加または置換します |
getAttribute(name) | BufferAttribute | 名前で属性を取得します |
deleteAttribute(name) | this | 名前付き属性を削除します |
hasAttribute(name) | boolean | 属性が存在するか確認します |
setIndex(attr) | — | インデックスバッファを設定します |
addGroup(start, count, materialIndex?) | — | 複数マテリアル用の描画グループを定義します |
clearGroups() | — | すべてのグループを削除します |
setDrawRange(start, count) | — | 描画範囲を制限します |
computeVertexNormals() | — | 面のトポロジーから滑らかな法線を計算します |
computeTangents() | — | 接線ベクトルを計算します(position、normal、uv、index が必要です) |
computeBoundingBox() | — | AABB を計算してキャッシュします |
computeBoundingSphere() | — | 境界球を計算してキャッシュします |
toNonIndexed() | 新しいジオメトリ | 頂点を複製した非インデックス形式のコピーを作成します |
translate(x, y, z) | this | 頂点の位置をその場で移動します |
rotateX/Y/Z(radians) | this | 頂点の位置をその場で回転します |
scale(x, y, z) | this | 頂点の位置をその場で拡大・縮小します |
center() | this | ジオメトリを原点に配置します |
dispose() | — | GPU リソースを解放します |
BufferAttribute:コンストラクターとプロパティ
import * as THREE from 'three';
new THREE.BufferAttribute(array: TypedArray, itemSize: number, normalized?: boolean)
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
array | TypedArray | — | 基になるデータ |
itemSize | number | — | 頂点ごとの値の数(1=スカラー、2=UV、3=位置、4=RGBA) |
count | number | 計算値 | array.length / itemSize |
needsUpdate | boolean | false | GPU に変更をアップロードするには true に設定します |
usage | number | StaticDrawUsage | GPU 使用方法のヒント |
型付きの便利なクラス
| クラス | 基になる型 | 用途 |
|---|---|---|
Float32BufferAttribute | Float32Array | 位置、法線、UV(最も一般的) |
Float16BufferAttribute | Float16Array | メモリを最適化した属性 |
Uint16BufferAttribute | Uint16Array | インデックスバッファ(頂点数 <65536) |
Uint32BufferAttribute | Uint32Array | インデックスバッファ(頂点数 >65536) |
Uint8BufferAttribute | Uint8Array | バイトカラー(normalized=true を指定) |
Int8/Int16/Int32BufferAttribute | 対応する配列 | 符号付き整数データ |
使用方法のヒント
| 定数 | 使用する場面 |
|---|---|
THREE.StaticDrawUsage | データを一度アップロードし、何度も読み取る場合(デフォルト) |
THREE.DynamicDrawUsage | データを頻繁に更新する場合(パーティクル、アニメーションする頂点) |
THREE.StreamDrawUsage | データを毎フレーム更新し、一度読み取る場合 |
重要な警告
絶対に setX/setXY/setXYZ または配列への直接書き込みで BufferAttribute データを変更した後に、attribute.needsUpdate = true を設定し忘れないでください。このフラグがないと、変更内容は GPU に反映されません。
絶対に boundingBox や boundingSphere が自動的に設定されると思い込まないでください。computeBoundingBox()/computeBoundingSphere() を明示的に呼び出すまで、これらは null です。
ライティングが必要な場合は、カスタムジオメトリの構築後に必ず computeVertexNormals() を呼び出してください。法線がないと、MeshStandardMaterial などのライティングを使うマテリアルは黒く描画されます。
シーンからジオメトリを完全に削除するときは、必ず geometry.dispose() を呼び出してください。破棄しないと GPU メモリがリークします。ガベージコレクターは GPU 側のバッファーを解放しません。
絶対に アニメーションループ内で translate()、rotateX()、scale() などのインプレース変換メソッドを呼び出さないでください。これらは頂点データそのものを永続的に変更します。実行時の変換には mesh.position、mesh.rotation、mesh.scale を使ってください。
毎フレーム属性データを更新する場合は、最初のレンダリングより前に必ず usage を DynamicDrawUsage に設定してください。初回のアップロード後に usage を変更しても、一部の GPU ドライバーでは効果がありません。
InstancedMesh で setMatrixAt() を呼び出した後は、絶対に instanceMatrix.needsUpdate = true を設定し忘れないでください。このフラグがないと、すべてのインスタンスが原点に描画されます。
インデックス付きジオメトリと非インデックス付きジオメトリ
| 項目 | インデックス付き | 非インデックス付き |
|---|---|---|
| メモリ | 少ない(頂点を共有) | 多い(頂点を複製) |
| GPU キャッシュ | 効率が良い(頂点を再利用) | 再利用なし |
| フラットシェーディング | 法線の複製が必要 | 面ごとに自然な法線 |
| ワイヤーフレーム | エッジが明瞭 | 対角線が表示される場合がある |
共有頂点を持つスムーズシェーディングのメッシュには、必ずインデックス付きジオメトリを使ってください。面ごとの属性(固有の法線によるフラットシェーディング)が必要な場合にのみ geometry.toNonIndexed() を使ってください。
組み込みジオメトリ全21種類
プリミティブ
| ジオメトリ | 主なパラメーター |
|---|---|
BoxGeometry | (width=1, height=1, depth=1, wSeg=1, hSeg=1, dSeg=1) |
SphereGeometry | (radius=1, wSeg=32, hSeg=16, phiStart, phiLen, thetaStart, thetaLen) |
PlaneGeometry | (width=1, height=1, wSeg=1, hSeg=1) |
CylinderGeometry | (radTop=1, radBot=1, height=1, radSeg=32, hSeg=1, open, thetaStart, thetaLen) |
ConeGeometry | (radius=1, height=1, radSeg=32, hSeg=1, open, thetaStart, thetaLen) |
CapsuleGeometry | (radius=1, length=1, capSeg=4, radSeg=8) |
TorusGeometry | (radius=1, tube=0.4, radSeg=12, tubSeg=48, arc=2PI) |
TorusKnotGeometry | (radius=1, tube=0.4, tubSeg=64, radSeg=8, p=2, q=3) |
CircleGeometry | (radius=1, seg=32, thetaStart=0, thetaLen=2PI) |
RingGeometry | (inner=0.5, outer=1, thetaSeg=32, phiSeg=1, thetaStart, thetaLen) |
多面体
すべて (radius=1, detail=0) を受け取ります。detail は細分化レベルを指定します。
| ジオメトリ | 基本面数 |
|---|---|
TetrahedronGeometry | 4 |
OctahedronGeometry | 8 |
DodecahedronGeometry | 12 |
IcosahedronGeometry | 20 |
PolyhedronGeometry | カスタム(vertices, indices, radius, detail) |
パスベース
| ジオメトリ | 説明 |
|---|---|
ExtrudeGeometry(shapes, options) | 2D Shape を押し出して 3D にします |
ShapeGeometry(shapes, curveSegments=12) | Shape から平坦な 2D ジオメトリを作成します |
LatheGeometry(points, segments=12, phiStart, phiLength) | 2D プロファイルを Y 軸の周りに回転させます |
TubeGeometry(path, tubSeg=64, radius=1, radSeg=8, closed) | Curve3 に沿ったチューブです |
ユーティリティ
| ジオメトリ | 説明 |
|---|---|
EdgesGeometry(geometry, thresholdAngle=1) | 角度がしきい値を超えるエッジ(輪郭を明瞭に表示) |
WireframeGeometry(geometry) | すべての三角形のエッジ(デバッグ用の可視化) |
ExtrudeGeometry のオプション
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
depth | number | 1 | 押し出しの深さ |
steps | number | 1 | 深さ方向の分割数 |
bevelEnabled | boolean | true | ベベルエッジを有効にします |
bevelThickness | number | 0.2 | 形状内部へのベベルの深さ |
bevelSize | number | bevelThickness - 0.1 | 輪郭からのベベルの距離 |
bevelOffset | number | 0 | エッジからのベベルのオフセット |
bevelSegments | number | 3 | ベベルの解像度 |
curveSegments | number | 12 | 曲線上の点の数 |
extrudePath | Curve | undefined | 押し出しに沿って使用する 3D パス |
UVGenerator | Object | WorldUVGenerator | カスタム UV 生成 |
Shape クラス:2D パスの描画
import * as THREE from 'three';
const shape = new THREE.Shape();
shape.moveTo(x, y); // Start new subpath
shape.lineTo(x, y); // Straight line
shape.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); // Cubic Bezier
shape.quadraticCurveTo(cpx, cpy, x, y); // Quadratic Bezier
shape.splineThru(points); // Smooth spline through Vector2[]
shape.arc(aX, aY, radius, startAngle, endAngle, cw); // Relative arc
shape.absarc(aX, aY, radius, startAngle, endAngle, cw); // Absolute arc
// Holes
const holePath = new THREE.Path();
holePath.absarc(0, 0, 0.5, 0, Math.PI * 2);
shape.holes.push(holePath);
モーフターゲット
import * as THREE from 'three';
// Define morph target positions
const morphPositions = new Float32Array([/* ... */]);
geometry.morphAttributes.position = [
new THREE.BufferAttribute(morphPositions, 3)
];
// Control on the mesh
mesh.morphTargetInfluences[0] = 0.5; // 50% blend toward morph target 0
// Named morph targets (from glTF)
mesh.morphTargetDictionary; // { "smile": 0, "frown": 1 }
モーフデータが絶対位置ではなくオフセットを表す場合は、geometry.morphTargetsRelative = true を設定します。
InstancedMesh
import * as THREE from 'three';
const mesh = new THREE.InstancedMesh(geometry, material, count);
| プロパティ | 型 | 説明 |
|---|---|---|
instanceMatrix | InstancedBufferAttribute | 4x4 行列(インスタンスあたり 16 個の浮動小数点数) |
instanceColor | InstancedBufferAttribute | null | インスタンスごとの RGB(最初の setColorAt 呼び出し時に作成) |
count | number | インスタンス数(構築後は読み取り専用) |
| メソッド | 説明 |
|---|---|
setMatrixAt(index, matrix4) | インスタンスの変換を設定します |
getMatrixAt(index, matrix4) | 変換をターゲットに読み込みます |
setColorAt(index, color) | インスタンスごとの色を設定します |
getColorAt(index, color) | インスタンスごとの色を読み込みます |
パフォーマンスに関するガイドライン
| インスタンス数 | 推奨事項 |
|---|---|
| < 10 | 個別の Mesh オブジェクトを使用します |
| 10 - 100 | どちらの方法でも構いません。使用ケースのパフォーマンスを測定してください |
| 100 - 10,000 | 必ず InstancedMesh を使用してください |
| > 10,000 | 空間分割または BatchedMesh(r160 以降)と併せて InstancedMesh を使用します |
インスタンスごとのカスタム属性
import * as THREE from 'three';
const phases = new Float32Array(count);
for (let i = 0; i < count; i++) phases[i] = Math.random();
mesh.geometry.setAttribute('aPhase', new THREE.InstancedBufferAttribute(phases, 1));
// Access in vertex shader: attribute float aPhase;
グループを使用した複数マテリアル
import * as THREE from 'three';
geometry.addGroup(0, 6, 0); // First 6 indices -> material[0]
geometry.addGroup(6, 6, 1); // Next 6 indices -> material[1]
const mesh = new THREE.Mesh(geometry, [materialA, materialB]);
InterleavedBuffer
大規模なメッシュ(頂点数 10,000 以上)で GPU キャッシュのパフォーマンスを最適化するには:
import * as THREE from 'three';
const stride = 8; // 3 (position) + 3 (normal) + 2 (uv)
const buffer = new THREE.InterleavedBuffer(new Float32Array(vertexCount * stride), stride);
geometry.setAttribute('position', new THREE.InterleavedBufferAttribute(buffer, 3, 0));
geometry.setAttribute('normal', new THREE.InterleavedBufferAttribute(buffer, 3, 3));
geometry.setAttribute('uv', new THREE.InterleavedBufferAttribute(buffer, 2, 6));
個々の属性を独立して更新する場合は、必ず個別のバッファを使用してください。インターリーブドバッファは、すべての属性が静的であるか、まとめて更新される場合にのみ使用してください。
破棄のルール
- シーンからジオメトリを完全に削除するときは、必ず
geometry.dispose()を呼び出してください - 共有ジオメトリ(複数のメッシュで使用):すべてのメッシュを削除した後にのみ破棄してください
- 組み込みジオメトリ:それを使用するメッシュを削除するときに破棄してください
- JavaScript のガベージコレクターは GPU 側の頂点バッファを解放しません
参考リンク
- references/methods.md — BufferGeometry、BufferAttribute、InstancedMesh の API シグネチャー一式
- references/examples.md — カスタムジオメトリ、インスタンシング、押し出しの実用的なコード例
- references/anti-patterns.md — Three.js のジオメトリで避けるべきこと