webgl
Skill0 starsChanged 48 days agoMITView on GitHub
Implements or debugs raw WebGL/WebGL2 contexts, GLSL, buffers, textures, and GL draw calls. Use for direct WebGL API work, not generic 3D tasks owned by a higher-level renderer.
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 2 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 23
Prefer WebGL2 (instancing, VAOs, MRT, 3D textures are core).
- Very specific: line 54
Use indexed drawing (drawElements) with element buffers.
- Very specific: line 55
Use gl.drawArraysInstanced / drawElementsInstanced for repeated objects (one call, N copies).
- Very specific: line 61
Prefer mediump precision in fragment shaders unless you need highp.
- Very specific: line 69
Use compressed formats (WEBGL_compressed_texture_*, KTX2/Basis) to cut VRAM and bandwidth.
- Distinctive: line 70
Use texture atlases to reduce binds and enable batching.
- Very specific: line 85
Always drive with requestAnimationFrame.
- Very specific: line 86
Avoid synchronous GPU→CPU reads (readPixels, getError in hot paths) — they stall the pipeline.
- Very specific: line 92
Use the browser's WebGL/Spector.js inspector to count draw calls and inspect state.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
WebGL
Low-level GPU rendering in the browser. The mental model: minimize state changes and draw calls, move work to the GPU, and never block the main thread.
Context setup
const gl = canvas.getContext('webgl2', {
alpha: false, // skip compositing transparency if unneeded
antialias: true,
powerPreference: 'high-performance', // optional performance/power hint
preserveDrawingBuffer: false, // true is slow; only for readback/screenshots
});
if (!gl) throw new Error('WebGL2 unavailable; show the product fallback.');- Prefer WebGL2 (instancing, VAOs, MRT, 3D textures are core). Fall back to WebGL1 only if you must.
- Handle context loss: call
event.preventDefault()inwebglcontextlostto allow restoration, stop rendering, and recreate resources onwebglcontextrestoredbefore restarting.
Confirm which GPU you actually got
const ext = gl.getExtension('WEBGL_debug_renderer_info');
if (ext) console.log(gl.getParameter(ext.UNMASKED_RENDERER_WEBGL));The extension may be unavailable for privacy reasons. powerPreference is a hint; it does not guarantee a discrete GPU, and renderer strings do not establish performance. Measure on target hardware.
DPR & viewport
const dpr = Math.min(window.devicePixelRatio, 2); // clamp; full DPR is costly
canvas.width = Math.floor(canvas.clientWidth * dpr);
canvas.height = Math.floor(canvas.clientHeight * dpr);
gl.viewport(0, 0, canvas.width, canvas.height);The cost model (profile to find the dominant cost)
- Draw calls — batch geometry, use instancing, sort by material to avoid redundant binds.
- State changes —
useProgram,bindTexture,bindBuffer, enabling/disabling are not free. Group draws that share state. - Fragment shader work — overdraw and expensive per-pixel math. Cull, depth-sort opaque front-to-back, avoid huge
discardusage. - Bandwidth — texture size/format. Use mipmaps and compressed textures.
Geometry & buffers
- Upload geometry once into VBOs; use VAOs to capture attribute state and rebind in one call.
- Use indexed drawing (
drawElements) with element buffers. - Use
gl.drawArraysInstanced/drawElementsInstancedfor repeated objects (one call, N copies). - Set buffer usage hints correctly:
STATIC_DRAWfor immutable,DYNAMIC_DRAWfor frequently updated.
Shaders
- Compile/link programs once at init, never per frame. Cache uniform locations.
- Prefer
mediumpprecision in fragment shaders unless you needhighp. - Minimize branching and dependent texture reads; avoid
discardwhere possible (it defeats early-Z). - Move constant math to the vertex shader or to the CPU as uniforms.
Textures
- Power-of-two enables full mipmap/wrap support in WebGL1; WebGL2 relaxes this but mipmaps still help.
- Generate mipmaps for anything minified; set sensible min/mag filters.
- Use compressed formats (
WEBGL_compressed_texture_*, KTX2/Basis) to cut VRAM and bandwidth. - Use texture atlases to reduce binds and enable batching.
The render loop
function frame(t) {
// update (use real delta time)
// clear only what you need
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// draw, grouped by program/material
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);- Always drive with
requestAnimationFrame. Skip rendering entirely when nothing changed (on-demand). - Avoid synchronous GPU→CPU reads (
readPixels,getErrorin hot paths) — they stall the pipeline. - Offload heavy CPU prep to a worker; consider
OffscreenCanvasfor worker-side rendering.
Debug & profile
gl.getError()only while debugging (it forces a flush) — strip from hot paths.- Use the browser's WebGL/Spector.js inspector to count draw calls and inspect state.
- Watch for: too many programs bound per frame, per-frame buffer reallocation, uncompressed large textures.
When to step up
- Need compute, storage buffers, or modern GPU features → use the
webgpuskill, but keep WebGL2 as the production fallback unless the product controls its browser/GPU matrix. - Building a full scene graph → use Three.js / React Three Fiber instead of hand-rolling (see the
react-three-fiberskill).
WebGL is also the fallback boundary for an experimental HTML-in-Canvas texture path. The explainer reviewed on 9 September 2026 uses texElementSubImage2D(), replacing earlier texElementImage2D() examples. Keep this experimental method feature-detected and preserve semantic DOM or an established texture pipeline when it is unavailable. See low-level-web-rendering.
Reference
- MDN: WebGL best practices, renderer info extension; WebGL2 Fundamentals.
- Khronos WebGL best practices.
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- sukirman1901/frontend-expert★ 10same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository21 other files it gives its agents.
- ask-dont-assumeSkill
- browser-devtoolsSkill
- cachingSkill
- code-qualitySkill
- cssSkill
- database-guardrailsSkill
- gitSkill
- htmlSkill
- javascriptSkill
- low-level-web-renderingSkill
- react-best-practicesSkill
- react-three-fiberSkill
- securitySkill
- service-workerSkill
- tanstackSkill
- vgpuSkill
- wasm-rustSkill
- web-design-guidelinesSkill
- webgpuSkill
- web-performanceSkill
- webview2-winuiSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

