I have a shader function which functions like the "color ramp" node in Blender3D. It takes as input a float between zero and one and outputs a color that is a blend of any number of colors in a specified order:
Here is my code:
fixed4 ColorRamp(float factor){
float positions[5] = {_Pos0, _Pos1, _Pos2, _Pos3, _Pos4};
fixed4 colors[5] = {_Color0, _Color1, _Color2, _Color3, _Color4};
fixed4 outColor = _Color0;
for(int i = 0; i <4; i++){
if(factor >= positions[i] && factor <positions[i+1]){
fixed localFactor = (factor - positions[i])/(positions[i+1] - positions[i]);
outColor = lerp(colors[i], colors[i+1], localFactor);
}else if (factor > positions [_NumColors-1]){
outColor = colors[_NumColors -1];
}
}
return outColor;
}
It works. But it sucks, for a few reasons:
My main question is the first one: How can I change the number of colors in the ramp without having to edit a hardcoded value?
Brice is right. I can tell you straight away - nobody ever uses gradients of this type for shaders, simply because it offers virtually no advantages over just using a 1x128px color ramp texture. Use a lookup texture like this:
fixed4 col = tex2D(_MainTex, i.uv); // Sample the input texture
half lum = dot(col.rgb, fixed3(0.3, 0.59, 0.11)); // Color to luminosity
col = tex2D(_LookUpTex, float2(lum, 0)); // Get value from color ramp
If you want to create a handy inspector for the user, just generate a lookup texture from the gradient instead and assign it to the shader through script at OnValidate(). It is trivial to generate one by just evaluating the gradient at x/127.0 for each x between 0 and 127. Unity has a special Gradient class which gives you a gradient editor in the inspector when exposed.