summaryrefslogtreecommitdiff
path: root/UnityEngine.PostProcessing/EyeAdaptationComponent.cs
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-03-13 11:00:58 +0800
committerchai <215380520@qq.com>2024-03-13 11:00:58 +0800
commit6ce8b9e22fc13be34b442c7b6af48b42cd44275a (patch)
treeb38119d2acf0a982cb67e381f146924b9bfc3b3f /UnityEngine.PostProcessing/EyeAdaptationComponent.cs
+init
Diffstat (limited to 'UnityEngine.PostProcessing/EyeAdaptationComponent.cs')
-rw-r--r--UnityEngine.PostProcessing/EyeAdaptationComponent.cs168
1 files changed, 168 insertions, 0 deletions
diff --git a/UnityEngine.PostProcessing/EyeAdaptationComponent.cs b/UnityEngine.PostProcessing/EyeAdaptationComponent.cs
new file mode 100644
index 0000000..fce1172
--- /dev/null
+++ b/UnityEngine.PostProcessing/EyeAdaptationComponent.cs
@@ -0,0 +1,168 @@
+namespace UnityEngine.PostProcessing;
+
+public sealed class EyeAdaptationComponent : PostProcessingComponentRenderTexture<EyeAdaptationModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _Params = Shader.PropertyToID("_Params");
+
+ internal static readonly int _Speed = Shader.PropertyToID("_Speed");
+
+ internal static readonly int _ScaleOffsetRes = Shader.PropertyToID("_ScaleOffsetRes");
+
+ internal static readonly int _ExposureCompensation = Shader.PropertyToID("_ExposureCompensation");
+
+ internal static readonly int _AutoExposure = Shader.PropertyToID("_AutoExposure");
+
+ internal static readonly int _DebugWidth = Shader.PropertyToID("_DebugWidth");
+ }
+
+ private ComputeShader m_EyeCompute;
+
+ private ComputeBuffer m_HistogramBuffer;
+
+ private readonly RenderTexture[] m_AutoExposurePool = new RenderTexture[2];
+
+ private int m_AutoExposurePingPing;
+
+ private RenderTexture m_CurrentAutoExposure;
+
+ private RenderTexture m_DebugHistogram;
+
+ private static uint[] s_EmptyHistogramBuffer;
+
+ private bool m_FirstFrame = true;
+
+ private const int k_HistogramBins = 64;
+
+ private const int k_HistogramThreadX = 16;
+
+ private const int k_HistogramThreadY = 16;
+
+ public override bool active => base.model.enabled && SystemInfo.supportsComputeShaders && !context.interrupted;
+
+ public void ResetHistory()
+ {
+ m_FirstFrame = true;
+ }
+
+ public override void OnEnable()
+ {
+ m_FirstFrame = true;
+ }
+
+ public override void OnDisable()
+ {
+ RenderTexture[] autoExposurePool = m_AutoExposurePool;
+ foreach (RenderTexture obj in autoExposurePool)
+ {
+ GraphicsUtils.Destroy(obj);
+ }
+ if (m_HistogramBuffer != null)
+ {
+ m_HistogramBuffer.Release();
+ }
+ m_HistogramBuffer = null;
+ if (m_DebugHistogram != null)
+ {
+ m_DebugHistogram.Release();
+ }
+ m_DebugHistogram = null;
+ }
+
+ private Vector4 GetHistogramScaleOffsetRes()
+ {
+ EyeAdaptationModel.Settings settings = base.model.settings;
+ float num = settings.logMax - settings.logMin;
+ float num2 = 1f / num;
+ float y = (float)(-settings.logMin) * num2;
+ return new Vector4(num2, y, Mathf.Floor((float)context.width / 2f), Mathf.Floor((float)context.height / 2f));
+ }
+
+ public Texture Prepare(RenderTexture source, Material uberMaterial)
+ {
+ EyeAdaptationModel.Settings settings = base.model.settings;
+ if (m_EyeCompute == null)
+ {
+ m_EyeCompute = Resources.Load<ComputeShader>("Shaders/EyeHistogram");
+ }
+ Material material = context.materialFactory.Get("Hidden/Post FX/Eye Adaptation");
+ material.shaderKeywords = null;
+ if (m_HistogramBuffer == null)
+ {
+ m_HistogramBuffer = new ComputeBuffer(64, 4);
+ }
+ if (s_EmptyHistogramBuffer == null)
+ {
+ s_EmptyHistogramBuffer = new uint[64];
+ }
+ Vector4 histogramScaleOffsetRes = GetHistogramScaleOffsetRes();
+ RenderTexture renderTexture = context.renderTextureFactory.Get((int)histogramScaleOffsetRes.z, (int)histogramScaleOffsetRes.w, 0, source.format);
+ Graphics.Blit(source, renderTexture);
+ if (m_AutoExposurePool[0] == null || !m_AutoExposurePool[0].IsCreated())
+ {
+ m_AutoExposurePool[0] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
+ }
+ if (m_AutoExposurePool[1] == null || !m_AutoExposurePool[1].IsCreated())
+ {
+ m_AutoExposurePool[1] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat);
+ }
+ m_HistogramBuffer.SetData(s_EmptyHistogramBuffer);
+ int kernelIndex = m_EyeCompute.FindKernel("KEyeHistogram");
+ m_EyeCompute.SetBuffer(kernelIndex, "_Histogram", m_HistogramBuffer);
+ m_EyeCompute.SetTexture(kernelIndex, "_Source", renderTexture);
+ m_EyeCompute.SetVector("_ScaleOffsetRes", histogramScaleOffsetRes);
+ m_EyeCompute.Dispatch(kernelIndex, Mathf.CeilToInt((float)renderTexture.width / 16f), Mathf.CeilToInt((float)renderTexture.height / 16f), 1);
+ context.renderTextureFactory.Release(renderTexture);
+ settings.highPercent = Mathf.Clamp(settings.highPercent, 1.01f, 99f);
+ settings.lowPercent = Mathf.Clamp(settings.lowPercent, 1f, settings.highPercent - 0.01f);
+ material.SetBuffer("_Histogram", m_HistogramBuffer);
+ material.SetVector(Uniforms._Params, new Vector4(settings.lowPercent * 0.01f, settings.highPercent * 0.01f, Mathf.Exp(settings.minLuminance * 0.6931472f), Mathf.Exp(settings.maxLuminance * 0.6931472f)));
+ material.SetVector(Uniforms._Speed, new Vector2(settings.speedDown, settings.speedUp));
+ material.SetVector(Uniforms._ScaleOffsetRes, histogramScaleOffsetRes);
+ material.SetFloat(Uniforms._ExposureCompensation, settings.keyValue);
+ if (settings.dynamicKeyValue)
+ {
+ material.EnableKeyword("AUTO_KEY_VALUE");
+ }
+ if (m_FirstFrame || !Application.isPlaying)
+ {
+ m_CurrentAutoExposure = m_AutoExposurePool[0];
+ Graphics.Blit(null, m_CurrentAutoExposure, material, 1);
+ Graphics.Blit(m_AutoExposurePool[0], m_AutoExposurePool[1]);
+ }
+ else
+ {
+ int autoExposurePingPing = m_AutoExposurePingPing;
+ RenderTexture source2 = m_AutoExposurePool[++autoExposurePingPing % 2];
+ RenderTexture renderTexture2 = m_AutoExposurePool[++autoExposurePingPing % 2];
+ Graphics.Blit(source2, renderTexture2, material, (int)settings.adaptationType);
+ m_AutoExposurePingPing = ++autoExposurePingPing % 2;
+ m_CurrentAutoExposure = renderTexture2;
+ }
+ if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation))
+ {
+ if (m_DebugHistogram == null || !m_DebugHistogram.IsCreated())
+ {
+ m_DebugHistogram = new RenderTexture(256, 128, 0, RenderTextureFormat.ARGB32)
+ {
+ filterMode = FilterMode.Point,
+ wrapMode = TextureWrapMode.Clamp
+ };
+ }
+ material.SetFloat(Uniforms._DebugWidth, m_DebugHistogram.width);
+ Graphics.Blit(null, m_DebugHistogram, material, 2);
+ }
+ m_FirstFrame = false;
+ return m_CurrentAutoExposure;
+ }
+
+ public void OnGUI()
+ {
+ if (!(m_DebugHistogram == null) && m_DebugHistogram.IsCreated())
+ {
+ Rect position = new Rect(context.viewport.x * (float)Screen.width + 8f, 8f, m_DebugHistogram.width, m_DebugHistogram.height);
+ GUI.DrawTexture(position, m_DebugHistogram);
+ }
+ }
+}