Recommended Tooling
Shader files
When the shaders are not trivial, it is more convenient to keep them in separate files. In that case, if you use Vite you can use vite-plugin-glsl to load the shader files.
npm install vite-plugin-glsl --save-devpnpm add -D vite-plugin-glslyarn add vite-plugin-glsl --devbun add vite-plugin-glsl --devThen add the plugin to your Vite configuration. You can enable minification of the shader source code to reduce the bundle size.
// vite.config.js
import { defineConfig } from "vite";
import glsl from "vite-plugin-glsl";
export default defineConfig({
plugins: [glsl({ minify: true })],
});Then you can import the shader files in your JavaScript or TypeScript module:
// main.js
import fragment from "./glsl/main.frag";And in the shader file you can use the #include directive to include other shader files, which allows to organize the shader code in multiple files for better maintainability.
// main.frag
#include common.glsl
void main() {
// ...
}See the documentation for more options.
Animation
When making animations that are not linear with time, you will want to animate the uniforms following a curve, or maybe spring physics. In that case, you can use the Motion library that provides lightweight and performant animation utilities that can be easily paired with Radiance.
import { glCanvas } from "@radiancejs/gl";
import { animate } from "motion";
const { uniforms } = glCanvas({
canvas: "#glCanvas",
fragment: `...`,
uniforms: {
uMorph: 0.0,
},
});
animate(0, 1, {
repeat: Infinity,
repeatType: "mirror",
onUpdate: (progress) => {
uniforms.uMorph = progress; // each update of the uniforms object will trigger a re-render
},
});See the Motion example for a complete example of how to use Motion with Radiance.