#define rendered texture0 #define bloom texture1 uniform sampler2D rendered; uniform sampler2D bloom; uniform mediump float exposureFactor; uniform lowp float bloomIntensity; #ifdef GL_ES varying mediump vec2 varTexCoord; #else centroid varying vec2 varTexCoord; #endif #ifdef ENABLE_BLOOM vec4 applyBloom(vec4 color, vec2 uv) { float bias = bloomIntensity; vec4 bloom = texture2D(bloom, uv); #ifdef ENABLE_BLOOM_DEBUG if (uv.x > 0.5 && uv.y < 0.5) return vec4(bloom.rgb, color.a); if (uv.x < 0.5) return color; #endif color.rgb = mix(color.rgb, bloom.rgb, bias); return color; } #endif #if ENABLE_TONE_MAPPING /* 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) { const float exposureBias = 2.0; 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; return color; } #endif void main(void) { vec2 uv = varTexCoord.st; vec4 color = texture2D(rendered, uv).rgba; // translate to linear colorspace (approximate) color.rgb = pow(color.rgb, vec3(2.2)); #ifdef ENABLE_BLOOM_DEBUG if (uv.x > 0.5 || uv.y > 0.5) #endif { color.rgb *= exposureFactor; } #ifdef ENABLE_BLOOM color = applyBloom(color, uv); #endif #ifdef ENABLE_BLOOM_DEBUG if (uv.x > 0.5 || uv.y > 0.5) #endif { #if ENABLE_TONE_MAPPING color = applyToneMapping(color); #else color.rgb /= 2.5; // default exposure factor, see also RenderingEngine::DEFAULT_EXPOSURE_FACTOR; #endif } color.rgb = clamp(color.rgb, vec3(0.), vec3(1.)); // return to sRGB colorspace (approximate) color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image. }