--- id: wiki-2026-0508-webgl-multi-draw title: WEBGL_multi_draw Extension category: 10_Wiki/Topics status: verified canonical_id: self aliases: [WEBGL_multi_draw, multi-draw, multiDrawArrays] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [webgl, graphics, performance, draw-call, frontend] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: JavaScript framework: WebGL 1.0/2.0 --- # WEBGL_multi_draw Extension ## 매 한 줄 > **"매 한 번의 JS→GL 호출로 매 수백 개 draw 를 batched 처리하는 매 WebGL 확장"**. 매 `gl.drawArrays` 의 매 N 회 호출을 매 `multiDrawArraysWEBGL` 한 번으로 줄여 매 CPU↔GPU command overhead 를 매 결정적으로 감소시킨다. 매 2026 기준 Chromium / Firefox / Safari 모두 매 안정 지원. ## 매 핵심 ### 매 정의 - 매 KhronosGroup WebGL extension. - 매 OpenGL `glMultiDrawArrays` / `glMultiDrawElements` 의 매 WebGL 매핑. - 매 WebGL 1 / WebGL 2 양쪽 매 사용 가능. ### 매 4 개 함수 - `multiDrawArraysWEBGL(mode, firsts, firstsOffset, counts, countsOffset, drawcount)` - `multiDrawElementsWEBGL(mode, counts, countsOffset, type, offsets, offsetsOffset, drawcount)` - `multiDrawArraysInstancedWEBGL(...)` - `multiDrawElementsInstancedWEBGL(...)` ### 매 응용 1. 매 Particle / sprite batching. 2. 매 Tile-based map rendering. 3. 매 CesiumJS, deck.gl 의 large-scale geo viz. ## 💻 패턴 ### Extension 활성화 ```javascript const gl = canvas.getContext('webgl2'); const ext = gl.getExtension('WEBGL_multi_draw'); if (!ext) throw new Error('WEBGL_multi_draw not supported'); ``` ### multiDrawArrays 기본 ```javascript const drawcount = 1000; const firsts = new Int32Array(drawcount); const counts = new Int32Array(drawcount); for (let i = 0; i < drawcount; i++) { firsts[i] = i * 6; counts[i] = 6; // 6 vertices per quad } ext.multiDrawArraysWEBGL( gl.TRIANGLES, firsts, 0, counts, 0, drawcount ); ``` ### multiDrawElementsInstanced ```javascript ext.multiDrawElementsInstancedWEBGL( gl.TRIANGLES, countsArr, 0, gl.UNSIGNED_SHORT, offsetsArr, 0, instanceCountsArr, 0, drawcount ); ``` ### gl_DrawID 사용 (vertex shader) ```glsl #version 300 es #extension GL_ANGLE_multi_draw : require in vec3 a_position; uniform mat4 u_mvps[256]; void main() { gl_Position = u_mvps[gl_DrawID] * vec4(a_position, 1.0); } ``` ### Polyfill fallback ```javascript function multiDraw(gl, ext, mode, firsts, counts, drawcount) { if (ext) { ext.multiDrawArraysWEBGL(mode, firsts, 0, counts, 0, drawcount); } else { for (let i = 0; i < drawcount; i++) { gl.drawArrays(mode, firsts[i], counts[i]); } } } ``` ### Benchmark guideline ```javascript const t0 = performance.now(); ext.multiDrawArraysWEBGL(gl.TRIANGLES, firsts, 0, counts, 0, drawcount); gl.finish(); console.log('multidraw ms:', performance.now() - t0); // expect 5-50× speedup vs naive loop on draw-call-bound scenes ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Draw call > 100/frame | multi_draw 적용 | | Same shader/state 반복 | 매 매 효과 큼 | | 적은 large draw | 매 효과 미미 — instancing 만으로 충분 | | Indirect 필요 | WebGPU 으로 이동 | **기본값**: WebGL 환경에서 매 draw call bound 면 매 1순위 최적화. ## 🔗 Graph - 부모: [[WebGL 20]] · [[WebGL]] - 변형: [[Instanced Rendering]] - 응용: [[CesiumJS]] - Adjacent: [[WebGPU]] · [[Draw Call Optimization]] ## 🤖 LLM 활용 **언제**: 매 batch boilerplate 생성, 매 fallback path 작성. **언제 X**: 매 shader 의 매 `gl_DrawID` 사용 — 매 cross-vendor 차이 매 manual 검증. ## ❌ 안티패턴 - **State change 섞기**: 매 매 draw 사이 uniform/texture 변경 — 매 batch 의미 사라짐. - **Drawcount=1**: 매 일반 drawArrays 와 동일하므로 매 overhead 만 추가. - **Extension 체크 누락**: 매 `getExtension` 결과 null 처리 없이 호출 → 매 runtime crash. ## 🧪 검증 / 중복 - Verified (KhronosGroup WebGL Registry, WEBGL_multi_draw spec). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — extension 4 함수 + gl_DrawID 패턴 |