using System.Collections.Generic; using UnityEngine; namespace DeepSky.Haze; [ExecuteInEditMode] [AddComponentMenu("DeepSky Haze/Controller", 51)] public class DS_HazeCore : MonoBehaviour { public enum HeightFalloffType { Exponential, None } public enum NoiseTextureSize { x8 = 8, x16 = 0x10, x32 = 0x20 } public enum DebugGUIPosition { TopLeft, TopCenter, TopRight, CenterLeft, Center, CenterRight, BottomLeft, BottomCenter, BottomRight } public static string kVersionStr = "DeepSky Haze v1.4.0"; private static int kGUIHeight = 180; private static DS_HazeCore instance; [SerializeField] [Range(0f, 1f)] [Tooltip("The time at which Zones will evaluate their settings. Animate this or set in code to create time-of-day transitions.")] private float m_Time; [SerializeField] [Tooltip("The height falloff method to use globally (default Exponential).")] private HeightFalloffType m_HeightFalloff; [SerializeField] private List m_Zones = new List(); [SerializeField] private DebugGUIPosition m_DebugGUIPosition; private HashSet m_LightVolumes = new HashSet(); [SerializeField] private Texture3D m_NoiseLUT; [SerializeField] private bool m_ShowDebugGUI; private Vector2 m_GUIScrollPosition; private int m_GUISelectedView = -1; private bool m_GUISelectionPopup; private DS_HazeView m_GUIDisplayedView; public static DS_HazeCore Instance { get { if (instance == null) { instance = Object.FindObjectOfType(); } return instance; } } public float Time { get { return m_Time; } set { m_Time = Mathf.Clamp01(value); } } public Texture3D NoiseLUT => m_NoiseLUT; public HeightFalloffType HeightFalloff { get { return m_HeightFalloff; } set { m_HeightFalloff = value; SetGlobalHeightFalloff(); } } private void SetGlobalHeightFalloff() { switch (m_HeightFalloff) { case HeightFalloffType.Exponential: Shader.DisableKeyword("DS_HAZE_HEIGHT_FALLOFF_NONE"); break; case HeightFalloffType.None: Shader.EnableKeyword("DS_HAZE_HEIGHT_FALLOFF_NONE"); break; } } private void OnTransformChildrenChanged() { m_Zones.Clear(); DS_HazeZone[] componentsInChildren = GetComponentsInChildren(includeInactive: true); m_Zones.AddRange(componentsInChildren); } private void Awake() { if (instance == null) { instance = this; } else if (instance != this) { Debug.LogError("DeepSky::DS_HazeCore:Awake - There is more than one Haze Controller in this scene! Disabling " + base.name); base.enabled = false; } } private void OnEnable() { SetGlobalHeightFalloff(); Shader.SetGlobalTexture("_SamplingOffsets", m_NoiseLUT); } private void Reset() { OnTransformChildrenChanged(); } public void SetGlobalNoiseLUT() { Shader.SetGlobalTexture("_SamplingOffsets", m_NoiseLUT); } public void AddLightVolume(DS_HazeLightVolume lightVolume) { RemoveLightVolume(lightVolume); m_LightVolumes.Add(lightVolume); } public void RemoveLightVolume(DS_HazeLightVolume lightVolume) { m_LightVolumes.Remove(lightVolume); } public void GetRenderLightVolumes(Vector3 cameraPosition, List lightVolumes, List shadowVolumes) { foreach (DS_HazeLightVolume lightVolume in m_LightVolumes) { if (lightVolume.WillRender(cameraPosition)) { if (lightVolume.CastShadows) { shadowVolumes.Add(lightVolume); } else { lightVolumes.Add(lightVolume); } } } } public DS_HazeContextItem GetRenderContextAtPosition(Vector3 position) { List list = new List(); for (int i = 0; i < m_Zones.Count; i++) { if (m_Zones[i].Contains(position) && m_Zones[i].enabled) { list.Add(m_Zones[i]); } } if (list.Count == 0) { return null; } if (list.Count == 1) { return list[0].Context.GetContextItemBlended(m_Time); } list.Sort((DS_HazeZone z1, DS_HazeZone z2) => (!(z1 < z2)) ? 1 : (-1)); DS_HazeContextItem contextItemBlended = list[0].Context.GetContextItemBlended(m_Time); float num = 0f; for (int j = 1; j < list.Count; j++) { num = list[j].GetBlendWeight(position); contextItemBlended.Lerp(list[j].Context.GetContextItemBlended(m_Time), num); } return contextItemBlended; } }