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:
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.