{"id":22120140,"url":"https://github.com/joshbrew/threeshaderhelper","last_synced_at":"2026-01-23T07:35:00.509Z","repository":{"id":133634956,"uuid":"451764317","full_name":"joshbrew/threeshaderhelper","owner":"joshbrew","description":"A fairly straightforward utility for ThreeJS to create shader materials and create any shaders from text with arbitrary uniforms. Modeled after ShaderToy, includes audio.","archived":false,"fork":false,"pushed_at":"2024-08-25T20:07:00.000Z","size":8790,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-25T17:05:07.914Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joshbrew.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-01-25T06:38:46.000Z","updated_at":"2024-08-25T20:07:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"eff95453-bf7b-4d15-ad80-cea1bd991471","html_url":"https://github.com/joshbrew/threeshaderhelper","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/joshbrew/threeshaderhelper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2Fthreeshaderhelper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2Fthreeshaderhelper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2Fthreeshaderhelper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2Fthreeshaderhelper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshbrew","download_url":"https://codeload.github.com/joshbrew/threeshaderhelper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbrew%2Fthreeshaderhelper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28683479,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T05:48:07.525Z","status":"ssl_error","status_checked_at":"2026-01-23T05:48:07.129Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-01T14:20:57.890Z","updated_at":"2026-01-23T07:35:00.486Z","avatar_url":"https://github.com/joshbrew.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## THREEShaderHelper\n\n`npm i threeshaderhelper`\n\nThis is a fairly straightforward utility for ThreeJS to create shader materials and apply any shaders from text with the ability to push uniform updates. It replicates a lot of functionality from ShaderToy, but we extended it to let us use arbitrary uniforms which can be generated from the shader text itself. We use it for biofeedback. It also includes its own audio decoder to get audio FFT data into the shader.\n\n### [Live Example](https://three-shader-helper.netlify.app/)\n\n## Example\n\nTo run the example, \n\n`cd example`\n\n`npm i -g tinybuild` if not installed\n\nthen\n\n`npm start` or `tinybuild` to run\n\n```js\n\n// Import necessary dependencies\nimport * as THREE from 'three'\nimport { THREEShaderHelper, Sounds } from 'threeshaderhelper/THREEShaderHelper'; // Assuming this is the file where your shader helper class is defined\nimport { Sounds } from 'threeshaderhelper/sound'; // Assuming this is where your Sounds class is defined\n\n// Function to run the default shader and play a sound\nexport function main() {\n    // Create a canvas element and append it to the body\n    // Create a button to play the sound\n    const button = document.createElement('button');\n    button.innerText = 'Play Sound';\n    document.body.appendChild(button);\n\n    // Create a dropdown selector for mesh geometry\n    const selector = document.createElement('select');\n    const options = ['plane', 'sphere', 'halfsphere', 'circle', 'vrscreen'];\n    options.forEach(option =\u003e {\n        const opt = document.createElement('option');\n        opt.value = option;\n        opt.innerText = option;\n        selector.appendChild(opt);\n    });\n    document.body.appendChild(selector);\n    \n    document.body.insertAdjacentHTML('beforeend',`\u003cbr/\u003e`)\n    \n    const canvas = document.createElement('canvas');\n    canvas.style.width = '512px';\n    canvas.style.height = '512px';\n    document.body.appendChild(canvas);\n\n    const sounds = new Sounds();\n\n    //setTimeout(()=\u003e{\n    canvas.width = canvas.clientWidth;\n    canvas.height = canvas.clientHeight;\n\n    // Instantiate the THREEShaderHelper with the canvas\n    const shaderHelper = new THREEShaderHelper(\n        canvas, \n        sounds,\n        THREEShaderHelper.defaultFragment,\n        THREEShaderHelper.defaultVertex\n    );\n    \n    // Set up the default renderer and start the animation loop\n    shaderHelper.createRenderer();\n    // shaderHelper.generateGUI();\n    // Optional: Set a background color for the renderer to see if it updates\n    shaderHelper.three.renderer.setClearColor(0x000000, 1);\n    //}, 300);\n\n    setTimeout(()=\u003e{ //test shader swap\n        shaderHelper.setShader(THREEShaderHelper.defaultFragmentSimple);\n        shaderHelper.generateGUI(); //regen gui\n    }, 1000);\n\n\n       // Handle mesh geometry selection from the dropdown\n    selector.addEventListener('change', (event) =\u003e {\n        shaderHelper.setMeshGeometry(event.target.value);\n    });\n\n    \n    // Instantiate the Sounds class when the button is clicked and play a default sound\n    button.addEventListener('click', () =\u003e {\n        //const soundURL = './sample.mp3'; // Default sound URL\n        // sounds.addSounds([soundURL], (sourceListIdx) =\u003e {\n        //     sounds.playSound(sourceListIdx);\n        // });\n        //or load your own \n        sounds.decodeLocalAudioFile((sourceListIdx) =\u003e {\n            sounds.playSound(sourceListIdx);\n        });\n    });\n}\n\nmain();\n\n```\n\nOriginally made for [Sensorium](https://app.brainsatplay.com#Sensorium) biofeedback demo with live editor. Select Audio FFT in the effects and load your mic or a random sound for the magic.\n![Capture](./Capture.PNG)\n\n### Class methods\n\n####  Static Methods\n`THREEShaderHelper.generateShaderGeometry(type, width, height, fragment, vertex)`\nGenerates a shader mesh with the specified geometry type, dimensions, and shaders. Returns a THREE.Mesh object with a ShaderMaterial applied.\n\n`THREEShaderHelper.generateShaderMaterial(fragment, vertex)`\nCreates a ShaderMaterial using the provided fragment and vertex shaders. Returns a THREE.ShaderMaterial.\n\n`THREEShaderHelper.createMeshGeometry(type, width, height)`\nGenerates geometry based on the specified type ('plane', 'sphere', 'circle', 'halfsphere', 'vrscreen'). Returns the corresponding THREE.Geometry.\n\n`THREEShaderHelper.downsample(array, fitCount, scalar)`\nDownsamples the provided array to the specified size, averaging values if necessary. Useful for reducing data size.\n\n`THREEShaderHelper.upsample(data, fitCount, scalar)`\nUpsamples the provided data array to the specified size using linear interpolation. Useful for increasing data resolution.\n\n#### Frontend Methods\n`this.createRenderer(canvas, controls=true)`\nInitializes the Three.js renderer, scene, and camera, setting up the environment for rendering the shader. togglable orbit controls. \n\n`this.destroyRenderer()`\nCleans up and disposes of all renderer resources, including geometry and materials, to free up memory.\n\n`this.generateGUI(uniformNames, material)`\nCreates a GUI interface for interacting with the shader's uniforms, allowing for real-time adjustments.\n\n`this.clearGUI()`\nRemove the GUI items you created, if it exists. Auto clears if calling generateGUI multiple times.\n\n#### More Instance Methods for Frontend Use\n`this.setShader(fragmentShaderText, vertexShaderText, onchange, matidx=0, name, author)`\nSets a shader from provided text for both fragment and vertex shaders, and applies it to the specified material index.\n\n`this.addUniformSetting(name, defaultValue, type, callback, min, max, step)`\nAdds a new uniform setting to the shader, allowing for customization and interaction through GUI controls.\n\n`this.addNewShaderMesh(fragment, vertex, type, width, height, name, author)`\nCreates and adds a new shader mesh to the scene with the specified fragment and vertex shaders, geometry type, and dimensions.\n\n`this.setUniforms(uniforms)`\nUpdates the values of the specified uniforms, allowing for dynamic interaction with the shader's parameters.\n\n`this.setMeshGeometry(type, matidx=0)`\nSets the geometry of the specified mesh to a new type, such as 'plane' or 'sphere', and updates its rotation.\n\n`this.setMeshRotation(anglex, angley, anglez, matidx=0)`\nAdjusts the rotation of the specified mesh to the provided angles.\n\n`this.resetMaterialUniforms(material, uniformNames)`\nResets the material's uniforms to their default values based on the current uniform settings.\n\n`this.updateMaterialUniforms(material, uniformNames, meshType)`\nDynamically updates the material's uniforms based on the current time, mouse input, and other parameters.\n\n`this.updateAllMaterialUniforms()`\nUpdates all the uniforms for all materials in the scene simultaneously, ensuring consistency across multiple shaders.\n\n`this.swapShader(matidx, onchange)`\nSwaps the shader for the specified material index and applies any additional changes using the provided callback.\n\n`this.setChannelTexture(channelNum, imageOrVideo, material)`\nSets a texture or video as the input for a specific channel in the shader, updating the corresponding uniform values.\n\n#### Default Shaders\n`THREEShaderHelper.defaultVertex`\nA basic vertex shader used as a default when no custom vertex shader is provided.\n\n`THREEShaderHelper.defaultFragment`\nA comprehensive fragment shader with multiple uniform inputs, including time, resolution, and audio data.\n\n`THREEShaderHelper.defaultFragmentSimple`\nA simple shader with audio and other input\n\n\n# Default Uniforms in `THREEShaderHelper`\n\nThe `THREEShaderHelper` class provides a set of default uniforms that can be used in your shaders. Below is a list of these uniforms, along with the corresponding GLSL code that needs to be added to your shader. It vaguely mimics shadertoy, the channel/image texture stuff is untested right now fyi\n\n## 1. `iResolution`\n- **Type**: `vec2`\n- **Description**: Represents the display resolution of the shader.\n- **GLSL Code**: \n    ```glsl\n    uniform vec2 iResolution;\n    ```\n\n## 2. `iTime`\n- **Type**: `float`\n- **Description**: The elapsed time in seconds since the start of the shader.\n- **GLSL Code**: \n    ```glsl\n    uniform float iTime;\n    ```\n\n## 3. `iTimeDelta`\n- **Type**: `float`\n- **Description**: The time difference between the current frame and the last frame.\n- **GLSL Code**: \n    ```glsl\n    uniform float iTimeDelta;\n    ```\n\n## 4. `iFrame`\n- **Type**: `int`\n- **Description**: The current frame number.\n- **GLSL Code**: \n    ```glsl\n    uniform int iFrame;\n    ```\n\n## 5. `iFrameRate`\n- **Type**: `float`\n- **Description**: The current frame rate in frames per second.\n- **GLSL Code**: \n    ```glsl\n    uniform float iFrameRate;\n    ```\n\n## 6. `iChannelTime`\n- **Type**: `float[4]`\n- **Description**: Time for each input channel (i.e., texture or video).\n- **GLSL Code**: \n    ```glsl\n    uniform float iChannelTime[4];\n    ```\n\n## 7. `iChannelResolution`\n- **Type**: `vec3[4]`\n- **Description**: Resolution for each input channel.\n- **GLSL Code**: \n    ```glsl\n    uniform vec3 iChannelResolution[4];\n    ```\n\n## 8. `iChannel0`, `iChannel1`, `iChannel2`, `iChannel3`\n- **Type**: `sampler2D`\n- **Description**: Sampler for each input texture or video channel.\n- **GLSL Code**: \n    ```glsl\n    uniform sampler2D iChannel0;\n    uniform sampler2D iChannel1;\n    uniform sampler2D iChannel2;\n    uniform sampler2D iChannel3;\n    ```\n\n## 9. `iSampleRate`\n- **Type**: `float`\n- **Description**: The audio sample rate in Hz.\n- **GLSL Code**: \n    ```glsl\n    uniform float iSampleRate;\n    ```\n\n## 10. `iDate`\n- **Type**: `vec4`\n- **Description**: The current date (year, month, day, time).\n- **GLSL Code**: \n    ```glsl\n    uniform vec4 iDate;\n    ```\n\n## 11. `iMouse`\n- **Type**: `vec4`\n- **Description**: Mouse coordinates in the window (x, y, click position).\n- **GLSL Code**: \n    ```glsl\n    uniform vec4 iMouse;\n    ```\n\n## 12. `iMouseInput`\n- **Type**: `bool`\n- **Description**: Indicates whether the mouse is clicked.\n- **GLSL Code**: \n    ```glsl\n    uniform bool iMouseInput;\n    ```\n\n## 14. `iAudio`\n- **Type**: `float[256]`\n- **Description**: The audio FFT data sampled from the sound object provided\n- **GLSL Code**: \n    ```glsl\n    uniform float iAudio[256];\n    ```\n\n\n## 13. `iImage`\n- **Type**: `sampler2D`\n- **Description**: The main texture (usually the canvas) to be used in the shader.\n- **GLSL Code**: \n    ```glsl\n    uniform sampler2D iImage;\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshbrew%2Fthreeshaderhelper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshbrew%2Fthreeshaderhelper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshbrew%2Fthreeshaderhelper/lists"}