This commit is contained in:
CortexCore
2024-11-20 11:36:36 +08:00
parent 99253854e8
commit 6cc53eb9dc
383 changed files with 21233 additions and 112159 deletions

View File

@@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Jupiter
{
[AttributeUsage(AttributeTargets.Property)]
public class JAnimatableAttribute : Attribute
{
public string DisplayName { get; set; }
public JCurveOrGradient CurveOrGradient { get; set; }
public JAnimatableAttribute(string displayName, JCurveOrGradient curveOrGradient)
{
DisplayName = displayName;
CurveOrGradient = curveOrGradient;
}
}
}

View File

@@ -0,0 +1,115 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Jupiter
{
[System.Serializable]
public class JAnimatedProperty
{
[SerializeField]
private string name;
public string Name
{
get
{
if (name == null)
{
name = string.Empty;
}
return name;
}
set
{
name = value;
}
}
[SerializeField]
private string displayName;
public string DisplayName
{
get
{
if (displayName == null)
{
displayName = string.Empty;
}
return displayName;
}
set
{
displayName = value;
}
}
[SerializeField]
private JCurveOrGradient curveOrGradient;
public JCurveOrGradient CurveOrGradient
{
get
{
return curveOrGradient;
}
set
{
curveOrGradient = value;
}
}
[SerializeField]
private AnimationCurve curve;
public AnimationCurve Curve
{
get
{
if (curve == null)
{
curve = AnimationCurve.EaseInOut(0, 0, 1, 0);
}
return curve;
}
set
{
curve = value;
}
}
[SerializeField]
private Gradient gradient;
public Gradient Gradient
{
get
{
if (gradient == null)
{
gradient = JUtilities.CreateFullWhiteGradient();
}
return gradient;
}
set
{
gradient = value;
}
}
public float EvaluateFloat(float t)
{
return Curve.Evaluate(t);
}
public Color EvaluateColor(float t)
{
return Gradient.Evaluate(t);
}
public static JAnimatedProperty Create(string name, string displayName, JCurveOrGradient curveOrGradient)
{
JAnimatedProperty props = new JAnimatedProperty();
props.name = name;
props.displayName = displayName;
props.curveOrGradient = curveOrGradient;
return props;
}
}
}

View File

@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Jupiter
{
public enum JCurveOrGradient
{
Curve, Gradient
}
}

View File

