Procedural 3D for the age of agents

Describe the scene.
Watch it being built.

GeneraFX is a procedural modeller, animator and renderer with an AI agent at the controls. You say what you want; the agent builds the node networks, writes the C# that shapes the geometry and the GLSL that runs on the GPU, lights the shot and renders it.

The upright piano beside this text was built that way, down to the hammers and the strings, and a MIDI file plays it: every key and hammer moves with the notes, and the music you hear comes from the same file. Everything happens in the open, in nodes and code you can read, change and undo.

In development · coming soon From a prompt to a shader
Built by an agent, driven by you

A tarantula you steer from the keyboard

Drive and record

One take, steered live with the keyboard and recorded as animation, then rendered in Forge with every hair.

How it was made

An agent through MCP, a person at the keys

The agent started from the science: a red-knee tarantula, Brachypelma hamorii, a 53 mm body and a 14 cm leg span, seven segments to a leg, read from the species description and turned into a node network. It grew 150,000 hairs with Fur, longer on the abdomen, orange on the knees, rendered as real fibres.

Then the rig: a skeleton with the tarantula's own proportions, hinge IK so each leg bends only in its plane, and a Body Control node for height, pitch, roll, twist, walking and turning. The feet are planted where they land and never slide, whatever the body does.

The last part is yours. In the Drive panel you steer it live: W and S walk, A and D turn, the arrows lean it forward and shift its weight, R and F raise and lower it, or a gamepad. Drive and record writes every move as keys, one take on top of another, and each take is one undo step. A spotlight that looks at the spider follows it across the floor.

MCPserver built in: the agent works in the program
C# & GLSLwritten by the agent, live on the GPU
2 + 1render engines: Forge, Spark, and Glint spectral
Modulesevery part replaceable, every node a plugin
Made for AI agents

The agent does not suggest. It builds.

GeneraFX runs a Model Context Protocol server on your machine. An AI agent connected to it works inside the program with the same tools you have: it creates objects, wires the node networks that make the models, sets materials, lights and cameras, keys the animation, runs the simulations, looks at the views to check its own work, and renders stills, sequences and MP4s.

Help > AI assistant opens an agent already connected. You talk, it works, you watch the network grow in front of you. Every action is one step in the undo stack, so nothing it does is out of your hands; and when you prefer to move a light or a camera yourself, it picks up from there.

ModelsNode networks built and wired by the agent: splines, lathes, lofts, booleans, scatters, variants
CodeAnvil C# for geometry and GLSL for materials, written, compiled and tuned on the fly
LookIt takes screenshots of any view, in wireframe or rendered, and corrects what it sees
MaterialsFrom the library or from scratch, baked to textures for export
AnimationKeys, curves and expressions; a spin that slows, wobbles and falls
SimulationLiquids, fire, rigid bodies, cloth, hair, particles, flocks, crowds
RenderForge, Spark or Glint, single frames or whole sequences to MP4
ExportglTF with baked materials, STL, 3MF, OBJ
Anvil & GLSL

A complex GPU shader is now a sentence

Writing a procedural shader used to mean knowing GLSL, the renderer's conventions and a good deal of maths. In GeneraFX you describe the surface and the agent writes the shader. The same code runs in the real time views, in Spark and in the Forge path tracer; on NVIDIA cards GeneraFX translates it to CUDA for OptiX by itself. You see the result in a second or two, and you ask again until it is right.

Geometry works the same way. Anvil is C# that runs on every point, every primitive or once per object, and the agent uses it wherever a node would be missing: a smooth lathe profile, a string of lights, a field of colours. Any param line in the code becomes a slider in the panel, so the knobs that matter are there for you to turn, without touching the code.

GLSL material

Written by the agent
“A lacquered wooden top: red and yellow segments, a blue band on the rim, a blue and cream spiral on the cap, a wooden handle and a steel tip.”
vec3 p = s.Po; // mm, tip at 0 float a = atan(p.z, p.x), r = length(p.xz), y = p.y; float seg = floor((a / 6.2831853 + 0.5) * 8.0); vec3 c = mod(seg, 2.0) < 1.0 ? red : yel; if (y > 36.5 && y < 39.5) c = blu; // band on the rim float sp = 0.5 + 0.5 * sin(a * 3.0 + r * 0.55); // spiral if (y >= 41.0 && y < 51.0) c = sp > 0.5 ? blu : crm; if (y >= 51.0) c = wood * (0.8 + 0.2 * fbm(p * 0.6, 3)); m.albedo = c; m.coat = 1.0; m.coatRoughness = 0.06; if (y < 6.0) { m.metallic = 1.0; m.roughness = 0.22; } // steel tip

