Simple OSL ... Color Match node and Color Mix node

Still tired, as always.

But, I wrote some simple OSL shaders.
Both use [Color, BSDF Closure] pairs.

The idea behind,
its about a node which work like “add bsdf” or “mix bsdf”, which is not limited to a single scalar. Rather then mixing using a scalar, bsdfs are mixed or matched basing on their color difference to the input color.

This BSDF tries to match an imput color to a color out of a [Color, BSDF] pair.


/* File match_bsdf_3.osl */
void match ( 
    color c, color v, 
    float min, 
    closure color C, 
    output float min_res, 
    output closure color C_res)
{
    float store_dist = distance (vector(c), vector(v));
    if ( store_dist < min) {
        C_res = C;
        min_res = store_dist;
    }
}

shader match_bsdf_3(
    color C1 = 0.8,
    color C2 = 0.8,
    color C3 = 0.8,
    closure color BSDF1=0,  
    closure color BSDF2=0,  
    closure color BSDF3=0, 
    color Switch = 0.8, 
    output closure color BSDF = 0)
{
    closure color b = BSDF1;
    vector sw = vector (Switch);
    float min_dist = distance (vector(C1), sw);
    
    match(C2, Switch, min_dist, BSDF2, min_dist, b);
    match(C3, Switch, min_dist, BSDF3, min_dist, b);
    BSDF = b;
}

This BSDF does not match input BSDFs, but it mix them, depending on their “paired” color.


/* file: mix_col_3.osl */

shader mix_col_3(
    color C1 = 0.8,
    color C2 = 0.8,
    color C3 = 0.8,
    closure color BSDF1=0,  
    closure color BSDF2=0,  
    closure color BSDF3=0, 
    color Switch = 0.8, 
    output closure color BSDF = 0)
{
    float dst1 = distance(vector(C1), vector(Switch));
    float dst2 = distance(vector(C2), vector(Switch));
    float dst3 = distance(vector(C3), vector(Switch));

    float mi = min ( min (dst1, dst2), dst3); 
    float ma = max ( max (dst1, dst2), dst3); 

    float siz = 1/(ma - mi); 
    
    BSDF = siz*(dst1*BSDF1 + dst2*BSDF2 + dst3*BSDF3);
}

The attached image was rendered using mix_col_3 node together with glossy bsdfs and algorithmic textures (those give the color input for “Switch”). The “value” field of the alghoritmic texture was used to create bumps.

“mix_col_3” still is WIP.

Happy blending.

Attachments


Little change in mix_col_3.osl

It uses something like an average calculation now to mix bsdf’s.
(Its not really an average, because it uses powers and nth roots.)

The way an average is calculated, is controlled by a “degree” parameter.

/* file: mix_col_3.osl */
/* calculate the nth root of a float */

float nth_sqrt (float x, float n)
{
    return exp( 1/n * log( x ));
}

/* the main shader */

shader choose_col_3(
    color C1 = 0.8,
    color C2 = 0.8,
    color C3 = 0.8,
    closure color BSDF1=0,  
    closure color BSDF2=0,  
    closure color BSDF3=0, 
    color Switch = 0.8, 
    int degree = 1,
    output closure color BSDF = 0)
{
    float dst1 = distance(vector(C1), vector(Switch));
    float dst2 = distance(vector(C2), vector(Switch));
    float dst3 = distance(vector(C3), vector(Switch));

    float average;
    
    if (degree<=1)
    {
        average = (dst1+dst2+dst3)/3;
    }
    else
    {
        average = nth_sqrt(pow(dst1,degree) + pow(dst2,degree) + pow(dst3,degree), degree); 
    }
    
    BSDF = 1/(3 * average)*(dst1*BSDF1 + dst2*BSDF2 + dst3*BSDF3);
}

I think I learned something about procedual textures.
Now, I enjoy much more using them.

There is a drop in brightness if I use a degree bigger then 1.
You can see a simple stone texture, using mix_col_3 and some procedual textures.

Attachments