{"record":{"id":"b35b7c0fe2775b19","repo":"MiniMax-AI/skills","slug":"webgl2-not-supported-b35b7c","errorCode":null,"errorMessage":"WebGL2 not supported","messagePattern":"WebGL2 not supported","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/shader-dev/techniques/shadow-techniques.md","lineNumber":390,"sourceCode":"<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <title>Soft Shadows - SDF Raymarching</title>\n    <style>\n        body { margin: 0; overflow: hidden; background: #000; }\n        canvas { display: block; width: 100vw; height: 100vh; }\n    </style>\n</head>\n<body>\n    <canvas id=\"canvas\"></canvas>\n    <script>\n        const canvas = document.getElementById('canvas');\n        const gl = canvas.getContext('webgl2');\n\n        if (!gl) {\n            document.body.innerHTML = '<p style=\"color:#fff;\">WebGL2 not supported</p>';\n            throw new Error('WebGL2 not supported');\n        }\n\n        // Vertex shader: fullscreen quad\n        const vsSource = `#version 300 es\n            in vec4 aPosition;\n            void main() {\n                gl_Position = aPosition;\n            }\n        `;\n\n        // Fragment shader: SDF soft shadows\n        const fsSource = `#version 300 es\n            precision highp float;\n\n            uniform float iTime;\n            uniform vec2 iResolution;\n            uniform vec4 iMouse;\n","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/MiniMax-AI/skills/blob/60aaae52bb2af8162732751a4332f62a5fef518b/skills/shader-dev/techniques/shadow-techniques.md#L372-L408","documentation":"`throw new Error('WebGL2 not supported')` in the shadow-techniques SDF demo. `canvas.getContext('webgl2')` returned null, so the script writes a fallback `<p>` and throws before compiling the `#version 300 es` shaders (which require a WebGL2 context). Without the throw, subsequent `gl.createShader` calls would throw a null-reference TypeError with a less obvious cause.","triggerScenarios":"Loading the shadow demo in a browser/VM without WebGL2 support, with acceleration disabled, or on a blocklisted GPU driver.","commonSituations":"Old Safari, headless testing, disabled hardware acceleration, or unsupported mobile GPUs.","solutions":["Use a WebGL2-capable browser and enable hardware acceleration.","Update GPU drivers or switch devices if the driver is blocklisted.","Wrap in a capability check that renders a static fallback instead of throwing."],"exampleFix":"// before\nconst gl = canvas.getContext('webgl2');\nif (!gl) { document.body.innerHTML = '<p>WebGL2 not supported</p>'; throw new Error('WebGL2 not supported'); }\n\n// after\nconst gl = canvas.getContext('webgl2');\nif (!gl) { showStaticShadowImage(); return; }\nrunSdfShadows(gl);","handlingStrategy":"fallback","validationCode":"const gl = canvas.getContext('webgl2');\nif (!gl) { showStaticShadowImage(); return; }\nrunSdfShadows(gl);","typeGuard":"function canRunWebGL2Demo(): boolean {\n  try { return !!document.createElement('canvas').getContext('webgl2'); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  const gl = canvas.getContext('webgl2');\n  if (!gl) throw new Error('WebGL2 not supported');\n  runSdfShadows(gl);\n} catch (e) {\n  if (e instanceof Error && /WebGL2/i.test(e.message)) showStaticShadowImage();\n  else throw e;\n}","preventionTips":["Gate the `#version 300 es` shader pipeline behind a confirmed WebGL2 context.","Offer a static fallback render so unsupported browsers degrade gracefully.","Surface the minimum browser/version requirement in the demo UI.","In headless tests, run under a software GL backend or skip the path."],"tags":["webgl","webgl2","browser","gpu","shadows","javascript"],"backgroundTag":null,"analyzedSha":"60aaae52bb2af8162732751a4332f62a5fef518b","analyzedAt":"2026-08-13T17:32:34.717Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}