This is the top spinning in the clip below. The stone wall behind the torch, Voronoi stones with uneven mortar and real relief, came out of the same kind of request.

Anvil geometry

Written by the agent
“Two strings of fairy lights sagging behind the table, mostly warm bulbs with a few cool ones.”
for (int f = 0; f < 2; f++) { float z = f == 0 ? -1.3f : -1.9f; float y0 = f == 0 ? 0.24f : 0.36f, sag = 0.12f + f * 0.03f; int n = f == 0 ? 30 : 40; for (int i = 0; i < n; i++) { float u = i / (float)(n - 1), x = -1f + 2f * u; float y = y0 - sag * (1 - (2 * u - 1) * (2 * u - 1)); // the sag int p = addpoint(vec3(x, y, z)); float h = rand(i * 12.9898f + f); setpointattrib(p, "Cd", h < 0.85f ? warm : cool); } }

The points become bulbs with Clone to Points and an emissive material; out of focus, they are the bokeh behind the spinning top.

Oak parquet and a leather sofa in Forge

Oak Parquet Satin Library

A floor from the GeneraFX library, written by an agent from a description and then refined by talking: “the reflection is too smooth, break it up with the grain”, “a little less”. Five laying patterns, uneven joints and bevels, grain and growth rings, a different tone for every plank, and a satin varnish whose gloss and bump follow the grain. The aged leather of the sofa is another shader made the same way, from a photo of a real sofa. Forge, sun through a window.

The shader

GLSL, 79 lines
“An oak parquet with real joints and bevels, grain and rings, each plank a little different, and a choice of laying patterns.”
param int pattern = 0; // 0..4 Disegno: 0 listoni, 1 correnti, 2 spina di pesce, 3 ungherese, 4 intrecciato param float rot = 0.0; // -90..90 Rotazione disegno (gradi) param float plank_l = 900.0; // 100..2000 Lunghezza doga (mm) param float plank_w = 120.0; // 30..400 Larghezza doga (mm) param float stagger = 1.0; // 0..1 Sfalsamento righe (listoni/correnti) // tab: Joints param float gap_w = 1.2; // 0..10 Fessura (mm) param float bevel_w = 3.5; // 0..20 Smusso (mm) param float edge_noise = 0.7; // 0..3 Irregolarita bordi (mm) param float edge_freq = 60.0; // 5..400 Frequenza irregolarita bordi param color col_gap = vec3(0.012, 0.007, 0.004); // Colore fessura // tab: Grain param float grain_scale = 1.0; // 0.2..4 Scala venatura param float grain_contrast = 0.6; // 0..1 Contrasto venatura param float tone_var = 0.6; // 0..1 Variazione tono doghe param float ring_amount = 1.0; // 0..1 Anelli di crescita param color col_dark = vec3(0.20, 0.10, 0.045); // Legno scuro param color col_light = vec3(0.62, 0.40, 0.20); // Legno chiaro // tab: Finish param float rough_base = 0.38; // 0.05..0.9 Roughness media param float rough_plank = 0.12; // 0..0.4 Var. roughness tra doghe param float rough_grain = 0.10; // 0..0.4 Roughness da venatura param float pores = 0.03; // 0..0.3 Pori (bump) param float wave = 0.06; // 0..0.4 Ondulazione (bump) param float tilt_amt = 0.25; // 0..1 Inclinazione doghe (bump) vec3 W = s.P * 0.001; float ang = rot * 0.0174533; vec2 q = vec2(cos(ang) * W.x - sin(ang) * W.z, sin(ang) * W.x + cos(ang) * W.z); float L = plank_l * 0.001; float Wd = plank_w * 0.001; float gm = gap_w * 0.001; float bm = bevel_w * 0.001; float al = 0.0; float ac = 0.0; vec2 pid = vec2(0.0); if (pattern <= 1) { float row = floor(q.y / Wd); float off = (pattern == 0) ? fract(sin(row * 12.9898) * 43758.5453) * L * stagger : mod(row, 2.0) * 0.5 * L * stagger; float uu = q.x + off; float cl = floor(uu / L); al = uu - cl * L; ac = q.y - row * Wd; pid = vec2(cl, row); } else if (pattern == 2) { float k = max(1.0, floor(L / Wd + 0.5)); L = k * Wd; vec2 c = q / Wd; float a = floor(c.x); float b = floor(c.y); float n = floor((a + b) / k); if (mod(n, 2.0) < 0.5) { al = (c.x + b - n * k) * Wd; ac = (c.y - b) * Wd; pid = vec2(n, b); } else { al = (c.y + a - n * k) * Wd; ac = (c.x - a) * Wd; pid = vec2(n, a + 0.37); } } else if (pattern == 3) { float cw = L * 0.70710678; float ci = floor(q.x / cw); float xl = q.x - ci * cw; float v = (mod(ci, 2.0) < 0.5) ? (q.y - xl) : (q.y + xl - cw); v *= 0.70710678; float j = floor(v / Wd); al = xl * 1.41421356; ac = v - j * Wd; pid = vec2(ci, j); } else { float n = max(1.0, floor(L / Wd + 0.5)); float Wb = L / n; Wd = Wb; float ix = floor(q.x / L); float iz = floor(q.y / L); float lx = q.x - ix * L; float lz = q.y - iz * L; if (mod(ix + iz, 2.0) < 0.5) { float j = floor(lz / Wb); al = lx; ac = lz - j * Wb; pid = vec2(ix * 9.0 + iz * 5.0, j); } else { float j = floor(lx / Wb); al = lz; ac = lx - j * Wb; pid = vec2(ix * 9.0 + iz * 5.0 + 0.5, j); } } float rnd = fract(sin(dot(pid, vec2(12.9898, 78.233))) * 43758.5453); float rnd2 = fract(sin(rnd * 91.7 + pid.y) * 4375.5453); float d = min(min(al, L - al), min(ac, Wd - ac)); d += edge_noise * 0.001 * fbm(vec3(al * edge_freq, ac * edge_freq, rnd * 13.0), 2) * 2.0; float gapm = 1.0 - smoothstep(gm * 0.4, gm * 1.5, d); float bev = 1.0 - smoothstep(gm * 1.5, max(bm, gm * 1.6), d); float g1 = fbm(vec3(al * 3.0 / grain_scale + rnd * 5.0, ac * 70.0 / grain_scale + rnd * 40.0, rnd * 9.0), 4); float rings = 0.5 + 0.5 * sin((ac * 55.0 / grain_scale + g1 * 5.0 + rnd2 * 6.0) * 3.0); vec3 tint = mix(col_dark, col_light, 0.5 - 0.5 * tone_var + tone_var * rnd); float gv = mix(0.5, rings * 0.6 + 0.4 * (0.5 + g1), ring_amount); vec3 c = mix(tint * (1.0 - 0.35 * grain_contrast), tint * (1.0 + 0.12 * grain_contrast), gv); c *= 1.0 - 0.35 * bev; c = mix(c, col_gap, gapm); m.albedo = c; float wear = 0.5 + 0.5 * fbm(W * 4.0, 3); float rg = rough_base + rough_plank * (rnd - 0.5) * 2.0 + rough_grain * (rings - 0.5) + 0.08 * (wear - 0.5); m.roughness = mix(clamp(rg, 0.12, 0.8), 0.9, max(gapm, bev * 0.6)); // il riflesso segue la venatura: la vernice piu' opaca e meno piena sulle fibre, lucida fra l'una e l'altra float gr = clamp(0.5 + (g1 - 0.5) * 0.8 + (rings - 0.5) * 0.3, 0.0, 1.0); m.coatRoughness = mix(0.15, 0.27, gr); m.coat *= 0.85 + 0.3 * (1.0 - gr); m.roughness = clamp(m.roughness + 0.06 * (gr - 0.5), 0.08, 0.9);
White marble floor with granite bands in a hall with columns

Marble with granite bands Library

From a photo of a real hall: white marble slabs with grey veins, dark granite bands and squares where they cross, laid at 45 degrees. The veins are stretched noise with a soft halo plus Voronoi cracks, so every slab is a different cut of the block. A hall with columns and bronze glazing, built by the agent around it, low sun over the sea, Forge.

The shader

GLSL, 65 lines
“This floor: big white marble slabs with grey veins and dark granite bands between them, at 45 degrees.”
// pavimento di marmo bianco venato a lastre quadre, con fasce di granito grigio e quadrotti agli incroci, posato a 45 gradi param float slab = 900.0; // 200..2000 Lastra (mm) param float band = 150.0; // 20..400 Fascia (mm) param float rot = 45.0; // -90..90 Rotazione posa (gradi) param float joint = 1.0; // 0..5 Fuga (mm) // tab: Marble param color marble = vec3(0.90, 0.895, 0.88); // Marmo param color veinc = vec3(0.36, 0.37, 0.40); // Venature param float veins = 0.85; // 0..1 Quantita venature param float vscale = 1.0; // 0.2..4 Scala venature param float vwidth = 0.035; // 0.005..0.2 Spessore venature param float clouds = 0.5; // 0..1 Nuvole grigie // tab: Band param color granite = vec3(0.25, 0.24, 0.25); // Granito param float speckle = 0.6; // 0..1 Puntinatura // tab: Finish param float rough_m = 0.05; // 0.02..0.6 Roughness marmo param float rough_g = 0.22; // 0.02..0.8 Roughness granito vec3 W = s.P * 0.001; float ang = rot * 0.0174533; vec2 q = vec2(cos(ang) * W.x - sin(ang) * W.z, sin(ang) * W.x + cos(ang) * W.z); float S = slab * 0.001; float B = band * 0.001; float Pd = S + B; vec2 cell = floor(q / Pd); vec2 f = q - cell * Pd; // la fascia occupa 0..B su ogni asse, la lastra B..Pd; agli incroci un quadrotto float isBand = max(step(f.x, B), step(f.y, B)); float dx = min(min(f.x, abs(f.x - B)), Pd - f.x); float dy = min(min(f.y, abs(f.y - B)), Pd - f.y); float d = min(dx, dy); float jm = 1.0 - smoothstep(joint * 0.0004, joint * 0.001, d); // marmo: ogni lastra un pezzo diverso del blocco vec2 o = vec2(hash13(vec3(cell, 3.0)), hash13(vec3(cell, 7.0))) * 40.0; // le venature corrono in una direzione (diversa di poco da lastra a lastra): rumore stirato float va = 0.6 + (hash13(vec3(cell, 11.0)) - 0.5) * 0.7; vec2 qr = vec2(cos(va) * q.x + sin(va) * q.y, -sin(va) * q.x + cos(va) * q.y) + o; vec3 vp = vec3(qr.x * 0.45, qr.y * 2.0, 0.0) * 1.6 / vscale; vec3 wv = vec3(fbm(vp + vec3(3.1, 0.0, 1.7), 4), fbm(vp + vec3(-5.2, 0.0, 4.4), 4), 0.0); float n1 = fbm(vp + wv * 1.1, 6); float v1 = 1.0 - smoothstep(0.0, vwidth, abs(n1)); float n2 = fbm(vp * 2.1 + wv * 1.6 + vec3(9.0, 0.0, 2.0), 5); float v2 = 1.0 - smoothstep(0.0, vwidth * 0.5, abs(n2)); float vis = smoothstep(-0.25, 0.3, fbm(vp * 0.6 + vec3(2.0, 0.0, 5.0), 3)); // alone: la venatura sfuma nel bianco intorno, a macchie float halo = (1.0 - smoothstep(0.0, vwidth * 7.0, abs(n1))) * (0.5 + 0.5 * fbm(vp * 4.0 + wv, 4)); // le crepe: i bordi delle celle di Voronoi su un dominio stirato e deformato, solo a tratti vec3 vc = voronoi(vec3(qr.x * 0.8, qr.y * 2.4, 0.0) * 2.2 / vscale + wv * 0.9); float crack = 1.0 - smoothstep(0.0, vwidth * 0.7, vc.y - vc.x); float cmask = smoothstep(-0.1, 0.35, fbm(vp * 1.4 + vec3(7.0, 0.0, 1.0), 3)); float vm = clamp(v1 * (0.6 + 0.4 * vis) + 0.5 * v2 * vis + 0.4 * halo * vis + 0.8 * crack * cmask, 0.0, 1.0) * veins; float cl = 0.5 + 0.5 * fbm(vp * 1.2 + wv * 1.3, 5); vec3 mc = marble * (1.0 - clouds * 0.22 * smoothstep(0.45, 0.85, cl)); mc = mix(mc, veinc, vm * 0.9); // granito: grana fine, puntini neri e chiari float g1 = noise(vec3(q * 700.0, 0.0)); float g2 = noise(vec3(q * 1700.0, 5.0)); vec3 gc = granite * (1.0 + speckle * (0.5 * g1 + 0.35 * g2)); gc = mix(gc, vec3(0.04, 0.04, 0.045), speckle * smoothstep(0.3, 0.55, g2)); gc = mix(gc, vec3(0.7, 0.69, 0.68), speckle * 0.6 * smoothstep(0.4, 0.62, -g1)); vec3 c = mix(mc, gc, isBand); c = mix(c, c * 0.5, jm); m.albedo = c; m.metallic = 0.0; m.roughness = mix(rough_m, rough_g, isBand) + 0.3 * jm;
Cream marble octagon tiles with black inserts

Octagon tiles Library

From another photo: cream marble octagons with faint golden veins, small black cabochons at the corners, light grout, each tile a slightly different tone. Same hall, the floor changed with one click.

The shader

GLSL, 51 lines
“This floor: cream marble octagons with small black diamonds at the corners.”
// pavimento a ottagoni di marmo crema con tozzetti neri agli angoli (posa classica) param float tile = 400.0; // 100..1000 Piastrella (mm) param float cab = 70.0; // 10..200 Tozzetto, mezza diagonale (mm) param float rot = 0.0; // -90..90 Rotazione posa (gradi) param float joint = 2.0; // 0..6 Fuga (mm) param color grout = vec3(0.62, 0.6, 0.56); // Stucco // tab: Marble param color cream = vec3(0.88, 0.81, 0.68); // Marmo crema param color veinc = vec3(0.72, 0.6, 0.42); // Venature dorate param float veins = 0.9; // 0..1 Quantita venature param float tone = 0.35; // 0..1 Variazione tono piastrelle // tab: Inserts param color black = vec3(0.025, 0.025, 0.028); // Tozzetti // tab: Finish param float rough_m = 0.12; // 0.02..0.6 Roughness marmo param float rough_b = 0.06; // 0.02..0.6 Roughness tozzetti vec3 W = s.P * 0.001; float ang = rot * 0.0174533; vec2 q = vec2(cos(ang) * W.x - sin(ang) * W.z, sin(ang) * W.x + cos(ang) * W.z); float T = tile * 0.001; float h = cab * 0.001; vec2 cell = floor(q / T); vec2 u = q - (cell + 0.5) * T; // -T/2..T/2 dal centro della piastrella float a1 = abs(u.x) + abs(u.y); float isCab = step(T - h, a1); // vicino all'angolo: il tozzetto // le fughe: i lati del quadrato e i lati del tozzetto float dSq = T * 0.5 - max(abs(u.x), abs(u.y)); float dCab = abs(a1 - (T - h)) * 0.70710678; float d = isCab > 0.5 ? dCab : min(dSq, dCab); float jm = 1.0 - smoothstep(joint * 0.0003, joint * 0.0007, d); // il tozzetto e' uno solo per quattro piastrelle: la sua cella e' l'angolo vec2 corner = cell + step(0.0, u); // marmo crema: ogni piastrella un pezzo diverso, venature sottili dorate vec2 o = vec2(hash13(vec3(cell, 3.0)), hash13(vec3(cell, 7.0))) * 40.0; vec3 vp = vec3((q + o) * vec2(1.4, 4.0), 0.0) * 2.0; vec3 wv = vec3(fbm(vp + vec3(3.1, 0.0, 1.7), 4), fbm(vp + vec3(-5.2, 0.0, 4.4), 4), 0.0); float n1 = fbm(vp + wv * 1.4, 5); float v1 = 1.0 - smoothstep(0.0, 0.03, abs(n1)); float vis = smoothstep(0.0, 0.4, fbm(vp * 0.5 + vec3(2.0, 0.0, 5.0), 3)); float cl = 0.5 + 0.5 * fbm(vp * 0.7 + wv, 5); float tv = (hash13(vec3(cell, 13.0)) - 0.5) * tone * 0.12; vec3 mc = cream * (1.0 + tv) * (0.94 + 0.1 * cl); mc = mix(mc, veinc, v1 * vis * veins * 0.7); // tozzetto nero lucido, appena nuvolato float bn = fbm(vec3((q + vec2(hash13(vec3(corner, 5.0)) * 9.0, 0.0)) * 30.0, 1.0), 3); vec3 bc = black * (1.0 + 0.5 * bn); vec3 c = mix(mc, bc, isCab); c = mix(c, grout, jm); m.albedo = c; m.metallic = 0.0; m.roughness = mix(rough_m, rough_b, isCab) + 0.4 * jm;
Designed in modules

Small parts that fit together

Two levels, as in the big procedural packages: objects with their transforms, parents and paths, and inside each one a network of nodes where geometry flows from top to bottom. Every node is a pure function, inputs and parameters in, geometry out: easy for an agent to reason about, easy for you to follow. Change anything upstream and only what depends on it cooks again, in the background and in parallel.

The rest is modular too: the render engines, the physics, the native geometry kernel, the material compiler. Editing one material rebuilds only that material.

Nodes

Procedural core

Undo on everything, subnets and network boxes, bookmarks, expressions on every parameter, and Variants: the network above it cooked N times, for N different trees, rocks or fruits from one recipe.

Data

Built for size

Millions of points and instances, nested, with level of detail in the views. Unchanged data stays the same data, so the views and the path tracer update only what really changed.

Plugins

Open by design

A new node is one C# class: menus, parameter panel, scene files and MCP tools pick it up by themselves, so the agent can use it the moment it exists. Drop a DLL into plugins and it is there.

Rendering

Forge, Spark, and Glint

The same materials and lights, three ways to see them: physically correct, in real time, or spectral. Switch engine at any moment; nothing in the scene has to change.

Forge

Path tracer

Runs on NVIDIA OptiX, or on any OpenGL card with the same images, pixel for pixel. Inside a view while you work, or to disk.

  • Many-light sampling with a light tree, HDRI and a physical sky
  • Random-walk subsurface, hair fibres, translucency, coat and sheen
  • Caustics through glass and water (MNEE)
  • Fire and smoke volumes, atmospheric fog with god rays
  • Motion blur, depth of field, physical camera
  • Intel Open Image Denoise, glow and bloom

Spark

Real time

A deferred raster engine in the spirit of EEVEE, for the views, previews and fast renders.

  • Area lights with soft shadows (PCSS) and LTC reflections
  • Ground-truth ambient occlusion and screen-space GI
  • Glass that refracts through its real thickness
  • Subsurface, depth of field, fog
  • Accumulated anti-aliasing, AgX, Filmic, ACES

Glint

Spectral engine

GeneraFX connects to Glint, a spectral renderer that runs as its own node. Light is computed wavelength by wavelength: dispersion in gems and glass, thin films, real pigments. Pick Glint in the render settings and the scene goes there as it is.

Motion blur and depth of field

A lacquered top spins at six turns a second, slows, wobbles and falls. The motion blur melts its colours, the lens turns the string lights behind it into bokeh.

The motion

Three expressions, written by the agent
“Let it spin like a gyroscope, then lose its strength, wobble and fall on the table.”
// s = clamp($F-120, 0, 80): the slowing down r = clamp($F-200, 0, 40): the fall // spin: 6 turns a second, slower from frame 120, then rolling on its rim top.r.y = -(90*min($F,120) + 90*s - 65*s*s/160 + 1.57*(30*r - 0.375*r*r)) // precession: slow, faster and faster as the spin dies, then the roll stops precess.r.y = 2.5*min($F,120) + 2.5*s + s*s*s/698.18 + 30*r - 0.375*r*r // tilt: 1.5 degrees, a growing wobble, the fall to 48 (tip and rim on the table), two bounces tilt.r.x = 1.5 + 46.5*pow(s/80,4) + 8*(s/80)*(1-s/80)*sin(s*$PI*12/80) - 6*exp(-r/5)*abs(sin(r*0.6))

No simulation: three nested objects (precession, tilt, spin) and one expression each. The resting angle comes from the profile of the top, so it lands exactly on its tip and rim, without sinking into the table.

GLSL materials in Forge

Glazed ceramic, marble, stone and wood, every one a GLSL shader written by the agent, turning 360 degrees under the path tracer.

Simulation and animation

Things that fall, burn, pour, fly and walk

Every simulation is a node: it reads its inputs, keeps its frames in memory so you can scrub back freely, and gives geometry to whatever comes next. Every clip below is a Forge render at 64 samples, denoised, except the hair, rendered in Spark.

Liquids FLIP

A FLIP solver with a pressure solve only where the water is, colliders of any shape, and a surface node that turns the particles into a smooth mesh. Here, water poured into a glass.

Fire and smoke

A grid solver for fuel, heat and smoke from any mesh, rendered as a true volume that lights the scene. The stone wall is one GLSL material: Voronoi stones, uneven mortar, real relief.

Rigid bodies Jolt

Jolt Physics inside a node: pieces from instances or connected parts, every frame cached and interpolated. A tower of blocks comes down.

Cloth and soft bodies

Fabric that drapes and folds, cushions that keep their shape and bounce: stretch, bend, pressure and damping, with collisions against the rest of the scene.

Hair and dynamics

Fur grown on any surface, groomed by clumps, length and curl, rendered as true fibres. Hair Dynamics swings the guides, and a Wind field moves hair, grass and trees together.

Particles

Emitters, forces, drag and collisions with any mesh: sparks that shoot, glow and bounce.

Flocks

Boids with separation, alignment and cohesion, goals and obstacles: a flock wheeling around a tower of stone.

Rigging and walking

Skeletons, IK with poles, skinning, and a Walker that turns any legged creature into a gait from the time alone. A red-knee tarantula, built from measured proportions, with every hair.

Crowds New

Forty legged agents of two kinds walk over sand and gravel, keep their personal space and go round the rocks. Feet land where they really stepped, so nothing slides.

Everything else

The advanced toolbox

SplinesCircle, arc, spiral, star, gear, fillet, join, carve, trim
Surfaces from curvesExtrude with bevels, Revolve, Loft through sections, Sweep
BooleansExact solid booleans on the Manifold kernel
SDF modellingSmooth implicit shapes, blended and carved, raymarched
Text3D lettering from system fonts, with bevels
Logo from an imageImage node, magic wand, Trace, Clean Curves, Pick: from a picture to a solid
DeformersBend, twist, taper, bulge, shear, squash, spherify, Melt, Path Deform
DistributionScatter, Clone to Points, Distribute without overlaps, Collector
GrowthVines that climb surfaces, GeoTexture cells bent onto any mesh
Audio and MIDISound levels and MIDI notes drive any parameter; MIDI played through a SoundFont, rendered into the MP4
Animation editorCurves and dopesheet, weighted tangents, cycles, ghosts, tween
Object pathsRide any curve with follow, bank and even speed
Camera trackingTrack filmed footage, solve the camera and lens, render over it
ImportFBX, glTF, OBJ, STL, 3MF and more, with materials and maps
ExportglTF with baked shader materials, STL, 3MF, OBJ
Material bakeProcedural GLSL baked to textures on an automatic atlas
Self-contained scenesModels and images embedded in the scene file
Render presetsOutput, frames, camera, engine; batch rendering from the console
Picture ViewerSequences in memory, play, save PNG or MP4
In development

GeneraFX is coming soon

It is still in development, in the hands of a few testers. The call for new testers will go out on LinkedIn: answer there if you want to try it.

WindowsLinuxmacOS