HDR: New blackout/redout effect
This commit is contained in:
parent
430fc52f4a
commit
3e9ec9bf6a
4 changed files with 128 additions and 20 deletions
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
57
Shaders/HDR/redout.glsl
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue