You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
11 KiB
C#
341 lines
11 KiB
C#
|
4 years ago
|
#if HDPipeline && UNITY_2021_2_OR_NEWER
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.Rendering;
|
||
|
|
using UnityEngine.Rendering.HighDefinition;
|
||
|
|
|
||
|
|
namespace ProceduralWorlds.HDRPTOD
|
||
|
|
{
|
||
|
|
public enum OverrideTODType { Day, Night }
|
||
|
|
|
||
|
|
[System.Serializable]
|
||
|
|
public class OverrideVolumeSettings
|
||
|
|
{
|
||
|
|
public bool m_drawGimzo = true;
|
||
|
|
public bool m_addOverrideVolumeType = true;
|
||
|
|
public bool m_removeFromController = true;
|
||
|
|
public OverrideTODType m_volumeType = OverrideTODType.Day;
|
||
|
|
public Color m_gizmoColor = new Color(1f, 0f, 0f, 0.4f);
|
||
|
|
public float m_blendTime = 3f;
|
||
|
|
public ClampedFloatParameter m_sunVolumetric = new ClampedFloatParameter(1f, 0f, 16f, false);
|
||
|
|
public ClampedFloatParameter m_sunVolumetricDimmer = new ClampedFloatParameter(1f, 0f, 1f, false);
|
||
|
|
public ClampedFloatParameter m_exposure = new ClampedFloatParameter(14f, -5f, 20f);
|
||
|
|
public ClampedFloatParameter m_ambientIntensity = new ClampedFloatParameter(1f, 0f, 4f, false);
|
||
|
|
public ClampedFloatParameter m_ambientReflectionIntensity = new ClampedFloatParameter(1f, 0f, 4f, false);
|
||
|
|
public ClampedFloatParameter m_shadowDistanceMultiplier = new ClampedFloatParameter(1f, 0.005f, 5f);
|
||
|
|
|
||
|
|
public bool IsAnyOverrideEnabled()
|
||
|
|
{
|
||
|
|
if (m_sunVolumetric.overrideState)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (m_sunVolumetricDimmer.overrideState)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (m_exposure.overrideState)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (m_ambientIntensity.overrideState)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (m_ambientReflectionIntensity.overrideState)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (m_shadowDistanceMultiplier.overrideState)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
[System.Serializable]
|
||
|
|
public class OverrideVolumeLocalFog
|
||
|
|
{
|
||
|
|
public bool m_enabled = false;
|
||
|
|
public bool m_useTODParameters = true;
|
||
|
|
public Color m_scatteringAlbedo = Color.white;
|
||
|
|
public Color m_scatteringAlbedoMultiplier = Color.white;
|
||
|
|
public float m_fogDistance = 150f;
|
||
|
|
public float m_fogDistanceMultiplier = 1f;
|
||
|
|
public float m_renderDistance = 1000f;
|
||
|
|
public Texture m_densityMask;
|
||
|
|
public Vector3 m_scrollSpeed = Vector3.zero;
|
||
|
|
public Vector3 m_tiling = Vector3.one;
|
||
|
|
}
|
||
|
|
[System.Serializable]
|
||
|
|
public class OverrideDataInfo
|
||
|
|
{
|
||
|
|
public bool m_isInVolue = false;
|
||
|
|
public float m_transitionTime = 0f;
|
||
|
|
public OverrideVolumeSettings m_settings = new OverrideVolumeSettings();
|
||
|
|
}
|
||
|
|
public enum OverrideVolumeType { Box, Sphere }
|
||
|
|
|
||
|
|
[ExecuteAlways]
|
||
|
|
public class HDRPTimeOfDayOverrideVolume : MonoBehaviour
|
||
|
|
{
|
||
|
|
public OverrideVolumeSettings m_volumeSettings = new OverrideVolumeSettings();
|
||
|
|
public OverrideVolumeLocalFog m_localFogSettings = new OverrideVolumeLocalFog();
|
||
|
|
|
||
|
|
[SerializeField] private LocalVolumetricFog m_localFog;
|
||
|
|
[SerializeField] private int m_id;
|
||
|
|
[SerializeField] private Bounds m_bounds;
|
||
|
|
[SerializeField] private bool m_isInBounds = false;
|
||
|
|
[SerializeField] private Vector3 m_lastScale = Vector3.zero;
|
||
|
|
|
||
|
|
private void OnEnable()
|
||
|
|
{
|
||
|
|
Setup();
|
||
|
|
m_bounds = BuildAndGetBounds();
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
if (!Application.isPlaying)
|
||
|
|
{
|
||
|
|
EditorApplication.update -= EditorUpdate;
|
||
|
|
EditorApplication.update += EditorUpdate;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
EditorApplication.update -= EditorUpdate;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
private void OnDestroy()
|
||
|
|
{
|
||
|
|
if (HDRPTimeOfDay.Instance != null)
|
||
|
|
{
|
||
|
|
m_isInBounds = HDRPTimeOfDay.Instance.RemoveOverrideVolume(m_id);
|
||
|
|
}
|
||
|
|
|
||
|
|
HDRPTimeOfDayOverrideVolumeController controller = HDRPTimeOfDayOverrideVolumeController.Instance;
|
||
|
|
if (controller != null)
|
||
|
|
{
|
||
|
|
controller.RemoveOverrideVolume(this, m_volumeSettings.m_volumeType);
|
||
|
|
}
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
EditorApplication.update -= EditorUpdate;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
private void OnDisable()
|
||
|
|
{
|
||
|
|
if (HDRPTimeOfDay.Instance != null)
|
||
|
|
{
|
||
|
|
m_isInBounds = HDRPTimeOfDay.Instance.RemoveOverrideVolume(m_id);
|
||
|
|
}
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
EditorApplication.update -= EditorUpdate;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
private void OnDrawGizmos()
|
||
|
|
{
|
||
|
|
if (!m_volumeSettings.m_drawGimzo)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Gizmos.color = m_volumeSettings.m_gizmoColor;
|
||
|
|
Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, m_bounds.size);
|
||
|
|
Gizmos.DrawCube(Vector3.zero, Vector3.one);
|
||
|
|
}
|
||
|
|
private void OnDrawGizmosSelected()
|
||
|
|
{
|
||
|
|
if (!m_volumeSettings.m_drawGimzo)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_lastScale != transform.localScale)
|
||
|
|
{
|
||
|
|
m_bounds = BuildAndGetBounds();
|
||
|
|
ApplyLocalFogVolume(true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
private void Update()
|
||
|
|
{
|
||
|
|
if (HDRPTimeOfDay.Instance == null || !HDRPTimeOfDay.Instance.UseOverrideVolumes || !Application.isPlaying)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
IsInBounds(HDRPTimeOfDay.Instance.Player);
|
||
|
|
if (m_localFogSettings.m_enabled)
|
||
|
|
{
|
||
|
|
ApplyLocalFogVolume(true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Sets up this override volume and sets the volume ID
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="ID"></param>
|
||
|
|
public void Setup(int ID = -1)
|
||
|
|
{
|
||
|
|
if (ID != -1)
|
||
|
|
{
|
||
|
|
m_id = ID;
|
||
|
|
}
|
||
|
|
LoadVolume();
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Loads the volume data and sets it up
|
||
|
|
/// </summary>
|
||
|
|
public void LoadVolume()
|
||
|
|
{
|
||
|
|
m_isInBounds = false;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Checks to see if the transform player is in the bounding volume
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="player"></param>
|
||
|
|
public void IsInBounds(Transform player)
|
||
|
|
{
|
||
|
|
if (!enabled)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (player != null)
|
||
|
|
{
|
||
|
|
bool inBounds = m_bounds.Contains(player.position);
|
||
|
|
if (inBounds)
|
||
|
|
{
|
||
|
|
m_isInBounds = HDRPTimeOfDay.Instance.AddOverrideVolume(m_id, this);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (m_isInBounds)
|
||
|
|
{
|
||
|
|
m_isInBounds = HDRPTimeOfDay.Instance.RemoveOverrideVolume(m_id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Adds the volume to the controller that with be managed is active state if it's day or night
|
||
|
|
/// </summary>
|
||
|
|
public void SetupVolumeTypeToController()
|
||
|
|
{
|
||
|
|
HDRPTimeOfDayOverrideVolumeController controller = HDRPTimeOfDayOverrideVolumeController.Instance;
|
||
|
|
if (!m_volumeSettings.m_addOverrideVolumeType)
|
||
|
|
{
|
||
|
|
if (controller != null && m_volumeSettings.m_removeFromController)
|
||
|
|
{
|
||
|
|
controller.RemoveOverrideVolume(this, m_volumeSettings.m_volumeType);
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (controller != null)
|
||
|
|
{
|
||
|
|
controller.AddOverrideVolume(this, m_volumeSettings.m_volumeType);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Applies local fog
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="runTimeSyncOnly"></param>
|
||
|
|
public void ApplyLocalFogVolume(bool runTimeSyncOnly)
|
||
|
|
{
|
||
|
|
if (m_localFogSettings.m_enabled)
|
||
|
|
{
|
||
|
|
HDRPTimeOfDay tod = HDRPTimeOfDay.Instance;
|
||
|
|
if (tod == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_localFog == null)
|
||
|
|
{
|
||
|
|
m_localFog = GetComponent<LocalVolumetricFog>();
|
||
|
|
if (m_localFog == null)
|
||
|
|
{
|
||
|
|
m_localFog = gameObject.AddComponent<LocalVolumetricFog>();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (m_localFog != null)
|
||
|
|
{
|
||
|
|
if (m_localFogSettings.m_useTODParameters)
|
||
|
|
{
|
||
|
|
m_localFog.parameters.albedo = (tod.GetCurrentFogColor() * m_localFogSettings.m_scatteringAlbedoMultiplier);
|
||
|
|
m_localFog.parameters.meanFreePath = (tod.GetCurrentLocalFogDistance() / m_localFogSettings.m_fogDistanceMultiplier);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
m_localFog.parameters.albedo = m_localFogSettings.m_scatteringAlbedo;
|
||
|
|
m_localFog.parameters.meanFreePath = (m_localFogSettings.m_fogDistance * m_localFogSettings.m_fogDistanceMultiplier);
|
||
|
|
}
|
||
|
|
|
||
|
|
m_localFog.parameters.size = transform.localScale;
|
||
|
|
if (!runTimeSyncOnly)
|
||
|
|
{
|
||
|
|
m_localFog.parameters.volumeMask = m_localFogSettings.m_densityMask;
|
||
|
|
m_localFog.parameters.textureScrollingSpeed = m_localFogSettings.m_scrollSpeed;
|
||
|
|
m_localFog.parameters.textureTiling = m_localFogSettings.m_tiling;
|
||
|
|
m_localFog.parameters.distanceFadeStart = m_localFogSettings.m_renderDistance;
|
||
|
|
m_localFog.parameters.distanceFadeEnd = m_localFogSettings.m_renderDistance;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (m_localFog != null)
|
||
|
|
{
|
||
|
|
DestroyImmediate(m_localFog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Removes the local fog volume
|
||
|
|
/// </summary>
|
||
|
|
public void RemoveLocalFogVolume()
|
||
|
|
{
|
||
|
|
if (m_localFog != null)
|
||
|
|
{
|
||
|
|
DestroyImmediate(m_localFog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Creates and returns the bounds
|
||
|
|
/// </summary>
|
||
|
|
/// <returns></returns>
|
||
|
|
public Bounds BuildAndGetBounds()
|
||
|
|
{
|
||
|
|
m_lastScale = transform.localScale;
|
||
|
|
return new Bounds(transform.position, new Vector3(transform.localScale.x, transform.localScale.y, transform.localScale.z));
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Editor update function
|
||
|
|
/// </summary>
|
||
|
|
private void EditorUpdate()
|
||
|
|
{
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
if (HDRPTimeOfDay.Instance == null || !HDRPTimeOfDay.Instance.UseOverrideVolumes)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_localFogSettings.m_enabled)
|
||
|
|
{
|
||
|
|
ApplyLocalFogVolume(true);
|
||
|
|
}
|
||
|
|
|
||
|
|
SceneView sceneView = SceneView.lastActiveSceneView;
|
||
|
|
if (sceneView != null)
|
||
|
|
{
|
||
|
|
Camera camera = sceneView.camera;
|
||
|
|
if (camera != null)
|
||
|
|
{
|
||
|
|
IsInBounds(camera.transform);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|