2022-09-29 20:34:05 +02:00
|
|
|
#define rendered texture0
|
|
|
|
#define bloom texture1
|
2022-09-06 08:25:18 +02:00
|
|
|
|
2023-12-19 20:18:11 +01:00
|
|
|
#ifdef GL_ES
|
|
|
|
// Dithering requires sufficient floating-point precision
|
|
|
|
#ifndef GL_FRAGMENT_PRECISION_HIGH
|
|
|
|
#undef ENABLE_DITHERING
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2023-01-06 22:33:25 +01:00
|
|
|
struct ExposureParams {
|
|
|
|
float compensationFactor;
|
|
|
|
};
|
|
|
|
|
2022-09-29 20:34:05 +02:00
|
|
|
uniform sampler2D rendered;
|
|
|
|
uniform sampler2D bloom;
|
2023-01-06 22:33:25 +01:00
|
|
|
|
2023-06-28 05:30:08 +02:00
|
|
|
uniform vec2 texelSize0;
|
|
|
|
|
2023-01-06 22:33:25 +01:00
|
|
|
uniform ExposureParams exposureParams;
|
2022-10-04 14:52:56 +02:00
|
|
|
uniform lowp float bloomIntensity;
|
2022-11-18 20:49:52 +01:00
|
|
|
uniform lowp float saturation;
|
2022-09-06 08:25:18 +02:00
|
|
|
|
|
|
|
#ifdef GL_ES
|
|
|
|
varying mediump vec2 varTexCoord;
|
|
|
|
#else
|
|
|
|
centroid varying vec2 varTexCoord;
|
|
|
|
#endif
|
|
|
|
|
2023-02-10 21:04:37 +01:00
|
|
|
#ifdef ENABLE_AUTO_EXPOSURE
|
|
|
|
varying float exposure; // linear exposure factor, see vertex shader
|
|
|
|
#endif
|
2023-01-06 22:33:25 +01:00
|
|
|
|
2022-10-04 14:52:56 +02:00
|
|
|
#ifdef ENABLE_BLOOM
|
2022-09-29 20:34:05 +02:00
|
|
|
|
|
|
|
vec4 applyBloom(vec4 color, vec2 uv)
|
|
|
|
{
|
2022-11-02 09:09:48 +01:00
|
|
|
vec3 light = texture2D(bloom, uv).rgb;
|
2022-10-04 14:52:56 +02:00
|
|
|
#ifdef ENABLE_BLOOM_DEBUG
|
2022-09-29 20:34:05 +02:00
|
|
|
if (uv.x > 0.5 && uv.y < 0.5)
|
2022-11-02 09:09:48 +01:00
|
|
|
return vec4(light, color.a);
|
2022-09-29 20:34:05 +02:00
|
|
|
if (uv.x < 0.5)
|
2022-11-03 08:43:31 +01:00
|
|
|
return color;
|
2022-09-29 20:34:05 +02:00
|
|
|
#endif
|
2022-11-02 09:09:48 +01:00
|
|
|
color.rgb = mix(color.rgb, light, bloomIntensity);
|
2022-09-29 20:34:05 +02:00
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2022-10-09 19:11:04 +02:00
|
|
|
#if ENABLE_TONE_MAPPING
|
2022-09-06 08:25:18 +02:00
|
|
|
|
|
|
|
/* Hable's UC2 Tone mapping parameters
|
|
|
|
A = 0.22;
|
|
|
|
B = 0.30;
|
|
|
|
C = 0.10;
|
|
|
|
D = 0.20;
|
|
|
|
E = 0.01;
|
|
|
|
F = 0.30;
|
|
|
|
W = 11.2;
|
|
|
|
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
|
|
|
*/
|
|
|
|
|
|
|
|
vec3 uncharted2Tonemap(vec3 x)
|
|
|
|
{
|
|
|
|
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec4 applyToneMapping(vec4 color)
|
|
|
|
{
|
2023-12-16 19:11:52 +01:00
|
|
|
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
|
|
|
|
const float gamma = 1.6;
|
|
|
|
const float exposureBias = 5.5;
|
2022-09-06 08:25:18 +02:00
|
|
|
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
|
|
|
|
// Precalculated white_scale from
|
|
|
|
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
|
|
|
vec3 whiteScale = vec3(1.036015346);
|
|
|
|
color.rgb *= whiteScale;
|
2023-12-16 19:11:52 +01:00
|
|
|
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
|
2022-09-06 08:25:18 +02:00
|
|
|
}
|
2023-12-16 19:15:34 +01:00
|
|
|
#endif
|
2022-11-18 20:49:52 +01:00
|
|
|
|
|
|
|
vec3 applySaturation(vec3 color, float factor)
|
|
|
|
{
|
|
|
|
// Calculate the perceived luminosity from the RGB color.
|
|
|
|
// See also: https://www.w3.org/WAI/GL/wiki/Relative_luminance
|
|
|
|
float brightness = dot(color, vec3(0.2125, 0.7154, 0.0721));
|
|
|
|
return mix(vec3(brightness), color, factor);
|
|
|
|
}
|
2022-09-06 08:25:18 +02:00
|
|
|
|
2023-12-19 20:18:11 +01:00
|
|
|
#ifdef ENABLE_DITHERING
|
|
|
|
// From http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf
|
|
|
|
// and https://www.shadertoy.com/view/MslGR8 (5th one starting from the bottom)
|
|
|
|
// NOTE: `frag_coord` is in pixels (i.e. not normalized UV).
|
|
|
|
vec3 screen_space_dither(highp vec2 frag_coord) {
|
|
|
|
// Iestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR.
|
|
|
|
highp vec3 dither = vec3(dot(vec2(171.0, 231.0), frag_coord));
|
|
|
|
dither.rgb = fract(dither.rgb / vec3(103.0, 71.0, 97.0));
|
|
|
|
|
|
|
|
// Subtract 0.5 to avoid slightly brightening the whole viewport.
|
|
|
|
return (dither.rgb - 0.5) / 255.0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-09-06 08:25:18 +02:00
|
|
|
void main(void)
|
|
|
|
{
|
|
|
|
vec2 uv = varTexCoord.st;
|
2023-06-28 05:30:08 +02:00
|
|
|
#ifdef ENABLE_SSAA
|
|
|
|
vec4 color = vec4(0.);
|
|
|
|
for (float dx = 1.; dx < SSAA_SCALE; dx += 2.)
|
|
|
|
for (float dy = 1.; dy < SSAA_SCALE; dy += 2.)
|
|
|
|
color += texture2D(rendered, uv + texelSize0 * vec2(dx, dy)).rgba;
|
|
|
|
color /= SSAA_SCALE * SSAA_SCALE / 4.;
|
|
|
|
#else
|
2022-09-06 08:25:18 +02:00
|
|
|
vec4 color = texture2D(rendered, uv).rgba;
|
2023-06-28 05:30:08 +02:00
|
|
|
#endif
|
2022-09-06 08:25:18 +02:00
|
|
|
|
2022-09-29 20:34:05 +02:00
|
|
|
// translate to linear colorspace (approximate)
|
|
|
|
color.rgb = pow(color.rgb, vec3(2.2));
|
|
|
|
|
2022-10-04 14:52:56 +02:00
|
|
|
#ifdef ENABLE_BLOOM_DEBUG
|
2022-09-29 20:34:05 +02:00
|
|
|
if (uv.x > 0.5 || uv.y > 0.5)
|
|
|
|
#endif
|
|
|
|
{
|
2023-02-10 21:04:37 +01:00
|
|
|
color.rgb *= exposureParams.compensationFactor;
|
|
|
|
#ifdef ENABLE_AUTO_EXPOSURE
|
|
|
|
color.rgb *= exposure;
|
|
|
|
#endif
|
2022-09-29 20:34:05 +02:00
|
|
|
}
|
|
|
|
|
2022-10-04 14:52:56 +02:00
|
|
|
#ifdef ENABLE_BLOOM
|
2022-09-29 20:34:05 +02:00
|
|
|
color = applyBloom(color, uv);
|
|
|
|
#endif
|
|
|
|
|
2023-12-16 19:11:52 +01:00
|
|
|
|
|
|
|
color.rgb = clamp(color.rgb, vec3(0.), vec3(1.));
|
|
|
|
|
|
|
|
// return to sRGB colorspace (approximate)
|
|
|
|
color.rgb = pow(color.rgb, vec3(1.0 / 2.2));
|
|
|
|
|
2022-10-04 14:52:56 +02:00
|
|
|
#ifdef ENABLE_BLOOM_DEBUG
|
2022-09-29 20:34:05 +02:00
|
|
|
if (uv.x > 0.5 || uv.y > 0.5)
|
|
|
|
#endif
|
|
|
|
{
|
2022-10-09 19:11:04 +02:00
|
|
|
#if ENABLE_TONE_MAPPING
|
2022-09-29 20:34:05 +02:00
|
|
|
color = applyToneMapping(color);
|
2022-09-06 08:25:18 +02:00
|
|
|
#endif
|
2023-12-16 19:15:34 +01:00
|
|
|
|
|
|
|
color.rgb = applySaturation(color.rgb, saturation);
|
2022-09-29 20:34:05 +02:00
|
|
|
}
|
|
|
|
|
2023-12-19 20:18:11 +01:00
|
|
|
#ifdef ENABLE_DITHERING
|
|
|
|
// Apply dithering just before quantisation
|
|
|
|
color.rgb += screen_space_dither(gl_FragCoord.xy);
|
|
|
|
#endif
|
|
|
|
|
2022-09-06 08:25:18 +02:00
|
|
|
gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image.
|
|
|
|
}
|