8
$\begingroup$

I'm trying to use UVW generated mapping of a lot of splines and each spline has a lot of points. I want to add gradients of colors to the meshes and I hit a limit in Cycles ColorRamp. I can't add more than 32 colours for one gradient or I get an error.

Using python and any automated way, how is it possible to have a gradient with more than 32 colours that I can map on uvw coordinates ?

I already thought of breaking curves into many polylines but I'm trying to find a clean solution on the mapping side.

Follow-up, May 2015

This question arose from a previous one answered here How to colour vertices of a beveled curve mesh without converting to mesh?

I have curves with sometimes more than 32 points and I would like to color these points without converting to mesh I insist so UVW texturing is a good way to do it. However, the gradient node only accepts up to 32 colours.

So far, I solved the problem by writing an OSL shader that parses XML data. The shader takes a value as input, let's say a voltage, and outputs a colour for it, based on a colour map. For scientific visualisation, it often happens you want to map some values to colours. So this answers your question gandalf3, the colours are representation of values of a certain unit and I don't think we can work on a pattern here.

What's important here is that a voltage at a given point is mapped to a colour, regardless of interpolation and all. Each and every voltage point will have its colour, which can then be interpolated with the following voltage point. A voltage point can be anywhere along the curve so what matters is the ratio. 0.0 is the start of the branch, 1.0 is the end of it. Points can be somewhere within that ratio.

When we simulate voltages, the values change over time so the colours will reflect the state of each time step.

So here's the node setup: OSL node setup for colouring points on a curve

The example below takes this XML data – produced on the fly while reading voltage values – and converts the voltage points to colours.

<report min="0" max="100" unit="mV">
    <compartment id="0" start="0.0" end="0.2" value="12.0" />
    <compartment id="1" start="0.2" end="0.4" value="25" />
    <compartment id="2" start="0.4" end="0.6" value="10.5" />
    <compartment id="3" start="0.6" end="0.8" value="38.5" />
    <compartment id="4" start="0.8" end="1.0" value="76.6" />
</report>

And the OSL sample code (took me a while to figure out this works!):

#include <stdosl.h>

shader xml_color_mapper(float Value=0.0, string Xml="test.xml", output color Color=(0.0))
{
    // The second parameter is an XPath string
    // Example string xpath = concat("//color[@name='",Name,"']/text()");
    int report = dict_find(Xml, "//report");

    string smin = "";
    dict_value(report, "min", smin);
    float min_value = stof(smin);

    string smax = "";
    dict_value(report, "max", smax);
    float max_value = stof(smax);

    color value_color = color(0);
    for (int comp = dict_find(Xml, "//compartment"); comp;  comp = dict_next(comp)) 
    {
        string sid = "";
        dict_value(comp, "id", sid);
        int id = stoi(sid);

        string sstart = "";
        dict_value(comp, "start", sstart);
        float segment_start = stof(sstart);

        string send = "";
        dict_value(comp, "end", send);
        float segment_end = stof(send);

        string svalue = "";
        dict_value(comp, "value", svalue);
        float value = stof(svalue);

        if (Value > segment_start && Value < segment_end)
        {
            float ratio = (value - min_value) / (max_value - min_value);
            value_color = color(ratio*ratio, 0.1, 0.1);
        }
    }
    Color = value_color;
}

The only drawback to this method is that I need OSL and thus CPU mode. OSL isn't supported yet in Blender (2.74) in GPU mode simply because it takes time to implement it.

Now that I have written the OSL shader, there may be a way to do the same with Cycles (math) nodes.

$\endgroup$
  • 3
    $\begingroup$ if you find a way to mix two Color Ramp nodes based on the geometry then you will have 64 colors available. Figure this out for the first one and you should be able to add as many as you want. $\endgroup$ – MarcClintDion Apr 13 '15 at 12:17
  • $\begingroup$ (I know this is old, but if you still would like an answer) Are all 32 colors different? Or is there a recurring pattern (e.g. green blue green blue etc.)? $\endgroup$ – gandalf3 May 4 '15 at 18:38
2
$\begingroup$

These are some node groups to accomplish colorRamps mixing based on the UV coordinates and certain scale ( in this example it's 8 ), which give as a total of 256 color, this is the final setup :

enter image description here

and these are the node groups needed :

"Equal to" node group : compare two numbers and output one if they are equal else a Zero

enter image description here

"Mapper" node group : remap the input ( by scaling) and output an integer number ( 0, 1, 2...) for controlling the color switches

enter image description here

"ColorRamps" node group : a group of colorRamps sharing the same factor input

enter image description here

"Decoder" node group: switch only one of the outputs to one if the input is equal to it's order

enter image description here

"ColorMix" node group: switch between colors based on the input if input = 5 the output will be the color-5

enter image description here

this will allow you to combine multiple color ramps as follow : for this example ( scale = 8 ): colorRamp zero will be used for U coordinates from 0.0 to 0.125 ,and colorRamp one from 0.125 to 0.250 and so on. You can try any scale equal to or less than 8 .

Note : since color ramps are separate there will be no transition between them but you can fake this by repeating the last color of the previous node as the first color of the next one.

test render :

enter image description here

$\endgroup$
  • $\begingroup$ Thank you Chebhou ! I will take time this week to test this and to translate this to Python. $\endgroup$ – nantille May 11 '15 at 15:45
  • $\begingroup$ @nantille the 32 color limit is in the source code can't be changed from python unless you rebuild, also tried pynodes but sadly they don't get updated in cycles, just a question you said the color is based on the voltage, is this voltage changing over time and how are you feeding the voltage value into the material ? $\endgroup$ – Chebhou May 11 '15 at 15:49
  • $\begingroup$ I see, I want to avoid rebuilding as much as possible. I'll edit the description to make it clear about the voltage. $\endgroup$ – nantille May 11 '15 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.