Tired and unhappy, as always.
But I think my last OSL might be useful for you.
Its a stencil node.
( ~~~ )
Stencil Parameters:
C: a user defined color.
range: determines the radius of a “sphere” in the color space. Center of the sphere is color C.
Curve Parameters
Curve1: one of “linear”, “constant”, “round”, “smooth”, “sharp”
Curve2: one of “linear”, “constant”, “round”, “smooth”, “sharp”
blend_curve: blend between Curve1 and Curve2.
Color input, used to create stencil.
Switch: color channel input. (E.g. … use it with textures.)
The stencil is computed, depending whether Switch is inside the sphere around C.
Curves control how the stencil blends.
( ~~~ )
Curves
linear … a straight blending.
constant … gives the stencil a sharp edge.
round … “dome” like blending.
smooth … smooth blending.
sharp … beginning with a soft blending, leading to a sharp tip.
( ~~~ )
The code …
/* File: color_stencil.osl
By Leonard Siebeneicher.
I am not used to Licensing stuff, sorry.
You can use it as you wish.
*/
#include <stdosl.h>
/*
* Currently supportet curves. (Blendings/Gradients)
*/
float curv_smooth(float x)
{
float arr[4] = {0,0,1,1};
return spline ("bezier", x, 4, arr);
}
float curv_sharp(float x)
{
float arr[4] = {0,0,0,1};
return spline ("bezier", x, 4, arr);
}
float curv_round(float x)
{
float arr[4] = {0,1,1,1};
return spline ("bezier", x, 4, arr);
}
/* Support waves? */
float curv_cos(float x)
{
return 1-cos(x*3*M_PI);
}
float curv_sharp_tri(float x)
{
float arr[4] = {0,1,0,1};
return spline ("linear", x, 4, arr);
}
/*
* This function is used to apply a curve chosen by a user.
*/
float apply_curve (string name, float blend)
{
/* We clamp 'blend' before we use it
* in a curve. */
float x = clamp (blend, 0, 1);
/* Very basic are "constant" and "linear". We
* do not nee to use spline function.
* All other curves use osl's spline function.
* New curves can be added easily. */
if ( name == "constant" ) {
return 1;
}
else if ( name == "linear") {
return x;
}
else if ( name == "smooth" ) {
return curv_smooth(x);
}
else if ( name == "sharp" ) {
return curv_sharp(x);
}
else if ( name == "round" ) {
return curv_round(x);
}
else
{
printf ("Shader Error; Curve %s not defined.
", name);
return 0;
}
}
/*
* Main shader
*/
shader node_color_stencil(
/* We have a color C and a "sphere" around
* it with the radius "range". */
color C = 0.8,
float range = 0.2,
/* We alter the stencil, using spline curve
* gradients. Possible values for Curve1 and
* Curve2 are "constant", "smooth",
* "sharp, "round", wave and "linear". */
string Curve1 = "linear",
string Curve2 = "smooth",
float blend_curve = 0,
/* The input color data is called 'Switch'.
* If color 'Switch' is inside the shpere around
* C, it is considered as a match. There we set
* a stencil value. */
color Switch = 0.8,
/* value of stencil should be between 0 and 1 */
output float stencil = 0)
{
/* We calculate distance between 'C' and 'Switch'. */
float dst = distance(vector(C), vector(Switch));
/* Now we test, whether 'Switch' is inside the spere
* arount C with radius 'range'. */
if ( dst <= range ) {
/* We are inside range. */
/* Transforming 'dst' (which can be any value)
* to a ratio which range between 0 and 1.
* This ratio is used to set strength of
* 'stencil'. */
float r = dst/range;
/* Now we can use 'r' to calculate stencil value.
* Using 'blend_curve' to blend between chosen curves. */
stencil = mix(apply_curve(Curve1, 1-r),
apply_curve(Curve2, 1-r),
blend_curve);
}
else {
/* We are outside range. */
stencil = 0;
}
}
Some examples using color_stencil appended to this posting.
Happy blending.