Skip to content

Commit a99eb4c

Browse files
Combined LateUpdate callbacks for lights (#104)
1 parent 8c85458 commit a99eb4c

File tree

1 file changed

+146
-84
lines changed

1 file changed

+146
-84
lines changed

com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs

Lines changed: 146 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
using Unity.Mathematics;
1717
using Unity.Profiling;
1818
using UnityEngine.Assertions;
19+
using UnityEngine.LowLevel;
20+
using UnityEngine.PlayerLoop;
1921

2022
namespace UnityEngine.Rendering.HighDefinition
2123
{
@@ -3064,121 +3066,130 @@ private void Start()
30643066
}
30653067

30663068
// TODO: There are a lot of old != current checks and assignation in this function, maybe think about using another system ?
3067-
void LateUpdate()
3069+
internal static void TickLateUpdate()
30683070
{
30693071
// Prevent any unwanted sync when not in HDRP (case 1217575)
30703072
if (HDRenderPipeline.currentPipeline == null)
30713073
return;
30723074

3073-
// We force the animation in the editor and in play mode when there is an animator component attached to the light
3075+
List<HDAdditionalLightData> allAdditionalLightDatas = s_InstancesHDAdditionalLightData;
3076+
3077+
int additionalLightCount = allAdditionalLightDatas.Count;
3078+
3079+
for (int i = 0; i < additionalLightCount; i++)
3080+
{
3081+
HDAdditionalLightData additionalLightData = allAdditionalLightDatas[i];
3082+
3083+
// We force the animation in the editor and in play mode when there is an animator component attached to the light
30743084
#if !UNITY_EDITOR
3075-
if (!m_Animated)
3076-
return;
3085+
if (!additionalLightData.m_Animated)
3086+
continue;
30773087
#endif
30783088

30793089
#if UNITY_EDITOR
30803090

3081-
// If modification are due to change on prefab asset that are non overridden on this prefab instance
3082-
if (m_NeedsPrefabInstanceCheck && PrefabUtility.IsPartOfPrefabInstance(this) && ((PrefabUtility.GetCorrespondingObjectFromOriginalSource(this) as HDAdditionalLightData)?.needRefreshPrefabInstanceEmissiveMeshes ?? false))
3083-
{
3084-
needRefreshPrefabInstanceEmissiveMeshes = true;
3085-
}
3086-
m_NeedsPrefabInstanceCheck = false;
3091+
// If modification are due to change on prefab asset that are non overridden on this prefab instance
3092+
if (additionalLightData.m_NeedsPrefabInstanceCheck && PrefabUtility.IsPartOfPrefabInstance(additionalLightData) && ((PrefabUtility.GetCorrespondingObjectFromOriginalSource(additionalLightData) as HDAdditionalLightData)?.needRefreshPrefabInstanceEmissiveMeshes ?? false))
3093+
{
3094+
additionalLightData.needRefreshPrefabInstanceEmissiveMeshes = true;
3095+
}
3096+
additionalLightData.m_NeedsPrefabInstanceCheck = false;
30873097

3088-
// Update the list of overlapping lights for the LightOverlap scene view mode
3089-
if (IsOverlapping())
3090-
s_overlappingHDLights.Add(this);
3091-
else
3092-
s_overlappingHDLights.Remove(this);
3098+
// Update the list of overlapping lights for the LightOverlap scene view mode
3099+
if (additionalLightData.IsOverlapping())
3100+
s_overlappingHDLights.Add(additionalLightData);
3101+
else
3102+
s_overlappingHDLights.Remove(additionalLightData);
30933103
#endif
30943104

30953105
#if UNITY_EDITOR
30963106

3097-
// If we requested an emissive mesh but for some reason (e.g. Reload scene unchecked in the Enter Playmode options) Awake has not been called,
3098-
// we need to create it manually.
3099-
if (m_DisplayAreaLightEmissiveMesh && (m_ChildEmissiveMeshViewer == null || m_ChildEmissiveMeshViewer.Equals(null)))
3100-
{
3101-
UpdateAreaLightEmissiveMesh();
3102-
}
3107+
// If we requested an emissive mesh but for some reason (e.g. Reload scene unchecked in the Enter Playmode options) Awake has not been called,
3108+
// we need to create it manually.
3109+
if (additionalLightData.m_DisplayAreaLightEmissiveMesh && (additionalLightData.m_ChildEmissiveMeshViewer == null || additionalLightData.m_ChildEmissiveMeshViewer.Equals(null)))
3110+
{
3111+
additionalLightData.UpdateAreaLightEmissiveMesh();
3112+
}
31033113

3104-
//if not parented anymore, refresh it
3105-
if (m_ChildEmissiveMeshViewer != null && !m_ChildEmissiveMeshViewer.Equals(null))
3106-
{
3107-
if (m_ChildEmissiveMeshViewer.transform.parent != transform)
3114+
//if not parented anymore, refresh it
3115+
if (additionalLightData.m_ChildEmissiveMeshViewer != null && !additionalLightData.m_ChildEmissiveMeshViewer.Equals(null))
31083116
{
3109-
CreateChildEmissiveMeshViewerIfNeeded();
3110-
UpdateAreaLightEmissiveMesh();
3117+
if (additionalLightData.m_ChildEmissiveMeshViewer.transform.parent != additionalLightData.transform)
3118+
{
3119+
additionalLightData.CreateChildEmissiveMeshViewerIfNeeded();
3120+
additionalLightData.UpdateAreaLightEmissiveMesh();
3121+
}
3122+
if (additionalLightData.m_ChildEmissiveMeshViewer.isStatic != additionalLightData.gameObject.isStatic)
3123+
additionalLightData.m_ChildEmissiveMeshViewer.isStatic = additionalLightData.gameObject.isStatic;
3124+
if (GameObjectUtility.GetStaticEditorFlags(additionalLightData.m_ChildEmissiveMeshViewer) != GameObjectUtility.GetStaticEditorFlags(additionalLightData.gameObject))
3125+
GameObjectUtility.SetStaticEditorFlags(additionalLightData.m_ChildEmissiveMeshViewer, GameObjectUtility.GetStaticEditorFlags(additionalLightData.gameObject));
31113126
}
3112-
if (m_ChildEmissiveMeshViewer.gameObject.isStatic != gameObject.isStatic)
3113-
m_ChildEmissiveMeshViewer.gameObject.isStatic = gameObject.isStatic;
3114-
if (GameObjectUtility.GetStaticEditorFlags(m_ChildEmissiveMeshViewer.gameObject) != GameObjectUtility.GetStaticEditorFlags(gameObject))
3115-
GameObjectUtility.SetStaticEditorFlags(m_ChildEmissiveMeshViewer.gameObject, GameObjectUtility.GetStaticEditorFlags(gameObject));
3116-
}
31173127
#endif
31183128

3119-
//auto change layer on emissive mesh
3120-
if (areaLightEmissiveMeshLayer == -1
3121-
&& m_ChildEmissiveMeshViewer != null && !m_ChildEmissiveMeshViewer.Equals(null)
3122-
&& m_ChildEmissiveMeshViewer.gameObject.layer != gameObject.layer)
3123-
m_ChildEmissiveMeshViewer.gameObject.layer = gameObject.layer;
3129+
//auto change layer on emissive mesh
3130+
if (additionalLightData.areaLightEmissiveMeshLayer == -1
3131+
&& additionalLightData.m_ChildEmissiveMeshViewer != null && !additionalLightData.m_ChildEmissiveMeshViewer.Equals(null)
3132+
&& additionalLightData.m_ChildEmissiveMeshViewer.layer != additionalLightData.gameObject.layer)
3133+
additionalLightData.m_ChildEmissiveMeshViewer.layer = additionalLightData.gameObject.layer;
31243134

3125-
// Delayed cleanup when removing emissive mesh from timeline
3126-
if (needRefreshEmissiveMeshesFromTimeLineUpdate)
3127-
{
3128-
needRefreshEmissiveMeshesFromTimeLineUpdate = false;
3129-
UpdateAreaLightEmissiveMesh();
3130-
}
3135+
// Delayed cleanup when removing emissive mesh from timeline
3136+
if (additionalLightData.needRefreshEmissiveMeshesFromTimeLineUpdate)
3137+
{
3138+
additionalLightData.needRefreshEmissiveMeshesFromTimeLineUpdate = false;
3139+
additionalLightData.UpdateAreaLightEmissiveMesh();
3140+
}
31313141

31323142
#if UNITY_EDITOR
3133-
// Prefab instance child emissive mesh update
3134-
if (needRefreshPrefabInstanceEmissiveMeshes)
3135-
{
3136-
// We must not call the update on Prefab Asset that are already updated or we will enter infinite loop
3137-
if (!PrefabUtility.IsPartOfPrefabAsset(this))
3143+
// Prefab instance child emissive mesh update
3144+
if (additionalLightData.needRefreshPrefabInstanceEmissiveMeshes)
31383145
{
3139-
UpdateAreaLightEmissiveMesh();
3146+
// We must not call the update on Prefab Asset that are already updated or we will enter infinite loop
3147+
if (!PrefabUtility.IsPartOfPrefabAsset(additionalLightData))
3148+
{
3149+
additionalLightData.UpdateAreaLightEmissiveMesh();
3150+
}
3151+
additionalLightData.needRefreshPrefabInstanceEmissiveMeshes = false;
31403152
}
3141-
needRefreshPrefabInstanceEmissiveMeshes = false;
3142-
}
31433153
#endif
31443154

3145-
Vector3 shape = new Vector3(shapeWidth, m_ShapeHeight, shapeRadius);
3155+
Vector3 shape = new Vector3(additionalLightData.shapeWidth, additionalLightData.m_ShapeHeight, additionalLightData.shapeRadius);
31463156

3147-
if (legacyLight.enabled != timelineWorkaround.lightEnabled)
3148-
{
3149-
SetEmissiveMeshRendererEnabled(legacyLight.enabled);
3150-
timelineWorkaround.lightEnabled = legacyLight.enabled;
3151-
}
3157+
if (additionalLightData.legacyLight.enabled != additionalLightData.timelineWorkaround.lightEnabled)
3158+
{
3159+
additionalLightData.SetEmissiveMeshRendererEnabled(additionalLightData.legacyLight.enabled);
3160+
additionalLightData.timelineWorkaround.lightEnabled = additionalLightData.legacyLight.enabled;
3161+
}
31523162

3153-
// Check if the intensity have been changed by the inspector or an animator
3154-
if (timelineWorkaround.oldLossyScale != transform.lossyScale
3155-
|| intensity != timelineWorkaround.oldIntensity
3156-
|| legacyLight.colorTemperature != timelineWorkaround.oldLightColorTemperature)
3157-
{
3158-
UpdateLightIntensity();
3159-
UpdateAreaLightEmissiveMesh();
3160-
timelineWorkaround.oldLossyScale = transform.lossyScale;
3161-
timelineWorkaround.oldIntensity = intensity;
3162-
timelineWorkaround.oldLightColorTemperature = legacyLight.colorTemperature;
3163-
}
3163+
// Check if the intensity have been changed by the inspector or an animator
3164+
if (additionalLightData.timelineWorkaround.oldLossyScale != additionalLightData.transform.lossyScale
3165+
|| additionalLightData.intensity != additionalLightData.timelineWorkaround.oldIntensity
3166+
|| additionalLightData.legacyLight.colorTemperature != additionalLightData.timelineWorkaround.oldLightColorTemperature)
3167+
{
3168+
additionalLightData.UpdateLightIntensity();
3169+
additionalLightData.UpdateAreaLightEmissiveMesh();
3170+
additionalLightData.timelineWorkaround.oldLossyScale = additionalLightData.transform.lossyScale;
3171+
additionalLightData.timelineWorkaround.oldIntensity = additionalLightData.intensity;
3172+
additionalLightData.timelineWorkaround.oldLightColorTemperature = additionalLightData.legacyLight.colorTemperature;
3173+
}
31643174

3165-
// Same check for light angle to update intensity using spot angle
3166-
if (type == HDLightType.Spot && (timelineWorkaround.oldSpotAngle != legacyLight.spotAngle))
3167-
{
3168-
UpdateLightIntensity();
3169-
timelineWorkaround.oldSpotAngle = legacyLight.spotAngle;
3170-
}
3175+
// Same check for light angle to update intensity using spot angle
3176+
if (additionalLightData.type == HDLightType.Spot && (additionalLightData.timelineWorkaround.oldSpotAngle != additionalLightData.legacyLight.spotAngle))
3177+
{
3178+
additionalLightData.UpdateLightIntensity();
3179+
additionalLightData.timelineWorkaround.oldSpotAngle = additionalLightData.legacyLight.spotAngle;
3180+
}
31713181

3172-
if (legacyLight.color != timelineWorkaround.oldLightColor
3173-
|| timelineWorkaround.oldLossyScale != transform.lossyScale
3174-
|| displayAreaLightEmissiveMesh != timelineWorkaround.oldDisplayAreaLightEmissiveMesh
3175-
|| legacyLight.colorTemperature != timelineWorkaround.oldLightColorTemperature)
3176-
{
3177-
UpdateAreaLightEmissiveMesh();
3178-
timelineWorkaround.oldLightColor = legacyLight.color;
3179-
timelineWorkaround.oldLossyScale = transform.lossyScale;
3180-
timelineWorkaround.oldDisplayAreaLightEmissiveMesh = displayAreaLightEmissiveMesh;
3181-
timelineWorkaround.oldLightColorTemperature = legacyLight.colorTemperature;
3182+
if (additionalLightData.legacyLight.color != additionalLightData.timelineWorkaround.oldLightColor
3183+
|| additionalLightData.timelineWorkaround.oldLossyScale != additionalLightData.transform.lossyScale
3184+
|| additionalLightData.displayAreaLightEmissiveMesh != additionalLightData.timelineWorkaround.oldDisplayAreaLightEmissiveMesh
3185+
|| additionalLightData.legacyLight.colorTemperature != additionalLightData.timelineWorkaround.oldLightColorTemperature)
3186+
{
3187+
additionalLightData.UpdateAreaLightEmissiveMesh();
3188+
additionalLightData.timelineWorkaround.oldLightColor = additionalLightData.legacyLight.color;
3189+
additionalLightData.timelineWorkaround.oldLossyScale = additionalLightData.transform.lossyScale;
3190+
additionalLightData.timelineWorkaround.oldDisplayAreaLightEmissiveMesh = additionalLightData.displayAreaLightEmissiveMesh;
3191+
additionalLightData.timelineWorkaround.oldLightColorTemperature = additionalLightData.legacyLight.colorTemperature;
3192+
}
31823193
}
31833194
}
31843195

@@ -4214,4 +4225,55 @@ public static List<Light> GetLightInstances()
42144225
}
42154226
// custom-end
42164227
}
4228+
4229+
public static class LightLateUpdate
4230+
{
4231+
#if UNITY_EDITOR
4232+
[UnityEditor.InitializeOnLoadMethod]
4233+
#else
4234+
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
4235+
#endif
4236+
internal static void Init()
4237+
{
4238+
var currentLoopSystem = LowLevel.PlayerLoop.GetCurrentPlayerLoop();
4239+
4240+
bool found = AppendToPlayerLoopList(typeof(LightLateUpdate), Tick, ref currentLoopSystem, typeof(PreLateUpdate.ScriptRunBehaviourLateUpdate));
4241+
LowLevel.PlayerLoop.SetPlayerLoop(currentLoopSystem);
4242+
}
4243+
internal static void Tick()
4244+
{
4245+
HDAdditionalLightData.TickLateUpdate();
4246+
}
4247+
4248+
internal static bool AppendToPlayerLoopList(Type updateType, PlayerLoopSystem.UpdateFunction updateFunction, ref PlayerLoopSystem playerLoop, Type playerLoopSystemType)
4249+
{
4250+
if (updateType == null || updateFunction == null || playerLoopSystemType == null)
4251+
return false;
4252+
4253+
if (playerLoop.type == playerLoopSystemType)
4254+
{
4255+
var oldListLength = playerLoop.subSystemList != null ? playerLoop.subSystemList.Length : 0;
4256+
var newSubsystemList = new PlayerLoopSystem[oldListLength + 1];
4257+
for (var i = 0; i < oldListLength; ++i)
4258+
newSubsystemList[i] = playerLoop.subSystemList[i];
4259+
newSubsystemList[oldListLength] = new PlayerLoopSystem
4260+
{
4261+
type = updateType,
4262+
updateDelegate = updateFunction
4263+
};
4264+
playerLoop.subSystemList = newSubsystemList;
4265+
return true;
4266+
}
4267+
4268+
if (playerLoop.subSystemList != null)
4269+
{
4270+
for (var i = 0; i < playerLoop.subSystemList.Length; ++i)
4271+
{
4272+
if (AppendToPlayerLoopList(updateType, updateFunction, ref playerLoop.subSystemList[i], playerLoopSystemType))
4273+
return true;
4274+
}
4275+
}
4276+
return false;
4277+
}
4278+
}
42174279
}

0 commit comments

Comments
 (0)