From flat texture to intelligent material

Published on August 29, 2026 · How the 3D studio learned to craft materials from a single sentence.

In short: every material in the studio used to be a name and a colour chosen once and for all. Now a single French sentence is enough: « a forge with bright metal and glowing embers » becomes a bright, metallic, emissive material — with nothing guessed, and tests to prove it.

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.

The tests say what a sentence becomes, leaving no room for interpretation:
• « 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 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.

🔭