@@ -0,0 +1,372 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
using System;
namespace Pinwheel.Jupiter
{
[ExecuteInEditMode]
public class JDayNightCycle : MonoBehaviour
{
[SerializeField]
private JDayNightCycleProfile profile;
public JDayNightCycleProfile Profile
{
get
{
return profile;
}
set
{
profile = value;
}
}
[SerializeField]
private JSky sky;
public JSky Sky
{
get
{
return sky;
}
set
{
sky = value;
}
}
[SerializeField]
private bool useSunPivot;
public bool UseSunPivot
{
get
{
return useSunPivot;
}
set
{
useSunPivot = value;
}
}
[SerializeField]
private Transform sunOrbitPivot;
public Transform SunOrbitPivot
{
get
{
return sunOrbitPivot;
}
set
{
sunOrbitPivot = value;
}
}
[SerializeField]
private bool useMoonPivot;
public bool UseMoonPivot
{
get
{
return useMoonPivot;
}
set
{
useMoonPivot = value;
}
}
[SerializeField]
private Transform moonOrbitPivot;
public Transform MoonOrbitPivot
{
get
{
return moonOrbitPivot;
}
set
{
moonOrbitPivot = value;
}
}
[SerializeField]
private float startTime;
public float StartTime
{
get
{
return startTime;
}
set
{
startTime = Mathf.Clamp(value, 0f, 24f);
}
}
[SerializeField]
private float timeIncrement;
public float TimeIncrement
{
get
{
return timeIncrement;
}
set
{
timeIncrement = Mathf.Max(0, value);
}
}
[SerializeField]
private bool autoTimeIncrement;
public bool AutoTimeIncrement
{
get
{
return autoTimeIncrement;
}
set
{
autoTimeIncrement = value;
}
}
private float time;
public float Time
{
get
{
return time % 24f;
}
set
{
time = value % 24f;
}
}
[SerializeField]
private bool shouldUpdateEnvironmentReflection;
public bool ShouldUpdateEnvironmentReflection
{
get
{
return shouldUpdateEnvironmentReflection;
}
set
{
shouldUpdateEnvironmentReflection = value;
}
}
[SerializeField]
private int environmentReflectionResolution;
public int EnvironmentReflectionResolution
{
get
{
return environmentReflectionResolution;
}
set
{
int oldValue = environmentReflectionResolution;
int newValue = Mathf.Clamp(value, 16, 2048);
environmentReflectionResolution = newValue;
if (oldValue != newValue)
{
if (environmentReflection != null)
{
JUtilities.DestroyObject(environmentReflection);
}
if (environmentProbe != null)
{
JUtilities.DestroyGameobject(environmentProbe.gameObject);
}
}
}
}
[SerializeField]
private ReflectionProbeTimeSlicingMode environmentReflectionTimeSlicingMode;
public ReflectionProbeTimeSlicingMode EnvironmentReflectionTimeSlicingMode
{
get
{
return environmentReflectionTimeSlicingMode;
}
set
{
environmentReflectionTimeSlicingMode = value;
}
}
[SerializeField]
private ReflectionProbe environmentProbe;
private ReflectionProbe EnvironmentProbe
{
get
{
if (environmentProbe == null)
{
GameObject probeGO = new GameObject("~EnvironmentReflectionRenderer");
probeGO.transform.parent = transform;
probeGO.transform.position = new Vector3(0, -1000, 0);
probeGO.transform.rotation = Quaternion.identity;
probeGO.transform.localScale = Vector3.one;
probeGO.hideFlags = HideFlags.DontSave;
environmentProbe = probeGO.AddComponent<ReflectionProbe>();
environmentProbe.resolution = EnvironmentReflectionResolution;
environmentProbe.size = new Vector3(1, 1, 1);
environmentProbe.cullingMask = 0;
}
environmentProbe.clearFlags = ReflectionProbeClearFlags.Skybox;
environmentProbe.mode = ReflectionProbeMode.Realtime;
environmentProbe.refreshMode = ReflectionProbeRefreshMode.ViaScripting;
environmentProbe.timeSlicingMode = EnvironmentReflectionTimeSlicingMode;
environmentProbe.hdr = false;
return environmentProbe;
}
}
private Cubemap environmentReflection;
private Cubemap EnvironmentReflection
{
get
{
if (environmentReflection == null)
{
environmentReflection = new Cubemap(EnvironmentProbe.resolution, TextureFormat.RGBA32, true);
}
return environmentReflection;
}
}
private int probeRenderId = -1;
private float DeltaTime
{
get
{
if (Application.isPlaying)
return UnityEngine.Time.deltaTime;
else
return 1.0f / 60f;
}
}
private void Reset()
{
Sky = GetComponent<JSky>();
StartTime = 0;
TimeIncrement = 1;
AutoTimeIncrement = true;
Time = 0;
}
private void OnEnable()
{
time = StartTime;
}
private void OnDisable()
{
CleanUp();
}
private void CleanUp()
{
if (environmentProbe != null)
{
JUtilities.DestroyGameobject(environmentProbe.gameObject);
}
if (environmentReflection != null)
{
JUtilities.DestroyObject(environmentReflection);
}
if (Sky != null)
{
Sky.DNC = null;
}
}
private void Update()
{
AnimateSky();
if (ShouldUpdateEnvironmentReflection)
{
UpdateEnvironmentReflection();
}
else
{
RenderSettings.defaultReflectionMode = DefaultReflectionMode.Skybox;
}
}
private void AnimateSky()
{
if (Profile == null)
return;
if (Sky == null)
return;
if (Sky.Profile == null)
return;
Sky.DNC = this;
if (AutoTimeIncrement)
{
Time += TimeIncrement * DeltaTime;
}
float evalTime = Mathf.InverseLerp(0f, 24f, Time);
Profile.Animate(Sky, evalTime);
if (Sky.Profile.EnableSun && Sky.SunLightSource != null)
{
float angle = evalTime * 360f;
Matrix4x4 localRotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(angle, 0, 0));
Vector3 localDirection = localRotationMatrix.MultiplyVector(Vector3.up);
Transform pivot = (UseSunPivot && SunOrbitPivot != null) ? SunOrbitPivot : transform;
Matrix4x4 localToWorld = pivot.localToWorldMatrix;
Vector3 worldDirection = localToWorld.MultiplyVector(localDirection);
Sky.SunLightSource.transform.forward = worldDirection;
Sky.SunLightSource.color = Sky.Profile.Material.GetColor(JMat.SUN_LIGHT_COLOR);
Sky.SunLightSource.intensity = Sky.Profile.Material.GetFloat(JMat.SUN_LIGHT_INTENSITY);
}
if (Sky.Profile.EnableMoon && Sky.MoonLightSource != null)
{
float angle = evalTime * 360f;
Matrix4x4 localRotationMatrix = Matrix4x4.Rotate(Quaternion.Euler(angle, 0, 0));
Vector3 localDirection = localRotationMatrix.MultiplyVector(Vector3.down);
Transform pivot = (UseMoonPivot && MoonOrbitPivot != null) ? MoonOrbitPivot : transform;
Matrix4x4 localToWorld = pivot.localToWorldMatrix;
Vector3 worldDirection = localToWorld.MultiplyVector(localDirection);
Sky.MoonLightSource.transform.forward = worldDirection;
Sky.MoonLightSource.color = Sky.Profile.Material.GetColor(JMat.MOON_LIGHT_COLOR);
Sky.MoonLightSource.intensity = Sky.Profile.Material.GetFloat(JMat.MOON_LIGHT_INTENSITY);
}
}
private void UpdateEnvironmentReflection()
{
if ((SystemInfo.copyTextureSupport & CopyTextureSupport.RTToTexture) != 0)
{
if (EnvironmentProbe.texture == null)
{
probeRenderId = EnvironmentProbe.RenderProbe();
}
else if (EnvironmentProbe.texture != null || EnvironmentProbe.IsFinishedRendering(probeRenderId))
{
Graphics.CopyTexture(EnvironmentProbe.texture, EnvironmentReflection as Texture);
RenderSettings.customReflection = EnvironmentReflection;
RenderSettings.defaultReflectionMode = DefaultReflectionMode.Custom;
probeRenderId = EnvironmentProbe.RenderProbe();
}
}
}
}
}

