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:
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
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