Shaders
A shader's uniforms as controls, from its source:
import { shader } from '@haxiomic/devui/shader';
import fragment from './fluid.frag?raw';
const s = shader(gui, fragment, { name: 'Fluid' });
const material = new THREE.ShaderMaterial({ fragmentShader: fragment, uniforms: s.uniforms }); // three
s.apply(gl, program); // raw WebGL: before drawing, with the program in use
s.write(device, uniformBuffer); // WebGPU: packed by WGSL's layout rules (or s.pack())
import.meta.hot?.accept('./fluid.frag?raw', (m) => s.update(m!.default)); // hot reload
uniform float uRoughness; // @range 0 1 @default 0.4
// @color @default #ff8800
uniform vec3 uLightColor;
uniform int uMode; // @options add multiply screen
uniform vec2 uOffset; // @view pad @range -1 1
- GLSL
uniforms, or the members of WGSL structs bound asvar<uniform>. Floats, ints, uints, booleans and vectors become controls; colours by@coloror a colour-like name (uTint,lightColor, unless you give it a@view), in linear values. - Annotations in a comment on the line, or the comment lines above:
@range min max,@softrange,@step,@log,@view knob|pad|direction|orientation…,@options a b c,@color,@default …(numbers,true, or a hex colour:#rgb,#rrggbb, or with alpha),@label,@hidden. - The values are
s.uniforms,{ name: { value } }as three takes them. Matrices and arrays are there too (identity, zeros) for your code to set.s.texture('uTex', texture)binds a sampler and shows the texture in the folder. - Hot reload:
s.update(source)keeps the values of uniforms that are still there; new ones get controls and gone ones go. - Compile errors:
s.reportErrors(gl.getShaderInfoLog(shader), source)ors.reportErrors(await module.getCompilationInfo())shows them in the folder with their lines (lineOffsetin the options for an engine's prefix). A clean compile (orupdate) clears them. - Production builds: it uses only the public folder API, so with the noop build the values you saved still reach
s.uniforms, and nothing is shown.