Blender Cycles OSL: Voronoi Tiles Material

Hi everybody. This code is ported to OSL from a GLSL version. The material looks like this:


The OSL code is as follows:
#include <stdosl.h>

#define TILE_MAX_HEIGHT 0.12
#define TILE_MIN_HEIGHT 0.05

// GLSL function
float fract(float x) {
    return (x - floor(x));
}

// GLSL function
vector fract(vector v) {
    return vector(v[0] - floor(v[0]),v[1] - floor(v[1]),v[2] - floor(v[2]));
}

float rand(vector co){ 
    return fract(sin(dot(co ,vector(12.9898,78.233,0.0))) * 43758.5453); 
}

vector random2f( vector seed ) {
    float rnd1 = mod(rand(seed), 1.0);
    float rnd2 = mod(rnd1*2.0,1.0);
    return vector(rnd1, rnd2, 0.0);
}

float hash(float n) { 
    return fract(pow(sin(n), 1.1)*1e6); 
}

float noise(vector x) {
    vector p = vector(x[0],x[1],x[1]);
    vector d = vector(1.0,30.0,30.0*30.0);
    vector f = fract(p), p0 = floor(p)*d, p1 = p0 + d;

    f[0] = f[0] * f[0] * (3.0 - 2.0 * f[0]);
    f[1] = f[1] * f[1] * (3.0 - 2.0 * f[1]);
    
    float t = mix(mix(mix(hash(p0[0]+p0[1]+p0[2]), hash(p1[0]+p0[1]+p0[2]),f[0]),
                  mix(hash(p0[0]+p1[1]+p0[2]), hash(p1[0]+p1[1]+p0[2]),f[0]), f[1]),
              mix(mix(hash(p0[0]+p0[1]+p1[2]), hash(p1[0]+p0[1]+p1[2]),f[0]),
                  mix(hash(p0[0]+p1[1]+p1[2]), hash(p1[0]+p1[1]+p1[2]),f[0]), f[1]), f[2]);

    return t * 2.0 - 1.0;
}

float tile_surface(vector p) {
    float f = 0.0;

    f += 0.3000*noise(p); p *= 1.22;
    f += 0.2500*noise(p); p *= 2.03;
    f += 0.1250*noise(p); p *= 3.01;
    f += 0.0625*noise(p); p *= 4.04;
    
    return f;
}


shader node_vornoi_tiles(
    float Scale = 1.0,
    vector Vector = P,
    color ColorTile1 = color(0.77,0.87,0.9),
    color ColorTile2 = color(0.9,0.9,0.9),
    output color Color = color(0.0),
    output color Height = color(0.0))
{
    color tile_color = color(0.0);

    float voronoi( vector x ) {
        vector p = floor( x );
        vector f = fract( x );
        vector res = vector(1.0);
    
       for( int j=-1; j<=1; j++ ) 
        for( int i=-1; i<=1; i++ ) {
            vector b = vector( i, j , 0.0);
            vector r = vector( b ) + random2f( p + b ) * 0.7 - f;
            float d = length( r );
        
            if ( d < res[0] ) {
             res = vector(d,res[0],res[1]);
             if (rand(p+b) < 0.5) 
                tile_color = ColorTile1;
             else 
                tile_color = ColorTile2;
            } else if (d < res[1]) {
              res[2] = res[1];
              res[1] = d;
            }
        }
    
       //float h_noise = 0.15*tile_surface((x+dot(tile_color,tile_color))*5.5);
        float h_noise = 0.15*tile_surface((x+(tile_color[0]*tile_color[0]+tile_color[1]*tile_color[1]+tile_color[2]*tile_color[2]))*5.5);
        float h = res[1] - res[0] - 0.15*sqrt(h_noise);
    
       if (h < TILE_MIN_HEIGHT) {
        tile_color = color(0.12,0.11,0.09);
        return TILE_MIN_HEIGHT + sqrt(h_noise);
       }
    
       if (h >= TILE_MAX_HEIGHT) {
        return TILE_MAX_HEIGHT - h_noise ;    
       }
    
       return h;
    }

    vector normal_voronoi(vector p) {
        float d = 0.001;
        float d2 = 0.02; // Smoothing parameter for normal
        vector dx = vector(d2, 0.0, voronoi(p + vector(d2, 0.0, 0.0))) - vector(-d, 0.0, voronoi(p + vector(-d, 0.0, 0.0)));
        vector dy = vector(0.0, d2, voronoi(p + vector(0.0, d2, 0.0))) - vector(0.0, -d, voronoi(p + vector(0.0, -d, 0.0)));
        return normalize(cross(dx,dy));
    }

    // Shader starts here    
    vector p = Scale * Vector;
    float color_voronoi = voronoi(p);
    
    float light_intensity = 0.5 / TILE_MAX_HEIGHT;
    vector light = normalize(vector(0.3,0.3,1.0)) * light_intensity;
    
    float shade = dot(light, normal_voronoi(p)) + 0.5;
    
    // Outputs
    Color = tile_color;
    Height = color(shade * color_voronoi);
}

And this is the node setup I have used in the image before:


You can change the tiles color and the scale in the script node.

Bye

Comentarios

Thri Kreen ha dicho que…
Que es el numero de pagina en el sitio, glsl.heroku?
Eduardo Maldonado Malo ha dicho que…
Hay muchos shaders hechos con glsl, simplemente debe ser la referencia al codigo de uno de ellos (en este caso el que yo he migrado)

Entradas populares de este blog

Santa Alejandra

Stucco Material III

Blender Cycles: Black Body Lights Reference (New Feature in Blender 2.69)