View File

@@ -0,0 +1,130 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System;
namespace Pinwheel.Jupiter
{
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
[CreateAssetMenu(menuName = "Jupiter/Day Night Cycle Profile")]
public class JDayNightCycleProfile : ScriptableObject
{
private static Dictionary<string, int> propertyRemap;
private static Dictionary<string, int> PropertyRemap
{
get
{
if (propertyRemap == null)
{
propertyRemap = new Dictionary<string, int>();
}
return propertyRemap;
}
set
{
propertyRemap = value;
}
}
static JDayNightCycleProfile()
{
InitPropertyRemap();
}
private static void InitPropertyRemap()
{
PropertyRemap.Clear();
Type type = typeof(JSkyProfile);
PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in props)
{
JAnimatableAttribute animatable = p.GetCustomAttribute(typeof(JAnimatableAttribute), false) as JAnimatableAttribute;
if (animatable == null)
continue;
string name = p.Name;
int id = Shader.PropertyToID("_" + name);
PropertyRemap.Add(name, id);
}
}
[SerializeField]
private List<JAnimatedProperty> animatedProperties;
public List<JAnimatedProperty> AnimatedProperties
{
get
{
if (animatedProperties == null)
{
animatedProperties = new List<JAnimatedProperty>();
}
return animatedProperties;
}
set
{
animatedProperties = value;
}
}
public void AddProperty(JAnimatedProperty p, bool setDefaultValue = true)
{
if (setDefaultValue)
{
JDayNightCycleProfile defaultProfile = JJupiterSettings.Instance.DefaultDayNightCycleProfile;
if (defaultProfile != null)
{
JAnimatedProperty defaultProp = defaultProfile.AnimatedProperties.Find(p0 => p0.Name != null && p0.Name.Equals(p.Name));
if (defaultProp != null)
{
p.Curve = defaultProp.Curve;
p.Gradient = defaultProp.Gradient;
}
}
}
AnimatedProperties.Add(p);
}
public void Animate(JSky sky, float t)
{
CheckDefaultProfileAndThrow(sky.Profile);
for (int i = 0; i < AnimatedProperties.Count; ++i)
{
JAnimatedProperty aProp = AnimatedProperties[i];
int id = 0;
if (!PropertyRemap.TryGetValue(aProp.Name, out id))
{
continue;
}
if (aProp.CurveOrGradient == JCurveOrGradient.Curve)
{
sky.Profile.Material.SetFloat(id, aProp.EvaluateFloat(t));
}
else
{
sky.Profile.Material.SetColor(id, aProp.EvaluateColor(t));
}
}
}
private void CheckDefaultProfileAndThrow(JSkyProfile p)
{
if (p == null)
return;
if (p == JJupiterSettings.Instance.DefaultProfileSunnyDay ||
p == JJupiterSettings.Instance.DefaultProfileStarryNight)
{
throw new ArgumentException("Animating default sky profile is prohibited. You must create a new profile for your sky to animate it.");
}
}
public bool ContainProperty(string propertyName)
{
return AnimatedProperties.Exists((p) => p.Name.Equals(propertyName));
}
}
}