EyeAdaptationComponent.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using System;
  2. namespace UnityEngine.PostProcessing
  3. {
  4. public sealed class EyeAdaptationComponent : PostProcessingComponentRenderTexture<EyeAdaptationModel>
  5. {
  6. public override bool active
  7. {
  8. get
  9. {
  10. return base.model.enabled && SystemInfo.supportsComputeShaders && !this.context.interrupted;
  11. }
  12. }
  13. public void ResetHistory()
  14. {
  15. this.m_FirstFrame = true;
  16. }
  17. public override void OnEnable()
  18. {
  19. this.m_FirstFrame = true;
  20. }
  21. public override void OnDisable()
  22. {
  23. foreach (RenderTexture obj in this.m_AutoExposurePool)
  24. {
  25. GraphicsUtils.Destroy(obj);
  26. }
  27. if (this.m_HistogramBuffer != null)
  28. {
  29. this.m_HistogramBuffer.Release();
  30. }
  31. this.m_HistogramBuffer = null;
  32. if (this.m_DebugHistogram != null)
  33. {
  34. this.m_DebugHistogram.Release();
  35. }
  36. this.m_DebugHistogram = null;
  37. }
  38. private Vector4 GetHistogramScaleOffsetRes()
  39. {
  40. EyeAdaptationModel.Settings settings = base.model.settings;
  41. float num = (float)(settings.logMax - settings.logMin);
  42. float num2 = 1f / num;
  43. float y = (float)(-(float)settings.logMin) * num2;
  44. return new Vector4(num2, y, Mathf.Floor((float)this.context.width / 2f), Mathf.Floor((float)this.context.height / 2f));
  45. }
  46. public Texture Prepare(RenderTexture source, Material uberMaterial)
  47. {
  48. EyeAdaptationModel.Settings settings = base.model.settings;
  49. if (this.m_EyeCompute == null)
  50. {
  51. this.m_EyeCompute = Resources.Load<ComputeShader>("Shaders/EyeHistogram");
  52. }
  53. Material material = this.context.materialFactory.Get("Hidden/Post FX/Eye Adaptation");
  54. material.shaderKeywords = null;
  55. if (this.m_HistogramBuffer == null)
  56. {
  57. this.m_HistogramBuffer = new ComputeBuffer(64, 4);
  58. }
  59. if (EyeAdaptationComponent.s_EmptyHistogramBuffer == null)
  60. {
  61. EyeAdaptationComponent.s_EmptyHistogramBuffer = new uint[64];
  62. }
  63. Vector4 histogramScaleOffsetRes = this.GetHistogramScaleOffsetRes();
  64. RenderTexture renderTexture = this.context.renderTextureFactory.Get((int)histogramScaleOffsetRes.z, (int)histogramScaleOffsetRes.w, 0, source.format, RenderTextureReadWrite.Default, FilterMode.Bilinear, TextureWrapMode.Clamp, "FactoryTempTexture");
  65. Graphics.Blit(source, renderTexture);
  66. if (this.m_AutoExposurePool[0] == null || !this.m_AutoExposurePool[0].IsCreated())
  67. {
  68. this.m_AutoExposurePool[0] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
  69. }
  70. if (this.m_AutoExposurePool[1] == null || !this.m_AutoExposurePool[1].IsCreated())
  71. {
  72. this.m_AutoExposurePool[1] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
  73. }
  74. this.m_HistogramBuffer.SetData(EyeAdaptationComponent.s_EmptyHistogramBuffer);
  75. int kernelIndex = this.m_EyeCompute.FindKernel("KEyeHistogram");
  76. this.m_EyeCompute.SetBuffer(kernelIndex, "_Histogram", this.m_HistogramBuffer);
  77. this.m_EyeCompute.SetTexture(kernelIndex, "_Source", renderTexture);
  78. this.m_EyeCompute.SetVector("_ScaleOffsetRes", histogramScaleOffsetRes);
  79. this.m_EyeCompute.Dispatch(kernelIndex, Mathf.CeilToInt((float)renderTexture.width / 16f), Mathf.CeilToInt((float)renderTexture.height / 16f), 1);
  80. this.context.renderTextureFactory.Release(renderTexture);
  81. settings.highPercent = Mathf.Clamp(settings.highPercent, 1.01f, 99f);
  82. settings.lowPercent = Mathf.Clamp(settings.lowPercent, 1f, settings.highPercent - 0.01f);
  83. material.SetBuffer("_Histogram", this.m_HistogramBuffer);
  84. material.SetVector(EyeAdaptationComponent.Uniforms._Params, new Vector4(settings.lowPercent * 0.01f, settings.highPercent * 0.01f, Mathf.Exp(settings.minLuminance * 0.6931472f), Mathf.Exp(settings.maxLuminance * 0.6931472f)));
  85. material.SetVector(EyeAdaptationComponent.Uniforms._Speed, new Vector2(settings.speedDown, settings.speedUp));
  86. material.SetVector(EyeAdaptationComponent.Uniforms._ScaleOffsetRes, histogramScaleOffsetRes);
  87. material.SetFloat(EyeAdaptationComponent.Uniforms._ExposureCompensation, settings.keyValue);
  88. if (settings.dynamicKeyValue)
  89. {
  90. material.EnableKeyword("AUTO_KEY_VALUE");
  91. }
  92. if (this.m_FirstFrame || !Application.isPlaying)
  93. {
  94. this.m_CurrentAutoExposure = this.m_AutoExposurePool[0];
  95. Graphics.Blit(null, this.m_CurrentAutoExposure, material, 1);
  96. Graphics.Blit(this.m_AutoExposurePool[0], this.m_AutoExposurePool[1]);
  97. }
  98. else
  99. {
  100. int num = this.m_AutoExposurePingPing;
  101. RenderTexture source2 = this.m_AutoExposurePool[++num % 2];
  102. RenderTexture renderTexture2 = this.m_AutoExposurePool[++num % 2];
  103. Graphics.Blit(source2, renderTexture2, material, (int)settings.adaptationType);
  104. this.m_AutoExposurePingPing = (num + 1) % 2;
  105. this.m_CurrentAutoExposure = renderTexture2;
  106. }
  107. if (this.context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation))
  108. {
  109. if (this.m_DebugHistogram == null || !this.m_DebugHistogram.IsCreated())
  110. {
  111. this.m_DebugHistogram = new RenderTexture(256, 128, 0, RenderTextureFormat.ARGB32)
  112. {
  113. filterMode = FilterMode.Point,
  114. wrapMode = TextureWrapMode.Clamp
  115. };
  116. }
  117. material.SetFloat(EyeAdaptationComponent.Uniforms._DebugWidth, (float)this.m_DebugHistogram.width);
  118. Graphics.Blit(null, this.m_DebugHistogram, material, 2);
  119. }
  120. this.m_FirstFrame = false;
  121. return this.m_CurrentAutoExposure;
  122. }
  123. public void OnGUI()
  124. {
  125. if (this.m_DebugHistogram == null || !this.m_DebugHistogram.IsCreated())
  126. {
  127. return;
  128. }
  129. Rect position = new Rect(this.context.viewport.x * (float)Screen.width + 8f, 8f, (float)this.m_DebugHistogram.width, (float)this.m_DebugHistogram.height);
  130. GUI.DrawTexture(position, this.m_DebugHistogram);
  131. }
  132. private ComputeShader m_EyeCompute;
  133. private ComputeBuffer m_HistogramBuffer;
  134. private readonly RenderTexture[] m_AutoExposurePool = new RenderTexture[2];
  135. private int m_AutoExposurePingPing;
  136. private RenderTexture m_CurrentAutoExposure;
  137. private RenderTexture m_DebugHistogram;
  138. private static uint[] s_EmptyHistogramBuffer;
  139. private bool m_FirstFrame = true;
  140. private const int k_HistogramBins = 64;
  141. private const int k_HistogramThreadX = 16;
  142. private const int k_HistogramThreadY = 16;
  143. private static class Uniforms
  144. {
  145. internal static readonly int _Params = Shader.PropertyToID("_Params");
  146. internal static readonly int _Speed = Shader.PropertyToID("_Speed");
  147. internal static readonly int _ScaleOffsetRes = Shader.PropertyToID("_ScaleOffsetRes");
  148. internal static readonly int _ExposureCompensation = Shader.PropertyToID("_ExposureCompensation");
  149. internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure");
  150. internal static readonly int _DebugWidth = Shader.PropertyToID("_DebugWidth");
  151. }
  152. }
  153. }