martes, 16 de abril de 2013

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

2 comentarios:

Thri Keen dijo...

Que es el numero de pagina en el sitio, glsl.heroku?

Eduardo Maldonado dijo...

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)

Este sitio emplea cookies de Google para prestar sus servicios, para personalizar anuncios y para analizar el tráfico. Google recibe información sobre tu uso de este sitio web. Si utilizas este sitio web, se sobreentiende que aceptas el uso de cookies. Más información Entendido