1"use strict";(globalThis.webpackChunkwebsite=globalThis.webpackChunkwebsite||[]).push([[2617],{490(e,n,t){t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"glre/README","title":"\ud83c\udf07 glre","description":"npm version","source":"@site/../../packages/glre/README.md","sourceDirName":"glre","slug":"/glre/","permalink":"/packages/glre/","draft":false,"unlisted":false,"editUrl":"https://github.com/tseijp/tseijp/tree/main/packages/../../packages/glre/README.md","tags":[],"version":"current","frontMatter":{},"sidebar":"defaultSidebar","previous":{"title":"\ud83c\udf01glrb","permalink":"/packages/glrb/"},"next":{"title":"\u30ea\u30a2\u30af\u30c6\u30a3\u30d6 GPU \u30a8\u30f3\u30b8\u30f3\u8a2d\u8a08\u4ed5\u69d8\u66f8","permalink":"/packages/glre/CLAUDE.ja"}}');var r=t(1085),i=t(1184);const a={},l="\ud83c\udf07 glre",o={},c=[{value:"Installation",id:"installation",level:2},{value:"Documentation",id:"documentation",level:2},{value:"Docs : glre Introduction",id:"docs--glre-introduction",level:6},{value:"API : glre API and feature",id:"api--glre-api-and-feature",level:6},{value:"Guide : Creating a scene",id:"guide--creating-a-scene",level:6},{value:"Ecosystem",id:"ecosystem",level:2},{value:"\u26ea\ufe0f reev: reactive event state manager",id:"\ufe0f-reev-reactive-event-state-manager",level:6},{value:"\ud83d\udd2e refr: request animation frame",id:"-refr-request-animation-frame",level:6},{value:"Staying informed",id:"staying-informed",level:2},{value:"github discussions welcome\u2728",id:"github-discussions-welcome",level:6},{value:"@tseijp twitter",id:"tseijp-twitter",level:6},{value:"tsei.jp articles",id:"tseijp-articles",level:6},{value:"What does it look like?",id:"what-does-it-look-like",level:2},{value:"Varying",id:"varying",level:3},{value:"Uniforms",id:"uniforms",level:3},{value:"Attributes",id:"attributes",level:3},{value:"Multiples",id:"multiples",level:3},{value:"Textures",id:"textures",level:3},{value:"Instancing",id:"instancing",level:3},{value:"Computing",id:"computing",level:3},{value:"Node System",id:"node-system",level:2},{value:"Type System Deconstruction",id:"type-system-deconstruction",level:3},{value:"Function Composition Reimagined",id:"function-composition-reimagined",level:3},{value:"Control Flow Dissolution",id:"control-flow-dissolution",level:3},{value:"Reactive Uniform Architecture",id:"reactive-uniform-architecture",level:3},{value:"Attribute Data Streams",id:"attribute-data-streams",level:3},{value:"PRs",id:"prs",level:2},{value:"welcome\u2728",id:"welcome",level:6},{value:"LICENSE",id:"license",level:2},{value:"MIT\u26be\ufe0f",id:"mit\ufe0f",level:6}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h6:"h6",header:"header",hr:"hr",img:"img",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"-glre",children:"\ud83c\udf07 glre"})}),"\n",(0,r.jsx)("strong",{children:(0,r.jsxs)("samp",{children:[(0,r.jsxs)("p",{align:"center",children:[(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.npmjs.com/package/glre",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/npm/v/glre?style=flat&colorA=000&colorB=000",alt:" npm version "})}),"\n",(0,r.jsx)(n.a,{href:"https://www.npmtrends.com/glre",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/npm/dm/glre.svg?style=flat&colorA=000&colorB=000",alt:" downloads "})}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/tseijp/glre",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/npm/l/glre?style=flat&colorA=000&colorB=000",alt:" license MIT "})}),"\n",(0,r.jsx)(n.a,{href:"https://glre.dev",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/badge/docs-available-000.svg?style=flat&colorA=000",alt:" docs available "})}),"\n",(0,r.jsx)(n.a,{href:"https://bundlephobia.com/package/glre@latest",children:(0,r.jsx)(n.img,{src:"https://img.shields.io/bundlephobia/minzip/glre?style=flat&colorA=000&colorB=000",alt:" bundle size "})})]}),(0,r.jsx)(n.p,{children:"glre is a simple glsl and wgsl Reactive Engine on the web and native via TypeScript, React, Solid and more."})]}),(0,r.jsxs)("p",{align:"center",valign:"top",children:[(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-test1-skyl9p",children:(0,r.jsx)("img",{alt:"test1",width:"256",src:"https://user-images.githubusercontent.com/40712342/212297558-15a1e721-55d6-4b6f-aab4-9f5d7cede2cb.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-test2-c1syho",children:(0,r.jsx)("img",{alt:"test2",width:"256",src:"https://user-images.githubusercontent.com/40712342/212297576-e12cef1b-b0e0-40cb-ac0f-7fb387ae6da8.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-test3-ntlk3l",children:(0,r.jsx)("img",{alt:"test3",width:"256",src:"https://user-images.githubusercontent.com/40712342/212297587-0227d536-5cef-447a-be3e-4c93dad002a2.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-raymarch-test-q8pyxv",target:"_blank",rel:"noopener",children:(0,r.jsx)("img",{alt:"raymarch1",width:"256",src:"https://user-images.githubusercontent.com/40712342/215024903-90f25934-1018-4f2a-81e6-f16e5c64c378.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-raymarch-test2-fcds29",target:"_blank",rel:"noopener",children:(0,r.jsx)("img",{alt:"raymarch2",width:"256",src:"https://user-images.githubusercontent.com/40712342/215024942-27766b2b-7b85-4725-bb3d-865bf137ea29.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-raymarch-test3-nx6ggi",target:"_blank",rel:"noopener",children:(0,r.jsx)("img",{alt:"raymarch3",width:"256",src:"https://user-images.githubusercontent.com/40712342/2150250
152-c2fa46e5-5e0e-4de8-baee-869ca6135a61.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-raymarch-test4-cy1wpp",target:"_blank",rel:"noopener",children:(0,r.jsx)("img",{alt:"raymarch4",width:"256",src:"https://user-images.githubusercontent.com/40712342/215025289-132b4213-aabc-48f2-bbe3-05764a8dae42.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-raymarch-test5-19v0g7",target:"_blank",rel:"noopener",children:(0,r.jsx)("img",{alt:"raymarch5",width:"256",src:"https://user-images.githubusercontent.com/40712342/215025456-8ab75328-ca7a-41f6-b5fe-98dd58410b38.gif"})}),(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-raymarch-test6-jew0it",target:"_blank",rel:"noopener",children:(0,r.jsx)("img",{alt:"raymarch6",width:"256",src:"https://user-images.githubusercontent.com/40712342/215025517-343fdfbf-af54-497c-a759-267acc450366.gif"})})]}),(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ruby",children:"npm install glre\n"})}),(0,r.jsxs)("table",{children:[(0,r.jsxs)("td",{width:"1000px",valign:"top",children:[(0,r.jsx)(n.h2,{id:"documentation",children:"Documentation"}),(0,r.jsxs)(n.h6,{id:"docs--glre-introduction",children:[(0,r.jsx)(n.a,{href:"https://glre.tsei.jp/docs",children:"Docs"})," : glre Introduction"]}),(0,r.jsxs)(n.h6,{id:"api--glre-api-and-feature",children:[(0,r.jsx)(n.a,{href:"https://glre.tsei.jp/api",children:"API"})," : glre API and feature"]}),(0,r.jsxs)(n.h6,{id:"guide--creating-a-scene",children:[(0,r.jsx)(n.a,{href:"https://glre.tsei.jp/guide",children:"Guide"})," : Creating a scene"]})]}),(0,r.jsxs)("td",{width:"1000px",valign:"top",children:[(0,r.jsx)(n.h2,{id:"ecosystem",children:"Ecosystem"}),(0,r.jsxs)(n.h6,{id:"\ufe0f-reev-reactive-event-state-manager",children:["\u26ea\ufe0f ",(0,r.jsx)(n.a,{href:"https://github.com/tseijp/reev",children:"reev"}),": reactive event state manager"]}),(0,r.jsxs)(n.h6,{id:"-refr-request-animation-frame",children:["\ud83d\udd2e ",(0,r.jsx)(n.a,{href:"https://github.com/tseijp/refr",children:"refr"}),": request animation frame"]})]}),(0,r.jsxs)("td",{width:"1000px",valign:"top",children:[(0,r.jsx)(n.h2,{id:"staying-informed",children:"Staying informed"}),(0,r.jsxs)(n.h6,{id:"github-discussions-welcome",children:[(0,r.jsx)(n.a,{href:"https://github.com/tseijp/glre/discussions",children:"github discussions"})," welcome\u2728"]}),(0,r.jsxs)(n.h6,{id:"tseijp-twitter",children:[(0,r.jsx)(n.a,{href:"https://twitter.com/tseijp",children:"@tseijp"})," twitter"]}),(0,r.jsxs)(n.h6,{id:"tseijp-articles",children:[(0,r.jsx)(n.a,{href:"https://tsei.jp/articles",children:"tsei.jp"})," articles"]})]})]}),(0,r.jsx)(n.h2,{id:"what-does-it-look-like",children:"What does it look like?"}),(0,r.jsx)("table",{children:(0,r.jsx)("tbody",{children:(0,r.jsxs)("tr",{children:[(0,r.jsx)("td",{width:"7500px",align:"center",valign:"center",children:(0,r.jsx)(n.p,{children:"glre simplifies WebGL2 / WebGPU programming via TypeScript, React, Solid and more."})}),(0,r.jsx)("td",{width:"2500px",valign:"top",children:(0,r.jsx)("a",{href:"https://codesandbox.io/s/glre-basic-demo-ppzo3d",children:(0,r.jsx)("img",{alt:"4",src:"https://i.imgur.com/Lb3h9fs.jpg"})})})]})})}),(0,r.jsx)("table",{children:(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"ESM"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-html",children:"<script type=\"module\">\n import { createGL } from 'https://esm.sh/glre'\n import { vec4, uv } from 'https://esm.sh/glre/node'\n createGL({ fs: vec4(uv, 0, 1) }).mount()\n<\/script>\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"React"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { createRoot } from 'react-dom/client'\nimport { useGL } from 'glre/react'\nimport { vec4, uv } from 'glre/node'\n\nconst Canvas = () => {\n const gl = useGL({ fragment: vec4(uv, 0, 1) })\n return <canvas ref={gl.ref} />\n}\n\nconst root = document.getElementById('root')\ncreateRoot(root).render(<Canvas />)\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"ReactNative"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { GLView } from 'expo-gl'\nimport { registerRootComponent } from 'expo'\nimport { useGL } from 'glre/native'\nimport { vec4, uv } from 'glre/node'\n\nconst Canvas = () => {\n const gl = useGL({ fragment: vec4(uv, 0, 1) })\n return (\n <GLView\n style={{ flex: 1 }}\n onContextCreate={gl.ref}\n />\n )\n}\n\nregisterRootComponent(Canvas)\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"Solid.js"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { render } from 'solid-js/web'\nimport { onGL } from 'glre/solid'\nimport { vec4, uv } from 'glre/node'\n\nconst Canvas = () => {\n const gl = onGL({ fragment: vec4(uv, 0, 1) })\n return <canvas ref={gl.ref} />\n}\n\nrender(() => <Canvas />, document.getElementById('root'))\n"})})]})})]})}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"varying",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#varying",children:"Varying"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const tri = attribute([\n 0, 0.73,\n -1, -1,\n 1, -1,\n ])\n const col = attribute([\n 1, 0, 0,\n 0, 1, 0,\n 0, 0, 1,\n ])\n const gl = useGL({\n isWebGL: true,\n triangleCount: 1,\n vertex: vec4(tri, 0, 1),\n fragment: vec4(varying(col), 1),\n })\n return <canvas ref={gl.ref} />\n}\n"})}),(0,r.jsxs)(t,{children:[(0,r.jsx)("summary",{children:"Or as follows:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const vCol = varying(ve
1c3())\n const tri = attribute([\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n const col = attribute([\n 1, 0, 0,\n 0, 1, 0,\n 0, 0, 1\n ])\n const gl = useGL({\n isWebGL: true,\n triangleCount: 1,\n vertex: Scope(() => {\n vCol.assign(col)\n return vec4(tri, 0, 1)\n }),\n fragment: vec4(vCol, 1),\n })\n return <canvas ref={gl.ref} />\n}\n"})})]})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: true,\n triangleCount: 1,\n vertex: `\n #version 300 es\n in vec4 tri;\n in vec3 col;\n out vec3 v_col;\n void main() {\n gl_Position = tri;\n v_col = col;\n }`,\n fragment: `\n #version 300 es\n precision mediump float;\n in vec3 v_col;\n out vec4 fragColor;\n void main() {\n fragColor = vec4(v_col, 1.0);\n }`,\n })\n gl.attribute('tri', [\n 0, 0.73,\n -1, -1,\n 1, -1,\n ])\n gl.attribute('col', [\n 1, 0, 0,\n 0, 1, 0,\n 0, 0, 1,\n ])\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: false,\n triangleCount: 1,\n vertex: `\n struct In {\n @location(0) tri: vec2f,\n @location(1) col: vec3f,\n }\n struct Out {\n @builtin(position) position: vec4f,\n @location(0) v_col: vec3f,\n }\n @vertex\n fn main(in: In) -> Out {\n var out: Out;\n out.position = vec4f(in.tri, 0.0, 1.0);\n out.v_col = in.col;\n return out;\n }`,\n fragment: `\n struct Out {\n @builtin(position) position: vec4f,\n @location(0) v_col: vec3f,\n }\n @fragment\n fn main(out: Out) -> @location(0) vec4f {\n return vec4f(out.v_col, 1.0);\n }`,\n })\n gl.attribute('tri', [\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n gl.attribute('col', [\n 1, 0, 0,\n 0, 1, 0,\n 0, 0, 1\n ])\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#varying",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/varying.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"uniforms",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#uniforms",children:"Uniforms"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: true,\n fragment: vec4(\n uv.sub(iMouse).fract(),\n iTime.sin().mul(0.5).add(0.5),\n 1\n ),\n })\n return <canvas ref={gl.ref} />\n}\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: true,\n fragment: `\n #version 300 es\n precision mediump float;\n uniform vec2 iResolution;\n uniform vec2 iMouse;\n uniform float iTime;\n out vec4 fragColor;\n void main() {\n vec2 uv = fract(gl_FragCoord.xy / iResolution.xy - iMouse);\n fragColor = vec4(uv, sin(iTime) * 0.5 + 0.5, 1.0);\n }`,\n })\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: false,\n fragment: `\n @group(0) @binding(0) var<uniform> iResolution: vec2f;\n @group(0) @binding(1) var<uniform> iMouse: vec2f;\n @group(0) @binding(2) var<uniform> iTime: f32;\n @fragment\n fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {\n let uv = fract(position.xy / iResolution - iMouse);\n return vec4f(uv, sin(iTime) * 0.5 + 0.5, 1.0);\n }`,\n })\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#uniforms",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/uniform.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"attributes",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#attributes",children:"Attributes"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const tri = attribute([\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n const gl = useGL({\n isWebGL: true,\n triangleCount: 1,\n vertex: vec4(tri, 0, 1),\n })\n return <canvas ref={gl.ref} />\n}\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: true,\n triangleCount: 1,\n vertex: `\n #version 300 es\n in vec4 tri;\n void main() {\n gl_Position = tri;\n }`,\n })\n gl.attribute('tri', [\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: false,\n triangleCount: 1,\n vertex: `\n @vertex\n fn main(@location(0) tri: vec2f) -> @builtin(position) vec4f {\n return vec4f(tri, 0.0, 1.0);\n }`,\n })\n gl.attribute('tri', [\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#attributes",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/attribute.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"multiples",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#multiples",children:"Multiples"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const tri = attribute([\n 0, 0.37,\n -0.5, -0.5,\n 0.5, -0.5\n ])\n const gl = useGL(\n {\n isWebGL: true,\n triangleCount: 1,\n vertex: vec4(vec2(-0.5, 0).add(tri), 0, 1),\n },\n {\n triangleCount: 1,\n vertex: vec4(vec2(0.5, 0).add(tri), 0, 1),\n }\n )\n return <canvas ref={gl.ref} />\n}\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL(\n {\n isWebGL: true,\n triangleCount: 1,\n vertex: `\n #version 300 es\n in vec2 tri;\n void main() {\n gl_Position = vec4((vec2(-0.5, 0.0) + tri), 0.0, 1.0);\n }`,\n },\n {\n triangleCount: 1,\n vertex: `\n #version 300 es\n in vec2 tri;\n void main() {\n gl_Position = vec4((vec2(0.5, 0.0) + tri), 0.0, 1.0);\n }`,\n }\n )\n gl.attribute('tri', [\n 0, 0.37,\n -0.5, -0.5,\n 0.5, -0.5\n ])\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL(\n {\n isWebGL: false,\n triangleCount: 1,\n vertex: `\n struct In {\n @location(0) tri: vec2f\n }\n struct Out {\n @builtin(position) position: vec4f\n }\n @vertex\n fn main(in: In) -> Out {\n var out: Out;\n out.position = vec4f((vec2f(-0.5, 0.0) + in.tri), 0.0, 1.0);\n return out;\n }`,\n },\n {\n triangleCount: 1,\n vertex: `\n struct In {\n @location(0) tri: vec2f\n }\n struct Out {\n @builtin(position) position: vec4f\n }\n @vertex\n fn main(in: In) -> Out {\n var out: Out;\n out.position = vec4f((vec2f(0.5, 0.0) + in.tri), 0.0, 1.0);\n return out;\n }`,\n }\n )\n gl.attribute('tri', [\n 0, 0.37,\n -0.5, -0.5,\n 0.5, -0.5\n ])\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#multiples",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/multiple.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"textures",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#textures",children:"Textures"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const iTexture = uniform('https://...')\n const gl = useGL({\n isWebGL: true,\n fragment: texture(iTexture, uv),\n })\n return <canvas ref={gl.ref} />\n}\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: true,\n fragment: `\n #version 300 es\n precision mediump float;\n uniform vec2 iResolution;\n uniform sampler2D iTexture;\n out vec4 fragColor;\n void main() {\n vec2 uv = gl_FragCoord.xy / iResolution.xy;\n fragColor = texture(iTexture, uv);\n }`,\n })\n gl.texture('iTexture', 'https://...')\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: false,\n fragment: `\n @group(0) @binding(0) var<uniform> iResolution: vec2f;\n @group(1) @binding(0) var iSampler: sampler;\n @group(1) @binding(1) var iTexture: texture_2d<f32>;\n @fragment\n fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {\n let uv = position.xy / iResolution;\n return textureSample(iTexture, iSampler, uv);\n }`,\n })\n gl.texture('iTexture', 'https://...')\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#textures",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/texture.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"instancing",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#instancing",children:"Instancing"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const tri = attribute([\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n const pos = instance(\n Array(1000 * 2)\n .fill(0)\n .map(Math.random)\n )\n const gl = useGL({\n isWebGL: true,\n instanceCount: 1000,\n triangleCount: 1,\n vertex: vec4(\n tri.mul(0.05).sub(1).add(pos.mul(2)),\n 0,\n 1\n ),\n })\n return <canvas ref={gl.ref} />\n}\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: true,\n instanceCount: 1000,\n triangleCount: 1,\n vertex: `\n #version 300 es\n in vec2 tri;\n in vec2 pos;\n void main() {\n gl_Position = vec4((((tri * 0.05) - 1.0) + (pos * 2.0)), 0.0, 1.0);\n }`,\n })\n gl.attribute('tri', [\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n gl.instance(\n 'pos',\n Array(1000 * 2)\n .fill(0)\n .map(Math.random)\n )\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const gl = useGL({\n isWebGL: false,\n instanceCount: 1000,\n triangleCount: 1,\n vertex: `\n struct In {\n @location(0) tri: vec2f,\n @location(1) pos: vec2f\n }\n struct Out {\n @builtin(position) position: vec4f\n }\n @vertex\n fn main(in: In) -> Out {\n var out: Out;\n out.position = vec4f((((in.tri * 0.05) - 1.0) + (in.pos * 2.0)), 0.0, 1.0);\n return out;\n }`,\n })\n gl.attribute('tri', [\n 0, 0.73,\n -1, -1,\n 1, -1\n ])\n gl.instance(\n 'pos',\n Array(1000 * 2)\n .fill(0)\n .map(Math.random)\n )\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#instancing",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/instancing.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsxs)("table",{children:[(0,r.jsx)("tr",{children:(0,r.jsx)("td",{width:"100%",colspan:"3",children:(0,r.jsx)(n.h3,{id:"computing",children:(0,r.jsx)(n.a,{href:"https://glre.dev/docs#computing",children:"Computing"})})})}),(0,r.jsxs)("tr",{valign:"top",children:[(0,r.jsxs)("td",{width:"1000px",children:[(0,r.jsx)("br",{}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TSL"})}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const wave = storage(float(Array(1024)), 'wave')\n const gl = useGL({\n isWebGL: true,\n compute: Scope(() =>
1 {\n If(uint(0).equal(id.x), () => {\n wave.element(id.x).assign(iMouse.x)\n }).Else(() => {\n const prev = wave.element(id.x.sub(uint(1)))\n wave.element(id.x).assign(prev)\n })\n }),\n fragment: Scope(() => {\n const x = wave\n .element(uint(uv.y.mul(1024)))\n .sub(uv.x)\n .abs()\n return vec4(\n vec3(uv.step(vec2(smoothstep(0.01, 0, x))), 0),\n 1\n )\n }),\n })\n return <canvas ref={gl.ref} />\n}\n"})})]}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGL"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const wave = storage(float(Array(1024)), 'wave')\n const gl = useGL({\n isWebGL: true,\n compute: `\n #version 300 es\n precision highp float;\n uniform sampler2D wave;\n uniform vec2 iMouse;\n layout(location = 0) out vec4 _wave;\n void main() {\n if ((uint(0.0) == uvec3(uint(gl_FragCoord.y) * uint(32) + uint(gl_FragCoord.x), 0u, 0u).x)) {\n _wave = vec4(iMouse.x, 0.0, 0.0, 1.0);\n } else {\n _wave = vec4(texelFetch(wave, ivec2(int((uvec3(uint(gl_FragCoord.y) * uint(32) + uint(gl_FragCoord.x), 0u, 0u).x - uint(1.0))) % 32, int((uvec3(uint(gl_FragCoord.y) * uint(32) + uint(gl_FragCoord.x), 0u, 0u).x - uint(1.0))) / 32), 0).x, 0.0, 0.0, 1.0);\n };\n }`,\n fragment: `\n #version 300 es\n precision highp float;\n out vec4 fragColor;\n uniform vec2 iResolution;\n uniform sampler2D wave;\n void main() {\n fragColor = vec4(vec3(step((gl_FragCoord.xy / iResolution), vec2(smoothstep(0.01, 0.0, abs((texelFetch(wave, ivec2(int(uint(((gl_FragCoord.xy / iResolution).y * 1024.0))) % 32, int(uint(((gl_FragCoord.xy / iResolution).y * 1024.0))) / 32), 0).x - (gl_FragCoord.xy / iResolution).x))))), 0.0), 1.0);\n }`,\n })\n gl.storage('wave', Array(1024))\n return <canvas ref={gl.ref} />\n}\n"})})]})}),(0,r.jsx)("td",{width:"0px",children:(0,r.jsxs)(t,{children:[(0,r.jsxs)("summary",{children:[(0,r.jsx)(n.p,{children:"WebGPU"}),(0,r.jsx)(n.hr,{})]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"function Canvas() {\n const wave = storage(float(Array(1024)), 'wave')\n const gl = useGL({\n isWebGL: false,\n compute: `\n struct In {\n @builtin(global_invocation_id) global_invocation_id: vec3u\n }\n @group(0) @binding(1) var<uniform> iMouse: vec2f;\n @group(2) @binding(0) var<storage, read_write> wave: array<f32>;\n @compute @workgroup_size(32)\n fn main(in: In) {\n if ((u32(0.0) == in.global_invocation_id.x)) {\n wave[in.global_invocation_id.x] = iMouse.x;\n } else {\n wave[in.global_invocation_id.x] = wave[in.global_invocation_id.x - u32(1.0)];\n };\n }`,\n fragment: `\n struct Out {\n @builtin(position) position: vec4f\n }\n @group(2) @binding(0) var<storage, read_write> wave: array<f32>;\n @group(0) @binding(0) var<uniform> iResolution: vec2f;\n @fragment\n fn main(out: Out) -> @location(0) vec4f {\n return vec4f(vec3f(step((out.position.xy / iResolution), vec2f(smoothstep(0.01, 0.0, abs((wave[u32(((out.position.xy / iResolution).y * 1024.0))] - (out.position.xy / iResolution).x))))), 0.0), 1.0);\n }`,\n })\n gl.storage('wave', Array(1024))\n return <canvas ref={gl.ref} />\n}\n"})})]})})]}),(0,r.jsx)("tr",{children:(0,r.jsx)("td",{colspan:"3",children:(0,r.jsx)("a",{href:"https://glre.dev/docs#computing",children:(0,r.jsx)("img",{width:"256px",src:"https://glre.dev/img/readme/computing.jpg"})})})})]}),(0,r.jsx)(n.hr,{}),(0,r.jsx)(n.h2,{id:"node-system",children:"Node System"}),(0,r.jsx)(n.p,{children:"glre's node system reconstructs shader authoring through TypeScript syntax,\ndissolving the boundary between CPU logic and GPU computation.\nRather than traditional string-based shader composition,\nthis system materializes shaders as abstract syntax trees,\nenabling unprecedented code mobility across WebGL2 and WebGPU architectures."}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// Shader logic materializes through method chaining\nconst fragment = vec4(fract(position.xy.div(iResolution)), 0, 1)\n .mul(uniform(brightness))\n .mix(texture(backgroundMap, uv()), blend)\n"})}),(0,r.jsx)(n.p,{children:"The system operates through proxy objects that capture mathematical operations\nas node graphs, later transpiled to target shader languages.\nThis deconstructed approach eliminates the traditional separation\nbetween shader compilation and runtime execution."}),(0,r.jsx)(n.h3,{id:"type-system-deconstruction",children:"Type System Deconstruction"}
1),(0,r.jsx)(n.p,{children:"Traditional shader types dissolve into factory functions that generate node proxies:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// Types emerge from function calls rather than declarations\nconst position = vec3(x, y, z) // Becomes position node\nconst transform = mat4().mul(modelView) // Matrix composition\nconst sampled = texture(map, uv()) // Sampling operation\n"})}),(0,r.jsx)(n.p,{children:"Each operation generates immutable node structures,\nbuilding computation graphs that exist independently of their eventual compilation target."}),(0,r.jsx)(n.h3,{id:"function-composition-reimagined",children:"Function Composition Reimagined"}),(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"Fn"})," constructor dissolves function boundaries, creating reusable computation patterns:"]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// Functions exist as first-class node compositions\nconst noise = Fn(([coord]) => {\n return sin(coord.x.mul(12.9898))\n .add(sin(coord.y.mul(78.233)))\n .mul(43758.5453)\n .fract()\n})\n\n// Composition becomes transparent\nconst surface = noise(position.xz.mul(scale)).mix(noise(position.xz.mul(scale.mul(2))), 0.5)\n"})}),(0,r.jsx)(n.h3,{id:"control-flow-dissolution",children:"Control Flow Dissolution"}),(0,r.jsx)(n.p,{children:"Traditional control structures become node compositions, eliminating imperative sequence:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// Conditional logic as expression trees\nIf(height.greaterThan(waterLevel), () => {\n return grassTexture.sample(worldUV)\n}).Else(() => {\n return waterTexture.sample(worldUV.add(wave))\n})\n\n// Loops decompose into iteration patterns\nLoop(samples, ({ i }) => {\n accumulator.assign(accumulator.add(sample(position.add(offsets.element(i)))))\n})\n"})}),(0,r.jsx)(n.h3,{id:"reactive-uniform-architecture",children:"Reactive Uniform Architecture"}),(0,r.jsx)(n.p,{children:"Uniforms transcend static parameter passing, becoming reactive data channels:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const time = uniform(0) // Creates reactive binding\nconst amplitude = uniform(1) // Automatic GPU synchronization\n\n// Values flow reactively without explicit updates\nconst wave = sin(time.mul(frequency)).mul(amplitude)\n\n// Runtime updates propagate automatically\ntime.value = performance.now() / 1000\n"})}),(0,r.jsx)(n.h3,{id:"attribute-data-streams",children:"Attribute Data Streams"}),(0,r.jsx)(n.p,{children:"Vertex attributes dissolve into data stream abstractions:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// Attributes become typed data channels\nconst positions = attribute(vertexData) // Raw data binding\nconst normals = attribute(normalData) // Parallel stream\nconst uvs = attribute(textureCoords) // Coordinate mapping\n\n// Streams compose transparently\nconst worldPosition = positions.transform(modelMatrix)\nconst viewNormal = normals.transform(normalMatrix)\n"})}),(0,r.jsx)(n.h2,{id:"prs",children:"PRs"}),(0,r.jsx)(n.h6,{id:"welcome",children:"welcome\u2728"}),(0,r.jsx)(n.h2,{id:"license",children:"LICENSE"}),(0,r.jsx)(n.h6,{id:"mit\ufe0f",children:"MIT\u26be\ufe0f"})]})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1184(e,n,t){t.d(n,{R:()=>a,x:()=>l});var s=t(4041);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.