--- id: wiki-2026-0508-webgl-api title: WebGL API category: 10_Wiki/Topics status: verified canonical_id: self aliases: [WebGL, WebGL API, WebGL 1.0, WebGL 2.0] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [webgl, graphics, gpu, gles] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: JavaScript/GLSL framework: Web Platform --- # WebGL API ## 매 한 줄 > **"매 OpenGL ES 의 web — canvas 의 GPU draw"**. WebGL 매 OpenGL ES 2.0 (WebGL1) / ES 3.0 (WebGL2) binding 의 browser. 2026 매 WebGPU rising 매 WebGL 매 still ubiquitous — fallback / wide compatibility 의 사용. ## 매 핵심 ### 매 pipeline - **Vertex shader**: per-vertex transform — clip space. - **Rasterizer**: triangles → fragments. - **Fragment shader**: per-pixel color. - **Framebuffer**: render target — default canvas / FBO offscreen. ### 매 핵심 objects - **Buffer** (`ARRAY_BUFFER`, `ELEMENT_ARRAY_BUFFER`): vertex / index data. - **Texture** (2D / cube / 3D-WebGL2 / array-WebGL2). - **Program**: vertex + fragment shader linked. - **VAO** (WebGL2): vertex attribute state. - **UBO** (WebGL2): uniform block — efficient bulk uniform. - **Framebuffer / Renderbuffer**: offscreen render targets. ### 매 응용 1. **3D libraries**: Three.js / Babylon.js / PlayCanvas. 2. **2D accelerated**: PixiJS / Konva. 3. **Data viz**: deck.gl / Mapbox GL / regl. 4. **Games / interactive**: itch.io HTML5 / Unity WebGL build. ## 💻 패턴 ### 매 minimal triangle ```js const canvas = document.querySelector('canvas'); const gl = canvas.getContext('webgl2'); const vs = `#version 300 es in vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0.0, 1.0); }`; const fs = `#version 300 es precision highp float; out vec4 fragColor; void main() { fragColor = vec4(1.0, 0.5, 0.2, 1.0); }`; function compile(type, src) { const s = gl.createShader(type); gl.shaderSource(s, src); gl.compileShader(s); if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) throw gl.getShaderInfoLog(s); return s; } const prog = gl.createProgram(); gl.attachShader(prog, compile(gl.VERTEX_SHADER, vs)); gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, fs)); gl.linkProgram(prog); const vao = gl.createVertexArray(); gl.bindVertexArray(vao); const vbo = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vbo); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.5, -0.5, -0.5, 0.5, -0.5]), gl.STATIC_DRAW); const loc = gl.getAttribLocation(prog, 'a_pos'); gl.enableVertexAttribArray(loc); gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0); gl.useProgram(prog); gl.drawArrays(gl.TRIANGLES, 0, 3); ``` ### Texture upload ```js const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.generateMipmap(gl.TEXTURE_2D); ``` ### Instanced rendering (WebGL2) ```js gl.vertexAttribDivisor(instanceLoc, 1); // advance per instance gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, 10000); // 10k instances 1 draw call ``` ### Uniform Buffer Object (WebGL2) ```js const ubo = gl.createBuffer(); gl.bindBuffer(gl.UNIFORM_BUFFER, ubo); gl.bufferData(gl.UNIFORM_BUFFER, mat4Buffer, gl.DYNAMIC_DRAW); const idx = gl.getUniformBlockIndex(prog, 'Camera'); gl.uniformBlockBinding(prog, idx, 0); gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo); ``` ### Framebuffer (offscreen / render-to-texture) ```js const fbo = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, w, h, 0, gl.RGBA, gl.HALF_FLOAT, null); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); // 매 render → tex, then post-process ``` ### Transform Feedback (WebGL2 GPU compute-ish) ```js gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, outBuf); gl.beginTransformFeedback(gl.POINTS); gl.drawArrays(gl.POINTS, 0, particleCount); gl.endTransformFeedback(); ``` ### Context loss handling ```js canvas.addEventListener('webglcontextlost', (e) => { e.preventDefault(); }); canvas.addEventListener('webglcontextrestored', () => { rebuildResources(); }); ``` ## 매 결정 기준 | 상황 | WebGL vs WebGPU | |---|---| | 2026 wide compatibility | WebGL2 — Safari iOS / older Android | | Compute shader | WebGPU | | Multi-pass complex | WebGPU 매 cleaner state model | | Existing Three.js / Babylon | WebGL2 fallback + WebGPU primary | | Simple 2D accel | WebGL2 / 2D canvas | | AAA-grade graphics | WebGPU | **기본값**: Three.js with WebGPURenderer + WebGL2 fallback. ## 🔗 Graph - 부모: [[OpenGL ES]] - 변형: [[WebGPU]] - 응용: [[Threejs]] · [[Babylonjs]] - Adjacent: [[GLSL]] · [[OffscreenCanvas]] ## 🤖 LLM 활용 **언제**: cross-browser 3D / 2D GPU accel / data viz / WebGPU 의 fallback. **언제 X**: heavy compute (no compute shader in WebGL) / cutting-edge graphics — WebGPU 사용. ## ❌ 안티패턴 - **State thrash**: bind/unbind every draw — batch by program/texture. - **Sync readback**: `readPixels` 매 GPU stall — use PBO async (WebGL2). - **No VAO**: re-binding attributes every draw — VAO 매 cache. - **Uniform per draw call**: UBO 의 bulk update / instancing. - **Premultiply confusion**: alpha blending 의 incorrect — `UNPACK_PREMULTIPLY_ALPHA_WEBGL`. ## 🧪 검증 / 중복 - Verified (Khronos WebGL 1.0/2.0 spec / MDN WebGL API). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — pipeline, VAO, UBO, FBO, instancing, transform feedback |