Started project

This commit is contained in:
Caleb Sandford deQuincey
2025-11-14 17:30:41 +00:00
parent 00b55a5b1e
commit 334021d04e
36526 changed files with 4940113 additions and 0 deletions

View File

@@ -0,0 +1,503 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
#if XR_MANAGEMENT_4_0_1_OR_NEWER
using UnityEditor.XR.Management;
#endif
namespace UnityEditor.Rendering.Universal
{
using CED = CoreEditorDrawer<UniversalRenderPipelineSerializedLight>;
internal partial class UniversalRenderPipelineLightUI
{
[URPHelpURL("light-component")]
enum Expandable
{
General = 1 << 0,
Shape = 1 << 1,
Emission = 1 << 2,
Rendering = 1 << 3,
Shadows = 1 << 4,
LightCookie = 1 << 5
}
static readonly ExpandedState<Expandable, Light> k_ExpandedState = new(~-1, "URP");
public static readonly CED.IDrawer Inspector = CED.Group(
CED.Conditional(
(_, __) =>
{
if (SceneView.lastActiveSceneView == null)
return false;
#if UNITY_2019_1_OR_NEWER
var sceneLighting = SceneView.lastActiveSceneView.sceneLighting;
#else
var sceneLighting = SceneView.lastActiveSceneView.m_SceneLighting;
#endif
return !sceneLighting;
},
(_, __) => EditorGUILayout.HelpBox(Styles.DisabledLightWarning.text, MessageType.Warning)),
CED.FoldoutGroup(LightUI.Styles.generalHeader,
Expandable.General,
k_ExpandedState,
DrawGeneralContent),
CED.Conditional(
(serializedLight, editor) => !serializedLight.settings.lightType.hasMultipleDifferentValues && serializedLight.settings.light.type == LightType.Spot,
CED.FoldoutGroup(LightUI.Styles.shapeHeader, Expandable.Shape, k_ExpandedState, DrawSpotShapeContent)),
CED.Conditional(
(serializedLight, editor) =>
{
if (serializedLight.settings.lightType.hasMultipleDifferentValues)
return false;
var lightType = serializedLight.settings.light.type;
return lightType == LightType.Rectangle || lightType == LightType.Disc;
},
CED.FoldoutGroup(LightUI.Styles.shapeHeader, Expandable.Shape, k_ExpandedState, DrawAreaShapeContent)),
CED.FoldoutGroup(LightUI.Styles.emissionHeader,
Expandable.Emission,
k_ExpandedState,
CED.Group(
LightUI.DrawColor,
DrawEmissionContent)),
CED.FoldoutGroup(LightUI.Styles.renderingHeader,
Expandable.Rendering,
k_ExpandedState,
DrawRenderingContent),
CED.FoldoutGroup(LightUI.Styles.shadowHeader,
Expandable.Shadows,
k_ExpandedState,
DrawShadowsContent)
);
static Func<int> s_SetGizmosDirty = SetGizmosDirty();
static Func<int> SetGizmosDirty()
{
var type = Type.GetType("UnityEditor.AnnotationUtility,UnityEditor");
var method = type.GetMethod("SetGizmosDirty", BindingFlags.Static | BindingFlags.NonPublic);
var lambda = Expression.Lambda<Func<int>>(Expression.Call(method));
return lambda.Compile();
}
static Action<GUIContent, SerializedProperty, LightEditor.Settings> k_SliderWithTexture = GetSliderWithTexture();
static Action<GUIContent, SerializedProperty, LightEditor.Settings> GetSliderWithTexture()
{
//quicker than standard reflection as it is compiled
var paramLabel = Expression.Parameter(typeof(GUIContent), "label");
var paramProperty = Expression.Parameter(typeof(SerializedProperty), "property");
var paramSettings = Expression.Parameter(typeof(LightEditor.Settings), "settings");
System.Reflection.MethodInfo sliderWithTextureInfo = typeof(EditorGUILayout)
.GetMethod(
"SliderWithTexture",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static,
null,
System.Reflection.CallingConventions.Any,
new[] { typeof(GUIContent), typeof(SerializedProperty), typeof(float), typeof(float), typeof(float), typeof(Texture2D), typeof(GUILayoutOption[]) },
null);
var sliderWithTextureCall = Expression.Call(
sliderWithTextureInfo,
paramLabel,
paramProperty,
Expression.Constant((float)typeof(LightEditor.Settings).GetField("kMinKelvin", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetRawConstantValue()),
Expression.Constant((float)typeof(LightEditor.Settings).GetField("kMaxKelvin", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetRawConstantValue()),
Expression.Constant((float)typeof(LightEditor.Settings).GetField("kSliderPower", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetRawConstantValue()),
Expression.Field(paramSettings, typeof(LightEditor.Settings).GetField("m_KelvinGradientTexture", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)),
Expression.Constant(null, typeof(GUILayoutOption[])));
var lambda = Expression.Lambda<System.Action<GUIContent, SerializedProperty, LightEditor.Settings>>(sliderWithTextureCall, paramLabel, paramProperty, paramSettings);
return lambda.Compile();
}
static void DrawGeneralContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
DrawGeneralContentInternal(serializedLight, owner, isInPreset: false);
}
static void DrawGeneralContentPreset(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
DrawGeneralContentInternal(serializedLight, owner, isInPreset: true);
}
static void DrawGeneralContentInternal(UniversalRenderPipelineSerializedLight serializedLight, Editor owner, bool isInPreset)
{
// To the user, we will only display it as a area light, but under the hood, we have Rectangle and Disc. This is not to confuse people
// who still use our legacy light inspector.
int selectedLightType = serializedLight.settings.lightType.intValue;
// Handle all lights that are not in the default set
if (!Styles.LightTypeValues.Contains(serializedLight.settings.lightType.intValue))
{
if (serializedLight.settings.lightType.intValue == (int)LightType.Disc)
{
selectedLightType = (int)LightType.Rectangle;
}
}
var rect = EditorGUILayout.GetControlRect();
EditorGUI.BeginProperty(rect, Styles.Type, serializedLight.settings.lightType);
EditorGUI.BeginChangeCheck();
int type;
if (Styles.LightTypeValues.Contains(selectedLightType))
{
// ^ The currently selected light type is supported in the
// current pipeline.
type = EditorGUI.IntPopup(rect, Styles.Type, selectedLightType, Styles.LightTypeTitles, Styles.LightTypeValues);
}
else
{
// ^ The currently selected light type is not supported in
// the current pipeline. Add it to the dropdown, since it
// would show up as a blank entry.
string currentTitle = ((LightType)selectedLightType).ToString();
GUIContent[] titles = Styles.LightTypeTitles.Append(EditorGUIUtility.TrTextContent(currentTitle)).ToArray();
int[] values = Styles.LightTypeValues.Append(selectedLightType).ToArray();
type = EditorGUI.IntPopup(rect, Styles.Type, selectedLightType, titles, values);
}
if (EditorGUI.EndChangeCheck())
{
s_SetGizmosDirty();
serializedLight.settings.lightType.intValue = type;
}
EditorGUI.EndProperty();
if (!Styles.LightTypeValues.Contains(type))
{
EditorGUILayout.HelpBox(
"This light type is not supported in the current active render pipeline. Change the light type or the active Render Pipeline to use this light.",
MessageType.Info
);
}
Light light = serializedLight.settings.light;
var lightType = light.type;
if (LightType.Directional != lightType && light == RenderSettings.sun)
{
EditorGUILayout.HelpBox(Styles.SunSourceWarning.text, MessageType.Warning);
}
if (!serializedLight.settings.lightType.hasMultipleDifferentValues)
{
using (new EditorGUI.DisabledScope(serializedLight.settings.isAreaLightType))
serializedLight.settings.DrawLightmapping();
if (serializedLight.settings.isAreaLightType && serializedLight.settings.lightmapping.intValue != (int)LightmapBakeType.Baked)
{
serializedLight.settings.lightmapping.intValue = (int)LightmapBakeType.Baked;
serializedLight.Apply();
}
}
}
internal static void SyncLightAndShadowLayers(UniversalRenderPipelineSerializedLight serializedLight, SerializedProperty serialized)
{
// If we're not in decoupled mode for light layers, we sync light with shadow layers.
// In mixed state, it makes sense to do it only on Light that links the mode.
foreach (var lightTarget in serializedLight.serializedObject.targetObjects)
{
var additionData = (lightTarget as Component).gameObject.GetComponent<UniversalAdditionalLightData>();
if (additionData.customShadowLayers)
continue;
Light target = lightTarget as Light;
if (target.renderingLayerMask != serialized.intValue)
target.renderingLayerMask = serialized.intValue;
}
}
static void DrawSpotShapeContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
serializedLight.settings.DrawInnerAndOuterSpotAngle();
}
static void DrawAreaShapeContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
int selectedShape = serializedLight.settings.isAreaLightType ? serializedLight.settings.lightType.intValue : 0;
// Handle all lights that are not in the default set
if (!Styles.LightTypeValues.Contains(serializedLight.settings.lightType.intValue))
{
if (serializedLight.settings.lightType.intValue == (int)LightType.Disc)
{
selectedShape = (int)LightType.Disc;
}
}
var rect = EditorGUILayout.GetControlRect();
EditorGUI.BeginProperty(rect, Styles.AreaLightShapeContent, serializedLight.settings.lightType);
EditorGUI.BeginChangeCheck();
int shape = EditorGUI.IntPopup(rect, Styles.AreaLightShapeContent, selectedShape, Styles.AreaLightShapeTitles, Styles.AreaLightShapeValues);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(serializedLight.settings.light, "Adjust Light Shape");
serializedLight.settings.lightType.intValue = shape;
}
EditorGUI.EndProperty();
using (new EditorGUI.IndentLevelScope())
serializedLight.settings.DrawArea();
}
static void DrawEmissionContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
serializedLight.settings.DrawIntensity();
serializedLight.settings.DrawBounceIntensity();
if (!serializedLight.settings.lightType.hasMultipleDifferentValues)
{
var lightType = serializedLight.settings.light.type;
if (lightType != LightType.Directional)
{
#if UNITY_2020_1_OR_NEWER
serializedLight.settings.DrawRange();
#else
serializedLight.settings.DrawRange(false);
#endif
}
}
DrawLightCookieContent(serializedLight, owner);
}
static void DrawRenderingContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
if (serializedLight.settings.light.type != LightType.Rectangle &&
!serializedLight.settings.isCompletelyBaked)
{
EditorGUI.BeginChangeCheck();
GUI.enabled = UniversalRenderPipeline.asset.useRenderingLayers;
EditorGUILayout.PropertyField(serializedLight.renderingLayers, UniversalRenderPipeline.asset.useRenderingLayers ? Styles.RenderingLayers : Styles.RenderingLayersDisabled);
GUI.enabled = true;
if (EditorGUI.EndChangeCheck())
{
if (!serializedLight.customShadowLayers.boolValue)
SyncLightAndShadowLayers(serializedLight, serializedLight.renderingLayers);
}
}
EditorGUILayout.PropertyField(serializedLight.settings.cullingMask, Styles.CullingMask);
if (serializedLight.settings.cullingMask.intValue != -1)
{
EditorGUILayout.HelpBox(Styles.CullingMaskWarning.text, MessageType.Info);
}
}
static void DrawShadowsContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
if (serializedLight.settings.lightType.hasMultipleDifferentValues)
{
EditorGUILayout.HelpBox("Cannot multi edit shadows from different light types.", MessageType.Info);
return;
}
serializedLight.settings.DrawShadowsType();
if (serializedLight.settings.shadowsType.hasMultipleDifferentValues)
{
EditorGUILayout.HelpBox("Cannot multi edit different shadow types", MessageType.Info);
return;
}
if (serializedLight.settings.light.shadows == LightShadows.None)
return;
var lightType = serializedLight.settings.light.type;
using (new EditorGUI.IndentLevelScope())
{
if (serializedLight.settings.isBakedOrMixed)
{
switch (lightType)
{
// Baked Shadow radius
case LightType.Point:
case LightType.Spot:
serializedLight.settings.DrawBakedShadowRadius();
break;
case LightType.Directional:
serializedLight.settings.DrawBakedShadowAngle();
break;
}
}
if (lightType != LightType.Rectangle && !serializedLight.settings.isCompletelyBaked)
{
EditorGUILayout.LabelField(Styles.ShadowRealtimeSettings, EditorStyles.boldLabel);
using (new EditorGUI.IndentLevelScope())
{
// Resolution
if (lightType == LightType.Point || lightType == LightType.Spot)
DrawShadowsResolutionGUI(serializedLight);
EditorGUILayout.Slider(serializedLight.settings.shadowsStrength, 0f, 1f, Styles.ShadowStrength);
// Bias
DrawAdditionalShadowData(serializedLight, owner);
// this min bound should match the calculation in SharedLightData::GetNearPlaneMinBound()
float nearPlaneMinBound = Mathf.Min(0.01f * serializedLight.settings.range.floatValue, 0.1f);
EditorGUILayout.Slider(serializedLight.settings.shadowsNearPlane, nearPlaneMinBound, 10.0f, Styles.ShadowNearPlane);
var isHololens = false;
var isQuest = false;
#if XR_MANAGEMENT_4_0_1_OR_NEWER
var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
var buildTargetSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup);
if (buildTargetSettings != null && buildTargetSettings.AssignedSettings != null && buildTargetSettings.AssignedSettings.activeLoaders.Count > 0)
{
isHololens = buildTargetGroup == BuildTargetGroup.WSA;
isQuest = buildTargetGroup == BuildTargetGroup.Android;
}
#endif
// Soft Shadow Quality
if (serializedLight.settings.light.shadows == LightShadows.Soft)
EditorGUILayout.PropertyField(serializedLight.softShadowQualityProp, Styles.SoftShadowQuality);
if (isHololens || isQuest)
{
EditorGUILayout.HelpBox(
"Per-light soft shadow quality level is not supported on HoloLens and Oculus platforms. Use the Soft Shadow Quality setting in the URP Asset instead",
MessageType.Warning
);
}
}
if (UniversalRenderPipeline.asset.useRenderingLayers)
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedLight.customShadowLayers, Styles.customShadowLayers);
if (serializedLight.customShadowLayers.boolValue)
{
using (new EditorGUI.IndentLevelScope())
EditorGUILayout.PropertyField(serializedLight.shadowRenderingLayers, Styles.ShadowLayer);
}
// Undo the changes in the light component because the SyncLightAndShadowLayers will change the value automatically when link is ticked
if (EditorGUI.EndChangeCheck())
{
if (serializedLight.customShadowLayers.boolValue)
{
serializedLight.settings.light.renderingLayerMask = serializedLight.shadowRenderingLayers.intValue;
}
else
{
serializedLight.serializedAdditionalDataObject.ApplyModifiedProperties(); // we need to push above modification the modification on object as it is used to sync
SyncLightAndShadowLayers(serializedLight, serializedLight.renderingLayers);
}
}
}
}
}
if (!UnityEditor.Lightmapping.bakedGI && !serializedLight.settings.lightmapping.hasMultipleDifferentValues && serializedLight.settings.isBakedOrMixed)
EditorGUILayout.HelpBox(Styles.BakingWarning.text, MessageType.Warning);
}
static void DrawAdditionalShadowData(UniversalRenderPipelineSerializedLight serializedLight, Editor editor)
{
// 0: Custom bias - 1: Bias values defined in Pipeline settings
int selectedUseAdditionalData = serializedLight.additionalLightData.usePipelineSettings ? 1 : 0;
Rect r = EditorGUILayout.GetControlRect(true);
EditorGUI.BeginProperty(r, Styles.shadowBias, serializedLight.useAdditionalDataProp);
{
using (var checkScope = new EditorGUI.ChangeCheckScope())
{
selectedUseAdditionalData = EditorGUI.IntPopup(r, Styles.shadowBias, selectedUseAdditionalData, Styles.displayedDefaultOptions, Styles.optionDefaultValues);
if (checkScope.changed)
{
Undo.RecordObjects(serializedLight.lightsAdditionalData, "Modified light additional data");
foreach (var additionData in serializedLight.lightsAdditionalData)
additionData.usePipelineSettings = selectedUseAdditionalData != 0;
serializedLight.Apply();
(editor as UniversalRenderPipelineLightEditor)?.ReconstructReferenceToAdditionalDataSO();
}
}
}
EditorGUI.EndProperty();
if (!serializedLight.useAdditionalDataProp.hasMultipleDifferentValues)
{
if (selectedUseAdditionalData != 1) // Custom Bias
{
using (new EditorGUI.IndentLevelScope())
{
using (var checkScope = new EditorGUI.ChangeCheckScope())
{
EditorGUILayout.Slider(serializedLight.settings.shadowsBias, 0f, 10f, Styles.ShadowDepthBias);
EditorGUILayout.Slider(serializedLight.settings.shadowsNormalBias, 0f, 10f, Styles.ShadowNormalBias);
if (checkScope.changed)
serializedLight.Apply();
}
}
}
}
}
static void DrawShadowsResolutionGUI(UniversalRenderPipelineSerializedLight serializedLight)
{
int shadowResolutionTier = serializedLight.additionalLightData.additionalLightsShadowResolutionTier;
using (new EditorGUILayout.HorizontalScope())
{
using (var checkScope = new EditorGUI.ChangeCheckScope())
{
Rect r = EditorGUILayout.GetControlRect(true);
r.width += 30;
shadowResolutionTier = EditorGUI.IntPopup(r, Styles.ShadowResolution, shadowResolutionTier, Styles.ShadowResolutionDefaultOptions, Styles.ShadowResolutionDefaultValues);
if (shadowResolutionTier == UniversalAdditionalLightData.AdditionalLightsShadowResolutionTierCustom)
{
// show the custom value field GUI.
var newResolution = EditorGUILayout.IntField(serializedLight.settings.shadowsResolution.intValue, GUILayout.ExpandWidth(false));
serializedLight.settings.shadowsResolution.intValue = Mathf.Max(UniversalAdditionalLightData.AdditionalLightsShadowMinimumResolution, Mathf.NextPowerOfTwo(newResolution));
}
else
{
if (GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset urpAsset)
EditorGUILayout.LabelField($"{urpAsset.GetAdditionalLightsShadowResolution(shadowResolutionTier)} ({urpAsset.name})", GUILayout.ExpandWidth(false));
}
if (checkScope.changed)
{
serializedLight.additionalLightsShadowResolutionTierProp.intValue = shadowResolutionTier;
serializedLight.Apply();
}
}
}
EditorGUILayout.HelpBox(Styles.ShadowInfo.text, MessageType.Info);
}
static void DrawLightCookieContent(UniversalRenderPipelineSerializedLight serializedLight, Editor owner)
{
var settings = serializedLight.settings;
if (settings.lightType.hasMultipleDifferentValues)
{
EditorGUILayout.HelpBox("Cannot multi edit light cookies from different light types.", MessageType.Info);
return;
}
settings.DrawCookie();
// Draw 2D cookie size for directional lights
bool isDirectionalLight = settings.light.type == LightType.Directional;
if (isDirectionalLight)
{
if (settings.cookie != null)
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedLight.lightCookieSizeProp, Styles.LightCookieSize);
EditorGUILayout.PropertyField(serializedLight.lightCookieOffsetProp, Styles.LightCookieOffset);
if (EditorGUI.EndChangeCheck())
Experimental.Lightmapping.SetLightDirty((UnityEngine.Light)serializedLight.serializedObject.targetObject);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a8cdd2e9d2eeaf4e956e5592d5d0278
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
using CED = CoreEditorDrawer<UniversalRenderPipelineSerializedLight>;
partial class UniversalRenderPipelineLightUI
{
static readonly ExpandedState<Expandable, Light> k_ExpandedStatePreset = new(0, "URP-preset");
public static readonly CED.IDrawer PresetInspector = CED.Group(
CED.Group((serialized, owner) =>
EditorGUILayout.HelpBox(LightUI.Styles.unsupportedPresetPropertiesMessage, MessageType.Info)),
CED.Group((serialized, owner) => EditorGUILayout.Space()),
CED.FoldoutGroup(LightUI.Styles.generalHeader,
Expandable.General,
k_ExpandedStatePreset,
DrawGeneralContentPreset),
CED.FoldoutGroup(LightUI.Styles.emissionHeader,
Expandable.Emission,
k_ExpandedStatePreset,
CED.Group(
LightUI.DrawColor,
DrawEmissionContent))
);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5eb1c80a4ef86db4aa019371e819c08f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
partial class UniversalRenderPipelineLightUI
{
private static class Styles
{
public static readonly GUIContent Type = EditorGUIUtility.TrTextContent("Type", "Specifies the current type of light. Possible types are Directional, Spot, Point, and Area lights.");
public static readonly GUIContent AreaLightShapeContent = EditorGUIUtility.TrTextContent("Shape", "Specifies the shape of the Area light. Possible types are Rectangle and Disc.");
public static readonly GUIContent[] LightTypeTitles = { EditorGUIUtility.TrTextContent("Spot"), EditorGUIUtility.TrTextContent("Directional"), EditorGUIUtility.TrTextContent("Point"), EditorGUIUtility.TrTextContent("Area (baked only)") };
public static readonly int[] LightTypeValues = { (int)LightType.Spot, (int)LightType.Directional, (int)LightType.Point, (int)LightType.Rectangle };
public static readonly GUIContent[] AreaLightShapeTitles = { EditorGUIUtility.TrTextContent("Rectangle"), EditorGUIUtility.TrTextContent("Disc") };
public static readonly int[] AreaLightShapeValues = { (int)LightType.Rectangle, (int)LightType.Disc };
public static readonly GUIContent SpotAngle = EditorGUIUtility.TrTextContent("Spot Angle", "Controls the angle in degrees at the base of a Spot light's cone.");
public static readonly GUIContent BakingWarning = EditorGUIUtility.TrTextContent("Light mode is currently overridden to Realtime mode. Enable Baked Global Illumination to use Mixed or Baked light modes.");
public static readonly GUIContent DisabledLightWarning = EditorGUIUtility.TrTextContent("Lighting has been disabled in at least one Scene view. Any changes applied to lights in the Scene will not be updated in these views until Lighting has been enabled again.");
public static readonly GUIContent SunSourceWarning = EditorGUIUtility.TrTextContent("This light is set as the current Sun Source, which requires a directional light. Go to the Lighting Window's Environment settings to edit the Sun Source.");
public static readonly GUIContent CullingMask = EditorGUIUtility.TrTextContent("Culling Mask", "Specifies which lights are culled per camera. To control exclude certain lights affecting certain objects, use Rendering Layers instead, which is supported across all rendering paths.");
public static readonly GUIContent CullingMaskWarning = EditorGUIUtility.TrTextContent("Culling Mask should be used to control which lights are culled per camera. If you want to exclude certain lights from affecting certain objects, use Rendering Layers on the Light, and Rendering Layer Mask on the Mesh Renderer.");
public static readonly GUIContent ShadowRealtimeSettings = EditorGUIUtility.TrTextContent("Realtime Shadows", "Settings for realtime direct shadows.");
public static readonly GUIContent ShadowStrength = EditorGUIUtility.TrTextContent("Strength", "Controls how dark the shadows cast by the light will be.");
public static readonly GUIContent ShadowNearPlane = EditorGUIUtility.TrTextContent("Near Plane", "Controls the value for the near clip plane when rendering shadows. Currently clamped to 0.1 units or 1% of the lights range property, whichever is lower.");
public static readonly GUIContent ShadowNormalBias = EditorGUIUtility.TrTextContent("Normal", "Determines the bias this Light applies along the normal of surfaces it illuminates. This is ignored for point lights.");
public static readonly GUIContent ShadowDepthBias = EditorGUIUtility.TrTextContent("Depth", "Determines the bias at which shadows are pushed away from the shadow-casting Game Object along the line from the Light.");
public static readonly GUIContent ShadowInfo = EditorGUIUtility.TrTextContent("Unity might reduce the Light's shadow resolution to ensure that shadow maps fit in the shadow atlas. Consider this when selecting the the size of the shadow atlas, the shadow resolution of Lights, the number of Lights in your scene and whether you use soft shadows.");
// Resolution (default or custom)
public static readonly GUIContent ShadowResolution = EditorGUIUtility.TrTextContent("Resolution", $"Sets the rendered resolution of the shadow maps. A higher resolution increases the fidelity of shadows at the cost of GPU performance and memory usage. Rounded to the next power of two, and clamped to be at least {UniversalAdditionalLightData.AdditionalLightsShadowMinimumResolution}.");
public static readonly int[] ShadowResolutionDefaultValues =
{
UniversalAdditionalLightData.AdditionalLightsShadowResolutionTierCustom,
UniversalAdditionalLightData.AdditionalLightsShadowResolutionTierLow,
UniversalAdditionalLightData.AdditionalLightsShadowResolutionTierMedium,
UniversalAdditionalLightData.AdditionalLightsShadowResolutionTierHigh
};
public static readonly GUIContent[] ShadowResolutionDefaultOptions =
{
EditorGUIUtility.TrTextContent("Custom"),
UniversalRenderPipelineAssetUI.Styles.additionalLightsShadowResolutionTierNames[0],
UniversalRenderPipelineAssetUI.Styles.additionalLightsShadowResolutionTierNames[1],
UniversalRenderPipelineAssetUI.Styles.additionalLightsShadowResolutionTierNames[2],
};
public static GUIContent SoftShadowQuality = EditorGUIUtility.TrTextContent("Soft Shadows Quality", "Controls the filtering quality of soft shadows. Higher quality has lower performance.");
// Bias (default or custom)
public static GUIContent shadowBias = EditorGUIUtility.TrTextContent("Bias", "Select if the Bias should use the settings from the Pipeline Asset or Custom settings.");
public static int[] optionDefaultValues = { 0, 1 };
public static GUIContent[] displayedDefaultOptions =
{
EditorGUIUtility.TrTextContent("Custom"),
EditorGUIUtility.TrTextContent("Use settings from Render Pipeline Asset")
};
public static readonly GUIContent customShadowLayers = EditorGUIUtility.TrTextContent("Custom Shadow Layers", "When enabled, you can use the Layer property below to specify the layers for shadows seperately to lighting. When disabled, the Light Layer property in the General section specifies the layers for both lighting and for shadows.");
public static readonly GUIContent ShadowLayer = EditorGUIUtility.TrTextContent("Layer", "Specifies the light layer to use for shadows.");
public static readonly GUIContent LightCookieSize = EditorGUIUtility.TrTextContent("Cookie Size", "Controls the size of the cookie mask currently assigned to the light.");
public static readonly GUIContent LightCookieOffset = EditorGUIUtility.TrTextContent("Cookie Offset", "Controls the offset of the cookie mask currently assigned to the light.");
/// <summary>Title with "Rendering Layer"</summary>
public static readonly GUIContent RenderingLayers = EditorGUIUtility.TrTextContent("Rendering Layers", "Select the Rendering Layers that the Light affects. This Light affects objects where at least one Rendering Layer value matches.");
public static readonly GUIContent RenderingLayersDisabled = EditorGUIUtility.TrTextContent("Rendering Layers", "Rendering Layers are disabled because they have a small GPU performance cost. To enable this setting, go to the active Universal Render Pipeline Asset, and enable Lighting -> Use Rendering Layers.");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f447f3361e81db4cb24d35be94da7c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal
{
internal class UniversalRenderPipelineSerializedLight : ISerializedLight
{
/// <summary>The base settings of the light</summary>
public LightEditor.Settings settings { get; }
/// <summary>The light serialized</summary>
public SerializedObject serializedObject { get; }
/// <summary>The additional light data serialized</summary>
public SerializedObject serializedAdditionalDataObject { get; private set; }
public UniversalAdditionalLightData additionalLightData => lightsAdditionalData[0];
public UniversalAdditionalLightData[] lightsAdditionalData { get; private set; }
// Common SRP's Lights properties
public SerializedProperty intensity { get; }
// URP Light Properties
public SerializedProperty useAdditionalDataProp { get; } // Does light use shadow bias settings defined in UniversalRP asset file?
public SerializedProperty additionalLightsShadowResolutionTierProp { get; } // Index of the AdditionalLights ShadowResolution Tier
public SerializedProperty softShadowQualityProp { get; } // Per light soft shadow filtering quality.
public SerializedProperty lightCookieSizeProp { get; } // Multi dimensional light cookie size replacing `cookieSize` in legacy light.
public SerializedProperty lightCookieOffsetProp { get; } // Multi dimensional light cookie offset.
// Light layers related
public SerializedProperty renderingLayers { get; }
public SerializedProperty customShadowLayers { get; }
public SerializedProperty shadowRenderingLayers { get; }
/// <summary>Method that updates the <see cref="SerializedObject"/> of the Light and the Additional Light Data</summary>
public void Update()
{
serializedObject.Update();
serializedAdditionalDataObject.Update();
settings.Update();
}
/// <summary>Method that applies the modified properties the <see cref="SerializedObject"/> of the Light and the Light Camera Data</summary>
public void Apply()
{
serializedObject.ApplyModifiedProperties();
serializedAdditionalDataObject.ApplyModifiedProperties();
settings.ApplyModifiedProperties();
}
/// <summary>Constructor</summary>
/// <param name="serializedObject"><see cref="SerializedObject"/> with the light</param>
/// <param name="settings"><see cref="LightEditor.Settings"/>with the settings</param>
public UniversalRenderPipelineSerializedLight(SerializedObject serializedObject, LightEditor.Settings settings)
{
this.settings = settings;
settings.OnEnable();
this.serializedObject = serializedObject;
lightsAdditionalData = CoreEditorUtils
.GetAdditionalData<UniversalAdditionalLightData>(serializedObject.targetObjects);
serializedAdditionalDataObject = new SerializedObject(lightsAdditionalData);
intensity = serializedObject.FindProperty("m_Intensity");
useAdditionalDataProp = serializedAdditionalDataObject.FindProperty("m_UsePipelineSettings");
additionalLightsShadowResolutionTierProp = serializedAdditionalDataObject.FindProperty("m_AdditionalLightsShadowResolutionTier");
softShadowQualityProp = serializedAdditionalDataObject.FindProperty("m_SoftShadowQuality");
lightCookieSizeProp = serializedAdditionalDataObject.FindProperty("m_LightCookieSize");
lightCookieOffsetProp = serializedAdditionalDataObject.FindProperty("m_LightCookieOffset");
renderingLayers = serializedAdditionalDataObject.FindProperty("m_RenderingLayersMask");
customShadowLayers = serializedAdditionalDataObject.FindProperty("m_CustomShadowLayers");
shadowRenderingLayers = serializedAdditionalDataObject.FindProperty("m_ShadowRenderingLayersMask");
settings.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ed11570e89eec24f9021d93325db0d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: