Skip to content

Commit 78b9591

Browse files
Merge pull request #8289 from Unity-Technologies/internal/6000.5/staging
Internal/6000.5/staging
2 parents 8d3c2e2 + d23db76 commit 78b9591

81 files changed

Lines changed: 8195 additions & 392 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ internal static string GetBakingMode(ProbeVolumeBakingSet bakingSet)
308308

309309
internal static void SetBakingMode(ProbeVolumeBakingSet bakingSet, string mode)
310310
{
311+
Undo.RecordObject(bakingSet, "Change Baking Mode");
311312
bakingSet.singleSceneMode = (mode == "Single Scene");
312313
}
313314

@@ -318,6 +319,7 @@ internal static int GetSkyOcclusionBakingSamples(ProbeVolumeBakingSet bakingSet)
318319

319320
internal static void SetSkyOcclusionBakingSamples(ProbeVolumeBakingSet bakingSet, int samples)
320321
{
322+
Undo.RecordObject(bakingSet, "Change Occlusion Baking");
321323
bakingSet.skyOcclusionBakingSamples = samples;
322324
}
323325

@@ -334,6 +336,7 @@ internal static void SetVolumeMode(GameObject go, string mode)
334336
if (!go.TryGetComponent<Volume>(out var volume))
335337
return;
336338

339+
Undo.RecordObject(volume, "Change Volume Mode");
337340
volume.isGlobal = (mode == "Global");
338341
}
339342

@@ -350,6 +353,7 @@ internal static void SetVolumeProfile(GameObject go, VolumeProfile profile)
350353
if (!go.TryGetComponent<Volume>(out var volume))
351354
return;
352355

356+
Undo.RecordObject(volume, "Change Volume Profile");
353357
volume.sharedProfile = profile;
354358
}
355359

@@ -368,6 +372,7 @@ internal static void SetLightShape(GameObject go, LightType value)
368372

369373
if (IsLightShapeApplicable(value))
370374
{
375+
Undo.RecordObject(light, "Change light Shape");
371376
light.type = value;
372377
}
373378
}

Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,41 @@ public CameraSelector()
10401040
private Camera[] m_CamerasArray;
10411041
private List<Camera> m_Cameras = new List<Camera>();
10421042

1043+
#if ENABLE_RENDERING_DEBUGGER_UI
1044+
/// <inheritdoc/>
1045+
protected override VisualElement Create()
1046+
{
1047+
var objectPopUpField = base.Create() as UIElements.PopupField<UnityEngine.Object>;
1048+
1049+
if (objectPopUpField == null)
1050+
return new Label("Error creating CameraSelector field");
1051+
1052+
objectPopUpField.choices ??= new List<UnityEngine.Object>() { null };
1053+
1054+
// Refresh the dropdown choices to keep it in sync with available cameras in the scene.
1055+
// NOTE: If the currently selected camera is deleted, PopupField handles it internally,
1056+
// so we only need to maintain the available choices list.
1057+
this.ScheduleTracked(objectPopUpField, () => objectPopUpField.schedule.Execute(() =>
1058+
{
1059+
// Using ListPool and SequenceEqual to avoid unnecessary allocations and UI updates
1060+
using (UnityEngine.Pool.ListPool<UnityEngine.Object>.Get(out var tmp))
1061+
{
1062+
tmp.Add(null);
1063+
tmp.AddRange(getObjects());
1064+
1065+
if (!tmp.SequenceEqual(objectPopUpField.choices))
1066+
{
1067+
objectPopUpField.choices.Clear();
1068+
objectPopUpField.choices.AddRange(tmp);
1069+
}
1070+
}
1071+
1072+
}).Every(500));
1073+
1074+
return objectPopUpField;
1075+
}
1076+
#endif
1077+
10431078
IEnumerable<Camera> cameras
10441079
{
10451080
get

Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,22 +308,19 @@ internal VisualElement ToVisualElement(Context context)
308308
m_Context = context;
309309
m_VisualElement = Create();
310310

311-
//Debug.Log($"ToVisualElement for {queryPath}");
312-
313311
if (m_VisualElement == null)
314312
{
315313
Debug.LogWarning($"Unable to create a Visual Element for type {GetType()}");
316314
return null;
317315
}
318316
m_VisualElement.AddToClassList("unity-inspector-element");
319-
317+
m_VisualElement.name = displayName;
320318

321319
#if UNITY_EDITOR
322320
// Support for legacy state handling
323321
if (this is ISupportsLegacyStateHandling legacyStateWidget)
324322
{
325323
m_RequiresLegacyStateHandling = legacyStateWidget.RequiresLegacyStateHandling();
326-
//Debug.Log($"LegacyState: {m_RequiresLegacyStateHandling} ({queryPath})");
327324
}
328325
#endif
329326

Packages/com.unity.render-pipelines.core/Runtime/Debugging/RuntimeDebugWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void OnDestroy()
139139

140140
// Need to unregister here as well because when the UI is closed and reopened, it is a different object so the member
141141
// function will be a different object and the Unregister call in RecreateGUI does nothing.
142-
m_PanelRootElement.UnregisterCallback<NavigationMoveEvent>(ConvertNavigationMoveEvents, TrickleDown.TrickleDown);
142+
m_PanelRootElement?.UnregisterCallback<NavigationMoveEvent>(ConvertNavigationMoveEvents, TrickleDown.TrickleDown);
143143
}
144144

