{"_id":"@alexjwayne/ts-gl-shader","_rev":"2-4ddaaf4c3f4dd957e3b124a3f44dac55","name":"@alexjwayne/ts-gl-shader","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@alexjwayne/ts-gl-shader","version":"0.1.0","description":"Strongly typed no boilerplate WebGL shaders.","main":"dist/alexjwayne-ts-gl-shader.cjs.js","module":"dist/alexjwayne-ts-gl-shader.esm.js","scripts":{"tsc":"tsc --noEmit --incremental","test":"vitest","build":"npm run build:lib && npm run build:examples","build:lib":"preconstruct build","build:examples":"vite build examples/hello-world && vite build examples/hello-world-3d","example":"run(){ vite examples/$1; }; run","check":"npm i && npm run tsc && npm test -- run && npm run build","deploy":"gh-pages -d examples/dist","release":"npm run check && npm run deploy && npm publish"},"repository":{"type":"git","url":"git+https://github.com/AlexJWayne/ts-gl-shader.git"},"author":{"name":"Alex Wayne"},"license":"MIT","browserslist":["defaults"],"devDependencies":{"@babel/preset-env":"^7.20.2","@babel/preset-typescript":"^7.18.6","@preconstruct/cli":"^2.2.2","@vitest/ui":"^0.26.3","gh-pages":"^4.0.0","prettier":"^2.8.1","typescript":"^4.9.4","vite":"^4.0.3","vitest":"^0.26.2","webgl-mock":"^0.1.7"},"types":"./dist/alexjwayne-ts-gl-shader.cjs.d.ts","gitHead":"de01b6691b87ec1aceebe00e7315cf08fde2669f","bugs":{"url":"https://github.com/AlexJWayne/ts-gl-shader/issues"},"homepage":"https://github.com/AlexJWayne/ts-gl-shader#readme","_id":"@alexjwayne/ts-gl-shader@0.1.0","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-O4DGV+1VPwUF1/MSy5tqu3ksNXHNLwhWnm8TSG6Mk/hncjn+VjmDq0Ji5vXRs/lp0SRbI+UA18+zrPox/++dpA==","shasum":"657a3b00c2cf7ffe3458a268d3e4e6fa047eff6a","tarball":"https://registry.npmjs.org/@alexjwayne/ts-gl-shader/-/ts-gl-shader-0.1.0.tgz","fileCount":17,"unpackedSize":48486,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD3zuWgXXPCRq8EBqCZpdmYh6YCC8hpa1MVUXxo6mjn4QIgWBDfGB8UqRAf0wLPpek9ELqm0rFfUlqrro0s2JMaXJQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJju5qsACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmodCA/+N7nGLwtXqWOMng2q30K3gNHQNbaoTfvW5oX3aPtnwmLG/yDJ\r\n0pkYTC5n9xG87HxL32UNU0E5E7KaBQwRdjOpS6tF7/ENtv5/F4uyAY2PkOut\r\nzzbxSFdmnCX6P9JBXmR8a/GyBkqZk4+NReO3P6h3eWUYYhqfv40bflwqNWHO\r\nd+5zMSOdJswexsVasb52A/eRQnf6iogcjnu59kguuhHYGj+YBH5n4Bj98707\r\nBr+AnaBhqSzxRtzEg8psKpVMdtCu8jbzSkrxmUefatl9WJueODPecqxnemJT\r\nBobB9SFk8OZU7pe0WvOUWg5ne4LOlLELAm2UaoGhoj7gXCYmTsj5QYku0wVZ\r\nmZpk+BTHwSeN3/NRBZvUoMXKFQTcknpsr/4c5zJDda5eekq14SVCCitp5l8/\r\nxGq0ds7jVu/iVKl/C6ijjo7dCqsZEve4Un8or0ejlod5nKirtwzP4wsKmmbX\r\nJCdjlk6LKTMQtgJKJIEzsu+VlCXwQ7oEfd490JGgZmAsJGjwLI25LVWi7N+N\r\nCOhFoDRRrZBt1xiR1bk8ACtm50Zvp/tFYpVPqzFmPo3KXK73/KTVzf/nNqVl\r\nB5CGfG/PZrsexvVgYP8hOMO1N5vPPs8Q+3AI8ZR6t/xw7L0uug22TCJvAhim\r\nhBflyKkhtwdKrJmbpRxqQ9SQy/Btilu8AOw=\r\n=VTOq\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"squeegy","email":"alex@beautifulpixel.com"},"directories":{},"maintainers":[{"name":"squeegy","email":"alex@beautifulpixel.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ts-gl-shader_0.1.0_1673239212655_0.09704273337591385"},"_hasShrinkwrap":false},"0.1.1":{"name":"@alexjwayne/ts-gl-shader","version":"0.1.1","description":"Strongly typed no boilerplate WebGL shaders.","main":"dist/alexjwayne-ts-gl-shader.cjs.js","module":"dist/alexjwayne-ts-gl-shader.esm.js","scripts":{"tsc":"tsc --noEmit --incremental","test":"vitest","build":"npm run build:lib && npm run build:examples","build:lib":"preconstruct build","build:examples":"vite build examples/hello-world && vite build examples/hello-world-3d","example":"run(){ vite examples/$1; }; run","check":"npm i && npm run tsc && npm test -- run && npm run build","deploy":"gh-pages -d examples/dist","release":"npm run check && npm run deploy && npm publish"},"repository":{"type":"git","url":"git+https://github.com/AlexJWayne/ts-gl-shader.git"},"author":{"name":"Alex Wayne"},"license":"MIT","browserslist":["defaults"],"devDependencies":{"@babel/preset-env":"^7.20.2","@babel/preset-typescript":"^7.18.6","@preconstruct/cli":"^2.2.2","@vitest/ui":"^0.26.3","gh-pages":"^4.0.0","prettier":"^2.8.1","typescript":"^4.9.4","vite":"^4.0.3","vitest":"^0.26.2","webgl-mock":"^0.1.7"},"types":"./dist/alexjwayne-ts-gl-shader.cjs.d.ts","gitHead":"f70c1aad50d1312c695d73a0f635debdf5171240","bugs":{"url":"https://github.com/AlexJWayne/ts-gl-shader/issues"},"homepage":"https://github.com/AlexJWayne/ts-gl-shader#readme","_id":"@alexjwayne/ts-gl-shader@0.1.1","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-CWKPUv5b4GJXAetMruzOtnOol8J19gkB/KuNtidLRw+iG47mhR4pNrJt5pCK8MC2cvLjuXkaYMTCbvE/GEay2g==","shasum":"20662ab5b8d7a92c2e8c7857e790068865ad9f4e","tarball":"https://registry.npmjs.org/@alexjwayne/ts-gl-shader/-/ts-gl-shader-0.1.1.tgz","fileCount":17,"unpackedSize":48510,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFMfd8PlMX7U8ohvGL1QIarvIBYhQlqFwPUScnlM2v7PAiB2mKSC5agVcE5w2gPxHLukJW0l5UCOW8sxmvlcsnGDTg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJju5uZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpSLBAAnKJFsqM5Lc2A6ZZIDoJb386gNCeCX5g0RzcG6zbek72katfQ\r\nejG3SmznE11Pa1yguNiD7zi7Vq4JFrVrtyFqD89SXeQz5Rr/61swSlv/a6AD\r\n7zKprC90X8THMz4XyqYFnG+K9aYKw4OXx1V+noByucByXIkLQ6GiNFW+o+no\r\nRXZ9nBCXQbE5SLq5xHNTnBogoMCebjmbwgjwKCBSO77IOTaUFy12rxROe4Hf\r\ngL66tmuV5iMCzVu63K/+epreo3XF1HeXXFikqXmjUHKJzrq2xOPK9DmE3suY\r\nIA4xRlqWqYUdYPN9XFV3QEDgsNN6cz0PP5F7CtfhRC3F1zjTF3Sp9xZ88NX8\r\nlTdLzuQ2KB378QOdVl/TNVKb5bEUkNcAd7OMZk5a2EEECWx/uGvAG1Ld1ds1\r\nFoCT2Ro+dE6vDFM4x5nHNJYIi8SEc365IsI2is13mnlerJ+ngcyCRqNsC3jw\r\nrmduC1bFOPktSjOFzhB9o0UR14Yp6Qtbcp7WUcbu2w7Qtw0yBoPEqqUjUxu2\r\noB6bImCjpuYP/lQEF8kJrYrDaoUSI3GKZtY/jtkyZA7V/a2H0bUBDPpxYl/k\r\nd5bwBuHmp5KK3R/CdUWWSLIyGbk93y1RDqgTM5svBe0UqIW3cvk7lmBaKNmb\r\nwzXGVUtPHqWGmC4QTcz0sO8i005UY83FUnw=\r\n=t/zT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"squeegy","email":"alex@beautifulpixel.com"},"directories":{},"maintainers":[{"name":"squeegy","email":"alex@beautifulpixel.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ts-gl-shader_0.1.1_1673239449106_0.7380577425695427"},"_hasShrinkwrap":false},"0.1.2":{"name":"@alexjwayne/ts-gl-shader","version":"0.1.2","description":"Strongly typed no boilerplate WebGL shaders.","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","scripts":{"tsc":"tsc --noEmit --incremental","test":"vitest","build":"npm run build:lib && npm run build:examples","build:lib":"tsup src/index.ts --format cjs,esm --dts","build:examples":"vite build examples/hello-world && vite build examples/hello-world-3d","example":"run(){ vite examples/$1; }; run","check":"npm i && npm run tsc && npm test -- run && npm run build","deploy":"gh-pages -d examples/dist","release":"npx changeset version && npm run check && npm run deploy && npm publish"},"repository":{"type":"git","url":"git+https://github.com/AlexJWayne/ts-gl-shader.git"},"author":{"name":"Alex Wayne"},"license":"MIT","browserslist":["defaults"],"devDependencies":{"@changesets/cli":"^2.26.0","@vitest/ui":"^0.26.3","gh-pages":"^4.0.0","prettier":"^2.8.1","tsup":"^6.5.0","typescript":"^4.9.4","vite":"^4.0.3","vitest":"^0.26.2","webgl-mock":"^0.1.7"},"gitHead":"5bc74656d5bd313f6f5a6a64641a4189251c38e8","bugs":{"url":"https://github.com/AlexJWayne/ts-gl-shader/issues"},"homepage":"https://github.com/AlexJWayne/ts-gl-shader#readme","_id":"@alexjwayne/ts-gl-shader@0.1.2","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-RDIScRJvEimhltPEsLnTBKvxsf0MdATcgxMme8KpqMa+l3vNwuQyn81RMS/aEpYS2lva0DNENCpIHc82YHK3MQ==","shasum":"2f4eecefeeeba30ad8ab9a36d76d6e63ba323f48","tarball":"https://registry.npmjs.org/@alexjwayne/ts-gl-shader/-/ts-gl-shader-0.1.2.tgz","fileCount":6,"unpackedSize":35543,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1//6v+GVdsttHtHnWyI4T9RnYjLZJwmBn4l5SYvT28AIgCKLgat3xlN/4p+QM4Xy9faC+eCwtDhi//bCHsSvti+4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjzFboACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrOZA//SxNj8nGGaB/uyyZq71YTo0TQ2Ei4zStqct+p5obeciQ06r0V\r\nPUkMHjj553bRzYDI+HDVVkZBN4OJBmzleb9UcbDjNgcfQrkNIKWZAb1U7ygk\r\n0xC8PJW0CEAIihgBRNo7wG33nMwM16FHFi0N1MfOf34LFtAkmTgywM+yZlcL\r\nIfDgj86g/wBZoglEyXzX/rEUrImlYspRDWBBGx9zq8tICGJzrsz4T8x/r4hB\r\ncR9RewIcajs8wwE46uTVvtDhuX4SOoHl5AH//oBYJEhgtHcP6Ygnsz2noo+1\r\nFa9+nLWbiIJ18NFNBONRNjtX+Ao2L84+KII94VVQIk8DUL6NcxUjEJJQ62CR\r\nHenTmLe9WSv5Vsw0HzsUfEuIApn3hwML4LnQzlUNW72nDM22XmibhZ0E/7JX\r\ng72wptFLxplvEZMpG8RFGkkOlSZ0TaquSiSxVYH2TMWIQZXNXfuTPDXnpkpn\r\nw1305PgPAzYPgTxXditcGDrOym5SdHUsdoBbZdyinUsG+KCYbWQxWivYfjcI\r\nL2Num2r8EQeFRe/qgxKIV4MSy0A4LabiLIYjB5Kc5CI5oIu0rBDwAYoaSwLS\r\n1EMw27pFIalvFX6IRTHA6cDTvQWPG7IM/bQkU5FacOAHNklZRFX/yJ3991RT\r\nc32j2f8ISTF7STOSMw4xy/kIjxu91ymxXCM=\r\n=+EqW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"squeegy","email":"alex@beautifulpixel.com"},"directories":{},"maintainers":[{"name":"squeegy","email":"alex@beautifulpixel.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ts-gl-shader_0.1.2_1674335976785_0.995123351859363"},"_hasShrinkwrap":false}},"time":{"created":"2023-01-09T04:40:12.558Z","0.1.0":"2023-01-09T04:40:12.907Z","modified":"2023-01-21T21:19:37.069Z","0.1.1":"2023-01-09T04:44:09.258Z","0.1.2":"2023-01-21T21:19:36.949Z"},"maintainers":[{"name":"squeegy","email":"alex@beautifulpixel.com"}],"description":"Strongly typed no boilerplate WebGL shaders.","homepage":"https://github.com/AlexJWayne/ts-gl-shader#readme","repository":{"type":"git","url":"git+https://github.com/AlexJWayne/ts-gl-shader.git"},"author":{"name":"Alex Wayne"},"bugs":{"url":"https://github.com/AlexJWayne/ts-gl-shader/issues"},"license":"MIT","readme":"[![Build](https://github.com/AlexJWayne/ts-gl-shader/actions/workflows/build.yml/badge.svg)](https://github.com/AlexJWayne/ts-gl-shader/actions/workflows/build.yml)\n\n# ts-gl-shader\n\n> _Strongly typed no boilerplate WebGL shaders._\n\n<img width=\"990\" alt=\"image\" src=\"https://user-images.githubusercontent.com/482/210218735-90f14598-6fe2-455e-aa51-78bdb4ce2727.png\">\n\nThis library will parse your GLSL shaders at the type level and provide an easy to use object for WebGL rendering.\n\n## Currently Unsupported\n\nPR's welcome.\n\n- [x] ~~Inspect set values in tests without having to spy on `gl.uniform3f()` and it's friends.~~\n- [x] ~~Precision overrides like `uniform highp vec3 uPos`.~~\n- [ ] Texture samplers.\n- [ ] Set GLSL arrays like `uniform vec3 uPoints[10]`.\n- [ ] Set GLSL structs.\n- [ ] VAOs\n- [ ] UBOs\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Examples](#examples)\n- [Usage](#usage)\n- [API Reference](#api-reference)\n  - [`createShaderProgram()`](#createshaderprogram)\n  - [`shaderProgram.use()`](#shaderprogramuse)\n  - [`shaderProgram.attributes[attributeName].set`](#shaderprogramattributesattributenameset)\n  - [`shaderProgram.uniforms[uniformName].set`](#shaderprogramuniformsuniformnameset)\n  - [`shaderProgram.uniforms[uniformName].setArray`](#shaderprogramuniformsuniformnamesetarray)\n- [Testing](#testing)\n\n## Features\n\n- Compiles and creates shader programs from vertex and fragment string literals.\n- Provides type safety for setting uniforms and attrubutes.\n- Caches shader locations on creation for you.\n- _FAST!_ Alomst zero overhead from calling the native APIs and allocates no objects or arrays when seting and rendering.\n\n## Installation\n\nInstall the library as a production depedency.\n\n```\nnpm install @alexjwayne/ts-gl-shader\n```\n\nAnd then import the `createShaderProgram` function.\n\n```typescript\nimport { createShaderProgram } from '@alexjwayne/ts-gl-shader'\n```\n\n## Examples\n\n- **Hello World**: [ [code](https://github.com/AlexJWayne/ts-gl-shader/blob/main/examples/hello-world/hello-world.ts) | [view](https://alexjwayne.github.io/ts-gl-shader/hello-world/) ] Render a simple fullscreen shader.\n- **Spinning Cube**: [ [code](https://github.com/AlexJWayne/ts-gl-shader/blob/main/examples/hello-world-3d/hello-world-3d.ts) | [view](https://alexjwayne.github.io/ts-gl-shader/hello-world-3d/) ] Render a cube that spins in the viewport\n\n## Usage\n\nFirst create a file for your shader.\n\n```typescript\n// my-shader.ts\nimport { createShaderProgram } from '@alexjwayne/ts-gl-shader'\n\nconst vertSrc = /* glsl */ `\n  precision mediump float;\n\n  attribute vec2 aVert2;\n  attribute vec3 aVert3;\n  attribute vec4 aVert4;\n  \n  uniform vec2 uVec2;\n  uniform vec3 uVec3;\n  uniform vec4 uVec4;\n\n  uniform float uFloat;\n  uniform bool uBool;\n\n  varying vec2 vUV;\n\n  void main() {\n    vUV = aVec2;\n    gl_Position = vec4(aVert3, 1.0);\n  }\n` as const\n\nconst fragSrc = /* glsl */ `\n  precision mediump float;\n\n  uniform int uInt; \n  uniform uint uUnsignedInt;\n  uniform vec2 uVec2; \n\n  varying vec2 vUV;\n\n  void main() {\n    gl_FragColor = vec4(vUV, 0.0, 1.0);\n  }\n` as const\n\nexport function createMyShader(gl: WebGL2RenderingContext) {\n  return createShaderProgram(gl, { vertSrc, fragSrc })\n}\n```\n\nThen use and render that shader.\n\n```typescript\n// index.ts\n\nimport { createMyShader } from './my-shader'\n\nfunction startGame(gl: WebGL2RenderingContext) {\n  const myShader = createMyShader(gl)\n\n  // other setup...\n\n  function render() {\n    // Make this shader current, so it's uniforms and attributes can be set.\n    myShader.use()\n\n    myShader.attributes.aVert2.set(someBuffer2D)\n    myShader.attributes.aVert3.set(someBuffer3D)\n    myShader.attributes.aVert4.set(someBuffer4D)\n\n    myShader.uniforms.uFloat.set(1)\n    myShader.uniforms.uVec2.set(1, 2)\n    myShader.uniforms.uVec3.set(1, 2, 3)\n    myShader.uniforms.uVec4.set(1, 2, 3, 4)\n\n    // @ts-expect-error Type safety in attributes\n    myShader.attributes.noAttributeHere.set(someBuffer) // type error\n\n    // @ts-expect-error Type safety in uniform properties\n    myShader.uniforms.noUniformHere.set(1, 2, 3) // type error\n\n    // @ts-expect-error Type safety in uniform values\n    myShader.uniforms.uVec3.set(1) // type error, expected three values for a vec3\n\n    // This library does not make any draw calls for you\n    // But it's easy to do yourself.\n    gl.drawArrays(gl.TRIANGLES, 0, triangleCount)\n\n    requestAnimationFrame(render)\n  }\n\n  requestAnimationFrame(render)\n}\n```\n\n# API Reference\n\n## `createShaderProgram()`\n\n```typescript\ncreateShaderProgram(\n  gl: WebGL2RenderingContext,\n  vertSrc: string,\n  fragSrc: string\n): ShaderProgram\n```\n\nCreates and returns a shader program that can be used for rendering.\n\n**_NOTE:_** `vertSrc` and `fragSrc` must be string literals that contain the source code of the shader itself. Otherwise Typescript cannot see the settable properties in the shader. This means you must declare the shader in a typescript file `as const`. This will not work if the shader source code is typed as `string`.\n\n```typescript\n// example\nconst shader = createShaderProgram(gl, `vertex shader source`, `fragment shader source`)\n```\n\n## `shaderProgram.use()`\n\n```typescript\nshaderProgram.use(fn?: (shaderProgram: ShaderProgram)): void\n```\n\nActivates the shader program so that its attributes and uniforms may be set, and the shader may be rendered. This _must_ be called before setting any values or rendering.\n\n```typescript\n// example\nshader.use()\n// set attributes\n// set uniforms\n// render\n```\n\nThe method optionally accepts a callback that provides the shader program `use()` was called on, which can reduce verbosity and provide a nice indent for the body of code that works with the shader.\n\n```typescript\n// example\ndeeply.nested.object.shader.use((shader) => {\n  // set attributes\n  // set uniforms\n  // render\n})\n```\n\n## `shaderProgram.attributes[attributeName].set`\n\n```typescript\nshaderProgram\n  .attributes[attributeNameHere]\n    .set(buffer: WebGLBuffer): void\n```\n\nSets a shader attribute to a `WebGLBuffer`. The `size` argument to WebGL that sets the number of values per vertex is set for you based on the data type of the attribute. For instance, a `vec3` will set a size of `3`.\n\n```typescript\n// example\n\n// shader has:\n//\n//     attribute vec3 aVert;\n//\n\nshader.use()\nshader.attributes.aVert.set(myGeometryBuffer)\n```\n\n## `shaderProgram.uniforms[uniformName].set`\n\n```typescript\nshaderProgram\n  .uniforms[uniformNameHere]\n    .set(...values: UniformSetterArgs): void\n```\n\nSets a shader uniform to a specific set of numeric values. The type of this setter function is derived from the type of the uniform in the shader. For instance, a `vec3` would accept three numbers as arguments.\n\n```typescript\n// example\n\n// shader has:\n//\n//     uniform vec4 uColor;\n//\n\nshader.use()\nshader.uniforms.uColor.set(1, 0, 1, 1)\n```\n\n## `shaderProgram.uniforms[uniformName].setArray`\n\n```typescript\nshaderProgram\n  .uniforms[uniformNameHere]\n    .setArray(values: UniformSetterArrayArg): void\n```\n\nSets a shader uniform to a specific binary typed array or tuple of `number`s. The type of this setter function is derived from the type of the uniform in the shader. For instance, a `vec3` would accept `[number, number, number] | Float32Array` but a `mat2` would accept `[number, number, number, number] | Float32Array`.\n\nIf a typed array is passed to `setArray()` this is not the correct length, a runtime error will be thrown.\n\n```typescript\n// example\n\n// shader has:\n//\n//     uniform vec4 uColor;\n//\n\nshader.use()\nshader.uniforms.uColor.setArray([1, 0, 1, 1])\nshader.uniforms.uColor.setArray(new Float32Array([1, 0, 1, 1]))\n\n// This will throw a runtime error.\nshader.uniforms.uColor.setArray(new Float32Array([1]))\n```\n\n# Testing\n\nUse `createShaderProgram.enableTestMode()` to capture the value that most recent value that was set on the `value` property of the uniform.\n\n**_NOTE:_** Test mode is set in the shader at creation time, and so it must be enabled _before_ the shader program is created.\n\nGiven a shader definition which defines custom logic such as this:\n\n```typescript\n// my-shader.ts\nconst vertSrc = /* glsl */ `\n  uniform vec2 uPos;\n  uniform vec2 uVel;\n  // ...\n`\n\nconst fragSrc = /* glsl */ `\n  //...\n`\n\nfunction createMyShader(gl: WebGL2RenderingContext) {\n  const shaderProgram = createShaderProgram(gl, vertSrc, fragSrc)\n\n  return {\n    ...shaderProgram,\n    setPhysicalProperties(x: number, y: number, vx: number, vy: number) {\n      shaderProgram.uniforms.uPos.set(x, y)\n      shaderProgram.uniforms.uVel.set(vx, vy)\n    },\n  }\n}\n```\n\nYou would test it like this:\n\n```typescript\n// my-shader.spec.ts\nbeforeEach(() => {\n  createShaderProgram.enableTestMode()\n})\n\nafterEach(() => {\n  createShaderProgram.disableTestMode()\n})\n\nit('should set the uniform', () => {\n  const shader = createMyShader(gl)\n  shader.setPhysicalProperties(1, 2, 3, 4)\n  expect(shader.uniforms.uPos.value).toEqual([1, 2])\n  expect(shader.uniforms.uVel.value).toEqual([3, 4])\n})\n```\n","readmeFilename":"readme.md"}