-
Notifications
You must be signed in to change notification settings - Fork 43
/
RandomTiles.osl
136 lines (108 loc) · 4.58 KB
/
RandomTiles.osl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
Generate a random tiles pattern based on four images.
RandomTiles.osl by Arjo Rozendaal.
Version 1.1: 2023-04-22.
Changes from version 1.0:
Added HSV color variation.
Different pattern can be generated by changing the "Seed" value.
The seed value does not generate a truly different pattern but shifts the tiles to another position.
Tiles can have small random rotations (choose values a little different from 0, 90 or 180 degrees).
Based on a Cell Noise one of four images is picked.
A number between 0-1 acts as a threshold.
From 0 to the value of Amount_T2, image 2 will be chosen.
Between the values of Amount_T2 and T3 image 3 will be chosen.
Between the values of Amaount_T3 and T4 image 4 will be chosen.
Above the value off Amount_T3 image 1 will be chosen.
Set the Random_Rotation value at 90 or 180 degrees if you want to rotate the images.
The Shift_Odd value shifts the odd rows to get a brick pattern.
Independent width and height controls to compansate for non square tiles.
Hook up a Texture Node to use a texture for the grout color instead of a solid color.
This file is licensed under Apache 2.0 license
*/
float variation_mix(float base, float variation, float mixvalue)
{
return base * (1 - clamp(mixvalue, 0, 1)) + variation * clamp(mixvalue, 0, 1);
}
shader RandomTiles(
string Image_1 = "" [[ string widget="filename" ]],
string Image_2 = "" [[ string widget="filename" ]],
string Image_3 = "" [[ string widget="filename" ]],
string Image_4 = "" [[ string widget="filename" ]],
float Amount_T2 = 0.25,
float Amount_T3 = 0.5,
float Amount_T4 = 0.75,
float Random_Rotation = 90,
vector HSV_Variation = vector(1.0, 0.0, 0.0),
float Shift_Odd = 0,
float Random_Shift = 0,
float Grout_Width = 0,
float Grout_Height = 0,
color Grout_Color = 1,
float Seed = 10,
output color Out_Color = 0
)
{
point pnt = point(u, 1 - v, 0);
// shift odd rows
float shift_u = 0;
float rnd_shift = noise("cell", v);
rnd_shift *= Random_Shift;
float row = mod(v, 2.0);
if (row < 1)
shift_u = u + Shift_Odd + rnd_shift;
else
shift_u = u + rnd_shift;
pnt[0] = shift_u; //assign shifted value to pnt u
float rnd = noise("cell", shift_u + Seed, v + Seed); //create a random ID for each tile
//randomly rotate tiles
point tile_pnt = floor(pnt); //restart at each tile
point center = tile_pnt + point(0.5, 0.5, 0.0); //tile center
point up = tile_pnt + point(0.5, 0.5, 1.0); //tile up vector
float rot = floor((rnd * 2 - 1) * 11) * Random_Rotation;
pnt = rotate(pnt, radians(rot), center, up);
//define grout width
point grout = center - pnt;
float GW = 0.5 - Grout_Width / 2;
float GH = 0.5 - Grout_Height / 2;
//scale tile texture to fit within grout borders
float scale_u = 1 - Grout_Width;
float scale_v = 1 - Grout_Height;;
pnt[0] -= tile_pnt[0] + Grout_Width / 2;
pnt[1] -= tile_pnt[1] + Grout_Height / 2;
pnt[0] = (pnt[0] / scale_u);
pnt[1] = (pnt[1] / scale_v);
// tile texture selection
color tile_color = 0;
if (rnd < Amount_T2)
tile_color = texture (Image_2, pnt[0], pnt[1]);
else if (rnd < Amount_T3)
tile_color = texture (Image_3, pnt[0], pnt[1]);
else if (rnd < Amount_T4)
tile_color = texture (Image_4, pnt[0], pnt[1]);
else
tile_color = texture (Image_1, pnt[0], pnt[1]);
// hsv color variation
float rnd_H = noise("cell", shift_u + (Seed * 2), v + (Seed * 3));
float rnd_S = noise("cell", shift_u + (Seed * 4), v + (Seed * 5));
float rnd_V = noise("cell", shift_u + (Seed * 6), v + (Seed * 7));
color tile_HSV = transformc("rgb", "hsv", tile_color);
color max_variation_HSV = 0;
max_variation_HSV[1] = (tile_HSV[1] + 0.5) * rnd_S;
tile_HSV[1] = variation_mix(tile_HSV[1], max_variation_HSV[1], HSV_Variation[1]);
max_variation_HSV[2] = (tile_HSV[2] + 0.5) * rnd_V;
tile_HSV[2] = variation_mix(tile_HSV[2], max_variation_HSV[2], HSV_Variation[2]);
// Hue variation must be mixed in rgb mode
color max_hue = tile_HSV;
max_variation_HSV[0] = tile_HSV[0] + rnd_H;
max_hue[0] = max_variation_HSV[0];
tile_color = transformc("hsv", "rgb", tile_HSV);
max_hue = transformc("hsv", "rgb", max_hue);
tile_color = mix(tile_color, max_hue, clamp(HSV_Variation[0], 0, 1));
tile_color = pow(tile_color, 2.2); //gamma correct tile textures
// fill tile and grout areas
if (grout[0] > -GW && grout[0] < GW &&
grout[1] > -GH && grout[1] < GH)
Out_Color = tile_color;
else
Out_Color = Grout_Color;
}