145145
DebugManager.instance.displayRuntimeUI = false;

Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,32 +1845,48 @@ public static IEnumerable<T> LoadAllAssets<T>(string extension = "asset", bool a
18451845
}
18461846
}
18471847

1848+
const char k_DirectorySeparatorChar = '/';
1849+
18481850
/// <summary>
18491851
/// Create any missing folders in the file path given.
18501852
/// </summary>
1851-
/// <param name="filePath">File or folder (ending with '/') path to ensure existence of each subfolder in. </param>
1853+
/// <param name="filePath">File or folder (ending with '/') path to ensure existence of each subfolder in.</param>
18521854
public static void EnsureFolderTreeInAssetFilePath(string filePath)
18531855
{
1854-
var path = filePath.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar);
1855-
if (!path.StartsWith("Assets" + Path.DirectorySeparatorChar, StringComparison.CurrentCultureIgnoreCase))
1856-
throw new ArgumentException($"Path should start with \"Assets/\". Got {filePath}.", filePath);
1856+
if (string.IsNullOrEmpty(filePath))
1857+
return;
1858+
1859+
// Normalize to forward slashes (Unity standard)
1860+
var path = filePath.Replace('\\', k_DirectorySeparatorChar);
1861+
1862+
if (!path.StartsWith("Assets/", StringComparison.Ordinal))
1863+
throw new ArgumentException($"Path should start with \"Assets/\". Got {filePath}.", nameof(filePath));
18571864

18581865
var folderPath = Path.GetDirectoryName(path);
18591866

1860-
if (!UnityEditor.AssetDatabase.IsValidFolder(folderPath))
1867+
if (string.IsNullOrEmpty(folderPath))
1868+
return;
1869+
1870+
// GetDirectoryName may reintroduce backslashes on Windows
1871+
folderPath = folderPath.Replace('\\', k_DirectorySeparatorChar);
1872+
1873+
// Early exit if folder already exists
1874+
if (AssetDatabase.IsValidFolder(folderPath))
1875+
return;
1876+
1877+
var folderNames = folderPath.Split(k_DirectorySeparatorChar);
1878+
string currentPath = "Assets";
1879+
1880+
for (int i = 1; i < folderNames.Length; ++i)
18611881
{
1862-
var folderNames = folderPath.Split(Path.DirectorySeparatorChar);
1863-
string rootPath = "";
1864-
foreach (var folderName in folderNames)
1865-
{
1866-
var newPath = rootPath + folderName;
1867-
if (!UnityEditor.AssetDatabase.IsValidFolder(newPath))
1868-
UnityEditor.AssetDatabase.CreateFolder(rootPath.TrimEnd(Path.DirectorySeparatorChar), folderName);
1869-
rootPath = newPath + Path.DirectorySeparatorChar;
1870-
}
1882+
string nextPath = currentPath + k_DirectorySeparatorChar + folderNames[i];
1883+
if (!UnityEditor.AssetDatabase.IsValidFolder(nextPath))
1884+
UnityEditor.AssetDatabase.CreateFolder(currentPath, folderNames[i]);
1885+
currentPath = nextPath;
18711886
}
18721887
}
18731888

1889+
18741890
/// <summary>
18751891
/// Returns the icon for the given type if it has an IconAttribute.
18761892
/// </summary>

Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -328,25 +328,6 @@ internal void SetOverridesTo(IEnumerable<VolumeParameter> enumerable, bool state
328328
}
329329
}
330330

