sure thing. tho’ it requires proper input data, not sure if it really helps
:
[icode]src_tex[/icode] is a RGB16F texture which contains the bloom data, mostly black with pixels too bright to fit into 0.0 … 1.0 range. it’s already blurred alot, using a ping-pong separated gauss-blur for each mipmap level. the sampler for that texture is set to linear with [icode]GL13.GL_CLAMP_TO_BORDER[/icode] which is set to transparent. [icode]src_tex2[/icode] is the same texture with another sampler object with clamping set to [icode]GL12.GL_CLAMP_TO_EDGE[/icode].
since i store custom blurred bloom masks in each miplevel, reading a deeper mip results in more blurrines. the effect is also very affected by how you extract the bloom data from hdr colors, cutoff, etc.
this code is not really optimised or finished, more a first attempt scratch.
#version 400
in vec2 st0;
out vec3 frag; // output is another RGB16F texture
uniform sampler2D src_tex;
uniform sampler2D src_tex2;
uniform float aspect; // display aspect ratio width/height
uniform float inv_aspect; // 1.0 / aspect
uniform float yfov; // screen y-fov radians, i set this to 0.0f if rendering 2D
#define lumcoeff vec3(0.2125, 0.7154, 0.0721)
#define luminance(color) (dot(lumcoeff, color))
#define flare_chromatic_disp
#define flare_saturation 0.5
// toggle horizontal flare
#define streak
// function and macro versionof distance to screen-border
float edge_dist_f( const vec2 st ) { return st.x*st.y*(1.0 - st.x)*(1.0 - st.y) * 16.0; }
#define edge_dist(st) ( st.x*st.y*(1.0 - st.x)*(1.0 - st.y) * 16.0 )
// 3rd argument is the amount of RGB dispersion
#ifdef flare_chromatic_disp
#define flare_sample_fade( st, mip, disp ) ( vec3( \
texture(src_tex, st + to_center * disp, mip).r * edge_dist_f( (st + to_center * disp) ), \
texture(src_tex, st, mip).g * edge_dist(st), \
texture(src_tex, st - to_center * disp, mip).b * edge_dist_f( (st - to_center * disp) ) \
) )
#define flare_sample( st, mip, disp ) ( vec3( \
texture(src_tex, st + to_center * disp, mip).r, \
texture(src_tex, st, mip).g, \
texture(src_tex, st - to_center * disp, mip).b \
) )
#else
#define flare_sample_fade( st, mip, disp ) ( texture(src_tex, st, mip).rgb * edge_dist(st) )
#define flare_sample( st, mip, disp ) ( texture(src_tex, st, mip).rgb )
#endif
void main()
{
vec2 st = st0;
vec2 mirror = vec2(1.0) - st;
vec2 to_center = vec2(0.5) - st;
vec2 to_center_as = (vec2(0.5) - st) * vec2(1.0, inv_aspect);
vec2 to_mirror = mirror - st;
float to_center_dist = length(to_center) * 2.0;
float to_center_as_dist = length(to_center_as) * 2.0;
float to_edge = edge_dist(st0);
vec3 smp = vec3(0.0);
// 3 halos
vec2 st_0 = st - to_center * +2.3;
vec2 st_1 = mirror + to_center * +3.0;
vec2 st_2 = mirror + to_center * -0.1;
float fade_2 = edge_dist(st_2);
fade_2 = 1.0 - pow( 1.0 - fade_2, 8.0 );
#define halo_mip_offset 1.0
smp += flare_sample_fade( st_0, -1.0 + halo_mip_offset, 0.5 ) * 0.5;
smp += flare_sample_fade( st_1, -1.0 + halo_mip_offset, 0.5 ) * 0.6;
smp += flare_sample ( st_2, 1.0 + halo_mip_offset, 0.1 ) * fade_2 * 0.65;
// ring
float radius_scale = 1.33 + yfov - (step(0.01, yfov) * 1.2);
vec2 st_h = mirror - to_center * 1.07 * radius_scale * to_center_as_dist * to_center_as_dist;
smp += flare_sample( st_h, halo_mip_offset, 0.05 ) * to_center_dist * to_center_dist * 0.5;
//
#ifdef flare_saturation
smp = mix(vec3(luminance(smp)), smp, flare_saturation);
#endif
// streak
#ifdef streak
#define streak_saturation 0.5
#define streak_samples 30
#define streak_samples_i 0.0333333
#define streak_mip 0.0
#define streak_width 0.33
#define streak_scale 0.8
vec3 s_smp = vec3(0.0);
for( int i = 0; i < streak_samples; i++)
{
float ramp = streak_samples_i * i;
float tri = ramp * 2.0 - 1.0;
float dist = abs(tri);
float rdist = 1.0 - dist;
float o = tri * streak_width;
vec2 s_st = vec2(st.x + o, st.y);
float edist = max(0.0, 1.0 - pow( 1.0 - edge_dist(s_st), 8.0 ));
s_smp += texture( src_tex2, s_st, streak_mip ).rgb * rdist * edist;
}
s_smp *= streak_samples_i;
#ifdef streak_saturation
s_smp = mix(vec3(luminance(s_smp)), s_smp, streak_saturation);
#endif
smp += s_smp * streak_scale;
#endif
frag = smp;
}