262 lines
8.5 KiB
C#

//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<IService> _services = new HashSet<IService>();
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;
}
}
/// <summary>
/// Reset Irradiance Cache
/// </summary>
public void ResetIrradianceCache()
{
SoftwareTracingShared.ClearRadianceCache = true;
}
/// <summary>
/// Forced scene voxelization
/// </summary>
public void VoxelizeNow()
{
VoxelizationRuntimeData.FullVoxelization = true;
}
/// <summary>
/// Apply Parameters, use only after changes setting's values in Parameters section. Do not recommend use it every frame.
/// </summary>
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<Volume>();
if (_volumeComponent == null)
{
_volumeComponent = gameObject.AddComponent<Volume>();
_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<VolumeProfile>($"{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
}
}