From flat texture to intelligent material
Where it started: a flat texture
In the studio, every material began as a name and a colour. The library kept a list of presets — stone, wood, metal, water, energy — each with its tint and its roughness, chosen by hand, once and for all. It is consistent: every building shares the same palette. But it is frozen: to change a scene's mood, you had to go over each material one by one, or write a new preset.
The real problem was not the colour, it was the link. A prompt like « a dark forge » spoke to the geometry — build, size, put on a roof — but never to the walls themselves. Materials were a label applied at the end, not an answer to the request.
Two articles that changed how I see it
I read two Blender articles and kept them because each told half of the
story. The first, Coding Blender Materials with Nodes & Python by
Jeremy Behreandt, shows how Blender's built-in nodes can be grouped into
utility functions: comparisons, logic gates, fract,
smoothstep, quantize, tiling patterns, shapers —
and an arrange_nodes function that lays the graph out in tidy
columns. The second, Beginner Blender : Materials & Shape Keys by
Jared Nielsen, opens another door: assigning materials, then animating simple
objects with shape keys.
The shared lesson fits in one sentence: a material can be a program, not a label. A colour has no memory; a constructed pattern answers what you ask of it.
How the prompt earned the right to design
The studio already started from a French sentence: the request goes through
a spec generator that recognises materials and features (dark wood, aged
stone, steep roof). If a sentence already decided the shape, why not the
design too? We added a layer (design_engine) that reads the same
sentences and draws a direction: « dark » → dark tone,
« glowing runes » → emission, « bright metal » → polished
surface, « checkerboard » → grid pattern.
• « A dark dungeon… with cyan glowing runes » → tone
dark, emissive ≥ 0.6;
• « A forge with bright metal and glowing embers, orange palette » →
roughness ≤ 0.3, metallic ≥ 0.6,
emissive ≥ 0.75;
• « A bright, sunny house with a checkerboard on its facade » →
bright, grid pattern.
Important rule: the layer only touches what the sentence actually describes. Everything else carries over from the current direction. Saying « a bit darker » does not change a palette you never named.
The path from sentence to screen
For a sentence to give birth to an object, everything follows the same path, like an order going through a kitchen:
- the sentence (the prompt) becomes a spec — a precise recipe: the shape, the dimensions, the materials, and now the design;
- Blender reads the recipe and sculpts the 3D shape, walls, roof, windows;
- the export produces a GLB, the file the game displays, plus a preview picture to show the result without opening Blender;
- a bridge shuttles between the window where you type your sentence and the kitchen — it takes the order, carries it, and brings back the dish.
The sentence is read two ways: locally, through rules that never invent anything; or, when a language-model key is set, through the model. Either way the sentence goes through the same spec, the same kitchen, the same dish — and you can always replay the same order to get the same result.
A design section that lives in the spec
The result is the design section, and it fits in a handful of
fields: tone, pattern, palette, emission, roughness, metal, detail. Every
value is clamped between 0 and 1. The section persists in the spec:
the same prompt gives the same design — reproducibility is the studio's
contract — and it survives validation and the metadata round-trip. What you
build once is reusable.
node_lib: the material as a program
The bridge to Blender remained. The library (node_lib) is built
in two layers. The first is pure: a descriptive node graph, serialisable,
testable without Blender — plus real mathematical functions (fract, quantize,
smoothstep, Minkowski distance) and a pattern engine that draws rings, grid,
waves, dots or noise. The second layer materialises that graph into a real
material, inside Blender, when the asset is built.
When the sentence asks for a pattern, the builder regenerates the walls with
this library instead of laying a flat colour. And the node layout reuses the
idea of the article's arrange_nodes: each node gets its column
and its row, so the graph reads like a diagram, not a tangle.
What we did not allow: guessing
A sentence written by a human will always be partly ambiguous. The studio
keeps the same rule as everywhere else: never guess. What the prompt
does not explain stays at its documented default. On-demand vision refuses
to act without its key rather than simulate. And every function is covered by
a test — verifie(), a home-grown battery — that counts its
failures and only accepts zero. Automation is not an excuse for sloppiness.
The limit the exporter reminds us of
The whole story meets one honest border. The glTF exporter cannot bake procedural nodes: a built material would arrive white in the render engine — a lesson already learned here. The library works around it by generating a real image texture of the pattern, embedded in the file. Full node groups would require a bake, or shaders written directly on the engine side (Three.js). We know where the magic stops, and we say it.
What comes next
The second article keeps a door open: shape keys. A building that animates, a gate that answers the wind — it is the same method as usual: a sentence, bounded parameters, and tests that prove. Style transfer from an image is also thinkable — never to replace reading, always to feed it.
How to verify it yourself
The project lives locally, and the test runs in one line:
python3 world_builder/tests/test_unit.py. It answers
« 0 failure(s) » or it answers nothing good. If you want to see a
3D world whose walls change their soul according to the sentence whispered
to it, ask for the demo.