luminance_reduce_raster.glsl 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /* clang-format off */
  2. #[vertex]
  3. #version 450
  4. #VERSION_DEFINES
  5. #include "luminance_reduce_raster_inc.glsl"
  6. layout(location = 0) out vec2 uv_interp;
  7. /* clang-format on */
  8. void main() {
  9. vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
  10. gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0);
  11. uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0
  12. }
  13. /* clang-format off */
  14. #[fragment]
  15. #version 450
  16. #VERSION_DEFINES
  17. #include "luminance_reduce_raster_inc.glsl"
  18. layout(location = 0) in vec2 uv_interp;
  19. /* clang-format on */
  20. layout(set = 0, binding = 0) uniform sampler2D source_exposure;
  21. #ifdef FINAL_PASS
  22. layout(set = 1, binding = 0) uniform sampler2D prev_luminance;
  23. #endif
  24. layout(location = 0) out highp float luminance;
  25. void main() {
  26. ivec2 dest_pos = ivec2(uv_interp * settings.dest_size);
  27. ivec2 src_pos = ivec2(uv_interp * settings.source_size);
  28. ivec2 next_pos = (dest_pos + ivec2(1)) * settings.source_size / settings.dest_size;
  29. next_pos = max(next_pos, src_pos + ivec2(1)); //so it at least reads one pixel
  30. highp vec3 source_color = vec3(0.0);
  31. for (int i = src_pos.x; i < next_pos.x; i++) {
  32. for (int j = src_pos.y; j < next_pos.y; j++) {
  33. source_color += texelFetch(source_exposure, ivec2(i, j), 0).rgb;
  34. }
  35. }
  36. source_color /= float((next_pos.x - src_pos.x) * (next_pos.y - src_pos.y));
  37. #ifdef FIRST_PASS
  38. luminance = max(source_color.r, max(source_color.g, source_color.b));
  39. // This formula should be more "accurate" but gave an overexposed result when testing.
  40. // Leaving it here so we can revisit it if we want.
  41. // luminance = source_color.r * 0.21 + source_color.g * 0.71 + source_color.b * 0.07;
  42. #else
  43. luminance = source_color.r;
  44. #endif
  45. #ifdef FINAL_PASS
  46. // Obtain our target luminance
  47. luminance = clamp(luminance, settings.min_luminance, settings.max_luminance);
  48. // Now smooth to our transition
  49. highp float prev_lum = texelFetch(prev_luminance, ivec2(0, 0), 0).r; //1 pixel previous luminance
  50. luminance = prev_lum + (luminance - prev_lum) * clamp(settings.exposure_adjust, 0.0, 1.0);
  51. #endif
  52. }