1
0
Fork 0

HDR: New blackout/redout effect

This commit is contained in:
Fernando García Liñán 2024-01-26 01:11:44 +01:00
parent 430fc52f4a
commit 3e9ec9bf6a
4 changed files with 128 additions and 20 deletions

View file

@ -4,14 +4,21 @@
<parameters>
<bloom-strength><use>/sim/rendering/hdr/bloom/strength</use></bloom-strength>
<debug-ev100><use>/sim/rendering/hdr/debug/display-ev100</use></debug-ev100>
<!-- redout.glsl -->
<alpha><use>/sim/rendering/redout/alpha</use></alpha>
<red><use>/sim/rendering/redout/red</use></red>
<max-distorsion-amount type="float">0.2</max-distorsion-amount>
</parameters>
<technique n="1">
<pass>
<program>
<vertex-shader>Shaders/HDR/quad.vert</vertex-shader>
<fragment-shader>Shaders/HDR/postprocess.frag</fragment-shader>
<fragment-shader>Shaders/HDR/aces.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/aces.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/redout.glsl</fragment-shader>
<fragment-shader>Shaders/HDR/noise.glsl</fragment-shader>
</program>
<uniform>
<name>hdr_tex</name>
@ -33,6 +40,22 @@
<type>bool</type>
<value><use>debug-ev100</use></value>
</uniform>
<!-- redout.glsl -->
<uniform>
<name>alpha</name>
<type>float</type>
<value><use>alpha</use></value>
</uniform>
<uniform>
<name>red</name>
<type>bool</type>
<value><use>red</use></value>
</uniform>
<uniform>
<name>max_distorsion_amount</name>
<type>float</type>
<value><use>max-distorsion-amount</use></value>
</uniform>
</pass>
</technique>
</PropertyList>

View file

@ -1,10 +1,5 @@
#version 330 core
float linear_srgb_to_luminance(vec3 color)
{
return dot(color, vec3(0.2126, 0.7152, 0.0722));
}
/*
* Transform an sRGB color to linear sRGB.
*/
@ -16,6 +11,14 @@ vec3 eotf_inverse_sRGB(vec3 srgb)
return mix(a, b, c);
}
float eotf_inverse_sRGB_component(float srgb)
{
float a = srgb / 12.92;
float b = pow((srgb + 0.055) / 1.055, 2.4);
float c = step(0.04045, srgb);
return mix(a, b, c);
}
/*
* Transform a linear sRGB color to sRGB (gamma correction).
*/
@ -26,3 +29,23 @@ vec3 eotf_sRGB(vec3 linear_srgb)
vec3 c = step(vec3(0.0031308), linear_srgb);
return mix(a, b, c);
}
float eotf_sRGB_component(float linear_srgb)
{
float a = 12.92 * linear_srgb;
float b = 1.055 * pow(linear_srgb, 1.0 / 2.4) - 0.055;
float c = step(0.0031308, linear_srgb);
return mix(a, b, c);
}
float linear_srgb_to_luminance(vec3 color)
{
return dot(color, vec3(0.2126, 0.7152, 0.0722));
}
float srgb_to_luminance(vec3 color)
{
vec3 linear = eotf_inverse_sRGB(color);
float lum = linear_srgb_to_luminance(linear);
return eotf_sRGB_component(lum);
}

View file

@ -12,10 +12,17 @@ uniform vec2 fg_BufferSize;
uniform float bloom_strength;
uniform bool debug_ev100;
// aces.glsl
vec3 aces_fitted(vec3 color);
const float NOISE_GRANULARITY = 0.5 / 255.0;
// color.glsl
vec3 eotf_sRGB(vec3 linear_srgb);
// aces.glsl
vec3 aces_fitted(vec3 color);
// redout.glsl
vec2 redout_distort(vec2 uv);
vec3 redout_apply(vec3 color, vec2 uv);
// noise.glsl
float rand_2d(vec2 co);
vec3 get_debug_color(float value)
{
@ -42,30 +49,28 @@ vec3 get_ev100_color(vec3 hdr)
return get_debug_color(norm);
}
float rand2D(vec2 co)
{
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main()
{
vec3 hdr_color = texture(hdr_tex, texcoord).rgb;
if (debug_ev100) {
fragColor = vec4(get_ev100_color(hdr_color), 1.0);
fragColor = vec4(get_ev100_color(texture(hdr_tex, texcoord).rgb), 1.0);
return;
}
// Apply bloom
vec3 bloom = texture(bloom_tex, texcoord).rgb;
hdr_color = mix(hdr_color, bloom, bloom_strength);
// Blackout/redout applies a small distortion effect
vec2 uv = redout_distort(texcoord);
vec3 hdr_color = texture(hdr_tex, uv).rgb;
// Apply bloom
vec3 bloom = texture(bloom_tex, uv).rgb;
hdr_color = mix(hdr_color, bloom, bloom_strength);
// Tonemap
vec3 color = aces_fitted(hdr_color);
// Apply blackout/redout
color = redout_apply(color, uv);
// Gamma correction
color = eotf_sRGB(color);
// Dithering
color += mix(-0.5/255.0, 0.5/255.0, rand2D(texcoord));
color += mix(-NOISE_GRANULARITY, NOISE_GRANULARITY, rand_2d(texcoord));
fragColor = vec4(color, 1.0);
}

57
Shaders/HDR/redout.glsl Normal file
View file

@ -0,0 +1,57 @@
#version 330 core
uniform float alpha;
uniform bool red;
uniform float max_distorsion_amount;
// math.glsl
float sqr(float x);
// color.glsl
float srgb_to_luminance(vec3 color);
vec3 desaturate(vec3 color, float saturation)
{
float lum = srgb_to_luminance(color);
return mix(vec3(lum), color, saturation);
}
float opacity(vec2 uv, float amount)
{
float dist_factor = 1.0 + distance(uv, vec2(0.5)) * 0.3;
return 1.0 - min(amount * dist_factor, 1.0);
}
/*
* Distort texcoords according to the intensity of the blackout/redout effect.
*/
vec2 redout_distort(vec2 uv)
{
// Early exit if there is no blackout/redout
if (alpha < 1e-5) {
return uv;
}
uv = uv - vec2(0.5);
float uva = atan(uv.x, uv.y);
float uvd = sqrt(dot(uv, uv));
float k = mix(0.0, -max_distorsion_amount, alpha);
uvd = uvd * (1.0 + k * sqr(uvd));
return vec2(sin(uva), cos(uva)) * uvd + vec2(0.5);
}
/*
* Apply the blackout/redout effect.
*/
vec3 redout_apply(vec3 color, vec2 uv)
{
// Early exit if there is no blackout/redout
if (alpha < 1e-5) {
return color;
}
color *= opacity(uv, alpha);
if (red) {
color = mix(color, vec3(color.r, 0.0, 0.0), alpha);
} else {
color = desaturate(color, 1.0 - alpha);
}
return color;
}