LogHistogram.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. namespace UnityEngine.Rendering.PostProcessing
  2. {
  3. internal sealed class LogHistogram
  4. {
  5. public const int rangeMin = -9; // ev
  6. public const int rangeMax = 9; // ev
  7. // Don't forget to update 'ExposureHistogram.hlsl' if you change these values !
  8. const int k_Bins = 128;
  9. int m_ThreadX;
  10. int m_ThreadY;
  11. public ComputeBuffer data { get; private set; }
  12. public void Generate(PostProcessRenderContext context)
  13. {
  14. if (data == null)
  15. {
  16. m_ThreadX = 16;
  17. m_ThreadY = RuntimeUtilities.isAndroidOpenGL ? 8 : 16;
  18. data = new ComputeBuffer(k_Bins, sizeof(uint));
  19. }
  20. var scaleOffsetRes = GetHistogramScaleOffsetRes(context);
  21. var compute = context.resources.computeShaders.exposureHistogram;
  22. var cmd = context.command;
  23. cmd.BeginSample("LogHistogram");
  24. // Clear the buffer on every frame as we use it to accumulate luminance values on each frame
  25. int kernel = compute.FindKernel("KEyeHistogramClear");
  26. cmd.SetComputeBufferParam(compute, kernel, "_HistogramBuffer", data);
  27. cmd.DispatchCompute(compute, kernel, Mathf.CeilToInt(k_Bins / (float)m_ThreadX), 1, 1);
  28. // Get a log histogram
  29. kernel = compute.FindKernel("KEyeHistogram");
  30. cmd.SetComputeBufferParam(compute, kernel, "_HistogramBuffer", data);
  31. cmd.SetComputeTextureParam(compute, kernel, "_Source", context.source);
  32. cmd.SetComputeVectorParam(compute, "_ScaleOffsetRes", scaleOffsetRes);
  33. cmd.DispatchCompute(compute, kernel,
  34. Mathf.CeilToInt(scaleOffsetRes.z / 2f / m_ThreadX),
  35. Mathf.CeilToInt(scaleOffsetRes.w / 2f / m_ThreadY),
  36. 1
  37. );
  38. cmd.EndSample("LogHistogram");
  39. }
  40. public Vector4 GetHistogramScaleOffsetRes(PostProcessRenderContext context)
  41. {
  42. float diff = rangeMax - rangeMin;
  43. float scale = 1f / diff;
  44. float offset = -rangeMin * scale;
  45. return new Vector4(scale, offset, context.width, context.height);
  46. }
  47. public void Release()
  48. {
  49. if (data != null)
  50. data.Release();
  51. data = null;
  52. }
  53. }
  54. }