tsl-uniform-ui-vite-plugin
v0.10.0
Published
A Vite plugin that automatically generates GUI controls for Three.js shader uniforms using Tweakpane. This plugin simplifies shader development by providing real-time controls for uniform values without manual GUI setup.
Maintainers
Readme
tsl-uniform-ui-vite-plugin
A Vite plugin that automatically generates GUI controls for Three.js shader uniforms using Tweakpane. This plugin simplifies shader development by providing real-time controls for uniform values without manual GUI setup.
Features
- Automatic GUI generation for shader uniforms
- Supports multiple uniform types:
- Boolean
- Number
- Color
- Vector2/3/4
- Texture
- Export Configs
- Persistent configs
- Undo/redo
- Presets
- Development-only mode (disabled in production by default)
Installation
npm install tsl-uniform-ui-vite-plugin @tweakpane/core tweakpane @tweakpane/plugin-essentials tweakpane-plugin-file-importUsage
- Add the plugin to your Vite config:
// vite.config.js
import threeUniformGui from "tsl-uniform-ui-vite-plugin";
export default {
plugins: [threeUniformGui()],
};- Define your uniforms using the
uniform()function:
import { uniform } from "three/tsl";
const brightness = uniform(1.0); // number
const color = uniform(new THREE.Color(1, 0, 0)); // color
const position = uniform(new THREE.Vector3(0, 1, 0)); // vector3The plugin will automatically generate appropriate Tweakpane controls for each uniform based on its type.
Configuration Options
You can configure the plugin with the following options:
// vite.config.js
import threeUniformGui from "tsl-uniform-ui-vite-plugin";
export default {
plugins: [
threeUniformGui({
persistent: true, // Save configurations in localStorage
devOnly: true, // Only active in development mode (default)
presets: true, // Enable the presets feature
}),
],
};| Option | Type | Default | Description |
| ------------ | ------- | ------- | ------------------------------------------ |
| persistent | boolean | false | Save UI state in localStorage |
| devOnly | boolean | true | Only enable the plugin in development mode |
| presets | boolean | false | Enable the presets feature |
For backward compatibility, you can still use the old configuration style:
// vite.config.js - Legacy style
import threeUniformGui from "tsl-uniform-ui-vite-plugin";
export default {
plugins: [threeUniformGui(true)], // Persistent mode, dev only
};Supported Types
| Type | Example | GUI Control |
| ------- | ---------------------------------------------------- | --------------- |
| Boolean | uniform(false) | Checkbox |
| Number | uniform(1.0) | Slider |
| Color | uniform(new THREE.Color()) | Color Picker |
| Vector2 | uniform(new THREE.Vector2()) | X/Y Sliders |
| Vector3 | uniform(new THREE.Vector3()) | X/Y/Z Sliders |
| Vector4 | uniform(new THREE.Vector4()) | X/Y/Z/W Sliders |
| Texture | texture(new THREE.TextureLoader().load("/uv.png")) | File Picker |
Range Configuration
You can specify custom ranges for number and vector uniforms using comment-based configuration:
// @range: { min: 0, max: 2, step: 0.1 }
const brightness = uniform(1.0);
// @range: { min: -5, max: 5, step: 0.5 }
const position = uniform(new THREE.Vector3(0, 0, 0), "vec3");The comment must be placed directly above the uniform declaration. Supported options:
min: Minimum value for the slidermax: Maximum value for the sliderstep: Step size for the slider (default: 0.01)
Controlling GUI Generation
By default, the plugin generates controls for all uniforms it finds. You can control this behavior on a per-file or per-uniform basis using special comments.
Excluding Uniforms (Default Mode)
In the default mode, you can exclude specific files or uniforms from the GUI.
Exclude an Entire File
Place this comment at the top of your JavaScript or TypeScript file to prevent the plugin from processing it.
//@no-gui-file
import { uniform } from "three/tsl";
// No GUI will be generated for any uniforms in this file.
const myUniform = uniform(0.5);Exclude a Single Uniform
Place this comment directly above a uniform declaration to exclude just that one.
import { uniform } from "three/tsl";
const includedUniform = uniform(0.5);
//@no-gui
const excludedUniform = uniform(1.0); // No control will be generated for this.Include-Only Mode
For more precise control, you can switch to an "include-only" mode. In this mode, no uniforms are included by default, and you must explicitly mark the ones you want.
Enable Include-Only Mode for a File
Place this comment at the top of your file.
//@uniforms-include-only
import { uniform } from "three/tsl";
// By default, no GUI is generated in this mode.
const ignoredUniform = uniform(0.5);Include a Specific Uniform
In include-only mode, place the //@gui comment directly above a uniform to
generate a control for it.
//@uniforms-include-only
import { uniform } from "three/tsl";
const ignoredUniform = uniform(0.5); // Ignored by default.
//@gui
const includedUniform = uniform(1.0); // A control will be generated for this.
/**
* @gui
* @range: { min: 0, max: 5 }
*/
export const anotherIncludedUniform = uniform(2.5); // Also included.Caveat
Passing Types to the uniform Function
When using the uniform() function, the plugin can sometimes automatically infer the type of the uniform based on the value you pass. However, there are specific cases where you must provide the type explicitly as a second argument to ensure the plugin generates the correct GUI controls.
When Type Inference Works
The plugin can automatically determine the type in these situations:
- Literals: When you pass a direct value like a number, boolean, or a
Three.js object.
- Example:
uniform(1.0)is inferred as "number". - Example:
uniform(new THREE.Vector3(0, 1, 0))is inferred as "vector3".
- Example:
- Variables with Obvious Types: When you pass a variable that has a clear
type from its declaration.
- Example:
const vec = new THREE.Vector3(0, 1, 0); const position = uniform(vec); // Inferred as "vector3"
- Example:
In these cases, you don't need to pass the type explicitly—the plugin will handle it for you.
When You Must Pass the Type Explicitly
You must provide the type as a second argument in these situations:
- Function Calls: When the value is the result of a function call, as the
plugin cannot inspect the return value at compile time.
- Example:
const position = uniform(randomVector3(), "vec3"); // Type must be specified
- Example:
- Complex Expressions: When the value comes from an expression whose type
cannot be determined statically.
- Example:
const value = uniform(Math.random() > 0.5 ? 1 : 0, "float"); // Type should be specified
- Example:
If you don't pass the type in these cases, the plugin won't be able to determine the type and will not generate any GUI controls for that uniform.
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
