-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathKuwaharaFilter.osl
More file actions
75 lines (60 loc) · 2.46 KB
/
Copy pathKuwaharaFilter.osl
File metadata and controls
75 lines (60 loc) · 2.46 KB
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
// KuwaharaFilter.osl by DizzyQuarkArt
// This file is licensed under Apache 2.0 license
shader kuwahara_filter(
string fileName = "" [[string widget="filename", string page = "Image" ]],
string fileColorSpace = "" [[string label = "Colorspace", string page = "Color Space Conversion", string widget = "colorspace"]],
float Radius = 0.003,
output color Output = color(0.0))
{
int radSteps = int(Radius * 1000); // Convert radius to integer steps
if (radSteps < 1)
radSteps = 1;
color mean[4] = {color(0), color(0), color(0), color(0)};
float variance[4] = {0.0, 0.0, 0.0, 0.0};
// Offset directions for the four neighborhoods
int offset_x[4] = {-1, 1, -1, 1};
int offset_y[4] = {-1, -1, 1, 1};
// Get the base UV coordinates
vector uv = vector(u, -v, 0);
// Loop through the four neighborhoods
for (int n = 0; n < 4; n++) {
color sum = color(0.0);
float sum_sq = 0.0;
int count = 0;
// Sample the neighborhood
for (int x = 0; x <= radSteps; x++) {
for (int y = 0; y <= radSteps; y++) {
// Compute texture coordinates with offsets
float u_offset = offset_x[n] * x * Radius;
float v_offset = offset_y[n] * y * Radius;
float u_new = uv[0] + u_offset;
float v_new = uv[1] + v_offset;
// Wrap UV coordinates to stay within 0 to 1
u_new = u_new - floor(u_new);
v_new = v_new - floor(v_new);
// Sample texture at offset
color sample = texture(fileName, u_new, v_new);
sum += sample;
sum_sq += dot(sample, sample);
count++;
}
}
// Calculate mean and variance for the neighborhood
mean[n] = sum / count;
variance[n] = (sum_sq / count) - dot(mean[n], mean[n]);
}
// Find the neighborhood with the minimum variance
int min_index = 0;
float min_variance = variance[0];
for (int i = 1; i < 4; i++) {
if (variance[i] < min_variance) {
min_variance = variance[i];
min_index = i;
}
}
// Set the output color to the mean of the selected neighborhood
color output_mean = mean[min_index];
color textureSampleRAW = transformc("ACEScg", "scene-linear Rec.709-sRGB", output_mean);
color outColor = transformc(fileColorSpace, "ACEScg", textureSampleRAW);
Output = outColor;
}