AutoExposure.compute 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma warning(disable : 3568)
  2. #pragma exclude_renderers gles gles3 d3d11_9x
  3. #pragma kernel KAutoExposureAvgLuminance_fixed MAIN=KAutoExposureAvgLuminance_fixed
  4. #pragma kernel KAutoExposureAvgLuminance_progressive MAIN=KAutoExposureAvgLuminance_progressive PROGRESSIVE
  5. #include "../StdLib.hlsl"
  6. #include "ExposureHistogram.hlsl"
  7. StructuredBuffer<uint> _HistogramBuffer;
  8. Texture2D<float> _Source;
  9. RWTexture2D<float> _Destination;
  10. CBUFFER_START(Params)
  11. float4 _Params1; // x: lowPercent, y: highPercent, z: minBrightness, w: maxBrightness
  12. float4 _Params2; // x: speed down, y: speed up, z: exposure compensation, w: delta time
  13. float4 _ScaleOffsetRes; // x: scale, y: offset, w: histogram pass width, h: histogram pass height
  14. CBUFFER_END
  15. groupshared uint gs_pyramid[HISTOGRAM_BINS];
  16. float GetExposureMultiplier(float avgLuminance)
  17. {
  18. avgLuminance = max(EPSILON, avgLuminance);
  19. //float keyValue = 1.03 - (2.0 / (2.0 + log2(avgLuminance + 1.0)));
  20. float keyValue = _Params2.z;
  21. float exposure = keyValue / avgLuminance;
  22. return exposure;
  23. }
  24. float InterpolateExposure(float newExposure, float oldExposure)
  25. {
  26. float delta = newExposure - oldExposure;
  27. float speed = delta > 0.0 ? _Params2.x : _Params2.y;
  28. float exposure = oldExposure + delta * (1.0 - exp2(-_Params2.w * speed));
  29. return exposure;
  30. }
  31. #ifdef DISABLE_COMPUTE_SHADERS
  32. TRIVIAL_COMPUTE_KERNEL(MAIN)
  33. #else
  34. [numthreads(HISTOGRAM_THREAD_X, HISTOGRAM_BINS / HISTOGRAM_THREAD_X, 1)]
  35. void MAIN(uint2 groupThreadId : SV_GroupThreadID)
  36. {
  37. const uint thread_id = groupThreadId.y * HISTOGRAM_THREAD_X + groupThreadId.x;
  38. gs_pyramid[thread_id] = _HistogramBuffer[thread_id];
  39. GroupMemoryBarrierWithGroupSync();
  40. // Parallel reduction to find the max value
  41. UNITY_UNROLL
  42. for (uint i = HISTOGRAM_BINS >> 1u; i > 0u; i >>= 1u)
  43. {
  44. if (thread_id < i)
  45. gs_pyramid[thread_id] = max(gs_pyramid[thread_id], gs_pyramid[thread_id + i]);
  46. GroupMemoryBarrierWithGroupSync();
  47. }
  48. GroupMemoryBarrierWithGroupSync();
  49. if (thread_id == 0u)
  50. {
  51. float maxValue = 1.0 / float(gs_pyramid[0]);
  52. #if PROGRESSIVE
  53. float avgLuminance = GetAverageLuminance(_HistogramBuffer, _Params1, maxValue, _ScaleOffsetRes.xy);
  54. float exposure = GetExposureMultiplier(avgLuminance);
  55. float prevExposure = _Source[uint2(0u, 0u)].x;
  56. exposure = InterpolateExposure(exposure, prevExposure);
  57. _Destination[uint2(0u, 0u)].x = exposure.x;
  58. #else
  59. float avgLuminance = GetAverageLuminance(_HistogramBuffer, _Params1, maxValue, _ScaleOffsetRes.xy);
  60. float exposure = GetExposureMultiplier(avgLuminance);
  61. _Destination[uint2(0u, 0u)].x = exposure.x;
  62. #endif
  63. }
  64. }
  65. #endif // DISABLE_COMPUTE_SHADERS