--- id: wiki-2026-0508-buffergeometry title: BufferGeometry category: 10_Wiki/Topics status: verified canonical_id: self aliases: [P-Reinforce-AUTO-2887C6, Three.js BufferGeometry] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [graphics, threejs, webgl, performance] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: javascript framework: three.js --- # BufferGeometry ## 매 한 줄 > **"매 Three.js 의 GPU-resident geometry container — 매 modern Three 의 only geometry class."**. BufferGeometry 는 typed-array 기반 attribute (position, normal, uv, index) 의 GPU upload 를 직접 관리하며, 매 Geometry class deprecation (r125) 이후 표준 — instancing/batching/morph 의 backbone. ## 매 핵심 ### 매 Attribute - **Position** (Float32Array, itemSize=3): vertex coords. - **Normal** (Float32Array, itemSize=3). - **UV** (Float32Array, itemSize=2). - **Index** (Uint16/Uint32Array): triangle list. - **Custom**: any vertex attribute (color, tangent, instance data). ### 매 Update Strategy - **Static**: upload once, never modify (default). - **Dynamic** (`setUsage(DynamicDrawUsage)`): frequent CPU update. - **Stream**: per-frame update (rare). ### 매 응용 1. Custom shaders with custom attributes. 2. GPU instancing (InstancedBufferAttribute). 3. Procedural geometry generation. 4. Mesh deformation / morphing. 5. GPGPU particle systems. ## 💻 패턴 ### Manual Triangle ```javascript import * as THREE from "three"; const geo = new THREE.BufferGeometry(); const positions = new Float32Array([ 0, 1, 0, -1, -1, 0, 1, -1, 0, ]); geo.setAttribute("position", new THREE.BufferAttribute(positions, 3)); geo.computeVertexNormals(); ``` ### Indexed Quad ```javascript const positions = new Float32Array([-1,-1,0, 1,-1,0, 1,1,0, -1,1,0]); const indices = new Uint16Array([0, 1, 2, 0, 2, 3]); const geo = new THREE.BufferGeometry(); geo.setAttribute("position", new THREE.BufferAttribute(positions, 3)); geo.setIndex(new THREE.BufferAttribute(indices, 1)); ``` ### Dynamic Vertex Update ```javascript const attr = geo.attributes.position; attr.setUsage(THREE.DynamicDrawUsage); function tick(t) { for (let i = 0; i < attr.count; i++) { attr.setY(i, Math.sin(t + i * 0.1)); } attr.needsUpdate = true; } ``` ### Custom Shader Attribute ```javascript const aRandom = new Float32Array(geo.attributes.position.count); for (let i = 0; i < aRandom.length; i++) aRandom[i] = Math.random(); geo.setAttribute("aRandom", new THREE.BufferAttribute(aRandom, 1)); const mat = new THREE.ShaderMaterial({ vertexShader: `attribute float aRandom; varying float vR; void main(){ vR=aRandom; gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.); }`, fragmentShader: `varying float vR; void main(){ gl_FragColor=vec4(vR,vR,vR,1.); }`, }); ``` ### Instanced Attribute ```javascript const N = 10000; const offsets = new Float32Array(N * 3); for (let i = 0; i < N; i++) { offsets[i*3] = (Math.random()-0.5)*100; offsets[i*3+1] = (Math.random()-0.5)*100; offsets[i*3+2] = (Math.random()-0.5)*100; } const igeo = new THREE.InstancedBufferGeometry().copy(geo); igeo.instanceCount = N; igeo.setAttribute("aOffset", new THREE.InstancedBufferAttribute(offsets, 3)); ``` ### Merge Geometries ```javascript import { mergeGeometries } from "three/addons/utils/BufferGeometryUtils.js"; const merged = mergeGeometries([geoA, geoB, geoC], false); // single draw call instead of three ``` ### Bounding Volume Recompute ```javascript geo.computeBoundingBox(); geo.computeBoundingSphere(); // required for frustum culling after vertex moves ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Static mesh | StaticDrawUsage (default) | | Per-frame deform | DynamicDrawUsage + needsUpdate | | Many copies | InstancedBufferGeometry | | Many distinct meshes | mergeGeometries or BatchedMesh | | Massive points | BufferGeometry + Points + custom shader | **기본값**: static indexed BufferGeometry; switch to instanced/merged for >100 copies. ## 🔗 Graph - 부모: [[Three.js]] - 변형: [[BatchedMesh]] - Adjacent: [[BufferAttribute]] ## 🤖 LLM 활용 **언제**: generate procedural geometry boilerplate, debug attribute layout. **언제 X**: micro-optimization of custom shaders without profiling. ## ❌ 안티패턴 - **Forgetting `needsUpdate = true`**: GPU never re-uploads. - **Recreating BufferGeometry per frame**: GC pressure — mutate in place. - **Float32 indices**: not supported — use Uint16/Uint32. - **No bounding sphere recompute**: frustum-culled erroneously after deform. ## 🧪 검증 / 중복 - Verified (three.js r170 docs, threejs-journey). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — attributes, dynamic update, instancing patterns |