diff --git a/projects/voxelization/resources/shaders/tonemapping.comp b/projects/voxelization/resources/shaders/tonemapping.comp
index b1bb08ded733791b57440069e6373711144747ca..84485b4760adc1dd03abe2b3253474770c61f980 100644
--- a/projects/voxelization/resources/shaders/tonemapping.comp
+++ b/projects/voxelization/resources/shaders/tonemapping.comp
@@ -1,7 +1,8 @@
 #version 440
 
-layout(set=0, binding=0, r11f_g11f_b10f)    uniform image2D inImage;
-layout(set=0, binding=1, rgba8)             uniform image2D outImage;
+layout(set=0, binding=0)        uniform texture2D   inTexture;
+layout(set=0, binding=1)        uniform sampler     textureSampler;
+layout(set=0, binding=2, rgba8) uniform image2D     outImage;
 
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 
@@ -69,16 +70,28 @@ vec3 applyGrain(ivec2 uv, vec3 c){
     return c * grain;
 }
 
+vec2 computeDistortedUV(vec2 uv, float aspectRatio){
+    vec2    toCenter    = vec2(vec2(0.5) - uv);
+    float   r2          = dot(toCenter, toCenter);
+    float   k1          = 0.15f;
+    float   k2          = 0.2f;
+    return uv + toCenter * (r2*k1 + r2*r2*k2); 
+}
+
 void main(){
 
-    if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))){
+    if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){
         return;
     }
-    ivec2 uv            = ivec2(gl_GlobalInvocationID.xy);
-    vec3 linearColor    = imageLoad(inImage, uv).rgb;
+    ivec2   textureRes  = textureSize(sampler2D(inTexture, textureSampler), 0);
+    ivec2   coord       = ivec2(gl_GlobalInvocationID.xy);
+    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 tonemapped     = ACESFilm(linearColor);
-    tonemapped          = applyGrain(uv, tonemapped);
+    tonemapped          = applyGrain(coord, tonemapped);
     
     vec3 gammaCorrected = pow(tonemapped, vec3(1.f / 2.2f));
-    imageStore(outImage, uv, vec4(gammaCorrected, 0.f));
+    imageStore(outImage, coord, vec4(gammaCorrected, 0.f));
 }
\ No newline at end of file
diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp
index 94778d4552d50df4ad570802091ab1ba971833cd..73cdaa611f578338fbb54465114f8b8c46129bbd 100644
--- a/projects/voxelization/src/main.cpp
+++ b/projects/voxelization/src/main.cpp
@@ -26,12 +26,12 @@ int main(int argc, const char** argv) {
 		true
 	);
 
-    vkcv::camera::CameraManager cameraManager(window);
-    uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
-    uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
+	vkcv::camera::CameraManager cameraManager(window);
+	uint32_t camIndex  = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
+	uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
 
-    cameraManager.getCamera(camIndex).setPosition(glm::vec3(0.f, 0.f, 3.f));
-    cameraManager.getCamera(camIndex).setNearFar(0.1f, 30.0f);
+	cameraManager.getCamera(camIndex).setPosition(glm::vec3(0.f, 0.f, 3.f));
+	cameraManager.getCamera(camIndex).setNearFar(0.1f, 30.0f);
 	cameraManager.getCamera(camIndex).setYaw(180.0f);
 	cameraManager.getCamera(camIndex).setFov(glm::radians(37.8));	// fov of a 35mm lens
 	
@@ -523,9 +523,10 @@ int main(int argc, const char** argv) {
 
 		// update descriptor sets which use swapchain image
 		vkcv::DescriptorWrites tonemappingDescriptorWrites;
-		tonemappingDescriptorWrites.storageImageWrites = {
-			vkcv::StorageImageDescriptorWrite(0, resolvedColorBuffer),
-			vkcv::StorageImageDescriptorWrite(1, swapchainInput) };
+		tonemappingDescriptorWrites.sampledImageWrites  = { vkcv::SampledImageDescriptorWrite(0, resolvedColorBuffer) };
+		tonemappingDescriptorWrites.samplerWrites       = { vkcv::SamplerDescriptorWrite(1, colorSampler) };
+		tonemappingDescriptorWrites.storageImageWrites  = { vkcv::StorageImageDescriptorWrite(2, swapchainInput) };
+
 		core.writeDescriptorSet(tonemappingDescriptorSet, tonemappingDescriptorWrites);
 
 		// update resolve descriptor, color images could be changed
@@ -651,7 +652,7 @@ int main(int argc, const char** argv) {
 		}
 
 		core.prepareImageForStorage(cmdStream, swapchainInput);
-		core.prepareImageForStorage(cmdStream, resolvedColorBuffer);
+		core.prepareImageForSampling(cmdStream, resolvedColorBuffer);
 
 		auto timeSinceStart = std::chrono::duration_cast<std::chrono::microseconds>(end - appStartTime);
 		float timeF         = static_cast<float>(timeSinceStart.count()) * 0.01;