Skip to content

Commit 2e92e26

Browse files
committed
Add new halo support to !flare filter
Complements the starburst lines with a soft halo.
1 parent 2d17f62 commit 2e92e26

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

docs/shaders.md

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,9 @@ be controlled with the `downsample` attribute.
436436
### `!flare`
437437

438438
A `!flare` filter attempts to emulate the tendency of optical lenses to produce
439-
artefacts in the image, including "starbursts" and "ghosts". The filter requires
440-
a high dynamic range input (such as output by `!canvas3d`). The filter accepts
441-
the following attributes:
439+
artefacts in the image, including "starbursts", "halos" and "ghosts". The filter
440+
requires a high dynamic range input (such as output by `!canvas3d`). The filter
441+
accepts the following attributes:
442442

443443
`threshold=` *L*
444444
: A luminosity threshold over which a pixel is deemed to be "bright". Default is
@@ -452,12 +452,23 @@ means one-quarter the luminosity. Default is `2`.
452452
`upright_length=` *LENGTH*
453453
: The length of the vertical/horizontal starburst lines, expressed as a
454454
multiple of the shorter of the filter width or height. Larger values are more
455-
expensive to compute. Default is `0.25`.
455+
expensive to compute. Default is `0.25`. Setting this to `0` disables the
456+
horizontal/vertical starburst lines.
456457

457458
`diagonal_length=` *LENGTH*
458459
: The length of the diagonal starburst lines, expressed as a multiple of the
459460
shorter of the filter width or height. Larger values are more expensive to
460-
compute. Default is `0.125`.
461+
compute. Default is `0.125`. Setting this to `0` disables the diagonal starburst
462+
lines.
463+
464+
`halo_radius=` *RADIUS*
465+
: The radius of the halo added on bright spots, expressed as a multiple of the
466+
shorter of the filter width or height. Larger values are more expensive to
467+
compute. Default is `0.0625`. Setting this to `0` disables the halo.
468+
469+
`halo_attenuation=` *ATTENUATION*
470+
: An additional attenuation to apply to the halo, expressed as a power-of-2.
471+
Default is `3`.
461472

462473
`ghosts=` *N*
463474
: The number of lens ghosts to add, between `0` and `6`. The size, location and
@@ -478,6 +489,13 @@ be controlled with the `downsample` attribute. As this filter is very expensive
478489
to compute, setting `downsample=3` or `downsample=4` can make a significant
479490
difference to GPU load – particularly if the filter `size` is large.
480491

492+
:::{note}
493+
Generally, you will want to combine this filter with a [`!bloom`](#bloom) as the
494+
thresholding and attenuation makes flares localised to the brightest spots. The
495+
order in which these filters are applied will result in subtly different
496+
outputs.
497+
:::
498+
481499
### `!edges`
482500

483501
The `!edges` node applies a simple edge-detection filter by blurring the input

examples/textures.png

119 KB
Loading

src/flitter/render/window/glsl/filter_functions.glsl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,19 @@ vec3 filter_lens_flare(sampler2D tex, vec2 coord, vec2 size, float upright_lengt
9797
}
9898
return max(upright_color, diagonal_color) * pow(0.5, attenuation);
9999
}
100+
101+
vec3 filter_lens_halo(sampler2D tex, vec2 coord, vec2 size, float radius, float threshold, float attenuation) {
102+
const float Tau = 6.283185307179586231995926937088370323181152343750;
103+
float l = min(size.x, size.y) * 0.5;
104+
vec3 color = vec3(0.0);
105+
float r = radius * l;
106+
float n = Tau * r;
107+
vec2 s = r / size;
108+
if (n > 0.0) {
109+
for (float i = 0.0; i < n; i += 1.0) {
110+
vec3 col = texture(tex, coord + s * vec2(cos(i / n * Tau), sin(i / n * Tau))).rgb;
111+
color = max(color, col * smoothstep(0.0, 1.0, srgb_luminance(col) - threshold));
112+
}
113+
}
114+
return color * pow(0.5, attenuation);
115+
}

src/flitter/render/window/glsl/flare.frag

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ uniform int pass;
88
uniform int ghosts;
99
uniform float upright_length;
1010
uniform float diagonal_length;
11+
uniform float halo_radius;
12+
uniform float halo_attenuation;
1113
uniform float threshold;
1214
uniform float attenuation;
1315
uniform float aberration;
@@ -60,6 +62,7 @@ void main() {
6062
% if ghosts > 5:
6163
col += filter_lens_ghost(${'last' if passes == 5 else 'texture0'}, coord, size, 1.0, -0.75, threshold, attenuation + 1.0, aberration);
6264
% endif
65+
col += filter_lens_halo(${'last' if passes == 5 else 'texture0'}, coord, size, halo_radius, threshold, attenuation + halo_attenuation);
6366
color = vec4(col, 1.0);
6467
break;
6568
}

src/flitter/render/window/shaders.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ def render(self, node, references, **kwargs):
129129
passes = 1
130130
downsample_passes = ()
131131
super().render(node, references, passes=passes, downsample_passes=downsample_passes,
132-
upright_length=0.25, diagonal_length=0.125, ghosts=6, threshold=1, attenuation=2, aberration=1, **kwargs)
132+
upright_length=1/4, diagonal_length=1/8, ghosts=6, threshold=1, attenuation=2, aberration=1,
133+
halo_radius=1/16, halo_attenuation=3, **kwargs)
133134

134135

135136
class Noise(Shader):

0 commit comments

Comments
 (0)