-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhalation.dctl
72 lines (59 loc) · 2.63 KB
/
halation.dctl
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
// Halation v22.09.7
//
// https://github.com/hotgluebanjo
//
// THIS DCTL REQUIRES OPEN DOMAIN SCENE-LINEAR INPUT VALUES.
// Size of the falloff filter. A higher value results in a larger pixel radius which will be slower.
DEFINE_UI_PARAMS(SIZE, Size, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 5.0, 0.001)
// How much light passes back through the green layer.
DEFINE_UI_PARAMS(COLOR, Color, DCTLUI_SLIDER_FLOAT, 0.15, 0.0, 0.5, 0.001)
// Method to use. Options are:
// - Proosa: https://liftgammagain.com/forum/index.php?threads/halation-and-gate-weave.13056/page-5#post-145519
// - Minuth: https://liftgammagain.com/forum/index.php?threads/halation-and-gate-weave.13056/page-6#post-149147
DEFINE_UI_PARAMS(METHOD, Method, DCTLUI_COMBO_BOX, 0, {PROOSA, MINUTH}, {Proosa, Minuth})
__DEVICE__ inline float3 _sample(__TEXTURE__ p_TexR, __TEXTURE__ p_TexG, __TEXTURE__ p_TexB, int p_X, int p_Y) {
return make_float3(
_tex2D(p_TexR, p_X, p_Y),
_tex2D(p_TexG, p_X, p_Y),
_tex2D(p_TexB, p_X, p_Y)
);
}
__DEVICE__ inline float exp_k(float x, float y, float r0) {
return _expf(-_sqrtf(x*x + y*y) / r0);
}
// There doesn't seem to be a way to set a pixel on a texture, so can't get faster.
// Pretty sure this kernel isn't separable anyway.
__DEVICE__ float3 exp_blur(__TEXTURE__ p_TexR, __TEXTURE__ p_TexG, __TEXTURE__ p_TexB, int p_X, int p_Y, float size) {
// Radius is just large enough to capture most of the falloff.
int radius = _ceil(4.5f * size);
float3 sum = make_float3(0.0f, 0.0f, 0.0f);
float weight_sum = 0.0f;
for (int i = -radius; i <= radius; i += 1) {
for (int j = -radius; j <= radius; j += 1) {
float weight = exp_k(i, j, size);
sum += weight * _sample(p_TexR, p_TexG, p_TexB, p_X + i, p_Y + j);
weight_sum += weight;
}
}
return sum / weight_sum;
}
__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, __TEXTURE__ p_TexR, __TEXTURE__ p_TexG, __TEXTURE__ p_TexB) {
float3 rgb = _sample(p_TexR, p_TexG, p_TexB, p_X, p_Y);
if (SIZE < 1e-10) return rgb;
float3 blurred = exp_blur(p_TexR, p_TexG, p_TexB, p_X, p_Y, SIZE);
float3 result, color, halated;
switch (METHOD) {
case PROOSA:
color = make_float3(1.0f, COLOR, 0.0f);
halated = rgb + (blurred * color);
result = halated / (color + 1.0f);
break;
// Approximation of what the Texture Blend blend mode is doing.
// Just frequency separation.
case MINUTH:
color = make_float3(0.7f, 1.0f - COLOR / 3.0f, 1.0f);
halated = (rgb - blurred) * color;
result = halated + blurred;
}
return result;
}