GUI Interactions#
The GuiParam class provides a declarative way to create interactive
GUI controls (dropdowns, sliders, checkboxes) that write to GPU uniform
buffers. A single GuiParam instance can be shared across multiple
renderers — it appears once in the GUI and writes to all bound targets.
Quick start#
from webgpu import GuiParam
# A slider that writes directly to a uniform field
shrink = GuiParam("slider", "Shrink", default=1.0, min=0.0, max=1.0)
shrink.bind(mesh_uniform, "shrink")
# A dropdown whose value is written to a buffer field
component = GuiParam("dropdown", "Component",
options={"Norm": -1, "x": 0, "y": 1}, default=-1)
component.bind(settings, "component")
# Side effects: when the dropdown changes, also update colormap range
component.affects(colormap, "min", values={-1: 0.1, 0: -1.0, 1: 0.5})
component.affects(colormap, "max", values={-1: 5.0, 0: 1.0, 1: 3.0})
Renderers expose their params via _gui_params. The scene collects
them automatically at render time — no manual wiring needed.
Concepts#
- bind(ref, field_name)
Write the selected value directly to a uniform buffer field. The byte offset and data type are derived automatically from the ctypes structure definition.
- affects(ref, field_name, values=…)
On change, look up the selected value in a dict and write the result to a different field. Use this for side effects like updating a colormap range when a component changes.
- Sharing
Multiple renderers can call
bind()on the sameGuiParam. The GUI shows one control that writes to all bound targets. This is the primary mechanism for keeping multiple views in sync.- Lazy resolution
bindandaffectsaccept references that are resolved at export time. You can pass:A
UniformBase(ctypes Structure) directlyAn object with a
.uniformattribute (e.g.FunctionSettings)An object with a
.uniformsattribute (e.g.Colormap)A callable that returns a uniform
Control types#
Dropdown#
mode = GuiParam("dropdown", "Mode",
options={"Real": 0, "Imag": 1, "Abs": 2},
default=0)
mode.bind(complex_settings, "mode")
The options dict maps display labels to values. The selected value
is what gets written to the buffer.
Slider#
phase = GuiParam("slider", "Phase",
default=0.0, min=0.0, max=6.283, step=0.01)
phase.bind(complex_settings, "phase")
Checkbox#
enabled = GuiParam("checkbox", "Clipping", default=True)
enabled.affects(clipping_uniforms, "mode", values={True: 1, False: 0})
Custom parameters#
You can create your own GuiParam and attach it to a renderer:
my_param = GuiParam("slider", "Threshold", default=0.5, min=0.0, max=1.0)
my_param.bind(my_renderer.uniforms, "threshold")
# Register so the scene picks it up
my_renderer._gui_params.append(my_param)
Draw([my_renderer])
How it works internally#
Renderers store
GuiParaminstances inself._gui_params.When the scene is initialized, it collects all params (deduplicated by identity — same object = one control).
Each
GuiParamexports itself as anInteractionentry containing the control definition and write targets.The JavaScript engine creates a lil-gui control and executes the buffer writes on change.
API Reference#
Declarative GUI parameters that work in both live and export paths.
A GuiParam describes a single interactive control (dropdown, slider, checkbox) that writes to one or more GPU uniform buffer fields. Multiple renderers can share the same GuiParam instance — it appears once in the GUI.
- class webgpu.gui_param.GuiParam(kind, label, *, default, options=None, min=None, max=None, step=None)#
Declarative GUI parameter. Works in both live and export paths.
- Examples:
- component = GuiParam(“dropdown”, “Component”,
options={“Norm”: -1, “x”: 0, “y”: 1}, default=-1)
component.bind(settings, “component”) # settings.uniform.component component.affects(colormap, “min”, values={-1: 0.1, 0: -1.0, 1: 0.5})
shrink = GuiParam(“slider”, “Shrink”, default=1.0, min=0.0, max=1.0) shrink.bind(mesh_uniform, “shrink”)
- affects(ref, field_name, *, values)#
On change, look up selected value in dict and write result to field.
ref: a UniformBase, or object with .uniform/.uniforms attr, or callable. values: dict mapping option values to write values, or a callable
returning such a dict (resolved at export time). E.g. {-1: 0.1, 0: -1.0, 1: 0.5}
- bind(ref, field_name)#
Write selected value directly to this uniform field on change.
ref: a UniformBase, or object with .uniform/.uniforms attr, or callable.
- export(registry)#
Produce an Interaction for the JS engine.