You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

447 lines
22 KiB

using UnityEngine.Rendering.HighDefinition;
using UnityEngine;
using System;
using System.Linq;
using System.Collections.Generic;
namespace UnityEditor.Rendering.HighDefinition
{
internal class SerializedHDLight : ISerializedLight
{
// HDRP specific properties
public SerializedProperty spotInnerPercent;
public SerializedProperty spotIESCutoffPercent;
public SerializedProperty lightDimmer;
public SerializedProperty fadeDistance;
public SerializedProperty affectDiffuse;
public SerializedProperty affectSpecular;
public SerializedProperty nonLightmappedOnly;
public SerializedProperty shapeWidth;
public SerializedProperty shapeHeight;
public SerializedProperty barnDoorAngle;
public SerializedProperty barnDoorLength;
public SerializedProperty aspectRatio;
public SerializedProperty shapeRadius;
public SerializedProperty maxSmoothness;
public SerializedProperty applyRangeAttenuation;
public SerializedProperty volumetricDimmer;
public SerializedProperty volumetricFadeDistance;
public SerializedProperty displayAreaLightEmissiveMesh;
public SerializedProperty areaLightEmissiveMeshCastShadow;
public SerializedProperty deportedAreaLightEmissiveMeshCastShadow;
public SerializedProperty areaLightEmissiveMeshMotionVector;
public SerializedProperty deportedAreaLightEmissiveMeshMotionVector;
public SerializedProperty areaLightEmissiveMeshLayer;
public SerializedProperty deportedAreaLightEmissiveMeshLayer;
public SerializedProperty renderingLayerMask;
public SerializedProperty shadowNearPlane;
public SerializedProperty blockerSampleCount;
public SerializedProperty filterSampleCount;
public SerializedProperty minFilterSize;
public SerializedProperty scaleForSoftness;
public SerializedProperty areaLightCookie; // We can't use default light cookies because the cookie gets reset by some safety measure on C++ side... :/
public SerializedProperty iesPoint;
public SerializedProperty iesSpot;
public SerializedProperty includeForRayTracing;
public SerializedProperty includeForPathTracing;
public SerializedProperty areaLightShadowCone;
public SerializedProperty useCustomSpotLightShadowCone;
public SerializedProperty customSpotLightShadowCone;
public SerializedProperty useScreenSpaceShadows;
public SerializedProperty interactsWithSky;
public SerializedProperty angularDiameter;
public SerializedProperty useRayTracedShadows;
public SerializedProperty numRayTracingSamples;
public SerializedProperty filterTracedShadow;
public SerializedProperty filterSizeTraced;
public SerializedProperty sunLightConeAngle;
public SerializedProperty lightShadowRadius;
public SerializedProperty semiTransparentShadow;
public SerializedProperty colorShadow;
public SerializedProperty distanceBasedFiltering;
public SerializedProperty evsmExponent;
public SerializedProperty evsmLightLeakBias;
public SerializedProperty evsmVarianceBias;
public SerializedProperty evsmBlurPasses;
public SerializedProperty dirLightPCSSMaxPenumbraSize;
public SerializedProperty dirLightPCSSMaxSamplingDistance;
public SerializedProperty dirLightPCSSMinFilterSizeTexels;
public SerializedProperty dirLightPCSSMinFilterMaxAngularDiameter;
public SerializedProperty dirLightPCSSBlockerSearchAngularDiameter;
public SerializedProperty dirLightPCSSBlockerSamplingClumpExponent;
public SerializedProperty dirLightPCSSBlockerSampleCount;
public SerializedProperty dirLightPCSSFilterSampleCount;
// Celestial Body
public SerializedProperty diameterOverride;
public SerializedProperty diameterMultiplier;
public SerializedProperty diameterMultiplerMode;
public SerializedProperty distance;
public SerializedProperty surfaceTexture;
public SerializedProperty surfaceTint;
public SerializedProperty shadingSource;
public SerializedProperty sunLightOverride;
public SerializedProperty sunColor;
public SerializedProperty sunIntensity;
public SerializedProperty phase;
public SerializedProperty phaseRotation;
public SerializedProperty earthshine;
public SerializedProperty flareSize;
public SerializedProperty flareFalloff;
public SerializedProperty flareTint;
public SerializedProperty flareMultiplier;
// Improved moment shadows data
public SerializedProperty lightAngle;
public SerializedProperty kernelSize;
public SerializedProperty maxDepthBias;
// Editor stuff
public SerializedProperty useOldInspector;
public SerializedProperty showFeatures;
public SerializedProperty useVolumetric;
// Layers
public SerializedProperty linkShadowLayers;
public SerializedProperty lightlayersMask;
// Shadow datas
public SerializedProperty shadowDimmer;
public SerializedProperty volumetricShadowDimmer;
public SerializedProperty shadowFadeDistance;
public SerializedScalableSettingValue contactShadows;
public SerializedProperty rayTracedContactShadow;
public SerializedProperty shadowTint;
public SerializedProperty penumbraTint;
public SerializedProperty shadowUpdateMode;
public SerializedProperty shadowAlwaysDrawDynamic;
public SerializedProperty shadowUpdateUponTransformChange;
public SerializedScalableSettingValue shadowResolution;
// Bias control
public SerializedProperty slopeBias;
public SerializedProperty normalBias;
[Obsolete("This property has been deprecated. Use SerializedHDLight.settings.intensity instead.")]
public SerializedProperty intensity => settings.intensity;
private GameObject[] emissiveMeshes;
public bool needUpdateAreaLightEmissiveMeshComponents = false;
public SerializedObject serializedObject { get; }
public SerializedObject serializedAdditionalDataObject { get; }
public SerializedProperty lightLayer;
private SerializedObject lightGameObject;
//contain serialized property that are mainly used to draw inspector
public LightEditor.Settings settings { get; }
struct AreaLightEmissiveMeshEditionScope : System.IDisposable
{
SerializedHDLight m_Serialized;
public AreaLightEmissiveMeshEditionScope(SerializedHDLight serialized)
{
m_Serialized = serialized;
foreach (GameObject emissiveMesh in m_Serialized.emissiveMeshes)
{
emissiveMesh.hideFlags &= ~HideFlags.NotEditable;
}
m_Serialized.areaLightEmissiveMeshCastShadow.serializedObject.Update();
}
void System.IDisposable.Dispose()
{
m_Serialized.areaLightEmissiveMeshCastShadow.serializedObject.ApplyModifiedProperties();
foreach (GameObject emissiveMesh in m_Serialized.emissiveMeshes)
{
emissiveMesh.hideFlags |= HideFlags.NotEditable;
}
m_Serialized.areaLightEmissiveMeshCastShadow.serializedObject.Update();
}
}
struct AreaLightEmissiveMeshObjectEditionScope : System.IDisposable
{
SerializedHDLight m_Serialized;
public AreaLightEmissiveMeshObjectEditionScope(SerializedHDLight serialized)
{
m_Serialized = serialized;
foreach (GameObject emissiveMesh in m_Serialized.emissiveMeshes)
{
emissiveMesh.hideFlags &= ~HideFlags.NotEditable;
}
m_Serialized.areaLightEmissiveMeshLayer.serializedObject.Update();
}
void System.IDisposable.Dispose()
{
m_Serialized.areaLightEmissiveMeshLayer.serializedObject.ApplyModifiedProperties();
foreach (GameObject emissiveMesh in m_Serialized.emissiveMeshes)
{
emissiveMesh.hideFlags |= HideFlags.NotEditable;
}
m_Serialized.areaLightEmissiveMeshLayer.serializedObject.Update();
}
}
public struct AreaLightEmissiveMeshDrawScope : System.IDisposable
{
SerializedProperty[] m_Properties;
bool m_OldEnableState;
public AreaLightEmissiveMeshDrawScope(Rect rect, GUIContent label, bool enabler, params SerializedProperty[] properties)
{
m_Properties = properties;
foreach (var property in m_Properties)
if (property != null)
EditorGUI.BeginProperty(rect, label, property);
m_OldEnableState = GUI.enabled;
GUI.enabled = enabler;
}
void System.IDisposable.Dispose()
{
GUI.enabled = m_OldEnableState;
foreach (var property in m_Properties)
if (property != null)
EditorGUI.EndProperty();
}
}
public void UpdateAreaLightEmissiveMeshCastShadow(UnityEngine.Rendering.ShadowCastingMode shadowCastingMode)
{
using (new AreaLightEmissiveMeshEditionScope(this))
{
areaLightEmissiveMeshCastShadow.intValue = (int)shadowCastingMode;
if (deportedAreaLightEmissiveMeshCastShadow != null) //only possible while editing from prefab
deportedAreaLightEmissiveMeshCastShadow.intValue = (int)shadowCastingMode;
}
}
public enum MotionVector
{
CameraMotionOnly = MotionVectorGenerationMode.Camera,
PerObjectMotion = MotionVectorGenerationMode.Object,
ForceNoMotion = MotionVectorGenerationMode.ForceNoMotion
}
public void UpdateAreaLightEmissiveMeshMotionVectorGeneration(MotionVector motionVectorGenerationMode)
{
using (new AreaLightEmissiveMeshEditionScope(this))
{
areaLightEmissiveMeshMotionVector.intValue = (int)motionVectorGenerationMode;
if (deportedAreaLightEmissiveMeshMotionVector != null) //only possible while editing from prefab
deportedAreaLightEmissiveMeshMotionVector.intValue = (int)motionVectorGenerationMode;
}
}
public void UpdateAreaLightEmissiveMeshLayer(int layer)
{
using (new AreaLightEmissiveMeshObjectEditionScope(this))
{
areaLightEmissiveMeshLayer.intValue = layer;
if (deportedAreaLightEmissiveMeshLayer != null) //only possible while editing from prefab
deportedAreaLightEmissiveMeshLayer.intValue = layer;
}
}
public SerializedHDLight(HDAdditionalLightData[] lightDatas, LightEditor.Settings settings)
{
serializedObject = new SerializedObject(lightDatas);
this.settings = settings;
using (var o = new PropertyFetcher<HDAdditionalLightData>(serializedObject))
{
spotInnerPercent = o.Find("m_InnerSpotPercent");
spotIESCutoffPercent = o.Find("m_SpotIESCutoffPercent");
lightDimmer = o.Find("m_LightDimmer");
volumetricDimmer = o.Find("m_VolumetricDimmer");
volumetricFadeDistance = o.Find("m_VolumetricFadeDistance");
displayAreaLightEmissiveMesh = o.Find("m_DisplayAreaLightEmissiveMesh");
fadeDistance = o.Find("m_FadeDistance");
affectDiffuse = o.Find("m_AffectDiffuse");
affectSpecular = o.Find("m_AffectSpecular");
nonLightmappedOnly = o.Find("m_NonLightmappedOnly");
shapeWidth = o.Find("m_ShapeWidth");
shapeHeight = o.Find("m_ShapeHeight");
barnDoorAngle = o.Find("m_BarnDoorAngle");
barnDoorLength = o.Find("m_BarnDoorLength");
aspectRatio = o.Find("m_AspectRatio");
shapeRadius = o.Find("m_ShapeRadius");
maxSmoothness = o.Find("m_MaxSmoothness");
applyRangeAttenuation = o.Find("m_ApplyRangeAttenuation");
shadowNearPlane = o.Find("m_ShadowNearPlane");
blockerSampleCount = o.Find("m_BlockerSampleCount");
filterSampleCount = o.Find("m_FilterSampleCount");
minFilterSize = o.Find("m_MinFilterSize");
scaleForSoftness = o.Find("m_SoftnessScale");
areaLightCookie = o.Find("m_AreaLightCookie");
iesPoint = o.Find("m_IESPoint");
iesSpot = o.Find("m_IESSpot");
includeForRayTracing = o.Find("m_IncludeForRayTracing");
includeForPathTracing = o.Find("m_IncludeForPathTracing");
areaLightShadowCone = o.Find("m_AreaLightShadowCone");
useCustomSpotLightShadowCone = o.Find("m_UseCustomSpotLightShadowCone");
customSpotLightShadowCone = o.Find("m_CustomSpotLightShadowCone");
useScreenSpaceShadows = o.Find("m_UseScreenSpaceShadows");
interactsWithSky = o.Find("m_InteractsWithSky");
angularDiameter = o.Find("m_AngularDiameter");
useRayTracedShadows = o.Find("m_UseRayTracedShadows");
numRayTracingSamples = o.Find("m_NumRayTracingSamples");
filterTracedShadow = o.Find("m_FilterTracedShadow");
filterSizeTraced = o.Find("m_FilterSizeTraced");
sunLightConeAngle = o.Find("m_SunLightConeAngle");
lightShadowRadius = o.Find("m_LightShadowRadius");
semiTransparentShadow = o.Find("m_SemiTransparentShadow");
colorShadow = o.Find("m_ColorShadow");
distanceBasedFiltering = o.Find("m_DistanceBasedFiltering");
evsmExponent = o.Find("m_EvsmExponent");
evsmVarianceBias = o.Find("m_EvsmVarianceBias");
evsmLightLeakBias = o.Find("m_EvsmLightLeakBias");
evsmBlurPasses = o.Find("m_EvsmBlurPasses");
dirLightPCSSMaxPenumbraSize = o.Find("m_DirLightPCSSMaxPenumbraSize");
dirLightPCSSMaxSamplingDistance = o.Find("m_DirLightPCSSMaxSamplingDistance");
dirLightPCSSMinFilterSizeTexels = o.Find("m_DirLightPCSSMinFilterSizeTexels");
dirLightPCSSMinFilterMaxAngularDiameter = o.Find("m_DirLightPCSSMinFilterMaxAngularDiameter");
dirLightPCSSBlockerSearchAngularDiameter = o.Find("m_DirLightPCSSBlockerSearchAngularDiameter");
dirLightPCSSBlockerSamplingClumpExponent = o.Find("m_DirLightPCSSBlockerSamplingClumpExponent");
dirLightPCSSBlockerSampleCount = o.Find("m_DirLightPCSSBlockerSampleCount");
dirLightPCSSFilterSampleCount = o.Find("m_DirLightPCSSFilterSampleCount");
// Celestial Body
diameterOverride = o.Find(x => x.diameterOverride);
diameterMultiplier = o.Find(x => x.diameterMultiplier);
diameterMultiplerMode = o.Find(x => x.diameterMultiplerMode);
distance = o.Find("m_Distance");
surfaceTexture = o.Find(x => x.surfaceTexture);
surfaceTint = o.Find(x => x.surfaceTint);
shadingSource = o.Find(x => x.celestialBodyShadingSource);
sunLightOverride = o.Find(x => x.sunLightOverride);
sunColor = o.Find(x => x.sunColor);
sunIntensity = o.Find(x => x.sunIntensity);
phase = o.Find(x => x.moonPhase);
phaseRotation = o.Find(x => x.moonPhaseRotation);
earthshine = o.Find(x => x.earthshine);
flareSize = o.Find(x => x.flareSize);
flareFalloff = o.Find(x => x.flareFalloff);
flareTint = o.Find(x => x.flareTint);
flareMultiplier = o.Find(x => x.flareMultiplier);
// Moment light
lightAngle = o.Find("m_LightAngle");
kernelSize = o.Find("m_KernelSize");
maxDepthBias = o.Find("m_MaxDepthBias");
// Editor stuff
useOldInspector = o.Find("useOldInspector");
showFeatures = o.Find("featuresFoldout");
useVolumetric = o.Find("useVolumetric");
renderingLayerMask = settings.renderingLayerMask;
// Layers
linkShadowLayers = o.Find("m_LinkShadowLayers");
lightlayersMask = o.Find("m_LightlayersMask");
// Shadow datas:
shadowDimmer = o.Find("m_ShadowDimmer");
volumetricShadowDimmer = o.Find("m_VolumetricShadowDimmer");
shadowFadeDistance = o.Find("m_ShadowFadeDistance");
contactShadows = new SerializedScalableSettingValue(o.Find((HDAdditionalLightData l) => l.useContactShadow));
rayTracedContactShadow = o.Find("m_RayTracedContactShadow");
shadowTint = o.Find("m_ShadowTint");
penumbraTint = o.Find("m_PenumbraTint");
shadowUpdateMode = o.Find("m_ShadowUpdateMode");
shadowAlwaysDrawDynamic = o.Find("m_AlwaysDrawDynamicShadows");
shadowUpdateUponTransformChange = o.Find("m_UpdateShadowOnLightMovement");
shadowResolution = new SerializedScalableSettingValue(o.Find((HDAdditionalLightData l) => l.shadowResolution));
slopeBias = o.Find("m_SlopeBias");
normalBias = o.Find("m_NormalBias");
// emission mesh
areaLightEmissiveMeshCastShadow = o.Find("m_AreaLightEmissiveMeshShadowCastingMode");
areaLightEmissiveMeshMotionVector = o.Find("m_AreaLightEmissiveMeshMotionVectorGenerationMode");
areaLightEmissiveMeshLayer = o.Find("m_AreaLightEmissiveMeshLayer");
}
RefreshEmissiveMeshReference();
lightGameObject = new SerializedObject(serializedObject.targetObjects.Select(ld => ((HDAdditionalLightData)ld).gameObject).ToArray());
lightLayer = lightGameObject.FindProperty("m_Layer");
}
void RefreshEmissiveMeshReference()
{
IEnumerable<MeshRenderer> meshRenderers = serializedObject.targetObjects.Select(ld => ((HDAdditionalLightData)ld).emissiveMeshRenderer).Where(mr => mr != null);
emissiveMeshes = meshRenderers.Select(mr => mr.gameObject).ToArray();
if (meshRenderers.Count() > 0)
{
SerializedObject meshRendererSerializedObject = new SerializedObject(meshRenderers.ToArray());
deportedAreaLightEmissiveMeshCastShadow = meshRendererSerializedObject.FindProperty("m_CastShadows");
deportedAreaLightEmissiveMeshMotionVector = meshRendererSerializedObject.FindProperty("m_MotionVectors");
SerializedObject gameObjectSerializedObject = new SerializedObject(emissiveMeshes);
deportedAreaLightEmissiveMeshLayer = gameObjectSerializedObject.FindProperty("m_Layer");
}
else
deportedAreaLightEmissiveMeshCastShadow = deportedAreaLightEmissiveMeshMotionVector = deportedAreaLightEmissiveMeshLayer = null;
}
public void FetchAreaLightEmissiveMeshComponents()
{
// Only apply display emissive mesh changes or type change as only ones that can happens
// Plus perhaps if we update deportedAreaLightEmissiveMeshMotionVector.serializedObject,
// it can no longuer have target here as refreshed only below
ApplyInternal(withDeportedEmissiveMeshData: false);
foreach (HDAdditionalLightData target in serializedObject.targetObjects)
target.UpdateAreaLightEmissiveMesh();
RefreshEmissiveMeshReference();
Update();
}
public void Update()
{
// Case 1182968
// For some reasons, the is different cache is not updated while we actually have different
// values for shadowResolution.level
// So we force the update here as a workaround
serializedObject.SetIsDifferentCacheDirty();
serializedObject.Update();
settings.Update();
lightGameObject.Update();
if (deportedAreaLightEmissiveMeshMotionVector.IsTargetAlive())
deportedAreaLightEmissiveMeshMotionVector?.serializedObject.Update();
if (deportedAreaLightEmissiveMeshLayer.IsTargetAlive())
deportedAreaLightEmissiveMeshLayer?.serializedObject.Update();
}
void ApplyInternal(bool withDeportedEmissiveMeshData)
{
serializedObject.ApplyModifiedProperties();
settings.ApplyModifiedProperties();
if (withDeportedEmissiveMeshData)
{
if (deportedAreaLightEmissiveMeshMotionVector.IsTargetAlive())
deportedAreaLightEmissiveMeshMotionVector?.serializedObject.ApplyModifiedProperties();
if (deportedAreaLightEmissiveMeshLayer.IsTargetAlive())
deportedAreaLightEmissiveMeshLayer?.serializedObject.ApplyModifiedProperties();
}
}
public void Apply() => ApplyInternal(withDeportedEmissiveMeshData: true);
public bool HasMultipleLightTypes(Editor owner)
{
return owner.serializedObject.FindProperty("m_Type").hasMultipleDifferentValues;
}
}
}