using System; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; namespace Misaki.HdrpToon { internal class UTSPass : CustomPass { private const int Adjustment_Curve_Precision = 128; private const string Compensation_Prop_Name = "_ToonEvAdjustmentCompensation"; private const string Exposure_Adjustment_Prop_Name = "_ToonEvAdjustmentCurve"; private const string Exposure_Array_Prop_Name = "_ToonEvAdjustmentValueArray"; private const string Exposure_Min_Prop_Name = "_ToonEvAdjustmentValueMin"; private const string Exposure_Max_Prop_Name = "_ToonEvAdjustmentValueMax"; private const string Toon_Light_Filter_Prop_Name = "_ToonLightHiCutFilter"; private const string Ignore_Volume_Exposure_Prop_Name = "_ToonIgnoreExposureMultiplier"; private float _max; private float _min; private float[] _exposureArray; protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd) { _exposureArray = new float[Adjustment_Curve_Precision]; } protected override void Execute(CustomPassContext ctx) { var utsRenderer = ctx.hdCamera.volumeStack.GetComponent(); if (utsRenderer == null) { return; } var toonEVAdjustment = utsRenderer.toonEVAdjustment.value ? 1 : 0; var lightIntensityLimiter = utsRenderer.lightIntensityLimiter.value ? 1 : 0; var ignoreVolumeExposure = utsRenderer.ignoreVolumeExposure.value ? 1 : 0; var compensation = utsRenderer.compensation.value; if (!utsRenderer.state.value) { _min = 0; _max = 0; _exposureArray.AsSpan().Fill(0); toonEVAdjustment = 0; lightIntensityLimiter = 0; ignoreVolumeExposure = 0; compensation = 0; } else { // Fail safe in case the curve is deleted / has 0 point var curve = utsRenderer.adjustmentCurve.value; if (curve == null || curve.length == 0) { _min = 0f; _max = 0f; _exposureArray.AsSpan().Fill(0); } else { _min = curve[0].time; _max = curve[curve.length - 1].time; var step = (_max - _min) / (Adjustment_Curve_Precision - 1f); for (var i = 0; i < Adjustment_Curve_Precision; i++) { _exposureArray[i] = curve.Evaluate(_min + step * i); } } } Shader.SetGlobalFloatArray(Exposure_Array_Prop_Name, _exposureArray); Shader.SetGlobalFloat(Exposure_Min_Prop_Name, _min); Shader.SetGlobalFloat(Exposure_Max_Prop_Name, _max); Shader.SetGlobalInt(Exposure_Adjustment_Prop_Name, toonEVAdjustment); Shader.SetGlobalInt(Toon_Light_Filter_Prop_Name, lightIntensityLimiter); Shader.SetGlobalInt(Ignore_Volume_Exposure_Prop_Name, ignoreVolumeExposure); Shader.SetGlobalFloat(Compensation_Prop_Name, compensation); } protected override void Cleanup() { _exposureArray = null; } } }