forked from Maxon-Computer/Redshift-OSL-Shaders
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBlur.osl
102 lines (85 loc) · 5.44 KB
/
Blur.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
// Blur Shader - the output of this OSL shader can be attached to a Redshift Texture's Offset port to create a blur
// Written by Darby Edelen based on work by Patrick Letourneau
/*
Copyright 2023 Edward Darby Edelen
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
vector powerFromUniform(vector vec_in, float power){
float u2_sin;
float u2_cos;
float r = pow(sqrt(vec_in.x), power);
sincos(M_2PI * vec_in.y, u2_sin, u2_cos);
return vector(r * u2_cos, r * u2_sin, 0);
}
vector exponentialFromUniform(vector vec_in){
float u2_sin;
float u2_cos;
float r = -log(vec_in.x);
sincos(M_2PI * vec_in.y, u2_sin, u2_cos);
return vector(r * u2_cos, r * u2_sin, 0);
}
vector gaussianFromUniform(vector vec_in){
float u2_sin;
float u2_cos;
float r = sqrt(-2 * log(vec_in.x));
sincos(M_2PI * vec_in.y, u2_sin, u2_cos);
return vector(r * u2_cos, r * u2_sin, 0);
}
vector samplePoints(vector vec_in, float power, int mode){
if(mode==0) return gaussianFromUniform(vec_in);
if(mode==1) return powerFromUniform(vec_in, power);
if(mode==2) return exponentialFromUniform(vec_in);
}
shader Blur(
float strength = 10 [[string label="Strength", string page="Blur", string widget="number", int slider=1, float slidermin = 0, float slidermax=100, float min=0, float max=1000000000, float sensitivity = 0.1]],
int space_select = 0 [[string label="Space", string page="Blur", string widget="mapper", string options="UV:0|Object:1|World:2"]],
int kernel_select = 0 [[string label="Blur", string page="Blur", string widget="mapper", string options="Gaussian:0|Power:1|Exponential:2"]],
float power = 1 [[string label="Power", string page="Blur", int slider=1, float min = -10000.0, float max = 10000.0, float slidermin = 0.0, float slidermax = 10.0]],
int dir_mode = 0 [[string label="Direction Mode", string page="Blur",
string widget="mapper", string options="Anisotropy:0|Vector Blur:1", int connectable=0]],
float aniso = 0 [[string label="Anisotropy", string page="Anisotropy", string widget = "number", int slider=1,float min=-1,float max=1]],
float rotation = 0 [[string label="Rotation", string page="Anisotropy", string widget = "number", int slider=1, float slidermin=-180, float slidermax=180]],
int direction_space = 0 [[string label="Space", string page="Vector Blur",
string widget="mapper", string options="UV:0|World:1"]],
vector direction = vector(0,1,0) [[string label="Direction Vector", string widget = "number", string page="Vector Blur"]],
float center = 0 [[string label="Center", string page="Vector Blur", string widget = "number", int slider=1, float slidermin = -1, float slidermax = 1]],
vector tangent_in = 0 [[string label="Tangent Input", string widget = "number", string page="Vector Blur"]],
output vector UV_offset = 0,
output vector object_offset = 0,
output vector world_offset = 0
)
{
vector tangent = select(normalize(dPdu), tangent_in, isconnected(tangent_in));
vector bitangent = cross(tangent, N);
matrix TBN = matrix(tangent.x, tangent.y, tangent.z, 0,
bitangent.x, bitangent.y, bitangent.z, 0,
Ng.x, Ng.y, Ng.z, 0,
0, 0, 0, 0);
float obj_scale = space_select == 1 ? length(transform(matrix("object","world"), normalize(vector(1)))) : 1;
vector a = vector(1 + aniso, 1 - aniso, 0);
vector zrnd = samplePoints(noise("hash", vector(1) - P), power, kernel_select);
vector off = samplePoints(noise("hash", P), power, kernel_select) + vector(0,0,zrnd.x);
vector uv_blur_direct = select(direction * vector(1,1,0),
vector(dot(direction, normalize(tangent)), dot(direction, normalize(bitangent)), 0),
direction_space);
vector world_blur_direct = select(transform(TBN, direction), direction, direction_space);
vector world_blur_vec = select(transform(TBN, a * off), (off.x + center) * world_blur_direct, dir_mode);
vector obj_blur_vec = transform(matrix("world", "object"), world_blur_vec);
float uv_blur_length = length(uv_blur_direct);
vector uv_space = select(vector(0.001), vector(0.1/length(dPdu), 0.1/length(dPdv), 0.), space_select);
vector xyz_space = select(vector(0.01), vector(0.01), space_select);
uv_blur_direct /= uv_blur_length;
float uv_blur_rotate = select(radians(rotation), atan2(uv_blur_direct.y, uv_blur_direct.x), dir_mode);
vector uv_blur_vec = select(off * a, (off.x + center) * vector(uv_blur_length,0,0), dir_mode);
UV_offset = rotate(uv_blur_vec, uv_blur_rotate, vector(0,0,1)) * strength * uv_space * obj_scale;
object_offset = select(rotate(obj_blur_vec, radians(rotation), Ng), obj_blur_vec, dir_mode) * strength * xyz_space;
world_offset = select(rotate(world_blur_vec, radians(rotation), Ng), world_blur_vec, dir_mode) * strength * xyz_space;
}