Interactive 3D shape generation tool built with Rust and Bevy.
Runtime tuning lives in config.toml at the repository root.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
The current prototype focuses on a fast local development loop and a usable vertical slice:
- inertial camera rotation on all 3 axes with preserved angular momentum
- keyboard zoom
- recursive shape spawning from parent vertices, edges, or faces
- selectable child shape type
- adjustable child scale ratio
- two-step in-app help overlay with text controls plus a hoverable neutral-mode keyboard map
- pinned F2 control page with a compact strip plus a second-press scrolling list for shader FX toggles/LFOs and scene, stage, and material runtime parameters, including direct numeric entry for numeric fields
- built-in screenshot capture for manual and scripted verification
- scene preset save/load/free workflow with 100 slots and collision resolution
- Blender
.blendexport with compositor reconstruction and embedded effect/LFO metadata - containment rejection so obviously hidden fully-inside spawns are skipped
- camera-output shader stack with hard-wrap wavefolder, lens distortion, gaussian blur, bloom, and edge detection
- Windows
- Rust stable MSVC toolchain
- Visual Studio 2022 Build Tools with the C++ workload
- Blender 5.x in
PATHif you want.blendexport (optional for normal app use)
UI text prefers Carbon Plus if you place a licensed font file in assets/fonts/.
Supported filenames:
assets/fonts/carbonplus-regular-bl.otfassets/fonts/CarbonPlus-Regular.ttfassets/fonts/CarbonPlus-Regular.otfassets/fonts/Carbon Plus Regular.ttfassets/fonts/Carbon Plus Regular.otfassets/fonts/CarbonPlus.ttfassets/fonts/Carbon Plus.ttfassets/fonts/carbonplus-bold-bl.otfassets/fonts/carbonplus-light-bl.otf
If you override ui.font_candidates in config.toml, the built-in Carbon Plus filenames above are still appended as fallback candidates. If none of those files are present, the app falls back to Bevy's default font.
The app loads config.toml from the repository root on startup.
Current configuration sections:
window: title, resolution, and present moderendering: clear color, ambient light, and optional stage floor/backdrop surfacescamera: initial orbit, motion tuning, and angular-momentum preservationgeneration: root shape, default child shape, default spawn placement mode, scale limits, twist defaults and bounds, spawn cadence, and spawn heuristicslighting: directional, point, and optional accent light colors, positions, and intensitieseffects: camera-output shader effectsmaterials: color progression, legacy or scene-wide procedural material families, PBR tuning, and live opacity defaultscapture: screenshot output directory and default capture delayui: font candidates plus overlay sizing and colors
If config.toml is missing, the app falls back to the same built-in defaults.
Live twist controls use these generation settings:
twist_per_vertex_radians: startup default for the child twist angletwist_adjust_step: per-keypress twist changetwist_hold_delay_secs: how long to hold before twist repeat startstwist_repeat_interval_secs: time between repeated twist updates while heldmin_twist_per_vertex_radians/max_twist_per_vertex_radians: live clamp range, with0.0as the minimum allowed floor
Live child-offset controls use these generation settings:
default_vertex_offset_ratio: startup default for the center offset from the selected parent attachment point, measured in child-radius unitsvertex_offset_adjust_step: per-keypress offset changevertex_offset_hold_delay_secs: how long to hold before offset repeat startsvertex_offset_repeat_interval_secs: time between repeated offset updates while heldmin_vertex_offset_ratio/max_vertex_offset_ratio: live clamp range, with0.0as the minimum allowed floor
Live spawn-exclusion controls use these generation settings:
default_vertex_spawn_exclusion_probability: startup default for the chance that a given attachment in the current spawn mode is skipped during spawningvertex_spawn_exclusion_adjust_step: per-keypress probability changevertex_spawn_exclusion_hold_delay_secs: how long to hold before repeat startsvertex_spawn_exclusion_repeat_interval_secs: time between repeated probability updates while heldmin_vertex_spawn_exclusion_probability/max_vertex_spawn_exclusion_probability: live clamp range, limited internally to[0.0, 1.0]
Camera-output effects run in this order:
effects.lens_distortion: warp the camera image with radial, tangential, and chromatic lens termseffects.color_wavefolder: hard-wrap the distorted camera color by amplification plus remaindereffects.gaussian_blur: blur the distorted and wavefolded imageeffects.bloom: add a bright-pass glow over the processed imageeffects.edge_detection: detect edges from the distorted and wavefolded image and mix a configurable edge color over it
Camera-output color wavefolder uses these effects.color_wavefolder settings:
enabled: turns the hard-wrap post-process on or offgain: amplifies the color before wrappingmodulus: the divisor whose remainder is kept after amplification
Camera-output lens distortion uses these effects.lens_distortion settings:
enabled: turns lens warping on or offstrength: primary radial barrel/pincushion term (k1)radial_k2/radial_k3: higher-order radial shaping terms for the shoulder of the warpcenter: distortion center in normalized screen coordinatesscale: per-axis distortion scale for anamorphic or elliptical warpingtangential: tangential skew terms that decenter the lens modelzoom: scales the distorted image to keep more or less of the warped frame in viewchromatic_aberration: shifts color channels apart along the distortion field
Camera-output gaussian blur uses these effects.gaussian_blur settings:
enabled: turns blur on or offsigma: controls the gaussian falloffradius_pixels: blur radius in pixels, clamped to16in the current single-pass shader
Camera-output bloom uses these effects.bloom settings:
enabled: turns bright-pass bloom on or offthreshold: minimum brightness that contributes to the glowintensity: bloom contribution added back onto the processed imageradius_pixels: bloom blur radius in pixels, clamped to16in the current single-pass shader
Camera-output edge detection uses these effects.edge_detection settings:
enabled: turns the edge pass on or offstrength: scales edge magnitude before thresholdingthreshold: subtracts a floor from the detected edge magnitudemix: blends the edge color over the processed imagecolor: RGB edge overlay color
The in-app F2 control page starts from the values loaded from config.toml at launch.
- Live edits affect the running app only.
- The F2 control list covers shader effects plus scene, stage, and material runtime controls, including enum-like fields such as child shape, spawn placement mode, add mode, stage toggles, and procedural surface families.
- The first
F2press opens the compact strip, the secondF2press opens a scrolling parameter list with an LFO detail panel beside the selected row, and the thirdF2press closes the page. Ctrl + Up/Ctrl + Downselect the active F2 control, with hold-to-repeat.Left/RightorTab/Shift + Tabswitch the active F2 field between value, LFO amplitude, LFO frequency, and LFO shape when the selected parameter supports LFOs.Up/Downadjust the active F2 field.Shiftmakes the step coarser andAltmakes it finer.Spacetoggles the selected shader effect on or off.Ltoggles the selected parameter LFO on or off when the selected parameter supports LFOs.- Type digits,
.,-, or+to set the active numeric field directly.Backspaceerases the typed numeric input. - LFO shapes currently available are
sine,triangle,saw,square,stepped random, andbrownian motion. Enterresets the selected F2 field.Shift + Enterresets all F2 controls to their startup defaults.- Shader-effect parameters expose LFO fields, and so do the supported numeric scene/material parameters that update the current scene immediately. Other scene, stage, and material controls remain value-only.
Esccloses the active control page.- The tuner does not write changes back to
config.tomlautomatically.
Live opacity controls use these materials settings:
default_opacity: startup default for all object materialsopacity_adjust_step: per-keypress opacity changemin_opacity/max_opacity: live clamp range
Press F3 to toggle scene preset mode. The bottom preset strip shows the 10 banks (0-9), each with 10 slots.
Preset behavior:
- two digits (
00to99) load the assigned scene preset for that bank and slot Sarms saving, then the next two digits choose the bank and slot assignmentDeletearms freeing, then the next two digits clear that slot assignment from any matching preset filesEsccloses the preset page- if multiple preset files claim the same slot, a chooser appears;
Up/Downselects which file keeps the slot andEnterconfirms it
Preset files are stored as TOML under scene-presets/. Filenames are unique and are not based on the bank and slot, so saving a new preset never overwrites an older file by name. The bank and slot assignment lives inside the preset file metadata.
Current scene preset contents:
- render clear color and ambient light
- directional and point light settings
- stage visibility plus floor/backdrop toggles
- material palette/PBR settings, procedural surface-family settings, and current global opacity
- camera position, distance, and momentum
- current shape tree, selected child shape, spawn placement mode, scale ratio, twist, outward offset, and global spawn-exclusion probability
- live camera-output effect values plus all per-parameter LFO settings
Press F4 during a normal interactive run to write a timestamped Blender scene under blend-exports/.
What the .blend currently includes:
- the full shape scene as real Blender mesh objects
- the current camera, directional light, point light, and world background
- per-object materials with transparency, metallic, roughness, and reflectance-derived specular
- compositor recreation for lens distortion, hard-wrap wavefolder, gaussian blur, bloom, and edge detection
- embedded
Textdatablocks with the full Intergen export snapshot, evaluated effect values, and all effect/LFO runtime settings
Current limitation:
- LFOs are preserved inside the
.blendas metadata, but they are not yet converted into native Blender animation drivers or node animation - Blender's built-in compositor does not expose every Intergen lens-distortion term directly, so the exported compositor is a best-effort approximation while the full original parameters remain in the embedded metadata
For automated export-and-exit from the command line:
cargo run -- --export-blend blend-exports\check.blend --export-blend-delay-frames 120cargo runThe default development build enables Bevy dynamic linking for faster rebuilds.
If you want to run without that mode:
cargo run-plainTo save a verification screenshot and exit automatically:
cargo run -- --capture screenshots\check.png --capture-delay-frames 120To load a scene preset on startup:
cargo run -- --load-scene-preset scene-presets\example.tomlDuring a normal interactive run, press F12 to save a screenshot under screenshots/.
cargo testWithout dynamic linking:
cargo test-plainArrow Up/Arrow Down: pitch cameraArrow Left/Arrow Right: yaw cameraQ/E: roll cameraW/S: zoom in / outBackspace: stop camera rotation momentum, or erase typed numeric F2 input while the F2 page is focusedF1orH: cycle help views between hidden, text, and keyboard-map overlaysF2: open the compact F2 control page, second press opens the list page, third press closes itF3: open or close the scene preset pageEsc: close the active control pageCtrl + Up/Ctrl + Downin F2: select the active F2 control, with hold-to-repeatLeft/RightorTab/Shift + Tabin F2: switch the active F2 fieldUp/Downin F2: adjust the active F2 fieldSpacein F2: toggle the selected shader effect on or offLin F2: toggle the selected parameter LFO on or off when supportedShiftin F2: coarse adjustment modifierAltin F2: fine adjustment modifierEnterin F2: reset the active F2 fieldShift + Enterin F2: reset all F2 controls to their startup defaultsF4: export the current scene toblend-exports/as a Blender.blendF12: save a screenshot toscreenshots/R: reset the scene with the currently selected shape as the new rootSpace: spawn child shapes with the current placement mode, or hold to keep spawningCtrl + Space: cycle the add mode between single spawn and fill-current-level spawningG: cycle the spawn placement mode between vertices, edges, and faces1: select cube2: select tetrahedron3: select octahedron4: select dodecahedron-: decrease child scale ratio+: increase child scale ratio[or,: decrease child twist angle, or hold to keep decreasing]or.: increase child twist angle, or hold to keep increasingZ: decrease the child outward offset, or hold to keep decreasingX: increase the child outward offset, or hold to keep increasingC: reset the child outward offset to the configured defaultV: decrease the global spawn-exclusion probability, or hold to keep decreasingB: increase the global spawn-exclusion probability, or hold to keep increasingN: reset the global spawn-exclusion probability to the configured defaultO: decrease global object opacityP: increase global object opacityI: reset global object opacity to the configured defaultT: reset the child twist angle to the configured default
cargo rundoes not always recompile. If nothing relevant changed, Cargo reuses the existing build output.- Editing Rust source files should usually rebuild only
intergen. - Changing
Cargo.toml, enabled features, toolchain, or profile settings can trigger a larger one-time rebuild. cargo checkis the fastest command for type-checking without launching the app.
Implemented now:
- custom meshes for cube, tetrahedron, octahedron, and dodecahedron
- recursive level-by-level spawning
- metallic lit PBR scene
- optional stage floor/backdrop plus procedural material surface families
- F2 control page for shader effects, scene parameters, stage toggles, and material tuning
- scene preset save/load/free support with slot-collision resolution
- camera-output hard-wrap wavefolder, lens distortion, gaussian blur, bloom, and edge-detection post process
- Blender export with embedded snapshot and effect/LFO metadata
- unit tests for geometry counts and spawn ordering
Not implemented yet:
- mouse controls
- hardware ray tracing
- more advanced visibility heuristics than simple containment rejection
- automatic conversion of runtime LFOs into native Blender animation/drivers
intergen is licensed under GPL-3.0-or-later.
Copyright (C) 2026 Francesco Stablum.
See LICENSE for the project notice and COPYING for the full GNU General Public License text.











