-
Notifications
You must be signed in to change notification settings - Fork 0
/
textureNoTile.osl
114 lines (99 loc) · 4.29 KB
/
textureNoTile.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
// OSL version of Inigo Quilez texture repetition shaders: https://www.iquilezles.org/www/articles/texturerepetition/texturerepetition.htm
shader textureNoTile
(
vector UVW = vector(u, v, 0),
string Filename = "" [[ string label="File name", string help="File path of the texture to repeat" ]],
float Frequency = 1 [[ string help="Multiplies the UV vector by this number to create more tiles" ]],
float ColorAvg = 0.5 [[ string help="Color average of input texture" ]],
float Contrast = 1.2 [[ string help="Adds a bit of contrast to final color" ]],
int Seed = 1 [[ string help="The random seed" ]],
int Technique = 1 [[ string help="Which tiling technique to use (1, 2 or 3)" ]],
output color Out = 0.0,
)
{
vector uvfreq = UVW * Frequency;
vector p = floor(uvfreq);
vector f = uvfreq - p;
float gamma = 1.0;
// Temporary workaround for color space issues
if (!endswith(Filename, ".exr") &&
!endswith(Filename, ".EXR") &&
!endswith(Filename, ".hdr") &&
!endswith(Filename, ".HDR") &&
!endswith(Filename, ".tx") &&
!endswith(Filename, ".TX"))
{
gamma = 2.2; //srgb approx
}
if (Technique == 1)
{
// generate per-tile transform
vector ofa = noise("cell", p + vector(0, 0, 0), Seed);
vector ofb = noise("cell", p + vector(1, 0, 0), Seed);
vector ofc = noise("cell", p + vector(0, 1, 0), Seed);
vector ofd = noise("cell", p + vector(1, 1, 0), Seed);
// transform per-tile uvs
vector signa = sign(ofa-0.5);
vector signb = sign(ofb-0.5);
vector signc = sign(ofc-0.5);
vector signd = sign(ofa-0.5);
vector uva = UVW*signa + ofa;
vector uvb = UVW*signb + ofb;
vector uvc = UVW*signc + ofc;
vector uvd = UVW*signd + ofd;
// fetch and blend
vector b = smoothstep(0.25, 0.75, f);
Out = mix( mix(texture(Filename, uva.x, 1.0 - uva.y, "wrap", "periodic"),
texture(Filename, uvb.x, 1.0 - uvb.y, "wrap", "periodic"), b[0]),
mix(texture(Filename, uvc.x, 1.0 - uvc.y, "wrap", "periodic"),
texture(Filename, uvd.x, 1.0 - uvd.y, "wrap", "periodic"), b[0]), b[1]);
// increase contrast
Out = ColorAvg + Contrast*(Out-ColorAvg);
}
else if (Technique == 2)
{
// voronoi contribution
vector va = vector(0, 0, 0);
float w1 = 0.0;
for (int j = -1; j <= 1; j++)
{
for (int i = -1; i <= 1; i++)
{
vector g = vector(float(i), float(j), 0);
vector o = noise("cell", p+g, Seed);
vector r = vector(g.x - f.x + o.x, g.y - f.y + o.y, 0.0);
float d = dot(r, r);
float w = exp(-5.0*d);
color c = texture(Filename, uvfreq.x + o.x, 1.0 - uvfreq.y + o.y, "wrap", "periodic");
if (gamma != 1.0) c = pow(c, gamma);
va += w*c;
w1 += w;
}
}
// normalization
Out = va / w1;
// increase contrast
Out = ColorAvg + Contrast*(Out-ColorAvg);
}
else if (Technique == 3)
{
float k = texture(Filename, 0.005 * UVW.x, 1.0 - 0.005 * UVW.y, "wrap", "periodic"); // cheap (cache friendly) lookup
// compute index
float index = k*8.0;
float i = floor(index);
float f = index - i;
// offsets for the different virtual patterns
vector offa = sin(vector(3.0, 7.0, 0.0) * (i + 0.0)); // can replace with any other hash
vector offb = sin(vector(3.0, 7.0, 0.0) * (i + 1.0)); // can replace with any other hash
// sample the two closest virtual patterns
color cola = texture(Filename, UVW.x + offa.x, 1.0 - UVW.y + offa.y , "wrap", "periodic");
if (gamma != 1.0) cola = pow(cola, gamma);
color colb = texture(Filename, UVW.x + offb.x, 1.0 - UVW.y + offb.y , "wrap", "periodic");
if (gamma != 1.0) colb = pow(colb, gamma);
float sum(vector v) { return v.x + v.y + v.z; }
// interpolate between the two virtual patterns
Out = mix(cola, colb, smoothstep(0.2, 0.8, f - 0.1 * sum(cola - colb)));
// increase contrast
Out = ColorAvg + Contrast*(Out-ColorAvg);
}
}