From ffad582358aeb85c8caf191a0d9522b18139d840 Mon Sep 17 00:00:00 2001
From: Alexander Gauggel <agauggel@uni-koblenz.de>
Date: Fri, 25 Jun 2021 17:34:25 +0200
Subject: [PATCH] [#82] Add subtle chromatic aberration in high contrast areas

---
 .../voxelization/resources/shaders/luma.inc   |  8 ++++
 .../resources/shaders/msaa4XResolve.comp      |  6 +--
 .../resources/shaders/tonemapping.comp        | 43 ++++++++++++++++++-
 3 files changed, 52 insertions(+), 5 deletions(-)
 create mode 100644 projects/voxelization/resources/shaders/luma.inc

diff --git a/projects/voxelization/resources/shaders/luma.inc b/projects/voxelization/resources/shaders/luma.inc
new file mode 100644
index 00000000..17b3b282
--- /dev/null
+++ b/projects/voxelization/resources/shaders/luma.inc
@@ -0,0 +1,8 @@
+#ifndef LUMA_INC
+#define LUMA_INC
+
+float computeLuma(vec3 c){
+    return dot(c, vec3(0.21, 0.72, 0.07));
+}
+
+#endif // #ifndef LUMA_INC
\ No newline at end of file
diff --git a/projects/voxelization/resources/shaders/msaa4XResolve.comp b/projects/voxelization/resources/shaders/msaa4XResolve.comp
index 746e0b1e..8bb1a946 100644
--- a/projects/voxelization/resources/shaders/msaa4XResolve.comp
+++ b/projects/voxelization/resources/shaders/msaa4XResolve.comp
@@ -1,17 +1,15 @@
 #version 450
 #extension GL_ARB_texture_multisample : enable
+#extension GL_GOOGLE_include_directive : enable
 
 layout(set=0, binding=0)                    uniform texture2DMS     srcTexture;
 layout(set=0, binding=1)                    uniform sampler         MSAASampler;                
 layout(set=0, binding=2, r11f_g11f_b10f)    uniform image2D         outImage;
 
+#include "luma.inc"
 
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 
-float computeLuma(vec3 c){
-    return dot(c, vec3(0.21, 0.72, 0.07));
-}
-
 vec3 tonemap(vec3 c){
     return c / (1 + computeLuma(c));
 }
diff --git a/projects/voxelization/resources/shaders/tonemapping.comp b/projects/voxelization/resources/shaders/tonemapping.comp
index 84485b47..500fa0c2 100644
--- a/projects/voxelization/resources/shaders/tonemapping.comp
+++ b/projects/voxelization/resources/shaders/tonemapping.comp
@@ -1,4 +1,7 @@
 #version 440
+#extension GL_GOOGLE_include_directive : enable
+
+#include "luma.inc"
 
 layout(set=0, binding=0)        uniform texture2D   inTexture;
 layout(set=0, binding=1)        uniform sampler     textureSampler;
@@ -78,6 +81,44 @@ vec2 computeDistortedUV(vec2 uv, float aspectRatio){
     return uv + toCenter * (r2*k1 + r2*r2*k2); 
 }
 
+float computeLocalContrast(vec2 uv){
+    float lumaMin = 100;
+    float lumaMax = 0;
+    
+    vec2 pixelSize = vec2(1) / textureSize(sampler2D(inTexture, textureSampler), 0);
+    
+    for(int x = -1; x <= 1; x++){
+        for(int y = -1; y <= 1; y++){
+            vec3 c = texture(sampler2D(inTexture, textureSampler), uv + vec2(x, y) * pixelSize).rgb;
+            float luma  = computeLuma(c);
+            lumaMin     = min(lumaMin, luma);
+            lumaMax     = max(lumaMax, luma);
+        }
+    }
+    
+    return lumaMax - lumaMin;
+}
+
+vec3 computeChromaticAberrationScale(vec2 uv){
+    float   localContrast   = computeLocalContrast(uv);
+    vec3    colorScales     = vec3(-1, 0, 1);
+    float   aberrationScale = 0.004;
+    vec3    maxScaleFactors = colorScales * aberrationScale;
+    float   factor          = clamp(localContrast, 0, 1);
+    return mix(vec3(0), maxScaleFactors, factor);
+}
+
+vec3 sampleColorChromaticAberration(vec2 uv){
+    vec2 toCenter       = (vec2(0.5) - uv);
+    
+    vec3 scaleFactors = computeChromaticAberrationScale(uv);
+    
+    float r = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.r).r;
+    float g = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.g).g;
+    float b = texture(sampler2D(inTexture, textureSampler), uv + toCenter * scaleFactors.b).b;
+    return vec3(r, g, b);
+}
+
 void main(){
 
     if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){
@@ -88,7 +129,7 @@ void main(){
     vec2    uv          = vec2(coord) / textureRes;
     float   aspectRatio = float(textureRes.x) / textureRes.y;
     uv                  = computeDistortedUV(uv, aspectRatio);
-    vec3 linearColor    = texture(sampler2D(inTexture, textureSampler), uv).rgb;
+    vec3 linearColor    = sampleColorChromaticAberration(uv);
     vec3 tonemapped     = ACESFilm(linearColor);
     tonemapped          = applyGrain(coord, tonemapped);
     
-- 
GitLab