ChromaStack: the colour model, and transmission distance per filament

A picture is reproduced on one face by stacking thin layers of a few
filaments, swapping filament at fixed layer boundaries, and varying how
high each pixel is built up. Filament is translucent, so a column that
stops part-way through a run shows a blend of that run's filament and what
is under it - which is where the colours come from, far more of them than
there are filaments loaded.

libslic3r/ChromaStack.hpp holds the whole model, free of the GUI. A stack
is a list of bands (a filament and its layer count, bottom-up) on a base
of solid backing. chroma_palette() turns it into the colour shown at every
column height, by Beer-Lambert absorption with each filament's
transmission distance; chroma_solve() maps every pixel to the height whose
colour is closest in CIELAB, optionally diffusing the rounding error, and
returns the 8-bit height map and the colours it predicts. Beer-Lambert is
the only model that stays consistent applied per layer, so the palette
does not depend on how the stack was cut into bands, and a test asserts
it.

chroma_layers_to_opaque() and chroma_distinct_levels() are what make a
stack's behaviour legible: how many layers a filament needs to hide what
is under it, and how many of a picture's layers change the colour at all.
chroma_ranges() turns the bands into object height ranges, which is how
the slicer is told to print a Z band in another filament.

Transmission distance is a property of the material, so it is a filament
preset option: filament_transmission_distance, with no effect on slicing.
This commit is contained in:
ExPikaPaka
2026-10-16 11:44:33 +02:00
parent d2675f15d1
commit e0a6000d50
10 changed files with 1103 additions and 3 deletions
+14
View File
@@ -3441,6 +3441,20 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0. });
def = this->add("filament_transmission_distance", coFloats);
def->label = L("Transmission distance");
def->tooltip = L("How deep light gets into this filament, in millimetres, also called its "
"transmission distance or TD. About 1 for an opaque filament, 4 to 7 for a usefully "
"translucent one, 8 and above for a nearly clear one. Used only to predict the "
"colours of a ChromaStack in the texture displacement tool; it has no effect on "
"slicing. Measure it with a step test print, or take a published value for the "
"filament.");
def->sidetext = L("mm");
def->min = 0;
def->max = 100;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 4. });
def = this->add("filament_type", coStrings);
def->label = L("Type");
def->tooltip = L("Filament material type");