3D Printing in Unlimited Colors – with a Single Filament
“Render to Filament Printing” just had its Chicago Pile moment… in Chicago.
3D Graphics, GPU, AI, and 3D printing aficionados alike – you’re going to like this one. I’ve conducted a series of experiments where I’ve applied GPU rendering techniques to… 3D printing. More techniques to come, but this particular experiment was too wacky not to share.
Some background:
Early versions of DirectX enabled graphics cards to perform “render to texture” operations, where one could draw a 3D scene into memory, and then load the result as a texture in a subsequent “pass”. These capability become a cornerstone of almost every visual effect and technique in videogame graphics – from drawing reflective mirrors to cloth simulation.
What if we apply a similar approach to 3D printing?
But 3D printers don’t process memory! They process plastic. Guess what? Doesn’t matter. After all, in Alan Turing’s classical view of computation, both are just a very long tape… er… filament.
It’s actually pretty useful if you can make this work
Multi-filament 3D printers like my Bambu X1C have become incredibly popular – offering the ability to print a single model in up to 4 colors.
The problem is that these printers can only print a single filament at once – changing colors involves swapping filaments in the machine. This process is automated, but it’s slow and wasteful. Printing this lion’s head takes two and a half days, when printing it in a single color takes less than 8 hours:
It also wastes a pound (!) of filament, because the machine needs to purge leftover filament from the extruder every time it switches. The purged filament is discarded through what is affectionately called the “poop chute” in the Bambu X1C.
Solution: Render to Filament
3D printer machine code (gcode) is deterministic. It will always perform the same order of operations precisely. Every filament extrusion is precisely controlled in the code (sometimes it goes backwards to end a segment and avoid ‘stringing’, but even this is precisely controlled). That means that for every segment extruded by the printer, you can theoretically know exactly how far along the filament the plastic was taken to make that segment.
What if we could print our own filament that was custom-made for the object we’re printing, with colors exactly where they are supposed to be on the final object?
This provides a series of advantages. Filament is relatively flat, so you’d only need a handful of filament switches to print it. If you use CYMK filaments as the ‘input’ you can make any color combination by controlling the relative contribution of each color at each point along the filament.
Step 1: Pick the object you want to print and slice it
This is a standard step for any print. You take your 3d object, and ‘slice’ it into 3d printer gcode. In the next step, we’ll project the bunny texture onto it.
Step 2: Compute your multicolor filament from machine gcode
Using ChatGPT and Claude, I wrote a prototype Python program that consumes 3d printer gcode and an overlay texture, extracts the extrusion and position commands to identify the target filament color sequence, and generates STL files for each one that can be put back into the ‘slicer’. For the test, I only used two colors. The texture is simply projected over the input object to see if I can recreate it.
Step 3: Slice and Print your Filament
I found I had to be especially careful here, as the filament surface has to be very smooth to avoid clogging the extruder, and the cross section has to be exactly 1.75mm. To do this, I ended up making sure there was a white ‘sheath’ around the filament so the color changes were only on the inside. That would wash out the resulting color a bit for now… but this is a problem we can solve later.
I printed the first few tests with a combo of white and pink filament.
Custom filament
Step 4: Feed your custom filament into the printer and print your original object
Now that you have a printed filament, you can feed it back into the printer, and print your original object.
Making sure you start at the right starting point is important. Getting the printer to do this without extruding extra filament at the beginning is tricky and requires some calibration – a process I’ll have to improve by drilling further into gcode and potentially printing some calibration runs to see how much is extruded during this process.
Lots of tuning to do, but here’s an early print (before this particular filament clogged the printer).
It’s definitely an early proof-of-concept and has a long way to go, but the fact that this was printed with a single filament demonstrates the viability of the method (with some more iteration).
Graphics folks – the ‘gaussian blur’ effect that you see on the texture isn’t a shader – it’s the result of melting plastic blending together.
Now that you understand the full process, there’s another important consideration about how we generate the gcode for the original object at the beginning, which you might notice on the photo above. So I’ll rewind a bit and fill you in on Step 1.5:
Step 1.5: Apply a Hilbert Pattern to the colored parts of your object
3D printer filament is 1.75mm wide. It’s squeezed and extruded into segments that are 0.08-0.28mm wide. That means that as your extruder zips back and forth printing your layers, two points that are next to each other on the filament might end up very far from each other on the object, and vice versa. Not good, when a lot of segments are going to come from a short region of filament of varying colors.
We’re very familiar with this problem in computer graphics. Computer memory is 1 dimensional (like filament), but graphics textures are two dimensional (like printing layers). In computer graphics, if you lay a texture out naively in memory, when you’re drawing a scene with that texture, chances are you’ll be hopping all around your memory which is actually very slow (it causes ‘cache misses’ which slows things down tremendously). How do you lay out a 2D image in 1D memory so that it has ‘locality’ – so that things that are close to each other in 2D are also close to each other in 1D?
A Hilbert Pattern!
David Hilbert is one of my favorite mathematicians. Why?
- He invented the Hilbert pattern in 1891 which we use extensively in computer graphics to store textures in memory (also known as a swizzle pattern).
2) Hilbert also had a reputation for standing up to his Nazi superiors at the University of Gottingen.
Most good 3D printer software will let you “slice” so that the extruder moves in a Hilbert Curve if you set everything up correctly.
Next Steps
This was a fun experiment that generated surprisingly good results quickly. Obviously there’s a long way to go. Next steps include:
- Produce better, smoother filaments that don’t clog the extruder on the second pass (I have a few ideas here)
- Test hitting a broad color range using CMYK filaments to print the custom filament using a full color range
- Establish a calibration technique to ensure the custom filament is loaded at the right spot
- Further optimize slicing to improve color resolution – by printing infill, followed by a short outer-wall segment, followed by more infill, to give high-resolution regions on the object’s surface more length along the custom filament.
- Extend the locality offered by Hilbert curves from 2D curves to 3D curves.
I’ve got a number of other experiments I want to perform before I get back to improving this technique.
What do you think? Should I keep iterating on this one?
I think a custom hotend is required to reduce the bleeding, or this will never be useful.