[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EGM58XRFBTNJKPTFFYNJ8C":3,"skill-same:01M6EGM58XRFBTNJKPTFFYNJ8C":45},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":20,"frontMatter":21,"refName":22,"commitSha":23,"skillDirectory":24,"forksCount":25,"repositoryHtmlUrl":26,"repositoryHomepageUrl":27,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M6EGM58XRFBTNJKPTFFYNJ8C","webgl",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fwebgl\u002FSKILL.md",[],[5],"2026-11-10 10:12:30",false,"# WebGL\n\nLow-level 3D graphics API for the browser. Direct GPU access through shaders, buffers, and textures.\n\n## Initializing a WebGL Context\n\n```typescript\n\u002F\u002F src\u002Fwebgl\u002Finit.ts — Get a WebGL2 rendering context and configure it.\n\u002F\u002F Falls back to WebGL1 if WebGL2 is unavailable.\nexport function initWebGL(canvas: HTMLCanvasElement): WebGL2RenderingContext {\n  const gl = canvas.getContext(\"webgl2\");\n  if (!gl) throw new Error(\"WebGL2 not supported\");\n\n  gl.viewport(0, 0, canvas.width, canvas.height);\n  gl.clearColor(0.0, 0.0, 0.0, 1.0);\n  gl.enable(gl.DEPTH_TEST);\n  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n  return gl;\n}\n```\n\n## Compiling Shaders\n\n```typescript\n\u002F\u002F src\u002Fwebgl\u002Fshaders.ts — Compile vertex and fragment shaders, link into a program.\n\u002F\u002F Shaders run on the GPU and control how vertices and pixels are processed.\nexport function createShaderProgram(\n  gl: WebGL2RenderingContext,\n  vertexSrc: string,\n  fragmentSrc: string\n): WebGLProgram {\n  const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexSrc);\n  const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);\n\n  const program = gl.createProgram()!;\n  gl.attachShader(program, vertexShader);\n  gl.attachShader(program, fragmentShader);\n  gl.linkProgram(program);\n\n  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n    throw new Error(`Link error: ${gl.getProgramInfoLog(program)}`);\n  }\n\n  return program;\n}\n\nfunction compileShader(\n  gl: WebGL2RenderingContext,\n  type: number,\n  source: string\n): WebGLShader {\n  const shader = gl.createShader(type)!;\n  gl.shaderSource(shader, source);\n  gl.compileShader(shader);\n\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    const info = gl.getShaderInfoLog(shader);\n    gl.deleteShader(shader);\n    throw new Error(`Shader compile error: ${info}`);\n  }\n  return shader;\n}\n```\n\n## GLSL Shaders\n\n```glsl\n\u002F\u002F shaders\u002Fvertex.glsl — Transform vertex positions and pass data to fragment shader.\n#version 300 es\nlayout(location = 0) in vec3 aPosition;\nlayout(location = 1) in vec3 aNormal;\nlayout(location = 2) in vec2 aTexCoord;\n\nuniform mat4 uModelView;\nuniform mat4 uProjection;\n\nout vec3 vNormal;\nout vec2 vTexCoord;\n\nvoid main() {\n  vNormal = mat3(uModelView) * aNormal;\n  vTexCoord = aTexCoord;\n  gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\n}\n```\n\n```glsl\n\u002F\u002F shaders\u002Ffragment.glsl — Calculate pixel color using lighting and texture.\n#version 300 es\nprecision highp float;\n\nin vec3 vNormal;\nin vec2 vTexCoord;\n\nuniform sampler2D uTexture;\nuniform vec3 uLightDir;\n\nout vec4 fragColor;\n\nvoid main() {\n  vec3 normal = normalize(vNormal);\n  float diffuse = max(dot(normal, normalize(uLightDir)), 0.0);\n  vec4 texColor = texture(uTexture, vTexCoord);\n  fragColor = vec4(texColor.rgb * (0.3 + 0.7 * diffuse), texColor.a);\n}\n```\n\n## Buffers and VAOs\n\n```typescript\n\u002F\u002F src\u002Fwebgl\u002Fgeometry.ts — Create vertex buffer objects and vertex array objects\n\u002F\u002F to upload geometry data to the GPU.\nexport function createTriangle(gl: WebGL2RenderingContext) {\n  const vertices = new Float32Array([\n    \u002F\u002F x,    y,    z\n     0.0,  0.5,  0.0,\n    -0.5, -0.5,  0.0,\n     0.5, -0.5,  0.0,\n  ]);\n\n  const vao = gl.createVertexArray()!;\n  gl.bindVertexArray(vao);\n\n  const vbo = gl.createBuffer()!;\n  gl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n  gl.enableVertexAttribArray(0);\n  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);\n\n  gl.bindVertexArray(null);\n  return { vao, vertexCount: 3 };\n}\n```\n\n## Render Loop\n\n```typescript\n\u002F\u002F src\u002Fwebgl\u002Frender.ts — Animation loop that clears the screen and draws geometry\n\u002F\u002F each frame, updating uniforms for animation.\nexport function startRenderLoop(\n  gl: WebGL2RenderingContext,\n  program: WebGLProgram,\n  draw: (time: number) => void\n) {\n  gl.useProgram(program);\n\n  function frame(time: number) {\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n    draw(time);\n    requestAnimationFrame(frame);\n  }\n\n  requestAnimationFrame(frame);\n}\n```\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Fwebgl",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill webgl",{"tool":37,"command":38},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill webgl",{"tool":40,"command":41},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill webgl","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fwebgl\u002FSKILL.md",true,[],[46,60,70,79,85,92],{"skillNo":47,"name":48,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":49,"categories":50,"keywords":56,"publishedAt":18},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[51],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[57,58,59],"model","model hierarchy","model hierarchy skill",{"skillNo":61,"name":62,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":66,"publishedAt":18},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[65],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},[67,68,69],"MCP","zoom","zoom mcp",{"skillNo":71,"name":72,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":75,"publishedAt":18},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[76,77,78,68],"sdk","zoom apps sdk","apps",{"skillNo":80,"name":81,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":18},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[81],{"skillNo":86,"name":87,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":91,"publishedAt":18},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[90],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},[87],{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":18},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[94]]