//pipelinedefine #define H_URP using System.Collections.Generic; using HTraceWSGI.Scripts.Data.Private; using HTraceWSGI.Scripts.Data.Public; using HTraceWSGI.Scripts.Globals; using HTraceWSGI.Scripts.Infrastructure.URP; using HTraceWSGI.Scripts.Passes.Shared; using HTraceWSGI.Scripts.Passes.URP; using HTraceWSGI.Scripts.Services; using HTraceWSGI.Scripts.Services.DirectionalShadowmap; using HTraceWSGI.Scripts.Services.VoxelCameras; using HTraceWSGI.Scripts.Services.LightsCluster; using LightingSettings = HTraceWSGI.Scripts.Data.Public.LightingSettings; using UnityEngine; using UnityEngine.Rendering; #if UNITY_EDITOR using UnityEditor; using HTraceWSGI.Scripts.PipelinesConfigurator; #endif namespace HTraceWSGI.Scripts { [ExecuteInEditMode, DefaultExecutionOrder(100)] [HelpURL(HNames.HTRACE_WSGI_DOCUMENTATION_LINK)] public class HTraceWSGI : MonoBehaviour { private Volume _volumeComponent; #if UNITY_6000_0_OR_NEWER private ProbeVolumesOptions _probeVolumesOptionsOverrideComponent; #endif private readonly HashSet _services = new HashSet(); public GeneralSettings GeneralSettings = new GeneralSettings(); public VoxelizationSettings VoxelizationSettings = new VoxelizationSettings(); public LightingSettings LightingSettings = new LightingSettings(); public ScreenSpaceLightingSettings ScreenSpaceLightingSettings = new ScreenSpaceLightingSettings(); public ReflectionIndirectLightingSettings ReflectionIndirectLightingSettings = new ReflectionIndirectLightingSettings(); [SerializeField] private DebugSettings DebugSettings = new DebugSettings(); [SerializeField] private bool _globalSettingsTab = true; [SerializeField] private bool _screenSpaceLightingTab = true; [SerializeField] private bool _wsgiTab = true; [SerializeField] private bool _lightingTab = true; [SerializeField] private bool _reflectionsTab = true; [SerializeField] private bool _debugTab = true; [SerializeField] private bool _showVoxelParams = true; [SerializeField] private bool _showUpdateOptions = true; private Light _prevDirLight; private TracingMode _prevTracingMode; internal bool NeedToReallocForUI { get { return VoxelsService.Instance.NeedToReallocForUI; } } /// /// Reset Irradiance Cache /// public void ResetIrradianceCache() { SoftwareTracingShared.ClearRadianceCache = true; } /// /// Forced scene voxelization /// public void VoxelizeNow() { VoxelizationRuntimeData.FullVoxelization = true; } /// /// Apply Parameters, use only after changes setting's values in Parameters section. Do not recommend use it every frame. /// public void ApplyParameters() { VoxelizationRuntimeData.OnReallocTextures?.Invoke(); } private void OnEnable() { HSettings.GeneralSettings = GeneralSettings; HSettings.VoxelizationSettings = VoxelizationSettings; HSettings.LightingSettings = LightingSettings; HSettings.ScreenSpaceLightingSettings = ScreenSpaceLightingSettings; HSettings.ReflectionIndirectLightingSettings = ReflectionIndirectLightingSettings; HSettings.DebugSettings = DebugSettings; SoftwareTracingPassURP.RequestHashBufferRecreate(); VoxelizationRuntimeData.OnReallocTextures += () => { HSettings.VoxelizationSettings.UpdateData(); SoftwareTracingPassURP.AllocationHashBuffers(forceRecreate: true); VoxelizationRuntimeData.FullVoxelization = true; VoxelizationRuntimeData.TextureSwapCounter = 0; VoxelizationRuntimeData.TextureOutputCounter = 0; VoxelizationRuntimeData.SetParamsForApplyButton(HSettings.VoxelizationSettings.VoxelDensity, HSettings.VoxelizationSettings.VoxelBounds, HSettings.VoxelizationSettings.OverrideBoundsHeight); }; //HSettings.GeneralSettings.OnRayCountChanged += (RayCountMode mode) => { SoftwareTracingResources.Allocation();}; #if UNITY_EDITOR HPipelinesConfigurator.AlwaysIncludedShaders(); #endif VoxelizationRuntimeData.Initialize(); // must be before RegisterService, because needed to reset OctantIndex VolumeSetup(); RegisterServices(); Register(); } private void OnValidate() { Register(); } private void Reset() { Register(); } private void LateUpdate() { foreach (var service in _services) { service.LateUpdate(); } VolumeSetup(); } private void RegisterServices() { VoxelsService.Instance.Initialize(0); _services.Add(VoxelsService.Instance); DirectionalShadowmapService.Instance.Initialize(0); _services.Add(DirectionalShadowmapService.Instance); LightService.Instance.Initialize(); _services.Add(LightService.Instance); } private void Register() { HTraceWSGIRendererFeature.RegisterSettings(this); } private void OnDisable() { if (_volumeComponent != null) _volumeComponent.enabled = false; #if UNITY_6000_0_OR_NEWER if (_probeVolumesOptionsOverrideComponent != null) _probeVolumesOptionsOverrideComponent.active = false; #endif foreach (var service in _services) { service.Cleanup(); } _services.Clear(); HTraceWSGIRendererFeature.UnregisterSettings(this); VoxelizationRuntimeData.OnReallocTextures = null; } private void VolumeSetup() { #if UNITY_6000_0_OR_NEWER CreateSSGIOverrideComponent(); SetSSGIOverrideComponentSettings(); ChangeObjectWithSerialization_ONLYEDITOR(); #endif } #if UNITY_6000_0_OR_NEWER private void CreateSSGIOverrideComponent() { _volumeComponent = gameObject.GetComponent(); if (_volumeComponent == null) { _volumeComponent = gameObject.AddComponent(); _volumeComponent.enabled = false; } if (_volumeComponent.sharedProfile == null || _volumeComponent.sharedProfile.name.Contains("HTrace") == false) { //We can't crate it in runtime, because after build it will break. //it will call only in editor, but if someone changes it in runtime, we will override. _volumeComponent.sharedProfile = Resources.Load($"{HNames.ASSET_NAME}/Volume Profile HTrace WSGI URP"); } _volumeComponent.sharedProfile.TryGet(out _probeVolumesOptionsOverrideComponent); } private void SetSSGIOverrideComponentSettings() { _volumeComponent.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.None : HideFlags.HideInInspector | HideFlags.DontSave; bool isEnable = HSettings.GeneralSettings != null && HSettings.GeneralSettings.AmbientOverride; _volumeComponent.enabled = isEnable; #if UNITY_6000_0_OR_NEWER _probeVolumesOptionsOverrideComponent.active = isEnable; #endif _volumeComponent.weight = 1; _volumeComponent.priority = 100; #if UNITY_EDITOR _volumeComponent.runInEditMode = true; #endif if (_probeVolumesOptionsOverrideComponent != null) { _probeVolumesOptionsOverrideComponent.normalBias.overrideState = true; _probeVolumesOptionsOverrideComponent.viewBias.overrideState = true; _probeVolumesOptionsOverrideComponent.samplingNoise.overrideState = true; } } private void ChangeObjectWithSerialization_ONLYEDITOR() { #if UNITY_EDITOR if (_probeVolumesOptionsOverrideComponent == null) return; SerializedObject probeVolumesOptionsObject = new SerializedObject(_probeVolumesOptionsOverrideComponent); var normalBias = probeVolumesOptionsObject.FindProperty("normalBias"); var m_OverrideState_normalBias = normalBias.FindPropertyRelative("m_OverrideState"); var m_Value_normalBias = normalBias.FindPropertyRelative("m_Value"); m_OverrideState_normalBias.boolValue = true; m_Value_normalBias.floatValue = 0.0f; var viewBias = probeVolumesOptionsObject.FindProperty("viewBias"); var m_OverrideState_viewBias = viewBias.FindPropertyRelative("m_OverrideState"); var m_Value_viewBias = viewBias.FindPropertyRelative("m_Value"); m_OverrideState_viewBias.boolValue = true; m_Value_viewBias.floatValue = 0.0f; var samplingNoise = probeVolumesOptionsObject.FindProperty("samplingNoise"); var m_OverrideState_samplingNoise = samplingNoise.FindPropertyRelative("m_OverrideState"); var m_Value_samplingNoise = samplingNoise.FindPropertyRelative("m_Value"); m_OverrideState_samplingNoise.boolValue = true; m_Value_samplingNoise.floatValue = 0.0f; probeVolumesOptionsObject.ApplyModifiedProperties(); #endif } #endif } }