331-
/// <summary>
332-
/// A custom hashing function that Unity uses to compare the state of parameters.
333-
/// </summary>
334-
/// <returns>A computed hash code for the current instance.</returns>
335-
public override int GetHashCode()
336-
{
337-
unchecked
338-
{
339-
//return parameters.Aggregate(17, (i, p) => i * 23 + p.GetHash());
340-
341-
int hash = 17;
342-
343-
for (int i = 0; i < parameterList.Length; i++)
344-
hash = hash * 23 + parameterList[i].GetHashCode();
345-
346-
return hash;
347-
}
348-
}
349-
350331
/// <summary>
351332
/// Returns true if any of the volume properites has been overridden.
352333
/// </summary>

Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,16 +272,14 @@ public void Initialize(VolumeProfile globalDefaultVolumeProfile = null, VolumePr
272272
void InitializeBaseTypesArray(VolumeProfile globalDefaultVolumeProfile = null)
273273
{
274274
using var profilerScope = k_ProfilerMarkerInitializeBaseTypesArray.Auto();
275-
#if UNITY_EDITOR
276-
LoadBaseTypesByReflection(GraphicsSettings.currentRenderPipelineAssetType);
277-
#else
275+
#if !UNITY_EDITOR
278276
if (globalDefaultVolumeProfile == null)
279277
{
280278
var defaultVolumeProfileSettings = GraphicsSettings.GetRenderPipelineSettings<IDefaultVolumeProfileAsset>();
281279
globalDefaultVolumeProfile = defaultVolumeProfileSettings?.defaultVolumeProfile;
282280
}
283-
LoadBaseTypes(globalDefaultVolumeProfile);
284281
#endif
282+
LoadBaseTypes(GraphicsSettings.currentRenderPipelineAssetType, globalDefaultVolumeProfile);
285283
}
286284

287285
//This is called by test where the basetypes are tuned for the purpose of the test.
@@ -323,7 +321,7 @@ public void Deinitialize()
323321
/// <param name="profile">The VolumeProfile to use as the global default profile.</param>
324322
public void SetGlobalDefaultProfile(VolumeProfile profile)
325323
{
326-
LoadBaseTypes(profile);
324+
LoadBaseTypes(GraphicsSettings.currentRenderPipelineAssetType, profile);
327325
globalDefaultProfile = profile;
328326
EvaluateVolumeDefaultState();
329327
}
@@ -435,8 +433,9 @@ public void DestroyStack(VolumeStack stack)
435433
/// LoadBaseTypes is responsible for loading the list of VolumeComponent types that will be used to build the default state of the VolumeStack. It uses the provided global default profile to determine which component types are relevant for the current render pipeline.
436434
/// This will be called only once at runtime on app boot
437435
/// </summary>
436+
/// <param name="rpType">The Pipeline Type used to check if each VolumeComponent is supported.</param>
438437
/// <param name="globalDefaultVolumeProfile">The global default volume profile to use to build the base component type array.</param>
439-
internal void LoadBaseTypes(VolumeProfile globalDefaultVolumeProfile)
438+
internal void LoadBaseTypesByDefaultVolume(Type rpType, VolumeProfile globalDefaultVolumeProfile)
440439
{
441440
if (globalDefaultVolumeProfile == null)
442441
{
@@ -446,13 +445,13 @@ internal void LoadBaseTypes(VolumeProfile globalDefaultVolumeProfile)
446445

447446
using (ListPool<Type>.Get(out var list))
448447
{
449-
var pipelineAssetType = GraphicsSettings.currentRenderPipelineAssetType;
450448
foreach (var comp in globalDefaultVolumeProfile.components)
451449
{
452-
if (comp == null) continue;
450+
if (comp == null)
451+
continue;
453452

454453
var componentType = comp.GetType();
455-
if (!SupportedOnRenderPipelineAttribute.IsTypeSupportedOnRenderPipeline(componentType, pipelineAssetType))
454+
if (!SupportedOnRenderPipelineAttribute.IsTypeSupportedOnRenderPipeline(componentType, rpType))
456455
continue;
457456

458457
list.Add(componentType);
@@ -481,15 +480,30 @@ internal Type[] LoadBaseTypesByReflection(Type pipelineAssetType)
481480
if (!SupportedOnRenderPipelineAttribute.IsTypeSupportedOnRenderPipeline(t, pipelineAssetType))
482481
continue;
483482

483+
if (t.GetCustomAttribute<ObsoleteAttribute>() != null)
484+
continue;
485+
484486
list.Add(t);
485487
}
486-
487488
m_BaseComponentTypeArray = list.ToArray();
488489
}
489490

490491
return m_BaseComponentTypeArray;
491492
}
492493
#endif
494+
/// <summary>
495+
/// Helper to choose a type loading depending if we are in Editor and Standalone.
496+
/// </summary>
497+
/// <param name="pipelineAssetType">The Pipeline Type used to check if each VolumeComponent is supported.</param>
498+
/// <param name="globalDefaultVolumeProfile">The global default volume profile to use to build the base component type array.</param>
499+
void LoadBaseTypes(Type pipelineAssetType, VolumeProfile globalDefaultVolumeProfile = null)
500+
{
501+
#if UNITY_EDITOR
502+
LoadBaseTypesByReflection(pipelineAssetType);
503+
#else
504+
LoadBaseTypesByDefaultVolume(pipelineAssetType, globalDefaultVolumeProfile);
505+
#endif
506+
}
493507

494508
internal void InitializeVolumeComponents()
495509
{

Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -321,33 +321,16 @@ public bool TryGetAllSubclassOf<T>(Type type, List<T> result)
321321
return count != result.Count;
322322
}
323323

324-
/// <summary>
325-
/// A custom hashing function that Unity uses to compare the state of parameters.
326-
/// </summary>
327-
/// <returns>A computed hash code for the current instance.</returns>
328-
public override int GetHashCode()
329-
{
330-
unchecked
331-
{
332-
int hash = 17;
333-
334-
for (int i = 0; i < components.Count; i++)
335-
hash = hash * 23 + components[i].GetHashCode();
336-
337-
return hash;
338-
}
339-
}
340-
341324
internal int GetComponentListHashCode()
342325
{
343326
unchecked
344327
{
345-
int hash = 17;
328+
var hashCode = HashFNV1A32.Create();
346329

347330
for (int i = 0; i < components.Count; i++)
348-
hash = hash * 23 + components[i].GetType().GetHashCode();
331+
hashCode.Append(components[i].GetType().GetHashCode());
349332

350-
return hash;
333+
return hashCode.value;
351334
}
352335
}
353336

Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class VisualizationPassData
3838
/// <summary>
3939
/// Check if conversion of color texture to shading rate image is supported.
4040
/// Convenience to abstract all capabilities checks.
41+
///
42+
/// The `IsColorMaskTextureConversionSupported` method checks for the following:
43+
///- VRS hardware support through [ShadingRateInfo.supportsPerImageTile](xref:UnityEngine.Rendering.ShadingRateInfo.supportsPerImageTile). The `supportsPerImageTile` property determines whether your GPU can define different quality levels to different tiles.
44+
///- Compute shader support through [SystemInfo.supportsComputeShaders](xref:UnityEngine.Device.SystemInfo.supportsComputeShaders)
45+
///- Proper initialization of VRS utility functions and compute shaders required for converting color textures to shading rate image (SRI). This is automatically handled by the render pipeline. However, for custom implementations, you must call <see cref="InitializeResources"/> manually.
4146
/// </summary>
4247
/// <returns>Returns true if conversion of color texture to shading rate image is supported, false otherwise.</returns>
4348
public static bool IsColorMaskTextureConversionSupported()

Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayout.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@ public class XRLayout
1010
{
1111
readonly List<(Camera, XRPass)> m_ActivePasses = new List<(Camera, XRPass)>();
1212

13+
/// <summary>
14+
/// State container for Quad View rendering, used to cache data across render passes.
15+
/// </summary>
16+
public QuadViewState quadView;
17+
18+
/// <summary>
19+
/// Contains cached state for Quad View XR rendering.
20+
/// Quad View is an XR rendering mode where peripheral (outer) and foveal (inner) views are rendered separately.
21+
/// </summary>
22+
public struct QuadViewState
23+
{
24+
/// <summary>
25+
/// Cached vignette center from the peripheral (outer) view pass.
26+
/// Used by the inner view pass to ensure vignette effect is consistent across both views.
27+
/// </summary>
28+
public Vector4 cachedPeripheralVignetteCenter;
29+
}
30+
1331
/// <summary>
1432
/// Configure the layout to render from the specified camera by generating passes from the the connected XR device.
1533
/// </summary>
@@ -76,6 +94,7 @@ internal void Clear()
7694
}
7795

7896
m_ActivePasses.Clear();
97+
quadView = default;
7998
}
8099

81100
internal void LogDebugInfo()

0 commit comments

Comments
 (0)