From 2ef8887468edb443a310c66637e2337b6b4a2bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20V=C3=A1zquez?= Date: Mon, 30 Mar 2026 15:14:26 +0000 Subject: [PATCH 01/88] HDRP: Rendering Debugger - "Freeze Camera For Culling" dropdown was only showing None as an option. --- .../Runtime/Debugging/DebugUI.Fields.cs | 35 +++++++ .../Runtime/Debugging/DebugUI.cs | 5 +- .../Runtime/Debug/DebugDisplay.cs | 92 ++++++++++++++----- .../RenderPipeline/HDRenderPipeline.cs | 3 - 4 files changed, 105 insertions(+), 30 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs index 654fb1b7e92..a2a052bbc3b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs @@ -1040,6 +1040,41 @@ public CameraSelector() private Camera[] m_CamerasArray; private List m_Cameras = new List(); +#if ENABLE_RENDERING_DEBUGGER_UI + /// + protected override VisualElement Create() + { + var objectPopUpField = base.Create() as UIElements.PopupField; + + if (objectPopUpField == null) + return new Label("Error creating CameraSelector field"); + + objectPopUpField.choices ??= new List() { null }; + + // Refresh the dropdown choices to keep it in sync with available cameras in the scene. + // NOTE: If the currently selected camera is deleted, PopupField handles it internally, + // so we only need to maintain the available choices list. + this.ScheduleTracked(objectPopUpField, () => objectPopUpField.schedule.Execute(() => + { + // Using ListPool and SequenceEqual to avoid unnecessary allocations and UI updates + using (UnityEngine.Pool.ListPool.Get(out var tmp)) + { + tmp.Add(null); + tmp.AddRange(getObjects()); + + if (!tmp.SequenceEqual(objectPopUpField.choices)) + { + objectPopUpField.choices.Clear(); + objectPopUpField.choices.AddRange(tmp); + } + } + + }).Every(500)); + + return objectPopUpField; + } +#endif + IEnumerable cameras { get diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs index 8ffc3f27344..dcc7edc4f1e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs @@ -308,22 +308,19 @@ internal VisualElement ToVisualElement(Context context) m_Context = context; m_VisualElement = Create(); - //Debug.Log($"ToVisualElement for {queryPath}"); - if (m_VisualElement == null) { Debug.LogWarning($"Unable to create a Visual Element for type {GetType()}"); return null; } m_VisualElement.AddToClassList("unity-inspector-element"); - + m_VisualElement.name = displayName; #if UNITY_EDITOR // Support for legacy state handling if (this is ISupportsLegacyStateHandling legacyStateWidget) { m_RequiresLegacyStateHandling = legacyStateWidget.RequiresLegacyStateHandling(); - //Debug.Log($"LegacyState: {m_RequiresLegacyStateHandling} ({queryPath})"); } #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index b93f9e8f5b9..5b7f3b5d6af 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -273,12 +273,6 @@ public partial class DebugDisplaySettings : IDebugData, ISerializedDebugDisplayS static GUIContent[] s_RenderingMipmapDebugMaterialTextureSlotStrings = null; static int[] s_RenderingMipmapDebugMaterialTextureSlotValues = null; - static List s_CameraNames = new List() { new("None") }; - static GUIContent[] s_CameraNamesStrings = { new ("No Visible Camera") }; - static int[] s_CameraNamesValues = { 0 }; - - static bool needsRefreshingCameraFreezeList = true; - #if ENABLE_NVIDIA && ENABLE_NVIDIA_MODULE internal UnityEngine.NVIDIA.DebugView nvidiaDebugView { get; } = new UnityEngine.NVIDIA.DebugView(); #endif @@ -341,8 +335,66 @@ public partial class DebugData public bool countRays = false; /// Display Show Lens Flare Data Driven Only. public bool showLensFlareDataDrivenOnly = false; + + [Obsolete("This API has been deprecated. #from(6000.6)")] // TODO: Remove with debugCameraToFreeze + private static Camera[] GetAvailableDebuggableCameras() + { + using (ListPool.Get(out var tmp)) + { + +#if UNITY_EDITOR + if (UnityEditor.SceneView.lastActiveSceneView != null) + { + var sceneCamera = UnityEditor.SceneView.lastActiveSceneView.camera; + if (sceneCamera != null) + tmp.Add(sceneCamera); + } +#endif + + var cameraArray = new Camera[Camera.allCamerasCount]; + Camera.GetAllCameras(cameraArray); + + foreach (var camera in cameraArray) + { + if (camera == null) + continue; + + if (camera.cameraType != CameraType.Preview && camera.cameraType != CameraType.Reflection) + { + if (camera.TryGetComponent(out _)) + tmp.Add(camera); + } + } + + return tmp.ToArray(); + } + } + /// Index of the camera to freeze for visibility. - public int debugCameraToFreeze = 0; + [Obsolete("Replace 'debugCameraToFreeze = index' with 'selectedCameraToFreeze = camera'. Index-based access is deprecated because camera list order is not stable. #from(6000.6)", false)] + public int debugCameraToFreeze + { + get + { + var cameras = GetAvailableDebuggableCameras(); + if (cameras == null || cameras.Length == 0 || selectedCameraToFreeze == null) + return -1; + + return Array.IndexOf(cameras, selectedCameraToFreeze); + } + set + { + var cameras = GetAvailableDebuggableCameras(); + if (value < 0 || value >= cameras.Length) + selectedCameraToFreeze = null; + else + selectedCameraToFreeze = cameras[value]; + } + } + + /// The camera to freeze for visibility. + public Camera selectedCameraToFreeze; + internal RTASDebugView rtasDebugView = RTASDebugView.Shadows; internal RTASDebugMode rtasDebugMode = RTASDebugMode.InstanceID; internal VolumetricCloudsDebug volumetricCloudDebug = VolumetricCloudsDebug.Lighting; @@ -680,7 +732,7 @@ public ColorPickerDebugMode GetDebugColorPickerMode() /// True if camera visibility is frozen public bool IsCameraFreezeEnabled() { - return data.debugCameraToFreeze != 0; + return data.selectedCameraToFreeze != null; } /// @@ -690,7 +742,7 @@ public bool IsCameraFreezeEnabled() /// True if a specific camera is frozen for visibility. public bool IsCameraFrozen(Camera camera) { - return IsCameraFreezeEnabled() && camera.name.Equals(s_CameraNamesStrings[data.debugCameraToFreeze].text); + return IsCameraFreezeEnabled() && camera == data.selectedCameraToFreeze; } /// @@ -1962,7 +2014,14 @@ void RegisterRenderingDebug() }); } - renderingSettings.children.Add(new DebugUI.EnumField { nameAndTooltip = RenderingStrings.FreezeCameraForCulling, getter = () => data.debugCameraToFreeze, setter = value => data.debugCameraToFreeze = value, enumNames = s_CameraNamesStrings, enumValues = s_CameraNamesValues, getIndex = () => data.debugCameraToFreezeEnumIndex, setIndex = value => data.debugCameraToFreezeEnumIndex = value }); + var freezeCameraForCullingSelector = new DebugUI.CameraSelector() + { + nameAndTooltip = RenderingStrings.FreezeCameraForCulling, + getter = () => data.selectedCameraToFreeze, + setter = value => data.selectedCameraToFreeze = value as Camera + }; + + renderingSettings.children.Add(freezeCameraForCullingSelector); renderingSettings.children.Add(new DebugUI.Container { @@ -2218,19 +2277,6 @@ internal void UpdateMaterials() } } - internal void UpdateCameraFreezeOptions() - { - if (needsRefreshingCameraFreezeList) - { - s_CameraNamesStrings = s_CameraNames.ToArray(); - s_CameraNamesValues = Enumerable.Range(0, s_CameraNames.Count()).ToArray(); - - UnregisterRenderingDebug(); - RegisterRenderingDebug(); - needsRefreshingCameraFreezeList = false; - } - } - internal bool DebugHideSky(HDCamera hdCamera) { return (IsMatcapViewEnabled(hdCamera) || diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 526dfa9c8bf..d54b2a27449 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2758,9 +2758,6 @@ AOVRequestData aovRequest } else { -#if DEVELOPMENT_BUILD || UNITY_EDITOR - m_DebugDisplaySettings.UpdateCameraFreezeOptions(); -#endif m_CurrentDebugDisplaySettings = m_DebugDisplaySettings; } From 03923839e69db112d59a16e48d5f10a5094fe6f1 Mon Sep 17 00:00:00 2001 From: Mikkel Simonsen Date: Mon, 30 Mar 2026 15:14:26 +0000 Subject: [PATCH 02/88] [UUM-108868] [URP] Fix GLES unsupported R32_SFloat RT format --- .../Runtime/2D/Rendergraph/Renderer2DRendergraph.cs | 12 ++++++++++-- .../Runtime/UniversalRenderPipelineCore.cs | 7 +++++++ .../Runtime/UniversalRendererRenderGraph.cs | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs index f5261a6876d..c6db7098961 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs @@ -646,8 +646,16 @@ void CreateCameraDepthCopyTexture(RenderGraph renderGraph, RenderTextureDescript var depthDescriptor = descriptor; depthDescriptor.msaaSamples = 1;// Depth-Only pass don't use MSAA - depthDescriptor.graphicsFormat = GraphicsFormat.R32_SFloat; - depthDescriptor.depthStencilFormat = GraphicsFormat.None; + if (PlatformAutoDetect.hasRenderToR32F) + { + depthDescriptor.graphicsFormat = GraphicsFormat.R32_SFloat; + depthDescriptor.depthStencilFormat = GraphicsFormat.None; + } + else + { + depthDescriptor.graphicsFormat = GraphicsFormat.None; + depthDescriptor.depthStencilFormat = CoreUtils.GetDefaultDepthOnlyFormat(); + } resourceData.cameraDepthTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, depthDescriptor, "_CameraDepthTexture", true); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 481fdd4e2f2..8637f9634d0 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -1949,6 +1949,7 @@ private sealed class PlatformDetectionCache public readonly bool isSwitch; public readonly bool isSwitch2; public readonly bool isRunningOnPowerVRGPU; + public readonly bool hasRenderToR32F; public PlatformDetectionCache() { @@ -1964,6 +1965,7 @@ public PlatformDetectionCache() isSwitch = Application.platform == RuntimePlatform.Switch; isSwitch2 = Application.platform == RuntimePlatform.Switch2; isRunningOnPowerVRGPU = SystemInfo.graphicsDeviceName.Contains("PowerVR"); + hasRenderToR32F = SystemInfo.IsFormatSupported(GraphicsFormat.R32_SFloat, GraphicsFormatUsage.Render); } } @@ -2016,6 +2018,11 @@ private static bool IsRunningXRMobile() internal static bool isRunningOnPowerVRGPU => platformCache.Value.isRunningOnPowerVRGPU; + /// + /// If true, then the runtime device supports R32_SFloat render targets. Not guaranteed on GLES 3.1 or earlier. + /// + internal static bool hasRenderToR32F => platformCache.Value.hasRenderToR32F; + /// /// Gives the SH evaluation mode when set to automatically detect. /// diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs index 415145115a0..4295a992d71 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs @@ -652,9 +652,9 @@ internal override void OnRecordRenderGraph(RenderGraph renderGraph, ScriptableRe bool requirePrepass = requirePrepassForTextures || useDepthPriming; - // Only use a depth format when we do a prepass directly the cameraDepthTexture. If we do depth priming (ie, prepass to the activeCameraDepth), we don't do a prepass to the texture. Instead, we do a copy from the primed attachment. + // Only use a depth format when we do a prepass directly to the cameraDepthTexture, or if R32F color format is not supported. If we do depth priming (ie, prepass to the activeCameraDepth), we don't do a prepass to the texture. Instead, we do a copy from the primed attachment. bool prepassToCameraDepthTexture = requirePrepassForTextures && !usesDeferredLighting && !useDepthPriming; - bool depthTextureIsDepthFormat = prepassToCameraDepthTexture; + bool depthTextureIsDepthFormat = prepassToCameraDepthTexture || !PlatformAutoDetect.hasRenderToR32F; bool requireCopyFromDepth = renderPassInputs.requiresDepthTexture && !prepassToCameraDepthTexture; // We configure this for the first camera of the stack and overlay camera will reuse create color/depth var From c4e41368aba0ca62657016b17a35c918e93c48c3 Mon Sep 17 00:00:00 2001 From: Mark Green Date: Mon, 30 Mar 2026 15:14:28 +0000 Subject: [PATCH 03/88] Shader graph documentation feedback improvements - sprint 26 Mar --- .../Colorspace-Conversion-Node.md | 2 +- .../Documentation~/HD-Scene-Color-Node.md | 41 ++++++++++++------- .../Documentation~/Property-Types.md | 2 +- ...aph-Sample-Custom-Lighting-Introduction.md | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/Packages/com.unity.shadergraph/Documentation~/Colorspace-Conversion-Node.md b/Packages/com.unity.shadergraph/Documentation~/Colorspace-Conversion-Node.md index 1a6a7ebaecf..a993c4ddcb3 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Colorspace-Conversion-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Colorspace-Conversion-Node.md @@ -16,7 +16,7 @@ Returns the result of converting the value of input **In** from one colorspace s | Name | Type | Options | Description | |:------------ |:-------------|:-----|:---| | From | Dropdown | RGB, Linear, HSV | Selects the colorspace to convert from | -| To | Dropdown | RGB, Linear, HSV | Selects the colorspace to convert to | +| To | Dropdown | RGB, Linear, HSV | Selects the colorspace to convert to. Returns values in the range 0 to 1, or higher if the color space is HDR. | ## Generated Code Example diff --git a/Packages/com.unity.shadergraph/Documentation~/HD-Scene-Color-Node.md b/Packages/com.unity.shadergraph/Documentation~/HD-Scene-Color-Node.md index 74ba57e3890..37a660a7696 100644 --- a/Packages/com.unity.shadergraph/Documentation~/HD-Scene-Color-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/HD-Scene-Color-Node.md @@ -1,24 +1,35 @@ -# HD Scene Color Node +# HD Scene Color node -The HD Scene Color Node does the same thing as the Scene Color Node, but allows you to access the mips of the color buffer. +The HD Scene Color node samples the color buffer of the current camera, using the screen space coordinates you input. The node works the same way as the [Scene Color Node](Scene-Color-Node.md) but returns the mipmap levels of the color buffer. -## Render pipeline compatibility +To make sure the HD Scene Color node outputs the correct values, follow these steps: -| **Node** | **Universal Render Pipeline (URP)** | **High Definition Render Pipeline (HDRP)** | -| -------------- | ----------------------------------- | ------------------------------------------ | -| HD Scene Color | No | Yes | +1. Connect the node to the fragment [shader stage](Shader-Stage.md). The HD Scene Color node doesn't support the vertex shader stage. +2. In the **Graph Settings** tab of the [**Graph Inspector**](Internal-inspector.md) window, set **Surface Type** to **Transparent**. Otherwise, the node samples the color buffer before Unity renders all the opaque contents in the scene. + +The node uses trilinear clamp mode to sample the color buffer, so it smoothly interpolates between the mipmap levels. + +## Render pipeline support + +The HD Scene Color node supports the High Definition Render Pipeline (HDRP) only. If you use the node with an unsupported pipeline, it returns 0 (black). + +If you use your own custom render pipeline, you must define the behavior of the node yourself. Otherwise, the node returns a value of 0 (black). ## Ports -| Name | Direction | Type | Binding | Description | -|:------------ |:-------------|:-----|:---|:---| -| **UV** | Input | Vector 4 | Screen Position | Sets the normalized screen coordinates to sample. | -| **Lod** | Input | float | None | Sets the mip level that the sampler uses to sample the color buffer. | -| **Output** | Output | Vector 3 | None | Output value | +| Name | Direction | Type | Binding | Description | +|:--|:--|:--|:--|:--| +| **UV** | Input | Vector 4 | Screen position | The normalized screen space coordinates to sample from. | +| **Lod** | Input | float | None | The mipmap level to sample. | +| **Output** | Output | Vector 3 | None | The color value from the color buffer at the coordinates and mipmap level. | + +## Properties -## Notes -### Exposure +| **Property** | **Description** | +|-|-| +| **Exposure** | Applies [exposure](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/index.html?subfolder=/manual/Override-Exposure.html) to the camera color. This property is disabled by default to avoid double exposure. | -You can use the Exposure property to specify if you want to output the Camera color with exposure applied or not. By default, this property is disabled to avoid double exposure. +## Additional resources -The sampler that this Node uses to sample the color buffer is in trilinear clamp mode. This allows the sampler to smoothly interpolate between the mip maps. +- [Scene Color Node](Scene-Color-Node.md) +- [Custom pass buffers and pyramids](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/index.html?subfolder=/manual/Custom-Pass-buffers-pyramids.html) diff --git a/Packages/com.unity.shadergraph/Documentation~/Property-Types.md b/Packages/com.unity.shadergraph/Documentation~/Property-Types.md index 2aee450abbe..fdd6c030211 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Property-Types.md +++ b/Packages/com.unity.shadergraph/Documentation~/Property-Types.md @@ -150,7 +150,7 @@ Defines a [Cubemap](https://docs.unity3d.com/Manual/class-Cubemap.html) value. D ## Virtual Texture -Defines a [Texture Stack](https://docs.unity3d.com/2020.1/Documentation/Manual/svt-use-in-shader-graph.html), which appears as object fields of type [Texture](https://docs.unity3d.com/Manual/class-TextureImporter.html) in the Material Inspector. The number of fields corresponds to the number of layers in the property. +Defines a [Texture Stack](https://docs.unity3d.com/Manual/svt-use-in-shader-graph.html), which appears as object fields of type [Texture](https://docs.unity3d.com/Manual/class-TextureImporter.html) in the Material Inspector. The number of fields corresponds to the number of layers in the property. | Parameter | Description | | :--- | :--- | diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Introduction.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Introduction.md index b52c4be8d66..96ea6158826 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Introduction.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Introduction.md @@ -24,7 +24,7 @@ The assets available in the **Custom Lighting** sample allow you to [get started Before you start to customize lighting models with Shader Graph, be aware of the following limitations: -### Shader Graph doesn't support deferred rendering +### Shader Graph doesn't support custom lighting with deferred rendering Customizable lighting is only intended to be used when you set the render type to Forward or Forward+ in the Render Asset. From 4bd1833c43ef1b59ddbffb87543b602e5a8238f9 Mon Sep 17 00:00:00 2001 From: Yorgos Petkakis Date: Mon, 30 Mar 2026 19:31:10 +0000 Subject: [PATCH 04/88] Finalize GTF 9.0 --- .../Scripts/Runtime/MockHmdSetupAttribute.cs | 2 +- .../Runtime/UniversalGraphicsTestBase.cs | 17 +- ...5_ShaderKeywords_Constant_MultiCompile.vfx | 4 +- ..._ShaderKeywords_Constant_ShaderFeature.vfx | 4 +- .../025_ShaderKeywords_Dynamic_Exposed.vfx | 4 +- .../025_ShaderKeywords_Dynamic_Random.vfx | 4 +- ..._ShaderKeywords_Dynamic_Random_Animate.vfx | 4 +- .../NamedObject_ExposedPropertiesMesh.vfx | 4 +- ...medObject_ExposedPropertiesSkinnedMesh.vfx | 4 +- .../NamedObject_ExposedPropertiesTexture.vfx | 4 +- .../Runtime/AssetBundleSetupAttribute.cs | 2 +- .../PerformanceTestSettingsSetupAttribute.cs | 2 +- .../Assets/Tests/Runtime/GraphicsTests.cs | 2 +- .../Assets/Tests/Runtime/GraphicsTests.cs | 2 +- .../Test/Runtime/BuiltInGraphicsTests.cs | 18 +- .../Assets/Tests/HDRP_DXR_Graphics_Tests.cs | 53 +- .../Tests/HDRP_Runtime_Graphics_Tests.cs | 34 +- .../GraphicTests/Tests/HDRP_Graphics_Tests.cs | 239 ++-- .../Assets/Common/Editor/BaseGraphicsTests.cs | 4 +- .../Assets/Tests/Editor/LensFlareTests.cs | 6 +- .../Scripts/ShaderGraphGraphicsTests.cs | 34 +- .../HDRenderPipelineAsset_APV.asset | 426 +++---- .../GraphicsTests/DistortionTest.unity | 4 +- .../DistortionTestSettings.lighting | 77 ++ .../DistortionTestSettings.lighting.meta | 8 + .../Assets/HDRP/HDRenderPipelineAsset.asset | 19 +- .../HDRenderPipelineGlobalSettings.asset | 1012 ++++++----------- .../HDRP_VisualEffectsGraph_GraphicsTests.cs | 16 +- ...DRP_VisualEffectsGraph_PerformanceTests.cs | 16 +- .../PackageManagerSettings.asset | 21 +- .../ProjectSettings/ShaderGraphSettings.asset | 1 + .../ProjectSettings/VFXManager.asset | 2 +- 32 files changed, 906 insertions(+), 1143 deletions(-) create mode 100644 Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting create mode 100644 Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting.meta diff --git a/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/MockHmdSetupAttribute.cs b/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/MockHmdSetupAttribute.cs index 42ac052e877..c6181a76172 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/MockHmdSetupAttribute.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/MockHmdSetupAttribute.cs @@ -7,7 +7,7 @@ public class MockHmdSetupAttribute : GraphicsPrebuildSetupAttribute { public MockHmdSetupAttribute(int order = 0) : base(order) { } - public override void Setup() + protected override void Setup() { #if UNITY_EDITOR && USE_XR_MOCK_HMD && !OCULUS_SDK // Configure the project for XR tests by adding the MockHMD plugin if required. diff --git a/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/UniversalGraphicsTestBase.cs b/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/UniversalGraphicsTestBase.cs index 06183d2f119..e801c8fb601 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/UniversalGraphicsTestBase.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.urp/Scripts/Runtime/UniversalGraphicsTestBase.cs @@ -31,14 +31,11 @@ public UniversalGraphicsTestBase(GpuResidentDrawerContext grdContext) { requestedGRDContext = grdContext; - gpuResidentDrawerContext = - GlobalContextManager.RegisterGlobalContext(typeof(GpuResidentDrawerGlobalContext)) - as GpuResidentDrawerGlobalContext; + gpuResidentDrawerContext = GlobalContextManager.Get(); - previousGRDContext = (GpuResidentDrawerContext)gpuResidentDrawerContext.Context; + previousGRDContext = (GpuResidentDrawerContext)gpuResidentDrawerContext.Current; - // Activate new context - gpuResidentDrawerContext.ActivateContext(requestedGRDContext); + gpuResidentDrawerContext.Activate(requestedGRDContext); } [OneTimeSetUp] @@ -66,9 +63,9 @@ public IEnumerator OneTimeSetup() [SetUp] public void SetUpContext() { - gpuResidentDrawerContext.ActivateContext(requestedGRDContext); + gpuResidentDrawerContext.Activate(requestedGRDContext); - GlobalContextManager.AssertContextIs(requestedGRDContext); + GlobalContextManager.AssertContextIs(requestedGRDContext); } [TearDown] @@ -85,9 +82,7 @@ public void OneTimeTearDown() { SceneManager.LoadScene("GraphicsTestTransitionScene", LoadSceneMode.Single); - gpuResidentDrawerContext.ActivateContext(previousGRDContext); - - GlobalContextManager.UnregisterGlobalContext(typeof(GpuResidentDrawerGlobalContext)); + gpuResidentDrawerContext.Activate(previousGRDContext); } } diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_MultiCompile.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_MultiCompile.vfx index fa1e6eef889..ff735ee9cd3 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_MultiCompile.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_MultiCompile.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc9c82b26ad40e8c85f0c69f57706211f4610a8e2171616f9db6a10c51fa9aaa -size 72081 +oid sha256:767d7a0f492f9d98bb65dc4b3e2cd38e038f824e7fc826de5a5a3bf21a9fd70a +size 72058 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_ShaderFeature.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_ShaderFeature.vfx index 257d9311433..477e8c68138 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_ShaderFeature.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Constant_ShaderFeature.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7c1f03adc60d334f4111e470cd869860a40ac05cdab9f59512572350b2737f6 -size 92809 +oid sha256:8663f6fd6da75d66acec8ea498faf102142fdc91649f634b2a10c09c8cbe7002 +size 91980 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Exposed.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Exposed.vfx index 43deeedceee..6a80632f955 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Exposed.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Exposed.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e66822ad5f52ff9f0521b50b29bac74a34d60dd68c4d8f365ce8e12396b8a19f -size 147769 +oid sha256:3d6ab04f0e16f72f11f08d83ad09e543520951bd40e32fb67d136b90ee84f130 +size 146325 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random.vfx index cf1be97b4d8..befbb3c6978 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94f06df6c6f34635b2944bd174a6ead73b63ae83ef30cb323adc3e0cc0d95cb0 -size 180283 +oid sha256:783de1e30e67dfa23cbe57d5c93bb151d4914e89a104438af0caa4c422d3f4d7 +size 178287 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random_Animate.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random_Animate.vfx index 2fe9665740e..fa4b8ecddd8 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random_Animate.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/025_ShaderKeywords_Dynamic_Random_Animate.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e514d3975db1135db412cd278e0ca03c512e218275eda7a602f969f780e24a41 -size 228014 +oid sha256:62036baaf1c8b31de49f0e45d1d1c07e844d79eae4b331aee7709b1712492c5a +size 225270 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesMesh.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesMesh.vfx index 102f9a4a55c..eae2e58c29f 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesMesh.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesMesh.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8bdd3cc1dd5a9479bfe7313b516121e18e33c318f116703d258ad0ba1abc7a3e -size 134762 +oid sha256:3b7ae2414752b4153a524d6ca44cb5a0c4584961474fafe46676ed61524c7f2c +size 133824 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesSkinnedMesh.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesSkinnedMesh.vfx index 733a12f5eb5..41af94d8168 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesSkinnedMesh.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesSkinnedMesh.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5046b856141b2a15e378e7a19ee5ba2d666ed44fb0285e13b3f6d7b064da71a5 -size 82757 +oid sha256:ec962f3a3f24294315893dede4b58737e48960d550fbe371a5347bea722a978b +size 82421 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesTexture.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesTexture.vfx index 072034653ce..ef7ec5644be 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesTexture.vfx +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/NamedObject_ExposedPropertiesTexture.vfx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:533f8fad985e25c260448ef2959af158fbd38e4b86673b4f52028a01634f39bf -size 122275 +oid sha256:18aa9d4e54d9be0a9e3904c3f89e4c3dd248d1302196d0bc4ac116c33f6abd3f +size 121441 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/AssetBundleSetupAttribute.cs b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/AssetBundleSetupAttribute.cs index 9c2ea235787..7442526cf28 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/AssetBundleSetupAttribute.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/AssetBundleSetupAttribute.cs @@ -13,7 +13,7 @@ public class AssetBundleSetupAttribute : GraphicsPrebuildSetupAttribute { public AssetBundleSetupAttribute() : base() { } - public override void Setup() + protected override void Setup() { #if UNITY_EDITOR var vfxAssetsGuid = AssetDatabase.FindAssets("t:VisualEffectAsset AssetBundle"); diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/PerformanceTestSettingsSetupAttribute.cs b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/PerformanceTestSettingsSetupAttribute.cs index a373140688a..a6541a88201 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/PerformanceTestSettingsSetupAttribute.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/PerformanceTestSettingsSetupAttribute.cs @@ -19,7 +19,7 @@ public PerformanceTestSettingsSetupAttribute() : base() { } // and any calls to PerformanceTestUtils will throw a NullReferenceException error during test runs // By calling PerformanceTestSettings.GetSerializedSettings() as a prebuild setup step, we ensure 'Resources/PerformanceTestsSettings' exists, // or gets created if it doesn't exist - public override void Setup() + protected override void Setup() { #if UNITY_EDITOR PerformanceTestSettings.GetSerializedSettings(); diff --git a/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Assets/Tests/Runtime/GraphicsTests.cs b/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Assets/Tests/Runtime/GraphicsTests.cs index ec6787d95ce..272abd755e1 100644 --- a/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Assets/Tests/Runtime/GraphicsTests.cs +++ b/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Assets/Tests/Runtime/GraphicsTests.cs @@ -16,7 +16,7 @@ public class GraphicsTests [UnityTest, Category("GraphicsTest")] [SceneGraphicsTest("Assets/SampleScenes")] - [IgnoreGraphicsTest("ErrorMaterial", "Ignoring this specially designed test that fails to build the build", isInclusive: true, runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor })] + [IgnoreGraphicsTest("ErrorMaterial", "Ignoring this specially designed test that fails to build the build", true, RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor)] public IEnumerator Run(SceneGraphicsTestCase testCase) { if (testCase.ScenePath.Contains("ErrorMaterial")) diff --git a/Tests/SRPTests/Projects/BatchRendererGroup_URP/Assets/Tests/Runtime/GraphicsTests.cs b/Tests/SRPTests/Projects/BatchRendererGroup_URP/Assets/Tests/Runtime/GraphicsTests.cs index 04d40c32ced..5d028e76627 100644 --- a/Tests/SRPTests/Projects/BatchRendererGroup_URP/Assets/Tests/Runtime/GraphicsTests.cs +++ b/Tests/SRPTests/Projects/BatchRendererGroup_URP/Assets/Tests/Runtime/GraphicsTests.cs @@ -18,7 +18,7 @@ public class GraphicsTests [UnityTest, Category("GraphicsTest")] [SceneGraphicsTest("Assets/SampleScenes")] - [IgnoreGraphicsTest("ErrorMaterial", "Ignoring this specially designed test that fails to build the build", isInclusive: true, runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor })] + [IgnoreGraphicsTest("ErrorMaterial", "Ignoring this specially designed test that fails to build the build", true, RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor)] public IEnumerator Run(SceneGraphicsTestCase testCase) { if (testCase.ScenePath.Contains("ErrorMaterial")) diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Assets/Test/Runtime/BuiltInGraphicsTests.cs b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Assets/Test/Runtime/BuiltInGraphicsTests.cs index 9f6a2cb5f8d..2c8f80297c2 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Assets/Test/Runtime/BuiltInGraphicsTests.cs +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Assets/Test/Runtime/BuiltInGraphicsTests.cs @@ -16,15 +16,15 @@ public class BuiltInGraphicsTests [SceneGraphicsTest("Assets/Scenes")] [IgnoreGraphicsTest("017_Lighting_Scene_DirectionalBaked", "Something about the meta pass seems wrong even in URP")] - [IgnoreGraphicsTest("009_AdditionalLightsShadows", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("019_Lighting_Scene_PointLights", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("031_Shader_GlossyEnvironmentSky", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("032_Shader_GlossyEnvironmentColor", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("033_Shader_HighlightsEnvironmentGradientSH", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("034_Shader_HighlightsEnvironmentGradientBaked", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("036_Lighting_Scene_DirectionalBakedDirectional", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("042_Lighting_Scene_VertexLighting", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("118_SkyboxReflectionTestOrthographic", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] + [IgnoreGraphicsTest("009_AdditionalLightsShadows", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("019_Lighting_Scene_PointLights", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("031_Shader_GlossyEnvironmentSky", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("032_Shader_GlossyEnvironmentColor", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("033_Shader_HighlightsEnvironmentGradientSH", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("034_Shader_HighlightsEnvironmentGradientBaked", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("036_Lighting_Scene_DirectionalBakedDirectional", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("042_Lighting_Scene_VertexLighting", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("118_SkyboxReflectionTestOrthographic", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] public IEnumerator Run(SceneGraphicsTestCase testCase) { Debug.Log($"Running test case '{testCase}' with scene '{testCase.ScenePath}' {testCase.ReferenceImagePathLog}."); diff --git a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Assets/Tests/HDRP_DXR_Graphics_Tests.cs b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Assets/Tests/HDRP_DXR_Graphics_Tests.cs index 77f329c1d7d..540708313d4 100644 --- a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Assets/Tests/HDRP_DXR_Graphics_Tests.cs +++ b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Assets/Tests/HDRP_DXR_Graphics_Tests.cs @@ -30,58 +30,55 @@ public class HDRP_Graphics_Tests "1000_RaytracingQualityKeyword_PathTracer_Default|2009_Debug_RTAS_ScreenSpaceReflections_InstanceID|2009_Debug_RTAS_ScreenSpaceReflections_PrimitiveID|2009_Debug_RTAS_Shadows_PrimitiveID|2010_Debug_ClusterDebug|308_ScreenSpaceGlobalIllumination", "Fails on Yamato" )] - [IgnoreGraphicsTest( + [TestNotSupportedOn( "1000_RaytracingQualityKeyword_MaterialQuality_Indirect", "Strict Mode not supported" )] [IgnoreGraphicsTest( "10001_TerrainReflectionPerf", "Unstable: https://jira.unity3d.com/browse/UUM-132736", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxSeries } + RuntimePlatform.GameCoreXboxSeries )] - [IgnoreGraphicsTest( + [TestNotSupportedOn( "10004_TerrainPathTracing|10004_TerrainPathTracing_NoDecalSurfaceGradient|5001_PathTracing|5001_PathTracing_Denoised_Intel|5001_PathTracing_Denoised_Optix|5002_PathTracing_GI|5003_PathTracing_transparency|5004_PathTracing_arealight|5005_PathTracing_Fog|5006_PathTracing_DoFVolume|5007_PathTracing_Materials_SG_Lit|5007_PathTracing_Materials_SG_Unlit|5007_PathTracing_Materials_StackLit|5008_PathTracing_NormalMapping|5009_PathTracing_FabricMaterial|501_RecursiveRendering|501_RecursiveRenderingTransparent|5010_PathTracingAlpha|5011_PathTracing_ShadowMatte|5012_PathTracing_Transmission|5013_PathTracing_ShadowFlags|5014_PathTracing_DoubleSidedOverride|5015_PathTracing_DoFCamera|5016_PathTracingTiledRendering|5017_PathTracing_Decals|505_RecursiveRenderingFog|506_RecursiveRenderingTransparentLayer|507_RecursiveRenderingDecal|5019_PathTracing_AmbientOcclusion|5018_PathTracing_MaterialOverrides|5021_PathTracing_Depth_2|5022_PathTracing_Depth_3|5020_PathTracing_Depth_1|5023_PathTracing_MeshInstancing_SG_Lit|5026_PathTracing_BoxLight", "Unsupported", - runtimePlatforms: new RuntimePlatform[] - { - RuntimePlatform.GameCoreXboxSeries, - RuntimePlatform.PS5 - } + RuntimePlatform.GameCoreXboxSeries, + RuntimePlatform.PS5 )] [IgnoreGraphicsTest( "2007_Debug_LightCluster", "issue on Yamato/HDRP-3081", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxSeries } + RuntimePlatform.GameCoreXboxSeries )] [IgnoreGraphicsTest( "2007_Debug_LightCluster", "issue on Yamato/HDRP-3081", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.PS5 } + RuntimePlatform.PS5 )] [IgnoreGraphicsTest( "5001_PathTracing|5010_PathTracingAlpha", "jira: https://jira.unity3d.com/browse/GFXFEAT-1332", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12 } + GraphicsDeviceType.Direct3D12 )] [IgnoreGraphicsTest( "5005_PathTracing_Fog", "jira: https://jira.unity3d.com/browse/GFXFEAT-1334", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12 } + GraphicsDeviceType.Direct3D12 )] [IgnoreGraphicsTest( "5007_PathTracing_Materials_SG_Lit", "issue on Yamato only: jira: https://jira.unity3d.com/browse/UUM-26542", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.WindowsPlayer } + RuntimePlatform.WindowsPlayer )] [IgnoreGraphicsTest( "802_SubSurfaceScatteringForward", "Inconsistent on Yamato", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxSeries } + RuntimePlatform.GameCoreXboxSeries )] [IgnoreGraphicsTest( "802_SubSurfaceScatteringForward", "Inconsistent on Yamato", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.PS5 } + RuntimePlatform.PS5 )] [IgnoreGraphicsTest( "900_Materials_AlphaTest_SG", @@ -90,7 +87,7 @@ public class HDRP_Graphics_Tests [IgnoreGraphicsTest( "902_Materials_SG_Variants_Lit", "issue on Yamato only: jira: https://jira.unity3d.com/browse/UUM-26542", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.WindowsPlayer } + RuntimePlatform.WindowsPlayer )] [IgnoreGraphicsTest( "10003_TerrainShadow", @@ -99,15 +96,12 @@ public class HDRP_Graphics_Tests [IgnoreGraphicsTest( "107_ReflectionsHybridFullRes_OnTransparent", "Disabled for Instability ", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxSeries } + RuntimePlatform.GameCoreXboxSeries )] [IgnoreGraphicsTest( "10002_TerrainReflectionQuality", "Disabled for Instability https://jira.unity3d.com/browse/UUM-134774", - runtimePlatforms: new RuntimePlatform[] - { - RuntimePlatform.GameCoreXboxSeries - } + RuntimePlatform.GameCoreXboxSeries )] public IEnumerator Run(SceneGraphicsTestCase testCase) { @@ -170,14 +164,10 @@ public HDRP_GRD_DXR_Graphics_Tests(GpuResidentDrawerContext grdContext) { requestedGRDContext = grdContext; - // Register context - gpuResidentDrawerContext = - GlobalContextManager.RegisterGlobalContext(typeof(GpuResidentDrawerGlobalContext)) - as GpuResidentDrawerGlobalContext; + gpuResidentDrawerContext = GlobalContextManager.Get(); - // Cache previous state to avoid state leak - previousGRDContext = (GpuResidentDrawerContext)gpuResidentDrawerContext.Context; - gpuResidentDrawerContext.ActivateContext(requestedGRDContext); + previousGRDContext = (GpuResidentDrawerContext)gpuResidentDrawerContext.Current; + gpuResidentDrawerContext.Activate(requestedGRDContext); } [OneTimeSetUp] @@ -192,15 +182,14 @@ public void OneTimeSetUp() public void OneTimeTearDown() { SceneManager.LoadScene("GraphicsTestTransitionScene", LoadSceneMode.Single); - gpuResidentDrawerContext.ActivateContext(previousGRDContext); - GlobalContextManager.UnregisterGlobalContext(typeof(GpuResidentDrawerGlobalContext)); + gpuResidentDrawerContext.Activate(previousGRDContext); } [SetUp] public void SetUpContext() { - gpuResidentDrawerContext.ActivateContext(requestedGRDContext); - GlobalContextManager.AssertContextIs(requestedGRDContext); + gpuResidentDrawerContext.Activate(requestedGRDContext); + GlobalContextManager.AssertContextIs(requestedGRDContext); } [TearDown] diff --git a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs index 5532c677477..f16eaa21860 100644 --- a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs @@ -42,56 +42,62 @@ public IEnumerable UnityOneTimeSetUp() [IgnoreGraphicsTest( "001-HDTemplate$", "https://jira.unity3d.com/browse/UUM-48116", - graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "001-HDTemplate$", "Small issue with incorrect rendering on bubble. Some half overflow issue and flickering artifacts. Will need image update when fixed", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch } + RuntimePlatform.Switch )] [IgnoreGraphicsTest( "001-HDTemplate$", "Linux/VK: The test is a bit flaky, failing around 1/6 runs. Needs further investigation.", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.LinuxPlayer }, - graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Vulkan } + RuntimePlatform.LinuxPlayer, + GraphicsDeviceType.Vulkan )] [IgnoreGraphicsTest( "001-HDTemplate$", "https://jira.unity3d.com/browse/UUM-105789", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.PS5, RuntimePlatform.WindowsPlayer } + RuntimePlatform.PS5, RuntimePlatform.WindowsPlayer )] [IgnoreGraphicsTest( "002-HDMaterials$", "", - graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "003-VirtualTexturing$", "https://jira.unity3d.com/browse/UUM-131182 Both Switches fail on MultiThreaded (pass on Native Jobs)", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.PS4 }, // Also unstable on PS4: https://jira.unity3d.com/browse/UUM-135501 - renderingThreadingModes: new RenderingThreadingMode[] { RenderingThreadingMode.MultiThreaded } + RuntimePlatform.Switch, RuntimePlatform.Switch2, RuntimePlatform.PS4, // Also unstable on PS4: https://jira.unity3d.com/browse/UUM-135501 + RenderingThreadingMode.MultiThreaded + )] + [IgnoreGraphicsTest( + "003-VirtualTexturing-Forward$", + "https://jira.unity3d.com/browse/UUM-131182 Switch fails on MultiThreaded (pass on Native Jobs)", + RuntimePlatform.Switch, + RenderingThreadingMode.MultiThreaded )] [IgnoreGraphicsTest( "004-CloudsFlaresDecals$", "Area with cloud-coverage is blue on Intel-based MacOS (CI).", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new [] { Architecture.X64 } + GraphicsDeviceType.Metal, + Architecture.X64 )] [IgnoreGraphicsTest( "007-BasicAPV$", "https://jira.unity3d.com/browse/UUM-54029", - graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal }, - architectures: new Architecture[] { Architecture.X64 } + GraphicsDeviceType.Metal, + Architecture.X64 )] [IgnoreGraphicsTest( "010-BRG-Simple", "Unstable: https://jira.unity3d.com/browse/UUM-134572", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.PS5 } + RuntimePlatform.PS5 )] [IgnoreGraphicsTest( "012-SVL_Check$", "https://jira.unity3d.com/browse/UUM-70791", - runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.PS4, RuntimePlatform.PS5, RuntimePlatform.Switch, RuntimePlatform.Switch2 } + RuntimePlatform.PS4, RuntimePlatform.PS5, RuntimePlatform.Switch, RuntimePlatform.Switch2 )] public IEnumerator Run(SceneGraphicsTestCase testCase) { diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs index 4ea1a362484..5af722f1c3e 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs @@ -39,21 +39,14 @@ public HDRP_Graphics_Tests(GpuResidentDrawerContext grdContext) requestedGRDContext = grdContext; requestedOccContext = GpuOcclusionCullingGlobalContext.ChooseContext(grdContext); - // Register context - gpuResidentDrawerContext = - GlobalContextManager.RegisterGlobalContext(typeof(GpuResidentDrawerGlobalContext)) - as GpuResidentDrawerGlobalContext; + gpuResidentDrawerContext = GlobalContextManager.Get(); + gpuOcclusionContext = GlobalContextManager.Get(); - gpuOcclusionContext = - GlobalContextManager.RegisterGlobalContext(typeof(GpuOcclusionCullingGlobalContext)) - as GpuOcclusionCullingGlobalContext; + previousGRDContext = (GpuResidentDrawerContext)gpuResidentDrawerContext.Current; + previousOccContext = (GpuOcclusionCullingContext)gpuOcclusionContext.Current; - // Cache previous state to avoid state leak - previousGRDContext = (GpuResidentDrawerContext)gpuResidentDrawerContext.Context; - previousOccContext = (GpuOcclusionCullingContext)gpuOcclusionContext.Context; - - gpuResidentDrawerContext.ActivateContext(requestedGRDContext); - gpuOcclusionContext.ActivateContext(requestedOccContext); + gpuResidentDrawerContext.Activate(requestedGRDContext); + gpuOcclusionContext.Activate(requestedOccContext); } [OneTimeSetUp] @@ -79,11 +72,11 @@ public IEnumerable UnityOneTimeSetUp() [SetUp] public void SetUpContext() { - gpuResidentDrawerContext.ActivateContext(requestedGRDContext); - gpuOcclusionContext.ActivateContext(requestedOccContext); + gpuResidentDrawerContext.Activate(requestedGRDContext); + gpuOcclusionContext.Activate(requestedOccContext); - GlobalContextManager.AssertContextIs(requestedGRDContext); - GlobalContextManager.AssertContextIs(requestedOccContext); + GlobalContextManager.AssertContextIs(requestedGRDContext); + GlobalContextManager.AssertContextIs(requestedOccContext); } [UnityTest] @@ -97,8 +90,7 @@ public void SetUpContext() [IgnoreGraphicsTest( "2319_Mixed_Cached_ShadowMap_Area|1705_Decals-stress-test", "Fails when GRD is enabled.", - contextTypes: new[] { typeof(GpuResidentDrawerGlobalContext) }, - contextMasks: new[] { (int)GpuResidentDrawerContext.GRDEnabled } + GpuResidentDrawerContext.GRDEnabled )] [IgnoreGraphicsTest( "1206_Lit_Transparent_Distortion$", @@ -107,22 +99,22 @@ public void SetUpContext() [IgnoreGraphicsTest( "1215_Lit_SubSurfaceScattering$", "Outdated ref-image + Slight noise divergence in the SSS.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "1217_Lit_SSS_Pre-Post$", "Slight noise divergence in the SSS + Some bigger difference near the top of the image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "1221_Lit_POM_Emission$", "There seems to be differences in texture-sampling between DX/VK and Metal GPUs. DX seems to be forcing trilinear filtering when using anisotropy, according to: https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Texture-anisoLevel.html", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "1227_Lit_Planar_Triplanar_ObjectSpace$", "Similar sampling issue to 1221.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan } + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan )] [IgnoreGraphicsTest( "1301_StackLitSG$", @@ -132,172 +124,160 @@ public void SetUpContext() [IgnoreGraphicsTest( "1351_Fabric$", "(Intel Mac) Slight divergence on the right-most materials.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest( "1710_Decals_Normal_Patch$", "(Intel Mac) Decals missing on top of StackLit and Fabric planes.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest( "1805_Depth_Pre_Post_Unlit$", "(Intel Mac) Certain overlapping areas diverge, though not too apparent to the naked eye.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest("1806_BatchCount$", "Fails everywhere (seems to be missing CPU markers).")] [IgnoreGraphicsTest( "2120_APV_Baking$", "Incorrect on DX12/Metal.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Metal } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "2121_APV_Baking_Sky_Occlusion$", "Incorrect on Metal/VK.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan } + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan )] [IgnoreGraphicsTest( "2123_APV_Baking_Shadowmask$", "Seems to be missing ref-image on Metal.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "2220_SmoothPlanarReflection$", "Rough reflections seem to be very different in Metal compared to other APIs.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "2222_ReflectionProbeDistanceBased$", "Need to update Metal ref-image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "2301_Shadow_Mask$", "Rendered results are too bright on Metal and DX11(instability?).", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal, GraphicsDeviceType.Direct3D11 } + GraphicsDeviceType.Metal, GraphicsDeviceType.Direct3D11 )] [IgnoreGraphicsTest( "2316_ShadowTint$", "Very small divergence on Metal. Maybe it needs a ref-image update?", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "2323_Shadow_Interlaced_Cascades_Update$", "(Intel Mac) Slight divergence on the right area of the image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest( "2405_EnlightenDynamicAreaLights$", "Results on CI are very close to DX/VK ref-images. Maybe it just need a ref-image update?", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "2405_EnlightenDynamicAreaLights$", "Results on CI are very close to Windows ref-images. Maybe it just need a ref-image update?", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.LinuxEditor } + GraphicsDeviceType.Vulkan, RuntimePlatform.LinuxEditor )] [IgnoreGraphicsTest( "3006_TileCluster_Cluster$", "Outdated ref-images.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "3005_VertexDensity", "Unstable: https://jira.unity3d.com/browse/UUM-135177", - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor } + RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( "3008_ShadowDebugMode$", "(Intel Mac) Clear color of the debug-view seems to be black instead of white. Probably just an outdated ref-image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest("4012_MotionBlur_CameraOnly$", "Missing ref-image.")] [IgnoreGraphicsTest( "4075_PhysicalCamera-gateFit$", "Noisy result in Linux + VK..", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.LinuxEditor } + GraphicsDeviceType.Vulkan, RuntimePlatform.LinuxEditor )] [IgnoreGraphicsTest( "4096_DRS-TAAU-Hardware$", "Very small fringing across edges. Maybe a sampling artifact?", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "4101_FP16Alpha$", "Outdated ref-image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "4105_LensFlareScreenSpace$", "(Intel Mac) Lens-flare behaviour seems to be different from all the other platforms.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest( "4106_DRS-TAAU-AfterPost$", "Very small fringing across edges. Maybe a sampling artifact?", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "5006_Pbr_Sky_Low_Altitude$", "Differences in banding around the horizon.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "5007_Exponential_Fog$", "Small divergence. Needs further investigation.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "5010_CloudLayer$", "Very minor divergence. Maybe it's an outdated ref-image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "5011_VolumetricClouds$", "Outdated ref-image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "5011_VolumetricCloudsShadows$", "Sky and planar reflections diverge too much from the reference image.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "5011_VolumetricCloudsShadowsBake$", "(Intel Mac) Rendered image is completely black.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest( "5013_VolumetricCloudsShadowsNoExposureControl$", "(Intel Mac) Rendered image is completely black.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest( "8101_Opaque$", "(Intel Mac) Small divergence around 'Iridescence Specular Occlusion from Bent Normal' material. Might need a ref-image update.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest("8207_InstanceIDWithKeywords$", "Missing ref-image.")] [IgnoreGraphicsTest( "8212_Fullscreen", "Unstable - see https://jira.unity3d.com/browse/UUM-100863", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "8213_Thickness$", "(Intel Mac) Bunny in the middle should be translucent-pink, not black.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal }, - architectures: new[] { Architecture.X64 } + GraphicsDeviceType.Metal, Architecture.X64 )] [IgnoreGraphicsTest("9006_StencilUsage$", "Missing ref-image.")] [IgnoreGraphicsTest("9601_SkinnedMeshBatching-Off$", "Outdated ref-image.")] @@ -305,147 +285,131 @@ public void SetUpContext() [IgnoreGraphicsTest( "9701_CustomPass_DrawRenderers", "Unstable - see https://jira.unity3d.com/browse/UUM-130183", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "9703_SampleColorBuffer_InjectionPoints_Scaling$", "Small differences in texture-sampling. Could be related to the forced-trilinear issue?", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] - [IgnoreGraphicsTest( + [TestNotSupportedOn( "9704_CustomPass_VRS$", "VRS not supported", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Metal } + GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "9910_GlobalMipBias$", "Needs further investigation.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "9920_WaterSurface$", "Diverges in the wave-modifier edges.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "9921_UnderWater", "Unstable - see https://jira.unity3d.com/browse/UUM-134223", - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor } + RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( "9921_UnderWater_Back", "Unstable - see https://jira.unity3d.com/browse/UUM-134223", - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor } + RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( "9922_WaterPrefab", "Unstable - see https://jira.unity3d.com/browse/UUM-134223", - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor } + RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( "9922_WaterPrefab$", "Minor divergence across the waves' crests.", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Metal } + GraphicsDeviceType.Metal )] [IgnoreGraphicsTest( "9001_LODTransition", "Failing with GpuResidentDrawer", - runtimePlatforms: new[] { RuntimePlatform.OSXEditor }, - architectures: new[] { Architecture.X64 }, - contextTypes: new[] { typeof(GpuResidentDrawerGlobalContext) }, - contextMasks: new[] { (int)GpuResidentDrawerContext.GRDEnabled } + RuntimePlatform.OSXEditor, + Architecture.X64, + GpuResidentDrawerContext.GRDEnabled )] [IgnoreGraphicsTest( "9950-LineRendering", "Failing with GpuResidentDrawer", - runtimePlatforms: new[] { RuntimePlatform.OSXEditor }, - architectures: new[] { Architecture.Arm64 }, - contextTypes: new[] { typeof(GpuResidentDrawerGlobalContext) }, - contextMasks: new[] { (int)GpuResidentDrawerContext.GRDEnabled } + RuntimePlatform.OSXEditor, + Architecture.Arm64, + GpuResidentDrawerContext.GRDEnabled )] [IgnoreGraphicsTest( "2120_APV_Baking", "Failing with GpuResidentDrawer", - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, - architectures: new[] { Architecture.X64 }, - contextTypes: new[] { typeof(GpuResidentDrawerGlobalContext) }, - contextMasks: new[] { (int)GpuResidentDrawerContext.GRDEnabled } + RuntimePlatform.WindowsEditor, + Architecture.X64, + GpuResidentDrawerContext.GRDEnabled )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4107_DRS-FSR2-Hardware", "Platform not supported", // FSR is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4108_DRS-FSR2-Software", "Platform not supported", // FSR is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4109_DRS-FSR2-AfterPost", "Platform not supported", // FSR is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4110_DRS-FSR2-With-CustomPass", "Platform not supported", // FSR is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4088_DRS-DLSS-Hardware", "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4089_DRS-DLSS-Software", "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4103_DRS-DLSS-AfterPost", "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] - [IgnoreGraphicsTest( + [TestOnlySupportedOn( "4111_DRS-DLSS-With-CustomPass", "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only - isInclusive: true, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer } + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] [IgnoreGraphicsTest( "3009_MaterialOverrides", "https://jira.unity3d.com/browse/UUM-134370 - Weird artifacts on NVIDIA A10", - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D11 }, - runtimePlatforms: new[] { RuntimePlatform.WindowsEditor } + GraphicsDeviceType.Direct3D11, RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( "3004_QuadOverdraw", "Disabled for Instability https://jira.unity3d.com/browse/UUM-134754", - runtimePlatforms: new [] { RuntimePlatform.WindowsEditor }, - graphicsDeviceTypes: new[] { GraphicsDeviceType.Direct3D12 } + RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12 )] [IgnoreGraphicsTest( "4075_PhysicalCamera-gateFit|4111_DRS-DLSS-With-CustomPass", "Disabled for Instability https://jira.unity3d.com/browse/UUM-134786", - runtimePlatforms: new RuntimePlatform[] - { - RuntimePlatform.WindowsEditor - } + RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( "4014_PrecomputedVelocityAlembic", @@ -470,34 +434,22 @@ public void SetUpContext() [IgnoreGraphicsTest( "4089_DRS-DLSS-Software", "Disabled for Instability https://jira.unity3d.com/browse/UUM-135194", - runtimePlatforms: new[] - { RuntimePlatform.WindowsEditor - } )] [IgnoreGraphicsTest( "4088_DRS-DLSS-Hardware", "Disabled for Instability https://jira.unity3d.com/browse/UUM-135194", - runtimePlatforms: new[] - { RuntimePlatform.WindowsEditor - } )] [IgnoreGraphicsTest( "9800_Compositor", "Disabled for Instability https://jira.unity3d.com/browse/UUM-138001", - runtimePlatforms: new[] - { RuntimePlatform.WindowsEditor - } )] [IgnoreGraphicsTest( "9801_ShurikenLightModule", "Disabled for Instability https://jira.unity3d.com/browse/UUM-138001", - runtimePlatforms: new[] - { RuntimePlatform.WindowsEditor - } )] public IEnumerator Run(SceneGraphicsTestCase testCase) { @@ -525,11 +477,8 @@ public void OneTimeTearDown() { SceneManager.LoadScene("GraphicsTestTransitionScene", LoadSceneMode.Single); - gpuResidentDrawerContext.ActivateContext(previousGRDContext); - gpuOcclusionContext.ActivateContext(previousOccContext); - - GlobalContextManager.UnregisterGlobalContext(typeof(GpuResidentDrawerGlobalContext)); - GlobalContextManager.UnregisterGlobalContext(typeof(GpuOcclusionCullingGlobalContext)); + gpuResidentDrawerContext.Activate(previousGRDContext); + gpuOcclusionContext.Activate(previousOccContext); } } diff --git a/Tests/SRPTests/Projects/MultipleSRP_Tests/Assets/Common/Editor/BaseGraphicsTests.cs b/Tests/SRPTests/Projects/MultipleSRP_Tests/Assets/Common/Editor/BaseGraphicsTests.cs index 6f387d38df0..03b2bc11db1 100644 --- a/Tests/SRPTests/Projects/MultipleSRP_Tests/Assets/Common/Editor/BaseGraphicsTests.cs +++ b/Tests/SRPTests/Projects/MultipleSRP_Tests/Assets/Common/Editor/BaseGraphicsTests.cs @@ -30,8 +30,8 @@ public IEnumerator SetUp() // The assembly rename has been reverted so these should now pass, but the ignores remain to avoid future issues // until the underlying problem with test order is identified and fixed. [Ignore("These tests all fail if they are run after the tests in the MultipleSRP and Preview namespaces")] - [IgnoreGraphicsTest("0001_SwitchPipeline_UniversalRenderPipelineAsset", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("0002_FallbackTest_UniversalRenderPipelineAsset", "Failed from the start when introducing DX12 coverage", runtimePlatforms: new[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] + [IgnoreGraphicsTest("0001_SwitchPipeline_UniversalRenderPipelineAsset", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("0002_FallbackTest_UniversalRenderPipelineAsset", "Failed from the start when introducing DX12 coverage", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] [UnityTest, Category("Base")] [MultipleSRPGraphicsTest("Assets/GraphicsTests")] [Timeout(300 * 1000)] diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/LensFlareTests.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/LensFlareTests.cs index c0ea322564c..afff364ba04 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/LensFlareTests.cs +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/LensFlareTests.cs @@ -329,7 +329,7 @@ public void FlareRendersToColorURP( } [Test, GraphicsTest] - [IgnoreGraphicsTest("", "Occlusion render texture is not supported on GL or WebGPU", graphicsDeviceTypes: new[] { GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLCore, GraphicsDeviceType.WebGPU })] + [TestNotSupportedOn("", "Occlusion render texture is not supported on GL or WebGPU", GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLCore, GraphicsDeviceType.WebGPU)] public void FlareRendersToColorHDRP( GraphicsTestCase testCase, [Values(SRPLensFlareType.Circle, SRPLensFlareType.Polygon, SRPLensFlareType.Ring)] SRPLensFlareType flareType @@ -341,7 +341,7 @@ public void FlareRendersToColorHDRP( } [Test, GraphicsTest] - [IgnoreGraphicsTest("", "Occlusion render texture is not supported on GL or WebGPU", graphicsDeviceTypes: new[] { GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLCore, GraphicsDeviceType.WebGPU })] + [TestNotSupportedOn("", "Occlusion render texture is not supported on GL or WebGPU", GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLCore, GraphicsDeviceType.WebGPU)] public void FlareRendersToOcclusionTexture( GraphicsTestCase testCase, [Values(SRP.URP, SRP.HDRP)] SRP srp @@ -368,7 +368,7 @@ public void FlareRendersToOcclusionTexture( } [Test, GraphicsTest] - [IgnoreGraphicsTest("", "Inline occlusion is only used on GL or WebGPU", graphicsDeviceTypes: new[] { GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLCore, GraphicsDeviceType.WebGPU }, isInclusive: true)] + [TestOnlySupportedOn("", "Inline occlusion is only used on GL or WebGPU", GraphicsDeviceType.OpenGLES3, GraphicsDeviceType.OpenGLCore, GraphicsDeviceType.WebGPU)] public void FlareRendersToColorWithInlineOcclusion( GraphicsTestCase testCase ) diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Scripts/ShaderGraphGraphicsTests.cs b/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Scripts/ShaderGraphGraphicsTests.cs index 6d0fe08d4df..4775081832b 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Scripts/ShaderGraphGraphicsTests.cs +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Scripts/ShaderGraphGraphicsTests.cs @@ -8,23 +8,23 @@ public class ShaderGraphGraphicsTests { - [IgnoreGraphicsTest("InputNodes|SamplerStateTests|UVNodes", "GLES3 renders these tests incorrectly (FB: 1354427)", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Android }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.OpenGLES3 })] - [IgnoreGraphicsTest("InputNodes", "UUM-134140", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.WindowsEditor }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.OpenGLES3 })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.PlayStation4 })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.XboxOne })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.OpenGLCore })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Direct3D12 })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Vulkan })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Switch })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.XboxOneD3D12 })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.GameCoreXboxOne })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.GameCoreXboxSeries })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.PlayStation5 })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.PlayStation5NGGC })] - [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.WebGPU })] - [IgnoreGraphicsTest("TransformNode", "Test is unstable", colorSpaces: new ColorSpace[] { ColorSpace.Linear }, runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Android }, graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Vulkan })] + [IgnoreGraphicsTest("InputNodes|SamplerStateTests|UVNodes", "GLES3 renders these tests incorrectly (FB: 1354427)", RuntimePlatform.Android, GraphicsDeviceType.OpenGLES3)] + [IgnoreGraphicsTest("InputNodes", "UUM-134140", RuntimePlatform.WindowsEditor, GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.OpenGLES3)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.PlayStation4)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.XboxOne)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.Metal)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.OpenGLCore)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.Direct3D12)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.Vulkan)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.Switch)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.XboxOneD3D12)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.GameCoreXboxOne)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.GameCoreXboxSeries)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.PlayStation5)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.PlayStation5NGGC)] + [IgnoreGraphicsTest("InstanceIDWithKeywords", "Platform Independent", GraphicsDeviceType.WebGPU)] + [IgnoreGraphicsTest("TransformNode", "Test is unstable", ColorSpace.Linear, RuntimePlatform.Android, GraphicsDeviceType.Vulkan)] [IgnoreGraphicsTest("InstancedRendering", "Test requires conversion to Render Graph")] [SceneGraphicsTest("Assets/Scenes")] diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/39_SmokeLighting/HDRenderPipelineAsset_APV.asset b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/39_SmokeLighting/HDRenderPipelineAsset_APV.asset index 3c2a79699a9..54466ef5784 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/39_SmokeLighting/HDRenderPipelineAsset_APV.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/39_SmokeLighting/HDRenderPipelineAsset_APV.asset @@ -12,6 +12,204 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0cf1dab834d4ec34195b920ea7bbf9ec, type: 3} m_Name: HDRenderPipelineAsset_APV m_EditorClassIdentifier: + m_Version: 26 + m_ObsoleteFrameSettings: + overrides: 0 + enableShadow: 0 + enableContactShadows: 0 + enableShadowMask: 0 + enableSSR: 0 + enableSSAO: 0 + enableSubsurfaceScattering: 0 + enableTransmission: 0 + enableAtmosphericScattering: 0 + enableVolumetrics: 0 + enableReprojectionForVolumetrics: 0 + enableLightLayers: 0 + enableExposureControl: 1 + diffuseGlobalDimmer: 0 + specularGlobalDimmer: 0 + shaderLitMode: 0 + enableDepthPrepassWithDeferredRendering: 0 + enableTransparentPrepass: 0 + enableMotionVectors: 0 + enableObjectMotionVectors: 0 + enableDecals: 0 + enableRoughRefraction: 0 + enableTransparentPostpass: 0 + enableDistortion: 0 + enablePostprocess: 0 + enableOpaqueObjects: 0 + enableTransparentObjects: 0 + enableRealtimePlanarReflection: 0 + enableMSAA: 0 + enableAsyncCompute: 0 + runLightListAsync: 0 + runSSRAsync: 0 + runSSAOAsync: 0 + runContactShadowsAsync: 0 + runVolumeVoxelizationAsync: 0 + lightLoopSettings: + overrides: 0 + enableDeferredTileAndCluster: 0 + enableComputeLightEvaluation: 0 + enableComputeLightVariants: 0 + enableComputeMaterialVariants: 0 + enableFptlForForwardOpaque: 0 + enableBigTilePrepass: 0 + isFptlEnabled: 0 + m_ObsoleteBakedOrCustomReflectionFrameSettings: + overrides: 0 + enableShadow: 0 + enableContactShadows: 0 + enableShadowMask: 0 + enableSSR: 0 + enableSSAO: 0 + enableSubsurfaceScattering: 0 + enableTransmission: 0 + enableAtmosphericScattering: 0 + enableVolumetrics: 0 + enableReprojectionForVolumetrics: 0 + enableLightLayers: 0 + enableExposureControl: 1 + diffuseGlobalDimmer: 0 + specularGlobalDimmer: 0 + shaderLitMode: 0 + enableDepthPrepassWithDeferredRendering: 0 + enableTransparentPrepass: 0 + enableMotionVectors: 0 + enableObjectMotionVectors: 0 + enableDecals: 0 + enableRoughRefraction: 0 + enableTransparentPostpass: 0 + enableDistortion: 0 + enablePostprocess: 0 + enableOpaqueObjects: 0 + enableTransparentObjects: 0 + enableRealtimePlanarReflection: 0 + enableMSAA: 0 + enableAsyncCompute: 0 + runLightListAsync: 0 + runSSRAsync: 0 + runSSAOAsync: 0 + runContactShadowsAsync: 0 + runVolumeVoxelizationAsync: 0 + lightLoopSettings: + overrides: 0 + enableDeferredTileAndCluster: 0 + enableComputeLightEvaluation: 0 + enableComputeLightVariants: 0 + enableComputeMaterialVariants: 0 + enableFptlForForwardOpaque: 0 + enableBigTilePrepass: 0 + isFptlEnabled: 0 + m_ObsoleteRealtimeReflectionFrameSettings: + overrides: 0 + enableShadow: 0 + enableContactShadows: 0 + enableShadowMask: 0 + enableSSR: 0 + enableSSAO: 0 + enableSubsurfaceScattering: 0 + enableTransmission: 0 + enableAtmosphericScattering: 0 + enableVolumetrics: 0 + enableReprojectionForVolumetrics: 0 + enableLightLayers: 0 + enableExposureControl: 1 + diffuseGlobalDimmer: 0 + specularGlobalDimmer: 0 + shaderLitMode: 0 + enableDepthPrepassWithDeferredRendering: 0 + enableTransparentPrepass: 0 + enableMotionVectors: 0 + enableObjectMotionVectors: 0 + enableDecals: 0 + enableRoughRefraction: 0 + enableTransparentPostpass: 0 + enableDistortion: 0 + enablePostprocess: 0 + enableOpaqueObjects: 0 + enableTransparentObjects: 0 + enableRealtimePlanarReflection: 0 + enableMSAA: 0 + enableAsyncCompute: 0 + runLightListAsync: 0 + runSSRAsync: 0 + runSSAOAsync: 0 + runContactShadowsAsync: 0 + runVolumeVoxelizationAsync: 0 + lightLoopSettings: + overrides: 0 + enableDeferredTileAndCluster: 0 + enableComputeLightEvaluation: 0 + enableComputeLightVariants: 0 + enableComputeMaterialVariants: 0 + enableFptlForForwardOpaque: 0 + enableBigTilePrepass: 0 + isFptlEnabled: 0 + m_ObsoleteDefaultVolumeProfile: {fileID: 11400000, guid: 6da6f79984c6a5e40ae22ead3a2ecfec, type: 2} + m_ObsoleteDefaultLookDevProfile: {fileID: 0} + m_ObsoleteFrameSettingsMovedToDefaultSettings: + bitDatas: + data1: 87872878411613 + data2: 4539628425463136280 + lodBias: 1 + lodBiasMode: 0 + lodBiasQualityLevel: 0 + maximumLODLevel: 0 + maximumLODLevelMode: 0 + maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 20 + sssCustomDownsampleSteps: 0 + msaaMode: 0 + materialQuality: 0 + m_ObsoleteBakedOrCustomReflectionFrameSettingsMovedToDefaultSettings: + bitDatas: + data1: 86936571215645 + data2: 4539628424389459992 + lodBias: 1 + lodBiasMode: 0 + lodBiasQualityLevel: 0 + maximumLODLevel: 0 + maximumLODLevelMode: 0 + maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 20 + sssCustomDownsampleSteps: 0 + msaaMode: 0 + materialQuality: 0 + m_ObsoleteRealtimeReflectionFrameSettingsMovedToDefaultSettings: + bitDatas: + data1: 87288601124637 + data2: 4539628424389459992 + lodBias: 1 + lodBiasMode: 0 + lodBiasQualityLevel: 0 + maximumLODLevel: 0 + maximumLODLevelMode: 0 + maximumLODLevelQualityLevel: 0 + sssQualityMode: 0 + sssQualityLevel: 0 + sssCustomSampleBudget: 20 + sssCustomDownsampleSteps: 0 + msaaMode: 0 + materialQuality: 0 + m_ObsoleteBeforeTransparentCustomPostProcesses: [] + m_ObsoleteBeforePostProcessCustomPostProcesses: [] + m_ObsoleteAfterPostProcessCustomPostProcesses: [] + m_ObsoleteBeforeTAACustomPostProcesses: [] + m_ObsoleteShaderVariantLogLevel: 0 + m_ObsoleteLensAttenuation: 0 + m_ObsoleteDiffusionProfileSettingsList: + - {fileID: 11400000, guid: cbe1ee9036c47b84ba1b8b3dbcde2aff, type: 2} + - {fileID: 11400000, guid: 38c0905fbe269274782e939ce4393d85, type: 2} + m_PrefilterUseLegacyLightmaps: 0 + m_PrefilterUseLightmapBicubicSampling: 0 + m_ShouldUseConservativeEnclosingSphere: 0 m_RenderPipelineSettings: supportShadowMask: 1 supportSSR: 1 @@ -19,6 +217,7 @@ MonoBehaviour: supportSSAO: 1 supportSSGI: 0 supportSubsurfaceScattering: 1 + subsurfaceScatteringAttenuation: 1 sssSampleBudget: m_Values: 140000002800000050000000 m_SchemaId: @@ -34,13 +233,13 @@ MonoBehaviour: supportWater: 0 waterSimulationResolution: 128 supportWaterExclusion: 1 - supportWaterDeformation: 1 - deformationAtlasSize: 512 - maximumDeformerCount: 64 - supportWaterFoam: 1 - foamAtlasSize: 512 + supportWaterHorizontalDeformation: 0 + supportWaterDecals: 1 + waterDecalAtlasSize: 1024 + maximumWaterDecalCount: 48 waterScriptInteractionsMode: 0 waterFullCPUSimulation: 0 + waterCausticsMeshResolution: 256 supportComputeThickness: 0 computeThicknessResolution: 1 computeThicknessLayerMask: @@ -51,7 +250,9 @@ MonoBehaviour: supportTransparentDepthPrepass: 1 supportTransparentDepthPostpass: 1 colorBufferFormat: 48 + depthBufferFormat: 0 supportCustomPass: 1 + supportVariableRateShading: 1 customBufferFormat: 12 supportedLitShaderMode: 3 planarReflectionResolution: @@ -149,6 +350,7 @@ MonoBehaviour: maxPunctualShadowMapResolution: 2048 maxAreaShadowMapResolution: 2048 supportScreenSpaceShadows: 0 + supportContactShadows: 1 maxScreenSpaceShadowSlots: 4 screenSpaceShadowBufferFormat: 48 decalSettings: @@ -168,10 +370,19 @@ MonoBehaviour: enabled: 0 useMipBias: 0 advancedUpscalersByPriority: + advancedUpscalerNames: [] DLSSPerfQualitySetting: 0 DLSSInjectionPoint: 0 + TAAUInjectionPoint: 0 + STPInjectionPoint: 0 + defaultInjectionPoint: 2 DLSSUseOptimalSettings: 0 DLSSSharpness: 0 + DLSSRenderPresetForQuality: 0 + DLSSRenderPresetForBalanced: 0 + DLSSRenderPresetForPerformance: 0 + DLSSRenderPresetForUltraPerformance: 0 + DLSSRenderPresetForDLAA: 0 FSR2EnableSharpness: 0 FSR2Sharpness: 0 FSR2UseOptimalSettings: 0 @@ -213,6 +424,10 @@ MonoBehaviour: DoFResolution: 040000000200000001000000 DoFHighQualityFiltering: 000101 DoFPhysicallyBased: 000000 + AdaptiveSamplingWeight: + - 0.5 + - 0.75 + - 2 LimitManualRangeNearBlur: 000000 MotionBlurSampleCount: 04000000080000000c000000 BloomRes: 040000000200000002000000 @@ -332,8 +547,7 @@ MonoBehaviour: enableSRPBatcher: 1 availableMaterialQualityLevels: -1 m_DefaultMaterialQualityLevel: 4 - diffusionProfileSettings: {fileID: 11400000, guid: cbe1ee9036c47b84ba1b8b3dbcde2aff, - type: 2} + diffusionProfileSettings: {fileID: 11400000, guid: cbe1ee9036c47b84ba1b8b3dbcde2aff, type: 2} m_VolumeProfile: {fileID: 0} virtualTexturingSettings: streamingCpuCacheSizeInMegaBytes: 256 @@ -342,204 +556,6 @@ MonoBehaviour: streamingGpuCacheSettings: - format: 0 sizeInMegaBytes: 128 - m_UseRenderGraph: 1 m_CompositorCustomVolumeComponentsList: m_InjectionPoint: 1 m_CustomPostProcessTypesAsString: [] - m_Version: 25 - m_ObsoleteFrameSettings: - overrides: 0 - enableShadow: 0 - enableContactShadows: 0 - enableShadowMask: 0 - enableSSR: 0 - enableSSAO: 0 - enableSubsurfaceScattering: 0 - enableTransmission: 0 - enableAtmosphericScattering: 0 - enableVolumetrics: 0 - enableReprojectionForVolumetrics: 0 - enableLightLayers: 0 - enableExposureControl: 1 - diffuseGlobalDimmer: 0 - specularGlobalDimmer: 0 - shaderLitMode: 0 - enableDepthPrepassWithDeferredRendering: 0 - enableTransparentPrepass: 0 - enableMotionVectors: 0 - enableObjectMotionVectors: 0 - enableDecals: 0 - enableRoughRefraction: 0 - enableTransparentPostpass: 0 - enableDistortion: 0 - enablePostprocess: 0 - enableOpaqueObjects: 0 - enableTransparentObjects: 0 - enableRealtimePlanarReflection: 0 - enableMSAA: 0 - enableAsyncCompute: 0 - runLightListAsync: 0 - runSSRAsync: 0 - runSSAOAsync: 0 - runContactShadowsAsync: 0 - runVolumeVoxelizationAsync: 0 - lightLoopSettings: - overrides: 0 - enableDeferredTileAndCluster: 0 - enableComputeLightEvaluation: 0 - enableComputeLightVariants: 0 - enableComputeMaterialVariants: 0 - enableFptlForForwardOpaque: 0 - enableBigTilePrepass: 0 - isFptlEnabled: 0 - m_ObsoleteBakedOrCustomReflectionFrameSettings: - overrides: 0 - enableShadow: 0 - enableContactShadows: 0 - enableShadowMask: 0 - enableSSR: 0 - enableSSAO: 0 - enableSubsurfaceScattering: 0 - enableTransmission: 0 - enableAtmosphericScattering: 0 - enableVolumetrics: 0 - enableReprojectionForVolumetrics: 0 - enableLightLayers: 0 - enableExposureControl: 1 - diffuseGlobalDimmer: 0 - specularGlobalDimmer: 0 - shaderLitMode: 0 - enableDepthPrepassWithDeferredRendering: 0 - enableTransparentPrepass: 0 - enableMotionVectors: 0 - enableObjectMotionVectors: 0 - enableDecals: 0 - enableRoughRefraction: 0 - enableTransparentPostpass: 0 - enableDistortion: 0 - enablePostprocess: 0 - enableOpaqueObjects: 0 - enableTransparentObjects: 0 - enableRealtimePlanarReflection: 0 - enableMSAA: 0 - enableAsyncCompute: 0 - runLightListAsync: 0 - runSSRAsync: 0 - runSSAOAsync: 0 - runContactShadowsAsync: 0 - runVolumeVoxelizationAsync: 0 - lightLoopSettings: - overrides: 0 - enableDeferredTileAndCluster: 0 - enableComputeLightEvaluation: 0 - enableComputeLightVariants: 0 - enableComputeMaterialVariants: 0 - enableFptlForForwardOpaque: 0 - enableBigTilePrepass: 0 - isFptlEnabled: 0 - m_ObsoleteRealtimeReflectionFrameSettings: - overrides: 0 - enableShadow: 0 - enableContactShadows: 0 - enableShadowMask: 0 - enableSSR: 0 - enableSSAO: 0 - enableSubsurfaceScattering: 0 - enableTransmission: 0 - enableAtmosphericScattering: 0 - enableVolumetrics: 0 - enableReprojectionForVolumetrics: 0 - enableLightLayers: 0 - enableExposureControl: 1 - diffuseGlobalDimmer: 0 - specularGlobalDimmer: 0 - shaderLitMode: 0 - enableDepthPrepassWithDeferredRendering: 0 - enableTransparentPrepass: 0 - enableMotionVectors: 0 - enableObjectMotionVectors: 0 - enableDecals: 0 - enableRoughRefraction: 0 - enableTransparentPostpass: 0 - enableDistortion: 0 - enablePostprocess: 0 - enableOpaqueObjects: 0 - enableTransparentObjects: 0 - enableRealtimePlanarReflection: 0 - enableMSAA: 0 - enableAsyncCompute: 0 - runLightListAsync: 0 - runSSRAsync: 0 - runSSAOAsync: 0 - runContactShadowsAsync: 0 - runVolumeVoxelizationAsync: 0 - lightLoopSettings: - overrides: 0 - enableDeferredTileAndCluster: 0 - enableComputeLightEvaluation: 0 - enableComputeLightVariants: 0 - enableComputeMaterialVariants: 0 - enableFptlForForwardOpaque: 0 - enableBigTilePrepass: 0 - isFptlEnabled: 0 - m_ObsoleteDefaultVolumeProfile: {fileID: 11400000, guid: 6da6f79984c6a5e40ae22ead3a2ecfec, - type: 2} - m_ObsoleteDefaultLookDevProfile: {fileID: 0} - m_ObsoleteFrameSettingsMovedToDefaultSettings: - bitDatas: - data1: 87872878411613 - data2: 4539628425463136280 - lodBias: 1 - lodBiasMode: 0 - lodBiasQualityLevel: 0 - maximumLODLevel: 0 - maximumLODLevelMode: 0 - maximumLODLevelQualityLevel: 0 - sssQualityMode: 0 - sssQualityLevel: 0 - sssCustomSampleBudget: 20 - sssCustomDownsampleSteps: 0 - msaaMode: 0 - materialQuality: 0 - m_ObsoleteBakedOrCustomReflectionFrameSettingsMovedToDefaultSettings: - bitDatas: - data1: 86936571215645 - data2: 4539628424389459992 - lodBias: 1 - lodBiasMode: 0 - lodBiasQualityLevel: 0 - maximumLODLevel: 0 - maximumLODLevelMode: 0 - maximumLODLevelQualityLevel: 0 - sssQualityMode: 0 - sssQualityLevel: 0 - sssCustomSampleBudget: 20 - sssCustomDownsampleSteps: 0 - msaaMode: 0 - materialQuality: 0 - m_ObsoleteRealtimeReflectionFrameSettingsMovedToDefaultSettings: - bitDatas: - data1: 87288601124637 - data2: 4539628424389459992 - lodBias: 1 - lodBiasMode: 0 - lodBiasQualityLevel: 0 - maximumLODLevel: 0 - maximumLODLevelMode: 0 - maximumLODLevelQualityLevel: 0 - sssQualityMode: 0 - sssQualityLevel: 0 - sssCustomSampleBudget: 20 - sssCustomDownsampleSteps: 0 - msaaMode: 0 - materialQuality: 0 - m_ObsoleteBeforeTransparentCustomPostProcesses: [] - m_ObsoleteBeforePostProcessCustomPostProcesses: [] - m_ObsoleteAfterPostProcessCustomPostProcesses: [] - m_ObsoleteBeforeTAACustomPostProcesses: [] - m_ObsoleteShaderVariantLogLevel: 0 - m_ObsoleteLensAttenuation: 0 - m_ObsoleteDiffusionProfileSettingsList: - - {fileID: 11400000, guid: cbe1ee9036c47b84ba1b8b3dbcde2aff, type: 2} - - {fileID: 11400000, guid: 38c0905fbe269274782e939ce4393d85, type: 2} - m_PrefilterUseLegacyLightmaps: 0 diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTest.unity b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTest.unity index e326b41ce6d..e5e4ba14e4b 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTest.unity +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTest.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe6fbe3ed00a7fb19b7fa6faf3faca255b297e9d5b300880c47a51e2dae6eda1 -size 15137 +oid sha256:6cc9b2fb15ed7ab4ba3341083a993f670d43373d4dd43478339dd5fa9292bbd2 +size 19860 diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting new file mode 100644 index 00000000000..38083d6d688 --- /dev/null +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting @@ -0,0 +1,77 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!850595691 &4890085278179872738 +LightingSettings: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: DistortionTestSettings + serializedVersion: 10 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_RealtimeEnvironmentLighting: 1 + m_BounceScale: 1 + m_AlbedoBoost: 1 + m_IndirectOutputScale: 1 + m_UsingShadowmask: 1 + m_BakeBackend: 1 + m_LightmapMaxSize: 1024 + m_LightmapSizeFixed: 0 + m_UseMipmapLimits: 1 + m_BakeResolution: 40 + m_Padding: 2 + m_LightmapCompression: 3 + m_LightmapPackingMode: 1 + m_LightmapPackingMethod: 0 + m_XAtlasPackingAttempts: 16384 + m_XAtlasBruteForce: 0 + m_XAtlasBlockAlign: 0 + m_XAtlasRepackUnderutilizedLightmaps: 1 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAO: 0 + m_MixedBakeMode: 2 + m_LightmapsBakeMode: 1 + m_FilterMode: 1 + m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} + m_ExportTrainingData: 0 + m_EnableWorkerProcessBaking: 1 + m_TrainingDataDestination: TrainingData + m_RealtimeResolution: 2 + m_ForceWhiteAlbedo: 0 + m_ForceUpdates: 0 + m_PVRCulling: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_LightProbeSampleCountMultiplier: 4 + m_PVRBounces: 2 + m_PVRMinBounces: 2 + m_PVREnvironmentImportanceSampling: 1 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_RespectSceneVisibilityWhenBakingGI: 0 + m_DirectLightSamplingMode: 2 + m_DirectRISCandidateCount: 4 + m_IndirectLightSamplingMode: 1 + m_IndirectRISCandidateCount: 1 + m_LightAccelerationStructure: 0 + m_LightGridMaxCells: 262144 + m_DirectEmissiveSamplingMode: 2 + m_IndirectEmissiveSamplingMode: 1 diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting.meta b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting.meta new file mode 100644 index 00000000000..7d713e20bf2 --- /dev/null +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/VFXTests/GraphicsTests/DistortionTestSettings.lighting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4388a43c0b69c467287abfd71dd4092d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 4890085278179872738 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRP/HDRenderPipelineAsset.asset b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRP/HDRenderPipelineAsset.asset index bd70dfcd765..32dfdec7b70 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRP/HDRenderPipelineAsset.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRP/HDRenderPipelineAsset.asset @@ -12,7 +12,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0cf1dab834d4ec34195b920ea7bbf9ec, type: 3} m_Name: HDRenderPipelineAsset m_EditorClassIdentifier: - m_Version: 25 + m_Version: 26 m_ObsoleteFrameSettings: overrides: 0 enableShadow: 0 @@ -148,8 +148,7 @@ MonoBehaviour: enableFptlForForwardOpaque: 0 enableBigTilePrepass: 0 isFptlEnabled: 0 - m_ObsoleteDefaultVolumeProfile: {fileID: 11400000, guid: 6da6f79984c6a5e40ae22ead3a2ecfec, - type: 2} + m_ObsoleteDefaultVolumeProfile: {fileID: 11400000, guid: 6da6f79984c6a5e40ae22ead3a2ecfec, type: 2} m_ObsoleteDefaultLookDevProfile: {fileID: 0} m_ObsoleteFrameSettingsMovedToDefaultSettings: bitDatas: @@ -210,6 +209,7 @@ MonoBehaviour: - {fileID: 11400000, guid: 38c0905fbe269274782e939ce4393d85, type: 2} m_PrefilterUseLegacyLightmaps: 0 m_PrefilterUseLightmapBicubicSampling: 0 + m_ShouldUseConservativeEnclosingSphere: 0 m_RenderPipelineSettings: supportShadowMask: 1 supportSSR: 1 @@ -239,6 +239,7 @@ MonoBehaviour: maximumWaterDecalCount: 48 waterScriptInteractionsMode: 0 waterFullCPUSimulation: 0 + waterCausticsMeshResolution: 256 supportComputeThickness: 0 computeThicknessResolution: 1 computeThicknessLayerMask: @@ -249,6 +250,7 @@ MonoBehaviour: supportTransparentDepthPrepass: 1 supportTransparentDepthPostpass: 1 colorBufferFormat: 48 + depthBufferFormat: 0 supportCustomPass: 1 supportVariableRateShading: 1 customBufferFormat: 12 @@ -348,6 +350,7 @@ MonoBehaviour: maxPunctualShadowMapResolution: 2048 maxAreaShadowMapResolution: 2048 supportScreenSpaceShadows: 0 + supportContactShadows: 1 maxScreenSpaceShadowSlots: 4 screenSpaceShadowBufferFormat: 48 decalSettings: @@ -367,6 +370,7 @@ MonoBehaviour: enabled: 0 useMipBias: 0 advancedUpscalersByPriority: + advancedUpscalerNames: [] DLSSPerfQualitySetting: 0 DLSSInjectionPoint: 0 TAAUInjectionPoint: 0 @@ -374,6 +378,11 @@ MonoBehaviour: defaultInjectionPoint: 2 DLSSUseOptimalSettings: 0 DLSSSharpness: 0 + DLSSRenderPresetForQuality: 0 + DLSSRenderPresetForBalanced: 0 + DLSSRenderPresetForPerformance: 0 + DLSSRenderPresetForUltraPerformance: 0 + DLSSRenderPresetForDLAA: 0 FSR2EnableSharpness: 0 FSR2Sharpness: 0 FSR2UseOptimalSettings: 0 @@ -538,8 +547,7 @@ MonoBehaviour: enableSRPBatcher: 1 availableMaterialQualityLevels: -1 m_DefaultMaterialQualityLevel: 4 - diffusionProfileSettings: {fileID: 11400000, guid: cbe1ee9036c47b84ba1b8b3dbcde2aff, - type: 2} + diffusionProfileSettings: {fileID: 11400000, guid: cbe1ee9036c47b84ba1b8b3dbcde2aff, type: 2} m_VolumeProfile: {fileID: 0} virtualTexturingSettings: streamingCpuCacheSizeInMegaBytes: 256 @@ -548,7 +556,6 @@ MonoBehaviour: streamingGpuCacheSettings: - format: 0 sizeInMegaBytes: 128 - m_UseRenderGraph: 1 m_CompositorCustomVolumeComponentsList: m_InjectionPoint: 1 m_CustomPostProcessTypesAsString: [] diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset index 93d50fa1e02..cc8944fee97 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset @@ -175,7 +175,6 @@ MonoBehaviour: - rid: 6023113869122600972 - rid: 6023113869122600973 - rid: 6023113869122600974 - - rid: 6023113869122600975 - rid: 6023113869122600976 - rid: 6023113869122600977 - rid: 6023113869122600978 @@ -196,6 +195,9 @@ MonoBehaviour: - rid: 6023113869122600993 - rid: 6023113869122600994 - rid: 6023113869122600995 + - rid: 1256477497507971072 + - rid: 1256477497507971073 + - rid: 1256477497507971074 m_RuntimeSettings: m_List: [] renderingLayerNames: @@ -241,9 +243,36 @@ MonoBehaviour: references: version: 2 RefIds: + - rid: 1256477497507971072 + type: {class: WorldRenderPipelineResources, ns: UnityEngine.PathTracing.Core, asm: Unity.PathTracing.Runtime} + data: + _version: 3 + _blitCubemap: {fileID: 7200000, guid: 5a992812cb320d146a66cc600200cce7, type: 3} + _blitGrayScaleCookie: {fileID: 7200000, guid: 557fa399e33bf7647bda5697c5c158df, type: 3} + _setAlphaChannelShader: {fileID: 7200000, guid: 5efaea0e81c66334aa9d062d6573e6fd, type: 3} + _environmentImportanceSamplingBuild: {fileID: 7200000, guid: 5bb2534d2411d344cbc54f880232640f, type: 3} + _skyBoxMesh: {fileID: 4300000, guid: 0529e6c5f6dea8c4a8c2835ed7de57cb, type: 2} + _sixFaceSkyBoxMesh: {fileID: 4300000, guid: a80925ceebd011741b42509226cefc74, type: 2} + _buildLightGridShader: {fileID: 7200000, guid: 16e47c1641bd0104e92b624601457bb0, type: 3} + - rid: 1256477497507971073 + type: {class: RayTracingRenderPipelineResources, ns: UnityEngine.Rendering.UnifiedRayTracing, asm: Unity.UnifiedRayTracing.Runtime} + data: + m_Version: 1 + m_GeometryPoolKernels: {fileID: 7200000, guid: 98e3d58cae7210c4786f67f504c9e899, type: 3} + m_CopyBuffer: {fileID: 7200000, guid: 1b95b5dcf48d1914c9e1e7405c7660e3, type: 3} + m_CopyPositions: {fileID: 7200000, guid: 1ad53a96b58d3c3488dde4f14db1aaeb, type: 3} + m_BitHistogram: {fileID: 7200000, guid: 8670f7ce4b60cef43bed36148aa1b0a2, type: 3} + m_BlockReducePart: {fileID: 7200000, guid: 4e034cc8ea2635c4e9f063e5ddc7ea7a, type: 3} + m_BlockScan: {fileID: 7200000, guid: 4d6d5de35fa45ef4a92119397a045cc9, type: 3} + m_BuildHlbvh: {fileID: 7200000, guid: 2d70cd6be91bd7843a39a54b51c15b13, type: 3} + m_RestructureBvh: {fileID: 7200000, guid: 56641cb88dcb31a4398a4997ef7a7a8c, type: 3} + m_Scatter: {fileID: 7200000, guid: a2eaeefdac4637a44b734e85b7be9186, type: 3} + - rid: 1256477497507971074 + type: {class: ColorCheckerResources, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} + data: + m_ColorCheckerMaterial: {fileID: 2100000, guid: 7a1044256d39dba4aa777255550527bf, type: 2} - rid: 6023113869122600960 - type: {class: RenderingPathFrameSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: RenderingPathFrameSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_Camera: @@ -295,476 +324,272 @@ MonoBehaviour: msaaMode: 1 materialQuality: 0 - rid: 6023113869122600961 - type: {class: HDRenderPipelineEditorTextures, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRenderPipelineEditorTextures, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_MoonAlbedo: {fileID: 2800000, guid: cce9f0cf7e606e547a7317aedb4ad6d9, type: 3} - rid: 6023113869122600962 - type: {class: HDRenderPipelineRuntimeAssets, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRenderPipelineRuntimeAssets, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: - m_DefaultDiffusionProfile: {fileID: 11400000, guid: 2b7005ba3a4d8474b8cdc34141ad766e, - type: 2} - m_ComputeMaterialLibrary: {fileID: 11400000, guid: 833ab0ec618db411699ea8cb1a221d0d, - type: 2} - m_EmissiveCylinderMesh: {fileID: 2534964839176971238, guid: accb6d90f0d50fe4ca0f68159b4323de, - type: 3} - m_EmissiveQuadMesh: {fileID: 4300000, guid: 1d5a8595286f94f4bb54171d49f473c3, - type: 3} + m_DefaultDiffusionProfile: {fileID: 11400000, guid: 2b7005ba3a4d8474b8cdc34141ad766e, type: 2} + m_ComputeMaterialLibrary: {fileID: 11400000, guid: 833ab0ec618db411699ea8cb1a221d0d, type: 2} + m_EmissiveCylinderMesh: {fileID: 2534964839176971238, guid: accb6d90f0d50fe4ca0f68159b4323de, type: 3} + m_EmissiveQuadMesh: {fileID: 4300000, guid: 1d5a8595286f94f4bb54171d49f473c3, type: 3} m_SphereMesh: {fileID: 4300000, guid: 9e0af751bc36ea146940ba245193e28c, type: 3} - rid: 6023113869122600963 - type: {class: LookDevVolumeProfileSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: LookDevVolumeProfileSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 - m_VolumeProfile: {fileID: 11400000, guid: b30e5a4359d3a8d949c286f694ae573a, - type: 2} + m_VolumeProfile: {fileID: 11400000, guid: b30e5a4359d3a8d949c286f694ae573a, type: 2} - rid: 6023113869122600964 - type: {class: HDRenderPipelineRuntimeShaders, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRenderPipelineRuntimeShaders, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: - m_DefaultShader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, - type: 3} - m_CameraMotionVectorsPS: {fileID: 4800000, guid: 035941b63024d1943af48811c1db20d9, - type: 3} - m_ColorPyramidPS: {fileID: 4800000, guid: 2fcfb8d92f45e4549b3f0bad5d0654bf, - type: 3} - m_ColorPyramidCS: {fileID: 7200000, guid: 4e3267a1135742441a14298d8dcac04a, - type: 3} - m_DepthPyramidCS: {fileID: 7200000, guid: 64a553bb564274041906f78ffba955e4, - type: 3} + m_DefaultShader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3} + m_CameraMotionVectorsPS: {fileID: 4800000, guid: 035941b63024d1943af48811c1db20d9, type: 3} + m_ColorPyramidPS: {fileID: 4800000, guid: 2fcfb8d92f45e4549b3f0bad5d0654bf, type: 3} + m_ColorPyramidCS: {fileID: 7200000, guid: 4e3267a1135742441a14298d8dcac04a, type: 3} + m_DepthPyramidCS: {fileID: 7200000, guid: 64a553bb564274041906f78ffba955e4, type: 3} m_MaxZCS: {fileID: 7200000, guid: e95abf8c7230c344595f41c4dd5ff517, type: 3} - m_ApplyDistortionPS: {fileID: 4800000, guid: 02ae56f4306413c4a96dcf005cde1971, - type: 3} - m_CustomPassUtils: {fileID: 4800000, guid: 7e3722d0388000848acb25fd3cc8c088, - type: 3} - m_CustomPassRenderersUtils: {fileID: 4800000, guid: cef5ba33ee5063d4c8b495d2292e394d, - type: 3} - m_ClearStencilBufferPS: {fileID: 4800000, guid: 8ea49ef16606acd489439e676ab84040, - type: 3} - m_CopyStencilBufferPS: {fileID: 4800000, guid: 3d1574f1cdfa0ce4995f9bc79ed7f8ec, - type: 3} - m_CopyDepthBufferPS: {fileID: 4800000, guid: 42dfcc8fe803ece4096c58630689982f, - type: 3} + m_ApplyDistortionPS: {fileID: 4800000, guid: 02ae56f4306413c4a96dcf005cde1971, type: 3} + m_CustomPassUtils: {fileID: 4800000, guid: 7e3722d0388000848acb25fd3cc8c088, type: 3} + m_CustomPassRenderersUtils: {fileID: 4800000, guid: cef5ba33ee5063d4c8b495d2292e394d, type: 3} + m_ClearStencilBufferPS: {fileID: 4800000, guid: 8ea49ef16606acd489439e676ab84040, type: 3} + m_CopyStencilBufferPS: {fileID: 4800000, guid: 3d1574f1cdfa0ce4995f9bc79ed7f8ec, type: 3} + m_CopyDepthBufferPS: {fileID: 4800000, guid: 42dfcc8fe803ece4096c58630689982f, type: 3} m_BlitPS: {fileID: 4800000, guid: e22fc1942c664490980b8793dd4a163d, type: 3} - m_BlitColorAndDepthPS: {fileID: 4800000, guid: b22ad378c678348729d3a3f981b9f270, - type: 3} - m_DownsampleDepthPS: {fileID: 4800000, guid: 67d6171b0acc6554aad48c845ec7e67f, - type: 3} - m_UpsampleTransparentPS: {fileID: 4800000, guid: 2ad7ce40f0dbaf64dadef1f58d8524d3, - type: 3} - m_ResolveStencilCS: {fileID: 7200000, guid: 65b89cac5f286b043a31bf8041776ee7, - type: 3} - m_DebugDisplayLatlongPS: {fileID: 4800000, guid: c1d1d149a043a5349ba367da6c2051ba, - type: 3} - m_DebugViewMaterialGBufferPS: {fileID: 4800000, guid: 439949ea1bfa91b4ba0d04269fcde33d, - type: 3} - m_DebugViewTilesPS: {fileID: 4800000, guid: c7c2bd17b06ceb4468e14081aaf1b96f, - type: 3} - m_DebugFullScreenPS: {fileID: 4800000, guid: e874aca2df8300a488258738c31f85cf, - type: 3} - m_DebugColorPickerPS: {fileID: 4800000, guid: 8137b807709e178498f22ed710864bb0, - type: 3} - m_DebugExposurePS: {fileID: 4800000, guid: 0ef322534f047a34c96d29419d56d17a, - type: 3} + m_BlitColorAndDepthPS: {fileID: 4800000, guid: b22ad378c678348729d3a3f981b9f270, type: 3} + m_DownsampleDepthPS: {fileID: 4800000, guid: 67d6171b0acc6554aad48c845ec7e67f, type: 3} + m_UpsampleTransparentPS: {fileID: 4800000, guid: 2ad7ce40f0dbaf64dadef1f58d8524d3, type: 3} + m_ResolveStencilCS: {fileID: 7200000, guid: 65b89cac5f286b043a31bf8041776ee7, type: 3} + m_DebugDisplayLatlongPS: {fileID: 4800000, guid: c1d1d149a043a5349ba367da6c2051ba, type: 3} + m_DebugViewMaterialGBufferPS: {fileID: 4800000, guid: 439949ea1bfa91b4ba0d04269fcde33d, type: 3} + m_DebugViewTilesPS: {fileID: 4800000, guid: c7c2bd17b06ceb4468e14081aaf1b96f, type: 3} + m_DebugFullScreenPS: {fileID: 4800000, guid: e874aca2df8300a488258738c31f85cf, type: 3} + m_DebugColorPickerPS: {fileID: 4800000, guid: 8137b807709e178498f22ed710864bb0, type: 3} + m_DebugExposurePS: {fileID: 4800000, guid: 0ef322534f047a34c96d29419d56d17a, type: 3} m_DebugHDRPS: {fileID: 4800000, guid: 9bc5229549892084da43ad706d84f1bc, type: 3} - m_DebugLightVolumePS: {fileID: 4800000, guid: 8e706c0e71fcec34a8f5c9713e5e2943, - type: 3} - m_DebugLightVolumeCS: {fileID: 7200000, guid: f5d5d21faef5cf445ac2c5d8ff9c4184, - type: 3} - m_DebugBlitQuad: {fileID: 4800000, guid: cf5ca5b6ef18b3f429ed707ee9ceac9f, - type: 3} - m_DebugViewVirtualTexturingBlit: {fileID: 4800000, guid: 55d195396b03b804eb78c92d468e3c8e, - type: 3} - m_MaterialError: {fileID: 4800000, guid: 79a966a5200a456188dec0d48d805614, - type: 3} - m_MaterialLoading: {fileID: 4800000, guid: 392325671f122f540be9033ca5ae7a56, - type: 3} - m_ClearDebugBufferCS: {fileID: 7200000, guid: 7fc6041d5cf70004aa33bb1ac64e3c06, - type: 3} - m_DebugWaveformPS: {fileID: 4800000, guid: 0024f9d09a828734192f3e1cd5931745, - type: 3} - m_DebugWaveformCS: {fileID: 7200000, guid: 62b785f79355903428a21d5d8f8aeabe, - type: 3} - m_DebugVectorscopePS: {fileID: 4800000, guid: 7a09af24008164d40ae85ccd6bf87e17, - type: 3} - m_DebugVectorscopeCS: {fileID: 7200000, guid: 6a70efb18a2b2964c8eb0fc04aba20e9, - type: 3} - m_DebugImageHistogramCS: {fileID: 7200000, guid: 52cc17ef5a5ffc443a5c142f9b745a85, - type: 3} - m_DebugHDRxyMappingCS: {fileID: 7200000, guid: f055d2983d992b64494f1a03fc725cde, - type: 3} - m_ProbeVolumeSamplingDebugComputeShader: {fileID: 7200000, guid: 22de19bc461f84742857dd64c56b0397, - type: 3} - m_PlanarReflectionFilteringCS: {fileID: 7200000, guid: 9f3f8a01b8caaaa4595591dc96d43dd2, - type: 3} - m_ScreenSpaceGlobalIlluminationCS: {fileID: 7200000, guid: 96170a954eb538b40a5ff369552c3629, - type: 3} - m_ScreenSpaceReflectionsCS: {fileID: 7200000, guid: d1de9ac7d9016204da289affe9677942, - type: 3} - m_ClearDispatchIndirectCS: {fileID: 7200000, guid: fc1f553acb80a6446a32d33e403d0656, - type: 3} - m_ClearLightListsCS: {fileID: 7200000, guid: 743eb3491795b9545955695d591195a1, - type: 3} - m_BuildDispatchIndirectCS: {fileID: 7200000, guid: 4eb1b418be7044c40bb5200496c50f14, - type: 3} - m_BuildScreenAABBCS: {fileID: 7200000, guid: 728dce960f8a9c44bbc3abb3b851d8f6, - type: 3} - m_BuildPerTileLightListCS: {fileID: 7200000, guid: 65af3444cbf4b3747a4dead7ee00cfee, - type: 3} - m_BuildPerBigTileLightListCS: {fileID: 7200000, guid: 5ee1f9d6e09abe045b2f5e0b784b9072, - type: 3} - m_BuildPerVoxelLightListCS: {fileID: 7200000, guid: 0bb1b7e0ddcd5c44baf3ddc7456eb196, - type: 3} - m_LightListClusterClearAtomicIndexCS: {fileID: 7200000, guid: 1e3472a94b14a334a93230bbc700d7b2, - type: 3} - m_BuildMaterialFlagsCS: {fileID: 7200000, guid: fb3eda953cd6e634e877fb777be2cd08, - type: 3} + m_DebugLightVolumePS: {fileID: 4800000, guid: 8e706c0e71fcec34a8f5c9713e5e2943, type: 3} + m_DebugLightVolumeCS: {fileID: 7200000, guid: f5d5d21faef5cf445ac2c5d8ff9c4184, type: 3} + m_DebugBlitQuad: {fileID: 4800000, guid: cf5ca5b6ef18b3f429ed707ee9ceac9f, type: 3} + m_DebugViewVirtualTexturingBlit: {fileID: 4800000, guid: 55d195396b03b804eb78c92d468e3c8e, type: 3} + m_MaterialError: {fileID: 4800000, guid: 79a966a5200a456188dec0d48d805614, type: 3} + m_MaterialLoading: {fileID: 4800000, guid: 392325671f122f540be9033ca5ae7a56, type: 3} + m_ClearDebugBufferCS: {fileID: 7200000, guid: 7fc6041d5cf70004aa33bb1ac64e3c06, type: 3} + m_DebugWaveformPS: {fileID: 4800000, guid: 0024f9d09a828734192f3e1cd5931745, type: 3} + m_DebugWaveformCS: {fileID: 7200000, guid: 62b785f79355903428a21d5d8f8aeabe, type: 3} + m_DebugVectorscopePS: {fileID: 4800000, guid: 7a09af24008164d40ae85ccd6bf87e17, type: 3} + m_DebugVectorscopeCS: {fileID: 7200000, guid: 6a70efb18a2b2964c8eb0fc04aba20e9, type: 3} + m_DebugImageHistogramCS: {fileID: 7200000, guid: 52cc17ef5a5ffc443a5c142f9b745a85, type: 3} + m_DebugHDRxyMappingCS: {fileID: 7200000, guid: f055d2983d992b64494f1a03fc725cde, type: 3} + m_ProbeVolumeSamplingDebugComputeShader: {fileID: 7200000, guid: 22de19bc461f84742857dd64c56b0397, type: 3} + m_PlanarReflectionFilteringCS: {fileID: 7200000, guid: 9f3f8a01b8caaaa4595591dc96d43dd2, type: 3} + m_ScreenSpaceGlobalIlluminationCS: {fileID: 7200000, guid: 96170a954eb538b40a5ff369552c3629, type: 3} + m_ScreenSpaceReflectionsCS: {fileID: 7200000, guid: d1de9ac7d9016204da289affe9677942, type: 3} + m_ClearDispatchIndirectCS: {fileID: 7200000, guid: fc1f553acb80a6446a32d33e403d0656, type: 3} + m_ClearLightListsCS: {fileID: 7200000, guid: 743eb3491795b9545955695d591195a1, type: 3} + m_BuildDispatchIndirectCS: {fileID: 7200000, guid: 4eb1b418be7044c40bb5200496c50f14, type: 3} + m_BuildScreenAABBCS: {fileID: 7200000, guid: 728dce960f8a9c44bbc3abb3b851d8f6, type: 3} + m_BuildPerTileLightListCS: {fileID: 7200000, guid: 65af3444cbf4b3747a4dead7ee00cfee, type: 3} + m_BuildPerBigTileLightListCS: {fileID: 7200000, guid: 5ee1f9d6e09abe045b2f5e0b784b9072, type: 3} + m_BuildPerVoxelLightListCS: {fileID: 7200000, guid: 0bb1b7e0ddcd5c44baf3ddc7456eb196, type: 3} + m_LightListClusterClearAtomicIndexCS: {fileID: 7200000, guid: 1e3472a94b14a334a93230bbc700d7b2, type: 3} + m_BuildMaterialFlagsCS: {fileID: 7200000, guid: fb3eda953cd6e634e877fb777be2cd08, type: 3} m_DeferredCS: {fileID: 7200000, guid: 0b64f79746d2daf4198eaf6eab9af259, type: 3} - m_VolumeVoxelizationCS: {fileID: 7200000, guid: c20b371db720da244b73830ec74a343a, - type: 3} - m_VolumetricLightingCS: {fileID: 7200000, guid: b4901a10df2d1e24282725e9fbc77c97, - type: 3} - m_VolumetricLightingFilteringCS: {fileID: 7200000, guid: ef9a910d0ec6ebb41ae3f5c7a69daf46, - type: 3} - m_DefaultFogVolumeShader: {fileID: -6465566751694194690, guid: 95060fe3e070428418e64e6bed27b111, - type: 3} - m_ScreenSpaceMultipleScatteringCS: {fileID: 7200000, guid: 29c79555731a206478f0ea448352340c, - type: 3} - m_SubsurfaceScatteringCS: {fileID: 7200000, guid: b06a7993621def248addd55d0fe931b1, - type: 3} - m_SubsurfaceScatteringDownsampleCS: {fileID: 7200000, guid: 4f8aaf0160a259e499fdfac512ca2692, - type: 3} - m_CombineLightingPS: {fileID: 4800000, guid: 2e37131331fbdca449b1a2bc47a639ca, - type: 3} - m_BlitCubemapPS: {fileID: 4800000, guid: d05913e251bed7a4992c921c62e1b647, - type: 3} - m_OpaqueAtmosphericScatteringPS: {fileID: 4800000, guid: 32f724728cf19904291226f239ec16f0, - type: 3} + m_VolumeVoxelizationCS: {fileID: 7200000, guid: c20b371db720da244b73830ec74a343a, type: 3} + m_VolumetricLightingCS: {fileID: 7200000, guid: b4901a10df2d1e24282725e9fbc77c97, type: 3} + m_VolumetricLightingFilteringCS: {fileID: 7200000, guid: ef9a910d0ec6ebb41ae3f5c7a69daf46, type: 3} + m_DefaultFogVolumeShader: {fileID: -6465566751694194690, guid: 95060fe3e070428418e64e6bed27b111, type: 3} + m_ScreenSpaceMultipleScatteringCS: {fileID: 7200000, guid: 29c79555731a206478f0ea448352340c, type: 3} + m_SubsurfaceScatteringCS: {fileID: 7200000, guid: b06a7993621def248addd55d0fe931b1, type: 3} + m_SubsurfaceScatteringDownsampleCS: {fileID: 7200000, guid: 4f8aaf0160a259e499fdfac512ca2692, type: 3} + m_CombineLightingPS: {fileID: 4800000, guid: 2e37131331fbdca449b1a2bc47a639ca, type: 3} + m_BlitCubemapPS: {fileID: 4800000, guid: d05913e251bed7a4992c921c62e1b647, type: 3} + m_OpaqueAtmosphericScatteringPS: {fileID: 4800000, guid: 32f724728cf19904291226f239ec16f0, type: 3} m_HdriSkyPS: {fileID: 4800000, guid: 9bd32a6ece529fd4f9408b8d7e00c10d, type: 3} - m_IntegrateHdriSkyPS: {fileID: 4800000, guid: 48db2705cf2856d4e893eb30a6892d1b, - type: 3} + m_IntegrateHdriSkyPS: {fileID: 4800000, guid: 48db2705cf2856d4e893eb30a6892d1b, type: 3} m_SkyboxCubemapPS: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0} - m_GradientSkyPS: {fileID: 4800000, guid: 2b5d4f1b26f03dc4a873b093e0c4adb1, - type: 3} - m_AmbientProbeConvolutionCS: {fileID: 7200000, guid: 6d048f7b1bd45e840b4e79ec92639fa8, - type: 3} - m_GroundIrradiancePrecomputationCS: {fileID: 7200000, guid: eb6ae6f326207ee4d987a3e5adddf63a, - type: 3} - m_InScatteredRadiancePrecomputationCS: {fileID: 7200000, guid: 70c69d514688f8545855680760d77418, - type: 3} - m_PhysicallyBasedSkyPS: {fileID: 4800000, guid: a06934a4863e778498be65d8f865b7a4, - type: 3} - m_CloudLayerPS: {fileID: 4800000, guid: 001a47fa123e95a4bba13ecb0442d944, - type: 3} - m_BakeCloudTextureCS: {fileID: 7200000, guid: 09a7f6850ee9fb4439e5ebd632127da5, - type: 3} - m_BakeCloudShadowsCS: {fileID: 7200000, guid: 3e7317e0800c066448ee07a3e47f102b, - type: 3} - m_SkyLUTGenerator: {fileID: 7200000, guid: 79224112d91b32241be6b65802863db4, - type: 3} - m_LineStagePrepareCS: {fileID: 7200000, guid: 53231d98bbe64477aacc1adc14ba2619, - type: 3} - m_LineStageSetupSegmentCS: {fileID: 7200000, guid: 028836c66d494d8d94e1b2ca7d5382ae, - type: 3} - m_LineStageShadingSetupCS: {fileID: 7200000, guid: fefde0fac988da24a93bc2d8d6e0a0a1, - type: 3} - m_LineStageRasterBinCS: {fileID: 7200000, guid: 17d1e3e43f0e4c878b40b52848a58a77, - type: 3} - m_LineStageWorkQueueCS: {fileID: 7200000, guid: dae4ea8aeff24b16be3f0b2948e0acc5, - type: 3} - m_LineStageRasterFineCS: {fileID: 7200000, guid: 8691ac13e67d457abb92eca75e88e995, - type: 3} - m_LineCompositePS: {fileID: 4800000, guid: 8d9fbe0862434a2298748d335b9abea5, - type: 3} - m_PreIntegratedFGD_GGXDisneyDiffusePS: {fileID: 4800000, guid: 123f13d52852ef547b2962de4bd9eaad, - type: 3} - m_PreIntegratedFGD_CharlieFabricLambertPS: {fileID: 4800000, guid: 3b3bf235775cf8b4baae7f3306787ab0, - type: 3} - m_PreIntegratedFGD_WardPS: {fileID: 4800000, guid: d279c46a545b0af4f9f0c4fa82cd489e, - type: 3} - m_PreIntegratedFGD_CookTorrancePS: {fileID: 4800000, guid: a6402c19b020b4a4fb7073aaa2e26aba, - type: 3} - m_PreIntegratedFGD_MarschnerPS: {fileID: 4800000, guid: 31f36caf0a5e7f848a1b5328b6ad3eb8, - type: 3} - m_PreIntegratedFiberScatteringCS: {fileID: 7200000, guid: 4a087c9d074552c48aeb85184d56312e, - type: 3} - m_VolumetricMaterialCS: {fileID: 7200000, guid: 26f18c9cb0bccbf4481f8c84579affb1, - type: 3} - m_EyeMaterialCS: {fileID: 7200000, guid: 76f78ba05cea1ed449c1ef613ab90597, - type: 3} - m_FilterAreaLightCookiesPS: {fileID: 4800000, guid: c243aac96dda5fa40bed693ed5ba02c4, - type: 3} - m_BuildProbabilityTablesCS: {fileID: 7200000, guid: b9f26cf340afe9145a699753531b2a4c, - type: 3} - m_ComputeGgxIblSampleDataCS: {fileID: 7200000, guid: 764a24bb47ef5ba4781d9ae82ca07445, - type: 3} - m_GGXConvolvePS: {fileID: 4800000, guid: 123ed592ad5c2494b8aed301fd609e7b, - type: 3} - m_CharlieConvolvePS: {fileID: 4800000, guid: 5685fd17e71045e4ca9fefca38a7c177, - type: 3} - m_GpuPrefixSumCS: {fileID: 7200000, guid: 76fcf27f72d24907b1846939a7a2d83f, - type: 3} + m_GradientSkyPS: {fileID: 4800000, guid: 2b5d4f1b26f03dc4a873b093e0c4adb1, type: 3} + m_AmbientProbeConvolutionCS: {fileID: 7200000, guid: 6d048f7b1bd45e840b4e79ec92639fa8, type: 3} + m_GroundIrradiancePrecomputationCS: {fileID: 7200000, guid: eb6ae6f326207ee4d987a3e5adddf63a, type: 3} + m_InScatteredRadiancePrecomputationCS: {fileID: 7200000, guid: 70c69d514688f8545855680760d77418, type: 3} + m_PhysicallyBasedSkyPS: {fileID: 4800000, guid: a06934a4863e778498be65d8f865b7a4, type: 3} + m_CloudLayerPS: {fileID: 4800000, guid: 001a47fa123e95a4bba13ecb0442d944, type: 3} + m_BakeCloudTextureCS: {fileID: 7200000, guid: 09a7f6850ee9fb4439e5ebd632127da5, type: 3} + m_BakeCloudShadowsCS: {fileID: 7200000, guid: 3e7317e0800c066448ee07a3e47f102b, type: 3} + m_SkyLUTGenerator: {fileID: 7200000, guid: 79224112d91b32241be6b65802863db4, type: 3} + m_LineStagePrepareCS: {fileID: 7200000, guid: 53231d98bbe64477aacc1adc14ba2619, type: 3} + m_LineStageSetupSegmentCS: {fileID: 7200000, guid: 028836c66d494d8d94e1b2ca7d5382ae, type: 3} + m_LineStageShadingSetupCS: {fileID: 7200000, guid: fefde0fac988da24a93bc2d8d6e0a0a1, type: 3} + m_LineStageRasterBinCS: {fileID: 7200000, guid: 17d1e3e43f0e4c878b40b52848a58a77, type: 3} + m_LineStageWorkQueueCS: {fileID: 7200000, guid: dae4ea8aeff24b16be3f0b2948e0acc5, type: 3} + m_LineStageRasterFineCS: {fileID: 7200000, guid: 8691ac13e67d457abb92eca75e88e995, type: 3} + m_LineCompositePS: {fileID: 4800000, guid: 8d9fbe0862434a2298748d335b9abea5, type: 3} + m_PreIntegratedFGD_GGXDisneyDiffusePS: {fileID: 4800000, guid: 123f13d52852ef547b2962de4bd9eaad, type: 3} + m_PreIntegratedFGD_CharlieFabricLambertPS: {fileID: 4800000, guid: 3b3bf235775cf8b4baae7f3306787ab0, type: 3} + m_PreIntegratedFGD_WardPS: {fileID: 4800000, guid: d279c46a545b0af4f9f0c4fa82cd489e, type: 3} + m_PreIntegratedFGD_CookTorrancePS: {fileID: 4800000, guid: a6402c19b020b4a4fb7073aaa2e26aba, type: 3} + m_PreIntegratedFGD_MarschnerPS: {fileID: 4800000, guid: 31f36caf0a5e7f848a1b5328b6ad3eb8, type: 3} + m_PreIntegratedFiberScatteringCS: {fileID: 7200000, guid: 4a087c9d074552c48aeb85184d56312e, type: 3} + m_VolumetricMaterialCS: {fileID: 7200000, guid: 26f18c9cb0bccbf4481f8c84579affb1, type: 3} + m_ClearVolumetricMaterialCS: {fileID: 7200000, guid: a34e917ab17a38d419e6dd712988ac15, type: 3} + m_EyeMaterialCS: {fileID: 7200000, guid: 76f78ba05cea1ed449c1ef613ab90597, type: 3} + m_FilterAreaLightCookiesPS: {fileID: 4800000, guid: c243aac96dda5fa40bed693ed5ba02c4, type: 3} + m_BuildProbabilityTablesCS: {fileID: 7200000, guid: b9f26cf340afe9145a699753531b2a4c, type: 3} + m_ComputeGgxIblSampleDataCS: {fileID: 7200000, guid: 764a24bb47ef5ba4781d9ae82ca07445, type: 3} + m_GGXConvolvePS: {fileID: 4800000, guid: 123ed592ad5c2494b8aed301fd609e7b, type: 3} + m_CharlieConvolvePS: {fileID: 4800000, guid: 5685fd17e71045e4ca9fefca38a7c177, type: 3} + m_GpuPrefixSumCS: {fileID: 7200000, guid: 76fcf27f72d24907b1846939a7a2d83f, type: 3} m_GpuSortCS: {fileID: 7200000, guid: e485b8d649234276ababbd36fcec8c1a, type: 3} - m_BilateralUpsampleCS: {fileID: 7200000, guid: 68e831c555284d741b985e05369f0e63, - type: 3} - m_TemporalFilterCS: {fileID: 7200000, guid: 741979ff70f7bd6489fbcb464280ecff, - type: 3} - m_DiffuseDenoiserCS: {fileID: 7200000, guid: b4ed2382141619f40af1f743a84ccaea, - type: 3} - m_FurnaceTestCS: {fileID: 7200000, guid: 9c19385e40e70ea41811a942a46b04a3, - type: 3} - m_ObjectIDPS: {fileID: -6465566751694194690, guid: 89daf81f8e8f6634da726cbca859ca38, - type: 3} - m_ComputeThicknessPS: {fileID: 4800000, guid: 4d2c6daf0d4968748bb5b82d5016fdea, - type: 3} - m_CopyChannelCS: {fileID: 7200000, guid: a4d45eda75e8e474dbe24a31f741f3b4, - type: 3} - m_ClearBuffer2D: {fileID: 7200000, guid: fa9b66253270e9c47a67ae142f669eb4, - type: 3} - m_EncodeBC6HCS: {fileID: 7200000, guid: aa922d239de60304f964e24488559eeb, - type: 3} - m_CubeToPanoPS: {fileID: 4800000, guid: 595434cc3b6405246b6cd3086d0b6f7d, - type: 3} - m_BlitCubeTextureFacePS: {fileID: 4800000, guid: d850d0a2481878d4bbf17e5126b04163, - type: 3} - m_ClearUIntTextureCS: {fileID: 7200000, guid: d067ad4b88af51c498875426894aef76, - type: 3} - m_Texture3DAtlasCS: {fileID: 7200000, guid: 81522e314a83afd4a8ed43bd00757051, - type: 3} - m_XrMirrorViewPS: {fileID: 4800000, guid: e6255f98cf405eb45ab6f9006cf11e1f, - type: 3} - m_XrOcclusionMeshPS: {fileID: 4800000, guid: 46a45b32bb110604fb36216b63bcdb81, - type: 3} - m_ContactShadowCS: {fileID: 7200000, guid: 3e6900e06dc185a4380af4dacb4db0a4, - type: 3} - m_ScreenSpaceShadowPS: {fileID: 4800000, guid: bfa43a48695613b4ea19c58858ae1a61, - type: 3} - m_ShadowClearPS: {fileID: 4800000, guid: e3cab24f27741f44d8af1e94d006267c, - type: 3} + m_BilateralUpsampleCS: {fileID: 7200000, guid: 68e831c555284d741b985e05369f0e63, type: 3} + m_TemporalFilterCS: {fileID: 7200000, guid: 741979ff70f7bd6489fbcb464280ecff, type: 3} + m_DiffuseDenoiserCS: {fileID: 7200000, guid: b4ed2382141619f40af1f743a84ccaea, type: 3} + m_FurnaceTestCS: {fileID: 7200000, guid: 9c19385e40e70ea41811a942a46b04a3, type: 3} + m_ObjectIDPS: {fileID: -6465566751694194690, guid: 89daf81f8e8f6634da726cbca859ca38, type: 3} + m_ComputeThicknessPS: {fileID: 4800000, guid: 4d2c6daf0d4968748bb5b82d5016fdea, type: 3} + m_CopyChannelCS: {fileID: 7200000, guid: a4d45eda75e8e474dbe24a31f741f3b4, type: 3} + m_ClearBuffer2D: {fileID: 7200000, guid: fa9b66253270e9c47a67ae142f669eb4, type: 3} + m_EncodeBC6HCS: {fileID: 7200000, guid: aa922d239de60304f964e24488559eeb, type: 3} + m_CubeToPanoPS: {fileID: 4800000, guid: 595434cc3b6405246b6cd3086d0b6f7d, type: 3} + m_BlitCubeTextureFacePS: {fileID: 4800000, guid: d850d0a2481878d4bbf17e5126b04163, type: 3} + m_ClearUIntTextureCS: {fileID: 7200000, guid: d067ad4b88af51c498875426894aef76, type: 3} + m_Texture3DAtlasCS: {fileID: 7200000, guid: 81522e314a83afd4a8ed43bd00757051, type: 3} + m_XrMirrorViewPS: {fileID: 4800000, guid: e6255f98cf405eb45ab6f9006cf11e1f, type: 3} + m_XrOcclusionMeshPS: {fileID: 4800000, guid: 46a45b32bb110604fb36216b63bcdb81, type: 3} + m_ContactShadowCS: {fileID: 7200000, guid: 3e6900e06dc185a4380af4dacb4db0a4, type: 3} + m_ScreenSpaceShadowPS: {fileID: 4800000, guid: bfa43a48695613b4ea19c58858ae1a61, type: 3} + m_ShadowClearPS: {fileID: 4800000, guid: e3cab24f27741f44d8af1e94d006267c, type: 3} m_EvsmBlurCS: {fileID: 7200000, guid: fb36979473602464fa32deacb9630c08, type: 3} - m_DebugHDShadowMapPS: {fileID: 4800000, guid: 93d40cc9a6e13994f86f576a624efa18, - type: 3} - m_DebugLocalVolumetricFogAtlasPS: {fileID: 4800000, guid: 8371b763f09c7304889c22aa97ebdfd2, - type: 3} - m_MomentShadowsCS: {fileID: 7200000, guid: 4dea53e2ff15ed0448817c2aa4246e53, - type: 3} - m_ShadowBlitPS: {fileID: 4800000, guid: ca059f1af4587a24b9a9eed3b66cff0f, - type: 3} - m_DecalNormalBufferPS: {fileID: 4800000, guid: fd532bf1795188c4daaa66ea798b8b0a, - type: 3} + m_DebugHDShadowMapPS: {fileID: 4800000, guid: 93d40cc9a6e13994f86f576a624efa18, type: 3} + m_DebugLocalVolumetricFogAtlasPS: {fileID: 4800000, guid: 8371b763f09c7304889c22aa97ebdfd2, type: 3} + m_MomentShadowsCS: {fileID: 7200000, guid: 4dea53e2ff15ed0448817c2aa4246e53, type: 3} + m_ShadowBlitPS: {fileID: 4800000, guid: ca059f1af4587a24b9a9eed3b66cff0f, type: 3} + m_DecalNormalBufferPS: {fileID: 4800000, guid: fd532bf1795188c4daaa66ea798b8b0a, type: 3} m_GTAOCS: {fileID: 7200000, guid: 6710b06492bd58c4bb8aec0fdc1fced3, type: 3} - m_GTAOSpatialDenoiseCS: {fileID: 7200000, guid: 2cb33c21587d12b4388d7866ab6c65f6, - type: 3} - m_GTAOTemporalDenoiseCS: {fileID: 7200000, guid: 31e0ca4c210f97c468037d11a5b832bb, - type: 3} - m_GTAOCopyHistoryCS: {fileID: 7200000, guid: 7f43be57ffd12ff469d4fc175c00c4b4, - type: 3} - m_GTAOBlurAndUpsample: {fileID: 7200000, guid: 9eb1abde882538a4ea46fa23e49ab9fa, - type: 3} + m_GTAOSpatialDenoiseCS: {fileID: 7200000, guid: 2cb33c21587d12b4388d7866ab6c65f6, type: 3} + m_GTAOTemporalDenoiseCS: {fileID: 7200000, guid: 31e0ca4c210f97c468037d11a5b832bb, type: 3} + m_GTAOCopyHistoryCS: {fileID: 7200000, guid: 7f43be57ffd12ff469d4fc175c00c4b4, type: 3} + m_GTAOBlurAndUpsample: {fileID: 7200000, guid: 9eb1abde882538a4ea46fa23e49ab9fa, type: 3} m_CopyAlphaCS: {fileID: 7200000, guid: c2c7eb6611725264187721ef9df0354b, type: 3} m_NanKillerCS: {fileID: 7200000, guid: 83982f199acf927499576a99abc9bea9, type: 3} m_ExposureCS: {fileID: 7200000, guid: 976d7bce54fae534fb9ec67e9c18570c, type: 3} - m_HistogramExposureCS: {fileID: 7200000, guid: 222da48299136f34b8e3fb75ae9f8ac7, - type: 3} - m_ApplyExposureCS: {fileID: 7200000, guid: 1a6fea1dc099b984d8f2b27d504dc096, - type: 3} + m_HistogramExposureCS: {fileID: 7200000, guid: 222da48299136f34b8e3fb75ae9f8ac7, type: 3} + m_ApplyExposureCS: {fileID: 7200000, guid: 1a6fea1dc099b984d8f2b27d504dc096, type: 3} m_UberPostCS: {fileID: 7200000, guid: f1bf52f7c71bffd4f91e6cd90d12a4f7, type: 3} - m_LutBuilder3DCS: {fileID: 7200000, guid: 37f2b1b0ecd6f1c439e4c1b4f2fdb524, - type: 3} - m_DepthOfFieldKernelCS: {fileID: 7200000, guid: 7869415cc3e4eaa4d82ac21a752a2780, - type: 3} - m_DepthOfFieldCoCCS: {fileID: 7200000, guid: 048b235b54fbfaa4d80ec85ea847d4f8, - type: 3} - m_DepthOfFieldCoCReprojectCS: {fileID: 7200000, guid: 4980decaa3878d6448569489f5fc7931, - type: 3} - m_DepthOfFieldDilateCS: {fileID: 7200000, guid: 1c93af4338c0c1b42b92464992eebc10, - type: 3} - m_DepthOfFieldMipCS: {fileID: 7200000, guid: d3ef53de069ded64e8377cba6eb951fa, - type: 3} - m_DepthOfFieldMipSafeCS: {fileID: 7200000, guid: 2d24ee7b2c804d947a5c371c12ed46bd, - type: 3} - m_DepthOfFieldPrefilterCS: {fileID: 7200000, guid: f2b89d19910854346b792fe7177ce634, - type: 3} - m_DepthOfFieldTileMaxCS: {fileID: 7200000, guid: 84f84585ea8a7a849bea4a581adb93a7, - type: 3} - m_DepthOfFieldGatherCS: {fileID: 7200000, guid: 486be52dddc4e054fb10a7b9b78788c2, - type: 3} - m_DepthOfFieldCombineCS: {fileID: 7200000, guid: c8049ca85c4c7d047ba28f34d800c663, - type: 3} - m_DepthOfFieldPreCombineFarCS: {fileID: 7200000, guid: 3b4a2acd03d1ce2438d93c325d588735, - type: 3} - m_DepthOfFieldClearIndirectArgsCS: {fileID: 7200000, guid: 69905045e1d0a65458b205d6ab55502b, - type: 3} - m_PaniniProjectionCS: {fileID: 7200000, guid: 0ddbf72c8fbb6e44b983f470c8384ef6, - type: 3} - m_DofCircleOfConfusion: {fileID: 7200000, guid: 75332b7b315c80d4babe506820aa0bfd, - type: 3} + m_LutBuilder3DCS: {fileID: 7200000, guid: 37f2b1b0ecd6f1c439e4c1b4f2fdb524, type: 3} + m_DepthOfFieldKernelCS: {fileID: 7200000, guid: 7869415cc3e4eaa4d82ac21a752a2780, type: 3} + m_DepthOfFieldCoCCS: {fileID: 7200000, guid: 048b235b54fbfaa4d80ec85ea847d4f8, type: 3} + m_DepthOfFieldCoCReprojectCS: {fileID: 7200000, guid: 4980decaa3878d6448569489f5fc7931, type: 3} + m_DepthOfFieldDilateCS: {fileID: 7200000, guid: 1c93af4338c0c1b42b92464992eebc10, type: 3} + m_DepthOfFieldMipCS: {fileID: 7200000, guid: d3ef53de069ded64e8377cba6eb951fa, type: 3} + m_DepthOfFieldMipSafeCS: {fileID: 7200000, guid: 2d24ee7b2c804d947a5c371c12ed46bd, type: 3} + m_DepthOfFieldPrefilterCS: {fileID: 7200000, guid: f2b89d19910854346b792fe7177ce634, type: 3} + m_DepthOfFieldTileMaxCS: {fileID: 7200000, guid: 84f84585ea8a7a849bea4a581adb93a7, type: 3} + m_DepthOfFieldGatherCS: {fileID: 7200000, guid: 486be52dddc4e054fb10a7b9b78788c2, type: 3} + m_DepthOfFieldCombineCS: {fileID: 7200000, guid: c8049ca85c4c7d047ba28f34d800c663, type: 3} + m_DepthOfFieldPreCombineFarCS: {fileID: 7200000, guid: 3b4a2acd03d1ce2438d93c325d588735, type: 3} + m_DepthOfFieldClearIndirectArgsCS: {fileID: 7200000, guid: 69905045e1d0a65458b205d6ab55502b, type: 3} + m_PaniniProjectionCS: {fileID: 7200000, guid: 0ddbf72c8fbb6e44b983f470c8384ef6, type: 3} + m_DofCircleOfConfusion: {fileID: 7200000, guid: 75332b7b315c80d4babe506820aa0bfd, type: 3} m_DofGatherCS: {fileID: 7200000, guid: 1e6b16a7970a1494db74b1d3d007d1cc, type: 3} - m_DofCoCMinMaxCS: {fileID: 7200000, guid: c70dd492c3d2fe94589d6ca8d4e37915, - type: 3} - m_DofMinMaxDilateCS: {fileID: 7200000, guid: 757a3f81b35177b44b2b178909b49172, - type: 3} - m_DofCombineCS: {fileID: 7200000, guid: d9b940a90a2d0884f94990a0dde43a53, - type: 3} - m_DofComputeSlowTilesCS: {fileID: 7200000, guid: b89f86a76de81ee42ae16daad78eb382, - type: 3} - m_DofComputeApertureShapeCS: {fileID: 7200000, guid: dd5acecb27e20334fa3be332e85172df, - type: 3} - m_MotionBlurMotionVecPrepCS: {fileID: 7200000, guid: ed9438fa777911d48933402087203b15, - type: 3} - m_MotionBlurGenTileCS: {fileID: 7200000, guid: 336e1fdbb3a1b8647b06208415f87804, - type: 3} - m_MotionBlurMergeTileCS: {fileID: 7200000, guid: cd14ddf849edeed43b0e3ccf66023038, - type: 3} - m_MotionBlurNeighborhoodTileCS: {fileID: 7200000, guid: 5ea9865df3e53b448856785b88f8e7b9, - type: 3} - m_MotionBlurCS: {fileID: 7200000, guid: 2af5c49c7865edb4b823826970ec176a, - type: 3} - m_BloomPrefilterCS: {fileID: 7200000, guid: 243b24008041aaa4a91800690f63c684, - type: 3} + m_DofCoCMinMaxCS: {fileID: 7200000, guid: c70dd492c3d2fe94589d6ca8d4e37915, type: 3} + m_DofMinMaxDilateCS: {fileID: 7200000, guid: 757a3f81b35177b44b2b178909b49172, type: 3} + m_DofCombineCS: {fileID: 7200000, guid: d9b940a90a2d0884f94990a0dde43a53, type: 3} + m_DofComputeSlowTilesCS: {fileID: 7200000, guid: b89f86a76de81ee42ae16daad78eb382, type: 3} + m_DofComputeApertureShapeCS: {fileID: 7200000, guid: dd5acecb27e20334fa3be332e85172df, type: 3} + m_MotionBlurMotionVecPrepCS: {fileID: 7200000, guid: ed9438fa777911d48933402087203b15, type: 3} + m_MotionBlurGenTileCS: {fileID: 7200000, guid: 336e1fdbb3a1b8647b06208415f87804, type: 3} + m_MotionBlurMergeTileCS: {fileID: 7200000, guid: cd14ddf849edeed43b0e3ccf66023038, type: 3} + m_MotionBlurNeighborhoodTileCS: {fileID: 7200000, guid: 5ea9865df3e53b448856785b88f8e7b9, type: 3} + m_MotionBlurCS: {fileID: 7200000, guid: 2af5c49c7865edb4b823826970ec176a, type: 3} + m_BloomPrefilterCS: {fileID: 7200000, guid: 243b24008041aaa4a91800690f63c684, type: 3} m_BloomBlurCS: {fileID: 7200000, guid: 133a68380d324de4ea8d3ff8657b02d8, type: 3} - m_BloomUpsampleCS: {fileID: 7200000, guid: 5dbb0ac12cb11f84084b7e5633481bd1, - type: 3} - m_DepthValuesPS: {fileID: 4800000, guid: 6e6a4a3dbb788234594aa74f2d6aeb6f, - type: 3} - m_ColorResolvePS: {fileID: 4800000, guid: dd7047092f3c82b40b3a07868f9c4de2, - type: 3} - m_ResolveMotionVecPS: {fileID: 4800000, guid: ea18ca9826385e943979c46cf98968cc, - type: 3} + m_BloomUpsampleCS: {fileID: 7200000, guid: 5dbb0ac12cb11f84084b7e5633481bd1, type: 3} + m_DepthValuesPS: {fileID: 4800000, guid: 6e6a4a3dbb788234594aa74f2d6aeb6f, type: 3} + m_ColorResolvePS: {fileID: 4800000, guid: dd7047092f3c82b40b3a07868f9c4de2, type: 3} + m_ResolveMotionVecPS: {fileID: 4800000, guid: ea18ca9826385e943979c46cf98968cc, type: 3} m_FXAACS: {fileID: 7200000, guid: 1535d29f35ea86b4282b6ca652002e2a, type: 3} m_FinalPassPS: {fileID: 4800000, guid: 5ac9ef0c50282754b93c7692488e7ee7, type: 3} - m_ClearBlackPS: {fileID: 4800000, guid: 3330c1503ea8c6d4d9408df3f64227eb, - type: 3} + m_ClearBlackPS: {fileID: 4800000, guid: 3330c1503ea8c6d4d9408df3f64227eb, type: 3} m_SMAAPS: {fileID: 4800000, guid: 9655f4aa89a469c49aceaceabf9bc77b, type: 3} - m_TemporalAntialiasingPS: {fileID: 4800000, guid: 3dd9fd928fdb83743b1f27d15df22179, - type: 3} - m_SharpeningCS: {fileID: 7200000, guid: 667941138a753f447bad3bf94052f590, - type: 3} - m_LensFlareDataDrivenPS: {fileID: 4800000, guid: 85330b3de0cfebc4ba78b2d61b1a2899, - type: 3} - m_LensFlareScreenSpacePS: {fileID: 4800000, guid: 97abfc9f0525e1849b417eaae10f0329, - type: 3} - m_LensFlareMergeOcclusionCS: {fileID: 7200000, guid: 07492750f384d9a4da9aaf5d2feeed4a, - type: 3} - m_DLSSBiasColorMaskPS: {fileID: 4800000, guid: 017a05924c0b0484ca29717ed0c60343, - type: 3} - m_CompositeUIAndOETFApplyPS: {fileID: 4800000, guid: 08b7ad21d2b8e9142b730b22d7355821, - type: 3} - m_ContrastAdaptiveSharpenCS: {fileID: 7200000, guid: 560896aec2f412c48995be35551a4ac6, - type: 3} - m_EdgeAdaptiveSpatialUpsamplingCS: {fileID: 7200000, guid: f054fa9fe2c85bb42b9489e2f9ffb643, - type: 3} - m_VTFeedbackDownsample: {fileID: 7200000, guid: 32d963548086c2c439aeb23a93e9a00a, - type: 3} - m_AccumulationCS: {fileID: 7200000, guid: ed80add7a217efa468d137d6f7c668f3, - type: 3} - m_BlitAndExposeCS: {fileID: 7200000, guid: 4b9a355e064de034dbfafe4583ba766b, - type: 3} - m_AlphaInjectionPS: {fileID: 4800000, guid: 4edd96259a5e8b44c90479928f0cd11e, - type: 3} - m_ChromaKeyingPS: {fileID: 4800000, guid: 49feb6b111e82ec4eb6d3d08e4b6903e, - type: 3} - m_CustomClearPS: {fileID: 4800000, guid: 9cef3686fa32c8840947ed99b561195c, - type: 3} + m_TemporalAntialiasingPS: {fileID: 4800000, guid: 3dd9fd928fdb83743b1f27d15df22179, type: 3} + m_SharpeningCS: {fileID: 7200000, guid: 667941138a753f447bad3bf94052f590, type: 3} + m_LensFlareDataDrivenPS: {fileID: 4800000, guid: 85330b3de0cfebc4ba78b2d61b1a2899, type: 3} + m_LensFlareScreenSpacePS: {fileID: 4800000, guid: 97abfc9f0525e1849b417eaae10f0329, type: 3} + m_LensFlareMergeOcclusionCS: {fileID: 7200000, guid: 07492750f384d9a4da9aaf5d2feeed4a, type: 3} + m_DLSSBiasColorMaskPS: {fileID: 4800000, guid: 017a05924c0b0484ca29717ed0c60343, type: 3} + m_CompositeUIAndOETFApplyPS: {fileID: 4800000, guid: 08b7ad21d2b8e9142b730b22d7355821, type: 3} + m_ContrastAdaptiveSharpenCS: {fileID: 7200000, guid: 560896aec2f412c48995be35551a4ac6, type: 3} + m_EdgeAdaptiveSpatialUpsamplingCS: {fileID: 7200000, guid: f054fa9fe2c85bb42b9489e2f9ffb643, type: 3} + m_VTFeedbackDownsample: {fileID: 7200000, guid: 32d963548086c2c439aeb23a93e9a00a, type: 3} + m_AccumulationCS: {fileID: 7200000, guid: ed80add7a217efa468d137d6f7c668f3, type: 3} + m_BlitAndExposeCS: {fileID: 7200000, guid: 4b9a355e064de034dbfafe4583ba766b, type: 3} + m_AlphaInjectionPS: {fileID: 4800000, guid: 4edd96259a5e8b44c90479928f0cd11e, type: 3} + m_ChromaKeyingPS: {fileID: 4800000, guid: 49feb6b111e82ec4eb6d3d08e4b6903e, type: 3} + m_CustomClearPS: {fileID: 4800000, guid: 9cef3686fa32c8840947ed99b561195c, type: 3} - rid: 6023113869122600965 - type: {class: DiffusionProfileDefaultSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: DiffusionProfileDefaultSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_AutoRegisterDiffusionProfiles: 0 - rid: 6023113869122600966 - type: {class: VolumetricCloudsRuntimeResources, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} - data: - m_VolumetricCloudsCS: {fileID: 7200000, guid: f911a8577fa9a4546a6b255bcf888baf, - type: 3} - m_VolumetricCloudsTraceCS: {fileID: 7200000, guid: 66eaa9becc91a8646a88c15375af8b86, - type: 3} - m_VolumetricCloudsTraceShadowsCS: {fileID: 7200000, guid: f350c5c3b41fd1b408aac9076f96610e, - type: 3} - m_VolumetricCloudsShadowFilterCS: {fileID: 7200000, guid: 771ea9a52996c024095906ac37a8a71f, - type: 3} - m_VolumetricCloudMapGeneratorCS: {fileID: 7200000, guid: 6b22771f0aa98744cb09f455a5a818cb, - type: 3} - m_VolumetricCloudsCombinePS: {fileID: 4800000, guid: 12f1a69ddf916f042ae6ce8a994506f3, - type: 3} - m_CloudLutRainAO: {fileID: 2800000, guid: e0bcfddf26ed5584ba3d8b94d3200114, - type: 3} - m_WorleyNoise128RGBA: {fileID: 11700000, guid: 1fe54a721d0e2504e89f121c723404a8, - type: 3} - m_WorleyNoise32RGB: {fileID: 11700000, guid: ec156c314a242914dbb706f73ad78cf2, - type: 3} - m_PerlinNoise32RGB: {fileID: 11700000, guid: d1aae012f8a4f23478471851f17ff915, - type: 3} + type: {class: VolumetricCloudsRuntimeResources, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} + data: + m_VolumetricCloudsCS: {fileID: 7200000, guid: f911a8577fa9a4546a6b255bcf888baf, type: 3} + m_VolumetricCloudsTraceCS: {fileID: 7200000, guid: 66eaa9becc91a8646a88c15375af8b86, type: 3} + m_VolumetricCloudsTraceShadowsCS: {fileID: 7200000, guid: f350c5c3b41fd1b408aac9076f96610e, type: 3} + m_VolumetricCloudsShadowFilterCS: {fileID: 7200000, guid: 771ea9a52996c024095906ac37a8a71f, type: 3} + m_VolumetricCloudMapGeneratorCS: {fileID: 7200000, guid: 6b22771f0aa98744cb09f455a5a818cb, type: 3} + m_VolumetricCloudsCombinePS: {fileID: 4800000, guid: 12f1a69ddf916f042ae6ce8a994506f3, type: 3} + m_CloudLutRainAO: {fileID: 2800000, guid: e0bcfddf26ed5584ba3d8b94d3200114, type: 3} + m_WorleyNoise128RGBA: {fileID: 11700000, guid: 1fe54a721d0e2504e89f121c723404a8, type: 3} + m_WorleyNoise32RGB: {fileID: 11700000, guid: ec156c314a242914dbb706f73ad78cf2, type: 3} + m_PerlinNoise32RGB: {fileID: 11700000, guid: d1aae012f8a4f23478471851f17ff915, type: 3} - rid: 6023113869122600967 - type: {class: AnalyticDerivativeSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: AnalyticDerivativeSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_AnalyticDerivativeEmulation: 0 m_AnalyticDerivativeDebugOutput: 0 - rid: 6023113869122600968 - type: {class: SpecularFadeSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: SpecularFadeSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_SpecularFade: 0 - rid: 6023113869122600969 - type: {class: ColorGradingSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: ColorGradingSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_ColorGradingSpace: 1 - rid: 6023113869122600970 - type: {class: HDRenderPipelineRuntimeMaterials, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRenderPipelineRuntimeMaterials, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: - m_PBRSkyMaterial: {fileID: -876546973899608171, guid: 02532cbb810fb404db49da84f1efe41e, - type: 3} - m_AreaLightMaterial: {fileID: 2100000, guid: ef5f65c980e25304098a95e28f3bd20b, - type: 2} - m_AreaLightCookieMaterial: {fileID: 2100000, guid: 78c6825c5d9c3664f9879ae8609618c7, - type: 2} + m_PBRSkyMaterial: {fileID: -876546973899608171, guid: 02532cbb810fb404db49da84f1efe41e, type: 3} + m_AreaLightMaterial: {fileID: 2100000, guid: ef5f65c980e25304098a95e28f3bd20b, type: 2} + m_AreaLightCookieMaterial: {fileID: 2100000, guid: 78c6825c5d9c3664f9879ae8609618c7, type: 2} - rid: 6023113869122600971 type: {class: LensSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_LensAttenuationMode: 0 - rid: 6023113869122600972 - type: {class: WaterSystemRuntimeResources, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} - data: - m_WaterMaterial: {fileID: -876546973899608171, guid: 3fda5e465882bec4d8e64161b681806c, - type: 3} - m_WaterExclusionMaterial: {fileID: 2100000, guid: 1e520c84f7fd17c46af5586f6632155c, - type: 2} - m_WaterDecalMaterial: {fileID: -876546973899608171, guid: 7e2c0d424490bfc4698c37245b8c63ed, - type: 3} - m_WaterSimulationCS: {fileID: 7200000, guid: 32ac7f445960a854595586a600c24034, - type: 3} - m_FourierTransformCS: {fileID: 7200000, guid: bc2ee21836a0b5147900ef35a6e1f508, - type: 3} - m_WaterEvaluationCS: {fileID: 7200000, guid: c24e765a2bbaace4d9a0ecec600e1967, - type: 3} - m_WaterPS: {fileID: -6465566751694194690, guid: 3fda5e465882bec4d8e64161b681806c, - type: 3} - m_WaterLightingCS: {fileID: 7200000, guid: 05d00ad19f202ee4891fdaa90d6d1b23, - type: 3} + type: {class: WaterSystemRuntimeResources, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} + data: + m_WaterMaterial: {fileID: -876546973899608171, guid: 3fda5e465882bec4d8e64161b681806c, type: 3} + m_WaterExclusionMaterial: {fileID: 2100000, guid: 1e520c84f7fd17c46af5586f6632155c, type: 2} + m_WaterDecalMaterial: {fileID: -876546973899608171, guid: 7e2c0d424490bfc4698c37245b8c63ed, type: 3} + m_WaterSimulationCS: {fileID: 7200000, guid: 32ac7f445960a854595586a600c24034, type: 3} + m_FourierTransformCS: {fileID: 7200000, guid: bc2ee21836a0b5147900ef35a6e1f508, type: 3} + m_WaterEvaluationCS: {fileID: 7200000, guid: c24e765a2bbaace4d9a0ecec600e1967, type: 3} + m_WaterPS: {fileID: -6465566751694194690, guid: 3fda5e465882bec4d8e64161b681806c, type: 3} + m_WaterLightingCS: {fileID: 7200000, guid: 05d00ad19f202ee4891fdaa90d6d1b23, type: 3} m_WaterLineCS: {fileID: 7200000, guid: 1e7e38362b5026d44ab4f3ff4a612026, type: 3} - m_WaterCausticsPS: {fileID: 4800000, guid: 020d64d10886f754e91664d240248c13, - type: 3} - m_WaterDecalPS: {fileID: 4800000, guid: cf863cbd7bbd44a43b414caed214ba29, - type: 3} - m_WaterDeformationCS: {fileID: 7200000, guid: 9b8063fa5834d4243bfca8c68a92d9f1, - type: 3} + m_WaterCausticsPS: {fileID: 4800000, guid: 020d64d10886f754e91664d240248c13, type: 3} + m_WaterDecalPS: {fileID: 4800000, guid: cf863cbd7bbd44a43b414caed214ba29, type: 3} + m_WaterDeformationCS: {fileID: 7200000, guid: 9b8063fa5834d4243bfca8c68a92d9f1, type: 3} m_WaterFoamCS: {fileID: 7200000, guid: 0d16d14b783e65f4d81dbcece2bd0ef9, type: 3} - m_WaterDecalMigrationShader: {fileID: -6465566751694194690, guid: 9f1661ed5b4d6ee4685ad5683b09a903, - type: 3} + m_WaterDecalMigrationShader: {fileID: -6465566751694194690, guid: 9f1661ed5b4d6ee4685ad5683b09a903, type: 3} m_FoamMask: {fileID: 2800000, guid: ca1d72d84c34dba4390eab4c86e62f62, type: 3} - rid: 6023113869122600973 - type: {class: CustomPostProcessOrdersSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: CustomPostProcessOrdersSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 m_BeforeTransparentCustomPostProcesses: @@ -783,141 +608,79 @@ MonoBehaviour: m_InjectionPoint: 2 m_CustomPostProcessTypesAsString: [] - rid: 6023113869122600974 - type: {class: HDRPDefaultVolumeProfileSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRPDefaultVolumeProfileSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 0 - m_VolumeProfile: {fileID: 11400000, guid: 6da6f79984c6a5e40ae22ead3a2ecfec, - type: 2} - - rid: 6023113869122600975 - type: {class: RenderGraphSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} - data: - m_Version: 0 - m_DynamicRenderPassCulling: 0 + m_VolumeProfile: {fileID: 11400000, guid: 6da6f79984c6a5e40ae22ead3a2ecfec, type: 2} - rid: 6023113869122600976 - type: {class: HDRPRayTracingResources, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} - data: - m_ReflectionRayTracingRT: {fileID: 4807578003741378534, guid: 1a500e5079fba734aa90fe92e70ea131, - type: 3} - m_ReflectionRayTracingCS: {fileID: 7200000, guid: 591207652a75a4844a89c0b9f45a61f2, - type: 3} - m_ReflectionBilateralFilterCS: {fileID: 7200000, guid: 07c445e7aa373284a9cc1584ca9b3f84, - type: 3} - m_ShadowRayTracingRT: {fileID: 4807578003741378534, guid: 6f93cb4dc095de14993f8d2baa972d5b, - type: 3} - m_ContactShadowRayTracingRT: {fileID: 4807578003741378534, guid: acaf840af875ab541b8f10069b7444c8, - type: 3} - m_ShadowRayTracingCS: {fileID: 7200000, guid: fc95b5dff16ba594896e211a389c03fc, - type: 3} - m_ShadowFilterCS: {fileID: 7200000, guid: f71fd853a538bf74e9e5a7228fc14dae, - type: 3} - m_ForwardRayTracing: {fileID: 4807578003741378534, guid: d3a89a2d3f73b3e4da6f191e844fe68c, - type: 3} - m_LightClusterBuildCS: {fileID: 7200000, guid: c0625ea908b52854bbf1d456e34026e4, - type: 3} - m_LightClusterDebugS: {fileID: 4800000, guid: c4d81c6e573560444bb1ea11ae4acfcb, - type: 3} - m_LightClusterDebugCS: {fileID: 7200000, guid: d48a3a5496d98a44c89f335934805d10, - type: 3} - m_IndirectDiffuseRayTracingOffRT: {fileID: 4807578003741378534, guid: fbcaf423d9f8e3843b2c046420608293, - type: 3} - m_IndirectDiffuseRayTracingL1RT: {fileID: 4807578003741378534, guid: 653044b9878c5764e818b20399112284, - type: 3} - m_IndirectDiffuseRaytracingL2RT: {fileID: 4807578003741378534, guid: 866a72c4868acec4088b0956b9ca73f9, - type: 3} - m_IndirectDiffuseRayTracingCS: {fileID: 7200000, guid: c5ad968b7cd39114d85dd860b3809087, - type: 3} - m_AoRayTracingRT: {fileID: 4807578003741378534, guid: 82dc8cd069971d2488c502b0f32b94fb, - type: 3} - m_AoRayTracingCS: {fileID: 7200000, guid: 10c05366baf9b0a44a827f3ef890b9e6, - type: 3} - m_SubSurfaceRayTracingRT: {fileID: 4807578003741378534, guid: b29a18f967c92364492508dddf78cff7, - type: 3} - m_SubSurfaceRayTracingCS: {fileID: 7200000, guid: 4e5684a8dba46fe42a47642f9b0a6b89, - type: 3} - m_SimpleDenoiserCS: {fileID: 7200000, guid: 74a980f1da9a4f842996035350fe756c, - type: 3} - m_ReflectionDenoiserCS: {fileID: 7200000, guid: 1b12fb238086d0f49983b4aa72768349, - type: 3} - m_DiffuseShadowDenoiserCS: {fileID: 7200000, guid: 9af806eab5889a74dad838edc9b07d07, - type: 3} - m_ReblurPreBlurCS: {fileID: 7200000, guid: 0be88ddf5240d49468d9159340465bfd, - type: 3} - m_ReblurTemporalAccumulationCS: {fileID: 7200000, guid: 11794ae415a38c747ba65d57d1bb60f9, - type: 3} - m_ReblurMipGenerationCS: {fileID: 7200000, guid: 44195ddb6d9240646847cbf4f38dfa98, - type: 3} - m_ReblurHistoryFixCS: {fileID: 7200000, guid: 4cc204b99166a9c40819bc04927c4feb, - type: 3} - m_ReblurBlurCS: {fileID: 7200000, guid: cff077c60ac76074893014e2f49e3159, - type: 3} - m_ReblurPostBlurCS: {fileID: 7200000, guid: 965700f9b9e0fec4bb31415ae91f0e09, - type: 3} - m_ReblurCopyHistoryCS: {fileID: 7200000, guid: 0d5230c403883b84cbf9d1d3b9e57beb, - type: 3} - m_ReblurTemporalStabilizationCS: {fileID: 7200000, guid: 4feaa605aeff33840b659850ce6bfcc2, - type: 3} - m_GBufferRayTracingRT: {fileID: 4807578003741378534, guid: e4c61a77b91f35845bbb546b848b18e5, - type: 3} - m_DeferredRayTracingCS: {fileID: 7200000, guid: 6e5ef632062bc484f812c7976f450ed1, - type: 3} - m_PathTracingRT: {fileID: 4807578003741378534, guid: c4f4525a058009a409fea974f9ad8d03, - type: 3} - m_PathTracingSkySamplingDataCS: {fileID: 7200000, guid: 8ef71a4b666992544ac5575a0e599a68, - type: 3} - m_RayMarchingCS: {fileID: 7200000, guid: 78d9a89700295a4418d0921bf27e1857, - type: 3} - m_RayBinningCS: {fileID: 7200000, guid: cddcb515ffe9a914893d6d8fc1d85454, - type: 3} - m_CountTracedRaysCS: {fileID: 7200000, guid: e1f3fa867f1dfbd4ab7dd4d39d2b96d8, - type: 3} - m_ReflectionFilterMappingTexture: {fileID: 2800000, guid: 82eec49626a00b047ba86244607816c8, - type: 3} - m_RtasDebugRT: {fileID: 4807578003741378534, guid: 7f98079d20376fd4f8590d58be99ab0d, - type: 3} + type: {class: HDRPRayTracingResources, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} + data: + m_ReflectionRayTracingRT: {fileID: 4807578003741378534, guid: 1a500e5079fba734aa90fe92e70ea131, type: 3} + m_ReflectionRayTracingCS: {fileID: 7200000, guid: 591207652a75a4844a89c0b9f45a61f2, type: 3} + m_ReflectionBilateralFilterCS: {fileID: 7200000, guid: 07c445e7aa373284a9cc1584ca9b3f84, type: 3} + m_ShadowRayTracingRT: {fileID: 4807578003741378534, guid: 6f93cb4dc095de14993f8d2baa972d5b, type: 3} + m_ContactShadowRayTracingRT: {fileID: 4807578003741378534, guid: acaf840af875ab541b8f10069b7444c8, type: 3} + m_ShadowRayTracingCS: {fileID: 7200000, guid: fc95b5dff16ba594896e211a389c03fc, type: 3} + m_ShadowFilterCS: {fileID: 7200000, guid: f71fd853a538bf74e9e5a7228fc14dae, type: 3} + m_ForwardRayTracing: {fileID: 4807578003741378534, guid: d3a89a2d3f73b3e4da6f191e844fe68c, type: 3} + m_LightClusterBuildCS: {fileID: 7200000, guid: c0625ea908b52854bbf1d456e34026e4, type: 3} + m_LightClusterDebugS: {fileID: 4800000, guid: c4d81c6e573560444bb1ea11ae4acfcb, type: 3} + m_LightClusterDebugCS: {fileID: 7200000, guid: d48a3a5496d98a44c89f335934805d10, type: 3} + m_IndirectDiffuseRayTracingOffRT: {fileID: 4807578003741378534, guid: fbcaf423d9f8e3843b2c046420608293, type: 3} + m_IndirectDiffuseRayTracingL1RT: {fileID: 4807578003741378534, guid: 653044b9878c5764e818b20399112284, type: 3} + m_IndirectDiffuseRaytracingL2RT: {fileID: 4807578003741378534, guid: 866a72c4868acec4088b0956b9ca73f9, type: 3} + m_IndirectDiffuseRayTracingCS: {fileID: 7200000, guid: c5ad968b7cd39114d85dd860b3809087, type: 3} + m_AoRayTracingRT: {fileID: 4807578003741378534, guid: 82dc8cd069971d2488c502b0f32b94fb, type: 3} + m_AoRayTracingCS: {fileID: 7200000, guid: 10c05366baf9b0a44a827f3ef890b9e6, type: 3} + m_SubSurfaceRayTracingRT: {fileID: 4807578003741378534, guid: b29a18f967c92364492508dddf78cff7, type: 3} + m_SubSurfaceRayTracingCS: {fileID: 7200000, guid: 4e5684a8dba46fe42a47642f9b0a6b89, type: 3} + m_SimpleDenoiserCS: {fileID: 7200000, guid: 74a980f1da9a4f842996035350fe756c, type: 3} + m_ReflectionDenoiserCS: {fileID: 7200000, guid: 1b12fb238086d0f49983b4aa72768349, type: 3} + m_DiffuseShadowDenoiserCS: {fileID: 7200000, guid: 9af806eab5889a74dad838edc9b07d07, type: 3} + m_ReblurPreBlurCS: {fileID: 7200000, guid: 0be88ddf5240d49468d9159340465bfd, type: 3} + m_ReblurTemporalAccumulationCS: {fileID: 7200000, guid: 11794ae415a38c747ba65d57d1bb60f9, type: 3} + m_ReblurMipGenerationCS: {fileID: 7200000, guid: 44195ddb6d9240646847cbf4f38dfa98, type: 3} + m_ReblurHistoryFixCS: {fileID: 7200000, guid: 4cc204b99166a9c40819bc04927c4feb, type: 3} + m_ReblurBlurCS: {fileID: 7200000, guid: cff077c60ac76074893014e2f49e3159, type: 3} + m_ReblurPostBlurCS: {fileID: 7200000, guid: 965700f9b9e0fec4bb31415ae91f0e09, type: 3} + m_ReblurCopyHistoryCS: {fileID: 7200000, guid: 0d5230c403883b84cbf9d1d3b9e57beb, type: 3} + m_ReblurTemporalStabilizationCS: {fileID: 7200000, guid: 4feaa605aeff33840b659850ce6bfcc2, type: 3} + m_GBufferRayTracingRT: {fileID: 4807578003741378534, guid: e4c61a77b91f35845bbb546b848b18e5, type: 3} + m_DeferredRayTracingCS: {fileID: 7200000, guid: 6e5ef632062bc484f812c7976f450ed1, type: 3} + m_PathTracingRT: {fileID: 4807578003741378534, guid: c4f4525a058009a409fea974f9ad8d03, type: 3} + m_PathTracingSkySamplingDataCS: {fileID: 7200000, guid: 8ef71a4b666992544ac5575a0e599a68, type: 3} + m_RayMarchingCS: {fileID: 7200000, guid: 78d9a89700295a4418d0921bf27e1857, type: 3} + m_RayBinningCS: {fileID: 7200000, guid: cddcb515ffe9a914893d6d8fc1d85454, type: 3} + m_CountTracedRaysCS: {fileID: 7200000, guid: e1f3fa867f1dfbd4ab7dd4d39d2b96d8, type: 3} + m_ReflectionFilterMappingTexture: {fileID: 2800000, guid: 82eec49626a00b047ba86244607816c8, type: 3} + m_RtasDebugRT: {fileID: 4807578003741378534, guid: 7f98079d20376fd4f8590d58be99ab0d, type: 3} - rid: 6023113869122600977 - type: {class: HDRenderPipelineEditorAssets, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRenderPipelineEditorAssets, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: - m_DefaultSettingsVolumeProfile: {fileID: 11400000, guid: f940a8037e6cda542891dc1aac1fa4e8, - type: 2} - m_LookDevDefaultLookDevVolumeProfile: {fileID: 11400000, guid: 254c4fe87beb7be4fa72e1681edbed02, - type: 2} + m_DefaultSettingsVolumeProfile: {fileID: 11400000, guid: f940a8037e6cda542891dc1aac1fa4e8, type: 2} + m_LookDevDefaultLookDevVolumeProfile: {fileID: 11400000, guid: 254c4fe87beb7be4fa72e1681edbed02, type: 2} m_DefaultDiffusionProfileSettingsList: - {fileID: 11400000, guid: 404820c4cf36ad944862fa59c56064f0, type: 2} - {fileID: 11400000, guid: 2384dbf2c1c420f45a792fbc315fbfb1, type: 2} - rid: 6023113869122600978 - type: {class: HDRenderPipelineEditorShaders, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} - data: - m_GpuInlineDebugDrawerLine: {fileID: 4800000, guid: 039c5248164c71b4aa6d780131c1bfaf, - type: 3} - m_AutodeskInteractive: {fileID: 4800000, guid: 7252379db4c18b641b517f2c91bb57e1, - type: 3} - m_AutodeskInteractiveTransparent: {fileID: 4800000, guid: ee2ce0be66f45d9449d71ba9b49c2acd, - type: 3} - m_AutodeskInteractiveMasked: {fileID: 4800000, guid: 29c4adff654862b40a2e9fb2015a42c3, - type: 3} - m_DefaultSpeedTree8Shader: {fileID: -6465566751694194690, guid: 4819724840ee9444f9da841b477038ce, - type: 3} - m_DefaultSpeedTree9Shader: {fileID: -6465566751694194690, guid: d81c74dd5f463104ca482aa23ef2c798, - type: 3} + type: {class: HDRenderPipelineEditorShaders, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} + data: + m_GpuInlineDebugDrawerLine: {fileID: 4800000, guid: 039c5248164c71b4aa6d780131c1bfaf, type: 3} + m_AutodeskInteractive: {fileID: 4800000, guid: 7252379db4c18b641b517f2c91bb57e1, type: 3} + m_AutodeskInteractiveTransparent: {fileID: 4800000, guid: ee2ce0be66f45d9449d71ba9b49c2acd, type: 3} + m_AutodeskInteractiveMasked: {fileID: 4800000, guid: 29c4adff654862b40a2e9fb2015a42c3, type: 3} + m_DefaultSpeedTree8Shader: {fileID: -6465566751694194690, guid: 4819724840ee9444f9da841b477038ce, type: 3} + m_DefaultSpeedTree9Shader: {fileID: -6465566751694194690, guid: d81c74dd5f463104ca482aa23ef2c798, type: 3} - rid: 6023113869122600979 - type: {class: WaterSystemGlobalSettings, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: WaterSystemGlobalSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: m_Version: 1 m_EnableMaskAndCurrentWaterDecals: 0 - rid: 6023113869122600980 - type: {class: HDRenderPipelineRuntimeTextures, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} + type: {class: HDRenderPipelineRuntimeTextures, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: - m_DebugFontTex: {fileID: 2800000, guid: a3ad2df0e49aaa341a3b3a80f93b3f66, - type: 3} - m_ColorGradient: {fileID: 2800000, guid: 4ea52e665573c1644bf05dd9b11fd2a4, - type: 3} + m_DebugFontTex: {fileID: 2800000, guid: a3ad2df0e49aaa341a3b3a80f93b3f66, type: 3} + m_ColorGradient: {fileID: 2800000, guid: 4ea52e665573c1644bf05dd9b11fd2a4, type: 3} m_MatcapTex: {fileID: 2800000, guid: e655445a13b501944a2641ea144edda5, type: 3} m_BlueNoise16LTex: - {fileID: 2800000, guid: efa2ea5416a18da46b64f1266464ffc7, type: 3} @@ -985,32 +748,19 @@ MonoBehaviour: - {fileID: 2800000, guid: 7641a2b116fafd64d9c3d6459fdfe801, type: 3} - {fileID: 2800000, guid: c6a5e40e6746fef4fa486e8f620ee8d4, type: 3} - {fileID: 2800000, guid: fd4189357c6dfb94fa2d36afbce72086, type: 3} - m_OwenScrambledRGBATex: {fileID: 2800000, guid: b0fe077c1ee7d80428f3d8dfa28a027d, - type: 3} - m_OwenScrambled256Tex: {fileID: 2800000, guid: 2a205358e67aa9e4a94a128ac9362f4e, - type: 3} - m_ScramblingTex: {fileID: 2800000, guid: bf25cd6288e2c8d43854a61a8496a830, - type: 3} - m_RankingTile1SPP: {fileID: 2800000, guid: f2fe0251f704c4c478a8063775cffedb, - type: 3} - m_ScramblingTile1SPP: {fileID: 2800000, guid: 6185473f62ad3e74da4acac5d482917a, - type: 3} - m_RankingTile8SPP: {fileID: 2800000, guid: af4bd638a4b3eb14781e6441adcdfbb9, - type: 3} - m_ScramblingTile8SPP: {fileID: 2800000, guid: 152f8b933250a7b448fc2d4d301b9944, - type: 3} - m_RankingTile256SPP: {fileID: 2800000, guid: 1e604a266c415cd46b36d97cd9220aa8, - type: 3} - m_ScramblingTile256SPP: {fileID: 2800000, guid: 882fb55d7b3e7c94598a318df9376e32, - type: 3} - m_EyeCausticLUT: {fileID: 11700000, guid: d4ec12283a044584794485916f4142a9, - type: 3} - m_HairAttenuationLUT: {fileID: 11700000, guid: d37662e2b254e594abf839dddc5ab653, - type: 2} - m_HairAzimuthalScatteringLUT: {fileID: 11700000, guid: d217deac7ff61094080126811521ab5b, - type: 2} - m_HairLongitudinalScatteringLUT: {fileID: 11700000, guid: 0da412d38ea6ba3459322abe6984ca9b, - type: 2} + m_OwenScrambledRGBATex: {fileID: 2800000, guid: b0fe077c1ee7d80428f3d8dfa28a027d, type: 3} + m_OwenScrambled256Tex: {fileID: 2800000, guid: 2a205358e67aa9e4a94a128ac9362f4e, type: 3} + m_ScramblingTex: {fileID: 2800000, guid: bf25cd6288e2c8d43854a61a8496a830, type: 3} + m_RankingTile1SPP: {fileID: 2800000, guid: f2fe0251f704c4c478a8063775cffedb, type: 3} + m_ScramblingTile1SPP: {fileID: 2800000, guid: 6185473f62ad3e74da4acac5d482917a, type: 3} + m_RankingTile8SPP: {fileID: 2800000, guid: af4bd638a4b3eb14781e6441adcdfbb9, type: 3} + m_ScramblingTile8SPP: {fileID: 2800000, guid: 152f8b933250a7b448fc2d4d301b9944, type: 3} + m_RankingTile256SPP: {fileID: 2800000, guid: 1e604a266c415cd46b36d97cd9220aa8, type: 3} + m_ScramblingTile256SPP: {fileID: 2800000, guid: 882fb55d7b3e7c94598a318df9376e32, type: 3} + m_EyeCausticLUT: {fileID: 11700000, guid: d4ec12283a044584794485916f4142a9, type: 3} + m_HairAttenuationLUT: {fileID: 11700000, guid: d37662e2b254e594abf839dddc5ab653, type: 2} + m_HairAzimuthalScatteringLUT: {fileID: 11700000, guid: d217deac7ff61094080126811521ab5b, type: 2} + m_HairLongitudinalScatteringLUT: {fileID: 11700000, guid: 0da412d38ea6ba3459322abe6984ca9b, type: 2} m_FilmGrainTex: - {fileID: 2800000, guid: 284a1ac236869fa4eacf377d73c7dff8, type: 3} - {fileID: 2800000, guid: bd74961b009b93145a998ae93a5fc186, type: 3} @@ -1022,56 +772,36 @@ MonoBehaviour: - {fileID: 2800000, guid: a187955d1d88a954cb32c3c4e5f0aeda, type: 3} - {fileID: 2800000, guid: 3f3cb0f4924d7a241b82a9081875f30d, type: 3} - {fileID: 2800000, guid: a35bdcb2008832646b3c8d2eb11e38a9, type: 3} - m_SMAASearchTex: {fileID: 2800000, guid: dc95d70472e232b438d0fd38651e7ec2, - type: 3} + m_SMAASearchTex: {fileID: 2800000, guid: dc95d70472e232b438d0fd38651e7ec2, type: 3} m_SMAAAreaTex: {fileID: 2800000, guid: 92e0d85ab4eca874098e7fcf6f8f674e, type: 3} - m_DefaultHDRISky: {fileID: 8900000, guid: 8253d41e6e8b11a4cbe77a4f8f82934d, - type: 3} - m_DefaultCloudMap: {fileID: 2800000, guid: 57a33fc2476a01644865bfde5f06e2f4, - type: 3} + m_DefaultHDRISky: {fileID: 8900000, guid: 8253d41e6e8b11a4cbe77a4f8f82934d, type: 3} + m_DefaultCloudMap: {fileID: 2800000, guid: 57a33fc2476a01644865bfde5f06e2f4, type: 3} - rid: 6023113869122600981 - type: {class: HDRenderPipelineEditorMaterials, ns: UnityEngine.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Runtime} - data: - m_DefaultMaterial: {fileID: 2100000, guid: 73c176f402d2c2f4d929aa5da7585d17, - type: 2} - m_DefaultParticleMaterial: {fileID: 2100000, guid: b739a3f02ff77bf48b7636e64c3e3b4c, - type: 2} - m_DefaultTerrainMaterial: {fileID: 2100000, guid: 22ff8771d87ef27429e670136399094b, - type: 2} - m_DefaultMirrorMat: {fileID: 2100000, guid: 6b17274157b33bc45b6a40e7d4ff51fe, - type: 2} - m_DefaultDecalMat: {fileID: 2100000, guid: 500e733574922d04ea961553b1b26a63, - type: 2} - m_GUITextureBlit2SRGB: {fileID: 2100000, guid: 6e95c04e4e686554e8bed96ee69f690c, - type: 2} + type: {class: HDRenderPipelineEditorMaterials, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} + data: + m_DefaultMaterial: {fileID: 2100000, guid: 73c176f402d2c2f4d929aa5da7585d17, type: 2} + m_DefaultParticleMaterial: {fileID: 2100000, guid: b739a3f02ff77bf48b7636e64c3e3b4c, type: 2} + m_DefaultTerrainMaterial: {fileID: 2100000, guid: 22ff8771d87ef27429e670136399094b, type: 2} + m_DefaultMirrorMat: {fileID: 2100000, guid: 6b17274157b33bc45b6a40e7d4ff51fe, type: 2} + m_DefaultDecalMat: {fileID: 2100000, guid: 500e733574922d04ea961553b1b26a63, type: 2} + m_GUITextureBlit2SRGB: {fileID: 2100000, guid: 6e95c04e4e686554e8bed96ee69f690c, type: 2} - rid: 6023113869122600982 - type: {class: HDRenderingLayersLimitSettings, ns: UnityEditor.Rendering.HighDefinition, - asm: Unity.RenderPipelines.HighDefinition.Editor} + type: {class: HDRenderingLayersLimitSettings, ns: UnityEditor.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Editor} data: m_Version: 0 - rid: 6023113869122600983 type: {class: GPUResidentDrawerResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.GPUDriven.Runtime} data: m_Version: 0 - m_InstanceDataBufferCopyKernels: {fileID: 7200000, guid: f984aeb540ded8b4fbb8a2047ab5b2e2, - type: 3} - m_InstanceDataBufferUploadKernels: {fileID: 7200000, guid: 53864816eb00f2343b60e1a2c5a262ef, - type: 3} - m_TransformUpdaterKernels: {fileID: 7200000, guid: 2a567b9b2733f8d47a700c3c85bed75b, - type: 3} - m_WindDataUpdaterKernels: {fileID: 7200000, guid: fde76746e4fd0ed418c224f6b4084114, - type: 3} - m_OccluderDepthPyramidKernels: {fileID: 7200000, guid: 08b2b5fb307b0d249860612774a987da, - type: 3} - m_InstanceOcclusionCullingKernels: {fileID: 7200000, guid: f6d223acabc2f974795a5a7864b50e6c, - type: 3} - m_OcclusionCullingDebugKernels: {fileID: 7200000, guid: b23e766bcf50ca4438ef186b174557df, - type: 3} - m_DebugOcclusionTestPS: {fileID: 4800000, guid: d3f0849180c2d0944bc71060693df100, - type: 3} - m_DebugOccluderPS: {fileID: 4800000, guid: b3c92426a88625841ab15ca6a7917248, - type: 3} + m_InstanceDataBufferCopyKernels: {fileID: 7200000, guid: f984aeb540ded8b4fbb8a2047ab5b2e2, type: 3} + m_InstanceDataBufferUploadKernels: {fileID: 7200000, guid: 53864816eb00f2343b60e1a2c5a262ef, type: 3} + m_TransformUpdaterKernels: {fileID: 7200000, guid: 2a567b9b2733f8d47a700c3c85bed75b, type: 3} + m_WindDataUpdaterKernels: {fileID: 7200000, guid: fde76746e4fd0ed418c224f6b4084114, type: 3} + m_OccluderDepthPyramidKernels: {fileID: 7200000, guid: 08b2b5fb307b0d249860612774a987da, type: 3} + m_InstanceOcclusionCullingKernels: {fileID: 7200000, guid: f6d223acabc2f974795a5a7864b50e6c, type: 3} + m_OcclusionCullingDebugKernels: {fileID: 7200000, guid: b23e766bcf50ca4438ef186b174557df, type: 3} + m_DebugOcclusionTestPS: {fileID: 4800000, guid: d3f0849180c2d0944bc71060693df100, type: 3} + m_DebugOccluderPS: {fileID: 4800000, guid: b3c92426a88625841ab15ca6a7917248, type: 3} - rid: 6023113869122600984 type: {class: RenderGraphGlobalSettings, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: @@ -1079,8 +809,7 @@ MonoBehaviour: m_EnableCompilationCaching: 1 m_EnableValidityChecks: 1 - rid: 6023113869122600985 - type: {class: RenderGraphUtilsResources, ns: UnityEngine.Rendering.RenderGraphModule.Util, - asm: Unity.RenderPipelines.Core.Runtime} + type: {class: RenderGraphUtilsResources, ns: UnityEngine.Rendering.RenderGraphModule.Util, asm: Unity.RenderPipelines.Core.Runtime} data: m_Version: 0 m_CoreCopyPS: {fileID: 4800000, guid: 12dc59547ea167a4ab435097dd0f9add, type: 3} @@ -1094,50 +823,32 @@ MonoBehaviour: type: {class: ProbeVolumeRuntimeResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: m_Version: 1 - probeVolumeBlendStatesCS: {fileID: 7200000, guid: a3f7b8c99de28a94684cb1daebeccf5d, - type: 3} - probeVolumeUploadDataCS: {fileID: 7200000, guid: 0951de5992461754fa73650732c4954c, - type: 3} - probeVolumeUploadDataL2CS: {fileID: 7200000, guid: 6196f34ed825db14b81fb3eb0ea8d931, - type: 3} + probeVolumeBlendStatesCS: {fileID: 7200000, guid: a3f7b8c99de28a94684cb1daebeccf5d, type: 3} + probeVolumeUploadDataCS: {fileID: 7200000, guid: 0951de5992461754fa73650732c4954c, type: 3} + probeVolumeUploadDataL2CS: {fileID: 7200000, guid: 6196f34ed825db14b81fb3eb0ea8d931, type: 3} - rid: 6023113869122600988 type: {class: ProbeVolumeBakingResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: m_Version: 1 - dilationShader: {fileID: 7200000, guid: 6bb382f7de370af41b775f54182e491d, - type: 3} - subdivideSceneCS: {fileID: 7200000, guid: bb86f1f0af829fd45b2ebddda1245c22, - type: 3} - voxelizeSceneShader: {fileID: 4800000, guid: c8b6a681c7b4e2e4785ffab093907f9e, - type: 3} - traceVirtualOffsetCS: {fileID: -6772857160820960102, guid: ff2cbab5da58bf04d82c5f34037ed123, - type: 3} - traceVirtualOffsetRT: {fileID: -5126288278712620388, guid: ff2cbab5da58bf04d82c5f34037ed123, - type: 3} - skyOcclusionCS: {fileID: -6772857160820960102, guid: 5a2a534753fbdb44e96c3c78b5a6999d, - type: 3} - skyOcclusionRT: {fileID: -5126288278712620388, guid: 5a2a534753fbdb44e96c3c78b5a6999d, - type: 3} - renderingLayerCS: {fileID: -6772857160820960102, guid: 94a070d33e408384bafc1dea4a565df9, - type: 3} - renderingLayerRT: {fileID: -5126288278712620388, guid: 94a070d33e408384bafc1dea4a565df9, - type: 3} + dilationShader: {fileID: 7200000, guid: 6bb382f7de370af41b775f54182e491d, type: 3} + subdivideSceneCS: {fileID: 7200000, guid: bb86f1f0af829fd45b2ebddda1245c22, type: 3} + voxelizeSceneShader: {fileID: 4800000, guid: c8b6a681c7b4e2e4785ffab093907f9e, type: 3} + traceVirtualOffsetCS: {fileID: -6772857160820960102, guid: ff2cbab5da58bf04d82c5f34037ed123, type: 3} + traceVirtualOffsetRT: {fileID: -5126288278712620388, guid: ff2cbab5da58bf04d82c5f34037ed123, type: 3} + skyOcclusionCS: {fileID: -6772857160820960102, guid: 5a2a534753fbdb44e96c3c78b5a6999d, type: 3} + skyOcclusionRT: {fileID: -5126288278712620388, guid: 5a2a534753fbdb44e96c3c78b5a6999d, type: 3} + renderingLayerCS: {fileID: -6772857160820960102, guid: 94a070d33e408384bafc1dea4a565df9, type: 3} + renderingLayerRT: {fileID: -5126288278712620388, guid: 94a070d33e408384bafc1dea4a565df9, type: 3} - rid: 6023113869122600989 type: {class: ProbeVolumeDebugResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: m_Version: 1 - probeVolumeDebugShader: {fileID: 4800000, guid: 3b21275fd12d65f49babb5286f040f2d, - type: 3} - probeVolumeFragmentationDebugShader: {fileID: 4800000, guid: 3a80877c579b9144ebdcc6d923bca303, - type: 3} - probeVolumeSamplingDebugShader: {fileID: 4800000, guid: bf54e6528c79a224e96346799064c393, - type: 3} - probeVolumeOffsetDebugShader: {fileID: 4800000, guid: db8bd7436dc2c5f4c92655307d198381, - type: 3} - probeSamplingDebugMesh: {fileID: -3555484719484374845, guid: 20be25aac4e22ee49a7db76fb3df6de2, - type: 3} - numbersDisplayTex: {fileID: 2800000, guid: 73fe53b428c5b3440b7e87ee830b608a, - type: 3} + probeVolumeDebugShader: {fileID: 4800000, guid: 3b21275fd12d65f49babb5286f040f2d, type: 3} + probeVolumeFragmentationDebugShader: {fileID: 4800000, guid: 3a80877c579b9144ebdcc6d923bca303, type: 3} + probeVolumeSamplingDebugShader: {fileID: 4800000, guid: bf54e6528c79a224e96346799064c393, type: 3} + probeVolumeOffsetDebugShader: {fileID: 4800000, guid: db8bd7436dc2c5f4c92655307d198381, type: 3} + probeSamplingDebugMesh: {fileID: -3555484719484374845, guid: 20be25aac4e22ee49a7db76fb3df6de2, type: 3} + numbersDisplayTex: {fileID: 2800000, guid: 73fe53b428c5b3440b7e87ee830b608a, type: 3} - rid: 6023113869122600990 type: {class: ShaderStrippingSetting, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: @@ -1158,27 +869,24 @@ MonoBehaviour: m_IncludeAssetsByLabel: 1 m_LabelToInclude: HDRP:IncludeInBuild - rid: 6023113869122600993 - type: {class: RenderingDebuggerRuntimeResources, ns: UnityEngine.Rendering, - asm: Unity.RenderPipelines.Core.Runtime} + type: {class: RenderingDebuggerRuntimeResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: m_version: 0 - m_DebugUIHandlerCanvasPrefab: {fileID: 1153602445894428, guid: cf6cbdd672089a84796e55a21fed1cbe, - type: 3} - m_DebugUIPersistentCanvasPrefab: {fileID: 1822588063230394, guid: f6b1a0fe75d5009449cf55ae76220e2b, - type: 3} + m_PanelSettings: {fileID: 11400000, guid: fa69697be3070b04a893666f5947f18c, type: 2} + m_StyleSheets: + - {fileID: 7433441132597879392, guid: 0ff99fd36f66f1a41bcc1d3c90e0922a, type: 3} + - {fileID: 7433441132597879392, guid: 3a8aa4d508da46d4dace18b280f064aa, type: 3} + m_VisualTreeAsset: {fileID: 9197481963319205126, guid: b647ceb1e15264943b9b439971e71110, type: 3} - rid: 6023113869122600994 type: {class: LightmapSamplingSettings, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: m_Version: 1 m_UseBicubicLightmapSampling: 0 - rid: 6023113869122600995 - type: {class: VrsRenderPipelineRuntimeResources, ns: UnityEngine.Rendering, - asm: Unity.RenderPipelines.Core.Runtime} + type: {class: VrsRenderPipelineRuntimeResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} data: - m_TextureComputeShader: {fileID: 7200000, guid: cacb30de6c40c7444bbc78cb0a81fd2a, - type: 3} - m_VisualizationShader: {fileID: 4800000, guid: 620b55b8040a88d468e94abe55bed5ba, - type: 3} + m_TextureComputeShader: {fileID: 7200000, guid: cacb30de6c40c7444bbc78cb0a81fd2a, type: 3} + m_VisualizationShader: {fileID: 4800000, guid: 620b55b8040a88d468e94abe55bed5ba, type: 3} m_VisualizationLookupTable: m_Data: - {r: 1, g: 0, b: 0, a: 1} diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs index 4faf68ebe36..2f33b42bc36 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs @@ -24,15 +24,15 @@ public class VFXGraphicsTests [IgnoreGraphicsTest("021_Check_Garbage_Spawner", "No reference images provided")] [IgnoreGraphicsTest("022_Repro_Crash_Null_Indexbuffer", "No reference images provided")] [IgnoreGraphicsTest("023_Check_Garbage_Timeline", "No reference images provided")] - [IgnoreGraphicsTest("026_InstancingGPUevents", "See UUM-88671", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal })] + [IgnoreGraphicsTest("026_InstancingGPUevents", "See UUM-88671", GraphicsDeviceType.Metal)] [IgnoreGraphicsTest("026_RWBuffer", "Unstable: https://jira.unity3d.com/browse/UUM-119810")] - [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822 and VFXG-539", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxOne, RuntimePlatform.Switch })] - [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] - [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] - [IgnoreGraphicsTest("015_FixedTime", "See UUM-109089", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] - [IgnoreGraphicsTest("DebugAlbedo", "Onscreen assert", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch2 })] - [IgnoreGraphicsTest("36_SkinnedSDF", "Onscreen assert", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch2 })] - [IgnoreGraphicsTest("015_FixedTime", "Onscreen assert", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch2 })] + [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822 and VFXG-539", RuntimePlatform.GameCoreXboxOne, RuntimePlatform.Switch)] + [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", RuntimePlatform.Switch)] + [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", RuntimePlatform.Switch)] + [IgnoreGraphicsTest("015_FixedTime", "See UUM-109089", RuntimePlatform.Switch)] + [IgnoreGraphicsTest("DebugAlbedo", "Onscreen assert", RuntimePlatform.Switch2)] + [IgnoreGraphicsTest("36_SkinnedSDF", "Onscreen assert", RuntimePlatform.Switch2)] + [IgnoreGraphicsTest("015_FixedTime", "Onscreen assert", RuntimePlatform.Switch2)] [IgnoreGraphicsTest("Repro_SampleGradient_Branch_Instancing", "Compute shader ([Repro_SampleGradient_Branch_Instancing] [Minimal] Update Particles): Property (Repro_SampleGradient_Branch_Instancing_Buffer) at kernel index (0) is not set")] [IgnoreGraphicsTest("Empty", "No reference images provided")] [IgnoreGraphicsTest("Empty_With_Camera", "No reference images provided")] diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_PerformanceTests.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_PerformanceTests.cs index e875ddf7d74..5864d5313a7 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_PerformanceTests.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_PerformanceTests.cs @@ -28,10 +28,10 @@ public class VFXRuntimePerformanceTests : PerformanceTests [IgnoreGraphicsTest("021_Check_Garbage_Spawner", "No reference images provided")] [IgnoreGraphicsTest("022_Repro_Crash_Null_Indexbuffer", "No reference images provided")] [IgnoreGraphicsTest("023_Check_Garbage_Timeline", "No reference images provided")] - [IgnoreGraphicsTest("026_InstancingGPUevents", "See UUM-88671", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal })] - [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxOne })] - [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] - [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] + [IgnoreGraphicsTest("026_InstancingGPUevents", "See UUM-88671", GraphicsDeviceType.Metal)] + [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822", RuntimePlatform.GameCoreXboxOne)] + [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", RuntimePlatform.Switch)] + [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", RuntimePlatform.Switch)] [IgnoreGraphicsTest("Repro_SampleGradient_Branch_Instancing", "Compute shader ([Repro_SampleGradient_Branch_Instancing] [Minimal] Update Particles): Property (Repro_SampleGradient_Branch_Instancing_Buffer) at kernel index (0) is not set")] [IgnoreGraphicsTest("Empty", "No reference images provided")] [IgnoreGraphicsTest("Empty_With_Camera", "No reference images provided")] @@ -75,10 +75,10 @@ public class VFXRuntimeMemoryTests : PerformanceTests [IgnoreGraphicsTest("021_Check_Garbage_Spawner", "No reference images provided")] [IgnoreGraphicsTest("022_Repro_Crash_Null_Indexbuffer", "No reference images provided")] [IgnoreGraphicsTest("023_Check_Garbage_Timeline", "No reference images provided")] - [IgnoreGraphicsTest("026_InstancingGPUevents", "See UUM-88671", graphicsDeviceTypes: new GraphicsDeviceType[] { GraphicsDeviceType.Metal })] - [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.GameCoreXboxOne })] - [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] - [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", runtimePlatforms: new RuntimePlatform[] { RuntimePlatform.Switch })] + [IgnoreGraphicsTest("026_InstancingGPUevents", "See UUM-88671", GraphicsDeviceType.Metal)] + [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822", RuntimePlatform.GameCoreXboxOne)] + [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", RuntimePlatform.Switch)] + [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", RuntimePlatform.Switch)] [IgnoreGraphicsTest("Repro_SampleGradient_Branch_Instancing", "Compute shader ([Repro_SampleGradient_Branch_Instancing] [Minimal] Update Particles): Property (Repro_SampleGradient_Branch_Instancing_Buffer) at kernel index (0) is not set")] [IgnoreGraphicsTest("Empty", "No reference images provided")] [IgnoreGraphicsTest("Empty_With_Camera", "No reference images provided")] diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/PackageManagerSettings.asset b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/PackageManagerSettings.asset index 73b2bb809c2..a07a04bef62 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/PackageManagerSettings.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/PackageManagerSettings.asset @@ -18,20 +18,27 @@ MonoBehaviour: m_SeeAllPackageVersions: 0 m_DismissPreviewPackagesInUse: 0 oneTimeWarningShown: 0 - oneTimeDeprecatedPopUpShown: 0 - m_Registries: - - m_Id: main + oneTimePackageErrorsPopUpShown: 0 + m_MainRegistry: + m_Id: main m_Name: - m_Url: https://artifactory-slo.bf.unity3d.com/artifactory/api/npm/upm-candidates + m_Url: https://packages.unity.com m_Scopes: [] m_IsDefault: 1 - m_Capabilities: 0 + m_IsUnityRegistry: 1 + m_Capabilities: 7 m_ConfigSource: 0 + m_Compliance: + m_Status: 0 + m_Violations: [] + m_ScopedRegistries: [] m_UserSelectedRegistryName: m_UserAddingNewScopedRegistry: 0 m_RegistryInfoDraft: m_Modified: 0 m_ErrorMessage: - m_UserModificationsInstanceId: -896 - m_OriginalInstanceId: -898 + m_UserModificationsEntityId: + m_rawData: 568105589213756490 + m_OriginalEntityId: + m_rawData: 568105589213756488 m_LoadAssets: 0 diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/ShaderGraphSettings.asset b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/ShaderGraphSettings.asset index d43918dc535..e33ca2483e0 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/ShaderGraphSettings.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/ShaderGraphSettings.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Unity.ShaderGraph.Editor::UnityEditor.ShaderGraph.ShaderGraphProjectSettings shaderVariantLimit: 2048 + overrideShaderVariantLimit: 0 customInterpolatorErrorThreshold: 32 customInterpolatorWarningThreshold: 16 customHeatmapValues: {fileID: 0} diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/VFXManager.asset b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/VFXManager.asset index 221bfb833af..a6c56598f99 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/VFXManager.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/ProjectSettings/VFXManager.asset @@ -15,6 +15,6 @@ VFXManager: m_MaxScrubTime: 30 m_MaxCapacity: 100000000 m_CompiledVersion: 7 - m_RuntimeVersion: 38 + m_RuntimeVersion: 40 m_RuntimeResources: {fileID: 11400000, guid: bc10b42afe3813544bffd38ae2cd893d, type: 2} m_BatchEmptyLifetime: 300 From 160e6b14f05d985b9e4369eb43e38441f61fda1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Maetz?= Date: Mon, 30 Mar 2026 19:31:10 +0000 Subject: [PATCH 05/88] Fix material debug not working --- .../Components/Debug/DebugMaterials.shadersubgraph | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.shadergraph/Samples~/CustomLighting/Components/Debug/DebugMaterials.shadersubgraph b/Packages/com.unity.shadergraph/Samples~/CustomLighting/Components/Debug/DebugMaterials.shadersubgraph index 54ef671ca09..40cca71738f 100644 --- a/Packages/com.unity.shadergraph/Samples~/CustomLighting/Components/Debug/DebugMaterials.shadersubgraph +++ b/Packages/com.unity.shadergraph/Samples~/CustomLighting/Components/Debug/DebugMaterials.shadersubgraph @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20ae7edbf30e8d9e39034a8181de491e80841f734885bdc5389b546d36873d93 -size 53717 +oid sha256:1bdc23cc7ff405cf1e4f793ace2a38582602125141dd7717eb2ac1b2c0a49f6a +size 53847 From 389f2da0dd5a5bdfae3c85290ba56253d6bc8f28 Mon Sep 17 00:00:00 2001 From: Kenny Tan Date: Mon, 30 Mar 2026 19:31:11 +0000 Subject: [PATCH 06/88] [UUM-136415][6000.6][URP 2D] Add capture pass for recorder --- .../Runtime/2D/Rendergraph/DrawRenderer2DPass.cs | 8 ++++++-- .../Runtime/2D/Rendergraph/Renderer2DRendergraph.cs | 13 +++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs index 359156f4704..91372f3983c 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs @@ -103,6 +103,10 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex // Early out for preview camera if (cameraData.cameraType == CameraType.Preview) isLitView = false; + + DebugHandler debugHandler = GetActiveDebugHandler(cameraData); + if (debugHandler != null) + isLitView = debugHandler.IsLightingActive; #endif // Preset global light textures for first batch @@ -110,7 +114,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex { using (var builder = graph.AddRasterRenderPass(k_SetLightBlendTexture, out var passData, m_SetLightBlendTextureProfilingSampler)) { - if (layerBatch.lightStats.useLights) + if (layerBatch.lightStats.useLights && isLitView) { passData.lightTextures = universal2DResourceData.lightTextures[batchIndex]; for (var i = 0; i < passData.lightTextures.Length; i++) @@ -164,7 +168,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex builder.UseRendererList(passData.rendererList); } - if (passData.layerUseLights) + if (passData.layerUseLights && isLitView) { passData.lightTextures = universal2DResourceData.lightTextures[batchIndex]; for (var i = 0; i < passData.lightTextures.Length; i++) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs index c6db7098961..ee9bbd216a3 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs @@ -56,6 +56,7 @@ private struct ImportResourceSummary CopyDepthPass m_CopyDepthPass; UpscalePass m_UpscalePass; CopyCameraSortingLayerPass m_CopyCameraSortingLayerPass; + CapturePass m_CapturePass; FinalBlitPass m_FinalBlitPass; FinalBlitPass m_OffscreenUICoverPrepass; DrawScreenSpaceUIPass m_DrawOffscreenUIPass; @@ -114,6 +115,7 @@ public Renderer2D(Renderer2DData data) : base(data) m_UpscalePass = new UpscalePass(RenderPassEvent.AfterRenderingPostProcessing, m_BlitMaterial); m_CopyCameraSortingLayerPass = new CopyCameraSortingLayerPass(m_BlitMaterial); + m_CapturePass = new CapturePass(RenderPassEvent.AfterRendering); m_FinalBlitPass = new FinalBlitPass(RenderPassEvent.AfterRendering + k_FinalBlitPassQueueOffset, m_BlitMaterial, m_BlitHDRMaterial); m_OffscreenUICoverPrepass = new FinalBlitPass(RenderPassEvent.BeforeRenderingPostProcessing, m_BlitMaterial, m_BlitOffscreenUICoverMaterial); @@ -196,7 +198,8 @@ private RenderPassInputSummary GetRenderPassInputs() || cameraData.cameraTargetDescriptor.msaaSamples > 1 && UniversalRenderer.PlatformRequiresExplicitMsaaResolve() || m_Renderer2DData.useCameraSortingLayerTexture || !Mathf.Approximately(cameraData.renderScale, 1.0f) - || (DebugHandler != null && DebugHandler.WriteToDebugScreenTexture(cameraData.resolveFinalTarget)); + || (DebugHandler != null && DebugHandler.WriteToDebugScreenTexture(cameraData.resolveFinalTarget)) + || cameraData.captureActions != null; return inputSummary; } @@ -977,7 +980,13 @@ private void OnAfterRendering(RenderGraph renderGraph) { m_UpscalePass.Render(renderGraph, cameraData.camera, commonResourceData.cameraColor, universal2DResourceData.upscaleTexture); commonResourceData.cameraColor = universal2DResourceData.upscaleTexture; - } + } + + // Capture pass for Unity Recorder + if (hasCaptureActions) + { + m_CapturePass.RecordRenderGraph(renderGraph, frameData); + } if (applyFinalPostProcessing) { From d2b72dfaf1d4dca39d079d90cfb68446b733853c Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 31 Mar 2026 00:57:47 +0000 Subject: [PATCH 07/88] GFXLIGHT-2046 : Make the roughness blur less dependent on resolution and field of view --- .../ShaderLibrary/ImageBasedLighting.hlsl | 2 +- .../Overrides/ScreenSpaceReflectionEditor.cs | 10 +++ .../Runtime/MipGen/MipGenerator.cs | 4 +- .../ScreenSpaceReflectionPass.cs | 35 ++++++++- .../ScreenSpaceReflectionVolumeSettings.cs | 4 + .../ComputeScreenSpaceReflection.hlsl | 11 ++- .../ShaderLibrary/GlobalIllumination.hlsl | 2 +- .../ShaderLibrary/Input.hlsl | 2 +- .../SampleScreenSpaceReflection.hlsl | 10 +-- .../ScreenSpaceReflectionCommon.hlsl | 78 +++++++++++++++++++ .../ScreenSpaceReflectionCommon.hlsl.meta | 3 + 11 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl.meta diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl index 515878e8254..bec560a8bb7 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl @@ -12,7 +12,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl" #ifndef UNITY_SPECCUBE_LOD_STEPS - // This is actuall the last mip index, we generate 7 mips of convolution + // This is actually the last mip index, we generate 7 mips of convolution #define UNITY_SPECCUBE_LOD_STEPS 6 #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Overrides/ScreenSpaceReflectionEditor.cs b/Packages/com.unity.render-pipelines.universal/Editor/Overrides/ScreenSpaceReflectionEditor.cs index 7c75307f06a..fb301a335c0 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Overrides/ScreenSpaceReflectionEditor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Overrides/ScreenSpaceReflectionEditor.cs @@ -33,6 +33,7 @@ enum PerformancePreset SerializedDataParameter m_Mode; SerializedDataParameter m_AfterOpaque; SerializedDataParameter m_RoughReflections; + SerializedDataParameter m_RoughnessScale; SerializedDataParameter m_MinimumSmoothness; SerializedDataParameter m_SmoothnessFadeStart; SerializedDataParameter m_NormalFade; @@ -119,6 +120,7 @@ public override void OnEnable() m_HitRefinementSteps = Unpack(o.Find(x => x.hitRefinementSteps)); m_FinalThicknessMultiplier = Unpack(o.Find(x => x.finalThicknessMultiplier)); m_RoughReflections = Unpack(o.Find(x => x.roughReflections)); + m_RoughnessScale = Unpack(o.Find(x => x.roughnessScale)); m_MinimumSmoothness = Unpack(o.Find(x => x.minimumSmoothness)); m_SmoothnessFadeStart = Unpack(o.Find(x => x.smoothnessFadeStart)); m_NormalFade = Unpack(o.Find(x => x.normalFade)); @@ -194,6 +196,14 @@ public override void OnInspectorGUI() DrawHeader("Visual Quality"); PropertyField(m_Mode); PropertyField(m_RoughReflections); + if (m_RoughReflections.value.enumValueIndex != (int)ScreenSpaceReflectionVolumeSettings.RoughReflectionsQuality.Disabled) + { + using (new EditorGUI.DisabledScope(!m_RoughReflections.overrideState.boolValue)) + { + PropertyField(m_RoughnessScale); + } + } + PropertyField(m_MinimumSmoothness); PropertyField(m_SmoothnessFadeStart); m_SmoothnessFadeStart.value.floatValue = Mathf.Max(m_MinimumSmoothness.value.floatValue, m_SmoothnessFadeStart.value.floatValue); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs index 8f7fcd4f482..f988ea90383 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs @@ -155,6 +155,8 @@ internal class MipGenerator public static readonly string k_EnableCheckerboard = "ENABLE_CHECKERBOARD"; + public const int k_MinimumResolutionGaussian = 8; + public MipGenerator(bool preferCompute = true) { if (!GraphicsSettings.TryGetRenderPipelineSettings(out var runtimeShaders)) @@ -347,7 +349,7 @@ public int RenderColorGaussianPyramid(RenderGraph renderGraph, Vector2Int size, // Note: smaller mips are excluded as we don't need them and the gaussian compute works // on 8x8 blocks - while (srcMipWidth >= 8 || srcMipHeight >= 8) + while (srcMipWidth >= k_MinimumResolutionGaussian || srcMipHeight >= k_MinimumResolutionGaussian) { int dstMipWidth = Mathf.Max(1, srcMipWidth >> 1); int dstMipHeight = Mathf.Max(1, srcMipHeight >> 1); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs index 368aae3d1ea..ff4368857bd 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs @@ -52,12 +52,12 @@ private enum ShaderPasses internal static class ShaderConstants { internal static readonly int _ReflectionParam = Shader.PropertyToID("_ScreenSpaceReflectionParam"); + internal static readonly int _ReflectionParam2 = Shader.PropertyToID("_ScreenSpaceReflectionParam2"); internal static readonly int _MaxRayLength = Shader.PropertyToID("_MaxRayLength"); internal static readonly int _MaxRaySteps = Shader.PropertyToID("_MaxRaySteps"); internal static readonly int _Downsample = Shader.PropertyToID("_Downsample"); internal static readonly int _ThicknessScaleAndBias = Shader.PropertyToID("_ThicknessScaleAndBias"); internal static readonly int _ScreenSpaceReflectionFinalTexture = Shader.PropertyToID(k_ScreenSpaceReflectionTextureName); - internal static readonly int _ProjectionParams2 = Shader.PropertyToID("_ProjectionParams2"); internal static readonly int _CameraProjections = Shader.PropertyToID("_CameraProjections"); internal static readonly int _CameraInverseProjections = Shader.PropertyToID("_CameraInverseProjections"); internal static readonly int _CameraInverseViewProjections = Shader.PropertyToID("_CameraInverseViewProjections"); @@ -207,9 +207,11 @@ private class ScreenSpaceReflectionPassData internal int hitRefinementSteps; internal int maxRaySteps; internal int resolutionScale; + internal float roughnessScale; internal bool reflectSky; internal bool afterOpaque; internal bool linearMarching; + internal bool useGaussianBlur; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) @@ -264,6 +266,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.cameraData = cameraData; passData.afterOpaque = m_AfterOpaque; passData.linearMarching = settings.ShouldUseLinearMarching(); + passData.useGaussianBlur = settings.ShouldUseGaussianBlurRoughness(); passData.minimumSmoothness = settings.minimumSmoothness.value; passData.smoothnessFadeStart = settings.smoothnessFadeStart.value; passData.normalFade = settings.normalFade.value; @@ -274,6 +277,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.rayLengthFade = settings.rayLengthFade.value; passData.maxRaySteps = settings.maxRaySteps.value; passData.resolutionScale = (int)settings.resolution.value; + passData.roughnessScale = settings.roughnessScale.value; passData.material = m_Material; passData.localKeywords = m_LocalKeywords; passData.mipsInfo = m_PackedMipChainInfo; @@ -373,8 +377,34 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer if (!ssrData.afterOpaque) { // We only want URP shaders to sample SSR if After Opaque is disabled... - cmd.SetGlobalVector(ShaderConstants._ReflectionParam, new Vector4(1f, ssrData.minimumSmoothness, ssrData.smoothnessFadeStart, 0f)); + cmd.SetGlobalVector(ShaderConstants._ReflectionParam, new Vector4(1f, ssrData.minimumSmoothness, ssrData.smoothnessFadeStart, 0)); } + + // This handles asymetric projections as well as orthographic ones. We only take into account the first eye as both eyes have the same "width", even + // if the projection is "flipped" + Vector3 right = ssrData.cameraInverseProjections[0].MultiplyPoint(new Vector3(1, 0, 0)); + Vector3 left = ssrData.cameraInverseProjections[0].MultiplyPoint(new Vector3(-1, 0, 0)); + + Vector4 ssrTextureSourceSize = PostProcessUtils.CalcShaderSourceSize(ssrData.ssrTexture); + float ssrTextureLastMipIndex = Mathf.Log(ssrTextureSourceSize.x) / Mathf.Log(2); + float ssrTextureLastValidMipIndex = ssrTextureLastMipIndex; + // With gaussian blurring, we do not compute mips that are under k_MinimumResolutionGaussian pixels wide. + // See MipGenerator.RenderColorGaussianPyramid + if (ssrData.useGaussianBlur) + { + float mipOffset = Mathf.Log((float)MipGenerator.k_MinimumResolutionGaussian) / Mathf.Log(2); + ssrTextureLastValidMipIndex = Mathf.Max(0, ssrTextureLastValidMipIndex - mipOffset); + } + + const float k_SSRBlurReferenceLastMipIndex = 10.0f; + float ssrTextureMipOffset = ssrTextureLastMipIndex - k_SSRBlurReferenceLastMipIndex; + + // Multiply by the ratio between a reference screen width and the actual width so we are independent of field of view. + const float k_SSRBlurReferenceScreenHalfWidth = 1.0f; + const float k_BlurrinessBase = 100f; + float screenHalfWidthAtOne = 0.5f * Math.Abs(left.x / left.z - right.x / right.z); + float blurriness = k_BlurrinessBase * Mathf.Pow(2f, ssrData.roughnessScale) * k_SSRBlurReferenceScreenHalfWidth / Math.Max(0.01f, screenHalfWidthAtOne); + cmd.SetGlobalVector(ShaderConstants._ReflectionParam2, new Vector4(blurriness, ssrTextureMipOffset, ssrTextureLastValidMipIndex, 0)); }); } @@ -468,7 +498,6 @@ static void SetupKeywordsAndParameters(ref ScreenSpaceReflectionPassData data) data.cameraInverseViewProjections[eyeIndex] = data.cameraViewProjections[eyeIndex].inverse; } - data.material.SetVector(ShaderConstants._ProjectionParams2, new Vector4(1.0f / cameraData.camera.nearClipPlane, 0.0f, 0.0f, 0.0f)); data.material.SetMatrixArray(ShaderConstants._CameraProjections, data.cameraProjections); data.material.SetMatrixArray(ShaderConstants._CameraInverseProjections, data.cameraInverseProjections); data.material.SetMatrixArray(ShaderConstants._CameraViews, data.cameraViews); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs index 5f978723706..4a50c071153 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs @@ -79,6 +79,10 @@ public enum ReflectionMode [Tooltip("Whether to enable rough reflections by blurring the reflected color. Disabling will improve performance, but all reflections will be mirror-like.")] public EnumParameter roughReflections = new(RoughReflectionsQuality.GaussianBlur); + /// Controls how blurry rough reflections appear on a logarithmic scale. A value of 0 is neutral, negative values reduce blurriness, positive values increase it. + [Tooltip("Controls how blurry rough reflections appear on a logarithmic scale. A value of 0 is neutral, negative values reduce blurriness, positive values increase it.")] + public ClampedFloatParameter roughnessScale = new(0.0f, -2.0f, 2.0f); + /// The minimum amount of surface smoothness at which Screen Space Reflections are used. [Tooltip("The minimum amount of surface smoothness at which Screen Space Reflections are used. Higher values will result in less objects receiving Screen Space Reflections.")] public ClampedFloatParameter minimumSmoothness = new(0.05f, 0.0f, 1.0f); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl index 36720009b76..0cd7be78ab0 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl @@ -2,7 +2,7 @@ #define UNIVERSAL_SSR_INCLUDED // Includes -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl" @@ -467,11 +467,16 @@ float4 CompositeSSRAfterOpaque(Varyings input) : SV_Target float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord); + // Reconstruct world position + float2 positionNDC = uv; + float deviceDepth = SampleSceneDepth(uv).r; + float3 positionWS = ComputeWorldSpacePosition(positionNDC, deviceDepth, _CameraInverseViewProjections[unity_eyeIndex]); + float perceptualSmoothness = SAMPLE_TEXTURE2D_X(_SmoothnessTexture, sampler_SmoothnessTexture, uv).a; + float perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(perceptualSmoothness); // Map roughness to mip level to get blur. - float perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(perceptualSmoothness); - float mipLevel = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + float mipLevel = GetSSRMipLevelFromPerceptualRoughness(positionWS, perceptualRoughness); float4 reflColor = SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_TrilinearClamp, uv, mipLevel); // Fade out reflections with smoothness. diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl index ddfa4d612b3..ad869797ca6 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl @@ -426,7 +426,7 @@ half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half p #if defined(_SCREENSPACEREFLECTIONS_OFF) half4 ssrColor = 0; #else - half4 ssrColor = GetScreenSpaceReflection(normalizedScreenSpaceUV, perceptualRoughness); + half4 ssrColor = GetScreenSpaceReflection(normalizedScreenSpaceUV, positionWS, perceptualRoughness); #endif // We skip sampling reflection probes if they would be overwritten by SSR anyways. diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl index 6c79c35a090..9bca18735a3 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl @@ -128,7 +128,7 @@ half4 _AmbientOcclusionParam; // x: SSR Enabled/Disabled (Needed for situations when OFF keyword is stripped out but feature disabled in runtime) // y: Minimum smoothness, used as a mask for SSR. // z: Smoothness fade start. -// w is currently unused +// w: is currently unused half4 _ScreenSpaceReflectionParam; half4 _AdditionalLightsCount; diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl index 13f6953346f..2e4c33a0399 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl @@ -1,17 +1,17 @@ #ifndef SAMPLE_SCREEN_SPACE_REFLECTION_INCLUDED #define SAMPLE_SCREEN_SPACE_REFLECTION_INCLUDED -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl" // SSR reflection color TEXTURE2D_X(_ScreenSpaceReflectionTexture); -half4 SampleScreenSpaceReflection(float2 normalizedScreenSpaceUV, float perceptualRoughness) +half4 SampleScreenSpaceReflection(float2 normalizedScreenSpaceUV, float3 positionWS, float perceptualRoughness) { float2 uv = UnityStereoTransformScreenSpaceTex(normalizedScreenSpaceUV); // Map roughness to mip level to get blur. - float mipLevel = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + float mipLevel = GetSSRMipLevelFromPerceptualRoughness(positionWS, perceptualRoughness); float4 reflColor = SAMPLE_TEXTURE2D_X_LOD(_ScreenSpaceReflectionTexture, sampler_TrilinearClamp, uv, mipLevel); // Fade out reflections for pixels that have smoothness below our minimum. @@ -24,11 +24,11 @@ half4 SampleScreenSpaceReflection(float2 normalizedScreenSpaceUV, float perceptu return reflColor; } -half4 GetScreenSpaceReflection(float2 normalizedScreenSpaceUV, float perceptualRoughness) +half4 GetScreenSpaceReflection(float2 normalizedScreenSpaceUV, float3 positionWS, float perceptualRoughness) { #if _SCREEN_SPACE_REFLECTION_KEYWORD_DECLARED if (_SCREEN_SPACE_REFLECTION) - return SampleScreenSpaceReflection(normalizedScreenSpaceUV, perceptualRoughness) * _ScreenSpaceReflectionParam.x; + return SampleScreenSpaceReflection(normalizedScreenSpaceUV, positionWS, perceptualRoughness) * _ScreenSpaceReflectionParam.x; else #endif return 0; diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl new file mode 100644 index 00000000000..b9aac3a3216 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl @@ -0,0 +1,78 @@ +#ifndef SCREEN_SPACE_REFLECTION_COMMON_INCLUDED +#define SCREEN_SPACE_REFLECTION_COMMON_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + +//#define SSR_USE_DISTANCE_BASED_BLUR + +static const float k_SSRBlurReferenceDistance = 1.0; + +// x : Blurriness - Exposed as a volume parameter; see ScreenSpaceReflectionVolumeSettings.blurriness. +// y : Delta between the screen Space Reflection texture last mip index and a reference last mip index. +// z : Screen Space Reflection texture last valid mip index +// w : Unused +float4 _ScreenSpaceReflectionParam2; + +float GetSSRBlurriness() +{ + return _ScreenSpaceReflectionParam2.x; +} + +float GetSSRTextureMipOffset() +{ + return _ScreenSpaceReflectionParam2.y; +} + +float GetSSRTextureLastValidMipIndex() +{ + return _ScreenSpaceReflectionParam2.z; +} + +float GetSSRBlurConeHalfAngle(float perceptualRoughness) +{ + float roughness = PerceptualRoughnessToRoughness(perceptualRoughness); + float roughnessSquared = roughness * roughness; + + // Inspired by http://pascal.lecocq.home.free.fr/publications/lecocq_i3D2016_specularAreaLighting.pdf + float k = (1.0 - roughnessSquared) / (2.0 - roughnessSquared); + return (PI / 3.0) * sqrt(1 - 4.0 * k * k); +} + +float GetSSRMipLevelFromPerceptualRoughness(float3 positionWS, float perceptualRoughness) +{ + // Map perceptual roughness to a blur cone radius + float blurConeAngle = GetSSRBlurConeHalfAngle(perceptualRoughness); + float blurRadius = GetSSRBlurriness() * tan(blurConeAngle); + + #ifdef SSR_USE_DISTANCE_BASED_BLUR + // Adjust based on camera distance + if (IsPerspectiveProjection()) + { + float fragZ = TransformWorldToView(positionWS).z; + // Assume we have the blur radius at a distance BLUR_REFERENCE_DISTANCE to the camera and divide this radius + // by 2 if the ratio between that reference distance and the fragment Z doubles. + const float k_MinimumZ = 0.01; + float scalingRatio = k_SSRBlurReferenceDistance / max(k_MinimumZ, abs(fragZ)); + blurRadius *= scalingRatio; + } + else + { + // TODO : handle orthographic projection. see https://jira.unity3d.com/browse/GFXLIGHT-1849 + } + #endif + + // Map this blur radius back to a mip level, but assuming the reference resolution. + const float k_MinimumRadius = 0.001; + float mipLevel = log2(max(k_MinimumRadius, blurRadius)); + + // Adjust for resolution: shift that mip by the difference between the actual SSR mip count and the reference one, + // so the same material roughness produces approximately the same screen-space blur in pixels regardless of + // reflection buffer resolution. The minimum-radius clamp keeps roughness 0 at mip 0 up to resolutions of + // k_SSRBlurReferenceResolution * 2^-log2(k_MinimumRadius) ~= 1024 * 1024 = 1M pixels wide. The subtraction below + // keeps roughness 1 at the highest mip level. + mipLevel += GetSSRTextureMipOffset(); + return clamp(mipLevel, 0, GetSSRTextureLastValidMipIndex()); +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl.meta new file mode 100644 index 00000000000..88b5c20f03d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d39ce33cadd344129a28bf89a1b8e4e4 +timeCreated: 1773851159 \ No newline at end of file From 5d0bae830137be1995d1dfb23894769088c248f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim-H=C3=A9l=C3=A8ne=20Bouvier-Zappa?= Date: Tue, 31 Mar 2026 00:57:48 +0000 Subject: [PATCH 08/88] Reenabled cinemachine tests. --- .../Projects/UniversalGraphicsTest_2D/Packages/manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json index 842507c869a..32bf3156f5f 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json @@ -4,6 +4,7 @@ "dependencies": { "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", + "com.unity.cinemachine": "2.10.7", "com.unity.ext.nunit": "1.0.0", "com.unity.feature.2d": "file:../../../../../Packages/com.unity.feature.2d", "com.unity.ide.rider": "3.0.38", From d3b4d9c1101a2aab7c47871e3ea6ef360cb042ad Mon Sep 17 00:00:00 2001 From: Esmeralda Salamone Date: Tue, 31 Mar 2026 07:31:35 +0000 Subject: [PATCH 09/88] [SGVFX][AI] Set Internals Visible from SGVFX to AI --- .../Editor/AssemblyInfo.cs | 1 + .../com.unity.render-pipelines.universal/Editor/AssemblyInfo.cs | 1 + Packages/com.unity.shadergraph/Editor/AssemblyInfo.cs | 1 + Packages/com.unity.visualeffectgraph/Editor/PackageInfo.cs | 1 + 4 files changed, 4 insertions(+) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/AssemblyInfo.cs index cf804066a3d..a8ff701b1c3 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/AssemblyInfo.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/AssemblyInfo.cs @@ -5,3 +5,4 @@ [assembly: InternalsVisibleTo("Unity.Industrial.Materials.AVRD.Editor")] [assembly: InternalsVisibleTo("Unity.TextMeshPro.Editor")] [assembly: InternalsVisibleTo("Unity.GI.ReflectionProbes.Test")] +[assembly: InternalsVisibleTo("Unity.AI.Assistant.Bridge.Editor")] diff --git a/Packages/com.unity.render-pipelines.universal/Editor/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.universal/Editor/AssemblyInfo.cs index ac7dfdecd5a..11927ba098d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/AssemblyInfo.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/AssemblyInfo.cs @@ -6,3 +6,4 @@ [assembly: InternalsVisibleTo("Unity.Testing.SRP.Universal-Upgrade.Editor")] [assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.Universal.Editor")] [assembly: InternalsVisibleTo("Unity.VisualEffectGraph.EditorTests")] +[assembly: InternalsVisibleTo("Unity.AI.Assistant.Bridge.Editor")] \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/AssemblyInfo.cs b/Packages/com.unity.shadergraph/Editor/AssemblyInfo.cs index 47d964ad47b..ab3ab17f1c1 100644 --- a/Packages/com.unity.shadergraph/Editor/AssemblyInfo.cs +++ b/Packages/com.unity.shadergraph/Editor/AssemblyInfo.cs @@ -12,3 +12,4 @@ [assembly: InternalsVisibleTo("Unity.ShaderGraphTool.Editor")] [assembly: InternalsVisibleTo("Unity.ShaderFoundry.Editor")] [assembly: InternalsVisibleTo("Unity.Environment.Editor.ShaderGraph")] +[assembly: InternalsVisibleTo("Unity.AI.Assistant.Bridge.Editor")] \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/PackageInfo.cs b/Packages/com.unity.visualeffectgraph/Editor/PackageInfo.cs index 87cee046aca..6641060138a 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/PackageInfo.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/PackageInfo.cs @@ -19,6 +19,7 @@ [assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor")] [assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor-testable")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] +[assembly: InternalsVisibleTo("Unity.AI.Assistant.Bridge.Editor")] namespace UnityEditor.VFX { From 01676107b9a2cb130e573cfb83f0168392880ae4 Mon Sep 17 00:00:00 2001 From: Yvain Raeymaekers Date: Tue, 31 Mar 2026 12:31:14 +0000 Subject: [PATCH 10/88] Migrate UnifiedRayTracing Tests from Editor to Player tests --- .../Editor/UnifiedRayTracing/APITests.cs | 62 -- .../Editor/UnifiedRayTracing/APITests.cs.meta | 2 - .../AccelStructAdapterTests.cs | 263 ------- .../AccelStructAdapterTests.cs.meta | 2 - .../UnifiedRayTracing/AccelStructTests.cs | 680 ------------------ .../AccelStructTests.cs.meta | 11 - .../UnifiedRayTracing/InvalidInputsTests.cs | 175 ----- .../InvalidInputsTests.cs.meta | 2 - .../UnifiedRayTracing/TraceRays.urtshader | 39 - .../TraceRays.urtshader.meta | 7 - .../TraceRaysAndFetchAttributes.urtshader | 49 -- ...TraceRaysAndFetchAttributes.urtshader.meta | 10 - .../TraceTransparentRays.urtshader | 67 -- .../TraceTransparentRays.urtshader.meta | 2 - 14 files changed, 1371 deletions(-) delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader delete mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs deleted file mode 100644 index 8b56cef9e54..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs +++ /dev/null @@ -1,62 +0,0 @@ -using NUnit.Framework; -using System; -using UnityEditor; -using System.Runtime.InteropServices; -using Unity.Mathematics; -using Unity.Collections.LowLevel.Unsafe; - -namespace UnityEngine.Rendering.UnifiedRayTracing.Tests -{ - [TestFixture("Compute")] - [TestFixture("Hardware")] - internal class IRayTracingBackendTests - { - readonly RayTracingBackend m_BackendType; - RayTracingResources m_Resources; - IRayTracingBackend m_Backend; - - public IRayTracingBackendTests(string backendAsString) - { - m_BackendType = Enum.Parse(backendAsString); - } - - [SetUp] - public void SetUp() - { - if (!SystemInfo.supportsRayTracing && m_BackendType == RayTracingBackend.Hardware) - { - Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); - } - - if (!SystemInfo.supportsComputeShaders && m_BackendType == RayTracingBackend.Compute) - { - Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); - } - - m_Resources = new RayTracingResources(); - m_Resources.Load(); - - if (m_BackendType == RayTracingBackend.Hardware) - m_Backend = new HardwareRayTracingBackend(m_Resources); - else if (m_BackendType == RayTracingBackend.Compute) - m_Backend = new ComputeRayTracingBackend(m_Resources); - else - Assert.Fail("Invalid backend type"); - } - - [Test] - public void IRayTracingBackend_QueryScratchBufferStride_ShouldGenerateCorrectResult() - { - Assert.AreEqual(4, RayTracingContext.GetScratchBufferStrideInBytes()); - } - - [Test] - public void IRayTracingBackend_QueryScratchBufferSize_ShouldGenerateCorrectResult() - { - if (m_BackendType == RayTracingBackend.Hardware) - Assert.AreEqual(0, m_Backend.GetRequiredTraceScratchBufferSizeInBytes(1, 2, 3)); - else if (m_BackendType == RayTracingBackend.Compute) - Assert.AreEqual(1536, m_Backend.GetRequiredTraceScratchBufferSizeInBytes(1, 2, 3)); - } - } -} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta deleted file mode 100644 index fcb17d986f7..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 1cee6a301a2297f4aa8e064f8504abc8 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs deleted file mode 100644 index d14290492a2..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs +++ /dev/null @@ -1,263 +0,0 @@ -using NUnit.Framework; -using System; -using UnityEditor; -using System.Runtime.InteropServices; -using Unity.Mathematics; -using Unity.Collections.LowLevel.Unsafe; - -namespace UnityEngine.Rendering.UnifiedRayTracing.Tests -{ - - [TestFixture("Compute")] - [TestFixture("Hardware")] - internal class AccelStructAdapterTests - { - readonly RayTracingBackend m_Backend; - RayTracingContext m_Context; - AccelStructAdapter m_AccelStruct; - IRayTracingShader m_Shader; - - public AccelStructAdapterTests(string backendAsString) - { - m_Backend = Enum.Parse(backendAsString); - } - - [SetUp] - public void SetUp() - { - if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware) - { - Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); - } - - if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute) - { - Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); - } - - if (SystemInfo.graphicsDeviceName.Contains("llvmpipe")) - { - Assert.Ignore("Cannot run test on this device (Renderer: llvmpipe (LLVM 10.0.0, 128 bits)). Tests are disabled because they fail on some platforms (that do not support 11 SSBOs). Once we do not run Ubuntu 18.04 try removing this"); - } - - CreateRayTracingResources(); - } - - [TearDown] - public void TearDown() - { - DisposeRayTracingResources(); - } - - void RayTraceAndCheckUVs(Mesh mesh, float2 expected, int uvChannel, float tolerance = 0.01f) - { - const int instanceCount = 4; - CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); - - for (ulong i = 0; i < instanceCount; ++i) - { - m_AccelStruct.AddInstance(i, instanceDescs[i].mesh, instanceDescs[i].localToWorldMatrix, new uint[]{ 0xFFFFFFFF }, new uint[]{ 0xFFFFFFFF }, new bool[] { true }, 1); - } - - HitGeomAttributes[] hitAttributes = null; - var hits = TraceRays(rays, out hitAttributes); - for (int i = 0; i < rays.Length; ++i) - { - Assert.IsTrue(hits[i].Valid(), "Expected ray to hit the mesh."); - float2 uv = uvChannel == 1 ? hitAttributes[i].uv1 : hitAttributes[i].uv0; - Assert.AreEqual(expected.x, uv.x, tolerance, $"Expected x (from uv{uvChannel}) to be fetched correctly in the ray tracing shader."); - Assert.AreEqual(expected.y, uv.y, tolerance, $"Expected y (from uv{uvChannel}) to be fetched correctly in the ray tracing shader."); - } - } - - [Test] - [TestCase(0)] - [TestCase(1)] - public void GeometryPool_MeshWithTwoWideUVs_UVsAreFetchedCorrectly(int uvChannel) - { - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - float x = 100.2f; - float y = -9.3f; - var uvs = new Vector2[] { new Vector2(x, y), new Vector2(x, y), new Vector2(x, y) }; - // Here we use the Vector2 version for setting the UVs on the mesh - mesh.SetUVs(uvChannel, uvs); - RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel); - } - - [Test] - [TestCase(0)] - [TestCase(1)] - public void GeometryPool_MeshWithThreeWideUVs_UVsAreFetchedCorrectly(int uvChannel) - { - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - float x = 100.2f; - float y = -9.3f; - float z = 32.4f; - var uvs = new Vector3[] { new Vector3(x, y, z), new Vector3(x, y, z), new Vector3(x, y, z) }; - // Here we use the Vector3 version for setting the UVs on the mesh - mesh.SetUVs(uvChannel, uvs); - RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel); - } - - [Test] - [TestCase(0)] - [TestCase(1)] - public void GeometryPool_MeshWithFourWideUVs_UVsAreFetchedCorrectly(int uvChannel) - { - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - float x = 100.2f; - float y = -9.3f; - float z = 32.4f; - float w = -12.5f; - var uvs = new Vector4[] { new Vector4(x, y, z, w), new Vector4(x, y, z, w), new Vector4(x, y, z, w) }; - // Here we use the Vector4 version for setting the UVs on the mesh - mesh.SetUVs(uvChannel, uvs); - RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel); - } - - [Test] - [TestCase(0)] - [TestCase(1)] - public void GeometryPool_MeshWithLargeUVValues_UVsAreFetchedCorrectly(int uvChannel) - { - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - float x = 100000.2f; - float y = -900000.3f; - float z = 32000.4f; - float w = -1200000.5f; - var uvs = new Vector4[] { new Vector4(x, y, z, w), new Vector4(x, y, z, w), new Vector4(x, y, z, w) }; - // Here we use the Vector4 version for setting the UVs on the mesh - mesh.SetUVs(uvChannel, uvs); - RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel, 0.2f); - } - - [Test] - [TestCase(0)] - [TestCase(1)] - public void GeometryPool_MeshWithDifferentVertexUVs_UVsAreInterpolatedCorrectly(int uvChannel) - { - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - float x = 1.0f; - float y = 5.0f; - float z = 7.0f; - var uvs = new Vector4[] { new Vector4(x, x, x, x), new Vector4(y, y, y, y), new Vector4(z, z, z, z) }; - // Here we use the Vector4 version for setting the UVs on the mesh - mesh.SetUVs(uvChannel, uvs); - RayTraceAndCheckUVs(mesh, new float2(4.333f, 4.333f), uvChannel, 0.001f); - } - - void CreateMatchingRaysAndInstanceDescs(uint instanceCount, Mesh mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs) - { - instanceDescs = new MeshInstanceDesc[instanceCount]; - rays = new RayWithFlags[instanceCount]; - var ray = new RayWithFlags(new float3(0.0f, 0.0f, 1.0f), new float3(0.0f, 0.0f, -1.0f)); - float3 step = new float3(2.0f, 0.0f, 0.0f); - - for (int i = 0; i < instanceCount; ++i) - { - instanceDescs[i] = new MeshInstanceDesc(mesh); - instanceDescs[i].localToWorldMatrix = float4x4.Translate(step * i); - - rays[i] = ray; - rays[i].origin += step * i; - } - } - - Hit[] TraceRays(RayWithFlags[] rays, out HitGeomAttributes[] hitAttributes) - { - var bufferTarget = GraphicsBuffer.Target.Structured; - var rayCount = rays.Length; - using var raysBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); - raysBuffer.SetData(rays); - using var hitsBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); - using var attributesBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); - - var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuildAndDispatch(m_AccelStruct.GetAccelerationStructure(), m_Shader, (uint)rayCount, 1, 1); - - var cmd = new CommandBuffer(); - m_AccelStruct.Build(cmd, ref scratchBuffer); - m_AccelStruct.Bind(cmd, "_AccelStruct", m_Shader); - m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Rays"), raysBuffer); - m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Hits"), hitsBuffer); - m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_HitAttributes"), attributesBuffer); - m_Shader.Dispatch(cmd, scratchBuffer, (uint)rayCount, 1, 1); - Graphics.ExecuteCommandBuffer(cmd); - - var hits = new Hit[rayCount]; - hitsBuffer.GetData(hits); - - hitAttributes = new HitGeomAttributes[rayCount]; - attributesBuffer.GetData(hitAttributes); - - scratchBuffer?.Dispose(); - - return hits; - } - - void CreateRayTracingResources() - { - var resources = new RayTracingResources(); - resources.Load(); - - m_Context = new RayTracingContext(m_Backend, resources); - m_AccelStruct = new AccelStructAdapter(m_Context.CreateAccelerationStructure(new AccelerationStructureOptions()), resources); - m_Shader = m_Context.LoadRayTracingShader("Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader"); - } - - void DisposeRayTracingResources() - { - m_AccelStruct?.Dispose(); - m_Context?.Dispose(); - } - - [StructLayout(LayoutKind.Sequential)] - public struct RayWithFlags - { - public float3 origin; - public float minT; - public float3 direction; - public float maxT; - public uint culling; - public uint instanceMask; - uint padding; - uint padding2; - - public RayWithFlags(float3 origin, float3 direction) - { - this.origin = origin; - this.direction = direction; - minT = 0.0f; - maxT = float.MaxValue; - instanceMask = 0xFFFFFFFF; - culling = 0; - padding = 0; - padding2 = 0; - } - } - - [System.Flags] - enum RayCulling { None = 0, CullFrontFace = 0x10, CullBackFace = 0x20 } - - [StructLayout(LayoutKind.Sequential)] - public struct Hit - { - public uint instanceID; - public uint primitiveIndex; - public float2 uvBarycentrics; - public float hitDistance; - public uint isFrontFace; - - public bool Valid() { return instanceID != 0xFFFFFFFF; } - } - - [StructLayout(LayoutKind.Sequential)] - public struct HitGeomAttributes - { - public float3 position; - public float3 normal; - public float3 faceNormal; - public float2 uv0; - public float2 uv1; - } - } -} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta deleted file mode 100644 index 23d0990967c..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 355495db5b95855439b77dcb5868f8f7 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs deleted file mode 100644 index 2b29ba78912..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs +++ /dev/null @@ -1,680 +0,0 @@ -using NUnit.Framework; -using System; -using UnityEditor; -using System.Runtime.InteropServices; -using Unity.Mathematics; -using Unity.Collections.LowLevel.Unsafe; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.TestTools; -using UnityEngine.Rendering.RadeonRays; - -namespace UnityEngine.Rendering.UnifiedRayTracing.Tests -{ - internal static class MeshUtil - { - static internal Mesh CreateSingleTriangleMesh(float2 scaling, float3 translation) - { - Mesh mesh = new Mesh(); - - Vector3[] vertices = new Vector3[] - { - (Vector3)translation + new Vector3(0.0f, 0.0f, 0), - (Vector3)translation + new Vector3(1.0f * scaling.x, 0.0f, 0), - (Vector3)translation + new Vector3(0.0f, 1.0f * scaling.y, 0) - }; - mesh.vertices = vertices; - - Vector3[] normals = new Vector3[] - { - -Vector3.forward, - -Vector3.forward, - -Vector3.forward - }; - mesh.normals = normals; - - Vector2[] uv = new Vector2[] - { - new Vector2(0, 1), - new Vector2(1, 1), - new Vector2(0, 0) - }; - mesh.uv = uv; - - int[] tris = new int[3] - { - 0, 2, 1 - }; - mesh.triangles = tris; - - return mesh; - } - - static internal Mesh CreateQuadMesh() - { - Mesh mesh = new Mesh(); - - Vector3[] vertices = new Vector3[] - { - new Vector3(-0.5f, -0.5f, 0.0f), - new Vector3(0.5f, -0.5f, 0.0f), - new Vector3(-0.5f, 0.5f, 0.0f), - new Vector3(0.5f, 0.5f, 0.0f) - }; - mesh.vertices = vertices; - - Vector3[] normals = new Vector3[] - { - -Vector3.forward, - -Vector3.forward, - -Vector3.forward, - -Vector3.forward - }; - mesh.normals = normals; - - Vector2[] uv = new Vector2[] - { - new Vector2(0, 0), - new Vector2(1, 0), - new Vector2(0, 1), - new Vector2(1, 1) - }; - mesh.uv = uv; - - int[] tris = new int[6] - { - 0, 2, 1, - 2, 3, 1 - }; - mesh.triangles = tris; - - return mesh; - } - } - - internal class ComputeRayTracingAccelStructTests - { - static private void AssertFloat3sAreEqual(float3 expected, float3 actual, float tolerance) - { - Assert.AreEqual(expected.x, actual.x, tolerance); - Assert.AreEqual(expected.y, actual.y, tolerance); - Assert.AreEqual(expected.z, actual.z, tolerance); - } - - static private void AssertAABBsAreEqual(float3 expectedMin, float3 expectedMax, float3 actualMin, float3 actualMax, float tolerance) - { - AssertFloat3sAreEqual(expectedMin, actualMin, tolerance); - AssertFloat3sAreEqual(expectedMax, actualMax, tolerance); - } - - [Test] - public void Build_TwoInstancesOfASingleTriangleMesh_ShouldGenerateCorrectResult() - { - var resources = new RayTracingResources(); - resources.Load(); - - using var accelStruct = new ComputeRayTracingAccelStruct( - new AccelerationStructureOptions() { buildFlags = BuildFlags.PreferFastBuild }, - resources, - new ReferenceCounter()); - - uint instanceCount = 2; - - { - var mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.0f, 1.0f), float3.zero); - var globalTranslation = new float3(1.0f, 1.0f, 0.0f); - for (uint i = 0; i < instanceCount; i++) - { - var instanceDesc = new MeshInstanceDesc(mesh); - instanceDesc.localToWorldMatrix = Matrix4x4.Translate(globalTranslation + new float3(2.0f * i, 0.0f, 0.0f)); - accelStruct.AddInstance(instanceDesc); - } - - using var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuild(accelStruct); - using var cmd = new CommandBuffer(); - accelStruct.Build(cmd, scratchBuffer); - Graphics.ExecuteCommandBuffer(cmd); - Object.DestroyImmediate(mesh); - } - - var tolerance = 0.001f; - { - // Verify bottom level BVH. - uint expectedTotalNodeCount = 1; - var bottomLevelNodes = new BvhNode[(int)expectedTotalNodeCount + 1]; // plus one for header - accelStruct.bottomLevelBvhBuffer.GetData(bottomLevelNodes); - - var header = UnsafeUtility.As(ref bottomLevelNodes[0]); - Assert.AreEqual(expectedTotalNodeCount, header.internalNodeCount + header.leafNodeCount); - Assert.AreEqual(1, header.leafNodeCount); - Assert.AreEqual(expectedTotalNodeCount, header.internalNodeCount + header.leafNodeCount); - AssertAABBsAreEqual(new float3(0.0f, 0.0f, 0.0f), new float3(1.0f, 1.0f, 0.0f), header.globalAabbMin, header.globalAabbMax, tolerance); - } - - { - // Verify top level BVH. - uint expectedInternalNodeCount = instanceCount - 1; - uint expectedLeafNodeCount = instanceCount; - var topLevelNodes = new BvhNode[(int)expectedInternalNodeCount + 1]; // plus one for header - accelStruct.topLevelBvhBuffer.GetData(topLevelNodes); - - var header = UnsafeUtility.As(ref topLevelNodes[0]); - Assert.AreEqual(expectedInternalNodeCount, header.internalNodeCount); - Assert.AreEqual(expectedLeafNodeCount, header.leafNodeCount); - - AssertAABBsAreEqual(new float3(1.0f, 1.0f, 0.0f), new float3(4.0f, 2.0f, 0.0f), header.globalAabbMin, header.globalAabbMax, tolerance); - - var instanceBvhRoot = topLevelNodes[1]; - Assert.AreEqual(0u | (1u << 31), instanceBvhRoot.child0); // MSB is set for leaf node indices - Assert.AreEqual(1u | (1u << 31), instanceBvhRoot.child1); - AssertAABBsAreEqual(new float3(1.0f, 1.0f, 0.0f), new float3(2.0f, 2.0f, 0.0f), instanceBvhRoot.aabb0_min, instanceBvhRoot.aabb0_max, tolerance); - AssertAABBsAreEqual(new float3(3.0f, 1.0f, 0.0f), new float3(4.0f, 2.0f, 0.0f), instanceBvhRoot.aabb1_min, instanceBvhRoot.aabb1_max, tolerance); - } - } - } - - - internal class AccelStructTestsBase - { - readonly protected RayTracingBackend m_Backend; - protected RayTracingContext m_Context; - protected RayTracingResources m_Resources; - protected IRayTracingAccelStruct m_AccelStruct; - protected IRayTracingShader m_Shader; - - public AccelStructTestsBase(string backendAsString) - { - m_Backend = Enum.Parse(backendAsString); - } - - protected void CreateRayTracingResources(string shaderFilename) - { - if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware) - { - Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); - } - - if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute) - { - Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); - } - - if (SystemInfo.graphicsDeviceName.Contains("llvmpipe")) - { - Assert.Ignore("Cannot run test on this device (Renderer: llvmpipe (LLVM 10.0.0, 128 bits)). Tests are disabled because they fail on some platforms (that do not support 11 SSBOs). Once we do not run Ubuntu 18.04 try removing this"); - } - - m_Resources = new RayTracingResources(); - m_Resources.Load(); - - m_Context = new RayTracingContext(m_Backend, m_Resources); - m_AccelStruct = m_Context.CreateAccelerationStructure(new AccelerationStructureOptions()); - m_Shader = m_Context.LoadRayTracingShader("Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/" + shaderFilename); - } - - protected void DisposeRayTracingResources() - { - m_AccelStruct?.Dispose(); - m_Context?.Dispose(); - } - - protected THit[] TraceRays(RayWithFlags[] rays, AnyHitDecision anyHitDecision = AnyHitDecision.Invalid) - { - var bufferTarget = GraphicsBuffer.Target.Structured; - var rayCount = rays.Length; - using var raysBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); - raysBuffer.SetData(rays); - using var hitsBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); - - using var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuildAndDispatch(m_AccelStruct, m_Shader, (uint)rayCount, 1, 1); - - var cmd = new CommandBuffer(); - m_AccelStruct.Build(cmd, scratchBuffer); - - if (anyHitDecision != AnyHitDecision.Invalid) - m_Shader.SetIntParam(cmd, Shader.PropertyToID("_AnyHitDecision"), (int)anyHitDecision); - - m_Shader.SetAccelerationStructure(cmd, "_AccelStruct", m_AccelStruct); - m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Rays"), raysBuffer); - m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Hits"), hitsBuffer); - m_Shader.Dispatch(cmd, scratchBuffer, (uint)rayCount, 1, 1); - Graphics.ExecuteCommandBuffer(cmd); - - var hits = new THit[rayCount]; - hitsBuffer.GetData(hits); - - return hits; - } - - [StructLayout(LayoutKind.Sequential)] - public struct RayWithFlags - { - public float3 origin; - public float minT; - public float3 direction; - public float maxT; - public uint culling; - public uint instanceMask; - uint padding; - uint padding2; - - public RayWithFlags(float3 origin, float3 direction) - { - this.origin = origin; - this.direction = direction; - minT = 0.0f; - maxT = float.MaxValue; - instanceMask = 0xFFFFFFFF; - culling = 0; - padding = 0; - padding2 = 0; - } - } - - protected enum AnyHitDecision { Invalid = -1, IgnoreHit = 0, AcceptHit = 1, AcceptHitAndEndSearch = 2 }; - - [System.Flags] - protected enum RayFlags { None = 0, ForceOpaque = 0x01, ForceNonOpaque = 0x02, AcceptFirstHitAndEndSearch = 0x04, SkipClosestHit = 0x08, CullBackFace = 0x10, CullFrontFace = 0x20, CullOpaque = 0x40, CullNonOpaque = 0x80 } - } - - - [TestFixture("Compute")] - [TestFixture("Hardware")] - internal class AccelStructTests : AccelStructTestsBase - { - public AccelStructTests(string backendAsString) : base(backendAsString) - { - } - - [SetUp] - public void SetUp() - { - CreateRayTracingResources("TraceRays.urtshader"); - } - - [TearDown] - public void TearDown() - { - DisposeRayTracingResources(); - } - - [Test] - public void RayTracePixelsInUnitQuad([Values(1, 10, 100)] int rayResolution, [Values(0, 1, 2, 3)] int buildFlagsAsInteger) - { - var buildFlags = (BuildFlags)buildFlagsAsInteger; // We do this ugly but simple cast hack because the BuildFlags type is not public as time of this writing (test methods must be public and so must their argument types). - - // re-create the acceleration structure with suitable options - m_AccelStruct?.Dispose(); - var options = new AccelerationStructureOptions() { buildFlags = buildFlags }; - m_AccelStruct = m_Context.CreateAccelerationStructure(options); - - Mesh mesh = MeshUtil.CreateQuadMesh(); - - var instanceDesc = new MeshInstanceDesc(mesh); - instanceDesc.localToWorldMatrix = Matrix4x4.identity; - instanceDesc.localToWorldMatrix.SetTRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.identity, new Vector3(1.0f, 1.0f, 1.0f)); - instanceDesc.enableTriangleCulling = false; - instanceDesc.frontTriangleCounterClockwise = true; - m_AccelStruct.AddInstance(instanceDesc); - - // trace N*N rays towards the quad and expect to hit it - int N = rayResolution; - var rays = new RayWithFlags[N * N]; - int rayI = 0; - for (int v = 0; v < N; ++v) - { - for (int u = 0; u < N; ++u) - { - float2 uv = new float2((float)u, (float)v); - uv += 0.5f; - uv /= N; - float3 origin = new float3(uv.x, uv.y, 1.0f); - float3 direction = new float3(0.0f, 0.0f, -1.0f); - rays[rayI] = new RayWithFlags(origin, direction); - rays[rayI].culling = (uint)RayFlags.None; - rayI++; - } - } - - var hits = TraceRays(rays); - for (int i = 0; i < hits.Length; ++i) - { - Assert.IsTrue(hits[i].Valid(), $"Expected all rays to hit the quad but ray {i} missed."); - } - } - - [Test] - public void FrontOrBackFaceCulling() - { - const int instanceCount = 4; - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); - - var raysDuplicated = new RayWithFlags[instanceCount * 3]; - Array.Copy(rays, 0, raysDuplicated, 0, instanceCount); - Array.Copy(rays, 0, raysDuplicated, instanceCount, instanceCount); - Array.Copy(rays, 0, raysDuplicated, 2 * instanceCount, instanceCount); - - for (int i = 0; i < instanceCount; ++i) - { - raysDuplicated[i].culling = (uint)RayFlags.None; - raysDuplicated[i + instanceCount].culling = (uint)RayFlags.CullBackFace; - raysDuplicated[i + instanceCount * 2].culling = (uint)RayFlags.CullFrontFace; - } - - instanceDescs[0].enableTriangleCulling = false; - instanceDescs[0].frontTriangleCounterClockwise = true; - - instanceDescs[1].enableTriangleCulling = false; - instanceDescs[1].frontTriangleCounterClockwise = false; - - instanceDescs[2].enableTriangleCulling = true; - instanceDescs[2].frontTriangleCounterClockwise = true; - - instanceDescs[3].enableTriangleCulling = true; - instanceDescs[3].frontTriangleCounterClockwise = false; - - for (int i = 0; i < instanceCount; ++i) - { - m_AccelStruct.AddInstance(instanceDescs[i]); - } - - var hits = TraceRays(raysDuplicated); - // No culling - Assert.IsTrue(hits[0].Valid()); - Assert.IsTrue(hits[1].Valid()); - Assert.IsTrue(hits[2].Valid()); - Assert.IsTrue(hits[3].Valid()); - - // FrontFace culling - Assert.IsTrue(hits[4].Valid()); - Assert.IsTrue(hits[5].Valid()); - Assert.IsTrue(hits[6].Valid()); - Assert.IsTrue(!hits[7].Valid()); - - // BackFace culling - Assert.IsTrue(hits[8].Valid()); - Assert.IsTrue(hits[9].Valid()); - Assert.IsTrue(!hits[10].Valid()); - Assert.IsTrue(hits[11].Valid()); - - - } - - - [Test] - public void InstanceAndRayMask() - { - const int instanceCount = 8; - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); - - var rayAndInstanceMasks = new (uint instanceMask, uint rayMask)[] - { - (0, 0), - (0xFFFFFFFF, 0xFFFFFFFF), - (0, 0xFFFFFFFF), - (0xFFFFFFFF, 0), - (0x0F, 0x01), - (0x0F, 0xF0), - (0x90, 0xF0), - (0xF0, 0x10), - }; - - for (int i = 0; i < instanceCount; ++i) - { - instanceDescs[i].mask = rayAndInstanceMasks[i].instanceMask; - rays[i].instanceMask = rayAndInstanceMasks[i].rayMask; - } - - for (int i = 0; i < instanceCount; ++i) - { - m_AccelStruct.AddInstance(instanceDescs[i]); - } - - var hits = TraceRays(rays); - - for (int i = 0; i < instanceCount; ++i) - { - bool rayShouldHit = ((rayAndInstanceMasks[i].instanceMask & rayAndInstanceMasks[i].rayMask) != 0); - bool rayHit = hits[i].Valid(); - - var message = String.Format("Ray {0} hit for InstanceMask: 0x{1:X} & RayMask: 0x{2:X}", - rayShouldHit ? "should" : "shouldn't", - rayAndInstanceMasks[i].instanceMask, - rayAndInstanceMasks[i].rayMask); - - Assert.AreEqual(rayShouldHit, rayHit, message); - } - } - - [Test] - public void AddAndRemoveInstances() - { - const int instanceCount = 4; - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); - - var instanceHandles = new int[instanceCount]; - var expectedVisibleInstances = new bool[instanceCount]; - - for (int i = 0; i < instanceCount; ++i) - { - instanceHandles[i] = m_AccelStruct.AddInstance(instanceDescs[i]); - expectedVisibleInstances[i] = true; - } - - CheckVisibleInstances(rays, expectedVisibleInstances); - - m_AccelStruct.RemoveInstance(instanceHandles[0]); expectedVisibleInstances[0] = false; - m_AccelStruct.RemoveInstance(instanceHandles[2]); expectedVisibleInstances[2] = false; - - CheckVisibleInstances(rays, expectedVisibleInstances); - - m_AccelStruct.ClearInstances(); - - Array.Fill(expectedVisibleInstances, false); - - CheckVisibleInstances(rays, expectedVisibleInstances); - - m_AccelStruct.AddInstance(instanceDescs[3]); - expectedVisibleInstances[3] = true; - - CheckVisibleInstances(rays, expectedVisibleInstances); - } - -#if ENABLE_TERRAIN_MODULE - private void AddTerrainToAccelerationStructure(int heightmapResolution) - { - Terrain.CreateTerrainGameObject(new TerrainData()); - #pragma warning disable CS0618 // Type or member is obsolete - Terrain terrain = GameObject.FindFirstObjectByType(); -#pragma warning restore CS0618 // Type or member is obsolete - Assert.NotNull(terrain); - - // Set terrain texture resolution on terrain data. - terrain.terrainData.heightmapResolution = heightmapResolution; - - // Convert to mesh. - AsyncTerrainToMeshRequest request = TerrainToMesh.ConvertAsync(terrain); - request.WaitForCompletion(); - - // Add the terrain to the acceleration structure. - MeshInstanceDesc instanceDesc = new MeshInstanceDesc(request.GetMesh()); - instanceDesc.localToWorldMatrix = float4x4.identity; - m_AccelStruct.AddInstance(instanceDesc); - } - - [Test] - public void Add_1KTerrain_Works() - { - AddTerrainToAccelerationStructure(1025); - } - - [Test] - [Ignore("This test is disabled because of the allocation limitation of 2 GB in GraphicsBuffer.")] - public void Add_4KTerrain_Works() - { - AddTerrainToAccelerationStructure(4097); - } -#endif - - void CheckVisibleInstances(RayWithFlags[] rays, bool[] expectedVisibleInstances) - { - var hits = TraceRays(rays); - for (int i = 0; i < rays.Length; ++i) - { - Assert.AreEqual(expectedVisibleInstances[i], hits[i].Valid(), $"Unexpected state of intersection with instance {i}"); - } - } - - void CreateMatchingRaysAndInstanceDescs(uint instanceCount, Mesh mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs) - { - instanceDescs = new MeshInstanceDesc[instanceCount]; - rays = new RayWithFlags[instanceCount]; - var ray = new RayWithFlags(new float3(0.0f, 0.0f, 1.0f), new float3(0.0f, 0.0f, -1.0f)); - float3 step = new float3(2.0f, 0.0f, 0.0f); - - for (int i = 0; i < instanceCount; ++i) - { - instanceDescs[i] = new MeshInstanceDesc(mesh); - instanceDescs[i].localToWorldMatrix = float4x4.Translate(step * i); - - rays[i] = ray; - rays[i].origin += step * i; - } - } - - - [StructLayout(LayoutKind.Sequential)] - public struct Hit - { - public uint instanceID; - public uint primitiveIndex; - public float2 uvBarycentrics; - public float hitDistance; - public uint isFrontFace; - - public bool Valid() { return instanceID != 0xFFFFFFFF; } - } - - } - - [TestFixture("Compute")] - [TestFixture("Hardware")] - internal class AccelStructTransparencyTests : AccelStructTestsBase - { - public AccelStructTransparencyTests(string backendAsString) : base(backendAsString) - { - } - - [SetUp] - public void SetUp() - { - CreateRayTracingResources("TraceTransparentRays.urtshader"); - } - - [TearDown] - public void TearDown() - { - DisposeRayTracingResources(); - } - - - [Test] - public void WithTransparentInstances_ClosestAndAnyHitsFuncsAreCalled() - { - Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); - - var isOpaque = new bool[] { false, false, true, false, false, false, true, false }; - for (int i = 0; i < isOpaque.Length; ++i) - { - var instanceDesc = new MeshInstanceDesc(mesh); - instanceDesc.localToWorldMatrix = float4x4.Translate(new float3(0.0f, 0.0f, 2.0f) * i); - instanceDesc.opaqueGeometry = isOpaque[i]; - instanceDesc.instanceID = (uint)i; - - m_AccelStruct.AddInstance(instanceDesc); - } - - { - var testCases = new TransparencyTestCase[] { - new(RayFlags.None, 2, new int[] { 0, 1 }), - new(RayFlags.ForceOpaque, 0, new int[] { }), - new(RayFlags.ForceNonOpaque, -1, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }), - new(RayFlags.CullOpaque, -1, new int[] { 0, 1, 3, 4, 5, 7 }), - new(RayFlags.CullNonOpaque, 2, new int[] { }), - new(RayFlags.CullOpaque | RayFlags.SkipClosestHit, -1, new int[] { 0, 1, 3, 4, 5, 7 }), - new(RayFlags.AcceptFirstHitAndEndSearch, 2, new int[] { 0, 1 }), - new(RayFlags.ForceNonOpaque | RayFlags.AcceptFirstHitAndEndSearch, -1, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }), - }; - - TestTransparentInstances(testCases, AnyHitDecision.IgnoreHit); - } - - { - var testCases = new TransparencyTestCase[] { - new(RayFlags.None, 0, new int[] { 0 }), - new(RayFlags.ForceOpaque, 0, new int[] { }), - new(RayFlags.ForceNonOpaque, 0, new int[] { 0 }), - new(RayFlags.CullOpaque, 0, new int[] { 0 }), - new(RayFlags.CullNonOpaque, 2, new int[] { }), - new(RayFlags.CullOpaque | RayFlags.SkipClosestHit, -1, new int[] { 0 }), - new(RayFlags.AcceptFirstHitAndEndSearch, 0, new int[] { 0 }), - new(RayFlags.ForceNonOpaque | RayFlags.AcceptFirstHitAndEndSearch, 0, new int[] { 0 }), - }; - - TestTransparentInstances(testCases, AnyHitDecision.AcceptHit); - TestTransparentInstances(testCases, AnyHitDecision.AcceptHitAndEndSearch); - } - } - - void TestTransparentInstances(TransparencyTestCase[] testCases, AnyHitDecision anyHitDecision) - { - var expectedResults = new List(); - var rayWithFlags = new List(); - - foreach (var testCase in testCases) - { - var ray = new RayWithFlags(new float3(0.0f, 0.0f, -1.0f), new float3(0.0f, 0.0f, 1.0f)); - ray.culling = (uint)testCase.rayFlags; - rayWithFlags.Add(ray); - - expectedResults.Add(testCase.expectedResult); - } - - var hits = TraceRays(rayWithFlags.ToArray(), anyHitDecision); - - for (int i = 0; i < testCases.Length; ++i) - { - Assert.AreEqual(testCases[i].expectedResult.closestHit, hits[i].closestHit, $"Unexpected closestHit with RayFlags=[{(RayFlags)rayWithFlags[i].culling}] and AnyHitDecision=[{anyHitDecision}]"); - Assert.AreEqual(testCases[i].expectedResult.anyHits, hits[i].anyHits, $"Unexpected anyHits with RayFlags=[{(RayFlags)rayWithFlags[i].culling}] and AnyHitDecision=[{anyHitDecision}]"); - } - } - - - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct TransparentRayResult - { - public uint anyHits; - public int closestHit; - } - - struct TransparencyTestCase - { - public TransparencyTestCase(RayFlags flags, int expectedClosestHit, int[] expectedAnyHitInvocations) - { - rayFlags = flags; - - expectedResult.closestHit = expectedClosestHit; - expectedResult.anyHits = 0; - for (int i = 0; i < expectedAnyHitInvocations.Length; ++i) - expectedResult.anyHits |= (1u << expectedAnyHitInvocations[i]); - } - - public RayFlags rayFlags; - public TransparentRayResult expectedResult; - } - } -} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta deleted file mode 100644 index 686c2868621..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 907dea72c9efc834499557d581dbc45a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs deleted file mode 100644 index f7a8bf6055a..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using NUnit.Framework; -using UnityEngine.TestTools; - -namespace UnityEngine.Rendering.UnifiedRayTracing.Tests -{ - [TestFixture("Compute")] - [TestFixture("Hardware")] - internal class InvalidInputsTests - { - readonly RayTracingBackend m_Backend; - RayTracingContext m_Context; - RayTracingResources m_Resources; - IRayTracingAccelStruct m_AccelStruct; - IRayTracingShader m_Shader; - - [Flags] - enum MeshField { Positions=1, Normals=2, Uvs=4, Indices=8 } - - static Mesh CreateSingleTriangleMesh(MeshField fields) - { - Mesh mesh = new Mesh(); - - if ((fields & MeshField.Positions) != 0) - { - Vector3[] vertices = new Vector3[] - { - new Vector3(1.0f, 0.0f, 0), - new Vector3(0.0f, 0.0f, 0), - new Vector3(0.0f, 0.0f, 0) - }; - mesh.vertices = vertices; - } - - - if ((fields & MeshField.Normals) != 0) - { - Vector3[] normals = new Vector3[] - { - -Vector3.forward, - -Vector3.forward, - -Vector3.forward - }; - mesh.normals = normals; - } - - if ((fields & MeshField.Uvs) != 0) - { - Vector2[] uv = new Vector2[] - { - new Vector2(0, 1), - new Vector2(1, 1), - new Vector2(0, 0) - }; - mesh.uv = uv; - } - - if ((fields & MeshField.Indices) != 0) - { - int[] tris = new int[3] - { - 0, 2, 1 - }; - mesh.triangles = tris; - } - - return mesh; - } - - public InvalidInputsTests(string backendAsString) - { - m_Backend = Enum.Parse(backendAsString); - } - - [SetUp] - public void SetUp() - { - if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware) - Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); - - - if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute) - Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); - - m_Resources = new RayTracingResources(); - m_Resources.Load(); - - m_Context = new RayTracingContext(m_Backend, m_Resources); - m_AccelStruct = m_Context.CreateAccelerationStructure(new AccelerationStructureOptions() { useCPUBuild = false }); - m_Shader = m_Context.LoadRayTracingShader("Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader"); - } - - [TearDown] - public void TearDown() - { - m_AccelStruct?.Dispose(); - m_Context?.Dispose(); - } - - - [Test] - public void AccelStruct_AddInstance_ThrowOnNullMesh() - { - var instanceDesc = new MeshInstanceDesc(null); - Assert.Throws(() => m_AccelStruct.AddInstance(instanceDesc)); - } - - [Test] - public void AccelStruct_AddInstance_ThrowOnMeshWithNoPositions() - { - var mesh = new Mesh(); - var instanceDesc = new MeshInstanceDesc(mesh); - Assert.Throws(() => m_AccelStruct.AddInstance(instanceDesc)); - } - - [Test] - public void AccelStruct_AddInstance_ThrowOnInvalidSubmeshIndex() - { - var mesh = CreateSingleTriangleMesh(MeshField.Positions | MeshField.Indices | MeshField.Normals | MeshField.Uvs); - var instanceDesc = new MeshInstanceDesc(mesh); - instanceDesc.subMeshIndex = -1; - Assert.Throws(() => m_AccelStruct.AddInstance(instanceDesc)); - } - - [Test] - public void AccelStruct_AddInstance_ThrowOnInvalidInstanceHandle() - { - var mesh = CreateSingleTriangleMesh(MeshField.Positions | MeshField.Indices | MeshField.Normals | MeshField.Uvs); - var instanceDesc = new MeshInstanceDesc(mesh); - var handle = m_AccelStruct.AddInstance(instanceDesc); - Assert.Throws(() => m_AccelStruct.RemoveInstance(handle + 1)); - - m_AccelStruct.ClearInstances(); - Assert.Throws(() => m_AccelStruct.RemoveInstance(handle)); - } - - [Test] - public void RayTracingShader_SetFloatParam_ThrowOnNullCmdBuffer() - { - Assert.Throws(() => m_Shader.SetFloatParam(null, 0, 1.0f)); - } - - [Test] - public void RayTracingShader_Dispatch_ThrowOnSmallScratchBuffer() - { - if (m_Backend == RayTracingBackend.Hardware) - { - Assert.Ignore("scratch buffer is lawfully null with hardware backend"); - return; - } - - using GraphicsBuffer scratch = new GraphicsBuffer(GraphicsBuffer.Target.Structured, 10, 4); - using CommandBuffer cmd = new CommandBuffer(); - var except = Assert.Throws(() => m_Shader.Dispatch(cmd, scratch, 20, 20, 20)); - Assert.That(except.Message, Does.Contain("scratch")); - } - - [Test] - public void RayTracingShader_Dispatch_ThrowOnScratchBufferWithInvalidTarget() - { - if (m_Backend == RayTracingBackend.Hardware) - { - Assert.Ignore("scratch buffer is lawfully null with hardware backend"); - return; - } - - using GraphicsBuffer scratch = new GraphicsBuffer(GraphicsBuffer.Target.Raw, 20*20*20*100, 4); - using CommandBuffer cmd = new CommandBuffer(); - var except = Assert.Throws(() => m_Shader.Dispatch(cmd, scratch, 20, 20, 20)); - Assert.That(except.Message, Does.Contain("target")); - } - - } -} - diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta deleted file mode 100644 index fae7e4e9083..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: dd65df3631672c9449ce603e84743fd9 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader deleted file mode 100644 index 4f17278e468..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader +++ /dev/null @@ -1,39 +0,0 @@ -#define UNIFIED_RT_GROUP_SIZE_X 16 -#define UNIFIED_RT_GROUP_SIZE_Y 8 -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl" -#pragma exclude_renderers webgpu - -UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); - -struct RayWithFlags -{ - float3 origin; - float tMin; - float3 direction; - float tMax; - uint culling; - uint instanceMask; - uint padding; - uint padding2; -}; - - - -StructuredBuffer _Rays; -RWStructuredBuffer _Hits; - - -void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) -{ - RayWithFlags rayWithFlags = _Rays[dispatchInfo.globalThreadIndex]; - UnifiedRT::Ray ray; - ray.origin = rayWithFlags.origin; - ray.direction = rayWithFlags.direction; - ray.tMin = rayWithFlags.tMin; - ray.tMax = rayWithFlags.tMax; - - UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); - UnifiedRT::Hit hitResult = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, rayWithFlags.instanceMask, ray, rayWithFlags.culling); - - _Hits[dispatchInfo.globalThreadIndex] = hitResult; -} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta deleted file mode 100644 index 1b9e032ae42..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 1142bbad8b9e8c44c83a9775ff120d37 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader deleted file mode 100644 index 1099b1e88ad..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader +++ /dev/null @@ -1,49 +0,0 @@ -#define UNIFIED_RT_GROUP_SIZE_X 16 -#define UNIFIED_RT_GROUP_SIZE_Y 8 -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl" -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl" -#pragma exclude_renderers webgpu - -UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); - -struct RayWithFlags -{ - float3 origin; - float tMin; - float3 direction; - float tMax; - uint culling; - uint instanceMask; - uint padding; - uint padding2; -}; - -StructuredBuffer _Rays; -RWStructuredBuffer _Hits; -RWStructuredBuffer _HitAttributes; - -void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) -{ - - RayWithFlags rayWithFlags = _Rays[dispatchInfo.globalThreadIndex]; - UnifiedRT::Ray ray; - ray.origin = rayWithFlags.origin; - ray.direction = rayWithFlags.direction; - ray.tMin = rayWithFlags.tMin; - ray.tMax = rayWithFlags.tMax; - - UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); - UnifiedRT::Hit hitResult = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, rayWithFlags.instanceMask, ray, rayWithFlags.culling); - if (hitResult.IsValid()) - { - UnifiedRT::HitGeomAttributes hitAttribs = UnifiedRT::FetchHitGeomAttributes(hitResult); - _HitAttributes[dispatchInfo.globalThreadIndex] = hitAttribs; - } - else - { - _HitAttributes[dispatchInfo.globalThreadIndex] = (UnifiedRT::HitGeomAttributes)0; - } - - - _Hits[dispatchInfo.globalThreadIndex] = hitResult; -} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta deleted file mode 100644 index 8ab85f8e486..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: fbc59f55df2416344b008dc23753cae2 -ScriptedImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 2 - userData: - assetBundleName: - assetBundleVariant: - script: {fileID: 11500000, guid: 42d537a8a4089e448a99fc57a06d74a9, type: 3} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader deleted file mode 100644 index f834bc9347f..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader +++ /dev/null @@ -1,67 +0,0 @@ -#pragma only_renderers d3d11 xboxone xboxseries vulkan metal webgpu -#define UNIFIED_RT_GROUP_SIZE_X 16 -#define UNIFIED_RT_GROUP_SIZE_Y 8 -#define UNIFIED_RT_PAYLOAD RayPayload -#define UNIFIED_RT_RAYGEN_FUNC RayGenExecute -#define UNIFIED_RT_CLOSESTHIT_FUNC ClosestHitExecute -#define UNIFIED_RT_ANYHIT_FUNC AnyHitExecute -#pragma exclude_renderers webgpu - -struct RayPayload -{ - uint anyHits; - int closestHit; -}; - -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl" - -int _AnyHitDecision; - -uint AnyHitExecute(UnifiedRT::HitContext hitContext, inout RayPayload payload) -{ - payload.anyHits |= (1u << hitContext.InstanceID()); - - return _AnyHitDecision; -} - -void ClosestHitExecute(UnifiedRT::HitContext hitContext, inout RayPayload payload) -{ - payload.closestHit = hitContext.InstanceID(); -} - -UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); - -struct RayWithFlags -{ - float3 origin; - float tMin; - float3 direction; - float tMax; - uint culling; - uint instanceMask; - uint padding; - uint padding2; -}; - -StructuredBuffer _Rays; -RWStructuredBuffer _Hits; - - -void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) -{ - RayWithFlags rayWithFlags = _Rays[dispatchInfo.globalThreadIndex]; - UnifiedRT::Ray ray; - ray.origin = rayWithFlags.origin; - ray.direction = rayWithFlags.direction; - ray.tMin = rayWithFlags.tMin; - ray.tMax = rayWithFlags.tMax; - - UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); - - RayPayload rayPayload = (RayPayload)0; - rayPayload.closestHit = -1; - UnifiedRT::TraceRay(dispatchInfo, accelStruct, 0xFFFFFFFF, ray, rayWithFlags.culling, rayPayload); - - _Hits[dispatchInfo.globalThreadIndex] = rayPayload; -} - diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta deleted file mode 100644 index f90fde8a674..00000000000 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 6513c3b892e933c4f8d00c19d5c47532 From 6bc59c3c701b30beabd9d557d5738ee73bb47f4f Mon Sep 17 00:00:00 2001 From: Kay Leng Chang Date: Wed, 1 Apr 2026 01:08:50 +0000 Subject: [PATCH 11/88] [UUM-130481][Switch2] Clear UI overlay texture on base camera if created but not rendered into --- .../Runtime/UniversalRendererRenderGraph.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs index 4295a992d71..a0ae55d1cda 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs @@ -1945,7 +1945,12 @@ void CreateOffscreenUITexture(RenderGraph renderGraph, TextureDesc descriptor) UniversalResourceData resourceData = frameData.Get(); DrawScreenSpaceUIPass.ConfigureOffscreenUITextureDesc(ref descriptor); RenderingUtils.ReAllocateHandleIfNeeded(ref s_OffscreenUIColorHandle, descriptor, name: "_OverlayUITexture"); - resourceData.overlayUITexture = renderGraph.ImportTexture(s_OffscreenUIColorHandle); + // Clear the texture to avoid stale data from previous frames + ImportResourceParams importParams = new ImportResourceParams(); + importParams.clearOnFirstUse = true; + importParams.clearColor = Color.clear; + importParams.discardOnLastUse = true; + resourceData.overlayUITexture = renderGraph.ImportTexture(s_OffscreenUIColorHandle, importParams); } void DepthNormalPrepassRender(RenderGraph renderGraph, RenderPassInputSummary renderPassInputs, in TextureHandle depthTarget, uint batchLayerMask, bool setGlobalDepth, bool setGlobalTextures, bool partialPass) From b2ecd1baf2954032af0a11ae36627b4ba7c4b7c8 Mon Sep 17 00:00:00 2001 From: Arttu Peltonen Date: Wed, 1 Apr 2026 01:08:52 +0000 Subject: [PATCH 12/88] Fix URP Asset multi-select inspector bugs --- .../UniversalRenderPipelineAssetUI.Drawers.cs | 102 ++++++++++++++---- 1 file changed, 79 insertions(+), 23 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs index a715ca96fde..0be0250ecb8 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs @@ -181,7 +181,13 @@ static void DrawRendering(SerializedUniversalRenderPipelineAsset serialized, Edi if ((GPUResidentDrawerMode)serialized.gpuResidentDrawerMode.intValue != GPUResidentDrawerMode.Disabled) { ++EditorGUI.indentLevel; - serialized.smallMeshScreenPercentage.floatValue = Mathf.Clamp(EditorGUILayout.FloatField(Styles.smallMeshScreenPercentage, serialized.smallMeshScreenPercentage.floatValue), 0.0f, 20.0f); + using (new EditorGUI.MixedValueScope(serialized.smallMeshScreenPercentage.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newSmallMeshScreenPercentage = Mathf.Clamp(EditorGUILayout.FloatField(Styles.smallMeshScreenPercentage, serialized.smallMeshScreenPercentage.floatValue), 0.0f, 20.0f); + if (EditorGUI.EndChangeCheck()) + serialized.smallMeshScreenPercentage.floatValue = newSmallMeshScreenPercentage; + } EditorGUILayout.PropertyField(serialized.gpuResidentDrawerEnableOcclusionCullingInCameras, Styles.gpuResidentDrawerEnableOcclusionCullingInCameras); DisplayTileOnlyHelpBox(serialized.gpuResidentDrawerEnableOcclusionCullingInCameras, p => p.boolValue, Styles.gpuResidentDrawerEnableOcclusionCullingInCameras); --EditorGUI.indentLevel; @@ -292,7 +298,13 @@ static void DrawQuality(SerializedUniversalRenderPipelineAsset serialized, Edito && !IsAndroidXRTargetted(), Styles.msaaText, MessageType.Info, Styles.msaaTileOnlyInfo); - serialized.renderScale.floatValue = EditorGUILayout.Slider(Styles.renderScaleText, serialized.renderScale.floatValue, UniversalRenderPipeline.minRenderScale, UniversalRenderPipeline.maxRenderScale); + using (new EditorGUI.MixedValueScope(serialized.renderScale.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newRenderScale = EditorGUILayout.Slider(Styles.renderScaleText, serialized.renderScale.floatValue, UniversalRenderPipeline.minRenderScale, UniversalRenderPipeline.maxRenderScale); + if (EditorGUI.EndChangeCheck()) + serialized.renderScale.floatValue = newRenderScale; + } DisplayTileOnlyHelpBox( serialized.renderScale, p => @@ -392,7 +404,13 @@ static void DrawUpscalingFilterDropdownAndOptions(SerializedUniversalRenderPipel // We put the FSR sharpness override value behind an override checkbox so we can tell when the user intends to use a custom value rather than the default. if (serialized.fsrOverrideSharpness.boolValue) { - serialized.fsrSharpness.floatValue = EditorGUILayout.Slider(Styles.fsrSharpnessText, serialized.fsrSharpness.floatValue, 0.0f, 1.0f); + using (new EditorGUI.MixedValueScope(serialized.fsrSharpness.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newFsrSharpness = EditorGUILayout.Slider(Styles.fsrSharpnessText, serialized.fsrSharpness.floatValue, 0.0f, 1.0f); + if (EditorGUI.EndChangeCheck()) + serialized.fsrSharpness.floatValue = newFsrSharpness; + } } --EditorGUI.indentLevel; break; @@ -473,7 +491,13 @@ static void DrawUpscalingFilterDropdownAndOptions(SerializedUniversalRenderPipel // We put the FSR sharpness override value behind an override checkbox so we can tell when the user intends to use a custom value rather than the default. if (serialized.fsrOverrideSharpness.boolValue) { - serialized.fsrSharpness.floatValue = EditorGUILayout.Slider(Styles.fsrSharpnessText, serialized.fsrSharpness.floatValue, 0.0f, 1.0f); + using (new EditorGUI.MixedValueScope(serialized.fsrSharpness.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newFsrSharpness = EditorGUILayout.Slider(Styles.fsrSharpnessText, serialized.fsrSharpness.floatValue, 0.0f, 1.0f); + if (EditorGUI.EndChangeCheck()) + serialized.fsrSharpness.floatValue = newFsrSharpness; + } } --EditorGUI.indentLevel; @@ -521,13 +545,13 @@ static void DrawLighting(SerializedUniversalRenderPipelineAsset serialized, Edit EditorGUI.EndDisabledGroup(); EditorGUI.indentLevel++; - disableGroup |= !serialized.mainLightRenderingModeProp.boolValue; + disableGroup |= serialized.mainLightRenderingModeProp.hasMultipleDifferentValues || !serialized.mainLightRenderingModeProp.boolValue; EditorGUI.BeginDisabledGroup(disableGroup); EditorGUILayout.PropertyField(serialized.mainLightShadowsSupportedProp, Styles.supportsMainLightShadowsText); EditorGUI.EndDisabledGroup(); - disableGroup |= !serialized.mainLightShadowsSupportedProp.boolValue; + disableGroup |= serialized.mainLightShadowsSupportedProp.hasMultipleDifferentValues || !serialized.mainLightShadowsSupportedProp.boolValue; EditorGUI.BeginDisabledGroup(disableGroup); EditorGUILayout.PropertyField(serialized.mainLightShadowmapResolutionProp, Styles.mainLightShadowmapResolutionText); EditorGUI.EndDisabledGroup(); @@ -545,7 +569,7 @@ static void DrawLighting(SerializedUniversalRenderPipelineAsset serialized, Edit EditorGUILayout.PropertyField(serialized.probeVolumeSHBands, Styles.probeVolumeSHBands); EditorGUILayout.PropertyField(serialized.supportProbeVolumeGPUStreaming, Styles.supportProbeVolumeGPUStreaming); - EditorGUI.BeginDisabledGroup(!serialized.supportProbeVolumeGPUStreaming.boolValue); + EditorGUI.BeginDisabledGroup(serialized.supportProbeVolumeGPUStreaming.hasMultipleDifferentValues || !serialized.supportProbeVolumeGPUStreaming.boolValue); EditorGUI.indentLevel++; EditorGUILayout.PropertyField(serialized.supportProbeVolumeDiskStreaming, Styles.supportProbeVolumeDiskStreaming); EditorGUI.indentLevel--; @@ -583,9 +607,15 @@ static void DrawLighting(SerializedUniversalRenderPipelineAsset serialized, Edit EditorGUILayout.PropertyField(serialized.additionalLightsRenderingModeProp, Styles.addditionalLightsRenderingModeText); EditorGUI.indentLevel++; - disableGroup = serialized.additionalLightsRenderingModeProp.intValue == (int)LightRenderingMode.Disabled; + disableGroup = serialized.additionalLightsRenderingModeProp.hasMultipleDifferentValues || serialized.additionalLightsRenderingModeProp.intValue == (int)LightRenderingMode.Disabled; EditorGUI.BeginDisabledGroup(disableGroup); - serialized.additionalLightsPerObjectLimitProp.intValue = EditorGUILayout.IntSlider(Styles.perObjectLimit, serialized.additionalLightsPerObjectLimitProp.intValue, 0, UniversalRenderPipeline.maxPerObjectLights); + using (new EditorGUI.MixedValueScope(serialized.additionalLightsPerObjectLimitProp.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + int newPerObjectLimit = EditorGUILayout.IntSlider(Styles.perObjectLimit, serialized.additionalLightsPerObjectLimitProp.intValue, 0, UniversalRenderPipeline.maxPerObjectLights); + if (EditorGUI.EndChangeCheck()) + serialized.additionalLightsPerObjectLimitProp.intValue = newPerObjectLimit; + } #if UNITY_META_QUEST if (serialized.additionalLightsPerObjectLimitProp.intValue > 1) { @@ -594,19 +624,23 @@ static void DrawLighting(SerializedUniversalRenderPipelineAsset serialized, Edit #endif EditorGUI.EndDisabledGroup(); - disableGroup |= (serialized.additionalLightsPerObjectLimitProp.intValue == 0 || serialized.additionalLightsRenderingModeProp.intValue != (int)LightRenderingMode.PerPixel); + disableGroup |= serialized.additionalLightsPerObjectLimitProp.hasMultipleDifferentValues + || serialized.additionalLightsRenderingModeProp.hasMultipleDifferentValues + || serialized.additionalLightsPerObjectLimitProp.intValue == 0 + || serialized.additionalLightsRenderingModeProp.intValue != (int)LightRenderingMode.PerPixel; EditorGUI.BeginDisabledGroup(disableGroup); EditorGUILayout.PropertyField(serialized.additionalLightShadowsSupportedProp, Styles.supportsAdditionalShadowsText); EditorGUI.EndDisabledGroup(); - disableGroup |= !serialized.additionalLightShadowsSupportedProp.boolValue; + disableGroup |= serialized.additionalLightShadowsSupportedProp.hasMultipleDifferentValues || !serialized.additionalLightShadowsSupportedProp.boolValue; EditorGUI.BeginDisabledGroup(disableGroup); EditorGUILayout.PropertyField(serialized.additionalLightShadowmapResolutionProp, Styles.additionalLightsShadowmapResolution); DrawShadowResolutionTierSettings(serialized, ownerEditor); EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); - disableGroup = serialized.additionalLightsRenderingModeProp.intValue == (int)LightRenderingMode.Disabled || !serialized.supportsLightCookies.boolValue; + disableGroup = serialized.additionalLightsRenderingModeProp.hasMultipleDifferentValues || serialized.additionalLightsRenderingModeProp.intValue == (int)LightRenderingMode.Disabled + || serialized.supportsLightCookies.hasMultipleDifferentValues || !serialized.supportsLightCookies.boolValue; EditorGUI.BeginDisabledGroup(disableGroup); EditorGUILayout.PropertyField(serialized.additionalLightCookieResolutionProp, Styles.additionalLightsCookieResolution); @@ -660,11 +694,9 @@ static void DrawShadowResolutionTierSettings(SerializedUniversalRenderPipelineAs { // UI code adapted from HDRP U.I logic implemented in com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedScalableSetting.cs ) - var rect = GUILayoutUtility.GetRect(0, float.Epsilon, EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight); + var rect = EditorGUILayout.GetControlRect(); var contentRect = EditorGUI.PrefixLabel(rect, Styles.additionalLightsShadowResolutionTiers); - EditorGUI.BeginChangeCheck(); - const int k_ShadowResolutionTiersCount = 3; var values = new[] { serialized.additionalLightsShadowResolutionTierLowProp, serialized.additionalLightsShadowResolutionTierMediumProp, serialized.additionalLightsShadowResolutionTierHighProp }; @@ -683,20 +715,29 @@ static void DrawShadowResolutionTierSettings(SerializedUniversalRenderPipelineAs if (spaceLeft > 2) // If at least two pixels are left to draw this field, draw it, otherwise, skip { var fieldSlot = new Rect(contentRect.x + pixelShift, contentRect.y, num - labelWidth, contentRect.height); // Define the rectangle for the field - int value = EditorGUI.DelayedIntField(fieldSlot, values[index].intValue); - values[index].intValue = Mathf.Max(UniversalAdditionalLightData.AdditionalLightsShadowMinimumResolution, Mathf.NextPowerOfTwo(value)); + using (new EditorGUI.MixedValueScope(values[index].hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + int value = EditorGUI.DelayedIntField(fieldSlot, values[index].intValue); + if (EditorGUI.EndChangeCheck()) + values[index].intValue = Mathf.Max(UniversalAdditionalLightData.AdditionalLightsShadowMinimumResolution, Mathf.NextPowerOfTwo(value)); + } } pixelShift += spaceLeft; // Shift by the slot that was left for the field } EditorGUI.indentLevel = indentLevel; - - EditorGUI.EndChangeCheck(); } static void DrawShadows(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) { - serialized.shadowDistanceProp.floatValue = Mathf.Max(0.0f, EditorGUILayout.FloatField(Styles.shadowDistanceText, serialized.shadowDistanceProp.floatValue)); + using (new EditorGUI.MixedValueScope(serialized.shadowDistanceProp.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newShadowDistance = Mathf.Max(0.0f, EditorGUILayout.FloatField(Styles.shadowDistanceText, serialized.shadowDistanceProp.floatValue)); + if (EditorGUI.EndChangeCheck()) + serialized.shadowDistanceProp.floatValue = newShadowDistance; + } EditorUtils.Unit unit = EditorUtils.Unit.Metric; if (serialized.shadowCascadeCountProp.intValue != 0) { @@ -723,8 +764,21 @@ static void DrawShadows(SerializedUniversalRenderPipelineAsset serialized, Edito DrawCascades(serialized, cascadeCount, useMetric, baseMetric); EditorGUI.indentLevel++; - serialized.shadowDepthBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowDepthBias, serialized.shadowDepthBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); - serialized.shadowNormalBiasProp.floatValue = EditorGUILayout.Slider(Styles.shadowNormalBias, serialized.shadowNormalBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); + using (new EditorGUI.MixedValueScope(serialized.shadowDepthBiasProp.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newDepthBias = EditorGUILayout.Slider(Styles.shadowDepthBias, serialized.shadowDepthBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); + if (EditorGUI.EndChangeCheck()) + serialized.shadowDepthBiasProp.floatValue = newDepthBias; + } + + using (new EditorGUI.MixedValueScope(serialized.shadowNormalBiasProp.hasMultipleDifferentValues)) + { + EditorGUI.BeginChangeCheck(); + float newNormalBias = EditorGUILayout.Slider(Styles.shadowNormalBias, serialized.shadowNormalBiasProp.floatValue, 0.0f, UniversalRenderPipeline.maxShadowBias); + if (EditorGUI.EndChangeCheck()) + serialized.shadowNormalBiasProp.floatValue = newNormalBias; + } EditorGUILayout.PropertyField(serialized.softShadowsSupportedProp, Styles.supportsSoftShadows); if (serialized.softShadowsSupportedProp.boolValue) { @@ -914,8 +968,10 @@ static void DrawPostProcessing(SerializedUniversalRenderPipelineAsset serialized else if (isHdrOn && PlayerSettings.allowHDRDisplaySupport && serialized.colorGradingMode.intValue == (int)ColorGradingMode.LowDynamicRange) EditorGUILayout.HelpBox(Styles.colorGradingModeWithHDROutput, MessageType.Warning); + EditorGUI.BeginChangeCheck(); EditorGUILayout.DelayedIntField(serialized.colorGradingLutSize, Styles.colorGradingLutSize); - serialized.colorGradingLutSize.intValue = Mathf.Clamp(serialized.colorGradingLutSize.intValue, UniversalRenderPipelineAsset.k_MinLutSize, UniversalRenderPipelineAsset.k_MaxLutSize); + if (EditorGUI.EndChangeCheck()) + serialized.colorGradingLutSize.intValue = Mathf.Clamp(serialized.colorGradingLutSize.intValue, UniversalRenderPipelineAsset.k_MinLutSize, UniversalRenderPipelineAsset.k_MaxLutSize); if (isHdrOn && serialized.colorGradingMode.intValue == (int)ColorGradingMode.HighDynamicRange && serialized.colorGradingLutSize.intValue < 32) EditorGUILayout.HelpBox(Styles.colorGradingLutSizeWarning, MessageType.Warning); From d64a5607d701b34d9e9197c0162e63fd1bd030d2 Mon Sep 17 00:00:00 2001 From: Yvain Raeymaekers Date: Wed, 1 Apr 2026 01:08:55 +0000 Subject: [PATCH 13/88] [UUM-138315] Silence FXC's annoying "potentially uninitialized variable" warnings in LightBaker shaders --- .../Runtime/PathTracing/Shaders/LightSampling.hlsl | 3 +++ .../Runtime/PathTracing/Shaders/LiveGI.urtshader | 2 ++ .../Runtime/PathTracing/Shaders/PathTracing.hlsl | 2 ++ .../PathTracing/Shaders/StochasticLightmapSampling.hlsl | 3 +++ 4 files changed, 10 insertions(+) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LightSampling.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LightSampling.hlsl index b78e6b2a702..4aae9bbd0bd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LightSampling.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LightSampling.hlsl @@ -1,6 +1,9 @@ #ifndef _PATHTRACING_LIGHTSAMPLING_HLSL_ #define _PATHTRACING_LIGHTSAMPLING_HLSL_ +// Silence FXC's annoying "potentially uninitialized variable" warnings +#pragma warning (disable : 4000) + #include "PathTracingCommon.hlsl" #include "PathTracingMaterials.hlsl" #include "PathTracingLightGrid.hlsl" diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LiveGI.urtshader b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LiveGI.urtshader index 368968dc8a0..b58df7feadb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LiveGI.urtshader +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/LiveGI.urtshader @@ -147,9 +147,11 @@ PixelState SamplePixel(UnifiedRT::DispatchInfo dispatchInfo) float4 GetHeatmapColor(int rays) { + UNITY_FLATTEN if (rays <= 2) return float4(0, 1, 0, 0); + UNITY_FLATTEN if (rays <= 3) return float4(0, 0, 1, 0); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/PathTracing.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/PathTracing.hlsl index 7e511086721..0a900775a3b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/PathTracing.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/PathTracing.hlsl @@ -33,6 +33,7 @@ int ScatterDiffusely(PTHitGeom hitGeom, float3 V, inout PathTracingSampler rngSt bounceRay = (UnifiedRT::Ray)0; float3 rayDirection; + UNITY_FLATTEN if (!SampleDiffuseBrdf(u, hitGeom.worldFaceNormal, hitGeom.worldNormal, V, rayDirection, brdfPdf)) return RAY_TERMINATION; @@ -275,6 +276,7 @@ bool Scatter(inout PathIterator iterator, inout PathTracingSampler rngState) { float brdfPdf; int event = ScatterDiffusely(iterator.hitGeo, -iterator.ray.direction, rngState, iterator.ray, brdfPdf); + UNITY_FLATTEN if (event == RAY_TERMINATION) return false; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/StochasticLightmapSampling.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/StochasticLightmapSampling.hlsl index 618f29aa536..a86c24d2a4a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/StochasticLightmapSampling.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/StochasticLightmapSampling.hlsl @@ -1,6 +1,9 @@ #ifndef _PATHTRACING_STOCHASTICLIGHTMAPSAMPLING_HLSL_ #define _PATHTRACING_STOCHASTICLIGHTMAPSAMPLING_HLSL_ +// Silence FXC's annoying "potentially uninitialized variable" warnings +#pragma warning (disable : 4000) + #include "PathTracingCommon.hlsl" UnifiedRT::Ray MakeUVRay(float2 origin) From 1a758cd12caab6a0173e898d7a91a047adccd78c Mon Sep 17 00:00:00 2001 From: Angela Dematte Date: Wed, 1 Apr 2026 01:08:57 +0000 Subject: [PATCH 14/88] Disable unstable SRP Foundation tests --- .../Tests/Runtime/Debugging/ProfilingSamplerTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Packages/com.unity.render-pipelines.core/Tests/Runtime/Debugging/ProfilingSamplerTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Runtime/Debugging/ProfilingSamplerTests.cs index a4fadb9f29f..646d14e20ae 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Runtime/Debugging/ProfilingSamplerTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Runtime/Debugging/ProfilingSamplerTests.cs @@ -165,6 +165,7 @@ public void RecordersAllocated_AfterFirstEnableRecording() } [UnityTest] + [Ignore("Unstable: https://jira.unity3d.com/browse/UUM-138435")] public IEnumerator EnableRecording_InlineCpuElapsedTime_IsGreaterThanZero() { m_Sampler.enableRecording = true; @@ -181,6 +182,7 @@ public IEnumerator EnableRecording_InlineCpuElapsedTime_IsGreaterThanZero() } [UnityTest] + [Ignore("Unstable: https://jira.unity3d.com/browse/UUM-138435")] public IEnumerator ProfilingScope_InlineCpuElapsedTime_IsGreaterThanZero() { m_Sampler.enableRecording = true; From 0a54b8e6632983aa73ed9c1425883dacb3dbd1ce Mon Sep 17 00:00:00 2001 From: Angela Dematte Date: Wed, 1 Apr 2026 01:08:58 +0000 Subject: [PATCH 15/88] Disable unstable Upscalers test --- .../Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs index 5af722f1c3e..bb9658786e0 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/HDRP_Graphics_Tests.cs @@ -390,6 +390,10 @@ public void SetUpContext() GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer )] + [IgnoreGraphicsTest( + "4103_DRS-DLSS-AfterPost", + "Unstable: https://jira.unity3d.com/browse/UUM-137893" + )] [TestOnlySupportedOn( "4111_DRS-DLSS-With-CustomPass", "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only From 73186607bdd11958e7385ce7be2d0a9ed84b83ab Mon Sep 17 00:00:00 2001 From: Arttu Peltonen Date: Wed, 1 Apr 2026 08:38:59 +0000 Subject: [PATCH 16/88] Add missing ENABLE_TERRAIN_MODULE define to lighting assemblies --- .../SurfaceCache/Unity.SurfaceCache.Runtime.asmdef | 10 ++++++++-- .../PathTracing/Unity.PathTracing.Runtime.asmdef | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Unity.SurfaceCache.Runtime.asmdef b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Unity.SurfaceCache.Runtime.asmdef index 28a31ad789b..0f64cb3b56d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Unity.SurfaceCache.Runtime.asmdef +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Unity.SurfaceCache.Runtime.asmdef @@ -14,6 +14,12 @@ "precompiledReferences": [], "autoReferenced": true, "defineConstraints": [], - "versionDefines": [], + "versionDefines": [ + { + "name": "com.unity.modules.terrain", + "expression": "1.0.0", + "define": "ENABLE_TERRAIN_MODULE" + } + ], "noEngineReferences": false -} \ No newline at end of file +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Unity.PathTracing.Runtime.asmdef b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Unity.PathTracing.Runtime.asmdef index 10260881fc1..3e9df26e30b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Unity.PathTracing.Runtime.asmdef +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Unity.PathTracing.Runtime.asmdef @@ -35,7 +35,12 @@ "name": "com.unity.modules.imageconversion", "expression": "1.0.0", "define": "ENABLE_IMAGECONVERSION_MODULE" + }, + { + "name": "com.unity.modules.terrain", + "expression": "1.0.0", + "define": "ENABLE_TERRAIN_MODULE" } ], "noEngineReferences": false -} \ No newline at end of file +} From 5a512ac5fc91e4e118ec634e0f5bff5485f6447e Mon Sep 17 00:00:00 2001 From: Ludovic Theobald Date: Wed, 1 Apr 2026 18:15:10 +0000 Subject: [PATCH 17/88] [VFX New Compiler] Plugging expressions and blocks --- .../Debug/VisualEffectAssetDescExtensions.cs | 246 +++++++++ .../VisualEffectAssetDescExtensions.cs.meta | 3 + .../Expressions/VFXAttributeExpression.cs | 2 +- .../Expressions/VFXExpressionAbstract.cs | 11 +- .../VFXExpressionAbstractNumericOperation.cs | 12 +- .../VFXExpressionAbstractValues.cs | 4 +- .../Editor/Expressions/VFXExpressionCamera.cs | 2 +- .../VFXExpressionExtractComponent.cs | 4 +- .../Editor/Expressions/VFXExpressionFlow.cs | 4 +- .../Editor/Expressions/VFXExpressionMesh.cs | 8 +- .../Expressions/VFXExpressionTextureValues.cs | 2 +- .../DataDescriptionWriterRegistry.cs | 7 +- .../Compiler/CodeGeneration/HlslCodeHelper.cs | 1 + .../CodeGeneration/IncludeFileShaderWriter.cs | 46 +- .../Compiler/Passes/GraphVisualizerPasses.cs | 32 +- .../Passes/StructuredDataLayoutPass.cs | 2 +- .../Passes/TemplateCodeGenerationPass.cs | 153 ++++-- .../AttributeDataDescriptionWriter.cs | 6 +- .../StructuredDataDescriptionWriter.cs | 2 + .../Editor/GraphCommon/Graph/DataContainer.cs | 5 + .../Editor/GraphCommon/Graph/DataNode.cs | 4 +- .../Editor/GraphCommon/Graph/DataView.cs | 2 + .../Editor/GraphCommon/Graph/IGraph.cs | 10 + .../Editor/GraphCommon/Graph/TaskGraph.cs | 14 +- .../GraphCommon/Task/SubtaskDescription.cs | 2 +- .../Editor/GraphCommon/Task/TemplatedTask.cs | 23 +- .../Editor/Models/VFXAttributesManager.cs | 8 +- .../ParticleSystemDataDescriptionWriter.cs | 4 +- .../SpawnerDataDescriptionWriter.cs | 4 +- ...xGraphLegacyCompilationOutputExtensions.cs | 261 ---------- ...hLegacyCompilationOutputExtensions.cs.meta | 2 - .../Passes/VfxGraphLegacyOutputPass.cs | 323 +++++------- .../Passes/VfxGraphLegacyTemplatedTaskPass.cs | 111 ---- .../VfxGraphLegacyTemplatedTaskPass.cs.meta | 2 - .../NewCompiler/Tasks/LegacyExpressionTask.cs | 41 ++ .../Tasks/LegacyExpressionTask.cs.meta | 3 + .../Editor/NewCompiler/Tasks/SpawnerTask.cs | 13 +- .../NewCompiler/Tasks/SpawnerTask.cs.meta | 3 +- .../Editor/NewCompiler/VfxGraphCompiler.cs | 17 +- .../VfxIntermediateGraphBuilder.cs | 491 ++++++++++++++++++ .../VfxIntermediateGraphBuilder.cs.meta | 2 + .../Shaders/Temp.meta | 8 + .../Shaders/Temp/Data.meta | 8 + .../Shaders/Temp/Data/AttributeBuffer.hlsl | 39 ++ .../Temp/Data/AttributeBuffer.hlsl.meta | 7 + .../Shaders/Temp/Data/ByteAddressBuffer.hlsl | 278 ++++++++++ .../Temp/Data/ByteAddressBuffer.hlsl.meta | 7 + .../Shaders/Temp/Data/DeadListData.hlsl | 44 ++ .../Shaders/Temp/Data/DeadListData.hlsl.meta | 7 + .../Shaders/Temp/Data/ParticleSystemData.hlsl | 18 + .../Temp/Data/ParticleSystemData.hlsl.meta | 7 + .../Shaders/Temp/Data/SpawnerData.hlsl | 15 + .../Shaders/Temp/Data/SpawnerData.hlsl.meta | 7 + .../Shaders/Temp/Data/StructuredBuffer.hlsl | 166 ++++++ .../Temp/Data/StructuredBuffer.hlsl.meta | 7 + .../Temp/Data/StructuredBufferUInt.hlsl | 7 + .../Temp/Data/StructuredBufferUInt.hlsl.meta | 7 + .../Shaders/Temp/Data/ThreadData.hlsl | 14 + .../Shaders/Temp/Data/ThreadData.hlsl.meta | 7 + .../Shaders/Temp/Templates.meta | 8 + .../Shaders/Temp/Templates/Init.hlsl | 36 ++ .../Shaders/Temp/Templates/Init.hlsl.meta | 7 + .../Shaders/Temp/Templates/Output.hlsl | 48 ++ .../Shaders/Temp/Templates/Output.hlsl.meta | 7 + .../Shaders/Temp/Templates/Update.hlsl | 32 ++ .../Shaders/Temp/Templates/Update.hlsl.meta | 7 + 66 files changed, 1978 insertions(+), 712 deletions(-) create mode 100644 Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs create mode 100644 Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs.meta delete mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs delete mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs.meta delete mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs delete mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs.meta create mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs create mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs.meta create mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs create mode 100644 Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl.meta diff --git a/Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs b/Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs new file mode 100644 index 00000000000..8ba7db652bd --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs @@ -0,0 +1,246 @@ +using System.Text; +using UnityEditor.VFX; + +static class VisualEffectAssetDescExtensions +{ + internal static string ToDetailedString(this VisualEffectAssetDesc assetDesc) + { + var sb = new StringBuilder(); + + sb.AppendLine("VisualEffectAssetDesc:"); + sb.AppendLine(" Expression Sheet:"); + if (assetDesc.sheet.expressions != null) + { + sb.AppendLine($" Expressions Count: {assetDesc.sheet.expressions.Length}"); + for (int i = 0; i < assetDesc.sheet.expressions.Length; i++) + { + var expr = assetDesc.sheet.expressions[i]; + sb.AppendLine($" Expression {i}: {expr.op}"); + } + } + else + { + sb.AppendLine(" Expressions: null"); + } + + if (assetDesc.sheet.expressionsPerSpawnEventAttribute != null) + { + sb.AppendLine($" PerSpawnEventAttribute Count: {assetDesc.sheet.expressionsPerSpawnEventAttribute.Length}"); + for (int i = 0; i < assetDesc.sheet.expressionsPerSpawnEventAttribute.Length; i++) + { + var expr = assetDesc.sheet.expressionsPerSpawnEventAttribute[i]; + sb.AppendLine($" Expression {i}: {expr.op}"); + } + } + else + { + sb.AppendLine(" PerSpawnEventAttribute: null"); + } + + if (assetDesc.sheet.values != null) + { + sb.AppendLine($" Values Count: {assetDesc.sheet.values.Length}"); + for (int i = 0; i < assetDesc.sheet.values.Length; i++) + { + var value = assetDesc.sheet.values[i]; + sb.AppendLine($" Value {i}: {value} - {value.expressionIndex}"); + } + } + else + { + sb.AppendLine(" Values: null"); + } + + if (assetDesc.sheet.exposed != null) + { + sb.AppendLine($" Exposed Values Count: {assetDesc.sheet.exposed.Length}"); + for (int i = 0; i < assetDesc.sheet.exposed.Length; i++) + { + var value = assetDesc.sheet.exposed[i]; + sb.AppendLine($" Exposed Value {i}: {value.mapping}"); + } + } + + + if (assetDesc.systemDesc != null) + { + sb.AppendLine(" System Descriptions:"); + for (int i = 0; i < assetDesc.systemDesc.Length; i++) + { + var systemDesc = assetDesc.systemDesc[i]; + sb.AppendLine($" System {i}:"); + sb.AppendLine($" Name: {systemDesc.name}"); + sb.AppendLine($" Type: {systemDesc.type}"); + sb.AppendLine($" Flags: {systemDesc.flags}"); + sb.AppendLine($" Layer: {systemDesc.layer}"); + + if (systemDesc.buffers != null) + { + sb.AppendLine($" Buffers Count: {systemDesc.buffers.Length}"); + for (int j = 0; j < systemDesc.buffers.Length; j++) + { + var buffer = systemDesc.buffers[j]; + sb.AppendLine($" Buffer {j}: Name={buffer.name}, Index={buffer.index}"); + } + } + else + { + sb.AppendLine(" Buffers: null"); + } + + if (systemDesc.values != null) + { + sb.AppendLine($" Values Count: {systemDesc.values.Length}"); + for (int j = 0; j < systemDesc.values.Length; j++) + { + var value = systemDesc.values[j]; + sb.AppendLine($" Value {j}: Name={value.name}, Index={value.index}"); + } + } + else + { + sb.AppendLine(" Values: null"); + } + + if (systemDesc.tasks != null) + { + sb.AppendLine($" Tasks Count: {systemDesc.tasks.Length}"); + for (int j = 0; j < systemDesc.tasks.Length; j++) + { + var task = systemDesc.tasks[j]; + sb.AppendLine($" Task {j}: Type={task.type}, ShaderSourceIndex={task.shaderSourceIndex}"); + sb.AppendLine($" Processor: {task.processor?.GetType().Name ?? "None"}"); + + //Add task buffers mapping + if(task.buffers != null) + { + sb.AppendLine($" Task Buffers Count: {task.buffers.Length}"); + for (int k = 0; k < task.buffers.Length; k++) + { + var buffer = task.buffers[k]; + sb.AppendLine($" Task Buffer {k}: Name={buffer.name}, Index={buffer.index}"); + } + } + else + { + sb.AppendLine(" Task Buffers: null"); + } + + if (task.values != null) + { + sb.AppendLine($" Task Values Count: {task.values.Length}"); + for (int k = 0; k < task.values.Length; k++) + { + var value = task.values[k]; + sb.AppendLine($" Task Value {k}: Name={value.name}, Index={value.index}"); + } + } + else + { + sb.AppendLine(" Task Values: null"); + } + } + } + else + { + sb.AppendLine(" Tasks: null"); + } + } + } + else + { + sb.AppendLine(" System Descriptions: null"); + } + + if (assetDesc.eventDesc != null) + { + sb.AppendLine(" Event Descriptions:"); + for (int i = 0; i < assetDesc.eventDesc.Length; i++) + { + var eventDesc = assetDesc.eventDesc[i]; + sb.AppendLine($" Event {i}: Name={eventDesc.name}"); + sb.AppendLine($" Init Systems Count: {eventDesc.initSystems?.Length ?? 0}"); + sb.AppendLine($" Start Systems Count: {eventDesc.startSystems?.Length ?? 0}"); + sb.AppendLine($" Stop Systems Count: {eventDesc.stopSystems?.Length ?? 0}"); + } + } + else + { + sb.AppendLine(" Event Descriptions: null"); + } + + if (assetDesc.gpuBufferDesc != null) + { + sb.AppendLine(" GPU Buffer Descriptions:"); + for (int i = 0; i < assetDesc.gpuBufferDesc.Length; i++) + { + var bufferDesc = assetDesc.gpuBufferDesc[i]; + sb.AppendLine($" Buffer {i}: Target={bufferDesc.target}, Size={bufferDesc.size}, Capacity={bufferDesc.capacity}, Stride={bufferDesc.stride}"); + if (bufferDesc.layout != null && bufferDesc.layout.Length > 0) + { + sb.AppendLine($" Layout elements Count: {bufferDesc.layout.Length}"); + foreach (var layoutDesc in bufferDesc.layout) + { + sb.AppendLine($" Name={layoutDesc.name}, Type={layoutDesc.type}, Offset (bucket, structure, element) ={layoutDesc.offset.bucket}, {layoutDesc.offset.structure}, {layoutDesc.offset.element}"); + } + } + } + } + else + { + sb.AppendLine(" GPU Buffer Descriptions: null"); + } + + if (assetDesc.cpuBufferDesc != null) + { + sb.AppendLine(" CPU Buffer Descriptions:"); + for (int i = 0; i < assetDesc.cpuBufferDesc.Length; i++) + { + var bufferDesc = assetDesc.cpuBufferDesc[i]; + sb.AppendLine($" Buffer {i}: Capacity={bufferDesc.capacity}, Stride={bufferDesc.stride}"); + foreach (var layoutDesc in bufferDesc.layout) + { + sb.AppendLine($" Name={layoutDesc.name}, Type={layoutDesc.type}, Offset (bucket, structure, element) ={layoutDesc.offset.bucket}, {layoutDesc.offset.structure}, {layoutDesc.offset.element}"); + } + } + } + else + { + sb.AppendLine(" CPU Buffer Descriptions: null"); + } + + if (assetDesc.temporaryBufferDesc != null) + { + sb.AppendLine(" Temporary GPU Buffer Descriptions:"); + for (int i = 0; i < assetDesc.temporaryBufferDesc.Length; i++) + { + var tempBufferDesc = assetDesc.temporaryBufferDesc[i]; + var bufferDesc = tempBufferDesc.desc; + sb.AppendLine($" Buffer {i}: FrameCount={tempBufferDesc.frameCount},Target={bufferDesc.target}, Size={bufferDesc.size}, Capacity={bufferDesc.capacity}, Stride={bufferDesc.stride}"); + } + } + else + { + sb.AppendLine(" Temporary GPU Buffer Descriptions: null"); + } + + if (assetDesc.shaderSourceDesc != null) + { + sb.AppendLine(" Shader Source Descriptions:"); + for (int i = 0; i < assetDesc.shaderSourceDesc.Length; i++) + { + var shaderDesc = assetDesc.shaderSourceDesc[i]; + sb.AppendLine($" Shader {i}: Name={shaderDesc.name}, Compute={shaderDesc.compute}"); + } + } + else + { + sb.AppendLine(" Shader Source Descriptions: null"); + } + + sb.AppendLine($" Renderer Settings: ShadowCastingMode={assetDesc.rendererSettings.shadowCastingMode}, MotionVectorGenerationMode={assetDesc.rendererSettings.motionVectorGenerationMode}"); + sb.AppendLine($" Instancing Disabled Reason: {assetDesc.instancingDisabledReason}"); + + return sb.ToString(); + } +} diff --git a/Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs.meta new file mode 100644 index 00000000000..c2b60d0021e --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/Debug/VisualEffectAssetDescExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 189a4ada2fe646eebe01e28770f6e828 +timeCreated: 1771360894 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXAttributeExpression.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXAttributeExpression.cs index c043151bfa3..16143ae1d54 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXAttributeExpression.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXAttributeExpression.cs @@ -207,7 +207,7 @@ public override IEnumerable GetNeededAttributes() private string attributeName => m_attribute.name; public override VFXValueType valueType => m_attribute.type; public override VFXExpressionOperation operation => VFXExpressionOperation.ReadEventAttribute; - protected override int[] additionnalOperands => new int[] { (int)m_elementOffset, (int)m_attribute.type }; + internal override int[] additionalOperands => new int[] { (int)m_elementOffset, (int)m_attribute.type }; } #pragma warning restore 0659 diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstract.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstract.cs index 6d8ee652834..6e3a2edaa9b 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstract.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstract.cs @@ -411,7 +411,7 @@ public virtual string GetCodeString(string[] parents) // Get the operands for the runtime evaluation public Operands GetOperands(VFXExpressionGraph graph) { - var addOperands = additionnalOperands; + var addOperands = additionalOperands; if (parents.Length + addOperands.Length > 4) throw new Exception("Too many parameters for expression : " + this); @@ -470,8 +470,8 @@ public override bool Equals(object obj) if (GetHashCode() != other.GetHashCode()) return false; - var operands = additionnalOperands; - var otherOperands = other.additionnalOperands; + var operands = additionalOperands; + var otherOperands = other.additionalOperands; if (operands.Length != otherOperands.Length) return false; @@ -516,7 +516,7 @@ protected virtual int GetInnerHashCode() for (int i = 0; i < parents.Length; ++i) hash = (hash * 397) ^ parents[i].GetHashCode(); // 397 taken from resharper - var operands = additionnalOperands; + var operands = additionalOperands; for (int i = 0; i < operands.Length; ++i) hash = (hash * 397) ^ operands[i].GetHashCode(); @@ -529,7 +529,8 @@ protected virtual int GetInnerHashCode() private static readonly int[] k_EmptyOperands = Enumerable.Empty().ToArray(); - protected virtual int[] additionnalOperands { get { return k_EmptyOperands; } } + internal virtual int[] additionalOperands { get { return k_EmptyOperands; } } + public virtual T Get() { var value = (this as VFXValue); diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractNumericOperation.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractNumericOperation.cs index 6c81c355092..3fac8c4b50a 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractNumericOperation.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractNumericOperation.cs @@ -11,7 +11,7 @@ abstract class VFXExpressionNumericOperation : VFXExpression protected VFXExpressionNumericOperation(VFXExpression[] parents) : base(Flags.None, parents) { - m_additionnalOperands = new int[] { }; + m_additionalOperands = new int[] { }; } static private object[] ToObjectArray(float input) { return new object[] { input }; } @@ -75,17 +75,17 @@ static protected bool IsNumeric(VFXValueType type) } sealed public override VFXExpressionOperation operation { get { return m_Operation; } } - sealed protected override int[] additionnalOperands { get { return m_additionnalOperands; } } + sealed internal override int[] additionalOperands { get { return m_additionalOperands; } } protected override VFXExpression Reduce(VFXExpression[] reducedParents) { var newExpression = (VFXExpressionNumericOperation)base.Reduce(reducedParents); - newExpression.m_additionnalOperands = m_additionnalOperands.Select(o => o).ToArray(); + newExpression.m_additionalOperands = m_additionalOperands.Select(o => o).ToArray(); newExpression.m_Operation = m_Operation; return newExpression; } - protected int[] m_additionnalOperands; + protected int[] m_additionalOperands; protected VFXExpressionOperation m_Operation; } @@ -97,7 +97,7 @@ protected VFXExpressionUnaryNumericOperation(VFXExpression parent, VFXExpression { throw new ArgumentException("Incorrect VFXExpressionUnaryMathOperation"); } - m_additionnalOperands = new int[] { (int)parent.valueType }; + m_additionalOperands = new int[] { (int)parent.valueType }; m_Operation = operation; } @@ -160,7 +160,7 @@ protected VFXExpressionBinaryNumericOperation(VFXExpression parentLeft, VFXExpre throw new ArgumentException("Incorrect VFXExpressionBinaryFloatOperation (incompatible numeric type)"); } - m_additionnalOperands = new int[] { (int)parentLeft.valueType }; + m_additionalOperands = new int[] { (int)parentLeft.valueType }; m_Operation = operation; } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs index 776a2f7d64c..cb743342147 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs @@ -236,7 +236,7 @@ private static VFXValueType ToValueType() } static private readonly VFXValueType s_ValueType = ToValueType(); - protected override int[] additionnalOperands + internal override int[] additionalOperands { get { @@ -252,7 +252,7 @@ public VFXObjectValue(EntityId entityId, Mode mode, VFXValueType contentType) : m_ContentType = contentType; } - sealed protected override int[] additionnalOperands + sealed internal override int[] additionalOperands { get { diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionCamera.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionCamera.cs index f0c27f4f589..8950b3b8ba1 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionCamera.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionCamera.cs @@ -185,7 +185,7 @@ protected override VFXExpression Reduce(VFXExpression[] reducedParents) return newExpression; } - protected override int[] additionnalOperands { get { return new int[] { (int)m_BufferType }; } } + internal override int[] additionalOperands { get { return new int[] { (int)m_BufferType }; } } private VFXCameraBufferTypes m_BufferType; } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionExtractComponent.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionExtractComponent.cs index 560dc9ccc82..490b1be5934 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionExtractComponent.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionExtractComponent.cs @@ -16,10 +16,10 @@ public VFXExpressionExtractComponent(VFXExpression parent, int iChannel) } m_Operation = VFXExpressionOperation.ExtractComponent; - m_additionnalOperands = new int[] { iChannel, TypeToSize(parent.valueType) }; + m_additionalOperands = new int[] { iChannel, TypeToSize(parent.valueType) }; } - private int channel { get { return m_additionnalOperands[0]; } } + private int channel { get { return m_additionalOperands[0]; } } static private float GetChannel(Vector2 input, int iChannel) { diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionFlow.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionFlow.cs index 6792611a51a..5fef6fd8862 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionFlow.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionFlow.cs @@ -96,7 +96,7 @@ protected override VFXExpression Reduce(VFXExpression[] reducedParents) return newExpression; } - protected override int[] additionnalOperands { get { return new int[] { (int)type, (int)condition }; } } + internal override int[] additionalOperands { get { return new int[] { (int)type, (int)condition }; } } private VFXValueType type; private VFXCondition condition; } @@ -140,6 +140,6 @@ protected override VFXExpression Reduce(VFXExpression[] reducedParents) return base.Reduce(reducedParents); } - protected override int[] additionnalOperands { get { return new int[] { (int)parents[1].valueType }; } } + internal override int[] additionalOperands { get { return new int[] { (int)parents[1].valueType }; } } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionMesh.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionMesh.cs index 30df85f060f..d338fbcba76 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionMesh.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionMesh.cs @@ -43,7 +43,7 @@ public VFXExpressionVertexBufferFromSkinnedMeshRenderer() : this(VFXValue m_Frame; - protected sealed override int[] additionnalOperands { get { return new[] { (int)m_Frame }; } } + internal sealed override int[] additionalOperands { get { return new[] { (int)m_Frame }; } } protected override VFXExpression Reduce(VFXExpression[] reducedParents) { @@ -299,7 +299,7 @@ protected override VFXExpression Reduce(VFXExpression[] reducedParents) private VFXSkinnedMeshFrame m_Frame; VFXSkinnedMeshFrame IVFXExpressionSampleSkinnedMesh.frame => m_Frame; - protected override int[] additionnalOperands => new[] { (int)m_Frame }; //Not used but needed for default comparison of VFXExpressionSampleSkinnedMeshRendererFloat3 + internal override int[] additionalOperands => new[] { (int)m_Frame }; //Not used but needed for default comparison of VFXExpressionSampleSkinnedMeshRendererFloat3 public sealed override VFXExpressionOperation operation => VFXExpressionOperation.None; @@ -365,7 +365,7 @@ protected override VFXExpression Reduce(VFXExpression[] reducedParents) private VFXSkinnedMeshFrame m_Frame; VFXSkinnedMeshFrame IVFXExpressionSampleSkinnedMesh.frame => m_Frame; - protected override int[] additionnalOperands => new[] { (int)m_Frame }; //Not used but needed for default comparison of VFXExpressionSampleSkinnedMeshRendererFloat4 + internal override int[] additionalOperands => new[] { (int)m_Frame }; //Not used but needed for default comparison of VFXExpressionSampleSkinnedMeshRendererFloat4 sealed public override VFXExpressionOperation operation { get { return VFXExpressionOperation.None; } } @@ -556,7 +556,7 @@ public VFXExpressionRootBoneTransformFromSkinnedMeshRenderer(VFXExpression skinn private VFXSkinnedTransform m_Transform; private VFXSkinnedMeshFrame m_Frame; - protected sealed override int[] additionnalOperands { get { return new[] { (int)m_Frame, (int)m_Transform }; } } + internal sealed override int[] additionalOperands { get { return new[] { (int)m_Frame, (int)m_Transform }; } } public sealed override VFXExpressionOperation operation { get { return VFXExpressionOperation.RootBoneTransformFromSkinnedMeshRenderer; } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs index a62a73202aa..3232b012dec 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs @@ -86,7 +86,7 @@ public override VFXValue CopyExpression(Mode mode) public override VFXValueType valueType { get { return VFXValueType.CameraBuffer; } } - sealed protected override int[] additionnalOperands { get { return new int[] { (int)valueType }; } } + sealed internal override int[] additionalOperands { get { return new int[] { (int)valueType }; } } public override T Get() { diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/DataDescriptionWriterRegistry.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/DataDescriptionWriterRegistry.cs index 0efb797082f..f259dfb2748 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/DataDescriptionWriterRegistry.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/DataDescriptionWriterRegistry.cs @@ -37,7 +37,7 @@ public string FindDynamicDataTypeName(DataView dataView) } else { - return dataView.DataContainer.Name; + return dataView.DataContainer.IdentifierName; } } @@ -49,10 +49,7 @@ public string FindDataTypeName(DataView dataView) } else if (dataView.DataDescription is ValueData valueData) { - if (typeof(Texture).IsAssignableFrom(valueData.Type)) // TODO: Binding resources directly, instead of declaring and initializing - return $"{HlslCodeHelper.GetTypeName(valueData.Type)}"; - else - return $"static {HlslCodeHelper.GetTypeName(valueData.Type)}"; + return HlslCodeHelper.GetTypeName(valueData.Type); } else { diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/HlslCodeHelper.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/HlslCodeHelper.cs index 03dbb4c4202..0f4e08b8fb4 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/HlslCodeHelper.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/HlslCodeHelper.cs @@ -27,6 +27,7 @@ static HlslCodeHelper() { typeof(Matrix4x4), "float4x4" }, { typeof(Quaternion), "float4" }, { typeof(Texture2D), "texture2D" }, + { typeof(Texture), "texture2D" }, }; } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/IncludeFileShaderWriter.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/IncludeFileShaderWriter.cs index b6e431ece25..ffc0f3f1a0e 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/IncludeFileShaderWriter.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/CodeGeneration/IncludeFileShaderWriter.cs @@ -6,7 +6,6 @@ namespace Unity.GraphCommon.LowLevel.Editor class IncludeFileShaderWriter : ShaderWriter { private string m_GuardName; - private StringBuilder m_Builder = new(); public override void Begin(string name) { @@ -31,30 +30,43 @@ public override string End() string BuildGuardName(string name) { + Debug.Assert(ShaderBuilder.Length == 0); + + StringBuilder builder = new(); + void AddWord(ref int from, int to) + { + int length = to - from; + if (length > 0) + { + builder.Append('_'); + builder.Append(name.Substring(from, to - from).ToUpperInvariant()); + from = to; + } + } + + builder.Append("VFX"); + int index = 0; bool wasLowercase = false; - - Debug.Assert(ShaderBuilder.Length == 0); - m_Builder.Append("VFX"); - for (int i = 0; i <= name.Length; ++i) + for (int i = 0; i < name.Length; ++i) { - bool split = i == name.Length; - if (!split) + if (char.IsWhiteSpace(name[i])) { - bool isLowercase = char.IsLower(name[i]); - split = wasLowercase && !isLowercase; - wasLowercase = isLowercase; + AddWord(ref index, i); + index++; } - if (split) + + bool isLowercase = char.IsLower(name[i]); + if (wasLowercase && !isLowercase) { - m_Builder.Append('_'); - m_Builder.Append(name.Substring(index, i - index).ToUpperInvariant()); - index = i; + AddWord(ref index, i); } + wasLowercase = isLowercase; + } - string guardName = m_Builder.ToString(); - m_Builder.Clear(); - return guardName; + AddWord(ref index, name.Length); + + return builder.ToString(); } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/GraphVisualizerPasses.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/GraphVisualizerPasses.cs index ac04843b611..9f292f6b630 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/GraphVisualizerPasses.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/GraphVisualizerPasses.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Text; +using UnityEditor.VFX; using UnityEngine; namespace Unity.GraphCommon.LowLevel.Editor @@ -270,12 +271,11 @@ public bool Execute(ref CompilationContext context) foreach (var taskNode in context.graph.TaskNodes) { var taskLabel = GraphVisualizerPassesHelpers.TaskLabel(taskNode); - using (new GraphVisualizer.ClusterScope(taskNode.Id.Index, taskLabel, sb)) { foreach (var dataNode in taskNode.DataNodes) { - var dataLabel = $"{dataNode.Id} (R:"; + var dataLabel = $"{dataNode.Id}\n (R:"; foreach (var dataView in dataNode.ReadDataViews) { dataLabel += $"{dataView.Id} "; @@ -286,6 +286,14 @@ public bool Execute(ref CompilationContext context) dataLabel += $"{dataView.Id} "; } dataLabel += ")"; + string bindingInfo = ""; + foreach (var binding in dataNode.DataBindings) + { + bindingInfo += $"{binding.BindingDataKey}, "; + } + + + dataLabel += $"\n[{bindingInfo[..^2]}]"; GraphVisualizer.AddNode(sb, dataNode.Id.Index, dataLabel); } } @@ -310,15 +318,17 @@ static class GraphVisualizerPassesHelpers { public static string TaskLabel(TaskNode taskNode) { - string taskName; - if(taskNode.Task is Task task) - taskName = task.DebugName; - else if (taskNode.Task is ExpressionTask expressionTask) - taskName = $"{expressionTask.GetType().Name}-{expressionTask.Expression.ResultType.Name}"; - else if (taskNode.Task is TemplatedTask templatedTask) - taskName = $"TemplatedTask-{templatedTask.TemplateName}"; - else - taskName = taskNode.Task.GetType().Name; + string taskName = taskNode.Task switch + { + LegacyExpressionTask legacyExpressionTask => + $"{legacyExpressionTask.Expression.GetType().Name}", + Task task => task.DebugName, + ExpressionTask expressionTask => + $"{expressionTask.GetType().Name}-{expressionTask.Expression.ResultType.Name}", + TemplatedTask templatedTask => $"TemplatedTask-{templatedTask.TemplateName}", + _ => taskNode.Task.GetType().Name, + + }; var taskLabel = $"{taskName}({taskNode.Id})"; return taskLabel; diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/StructuredDataLayoutPass.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/StructuredDataLayoutPass.cs index c503e29efc4..2018477c707 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/StructuredDataLayoutPass.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/StructuredDataLayoutPass.cs @@ -145,7 +145,7 @@ public void ComputeOffsets() { m_ValueDataOffsets[offsetValueData.ValueData] = currentBucketOffset + offsetValueData.OffsetInBucket; } - currentBucketOffset += kAlignement; + currentBucketOffset += (bucket.CurrentSize + kAlignement - 1) / kAlignement * kAlignement; } m_TotalSize = currentBucketOffset; } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/TemplateCodeGenerationPass.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/TemplateCodeGenerationPass.cs index 0831b20d8e3..a958b33d936 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/TemplateCodeGenerationPass.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Compiler/Passes/TemplateCodeGenerationPass.cs @@ -35,7 +35,7 @@ public bool Execute(ref CompilationContext context) foreach (var dataContainer in context.graph.DataContainers) { - if (!IsResource(dataContainer.RootDataView.DataDescription)) + if (IsCompositeData(dataContainer.RootDataView.DataDescription)) { string sourceCode = GenerateContainerSourceCode(dataContainer, context); generatedCodeContainer.Add(dataContainer.Id, sourceCode); @@ -74,24 +74,30 @@ public bool Execute(ref CompilationContext context) string GenerateContainerSourceCode(DataContainer dataContainer, CompilationContext context) { - var containerName = dataContainer.Name; + var containerName = dataContainer.IdentifierName; + var rootDataView = dataContainer.RootDataView; m_IncludeFileShaderWriter.Begin(containerName); - if (m_DataWriter.TryGetDataDescriptionWriter(dataContainer.RootDataView.DataDescription, out var dataDescriptionWriter)) + if (m_DataWriter.TryGetDataDescriptionWriter(rootDataView.DataDescription, out var dataDescriptionWriter)) { - foreach (var resource in dataDescriptionWriter.GetUsedResources(dataContainer.Name, dataContainer.RootDataView)) + foreach (var resource in dataDescriptionWriter.GetUsedResources(containerName, rootDataView)) { if (resource.Item2 != null) { - m_IncludeFileShaderWriter.WriteLine($"{resource.Item1} {resource.Item2};"); + WriteVariableDeclaration(m_IncludeFileShaderWriter, resource.Item1, resource.Item2); m_IncludeFileShaderWriter.NewLine(); } } - dataDescriptionWriter.WriteDescription(m_IncludeFileShaderWriter, dataContainer.RootDataView, containerName, context); + dataDescriptionWriter.WriteDescription(m_IncludeFileShaderWriter, rootDataView, containerName, context); } return m_IncludeFileShaderWriter.End(); } + void WriteVariableDeclaration(ShaderWriter shaderWriter, string type, string name, bool isStatic = false) // TODO: maybe add an enum of modifiers and move to shader writer + { + shaderWriter.WriteLine($"{(isStatic ? "static " : "")}{type} {name};"); + } + string GenerateTemplatedTaskSourceCode_Compute(TaskNode taskNode, CompilationContext context) { TemplatedTask templatedTask = taskNode.Task as TemplatedTask; @@ -100,7 +106,7 @@ string GenerateTemplatedTaskSourceCode_Compute(TaskNode taskNode, CompilationCon m_ComputeShaderWriter.Begin(shaderName); - m_ComputeShaderWriter.WriteLine("#include \"Shaders/Data/ThreadData.hlsl\""); + m_ComputeShaderWriter.WriteLine("#include \"Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl\""); IncludeData(m_ComputeShaderWriter, taskNode, context); @@ -158,11 +164,16 @@ void IncludeData(ShaderWriter shaderWriter, TaskNode taskNode, CompilationContex foreach (var dataNode in taskNode.DataNodes) { - var dataDescription = dataNode.DataContainer.RootDataView.DataDescription; - if (!IsResource(dataDescription)) + var rootDataView = dataNode.DataContainer.RootDataView; + var dataDescription = rootDataView.DataDescription; + if (!IsCompositeData(dataDescription)) + { + shaderWriter.NewLine(); + var dataTypename = m_DataWriter.FindDataTypeName(rootDataView); + WriteVariableDeclaration(shaderWriter, dataTypename, dataNode.DataContainer.Name); + } + else if (m_DataWriter.TryGetDataDescriptionWriter(dataDescription, out var dataDescriptionWriter)) { - m_DataWriter.TryGetDataDescriptionWriter(dataDescription, out var dataDescriptionWriter); - shaderWriter.NewLine(); //shaderWriter.IncludeFile($"{dataNode.DataContainer.Name}.hlsl"); shaderWriter.WriteLine($"// Begin {dataNode.DataContainer.Name}"); @@ -171,6 +182,10 @@ void IncludeData(ShaderWriter shaderWriter, TaskNode taskNode, CompilationContex dataDescriptionWriter.UndefineResourceUsage(shaderWriter, dataNode.UsedDataViewsRoot, dataNode.ReadDataViewsRoot, dataNode.WrittenDataViewsRoot); shaderWriter.WriteLine($"// End {dataNode.DataContainer.Name}"); } + else + { + Debug.Assert(false, "Data node not handled"); + } } } @@ -254,25 +269,39 @@ void LocateDataView(DataView dataView, ref DataView usedDataView, ref DataView r shaderWriter.NewLine(); bool hasView = false; - string sourceName = m_DataWriter.FindDataTypeName(dataView); + string typeName = m_DataWriter.FindDataTypeName(dataView); string bindingName = dataBinding.BindingDataKey.ToString(); - if (m_DataWriter.TryGetDataDescriptionWriter(dataDescription, out var dataDescriptionWriter)) + if (IsCompositeData(dataDescription)) { - hasView = dataDescriptionWriter.WriteView(shaderWriter, usedDataView, readDataView, writtenDataView, bindingName, sourceName, context); + if (m_DataWriter.TryGetDataDescriptionWriter(dataDescription, out var dataDescriptionWriter)) + { + hasView = dataDescriptionWriter.WriteView(shaderWriter, usedDataView, readDataView, writtenDataView, bindingName, typeName, context); + } } + if (hasView) { m_DataBindingsWithView.Add(dataBinding.Id); } - else + else if (BindingNeedsRemapping(dataBinding)) { - shaderWriter.WriteLine($"{sourceName} {bindingName};"); + bool isStatic = !IsCompositeData(dataDescription); + WriteVariableDeclaration(shaderWriter, typeName, bindingName, isStatic); } + } var attributeSourceManager = context.data.GetOrCreate(); attributeSourceManager.Clear(); } + bool BindingNeedsRemapping(DataBinding dataBinding) + { + var dataView = dataBinding.DataView; + var containerName = dataView.DataContainer.Name; + var bindingName = dataBinding.BindingDataKey.ToString(); + return !dataView.IsRoot || containerName != bindingName; + } + void WriteProcessBlocksDeclaration(ShaderWriter shaderWriter, TemplatedTask templatedTask) { shaderWriter.Indent(); @@ -293,6 +322,9 @@ void WriteProcessBlocksDeclaration(ShaderWriter shaderWriter, TemplatedTask temp void ForwardDeclarations(ShaderWriter shaderWriter, TemplatedTask templatedTask) { shaderWriter.NewLine(); + shaderWriter.Define("VFX_LOCAL_SPACE", "1"); + shaderWriter.IncludeFile("Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl"); + shaderWriter.IncludeFile("Packages/com.unity.visualeffectgraph/Shaders/VFXCommon.hlsl"); WriteProcessBlocksDeclaration(shaderWriter, templatedTask); shaderWriter.Write(";"); shaderWriter.NewLine(); @@ -301,7 +333,7 @@ void ForwardDeclarations(ShaderWriter shaderWriter, TemplatedTask templatedTask) void IncludeTemplateFile(ShaderWriter shaderWriter, string templateName) { shaderWriter.NewLine(); - shaderWriter.IncludeFile($"Shaders/Templates/{templateName}.hlsl"); // TODO: Template should have full path + shaderWriter.IncludeFile($"Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/{templateName}.hlsl"); // TODO: Template should have full path } void GenerateEntryPoint_Compute(ComputeShaderWriter computeShaderWriter, TaskNode taskNode, @@ -311,7 +343,7 @@ void GenerateEntryPoint_Compute(ComputeShaderWriter computeShaderWriter, TaskNod uint threadCount = 64u; computeShaderWriter.WriteMainFunction(threadCount, 1, 1); computeShaderWriter.OpenBlock(); - InitMainData(computeShaderWriter, taskNode, context); + InitMainData(computeShaderWriter, taskNode); computeShaderWriter.NewLine(); computeShaderWriter.WriteLine("// Template entry point"); computeShaderWriter.WriteLine("ThreadData threadData;"); @@ -325,7 +357,7 @@ void GenerateEntryPoints_Rendering(RenderingShaderWriter renderingShaderWriter, renderingShaderWriter.NewLine(); renderingShaderWriter.WriteVertexFunction(); renderingShaderWriter.OpenBlock(); - InitMainData(renderingShaderWriter, taskNode, context); + InitMainData(renderingShaderWriter, taskNode); renderingShaderWriter.NewLine(); renderingShaderWriter.WriteLine("return vert(id, input);"); renderingShaderWriter.CloseBlock(); @@ -333,19 +365,25 @@ void GenerateEntryPoints_Rendering(RenderingShaderWriter renderingShaderWriter, renderingShaderWriter.NewLine(); renderingShaderWriter.WriteFragmentFunction(); renderingShaderWriter.OpenBlock(); - InitMainData(renderingShaderWriter, taskNode, context); + InitMainData(renderingShaderWriter, taskNode); renderingShaderWriter.NewLine(); renderingShaderWriter.WriteLine("return frag(input);"); renderingShaderWriter.CloseBlock(); } - void InitMainData(ShaderWriter shaderWriter, TaskNode taskNode, CompilationContext context) + void InitMainData(ShaderWriter shaderWriter, TaskNode taskNode) + { + InitContainers(shaderWriter, taskNode); + InitBindings(shaderWriter, taskNode); + } + + void InitContainers(ShaderWriter shaderWriter, TaskNode taskNode) { bool initContainers = false; foreach (var dataNode in taskNode.DataNodes) { var dataContainer = dataNode.DataContainer; - if (!IsResource(dataContainer.RootDataView.DataDescription)) + if (IsCompositeData(dataContainer.RootDataView.DataDescription)) { shaderWriter.NewLine(); if (!initContainers) @@ -354,46 +392,75 @@ void InitMainData(ShaderWriter shaderWriter, TaskNode taskNode, CompilationConte initContainers = true; } - var typeName = dataContainer.Name; + var typeName = dataContainer.IdentifierName; var variableName = char.ToLowerInvariant(typeName[0]) + typeName.Substring(1); shaderWriter.WriteLine($"{typeName} {variableName};"); shaderWriter.WriteLine($"{variableName}.Init();"); } } + } + void InitBindings(ShaderWriter shaderWriter, TaskNode taskNode) + { bool initBindings = false; foreach (var dataBinding in taskNode.DataBindings) { - if (dataBinding.DataView.DataDescription is ConstantValueData valueData) - { - if (typeof(Texture).IsAssignableFrom(valueData.Type)) - continue; - } - - shaderWriter.NewLine(); if (!initBindings) { shaderWriter.WriteLine("// Init bindings"); initBindings = true; } + var dataDescription = dataBinding.DataView.DataDescription; bool hasView = m_DataBindingsWithView.Contains(dataBinding.Id); - shaderWriter.Indent(); - shaderWriter.Write(dataBinding.BindingDataKey.ToString()); - shaderWriter.Write(hasView ? ".Init(" : " = "); - if (dataBinding.DataView.DataDescription is ConstantValueData constantValueData) + if (hasView) { - shaderWriter.Write(HlslCodeHelper.GetValueString(constantValueData.ObjectValue)); + WriteBindingInit(shaderWriter, dataBinding); + shaderWriter.NewLine(); } - else + else if (BindingNeedsRemapping(dataBinding)) + { + WriteBindingRemap(shaderWriter, dataBinding); + shaderWriter.NewLine(); + } + } + } + + void WriteBindingInit(ShaderWriter shaderWriter, DataBinding dataBinding) + { + shaderWriter.Indent(); + shaderWriter.Write(dataBinding.BindingDataKey.ToString()); + shaderWriter.Write(".Init("); + WriteSubdataPath(shaderWriter, dataBinding.DataNode.DataContainer, dataBinding.DataView); + shaderWriter.WriteLine(");", ShaderWriter.WriteLineOptions.NoIndent); + } + + void WriteBindingRemap(ShaderWriter shaderWriter, DataBinding dataBinding) + { + shaderWriter.Indent(); + shaderWriter.Write(dataBinding.BindingDataKey.ToString()); + shaderWriter.Write(" = "); + WriteSubdataPath(shaderWriter, dataBinding.DataNode.DataContainer, dataBinding.DataView); + shaderWriter.WriteLine(";", ShaderWriter.WriteLineOptions.NoIndent); + } + + void WriteSubdataPath(ShaderWriter shaderWriter, DataContainer container, DataView toDataView) + { + if (toDataView.DataDescription is ConstantValueData constantValueData) + { + shaderWriter.Write(HlslCodeHelper.GetValueString(constantValueData.ObjectValue)); + } + else + { + var rootDataView = container.RootDataView; + var containerName = container.IdentifierName; + var variableName = containerName; + if (IsCompositeData(rootDataView.DataDescription)) { - var container = dataBinding.DataNode.DataContainer; - var containerName = container.Name; - var variableName = char.ToLowerInvariant(containerName[0]) + containerName.Substring(1); - shaderWriter.Write(variableName); - WriteSubdataPath(shaderWriter, container.RootDataView, dataBinding.DataView); + variableName = char.ToLowerInvariant(variableName[0]) + variableName.Substring(1); } - shaderWriter.WriteLine(hasView ? ");" : ";", ShaderWriter.WriteLineOptions.NoIndent); + shaderWriter.Write(variableName); + WriteSubdataPath(shaderWriter, rootDataView, toDataView); } } @@ -427,7 +494,7 @@ void GenerateSnippetFunctions(ShaderWriter shaderWriter, TemplatedTask templated shaderWriter.CloseBlock(); } - bool IsResource(IDataDescription dataDescription) => dataDescription is ValueData; // TODO: Temp + bool IsCompositeData(IDataDescription dataDescription) => dataDescription is not ValueData; // TODO: Temp } class GeneratedCodeContainer diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/AttributeDataDescriptionWriter.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/AttributeDataDescriptionWriter.cs index 32e055d9ef1..8735bc01158 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/AttributeDataDescriptionWriter.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/AttributeDataDescriptionWriter.cs @@ -5,7 +5,7 @@ class AttributeDataDescriptionWriter : IDataDescriptionWriter { public void WriteDescription(ShaderWriter shaderWriter, DataView dataView, AttributeData attributeData, string name, CompilationContext context) { - shaderWriter.IncludeFile("Packages/com.unity.vfxgraph/Shaders/Data/AttributeBuffer.hlsl"); + shaderWriter.IncludeFile("Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl"); shaderWriter.NewLine(); shaderWriter.WriteLine($"struct {name}"); @@ -72,7 +72,7 @@ public bool WriteView(ShaderWriter shaderWriter, DataView usedDataView, DataView // That would allow multiple attribute sources for each attribute buffer, overloading the methods // If detached, the attribute set to be used would be included on each attributeSource (.AttributeSet) var attributeSourceTypename = attributeSource.ToString(); - if (readDataView.Children.Count > 0) + //if (readDataView.Children.Count > 0) { shaderWriter.NewLine(); shaderWriter.WriteLine($"void LoadData(out {attributeSourceTypename} {variableName}, uint index)"); @@ -85,7 +85,7 @@ public bool WriteView(ShaderWriter shaderWriter, DataView usedDataView, DataView } shaderWriter.CloseBlock(); } - if (writtenDataView.Children.Count > 0) + //if (writtenDataView.Children.Count > 0) { shaderWriter.NewLine(); shaderWriter.WriteLine($"void StoreData({attributeSourceTypename} {variableName}, uint index)"); diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/StructuredDataDescriptionWriter.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/StructuredDataDescriptionWriter.cs index 02dc7d8efbf..56c2660e17e 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/StructuredDataDescriptionWriter.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Data/DescriptionWriter/StructuredDataDescriptionWriter.cs @@ -8,6 +8,8 @@ class StructuredDataDescriptionWriter : IDataDescriptionWriter public void WriteDescription(ShaderWriter shaderWriter, DataView dataView, StructuredData structuredData, string name, CompilationContext context) { + shaderWriter.IncludeFile("Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl"); + shaderWriter.WriteLine($"struct {name}"); shaderWriter.OpenBlock(); shaderWriter.WriteLine("VFXByteAddressBuffer buffer;"); diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataContainer.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataContainer.cs index ddc93286aaf..00307ed1b64 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataContainer.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataContainer.cs @@ -82,6 +82,11 @@ public DataContainerInfo(DataContainerId id, string name, DataViewId rootDataVie /// public string Name => m_Graph.Valid ? m_Info.Name : null; + /// + /// Gets the name of this container. Returns null if the graph is not valid. + /// + public string IdentifierName => Name.Replace(' ', '_'); + /// /// Gets the root DataView of this container. /// diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataNode.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataNode.cs index e6ad204c4df..7b36d3f1508 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataNode.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataNode.cs @@ -104,6 +104,8 @@ public DataNodeInfo(DataNodeId id, TaskNodeId taskNodeId, DataContainerId dataCo /// public DataView UsedDataViewsRoot => m_Graph.Ref.GetUsedDataViews(Id); + public DataBindingEnumerable> DataBindings => m_Graph.Ref.GetDataBindings(Id); + /// /// Gets the data views used by this data node, as an enumerable. /// @@ -128,7 +130,7 @@ public DataNodeInfo(DataNodeId id, TaskNodeId taskNodeId, DataContainerId dataCo /// Gets the data views written by this data node, as an enumerable. /// public DataViewFlatTreeEnumerable WrittenDataViews => WrittenDataViewsRoot.Flat; - + internal DataNode(IIndexable, DataNode> nodeConverter, GraphNode node, IReadOnlyGraph graph, DataNodeInfo info) { m_NodeConverter = nodeConverter; diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataView.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataView.cs index da3eab30ba6..8b31bf3da86 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataView.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/DataView.cs @@ -109,6 +109,8 @@ public DataView? Parent /// public DataView Root => m_Source[m_Node.Root]; + public bool IsRoot => Id.IsValid && !Parent.HasValue; + /// /// Gets the IDataDescription associated with this data view. /// Returns null if the graph is not valid. diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/IGraph.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/IGraph.cs index 4907442933f..8a723a4a313 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/IGraph.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/IGraph.cs @@ -80,6 +80,16 @@ namespace Unity.GraphCommon.LowLevel.Editor /// DataBindingEnumerable> GetDataBindings(TaskNodeId taskNodeId); + /// + /// Retrieves an enumerable collection of data bindings associated with a specified data node. + /// + /// The identifier of the data node for which data bindings are to be retrieved. + /// + /// A containing the data bindings + /// related to the specified . + /// + DataBindingEnumerable> GetDataBindings(DataNodeId dataNodeId); + /// /// Retrieves an enumerable collection of data views used in the specified data node. /// diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/TaskGraph.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/TaskGraph.cs index 666fc6ef8f6..f4420518d1d 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/TaskGraph.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Graph/TaskGraph.cs @@ -258,8 +258,9 @@ public void BindData(TaskNodeId taskNodeId, IDataKey bindingKey, DataViewId data } else if (usageFromTask != BindingUsage.Unknown && usage != usageFromTask) { - Debug.LogWarning($"Provided binding usage {usage} doesn't match binding usage {usageFromTask} from task node"); - return; + //TODO: Let's skip usage validation for now + //Debug.LogWarning($"Provided binding usage {usage} doesn't match binding usage {usageFromTask} from task node"); + //return; } if (usage == BindingUsage.Unknown) { @@ -425,6 +426,15 @@ public DataBindingEnumerable> GetDataBindings(TaskN return new(DataBindings, subEnumerable); } + /// + public DataBindingEnumerable> GetDataBindings(DataNodeId dataNodeId) + { + var container = DataNodeToDataBindings.Data; + SubEnumerable subEnumerable = new(container, dataNodeId.Index, container[dataNodeId.Index].Count); + return new(DataBindings, subEnumerable); + } + + /// public DataView GetUsedDataViews(DataNodeId dataNodeId) { diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/SubtaskDescription.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/SubtaskDescription.cs index 27ac1b1d7c1..9990a60783f 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/SubtaskDescription.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/SubtaskDescription.cs @@ -15,7 +15,7 @@ namespace Unity.GraphCommon.LowLevel.Editor /// /// The list of expressions associated with the subtask, each paired with a data binding key. /// - public List<(IDataKey, IExpression)> Expressions { get; set; } + public List ExpressionBindingKeys { get; set; } /// /// The actual task description. diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/TemplatedTask.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/TemplatedTask.cs index dac645dad9f..9cc6b140bd4 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/TemplatedTask.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphCommon/Task/TemplatedTask.cs @@ -177,8 +177,7 @@ public TemplatedTaskBinding(System.Type dataType, BindingUsagePaths usagePaths) /// /// List of all the expressions used by the task. /// - public List<(IDataKey bindingKey, IExpression expression)> Expressions; - + public List ExpressionBindingKeys; } /// @@ -189,7 +188,7 @@ public TemplatedTaskBinding(System.Type dataType, BindingUsagePaths usagePaths) readonly Dictionary m_BindingToUsage = new(); readonly Dictionary m_AttributeKeyMappings; - readonly Dictionary m_Expressions = new(); + readonly List m_ExpressionBindingKeys = new(); /// /// Gets the name of the template associated with the task. @@ -216,9 +215,6 @@ public TemplatedTaskBinding(System.Type dataType, BindingUsagePaths usagePaths) /// public IEnumerable> AttributeKeyMappings => m_AttributeKeyMappings; - /// - public IEnumerable> Expressions => m_Expressions; - //TODO: These two keys are legacy and should be moved somewhere else. /// /// Unique data key that represents the graph values data used by this task. @@ -251,9 +247,9 @@ public TemplatedTask(string templateName, TemplatedTaskArgs args, bool isCompute m_AttributeKeyMappings = args.AttributeKeyMappings != null ? new(args.AttributeKeyMappings) : new(); - if (args.Expressions != null) + if (args.ExpressionBindingKeys != null) { - AddExpressions(args.Expressions); + AddExpressionsBindingKeys(args.ExpressionBindingKeys); } if (args.Bindings != null) @@ -316,10 +312,9 @@ public TemplatedTask(string templateName, TemplatedTaskArgs args, bool isCompute } } } - AddExpressions(block.Expressions); + AddExpressionsBindingKeys(block.ExpressionBindingKeys); } - - foreach (var (bindingKey, _) in Expressions) + foreach (var bindingKey in m_ExpressionBindingKeys) { var bindingUsagePath = new BindingUsagePaths(); bindingUsagePath.Read.Add(DataPath.Empty); @@ -362,11 +357,11 @@ public bool GetBindingUsage(IDataKey dataKey, out BindingUsage usage) return true; } - void AddExpressions(List<(IDataKey, IExpression)> expressions) + void AddExpressionsBindingKeys(List expressionBindingKeys) { - foreach (var (bindingKey, expression) in expressions) + foreach (var bindingKey in expressionBindingKeys) { - m_Expressions.TryAdd(bindingKey, expression); // TODO: What to do on name collision + m_ExpressionBindingKeys.Add(bindingKey); } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Models/VFXAttributesManager.cs b/Packages/com.unity.visualeffectgraph/Editor/Models/VFXAttributesManager.cs index a46504454cf..aadf091cbe9 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Models/VFXAttributesManager.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Models/VFXAttributesManager.cs @@ -257,9 +257,15 @@ public static IEnumerable GetBuiltInNamesAndCombination(bool includeVari } } + static Dictionary s_NewCompilerAttributes = new(); public static Unity.GraphCommon.LowLevel.Editor.Attribute ConvertToNewCompiler(VFXAttribute vfxAttribute) { - return new Unity.GraphCommon.LowLevel.Editor.Attribute(vfxAttribute.name, vfxAttribute.value.GetContent()); + if (!s_NewCompilerAttributes.TryGetValue(vfxAttribute, out var attribute)) + { + attribute = new Unity.GraphCommon.LowLevel.Editor.Attribute(vfxAttribute.name, vfxAttribute.value.GetContent()); + s_NewCompilerAttributes.Add(vfxAttribute, attribute); + } + return attribute; } /****************************************************************/ diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/ParticleSystemDataDescriptionWriter.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/ParticleSystemDataDescriptionWriter.cs index 55a49af9f6d..951f84ecde3 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/ParticleSystemDataDescriptionWriter.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/ParticleSystemDataDescriptionWriter.cs @@ -20,14 +20,14 @@ public void WriteDescription(ShaderWriter shaderWriter, DataView dataView, Parti { var layoutCompilationData = context.data.Get(); - shaderWriter.IncludeFile("Packages/com.unity.vfxgraph/Shaders/Data/ParticleSystemData.hlsl"); + shaderWriter.IncludeFile("Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl"); var attributeData = dataView.FindSubData(ParticleData.AttributeDataKey, out var attributeDataView) ? attributeDataView.DataDescription as AttributeData : null; var deadlist = dataView.FindSubData(ParticleData.DeadlistKey, out var deadlistDataView) ? deadlistDataView.DataDescription : null; if (deadlist != null) { - shaderWriter.IncludeFile("Packages/com.unity.vfxgraph/Shaders/Data/DeadListData.hlsl"); + shaderWriter.IncludeFile("Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl"); } if (attributeData != null) diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/SpawnerDataDescriptionWriter.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/SpawnerDataDescriptionWriter.cs index a0ef456a6e0..c25ff538946 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/SpawnerDataDescriptionWriter.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Data/DescriptionWriter/SpawnerDataDescriptionWriter.cs @@ -5,9 +5,9 @@ namespace UnityEditor.VFX { class SpawnerDataDescriptionWriter : IDataDescriptionWriter { - public void WriteDescription(ShaderWriter shaderWriter, DataView dataView, SpawnData structuredData, string name, CompilationContext context) + public void WriteDescription(ShaderWriter shaderWriter, DataView dataView, SpawnData spawnData, string name, CompilationContext context) { - shaderWriter.IncludeFile("Packages/com.unity.vfxgraph/Shaders/Data/SpawnerData.hlsl"); + shaderWriter.IncludeFile("Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl"); shaderWriter.NewLine(); shaderWriter.WriteLine($"struct {name}"); diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs deleted file mode 100644 index 766d8dd2fec..00000000000 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System.Text; - -namespace UnityEditor.VFX -{ - static class VFXGraphLegacyCompilationOutputExtensions - { - internal static string ToDetailedString(this VfxGraphLegacyCompilationOutput output) - { - var sb = new StringBuilder(); - - sb.AppendLine("VFXGraphLegacyCompilationOutput:"); - sb.AppendLine($" Version: {output.Version}"); - sb.AppendLine($" Compilation Mode: {output.CompilationMode}"); - - sb.AppendLine(" Expression Sheet:"); - if (output.SheetExpressions != null) - { - sb.AppendLine($" Expressions Count: {output.SheetExpressions.Count}"); - for (int i = 0; i < output.SheetExpressions.Count; i++) - { - var expr = output.SheetExpressions[i]; - sb.AppendLine($" Expression {i}: {expr.op}"); - } - } - else - { - sb.AppendLine(" Expressions: null"); - } - - if (output.SheetExpressionsPerSpawnEventAttribute != null) - { - sb.AppendLine($" PerSpawnEventAttribute Count: {output.SheetExpressionsPerSpawnEventAttribute.Count}"); - for (int i = 0; i < output.SheetExpressionsPerSpawnEventAttribute.Count; i++) - { - var expr = output.SheetExpressionsPerSpawnEventAttribute[i]; - sb.AppendLine($" Expression {i}: {expr.op}"); - } - } - else - { - sb.AppendLine(" PerSpawnEventAttribute: null"); - } - - if (output.SheetValues != null) - { - sb.AppendLine($" Values Count: {output.SheetValues.Count}"); - for (int i = 0; i < output.SheetValues.Count; i++) - { - var value = output.SheetValues[i]; - sb.AppendLine($" Value {i}: {value} - {value.expressionIndex}"); - } - } - else - { - sb.AppendLine(" Values: null"); - } - - if (output.SheetExposed != null) - { - sb.AppendLine($" Exposed Count: {output.SheetExposed.Count}"); - for (int i = 0; i < output.SheetExposed.Count; i++) - { - var value = output.SheetExposed[i]; - sb.AppendLine($" Exposed Value {i}: {value.mapping}"); - } - } - else - { - sb.AppendLine(" Exposed Values: null"); - - } - - if (output.SystemDescs != null) - { - sb.AppendLine(" System Descriptions:"); - for (int i = 0; i < output.SystemDescs.Count; i++) - { - var systemDesc = output.SystemDescs[i]; - sb.AppendLine($" System {i}:"); - sb.AppendLine($" Name: {systemDesc.name}"); - sb.AppendLine($" Type: {systemDesc.type}"); - sb.AppendLine($" Flags: {systemDesc.flags}"); - sb.AppendLine($" Layer: {systemDesc.layer}"); - - if (systemDesc.buffers != null) - { - sb.AppendLine($" Buffers Count: {systemDesc.buffers.Length}"); - for (int j = 0; j < systemDesc.buffers.Length; j++) - { - var buffer = systemDesc.buffers[j]; - sb.AppendLine($" Buffer {j}: Name={buffer.name}, Index={buffer.index}"); - } - } - else - { - sb.AppendLine(" Buffers: null"); - } - - if (systemDesc.values != null) - { - sb.AppendLine($" Values Count: {systemDesc.values.Length}"); - for (int j = 0; j < systemDesc.values.Length; j++) - { - var value = systemDesc.values[j]; - sb.AppendLine($" Value {j}: Name={value.name}, Index={value.index}"); - } - } - else - { - sb.AppendLine(" Values: null"); - } - - if (systemDesc.tasks != null) - { - sb.AppendLine($" Tasks Count: {systemDesc.tasks.Length}"); - for (int j = 0; j < systemDesc.tasks.Length; j++) - { - var task = systemDesc.tasks[j]; - sb.AppendLine( - $" Task {j}: Type={task.type}, ShaderSourceIndex={task.shaderSourceIndex}"); - sb.AppendLine($" Processor: {task.processor?.GetType().Name ?? "None"}"); - - //Add task buffers mapping - if (task.buffers != null) - { - sb.AppendLine($" Task Buffers Count: {task.buffers.Length}"); - for (int k = 0; k < task.buffers.Length; k++) - { - var buffer = task.buffers[k]; - sb.AppendLine($" Task Buffer {k}: Name={buffer.name}, Index={buffer.index}"); - } - } - else - { - sb.AppendLine(" Task Buffers: null"); - } - - if (task.values != null) - { - sb.AppendLine($" Task Values Count: {task.values.Length}"); - for (int k = 0; k < task.values.Length; k++) - { - var value = task.values[k]; - sb.AppendLine($" Task Value {k}: Name={value.name}, Index={value.index}"); - } - } - else - { - sb.AppendLine(" Task Values: null"); - } - } - } - } - } - else - { - sb.AppendLine(" System Descriptions: null"); - } - - if (output.EventDescs != null) - { - sb.AppendLine(" Event Descriptions:"); - for (int i = 0; i < output.EventDescs.Count; i++) - { - var eventDesc = output.EventDescs[i]; - sb.AppendLine($" Event {i}: Name={eventDesc.name}"); - sb.AppendLine($" Init Systems Count: {eventDesc.initSystems?.Length ?? 0}"); - sb.AppendLine($" Start Systems Count: {eventDesc.startSystems?.Length ?? 0}"); - sb.AppendLine($" Stop Systems Count: {eventDesc.stopSystems?.Length ?? 0}"); - } - } - else - { - sb.AppendLine(" Event Descriptions: null"); - } - - if (output.GpuBufferDescs != null) - { - sb.AppendLine(" GPU Buffer Descriptions:"); - for (int i = 0; i < output.GpuBufferDescs.Count; i++) - { - var bufferDesc = output.GpuBufferDescs[i]; - sb.AppendLine($" Buffer {i}: Target={bufferDesc.target}, Size={bufferDesc.size}, Capacity={bufferDesc.capacity}, Stride={bufferDesc.stride}"); - if (bufferDesc.layout != null && bufferDesc.layout.Length > 0) - { - sb.AppendLine($" Layout elements Count: {bufferDesc.layout.Length}"); - foreach (var layoutDesc in bufferDesc.layout) - { - sb.AppendLine($" Name={layoutDesc.name}, Type={layoutDesc.type}, Offset (bucket, structure, element) ={layoutDesc.offset.bucket}, {layoutDesc.offset.structure}, {layoutDesc.offset.element}"); - } - } - } - } - else - { - sb.AppendLine(" GPU Buffer Descriptions: null"); - } - - if (output.CpuBufferDescs != null) - { - sb.AppendLine(" CPU Buffer Descriptions:"); - for (int i = 0; i < output.CpuBufferDescs.Count; i++) - { - var bufferDesc = output.CpuBufferDescs[i]; - sb.AppendLine($" Buffer {i}: Capacity={bufferDesc.capacity}, Stride={bufferDesc.stride}"); - } - } - else - { - sb.AppendLine(" CPU Buffer Descriptions: null"); - } - - if (output.TemporaryBufferDescs != null) - { - sb.AppendLine(" Temporary GPU Buffer Descriptions:"); - for (int i = 0; i < output.TemporaryBufferDescs.Count; i++) - { - var tempBufferDesc = output.TemporaryBufferDescs[i]; - var bufferDesc = tempBufferDesc.desc; - sb.AppendLine($" Buffer {i}: FrameCount={tempBufferDesc.frameCount},Target={bufferDesc.target}, Capacity={bufferDesc.capacity}, Size={bufferDesc.size}, Stride={bufferDesc.stride}"); - } - } - else - { - sb.AppendLine(" Temporary GPU Buffer Descriptions: null"); - } - - if (output.ShaderSourceDescs != null) - { - sb.AppendLine(" Shader Source Descriptions:"); - for (int i = 0; i < output.ShaderSourceDescs.Count; i++) - { - var shaderDesc = output.ShaderSourceDescs[i]; - sb.AppendLine($" Shader {i}: Name={shaderDesc.name}, Compute={shaderDesc.compute}"); - // Be careful with large shader sources! - // sb.AppendLine($" Shader {i} Source:\n{shaderDesc.source}\n"); - } - } - else - { - sb.AppendLine(" Shader Source Descriptions: null"); - } - - if (output.Objects != null) - { - sb.AppendLine(" Objects:"); - for (int i = 0; i < output.Objects.Count; ++i) - { - var obj = output.Objects[i]; - sb.AppendLine($" Object {i}: Name={obj?.name}, Type={obj?.GetType().Name}"); - } - } - else - { - sb.AppendLine(" Objects: null"); - } - - return sb.ToString(); - } - } -} diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs.meta deleted file mode 100644 index 3d44dfb399b..00000000000 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyCompilationOutputExtensions.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 743861908f7281046add6c1c7002c71f \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyOutputPass.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyOutputPass.cs index a8bff421ec2..75232447487 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyOutputPass.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyOutputPass.cs @@ -81,56 +81,6 @@ class VfxGraphLegacyOutputPass : DataGenerationPass parentExpressionIndices); - - struct ExpressionHandler - { - VFXExpressionOperation operation; - OnAddExpression onAddExpression; - public ExpressionHandler(VFXExpressionOperation operation, OnAddExpression onAddExpression) - { - this.operation = operation; - this.onAddExpression = onAddExpression; - } - - public uint AddExpression(VfxGraphLegacyOutputPass pass, IExpression expression, List parentExpressionIndices) - { - return onAddExpression(pass, expression, operation, parentExpressionIndices); - } - } - static uint AddOperationExpression(VfxGraphLegacyOutputPass pass, IExpression expression, VFXExpressionOperation op, List parentExpressionIndices) - { - Type resultType = expression.ResultType; - var valueType = GetVFXValueTypeFromType(resultType); - int[] data = { -1, -1, -1 }; - for(int i = 0; i < parentExpressionIndices.Count; i++) - data[i] = (int)parentExpressionIndices[ i]; - return pass.AddExpression(op, data[0], data[1], data[2], (int)valueType); - } - - static uint AddBuiltinExpression(VfxGraphLegacyOutputPass pass, IExpression expression, VFXExpressionOperation op, List parentExpressionIndices) - { - int[] data = { -1, -1, -1, -1 }; - for(int i = 0; i < parentExpressionIndices.Count; i++) - data[i] = (int)parentExpressionIndices[ i]; - return pass.AddExpression(op, data[0], data[1], data[2], data[3]); - } - - static uint AddValueExpression(VfxGraphLegacyOutputPass pass, IExpression expression, VFXExpressionOperation op, List parentExpressionIndices) - { - return pass.AddValueExpression((IValueExpression)expression); - } - - ExpressionHandler _valueExpressionHandler = new(VFXExpressionOperation.Value, AddValueExpression); - - static readonly Dictionary s_PredefinedExpressions = new() - { - { typeof(DeltaTimeExpression), new ExpressionHandler(VFXExpressionOperation.DeltaTime, AddBuiltinExpression)}, - { typeof(TotalTimeExpression), new ExpressionHandler(VFXExpressionOperation.TotalTime, AddBuiltinExpression)}, - { typeof(CosineExpression), new ExpressionHandler(VFXExpressionOperation.Cos, AddOperationExpression)}, - { typeof(AddExpression), new ExpressionHandler(VFXExpressionOperation.Add, AddOperationExpression)}, - }; - readonly Dictionary m_GpuBufferDescIndices = new(); readonly Dictionary m_CpuBufferDescIndices = new(); readonly Dictionary m_ValuesExpressionIndices = new(); @@ -140,7 +90,7 @@ static uint AddValueExpression(VfxGraphLegacyOutputPass pass, IExpression expres public VfxGraphLegacyCompilationOutput Execute(ref CompilationContext context) { VfxGraphLegacyCompilationOutput output = new(); - + Cleanup(); m_currentOutput = output; m_currentOutput.Version = 7; @@ -163,39 +113,29 @@ public VfxGraphLegacyCompilationOutput Execute(ref CompilationContext context) return output; } - IValueExpression EvaluateExpressionRecursively(IExpression expression) - { - List parentExpressionValues = new(); - foreach (var parentExpression in expression.Parents) - { - var parentExpressionValue = EvaluateExpressionRecursively(parentExpression); - parentExpressionValues.Add(parentExpressionValue); - } - return expression.Evaluate(parentExpressionValues); - } - - uint AddExpressionRecursively(IExpression expression) + uint AddExpressionRecursively(VFXExpression expression) { List parentExpressionIndices = new(); - foreach (var parentExpression in expression.Parents) + foreach (var parentExpression in expression.parents) { var parentExpressionValue = AddExpressionRecursively(parentExpression); parentExpressionIndices.Add(parentExpressionValue); } - uint vfxExpressionIndex; - if (s_PredefinedExpressions.TryGetValue(expression.GetType(), out var expressionAdder)) - { - vfxExpressionIndex = expressionAdder.AddExpression(this, expression, parentExpressionIndices); - } - else if (expression is IValueExpression valueExpression) - { - vfxExpressionIndex = _valueExpressionHandler.AddExpression(this, valueExpression, parentExpressionIndices); - } - else + // See VFXExpressionAbstract GetOperands for reference + var data = new VFXExpression.Operands(-1); + for(int i = 0; i < parentExpressionIndices.Count; i++) + data[i] = (int)parentExpressionIndices[i]; + for (int i = 0; i < expression.additionalOperands.Length; i++) + data[VFXExpression.Operands.OperandCount - expression.additionalOperands.Length + i] = expression.additionalOperands[i]; + + uint vfxExpressionIndex = AddExpression(expression.operation, data[0], data[1], data[2], data[3]); + + if (expression.Is(VFXExpression.Flags.Value)) { - throw new NotImplementedException($"Expression of type {expression.GetType()} is not supported"); + m_currentOutput.SheetValues.Add(CreateValueContainerDesc(expression, vfxExpressionIndex)); } + return vfxExpressionIndex; } @@ -216,11 +156,11 @@ void GenerateExpressionSheet(ref CompilationContext context) { foreach (var dataNode in context.graph.DataNodes) { - if (dataNode.TaskNode.Task is ExpressionTask expressionTask) + if (dataNode.TaskNode.Task is LegacyExpressionTask expressionTask) { foreach (var childDataNode in dataNode.Children) { - if (childDataNode.TaskNode.Task is GpuKernelTask or PlaceholderSystemTask or RenderingTask) + if (childDataNode.TaskNode.Task is GpuKernelTask or PlaceholderSystemTask or RenderingTask or SpawnerTask) { uint vfxExpressionIndex = AddExpressionRecursively(expressionTask.Expression); m_ValuesExpressionIndices.Add(childDataNode.Id, vfxExpressionIndex); @@ -316,7 +256,7 @@ void GenerateDeadListBuffersDescription(ref CompilationContext context) target = GraphicsBuffer.Target.Structured, size = particleData.Capacity + 2, stride = 4u, - mode = ComputeBufferMode.Dynamic, + mode = ComputeBufferMode.Immutable, }); m_GpuBufferDescIndices[deadListData] = bufferIndex; @@ -345,13 +285,7 @@ void GenerateSpawnBuffersDescriptions(ref CompilationContext context) void GenerateSystemDescs(ref CompilationContext context) { - foreach (var taskNode in context.graph.TaskNodes) - { - if (taskNode.Task is SpawnerTask spawnerTask && GenerateSpawnerSystemDesc(ref context, taskNode, spawnerTask, out var systemDesc)) - { - m_currentOutput.SystemDescs.Add(systemDesc); - } - } + GenerateSpawnerSystemDescs(ref context); var particleSystemContainer = context.data.Get(); foreach (var particleSystem in particleSystemContainer) @@ -363,21 +297,50 @@ void GenerateSystemDescs(ref CompilationContext context) } } - bool GenerateSpawnerSystemDesc(ref CompilationContext context, TaskNode taskNode, SpawnerTask task, out UnityEditor.VFX.VFXEditorSystemDesc systemDesc) + void GenerateSpawnerSystemDescs(ref CompilationContext context) { - systemDesc = new(); + Dictionary spawnDataMap = new(); - SpawnData spawnData = null; - foreach (var dataNode in taskNode.DataNodes) + // Collect systems from spawn data first + foreach (var dataView in context.graph.DataViews) + { + if (dataView.Root.DataDescription is SpawnData spawnData) + { + if (!spawnDataMap.ContainsKey(spawnData)) + { + GenerateSpawnerSystemDesc(ref context, spawnData, out var systemDesc); + spawnDataMap[spawnData] = systemDesc; + } + } + } + // Then fill tasks for each spawner system + foreach (var taskNode in context.graph.TaskNodes) { - foreach (var dataView in dataNode.UsedDataViews) + if (taskNode.Task is SpawnerTask spawnerTask) { - if (dataView.DataDescription is SpawnData spawnDataDescription) + foreach (var dataNode in taskNode.DataNodes) { - spawnData = spawnDataDescription; + if(dataNode.UsedDataViewsRoot.DataDescription is SpawnData spawnDataDescription) + { + var systemDesc = spawnDataMap[spawnDataDescription]; + List taskDescs = new List(systemDesc.tasks); + GenerateSpawnerTask(ref context, spawnerTask, taskNode, out var task); + taskDescs.Add(task); + systemDesc.tasks = taskDescs.ToArray(); + spawnDataMap[spawnDataDescription] = systemDesc; + } } } } + foreach (var spawnerSystemDesc in spawnDataMap.Values) + { + m_currentOutput.SystemDescs.Add(spawnerSystemDesc); + } + } + + bool GenerateSpawnerSystemDesc(ref CompilationContext context, SpawnData spawnData, out UnityEditor.VFX.VFXEditorSystemDesc systemDesc) + { + systemDesc = new(); var cpuData = new UnityEditor.VFX.VFXCPUBufferData(); cpuData.PushFloat(1.0f); @@ -398,51 +361,33 @@ bool GenerateSpawnerSystemDesc(ref CompilationContext context, TaskNode taskNode }); m_CpuBufferDescIndices[spawnData] = spawnerOutputIndex; - systemDesc.name = task.TemplateName; - systemDesc.type = UnityEngine.VFX.VFXSystemType.Spawner; - - List tasks = new(); - foreach (var block in task.Blocks) - { - if (GenerateSpawnerTask(ref context, block, out var taskDesc)) - { - tasks.Add(taskDesc); - } - } - - systemDesc.tasks = tasks.ToArray(); + systemDesc.name = "Spawn System"; systemDesc.type = UnityEngine.VFX.VFXSystemType.Spawner; systemDesc.buffers = new[] { new UnityEditor.VFX.VFXMapping("spawner_output", (int)spawnerOutputIndex) }; + systemDesc.tasks = Array.Empty(); return true; } - bool GenerateSpawnerTask(ref CompilationContext context, SubtaskDescription block, out UnityEditor.VFX.VFXEditorTaskDesc taskDesc) + bool GenerateSpawnerTask(ref CompilationContext context, SpawnerTask spawnerTask, TaskNode spawnerTaskNode, out UnityEditor.VFX.VFXEditorTaskDesc taskDesc) { taskDesc = new(); - if (block.Name == "ConstantRate") // TODO: remove this hack + taskDesc.shaderSourceIndex = -1; + taskDesc.type = (UnityEngine.VFX.VFXTaskType)spawnerTask.SpawnerType; + + List valueMappings = new(); + var taskNode = spawnerTaskNode; + foreach (var dataBinding in taskNode.DataBindings) { - var rateExpression = block.Expressions[0].Item2.Evaluate(new ReadOnlyList()); - var enabledExpression = block.Expressions[1].Item2.Evaluate(new ReadOnlyList()); - if (rateExpression != null && enabledExpression != null) + if (m_ValuesExpressionIndices.TryGetValue(dataBinding.DataNode.Id, out var expressionIndex)) { - var vfxEnableIndex = AddValueExpression(enabledExpression); - var rateExpressionIndex = AddValueExpression(rateExpression); - taskDesc = new() - { - type = UnityEngine.VFX.VFXTaskType.ConstantRateSpawner, - values = new UnityEditor.VFX.VFXMapping[] - { - new() { name = "_vfx_enabled", index = (int)vfxEnableIndex }, - new() { name = "Rate", index = (int)rateExpressionIndex } - }, - shaderSourceIndex = -1, - }; - return true; + string name = dataBinding.BindingDataKey.ToString(); + valueMappings.Add(new VFXMapping(name, (int)expressionIndex)); } } - return false; + taskDesc.values = valueMappings.ToArray(); + return true; } bool GenerateParticleSystemDesc(ref CompilationContext context, VfxGraphLegacyParticleSystemContainer.ParticleSystem particleSystem, out UnityEditor.VFX.VFXEditorSystemDesc systemDesc) @@ -498,23 +443,13 @@ VFXMapping[] GenerateSystemValuesMappings(CompilationContext context, VfxGraphLe if (m_ValuesExpressionIndices.TryGetValue(dataBinding.DataNode.Id, out var index)) { var name = dataBinding.BindingDataKey.ToString(); - // Dirty approach for renaming some specific values to match the expected names in the VFX system - switch (name) + // "System values" + if(name is "bounds_center" or "bounds_size" or "boundsPadding") { - case "BoundsCenter": - name = "bounds_center"; - valueMappings.Add(new VFXMapping(name, (int)index)); - continue; - case "BoundsSize": - name = "bounds_size"; - valueMappings.Add(new VFXMapping(name, (int)index)); - continue; - case "BoundsPadding": - name = "boundsPadding"; - valueMappings.Add(new VFXMapping(name, (int)index)); - continue; + valueMappings.Add(new VFXMapping(name, (int)index)); + continue; } - + // Graph values graphValueMappings.Add(dataBinding.DataView.DataDescription as ValueData, new VFXMapping(name, (int)index)); graphValueBufferLayout.AddValueData(dataBinding.DataView.DataDescription as ValueData); } @@ -601,36 +536,36 @@ bool GenerateParticleSystemTask(ref CompilationContext context, VfxGraphLegacyPa { if(dataView.DataDescription is AttributeData) { - bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.Name}_attributeBuffer", (int)gpuIndex)); + bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.IdentifierName}_attributeBuffer", (int)gpuIndex)); } else if (dataView.DataDescription is DeadListData) { - bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.Name}_deadListBuffer", (int)gpuIndex)); + bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.IdentifierName}_deadListBuffer", (int)gpuIndex)); } else if(dataView.Root.DataDescription is StructuredData) { - bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.Name}_buffer", (int)gpuIndex)); + bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.IdentifierName}_buffer", (int)gpuIndex)); } else if (dataView.DataDescription is SpawnData) { - bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.Name}_instancingPrefixSum", (int)gpuIndex)); + bufferMappings.Add(new VFXMapping($"_{dataView.DataContainer.IdentifierName}_instancingPrefixSum", (int)gpuIndex)); } } - - if (m_ValuesExpressionIndices.TryGetValue(dataBinding.DataNode.Id, out var expressionIndex)) - { - string name = dataBinding.BindingDataKey.ToString(); - valueMappings.Add(new VFXMapping( name, (int)expressionIndex)); - } + } + if (m_ValuesExpressionIndices.TryGetValue(dataBinding.DataNode.Id, out var expressionIndex)) + { + // For textures/buffers for now we need to use the name of the data container to match with what is generated in the description writer, we should find a better way to link them together + string name = dataBinding.DataNode.DataContainer.Name; + valueMappings.Add(new VFXMapping(name, (int)expressionIndex)); } } if (taskNode.Task is GpuKernelTask gpuKernelTask) { - taskDesc.processor = gpuKernelTask.Shader; + //taskDesc.processor = gpuKernelTask.Shader; } else if (taskNode.Task is RenderingTask renderingTask) { - taskDesc.processor = renderingTask.Material; + //taskDesc.processor = renderingTask.Material; } taskDesc.values = valueMappings.ToArray(); @@ -639,33 +574,51 @@ bool GenerateParticleSystemTask(ref CompilationContext context, VfxGraphLegacyPa return true; } - VFXExpressionValueContainerDesc CreateValueContainerDesc(IValueExpression exp, uint expressionIndex) + VFXExpressionValueContainerDesc CreateValueContainerDesc(VFXExpression exp, uint expressionIndex) + { + VFXExpressionValueContainerDesc value; + switch (exp.valueType) + { + case VFXValueType.Float: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Float2: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Float3: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Float4: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Int32: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Uint32: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Texture2D: + case VFXValueType.Texture2DArray: + case VFXValueType.Texture3D: + case VFXValueType.TextureCube: + case VFXValueType.TextureCubeArray: + value = CreateObjectValueDesc(exp, (int)expressionIndex); + break; + case VFXValueType.CameraBuffer: value = CreateObjectValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Matrix4x4: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Curve: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.ColorGradient: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Mesh: value = CreateObjectValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.SkinnedMeshRenderer: value = CreateObjectValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Boolean: value = CreateValueDesc(exp, (int)expressionIndex); break; + case VFXValueType.Buffer: value = CreateValueDesc(exp, (int)expressionIndex); break; + default: throw new InvalidOperationException("Invalid type : " + exp.valueType); + } + + return value; + } + + private static VFXExpressionValueContainerDesc CreateValueDesc(VFXExpression exp, int expressionIndex) + { + var desc = new VFXExpressionValueContainerDesc(); + desc.value = exp.Get(); + desc.expressionIndex = (uint)expressionIndex; + return desc; + } + private static VFXExpressionObjectValueContainerDesc CreateObjectValueDesc(VFXExpression exp, int expressionIndex) { - Type resultType = exp.ResultType; - - if(resultType == typeof(bool) && exp.TryGetValue(out var boolVal)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = boolVal }; - if (resultType == typeof(float) && exp.TryGetValue(out var floatVal)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = floatVal }; - if (resultType == typeof(Vector2) && exp.TryGetValue(out var vector2Val)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = vector2Val }; - if (resultType == typeof(Vector3) && exp.TryGetValue(out var vector3Val)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = vector3Val }; - if (resultType == typeof(Vector4) && exp.TryGetValue(out var vector4Val)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = vector4Val }; - if (resultType == typeof(int) && exp.TryGetValue(out var intVal)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = intVal }; - if (resultType == typeof(uint) && exp.TryGetValue(out var uintVal)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = uintVal }; - if (resultType == typeof(Color) && exp.TryGetValue(out var colorVal)) - return new VFXExpressionValueContainerDesc() { expressionIndex = expressionIndex, value = (Vector4)colorVal }; - if (resultType == typeof(Texture) && exp.TryGetValue(out var textureVal)) - return new VFXExpressionObjectValueContainerDesc() { expressionIndex = expressionIndex, entityId = textureVal ? textureVal.GetEntityId() : EntityId.None}; - if (resultType == typeof(Texture2D) && (exp.TryGetValue(out var texture2DVal) || true)) - return new VFXExpressionObjectValueContainerDesc() { expressionIndex = expressionIndex, entityId = texture2DVal ? texture2DVal.GetEntityId() : EntityId.None }; - - - throw new NotSupportedException($"Unsupported result type {resultType}"); + var desc = new VFXExpressionObjectValueContainerDesc(); + desc.entityId = exp.Get(); + desc.expressionIndex = (uint)expressionIndex; + return desc; } uint AddExpression(VFXExpressionOperation op, int data0, int data1, int data2, int data3) @@ -674,22 +627,6 @@ uint AddExpression(VFXExpressionOperation op, int data0, int data1, int data2, i vfxExpression.data = new[] { data0, data1, data2, data3 }; var vfxExpressionIndex = (uint)m_currentOutput.SheetExpressions.Count; m_currentOutput.SheetExpressions.Add(vfxExpression); - - return vfxExpressionIndex; - } - - uint AddValueExpression(IValueExpression exp) - { - Debug.Assert(exp != null); - Type resultType = exp.ResultType; - if (!s_ValueTypeConversion.ContainsKey(resultType)) - throw new NotSupportedException($"Unsupported result type {resultType}"); - - var valueType = GetVFXValueTypeFromType(resultType); - - uint vfxExpressionIndex = AddExpression(VFXExpressionOperation.Value, -1, -1, -1, (int)valueType); - - m_currentOutput.SheetValues.Add(CreateValueContainerDesc(exp, vfxExpressionIndex)); return vfxExpressionIndex; } diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs deleted file mode 100644 index 857ad998bcc..00000000000 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Collections.Generic; -using Unity.GraphCommon.LowLevel.Editor; -using UnityEngine; - -namespace UnityEditor.VFX -{ - class VfxGraphLegacyTemplatedTaskPass : CompilationPass - { - struct TemplatedTaskNodeCache - { - public TaskNodeId taskNodeId; - public TemplatedTask task; - } - struct SystemTaskNodeCache - { - public TaskNodeId taskNodeId; - public PlaceholderSystemTask task; - } - public bool Execute(ref CompilationContext context) - { - Dictionary> taskNodesGroups = new(); - Dictionary systemTasks = new(); - foreach (var taskNode in context.graph.TaskNodes) - { - if (taskNode.Task is TemplatedTask or PlaceholderSystemTask) - { - foreach (var dataNode in taskNode.DataNodes) - { - if (dataNode.DataContainer.RootDataView.DataDescription is ParticleData particleData) - { - if (taskNode.Task is TemplatedTask templatedTask) - { - if (!taskNodesGroups.ContainsKey(particleData)) - { - taskNodesGroups.Add(particleData, new()); - } - - taskNodesGroups[particleData].Add(new() { taskNodeId = taskNode.Id, task = templatedTask }); - } - else if (taskNode.Task is PlaceholderSystemTask systemTask) - { - systemTasks.Add(particleData, new() { taskNodeId = taskNode.Id, task = systemTask }); - } - } - } - } - } - - foreach (var particleData in systemTasks.Keys) - { - var systemTask = systemTasks[particleData]; - - StructuredData graphValuesBuffer = new StructuredData(); - var graphValuesId = context.graph.AddData("GraphValuesBuffer", graphValuesBuffer); - context.graph.BindData(systemTask.taskNodeId, TemplatedTask.GraphValuesKey, graphValuesId, BindingUsage.Write); - - // Add a default subdata for ContextData, which is expected from the C++ runtime. - graphValuesBuffer.AddSubdata(TemplatedTask.ContextDataKey, ValueData.Create(typeof(Vector4))); - - foreach (var taskNode in taskNodesGroups[particleData]) - { - foreach (var (subDatakey, expression) in taskNode.task.Expressions) - { - if (graphValuesBuffer.GetSubdata(subDatakey) != null) continue; //Duplicate subdata, skip - - var inputDataViewId = BuildExpressionGraph(context.graph, expression); - - if (expression.IsConstant || typeof(Texture).IsAssignableFrom(expression.ResultType)) // Do not go through graphValues - { - context.graph.BindData(taskNode.taskNodeId, subDatakey, inputDataViewId, BindingUsage.Read); - } - else - { - if (graphValuesBuffer.AddSubdata(subDatakey, ValueData.Create(expression.ResultType))) - { - context.graph.BindData(systemTask.taskNodeId, subDatakey, inputDataViewId, BindingUsage.Read); - } - var subdataViewId = context.graph.GetSubdata(graphValuesId, subDatakey); - context.graph.BindData(taskNode.taskNodeId, subDatakey, subdataViewId, BindingUsage.Read); - } - } - var contextDataViewId = context.graph.GetSubdata(graphValuesId, TemplatedTask.ContextDataKey); - context.graph.BindData(taskNode.taskNodeId, TemplatedTask.ContextDataKey, contextDataViewId, BindingUsage.Read); - } - foreach (var (subDatakey, expression) in systemTask.task.Expressions) - { - var inputDataViewId = BuildExpressionGraph(context.graph, expression); - context.graph.BindData(systemTask.taskNodeId, subDatakey, inputDataViewId, BindingUsage.Read); - } - } - - return true; - } - - private DataViewId BuildExpressionGraph(IMutableGraph graph, IExpression expression) - { - // TODO: This is duplicated code (see BlockBuilder). Find a proper place for expression graph - // TODO: Cache expressions per-task? - var taskId = graph.AddTask(new ExpressionTask(expression)); - var parents = expression.Parents; - for (int i = 0; i < parents.Count; ++i) - { - graph.BindData(taskId, new IndexDataKey(i),BuildExpressionGraph(graph, parents[i]), BindingUsage.Read); - } - var dataDescription = expression is IValueExpression valueExpression && expression.IsConstant ? ConstantValueData.Create(valueExpression.Value, expression.ResultType) : ValueData.Create(expression.ResultType); - var dataId = graph.AddData(expression.GetType().Name, dataDescription); - graph.BindData(taskId, ExpressionTask.Value, dataId, BindingUsage.Write); - return dataId; - } - } -} diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs.meta deleted file mode 100644 index f2ded974733..00000000000 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Passes/VfxGraphLegacyTemplatedTaskPass.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 534c436956f747047bf69f9d1cf6dd21 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs new file mode 100644 index 00000000000..8921e83c67a --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs @@ -0,0 +1,41 @@ +using Unity.GraphCommon.LowLevel.Editor; + +namespace UnityEditor.VFX +{ + class LegacyExpressionTask : ITask + { + public VFXExpression Expression { get; private set; } + public static UniqueDataKey Value { get; } = new("Out"); + + public LegacyExpressionTask(VFXExpression expression) + { + Expression = expression; + } + + public bool GetDataUsage(IDataKey dataKey, out DataPathSet readUsage, out DataPathSet writeUsage) + { + if (dataKey is IndexDataKey indexDataKey) + { + if (indexDataKey.Index < Expression.parents.Length) + { + readUsage = new DataPathSet(); + writeUsage = new DataPathSet(); + readUsage.Add(DataPath.Empty); + return true; + } + } + + if (dataKey == Value) + { + readUsage = new DataPathSet(); + writeUsage = new DataPathSet(); + writeUsage.Add(DataPath.Empty); + return true; + } + + readUsage = null; + writeUsage = null; + return false; + } + } +} diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs.meta new file mode 100644 index 00000000000..1b89418ad88 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/LegacyExpressionTask.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 99fa86a67c0b4c8f977c557f6139eb2d +timeCreated: 1770989919 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs index 1be6483dd35..09291e4a3ad 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Unity.GraphCommon.LowLevel.Editor; +using UnityEngine; namespace UnityEditor.VFX { @@ -12,11 +13,7 @@ namespace UnityEditor.VFX /// Gets the name of the template associated with the task. /// public string TemplateName { get; } - - /// - /// Gets the collection of task snippets that compose the task. - /// - public List Blocks { get; } = new(); + public VFXTaskType SpawnerType { get; } IDataKey m_SpawnDataKey; @@ -25,12 +22,12 @@ namespace UnityEditor.VFX /// and task snippets. /// /// The name of the template associated with the task. - /// The initial collection of objects that compose the task. + /// The spawner task type. /// The data key for the spawn data - public SpawnerTask(string templateName, IEnumerable blocks, IDataKey spawnDataKey) + public SpawnerTask(string templateName, VFXTaskType spawnerType, IDataKey spawnDataKey) { + SpawnerType = spawnerType; TemplateName = templateName; - Blocks.AddRange(blocks); m_SpawnDataKey = spawnDataKey; } diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs.meta index ce5ababc01d..b5e5a13547b 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs.meta +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/Tasks/SpawnerTask.cs.meta @@ -1,2 +1,3 @@ fileFormatVersion: 2 -guid: 772e5f6a15f31134395321277cd1cedd \ No newline at end of file +guid: 770f15b1e6bb413abe901a659e4770c7 +timeCreated: 1771418458 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxGraphCompiler.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxGraphCompiler.cs index 5ce1d1935b1..4f80c37f0ae 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxGraphCompiler.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxGraphCompiler.cs @@ -1,4 +1,6 @@ +using System.Collections.Generic; using Unity.GraphCommon.LowLevel.Editor; +using UnityEngine; using UnityEngine.VFX; namespace UnityEditor.VFX @@ -6,6 +8,7 @@ namespace UnityEditor.VFX class VfxGraphCompiler { private Compiler m_GraphCompiler; + private VfxIntermediateGraphBuilder m_GraphBuilder = new(); private DataDescriptionWriterRegistry m_DataWriter; @@ -20,7 +23,6 @@ public VfxGraphCompiler() m_DataWriter.Register(new SpawnerDataDescriptionWriter()); m_GraphCompiler = new(new VfxGraphLegacyOutputPass(), - new VfxGraphLegacyTemplatedTaskPass(), new AttributeLayoutPass(), new VfxGraphLegacyParticleSystemPass(), new StructuredDataLayoutPass(), @@ -29,7 +31,13 @@ public VfxGraphCompiler() public VFXGraphCompiledData.VFXCompileOutput Compile(VFXGraph graph, VFXCompilationMode compilationMode, bool generateShadersDebugSymbols) { - var intermediateGraph = BuildGraph(graph); + // One of supported SRPs is not current SRP + if (VFXLibrary.currentSRPBinder == null) + { + return new() { success = false }; + } + + var intermediateGraph = m_GraphBuilder.BuildGraph(graph); // TODO: setup compilation mode and shader debug symbols var compilationResult = m_GraphCompiler.Compile(intermediateGraph); @@ -43,10 +51,5 @@ public VFXGraphCompiledData.VFXCompileOutput Compile(VFXGraph graph, VFXCompilat return output; } - - IReadOnlyGraph BuildGraph(VFXGraph graph) - { - return new TaskGraph(); - } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs new file mode 100644 index 00000000000..80b85294f33 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs @@ -0,0 +1,491 @@ +using System.Collections.Generic; +using System.Text; +using Unity.GraphCommon.LowLevel.Editor; +using UnityEngine.VFX; +using UnityEngine; + +namespace UnityEditor.VFX +{ + class VfxIntermediateGraphBuilder + { + private class ParticleSystemBuildInfo + { + public ParticleSystemBuildInfo(VFXData data) + { + Data = data; + } + + public VFXData Data { get; } + public VFXBasicInitialize InitContext { get; set; } + public List UpdateContexts { get; } = new(); + public List OutputContexts { get; } = new(); + public DataViewId InputSpawnData { get; set; } = DataViewId.Invalid; + } + + private static readonly DataPath kAttributeDataPath = new DataPath(ParticleData.AttributeDataKey); + private static readonly IDataKey kParticleBindingKey = new NameDataKey("ParticleDataBinding"); + private static readonly IDataKey kSpawnDataBindingKey = new NameDataKey("SpawnDataBinding"); + private static readonly IDataKey kMainTextureKey = new NameDataKey("MainTexture"); + + Dictionary m_ParticleSystems = new(); + VFXSystemNames m_SystemNames = new(); + VFXExpressionGraph m_ExpressionGraph; + + Dictionary> m_StructuredDataNamesCount = new(); + + public IReadOnlyGraph BuildGraph(VFXGraph graph) + { + var intermediateGraph = new TaskGraph(); + + Clear(); + + var models = new HashSet(); + graph.CollectDependencies(models, false); + + m_ExpressionGraph = new VFXExpressionGraph(); + List compilableContexts = new List(); + List spawners = new List(); + foreach (var model in models) + { + if (model is VFXContext context && context.CanBeCompiled()) + { + var data = context.GetData(); + + switch (context) + { + case VFXBasicSpawner basicSpawner: + { + spawners.Add(basicSpawner); + break; + } + case VFXBasicInitialize initContext: + { + var particleSystemBuildInfo = GetParticleSystemBuildInfo(data); + Debug.Assert(particleSystemBuildInfo.InitContext == null); + particleSystemBuildInfo.InitContext = initContext; + break; + } + case VFXBasicUpdate updateContext: + { + var particleSystemBuildInfo = GetParticleSystemBuildInfo(data); + particleSystemBuildInfo.UpdateContexts.Add(updateContext); + break; + } + case VFXAbstractParticleOutput outputContext: + { + var particleSystemBuildInfo = GetParticleSystemBuildInfo(data); + particleSystemBuildInfo.OutputContexts.Add(outputContext); + break; + } + } + compilableContexts.Add(context); + } + } + + m_ExpressionGraph.CompileExpressions(compilableContexts, VFXExpressionContextOption.ConstantFolding); + + foreach (var spawner in spawners) + { + BuildSpawnerSystem(spawner, intermediateGraph); + } + foreach (var particleSystem in m_ParticleSystems.Values) + { + BuildParticleSystem(particleSystem, intermediateGraph); + } + + //return new TaskGraph(); + return intermediateGraph; + } + + void Clear() + { + m_ParticleSystems.Clear(); + m_StructuredDataNamesCount.Clear(); + } + + void BuildSpawnerSystem(VFXBasicSpawner spawner, TaskGraph intermediateGraph) + { + var spawnDataDescription = BuildSpawnerDataDescription(spawner.GetData()); + var spawnData = intermediateGraph.AddData(spawnDataDescription.Name, spawnDataDescription); + + // Propagate spawn data to linked contexts + foreach (var outputContext in spawner.outputContexts) + { + var particleSystemBuildInfo = GetParticleSystemBuildInfo(outputContext.GetData()); + particleSystemBuildInfo.InputSpawnData = spawnData; + } + + bool first = true; + foreach (var block in spawner.activeFlattenedChildrenWithImplicit) + { + if (block is VFXAbstractSpawner spawnerBlock) + { + SpawnerTask subTask = new SpawnerTask(block.name, spawnerBlock.spawnerType, kSpawnDataBindingKey); + var spawnerTaskNodeId = intermediateGraph.AddTask(subTask); + intermediateGraph.BindData(spawnerTaskNodeId, kSpawnDataBindingKey, spawnData, first ? BindingUsage.Write : BindingUsage.ReadWrite); + BindSpawnerExpressions(intermediateGraph, spawner, spawnerTaskNodeId); + first = false; + } + } + } + + IDataDescription BuildSpawnerDataDescription(VFXData data) + { + return new SpawnData(m_SystemNames.GetUniqueSystemName(data)); + } + + ParticleSystemBuildInfo GetParticleSystemBuildInfo(VFXData data) + { + ParticleSystemBuildInfo particleSystemBuildInfo = null; + if (!m_ParticleSystems.TryGetValue(data, out particleSystemBuildInfo)) + { + particleSystemBuildInfo = new ParticleSystemBuildInfo(data); + m_ParticleSystems.Add(data, particleSystemBuildInfo); + } + return particleSystemBuildInfo; + } + + void BuildParticleSystem(ParticleSystemBuildInfo particleSystemBuildInfo, TaskGraph intermediateGraph) + { + //if (!Validate(particleSystem)) + // return; // And log error + + var particleDataDescription = BuildParticleDataDescription(particleSystemBuildInfo.Data); + var particleData = intermediateGraph.AddData(particleDataDescription.Name, particleDataDescription); + + var systemTask = intermediateGraph.AddTask(BuildSystemTask()); + intermediateGraph.BindData(systemTask, kParticleBindingKey, particleData, BindingUsage.Write); + + BuildGraphValuesBuffer(intermediateGraph, systemTask, out var graphValuesViewId, out var contextDataViewId, out var graphValuesBuffer); + + var initializeTask = intermediateGraph.AddTask(BuildInitializeTask(particleSystemBuildInfo.InitContext)); + BindExpressions(intermediateGraph, particleSystemBuildInfo.InitContext, initializeTask, systemTask, graphValuesBuffer, graphValuesViewId); + BindContextData(intermediateGraph, initializeTask, contextDataViewId); + + var spawnData = particleSystemBuildInfo.InputSpawnData; + if (spawnData.IsValid) + { + intermediateGraph.BindData(initializeTask, kSpawnDataBindingKey, spawnData, BindingUsage.Read); + } + intermediateGraph.BindData(initializeTask, kParticleBindingKey, particleData, BindingUsage.ReadWrite); + + foreach (var updateContext in particleSystemBuildInfo.UpdateContexts) + { + var updateTask = intermediateGraph.AddTask(BuildUpdateTask(updateContext)); + intermediateGraph.BindData(updateTask, kParticleBindingKey, particleData, BindingUsage.ReadWrite); + BindExpressions(intermediateGraph, updateContext, updateTask, systemTask, graphValuesBuffer, graphValuesViewId); + BindContextData(intermediateGraph, updateTask, contextDataViewId); + } + + foreach (var outputContext in particleSystemBuildInfo.OutputContexts) + { + var outputTask = intermediateGraph.AddTask(BuildOutputTask(outputContext)); + intermediateGraph.BindData(outputTask, kParticleBindingKey, particleData, BindingUsage.Read); + BindExpressions(intermediateGraph, outputContext, outputTask, systemTask, graphValuesBuffer, graphValuesViewId); + BindContextData(intermediateGraph, outputTask, contextDataViewId); + } + } + + void BuildGraphValuesBuffer(TaskGraph intermediateGraph, TaskNodeId systemTask, out DataViewId graphValuesViewId, out DataViewId contextDataViewId, out StructuredData graphValuesBuffer) + { + graphValuesBuffer = new StructuredData(); + graphValuesViewId = intermediateGraph.AddData("GraphValuesBuffer", graphValuesBuffer); + intermediateGraph.BindData(systemTask, TemplatedTask.GraphValuesKey, graphValuesViewId, BindingUsage.Write); + graphValuesBuffer.AddSubdata(TemplatedTask.ContextDataKey, ValueData.Create(typeof(Vector4))); // Adds a default subdata for ContextData, which is expected from the C++ runtime. + contextDataViewId = intermediateGraph.GetSubdata(graphValuesViewId, TemplatedTask.ContextDataKey); + m_StructuredDataNamesCount.Add(graphValuesBuffer, new Dictionary()); + } + + void BindContextData(TaskGraph intermediateGraph, TaskNodeId contextTask, DataViewId contextDataViewId) + { + intermediateGraph.BindData(contextTask, TemplatedTask.ContextDataKey, contextDataViewId, BindingUsage.Read); + } + + void BindSpawnerExpressions(TaskGraph intermediateGraph, VFXBasicSpawner spawner, TaskNodeId spawnerTaskNodeId) + { + // For spawner, we only bind CPU expressions and we do not use the full name for the binding. + var cpuMapper = m_ExpressionGraph.BuildCPUMapper(spawner); + foreach (var expression in cpuMapper.expressions) + { + var expressionDataViewId = AddExpressionRecursively(intermediateGraph, expression); + string bindingName = cpuMapper.GetData(expression)[0].name; + intermediateGraph.BindData(spawnerTaskNodeId, new NameDataKey(bindingName), expressionDataViewId, BindingUsage.Read); + } + } + + void BindExpressions(TaskGraph intermediateGraph, VFXContext context, TaskNodeId contextTask, TaskNodeId systemTask, StructuredData graphValuesBuffer, DataViewId graphValuesViewId) + { + BindGPUExpressions(intermediateGraph, context, contextTask, systemTask, graphValuesBuffer, graphValuesViewId); + BindCPUExpressions(intermediateGraph, context, contextTask, systemTask); + } + + void BindGPUExpressions(TaskGraph intermediateGraph, VFXContext context, TaskNodeId contextTask, TaskNodeId systemTask, StructuredData graphValuesBuffer, DataViewId graphValuesViewId) + { + var gpuMapper = m_ExpressionGraph.BuildGPUMapper(context); + foreach (var expression in gpuMapper.expressions) + { + var expressionDataViewId = AddExpressionRecursively(intermediateGraph, expression); + if (!VFXExpression.IsUniform(expression.valueType)) + { + string bindingName = gpuMapper.GetData(expression)[0].fullName; + IDataKey bindingKey = new NameDataKey(bindingName); + intermediateGraph.BindData(contextTask, bindingKey, expressionDataViewId, BindingUsage.Read); + } + else + { + Debug.Assert(m_StructuredDataNamesCount.ContainsKey(graphValuesBuffer)); + string bindingName = gpuMapper.GetData(expression)[0].name; + var nameCountMap = m_StructuredDataNamesCount[graphValuesBuffer]; + if (nameCountMap.TryGetValue(bindingName, out uint count)) + { + nameCountMap[bindingName] = count + 1; + } + else + { + count = 0; + nameCountMap.Add(bindingName, 1); + } + + string systemUniqueBindingName = $"{bindingName}_{VFXCodeGeneratorHelper.GeneratePrefix(count)}"; + IDataKey systemBindingKey = new NameDataKey(systemUniqueBindingName); + IDataKey contextBindingKey = new NameDataKey(gpuMapper.GetData(expression)[0].fullName); + + if(graphValuesBuffer.AddSubdata(systemBindingKey, ValueData.Create(VFXExpression.TypeToType(expression.valueType)))) + { + intermediateGraph.BindData(systemTask, systemBindingKey, expressionDataViewId, BindingUsage.Read); + } + var subdataViewId = intermediateGraph.GetSubdata(graphValuesViewId, systemBindingKey); + intermediateGraph.BindData(contextTask, contextBindingKey, subdataViewId, BindingUsage.Read); + } + } + } + + void BindCPUExpressions(TaskGraph intermediateGraph, VFXContext context, TaskNodeId contextTask, TaskNodeId systemTask) + { + var cpuMapper = m_ExpressionGraph.BuildCPUMapper(context); + + TaskNodeId targetNodeId = context is VFXBasicSpawner ? contextTask : systemTask; + + foreach (var expression in cpuMapper.expressions) + { + var expressionDataViewId = AddExpressionRecursively(intermediateGraph, expression); + string bindingName = cpuMapper.GetData(expression)[0].fullName; + intermediateGraph.BindData(targetNodeId, new NameDataKey(bindingName), expressionDataViewId, BindingUsage.Read); + } + } + + IDataDescription BuildParticleDataDescription(VFXData data) + { + uint capacity = (uint)data.GetSettingValue("capacity"); + return new ParticleData(m_SystemNames.GetUniqueSystemName(data), new Bounds(), data is ISpaceable spaceable ? spaceable.space : VFXSpace.None, capacity); + } + + ITask BuildSystemTask() + { + return new PlaceholderSystemTask( + new List<(IDataKey, IExpression)>(), + new List() + { + new(kParticleBindingKey, DataPath.Empty), + new(TemplatedTask.GraphValuesKey, DataPath.Empty) + }); + } + + ITask BuildInitializeTask(VFXBasicInitialize initContext) + { + AttributeSet particleAttributes = new AttributeSet(); + particleAttributes.AddAttribute(VFXAttributesManager.ConvertToNewCompiler(VFXAttribute.Alive), AttributeUsage.Write); + particleAttributes.AddAttribute(VFXAttributesManager.ConvertToNewCompiler(VFXAttribute.ParticleId), AttributeUsage.Write); + particleAttributes.AddAttribute(VFXAttributesManager.ConvertToNewCompiler(VFXAttribute.Seed), AttributeUsage.Write); + + BindingUsagePaths particleSystemUsage = new(); + particleSystemUsage.Add(kAttributeDataPath, particleAttributes); + //TODO: Is this where it should be added? Maybe not the dead list, but the id tracker? Which is the same key here anyways + particleSystemUsage.Read.Add(new DataPath(ParticleData.DeadlistKey)); + particleSystemUsage.Write.Add(new DataPath(ParticleData.DeadlistKey)); + + BindingUsagePaths spawnSystemUsage = new(); + spawnSystemUsage.Read.Add(new DataPath(SpawnData.SourceAttributeDataKey)); + + BindingUsagePaths contextDataUsage = new(); + contextDataUsage.Read.Add(DataPath.Empty); + + var args = new TemplatedTaskArgs + { + Subtasks = GenerateSubtasks(initContext), + + AttributeKeyMappings = new() + { + [AttributeData.DefaultKey] = new(kParticleBindingKey, kAttributeDataPath) // TODO: Use a proper key for particle attributes and just provide which one is default + }, + + Bindings = new() + { + [kParticleBindingKey] = new(typeof(ParticleData), particleSystemUsage), + [kSpawnDataBindingKey] = new(typeof(SpawnData), spawnSystemUsage), + [TemplatedTask.ContextDataKey] = new(typeof(ValueData), contextDataUsage) + } + }; + return new TemplatedTask("Init", args); + } + + ITask BuildUpdateTask(VFXBasicUpdate updateContext) + { + AttributeSet particleAttributes = new AttributeSet(); + particleAttributes.AddAttribute(VFXAttributesManager.ConvertToNewCompiler(VFXAttribute.Alive), AttributeUsage.Read); + + BindingUsagePaths particleSystemUsage = new(); + particleSystemUsage.Add(kAttributeDataPath, particleAttributes); + //TODO: Is this where it should be added? Maybe not the dead list, but the id tracker? Which is the same key here anyways + particleSystemUsage.Read.Add(new DataPath(ParticleData.DeadlistKey)); + particleSystemUsage.Write.Add(new DataPath(ParticleData.DeadlistKey)); + + BindingUsagePaths contextDataUsage = new(); + contextDataUsage.Read.Add(DataPath.Empty); + + TemplatedTaskArgs args = new TemplatedTaskArgs + { + Subtasks = GenerateSubtasks(updateContext), + + //Expressions = CollectInputExpressions(processor), + + AttributeKeyMappings = new() + { + [AttributeData.DefaultKey] = new(kParticleBindingKey, kAttributeDataPath) + }, + + Bindings = new() + { + [kParticleBindingKey] = new(typeof(ParticleData), particleSystemUsage), + [TemplatedTask.ContextDataKey] = new(typeof(ValueData), contextDataUsage) + } + }; + + return new TemplatedTask("Update", args); + } + + ITask BuildOutputTask(VFXAbstractParticleOutput outputContext) + { + List s_ReadAttributes = new() + { + VFXAttribute.Alive, + VFXAttribute.Color, + VFXAttribute.Alpha, + VFXAttribute.Position, + VFXAttribute.Size, + VFXAttribute.ScaleX, + VFXAttribute.ScaleY, + VFXAttribute.ScaleZ + }; + + AttributeSet particleAttributes = new AttributeSet(); + foreach (var attribute in s_ReadAttributes) + { + particleAttributes.AddAttribute(VFXAttributesManager.ConvertToNewCompiler(attribute), AttributeUsage.Read); + } + + BindingUsagePaths particleSystemUsage = new(); + particleSystemUsage.Add(kAttributeDataPath, particleAttributes); + + BindingUsagePaths mainTextureUsage = new(); + mainTextureUsage.Read.Add(DataPath.Empty); + + TemplatedTaskArgs args = new TemplatedTaskArgs + { + Subtasks = GenerateSubtasks(outputContext), + + //Expressions = CollectInputExpressions(processor), + + AttributeKeyMappings = new() + { + [AttributeData.DefaultKey] = new(kParticleBindingKey, kAttributeDataPath) + }, + + Bindings = new() + { + [kParticleBindingKey] = new(typeof(ParticleData), particleSystemUsage), + [kMainTextureKey] = new(typeof(ValueData), mainTextureUsage) + } + }; + + return new TemplatedTask("Output", args, false); + } + + DataViewId AddExpressionRecursively(TaskGraph taskGraph, VFXExpression expression) + { + LegacyExpressionTask expressionTask = new LegacyExpressionTask(expression); + var taskNodeId = taskGraph.AddTask(expressionTask); + + var parents = expression.parents; + for (int i = 0; i < parents.Length; ++i) + { + taskGraph.BindData(taskNodeId, new IndexDataKey(i), AddExpressionRecursively(taskGraph, parents[i]), BindingUsage.Read); + } + + var dataDescription = ValueData.Create(VFXExpression.TypeToType(expression.valueType)); + var dataViewId = taskGraph.AddData(expression.GetType().Name, dataDescription); + taskGraph.BindData(taskNodeId, LegacyExpressionTask.Value, dataViewId, BindingUsage.Write); + return dataViewId; + } + + List GenerateSubtasks(VFXContext context) + { + List subtaskDescriptions = new List(); + var gpuMapper = m_ExpressionGraph.BuildGPUMapper(context); + foreach (var block in context.activeFlattenedChildrenWithImplicit) + { + var subTaskDesc = new SubtaskDescription(); + subTaskDesc.Name = block.name; + subTaskDesc.ExpressionBindingKeys = new List(); + + StringBuilder codeBuilder = new StringBuilder(block.source); + + foreach (var parameter in block.parameters) + { + var reduced = m_ExpressionGraph.GPUExpressionsToReduced[parameter.exp]; + if (gpuMapper.GetData(reduced).Count > 0) + { + string bindingName = gpuMapper.GetData(reduced)[0].fullName; + subTaskDesc.ExpressionBindingKeys.Add(new NameDataKey(bindingName)); + + // Generate assignment + if(VFXExpression.IsUniform(reduced.valueType)) + { + string assignment = $"{VFXExpression.TypeToCode(reduced.valueType)} {parameter.name} = {bindingName};\n"; + codeBuilder.Insert(0, assignment); + } + } + } + + Dictionary attributeSets = new Dictionary(); + var attributeSet = new AttributeSet(); + foreach (var attributeInfo in block.attributes) + { + var attribute = VFXAttributesManager.ConvertToNewCompiler(attributeInfo.attrib); + AttributeUsage usage = GetAttributeUsage(attributeInfo.mode); + attributeSet.AddAttribute(attribute, usage); + codeBuilder.Replace(attributeInfo.attrib.name, "attributes." + attributeInfo.attrib.name); + } + if(block.source.Contains("RAND")) + codeBuilder.Insert(0, "uint seed = attributes.seed;"); + + attributeSets.Add(AttributeData.DefaultKey, attributeSet); + + subTaskDesc.Task = new TemplateSubtask(block.name, codeBuilder.ToString(), attributeSets); + + subtaskDescriptions.Add(subTaskDesc); + } + return subtaskDescriptions; + } + + AttributeUsage GetAttributeUsage(VFXAttributeMode mode) + { + AttributeUsage usage = 0; + if (mode.HasFlag(VFXAttributeMode.Read)) + usage |= AttributeUsage.Read; + if (mode.HasFlag(VFXAttributeMode.Write)) + usage |= AttributeUsage.Write; + return usage; + } + } +} diff --git a/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs.meta new file mode 100644 index 00000000000..1d883bab232 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/NewCompiler/VfxIntermediateGraphBuilder.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3897e883fc167a042820eab62742c688 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp.meta new file mode 100644 index 00000000000..294e8a2a181 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 26dcf047d622f8d419694267055fd2db +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data.meta new file mode 100644 index 00000000000..913c03fce28 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2f5dda3a6884cdb47acaaefc56037e49 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl new file mode 100644 index 00000000000..157c9282458 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl @@ -0,0 +1,39 @@ +#ifndef __VFX_ATTRIBUTE_BUFFER +#define __VFX_ATTRIBUTE_BUFFER + +#include "Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl" + +struct VFXAttributeBuffer +{ + VFXByteAddressBuffer buffer; + + void Init(VFXByteAddressBuffer buffer) + { + this.buffer = buffer; + } +}; + +#define VFX_ATTRIBUTE_DECLARE(type, name, value, offset, stride)\ + type Load_##name(uint index)\ + {\ + type name = value;\ + attributeBuffer.buffer.LoadData(name, offset + index * stride);\ + return name;\ + }\ + void Store_##name(type name, uint index)\ + {\ + attributeBuffer.buffer.StoreData(name, offset + index * stride);\ + }\ + type __##name + +#define VFX_ATTRIBUTE_IGNORE(type, name, value)\ + type Load_##name(uint index)\ + {\ + return value;\ + }\ + void Store_##name(type name, uint index)\ + {\ + }\ + type __##name + +#endif //__VFX_ATTRIBUTE_BUFFER diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl.meta new file mode 100644 index 00000000000..a75a42c3902 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5b820e407f13dd444830580fdafaa327 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl new file mode 100644 index 00000000000..675959e862a --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl @@ -0,0 +1,278 @@ +#ifndef __VFX_BYTE_ADDRESS_BUFFER +#define __VFX_BYTE_ADDRESS_BUFFER + +ByteAddressBuffer __VFXEmptyByteAddressBuffer; +RWByteAddressBuffer __VFXEmptyRWByteAddressBuffer; + +struct VFXByteAddressBuffer +{ + ByteAddressBuffer buffer; + RWByteAddressBuffer bufferRW; + uint offset; + uint size; + bool readAccess; + bool writeAccess; + bool rangeCheck; + + void Init(ByteAddressBuffer buffer, uint offset, uint size) + { + this.buffer = buffer; + this.bufferRW = __VFXEmptyRWByteAddressBuffer; + this.offset = offset; + this.size = size; + this.readAccess = true; + this.writeAccess = false; + this.rangeCheck = false; + } + + void Init(RWByteAddressBuffer buffer, uint offset, uint size) + { + this.buffer = __VFXEmptyByteAddressBuffer; + this.bufferRW = buffer; + this.offset = offset; + this.size = size; + this.readAccess = true; + this.writeAccess = true; + this.rangeCheck = false; + } + + bool LoadData(out uint data, uint index) + { + bool valid = !rangeCheck || index < size; + data = 0u; + if (valid && readAccess) + { + if (writeAccess) + { + data = bufferRW.Load((offset + index) << 2); + } + else + { + data = buffer.Load((offset + index) << 2); + } + } + return valid; + } + + bool StoreData(uint data, uint index) + { + bool valid = !rangeCheck || index < size; + if (valid && writeAccess) + { + bufferRW.Store((offset + index) << 2, data); + } + return valid; + } + + bool LoadData(out uint2 data, uint index) + { + bool valid = !rangeCheck || index + 1 < size; + data = 0u; + if (valid && readAccess) + { + if (writeAccess) + { + data = bufferRW.Load2((offset + index) << 2); + } + else + { + data = buffer.Load2((offset + index) << 2); + } + } + return valid; + } + + bool StoreData(uint2 data, uint index) + { + bool valid = !rangeCheck || index + 1 < size; + if (valid && writeAccess) + { + bufferRW.Store2((offset + index) << 2, data); + } + return valid; + } + + bool LoadData(out uint3 data, uint index) + { + bool valid = !rangeCheck || index + 2 < size; + data = 0u; + if (valid && readAccess) + { + if (writeAccess) + { + data = bufferRW.Load3((offset + index) << 2); + } + else + { + data = buffer.Load3((offset + index) << 2); + } + } + return valid; + } + + bool StoreData(uint3 data, uint index) + { + bool valid = !rangeCheck || index + 2 < size; + if (valid && writeAccess) + { + bufferRW.Store3((offset + index) << 2, data); + } + return valid; + } + + bool LoadData(out uint4 data, uint index) + { + bool valid = !rangeCheck || index + 3 < size; + data = 0u; + if (valid && readAccess) + { + if (writeAccess) + { + data = bufferRW.Load4((offset + index) << 2); + } + else + { + data = buffer.Load4((offset + index) << 2); + } + } + return valid; + } + + bool StoreData(uint4 data, uint index) + { + bool valid = !rangeCheck || index + 3 < size; + if (valid && writeAccess) + { + bufferRW.Store4((offset + index) << 2, data); + } + return valid; + } + + bool LoadData(out float data, uint index) + { + uint rawData = 0u; + data = 0.0f; + bool valid = LoadData(rawData, index); + if (valid) + { + data = asfloat(rawData); + } + return valid; + } + + bool StoreData(float data, uint index) + { + uint rawData = asuint(data); + return StoreData(rawData, index); + } + + bool LoadData(out float2 data, uint index) + { + uint2 rawData = 0u; + data = 0.0f; + bool valid = LoadData(rawData, index); + if (valid) + { + data = asfloat(rawData); + } + return valid; + } + + bool StoreData(float2 data, uint index) + { + uint2 rawData = asuint(data); + return StoreData(rawData, index); + } + + bool LoadData(out float3 data, uint index) + { + uint3 rawData = 0u; + data = 0.0f; + bool valid = LoadData(rawData, index); + if (valid) + { + data = asfloat(rawData); + } + return valid; + } + + bool StoreData(float3 data, uint index) + { + uint3 rawData = asuint(data); + return StoreData(rawData, index); + } + + bool LoadData(out float4 data, uint index) + { + uint4 rawData = 0u; + bool valid = LoadData(rawData, index); + if (valid) + { + data = asfloat(rawData); + } + return valid; + } + + bool StoreData(float4 data, uint index) + { + uint4 rawData = asuint(data); + return StoreData(rawData, index); + } + + bool LoadData(out float4x4 data, uint index) + { + bool valid = !rangeCheck || index + 15 < size; + data = 0u; + if (valid && readAccess) + { + if (writeAccess) + { + data[0] = asfloat(bufferRW.Load4((offset + index + 0) << 2)); + data[1] = asfloat(bufferRW.Load4((offset + index + 4) << 2)); + data[2] = asfloat(bufferRW.Load4((offset + index + 8) << 2)); + data[3] = asfloat(bufferRW.Load4((offset + index + 12) << 2)); + } + else + { + data[0] = asfloat(buffer.Load4((offset + index + 0) << 2)); + data[1] = asfloat(buffer.Load4((offset + index + 4) << 2)); + data[2] = asfloat(buffer.Load4((offset + index + 8) << 2)); + data[3] = asfloat(buffer.Load4((offset + index + 12) << 2)); + } + } + return valid; + } + + bool StoreData(float4x4 data, uint index) + { + bool valid = !rangeCheck || index + 15 < size; + if (valid && writeAccess) + { + for (int i = 0; i < 4; ++i) + { + bufferRW.Store4((offset + index + 4 * i) << 2, data[i]); + } + } + return valid; + } + + bool LoadData(out bool data, uint index) + { + uint rawData = 0u; + data = false; + bool valid = LoadData(rawData, index); + if (valid) + { + data = rawData != 0; + } + return valid; + } + + bool StoreData(bool data, uint index) + { + uint rawData = data ? 1u : 0u; + return StoreData(rawData, index); + } +}; + +#endif //__VFX_BYTE_ADDRESS_BUFFER diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl.meta new file mode 100644 index 00000000000..e87292067ef --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ByteAddressBuffer.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f76d4424c62dd0f429d86962b6f7fea0 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl new file mode 100644 index 00000000000..44fb5100f18 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl @@ -0,0 +1,44 @@ +#ifndef __VFX_DEAD_LIST_DATA +#define __VFX_DEAD_LIST_DATA + +#include "Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUint.hlsl" + +struct VFXDeadListData +{ + VFXStructuredBuffer_uint counter; + VFXStructuredBuffer_uint counterCopy; + VFXStructuredBuffer_uint buffer; + + void Init(VFXStructuredBuffer_uint counter, VFXStructuredBuffer_uint counterCopy, VFXStructuredBuffer_uint buffer) + { + this.counter = counter; + this.counterCopy = counterCopy; + this.buffer = buffer; + } + + bool NewIndex(uint threadIndex, out uint particleIndex) + { + uint deadCount; + counterCopy.LoadData(deadCount, 0); + bool success = false; + particleIndex = 0; + + if (threadIndex < deadCount) + { + uint deadIndex; + counter.DoInterlockedAdd(0, -1, deadIndex); + success = buffer.LoadData(particleIndex, deadIndex - 1); + } + return success; + } + + bool DeleteIndex(uint index) + { + uint deadIndex; + counter.DoInterlockedAdd(0, 1, deadIndex); + + return buffer.StoreData(index, deadIndex); + } +}; + +#endif //__VFX_DEAD_LIST_DATA diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl.meta new file mode 100644 index 00000000000..36728ffa2be --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/DeadListData.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d95c77ffcfce98f49b04b626b444d68f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl new file mode 100644 index 00000000000..0ef4f21359e --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl @@ -0,0 +1,18 @@ +#ifndef __VFX_PARTICLE_SYSTEM_DATA +#define __VFX_PARTICLE_SYSTEM_DATA + +#include "Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/AttributeBuffer.hlsl" + +struct VFXParticleSystemData +{ + uint capacity; + //VFXSpace space; + //VFXBounds bounds; + + void Init(uint capacity) + { + this.capacity = capacity; + } +}; + +#endif //__VFX_PARTICLE_SYSTEM_DATA diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl.meta new file mode 100644 index 00000000000..b60c0928d4b --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ParticleSystemData.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ff4794bacd10e244f994a2496126b83b +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl new file mode 100644 index 00000000000..d93f0006568 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl @@ -0,0 +1,15 @@ +#ifndef __VFX_SPAWNER_DATA +#define __VFX_SPAWNER_DATA + +#include "Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUint.hlsl" + +struct SpawnerData +{ + VFXStructuredBuffer_uint instancingPrefixSum; + void Init(VFXStructuredBuffer_uint _instancingPrefixSum) + { + instancingPrefixSum = _instancingPrefixSum; + } +}; + +#endif //__VFX_SPAWNER_DATA diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl.meta new file mode 100644 index 00000000000..47e5381f942 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/SpawnerData.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f3edafe506379ad4f92654c55297293b +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl new file mode 100644 index 00000000000..a375cf19826 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl @@ -0,0 +1,166 @@ +// File can be included many times, for different types +// Requires defining __VFX_STRUCTURED_BUFFER_TYPE before including this file. +// __VFX_STRUCTURED_BUFFER_TYPE will be undefined at the end + +#ifdef __VFX_STRUCTURED_BUFFER_TYPE + +#define __VFX_STRUCTURED_BUFFER(type) VFXStructuredBuffer_##type +#define __VFX_STRUCTURED_BUFFER_EMPTY(type) __VFXEmptyStructuredBuffer_##type +#define __VFX_STRUCTURED_BUFFER_RW_EMPTY(type) __VFXEmptyRWStructuredBuffer_##_type + +StructuredBuffer<__VFX_STRUCTURED_BUFFER_TYPE> __VFX_STRUCTURED_BUFFER_EMPTY(__VFX_STRUCTURED_BUFFER_TYPE); +RWStructuredBuffer<__VFX_STRUCTURED_BUFFER_TYPE> __VFX_STRUCTURED_BUFFER_RW_EMPTY(__VFX_STRUCTURED_BUFFER_TYPE); + +struct __VFX_STRUCTURED_BUFFER(__VFX_STRUCTURED_BUFFER_TYPE) +{ + StructuredBuffer<__VFX_STRUCTURED_BUFFER_TYPE> buffer; + RWStructuredBuffer<__VFX_STRUCTURED_BUFFER_TYPE> bufferRW; + uint offset; + uint size; + //TODO: STRIDE? + bool readAccess; + bool writeAccess; + bool rangeCheck; + + void Init(StructuredBuffer<__VFX_STRUCTURED_BUFFER_TYPE> buffer, uint offset, uint size) + { + this.buffer = buffer; + this.bufferRW = __VFX_STRUCTURED_BUFFER_RW_EMPTY(__VFX_STRUCTURED_BUFFER_TYPE); + this.offset = offset; + this.size = size; + this.readAccess = true; + this.writeAccess = false; + this.rangeCheck = false; + } + + void Init(RWStructuredBuffer<__VFX_STRUCTURED_BUFFER_TYPE> buffer, uint offset, uint size) + { + this.buffer = __VFX_STRUCTURED_BUFFER_EMPTY(__VFX_STRUCTURED_BUFFER_TYPE); + this.bufferRW = buffer; + this.offset = offset; + this.size = size; + this.readAccess = true; + this.writeAccess = true; + this.rangeCheck = false; + } + + bool LoadData(out __VFX_STRUCTURED_BUFFER_TYPE data, uint index) + { + bool valid = !rangeCheck || index < size; + data = (__VFX_STRUCTURED_BUFFER_TYPE)0; + if (valid && readAccess) + { + if (writeAccess) + { + data = bufferRW[offset + index]; + } + else + { + data = buffer[offset + index]; + } + } + return valid; + } + + bool StoreData(__VFX_STRUCTURED_BUFFER_TYPE data, uint index) + { + bool valid = !rangeCheck || index < size; + if (valid && writeAccess) + { + bufferRW[offset + index] = data; + } + return valid; + } + +#if __VFX_STRUCTURED_BUFFER_TYPE == uint || __VFX_STRUCTURED_BUFFER_TYPE == int + void DoInterlockedAdd(uint index, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedAdd(bufferRW[index], value, original); + } + } + + void DoInterlockedAnd(uint index, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedAnd(bufferRW[index], value, original); + } + } + + void DoInterlockedOr(uint index, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedOr(bufferRW[index], value, original); + } + } + + void DoInterlockedXor(uint index, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedXor(bufferRW[index], value, original); + } + } + + void DoInterlockedMin(uint index, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedMin(bufferRW[index], value, original); + } + } + + void DoInterlockedMax(uint index, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedMax(bufferRW[index], value, original); + } + } + + void DoInterlockedCompareStore(uint index, __VFX_STRUCTURED_BUFFER_TYPE compare, __VFX_STRUCTURED_BUFFER_TYPE value) + { + if (writeAccess) + { + InterlockedCompareStore(bufferRW[index], compare, value); + } + } + + void DoInterlockedCompareExchange(uint index, __VFX_STRUCTURED_BUFFER_TYPE compare, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedCompareExchange(bufferRW[index], compare, value, original); + } + } +#endif + +#ifdef __VFX_STRUCTURED_BUFFER_EXCHANGE + void DoInterlockedExchange(uint index, __VFX_STRUCTURED_BUFFER_TYPE compare, __VFX_STRUCTURED_BUFFER_TYPE value, out __VFX_STRUCTURED_BUFFER_TYPE original) + { + original = 0; + if (writeAccess) + { + InterlockedExchange(bufferRW[index], compare, value); + } + } +#endif +}; + +#undef __VFX_STRUCTURED_BUFFER +#undef __VFX_STRUCTURED_BUFFER_EMPTY +#undef __VFX_STRUCTURED_BUFFER_RW_EMPTY +#undef __VFX_STRUCTURED_BUFFER_EXCHANGE + +#undef __VFX_STRUCTURED_BUFFER_TYPE +#endif // __VFX_STRUCTURED_BUFFER_TYPE diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl.meta new file mode 100644 index 00000000000..72a0e3e6d89 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 00c7ea3330da819409467c00dd7d3af8 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl new file mode 100644 index 00000000000..4ea3aae9526 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl @@ -0,0 +1,7 @@ +#ifndef __VFX_STRUCTURED_BUFFER_UINT +#define __VFX_STRUCTURED_BUFFER_UINT + +#define __VFX_STRUCTURED_BUFFER_TYPE uint +#include "Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBuffer.hlsl" + +#endif //__VFX_STRUCTURED_BUFFER_UINT diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl.meta new file mode 100644 index 00000000000..d607cc0a9a4 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/StructuredBufferUInt.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 833a2bbe5a6dc8341ae90e014f95ef29 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl new file mode 100644 index 00000000000..6a858f8b110 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl @@ -0,0 +1,14 @@ +#ifndef __VFX_THREAD_DATA +#define __VFX_THREAD_DATA + +struct ThreadData +{ + uint index; + + void Init(uint index) + { + this.index = index; + } +}; + +#endif //__VFX_THREAD_DATA diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl.meta new file mode 100644 index 00000000000..35455a6eee5 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Data/ThreadData.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4e890e2852548a34a95431a282c6d9d7 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates.meta new file mode 100644 index 00000000000..85765efd82a --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4e5e00053fedb544faf5a339916d0f56 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl new file mode 100644 index 00000000000..2791f43e539 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl @@ -0,0 +1,36 @@ + +//VFX_DECLARE_BINDING(ParticleData, ParticleDataBinding); +//VFX_DECLARE_BINDING(SpawnerData, SpawnDataBinding); + +//VFX_MAP_ATTRIBUTES(Attributes, ParticleDataBinding.particleAttributeBuffer); +//VFX_MAP_ATTRIBUTES(SourceAttributes, SpawnDataBinding.attributes); +void main(ThreadData threadData) +{ + Attributes particleAttributes; + particleAttributes.Init(); + + uint maxSpawnCount; + SpawnDataBinding.spawner.instancingPrefixSum.LoadData(maxSpawnCount, 0); + + if(threadData.index >= maxSpawnCount) + { + return; + } + + uint systemSeed = asuint(ContextData.y); + uint initSpawnIndex = asuint(ContextData.z); + + particleAttributes.particleId = initSpawnIndex + threadData.index; + particleAttributes.seed = WangHash(particleAttributes.particleId ^ systemSeed); + + VFXProcessBlocks(particleAttributes); + + if (particleAttributes.alive) + { + uint particleIndex; + if (ParticleDataBinding.NewParticle(threadData.index, particleIndex)) + { + ParticleDataBinding.particleAttributeBuffer.StoreData(particleAttributes, particleIndex); + } + } +} diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl.meta new file mode 100644 index 00000000000..81eb32377d5 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Init.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e0b73f7a5cf87c64fa581d87ec210906 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl new file mode 100644 index 00000000000..1b35ffe893e --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl @@ -0,0 +1,48 @@ + +struct VertexInput +{ + uint instanceID : SV_InstanceID; +}; + +struct Varyings +{ + float2 uv : TEXCOORD0; + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +Varyings vert(uint id : SV_VertexID, VertexInput vs_input) +{ + Varyings o = (Varyings)0; + + uint index = (id >> 2) + vs_input.instanceID * 2048; + + Attributes particleAttributes; + particleAttributes.Init(); + ParticleDataBinding.particleAttributeBuffer.LoadData(particleAttributes, index); + + if (particleAttributes.alive) + { + VFXProcessBlocks(particleAttributes); + + float3 position = particleAttributes.position; + float size = particleAttributes.size; + float2 varyingUV; + varyingUV.x = float(id & 1); + varyingUV.y = (id & 2) * 0.5f; + const float2 vOffsets = varyingUV.xy - 0.5f; + float3 inputVertexPosition = float3(vOffsets, 0.0f); + float3 vPos = position + inputVertexPosition * size ; + + + o.pos = TransformPositionVFXToClip(vPos); + o.uv = varyingUV; + o.color = float4(particleAttributes.color, particleAttributes.alpha); + } + return o; +} + +float4 frag(Varyings i) : SV_Target +{ + return mainTexture.Sample(default_sampler_Linear_Repeat, i.uv) * i.color; +} diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl.meta new file mode 100644 index 00000000000..b208dc61d9c --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Output.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2449738899b822e498f974f49bfd831a +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl new file mode 100644 index 00000000000..1a549294a44 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl @@ -0,0 +1,32 @@ + +//VFX_DECLARE_BINDING(ParticleData, ParticleDataBinding); + +//VFX_MAP_ATTRIBUTES(Attributes, ParticleDataBinding.particleAttributeBuffer); + +void main(ThreadData threadData) +{ + uint particleIndex = threadData.index; + uint maxParticleCount = asuint(ContextData.x); + + if(particleIndex >= maxParticleCount) + { + return; + } + + Attributes particleAttributes; + ParticleDataBinding.particleAttributeBuffer.LoadData(particleAttributes, particleIndex); + + if (particleAttributes.alive) + { + VFXProcessBlocks(particleAttributes); + + if (particleAttributes.alive) + { + ParticleDataBinding.particleAttributeBuffer.StoreData(particleAttributes, particleIndex); + } + else + { + ParticleDataBinding.DeleteParticle(particleIndex); + } + } +} diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl.meta b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl.meta new file mode 100644 index 00000000000..4a41a5713f9 --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Shaders/Temp/Templates/Update.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 154f27dff604d8c4283a53aecf798ece +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 5730cbf6b507a9a1f06a8cfb59ed4401f90eea6a Mon Sep 17 00:00:00 2001 From: Pema Malling Date: Wed, 1 Apr 2026 18:15:13 +0000 Subject: [PATCH 18/88] Better reprojection for URP SSR --- .../Runtime/History/DepthHistory.cs | 124 ++++++++++++++++++ .../Runtime/History/DepthHistory.cs.meta | 2 + .../Runtime/History/RawDepthHistory.cs | 103 +-------------- .../ScreenSpaceReflectionDepthHistory.cs | 18 +++ .../ScreenSpaceReflectionDepthHistory.cs.meta | 2 + .../ScreenSpaceReflectionPass.cs | 58 ++++++++ .../ComputeScreenSpaceReflection.hlsl | 48 ++++++- 7 files changed, 249 insertions(+), 106 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs.meta diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs new file mode 100644 index 00000000000..840d3076767 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs @@ -0,0 +1,124 @@ +using System; +using UnityEngine.Experimental.Rendering; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// Base class for depth history. + /// Format is the camera depth format or R32Float on platforms with limitations. + /// If TemporalAA is enabled the depth is jittered. + /// No mips. No depth pyramid. + /// MSAA is not supported and is resolved for the history. + /// XR is supported. + /// + public abstract class DepthHistory : CameraHistoryItem + { + private int[] m_Ids = new int[2]; + /// + /// The names to use for history items. + /// + protected readonly string[] m_Names = new[] + { + "DepthHistory0", + "DepthHistory1" + }; + private RenderTextureDescriptor m_Descriptor; + private Hash128 m_DescKey; + + /// + public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) + { + base.OnCreate(owner, typeId); + m_Ids[0] = MakeId(0); + m_Ids[1] = MakeId(1); + } + + /// + /// Get the current history texture. + /// Current history might not be valid yet. It is valid only after executing the producing render pass. + /// + /// Eye index, typically XRPass.multipassId. + /// The texture. + public RTHandle GetCurrentTexture(int eyeIndex = 0) + { + if ((uint)eyeIndex >= m_Ids.Length) + return null; + + return GetCurrentFrameRT(m_Ids[eyeIndex]); + } + + /// + /// Get the previous history texture. + /// + /// Eye index, typically XRPass.multipassId. + /// The texture. + public RTHandle GetPreviousTexture(int eyeIndex = 0) + { + if ((uint)eyeIndex >= m_Ids.Length) + return null; + + return GetPreviousFrameRT(m_Ids[eyeIndex]); + } + + private bool IsAllocated() + { + return GetCurrentTexture() != null; + } + + // True if the desc changed, graphicsFormat etc. + private bool IsDirty(ref RenderTextureDescriptor desc) + { + return m_DescKey != Hash128.Compute(ref desc); + } + + private void Alloc(ref RenderTextureDescriptor desc, bool xrMultipassEnabled) + { + // Generic type, we need double buffering. + AllocHistoryFrameRT(m_Ids[0], 2, ref desc, m_Names[0]); + + if(xrMultipassEnabled) + AllocHistoryFrameRT(m_Ids[1], 2, ref desc, m_Names[1]); + + m_Descriptor = desc; + m_DescKey = Hash128.Compute(ref desc); + } + + /// + /// Release the history texture(s). + /// + public override void Reset() + { + for(int i = 0; i < m_Ids.Length; i++) + ReleaseHistoryFrameRT(m_Ids[i]); + } + + internal RenderTextureDescriptor GetHistoryDescriptor(ref RenderTextureDescriptor cameraDesc) + { + var depthDesc = cameraDesc; + depthDesc.mipCount = 0; + depthDesc.msaaSamples = 1; // History copy should not have MSAA. + + return depthDesc; + } + + // Return true if the RTHandles were reallocated. + internal bool Update(ref RenderTextureDescriptor cameraDesc, bool xrMultipassEnabled) + { + if (cameraDesc.width > 0 && cameraDesc.height > 0 && (cameraDesc.depthStencilFormat != GraphicsFormat.None || cameraDesc.graphicsFormat != GraphicsFormat.None) ) + { + var historyDesc = GetHistoryDescriptor(ref cameraDesc); + + if (IsDirty(ref historyDesc)) + Reset(); + + if (!IsAllocated()) + { + Alloc(ref historyDesc, xrMultipassEnabled); + return true; + } + } + + return false; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs.meta new file mode 100644 index 00000000000..10e52e79634 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/DepthHistory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 691713c8a2b6fda46a6e558da3e63dd4 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/RawDepthHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/History/RawDepthHistory.cs index 968351b7fb2..67ee4a675c1 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/History/RawDepthHistory.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/RawDepthHistory.cs @@ -12,111 +12,14 @@ namespace UnityEngine.Rendering.Universal /// MSAA is not supported and is resolved for the history. /// XR is supported. /// - public sealed class RawDepthHistory : CameraHistoryItem + public sealed class RawDepthHistory : DepthHistory { - private int[] m_Ids = new int[2]; - private static readonly string[] m_Names = new[] - { - "RawDepthHistory0", - "RawDepthHistory1" - }; - private RenderTextureDescriptor m_Descriptor; - private Hash128 m_DescKey; - /// public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) { + m_Names[0] = "RawDepthHistory0"; + m_Names[1] = "RawDepthHistory1"; base.OnCreate(owner, typeId); - m_Ids[0] = MakeId(0); - m_Ids[1] = MakeId(1); - } - - /// - /// Get the current history texture. - /// Current history might not be valid yet. It is valid only after executing the producing render pass. - /// - /// Eye index, typically XRPass.multipassId. - /// The texture. - public RTHandle GetCurrentTexture(int eyeIndex = 0) - { - if ((uint)eyeIndex >= m_Ids.Length) - return null; - - return GetCurrentFrameRT(m_Ids[eyeIndex]); - } - - /// - /// Get the previous history texture. - /// - /// Eye index, typically XRPass.multipassId. - /// The texture. - public RTHandle GetPreviousTexture(int eyeIndex = 0) - { - if ((uint)eyeIndex >= m_Ids.Length) - return null; - - return GetPreviousFrameRT(m_Ids[eyeIndex]); - } - - private bool IsAllocated() - { - return GetCurrentTexture() != null; - } - - // True if the desc changed, graphicsFormat etc. - private bool IsDirty(ref RenderTextureDescriptor desc) - { - return m_DescKey != Hash128.Compute(ref desc); - } - - private void Alloc(ref RenderTextureDescriptor desc, bool xrMultipassEnabled) - { - // Generic type, we need double buffering. - AllocHistoryFrameRT(m_Ids[0], 2, ref desc, m_Names[0]); - - if(xrMultipassEnabled) - AllocHistoryFrameRT(m_Ids[1], 2, ref desc, m_Names[1]); - - m_Descriptor = desc; - m_DescKey = Hash128.Compute(ref desc); - } - - /// - /// Release the history texture(s). - /// - public override void Reset() - { - for(int i = 0; i < m_Ids.Length; i++) - ReleaseHistoryFrameRT(m_Ids[i]); - } - - internal RenderTextureDescriptor GetHistoryDescriptor(ref RenderTextureDescriptor cameraDesc) - { - var depthDesc = cameraDesc; - depthDesc.mipCount = 0; - depthDesc.msaaSamples = 1; // History copy should not have MSAA. - - return depthDesc; - } - - // Return true if the RTHandles were reallocated. - internal bool Update(ref RenderTextureDescriptor cameraDesc, bool xrMultipassEnabled) - { - if (cameraDesc.width > 0 && cameraDesc.height > 0 && (cameraDesc.depthStencilFormat != GraphicsFormat.None || cameraDesc.graphicsFormat != GraphicsFormat.None) ) - { - var historyDesc = GetHistoryDescriptor(ref cameraDesc); - - if (IsDirty(ref historyDesc)) - Reset(); - - if (!IsAllocated()) - { - Alloc(ref historyDesc, xrMultipassEnabled); - return true; - } - } - - return false; } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs new file mode 100644 index 00000000000..32138c42574 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs @@ -0,0 +1,18 @@ +#if URP_SCREEN_SPACE_REFLECTION +namespace UnityEngine.Rendering.Universal +{ + /// + /// Depth history used by Screen Space Reflection feature. Contains transparents if transparency support is enabled. + /// + internal sealed class ScreenSpaceReflectionDepthHistory : DepthHistory + { + /// + public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) + { + m_Names[0] = "ScreenSpaceReflectionDepthHistory0"; + m_Names[1] = "ScreenSpaceReflectionDepthHistory1"; + base.OnCreate(owner, typeId); + } + } +} +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs.meta new file mode 100644 index 00000000000..7f5c6ee36e1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthHistory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4a7b181b6b76dce42a8310f117510ab4 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs index ff4368857bd..4cabadbde5c 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs @@ -68,6 +68,7 @@ internal static class ShaderConstants internal static readonly int _CameraNormalsTexture = Shader.PropertyToID("_CameraNormalsTexture"); internal static readonly int _SmoothnessTexture = Shader.PropertyToID("_SmoothnessTexture"); internal static readonly int _MotionVectorColorTexture = Shader.PropertyToID("_MotionVectorColorTexture"); + internal static readonly int _LastFrameCameraDepthTexture = Shader.PropertyToID("_LastFrameCameraDepthTexture"); internal static readonly int _SsrDepthPyramidMaxMip = Shader.PropertyToID("_SsrDepthPyramidMaxMip"); internal static readonly int _SsrDepthPyramid = Shader.PropertyToID("_DepthPyramid"); internal static readonly int _MinimumSmoothnessAndFadeStart = Shader.PropertyToID("_MinimumSmoothnessAndFadeStart"); @@ -189,6 +190,7 @@ private class ScreenSpaceReflectionPassData internal TextureHandle blackTexture; // A black fallback texture. // Optional textures. + internal TextureHandle lastFrameCameraDepth; // Camera depth texture from last frame (only needed if AfterOpaque=false). May contain transparents if transparency support is on. internal TextureHandle lastFrameCameraColor; // Camera target texture from last frame (only needed if AfterOpaque=false). internal TextureHandle motionVectorColor; // Motion vectors (only needed if AfterOpaque=false). internal TextureHandle depthPyramidTexture; // Depth pyramid texture for HiZ marching (only needed if LinearMarching=false). @@ -294,6 +296,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // Set optional input textures to black by default. passData.lastFrameCameraColor = passData.blackTexture; + passData.lastFrameCameraDepth = passData.blackTexture; passData.motionVectorColor = passData.blackTexture; passData.depthPyramidTexture = passData.blackTexture; @@ -349,6 +352,18 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.motionVectorColor = motionVectorColorTexture; builder.UseTexture(passData.motionVectorColor); } + + // We also need depth from last frame to reject our reprojected positions. + { + cameraData.historyManager.RequestAccess(); + ScreenSpaceReflectionDepthHistory history = cameraData.historyManager.GetHistoryForRead(); + var depthHistoryTexture = history?.GetPreviousTexture(multipassId); + if (depthHistoryTexture != null) + { + passData.lastFrameCameraDepth = renderGraph.ImportTexture(depthHistoryTexture); + builder.UseTexture(passData.lastFrameCameraDepth); + } + } } builder.SetRenderFunc(static (ssrData, rgContext) => @@ -359,6 +374,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer ssrData.material.SetVector(ShaderConstants._SourceSize, PostProcessUtils.CalcShaderSourceSize(ssrData.cameraColor)); ssrData.material.SetTexture(ShaderConstants._CameraDepthTexture, ssrData.cameraDepth); + if (ssrData.afterOpaque) ssrData.material.SetTexture(ShaderConstants._CameraColorTexture, ssrData.cameraColor); // Somehow this texture can be null even when TextureHandle.IsValid() is true, guard against that. @@ -367,6 +383,13 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer else ssrData.material.SetTexture(ShaderConstants._CameraColorTexture, ssrData.lastFrameCameraColor); + if (ssrData.afterOpaque) + ssrData.material.SetTexture(ShaderConstants._LastFrameCameraDepthTexture, ssrData.blackTexture); + else if (((RTHandle)ssrData.lastFrameCameraDepth)?.rt == null) + ssrData.material.SetTexture(ShaderConstants._LastFrameCameraDepthTexture, ssrData.blackTexture); + else + ssrData.material.SetTexture(ShaderConstants._LastFrameCameraDepthTexture, ssrData.lastFrameCameraDepth); + ssrData.material.SetTexture(ShaderConstants._CameraNormalsTexture, ssrData.cameraNormalsTexture); ssrData.material.SetTexture(ShaderConstants._SmoothnessTexture, ssrData.smoothnessTexture); ssrData.material.SetTexture(ShaderConstants._MotionVectorColorTexture, ssrData.motionVectorColor); @@ -472,6 +495,8 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer } } + RenderDepthHistory(renderGraph, cameraData, cameraDepthTexture); + // Set global texture so subsequent passes can read it. if (m_AfterOpaque) resourceData.ssrTexture = TextureHandle.nullHandle; @@ -648,6 +673,39 @@ private void CreateRenderTextureHandles( else depthPyramidTexture = TextureHandle.nullHandle; } + + private static void RenderDepthHistory(RenderGraph renderGraph, UniversalCameraData cameraData, TextureHandle cameraDepthTexture) + { + if (cameraData.historyManager != null) + { + UniversalCameraHistory history = cameraData.historyManager; + + bool xrMultipassEnabled = false; + int multipassId = 0; +#if ENABLE_VR && ENABLE_XR_MODULE + xrMultipassEnabled = cameraData.xr.enabled && !cameraData.xr.singlePassEnabled; + multipassId = cameraData.xr.multipassId; +#endif + if (history.IsAccessRequested() && cameraDepthTexture.IsValid()) + { + var depthHistory = history.GetHistoryForWrite(); + if (depthHistory != null) + { + var tempColorDepthDesc = cameraData.cameraTargetDescriptor; + tempColorDepthDesc.graphicsFormat = GraphicsFormat.R32_SFloat; + tempColorDepthDesc.depthStencilFormat = GraphicsFormat.None; + + depthHistory.Update(ref tempColorDepthDesc, xrMultipassEnabled); + + if (depthHistory.GetCurrentTexture(multipassId) != null) + { + var depthHistoryTarget = renderGraph.ImportTexture(depthHistory.GetCurrentTexture(multipassId)); + renderGraph.AddBlitPass(cameraDepthTexture, depthHistoryTarget, Vector2.one, Vector2.zero, filterMode: BlitFilterMode.ClampNearest); + } + } + } + } + } } } #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl index 0cd7be78ab0..5d5222cedae 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl @@ -20,6 +20,8 @@ SAMPLER(sampler_SmoothnessTexture); TEXTURE2D_X(_MotionVectorColorTexture); SAMPLER(sampler_MotionVectorColorTexture); +TEXTURE2D_X(_LastFrameCameraDepthTexture); + SAMPLER(sampler_BlitTexture); // Params @@ -354,17 +356,13 @@ float4 ComputeSSR(Varyings input) : SV_Target float perceptualSmoothness = SampleSmoothness(positionNDC); UNITY_BRANCH if (perceptualSmoothness <= GetMinimumSmoothness()) { - #if UNITY_REVERSED_Z - float alpha = deviceDepth != 0; - #else - float alpha = deviceDepth != 1; - #endif // Output the framebuffer color -> // avoids bleeding black/uninitialized texels into reflections when blurring. // If the pixel is showing skybox, output 0 alpha -> // avoids bleeding the skybox color into reflections when blurring, which would cause haloing. // If the pixel is showing an object, output 1 alpha -> // avoids bleeding 0 alpha into reflections when blurring, which would cause peter-panning. + float alpha = deviceDepth != UNITY_RAW_FAR_CLIP_VALUE; return float4(SAMPLE_TEXTURE2D_X_LOD(_CameraColorTexture, sampler_CameraColorTexture, positionNDC, 0).rgb, alpha); } @@ -423,10 +421,48 @@ float4 ComputeSSR(Varyings input) : SV_Target UNITY_BRANCH if (hit) { #ifdef _USE_MOTION_VECTORS + // Reproject position + const float2 downsampledScreenSize = screenSizeWithInverse.zw * _Downsample; rayHitPosNDC.xy -= SampleMotionVector(rayHitPosNDC.xy); - #endif + const int2 topLeftReprojectedPixelPos = int2(rayHitPosNDC.xy * downsampledScreenSize - 0.5); + // Manually apply bilinear filter at the reprojected position + float3 hitColor = 0; + float weightSum = 0; + for (int dx = 0; dx < 2; dx++) + { + for (int dy = 0; dy < 2; dy++) + { + const int2 samplePixelPos = topLeftReprojectedPixelPos + int2(dx, dy); + const float2 samplePixelCenter = float2(samplePixelPos) + 0.5; + + // Reject samples that are off-screen + const bool isInView = all(0 <= samplePixelPos && samplePixelPos < downsampledScreenSize); + if (!isInView) + continue; + + // Reject samples that land on the skybox (unless we are intentionally reflecting skybox) + const float sampleDeviceDepth = LOAD_TEXTURE2D_X_LOD(_LastFrameCameraDepthTexture, samplePixelPos, 0).x; + if (sampleDeviceDepth == UNITY_RAW_FAR_CLIP_VALUE && rayHitPosNDC.z != UNITY_RAW_FAR_CLIP_VALUE) + continue; + + // Calculate bilinear weight and accumulate + const float weight = + (1.0f - abs(rayHitPosNDC.x * downsampledScreenSize.x - samplePixelCenter.x)) * + (1.0f - abs(rayHitPosNDC.y * downsampledScreenSize.y - samplePixelCenter.y)); + const float3 sampleColor = LOAD_TEXTURE2D_X_LOD(_CameraColorTexture, samplePixelPos, 0).rgb; + hitColor += weight * sampleColor; + weightSum += weight; + } + } + // If we got no valid samples, just return the existing framebuffer color. + if (weightSum == 0) + return float4(SAMPLE_TEXTURE2D_X_LOD(_CameraColorTexture, sampler_CameraColorTexture, positionNDC, 0).rgb, 0); + else + hitColor /= weightSum; + #else float3 hitColor = SAMPLE_TEXTURE2D_X_LOD(_CameraColorTexture, sampler_CameraColorTexture, rayHitPosNDC.xy, 0).rgb; + #endif // Fade rays pointing toward camera. float viewDotRay = dot(SafeNormalize(positionVS), rayDirVS); From 087f14c9bc7cd48342930270fbda4705feb32625 Mon Sep 17 00:00:00 2001 From: Alexey Zakharov Date: Thu, 2 Apr 2026 05:19:06 +0000 Subject: [PATCH 19/88] SRP: Replace BeginSample(string) and ProfilingSampler.Get() with inline ProfilerMarker fields --- .../GPUDriven/Batching/CPUDrawInstanceData.cs | 56 +++- .../Batching/InstanceCullingBatcher.cs | 73 +++-- .../CoreDataSystems/GPUInstanceDataBuffer.cs | 27 +- .../CoreDataSystems/InstanceDataSystem.cs | 177 ++++++++---- .../SceneProcessors/LODGroupProcessor.cs | 29 +- .../SceneProcessors/MeshRendererProcessor.cs | 200 ++++++++++---- .../SpeedTreeWindGPUDataUpdater.cs | 30 +- .../SceneProcessors/WorldProcessor.cs | 257 +++++++++++++----- .../Lighting/ProbeVolume/ProbeBrickIndex.cs | 29 +- .../Lighting/ProbeVolume/ProbeBrickPool.cs | 17 +- .../ProbeVolume/ProbeReferenceVolume.cs | 32 ++- .../ProbeVolume/ProbeVolumeGIContributor.cs | 96 +++++-- .../Runtime/PathTracing/BakeLightmapDriver.cs | 14 +- .../Runtime/PathTracing/LightmapExpansion.cs | 63 ++++- .../PathTracing/LightmapIntegration.cs | 42 ++- .../PathTracing/LightmapIntegrationHelpers.cs | 14 +- .../PathTracing/LightmapResourceCache.cs | 14 +- .../Runtime/PathTracing/UVFallbackBuffer.cs | 14 +- .../Compiler/NativePassCompiler.Markers.cs | 101 +++++++ .../NativePassCompiler.Markers.cs.meta | 2 + .../Compiler/NativePassCompiler.cs | 30 +- .../RenderGraph/RenderGraph.Compiler.cs | 2 +- .../Runtime/RenderGraph/RenderGraph.cs | 2 +- .../RenderGraph/RenderGraphProfilerMarkers.cs | 16 +- .../Runtime/STP/STP.cs | 34 ++- .../Runtime/Utilities/GPUSort/GPUSort.cs | 33 ++- 26 files changed, 1075 insertions(+), 329 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/CPUDrawInstanceData.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/CPUDrawInstanceData.cs index 3b180b11853..0877c9c4027 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/CPUDrawInstanceData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/CPUDrawInstanceData.cs @@ -4,12 +4,42 @@ using Unity.Collections; using Unity.Jobs; using Unity.Collections.LowLevel.Unsafe; -using UnityEngine.Profiling; +using Unity.Profiling; +using Unity.Profiling.LowLevel; namespace UnityEngine.Rendering { internal class CPUDrawInstanceData { + /// + /// Sorts and removes the destroyed draw instance indices from the CPU draw instance, batch, and + /// range data structures using binary search. Cost scales with total live draw instance count, not just the number removed. + /// + static readonly ProfilerMarker k_DestroyDrawInstanceIndices = + new ProfilerMarker(ProfilerCategory.Render, "DestroyDrawInstanceIndices.RemoveDrawInstanceIndices", MarkerFlags.VerbosityAdvanced); + + /// + /// Removes a batch of GPU instances from all CPU draw data structures. Sorts instance + /// handles, maps them to draw instance indices via a parallel job, then removes those + /// indices. Cost scales with total live draw instance count, not just the number removed. + /// + static readonly ProfilerMarker k_DestroyDrawInstances = + new ProfilerMarker(ProfilerCategory.Render, "DestroyDrawInstances", MarkerFlags.VerbosityAdvanced); + + /// + /// Sorts the destroyed instance handle array in parallel. A prerequisite for the + /// binary-search index-lookup job in DestroyDrawInstances. + /// + static readonly ProfilerMarker k_DestroyDrawInstancesParallelSort = + new ProfilerMarker(ProfilerCategory.Render, "DestroyDrawInstances.ParallelSort", MarkerFlags.VerbosityAdvanced); + + /// + /// Sorts the destroyed batch material ID array in parallel. A prerequisite for the + /// binary-search index-lookup job in DestroyMaterialDrawInstances. + /// + static readonly ProfilerMarker k_DestroyedBatchMaterialsParallelSort = + new ProfilerMarker(ProfilerCategory.Render, "DestroyedBatchMaterials.ParallelSort", MarkerFlags.VerbosityAdvanced); + public NativeList drawInstances => m_DrawInstances; public NativeParallelHashMap batchHash => m_BatchHash; public NativeList drawBatches => m_DrawBatches; @@ -106,18 +136,16 @@ public void RebuildDrawListsIfNeeded() public unsafe void DestroyDrawInstanceIndices(NativeArray drawInstanceIndicesToDestroy) { - Profiler.BeginSample("DestroyDrawInstanceIndices.ParallelSort"); + using var _ = k_DestroyDrawInstanceIndices.Auto(); + drawInstanceIndicesToDestroy.ParallelSort().Complete(); - Profiler.EndSample(); - Profiler.BeginSample("DestroyDrawInstanceIndices.RemoveDrawInstanceIndices"); CPUDrawInstanceDataBurst.RemoveDrawInstanceIndices(drawInstanceIndicesToDestroy, ref m_DrawInstances, ref m_RangeHash, ref m_BatchHash, ref m_DrawRanges, ref m_DrawBatches); - Profiler.EndSample(); } public unsafe void DestroyDrawInstances(NativeArray destroyedInstances) @@ -125,16 +153,17 @@ public unsafe void DestroyDrawInstances(NativeArray destroyedIns if (m_DrawInstances.IsEmpty || destroyedInstances.Length == 0) return; - Profiler.BeginSample("DestroyDrawInstances"); + using var _ = k_DestroyDrawInstances.Auto(); NeedsRebuild(); var destroyedInstancesSorted = new NativeArray(destroyedInstances, Allocator.TempJob); Assert.AreEqual(UnsafeUtility.SizeOf(), UnsafeUtility.SizeOf()); - Profiler.BeginSample("DestroyDrawInstances.ParallelSort"); - destroyedInstancesSorted.Reinterpret().ParallelSort().Complete(); - Profiler.EndSample(); + using (k_DestroyDrawInstancesParallelSort.Auto()) + { + destroyedInstancesSorted.Reinterpret().ParallelSort().Complete(); + } var drawInstanceIndicesToDestroy = new NativeList(m_DrawInstances.Length, Allocator.TempJob); @@ -150,8 +179,6 @@ public unsafe void DestroyDrawInstances(NativeArray destroyedIns destroyedInstancesSorted.Dispose(); drawInstanceIndicesToDestroy.Dispose(); - - Profiler.EndSample(); } public unsafe void DestroyMaterialDrawInstances(NativeArray destroyedBatchMaterials) @@ -163,9 +190,10 @@ public unsafe void DestroyMaterialDrawInstances(NativeArray destroyedBatch var destroyedBatchMaterialsSorted = new NativeArray(destroyedBatchMaterials, Allocator.TempJob); - Profiler.BeginSample("DestroyedBatchMaterials.ParallelSort"); - destroyedBatchMaterialsSorted.Reinterpret().ParallelSort().Complete(); - Profiler.EndSample(); + using (k_DestroyedBatchMaterialsParallelSort.Auto()) + { + destroyedBatchMaterialsSorted.Reinterpret().ParallelSort().Complete(); + } var drawInstanceIndicesToDestroy = new NativeList(m_DrawInstances.Length, Allocator.TempJob); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/InstanceCullingBatcher.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/InstanceCullingBatcher.cs index 2bf448c0de2..2b80d822f4f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/InstanceCullingBatcher.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/Batching/InstanceCullingBatcher.cs @@ -2,8 +2,9 @@ using System; using Unity.Collections; using Unity.Jobs; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; -using UnityEngine.Profiling; namespace UnityEngine.Rendering { @@ -47,6 +48,51 @@ public bool EqualsSourceData(in GPUDrivenMeshData otherData, NativeArray + /// Filters the incoming mesh IDs to find previously unseen ones, registers them with the + /// BatchRendererGroup, then fetches and stores their sub-mesh data. Cost scales with the + /// number of unique new meshes and their sub-mesh counts. + /// + static readonly ProfilerMarker k_RegisterMeshes = + new ProfilerMarker(ProfilerCategory.Render, "RegisterMeshes", MarkerFlags.VerbosityAdvanced); + + /// + /// Filters the incoming material IDs to find previously unseen ones, then registers them + /// with the BatchRendererGroup. Cost scales with the number of unique new materials. + /// + static readonly ProfilerMarker k_RegisterMaterials = + new ProfilerMarker(ProfilerCategory.Render, "RegisterMaterials", MarkerFlags.VerbosityAdvanced); + + /// + /// Unregisters each destroyed material from the BatchRendererGroup, removes it from the + /// material map, and removes all associated draw instances from CPU draw data structures. + /// + static readonly ProfilerMarker k_DestroyMaterials = + new ProfilerMarker(ProfilerCategory.Render, "DestroyMaterials", MarkerFlags.VerbosityAdvanced); + + /// + /// Unregisters each destroyed mesh from the BatchRendererGroup, disposes its sub-mesh + /// data, and removes it from the mesh map. + /// + static readonly ProfilerMarker k_DestroyMeshes = + new ProfilerMarker(ProfilerCategory.Render, "DestroyMeshes", MarkerFlags.VerbosityAdvanced); + + /// + /// Removes stale draw instances for the given instances, then creates new draw batches + /// by grouping instances by mesh, material, and render state. Marks the draw lists dirty + /// for rebuild on next cull. + /// + static readonly ProfilerMarker k_BuildBatches = + new ProfilerMarker(ProfilerCategory.Render, "BuildBatches", MarkerFlags.VerbosityAdvanced); + + /// + /// Registers any new meshes and materials in the update batch, then rebuilds draw batches + /// for the affected instances. Combines RegisterMeshes, RegisterMaterials, + /// and BuildBatches in a single scope. + /// + static readonly ProfilerMarker k_RegisterAndBuildBatches = + new ProfilerMarker(ProfilerCategory.Render, "RegisterAndBuildBatches"); + private GPUResidentContext m_GRDContext; private InstanceDataSystem m_InstanceDataSystem; private LODGroupDataSystem m_LODGroupDataSystem; @@ -212,7 +258,8 @@ private void OnFetchMeshesDataForRegistration(NativeArray meshIDs, private void RegisterMeshes(JaggedSpan meshIDs) { - Profiler.BeginSample("RegisterMeshes"); + using var _ = k_RegisterMeshes.Auto(); + var jobRanges = JaggedJobRange.FromSpanWithMaxBatchSize(meshIDs, FindNonRegisteredInstanceIDsJob.MaxBatchSize, Allocator.TempJob); var newMeshSet = new NativeParallelHashSet(meshIDs.totalLength, Allocator.TempJob); @@ -245,12 +292,12 @@ private void RegisterMeshes(JaggedSpan meshIDs) jobRanges.Dispose(); newMeshSet.Dispose(); - Profiler.EndSample(); } private void RegisterMaterials(JaggedSpan materials) { - Profiler.BeginSample("RegisterMaterials"); + using var _ = k_RegisterMaterials.Auto(); + var jobRanges = JaggedJobRange.FromSpanWithMaxBatchSize(materials, FindNonRegisteredInstanceIDsJob.MaxBatchSize, Allocator.TempJob); var newMaterialIDSet = new NativeParallelHashSet(materials.totalLength, Allocator.TempJob); @@ -287,7 +334,6 @@ private void RegisterMaterials(JaggedSpan materials) jobRanges.Dispose(); newMaterialIDSet.Dispose(); - Profiler.EndSample(); } private void OnFetchMeshesDataForUpdate(NativeArray meshIDs, @@ -388,8 +434,7 @@ public void DestroyMaterials(NativeArray destroyedInstanceIDs) if (destroyedInstanceIDs.Length == 0) return; - Profiler.BeginSample("DestroyMaterials"); - + using var _ = k_DestroyMaterials.Auto(); var destroyedBatchMaterials = new NativeList(destroyedInstanceIDs.Length, Allocator.TempJob); foreach (EntityId instanceID in destroyedInstanceIDs) @@ -406,8 +451,6 @@ public void DestroyMaterials(NativeArray destroyedInstanceIDs) m_DrawInstanceData.DestroyMaterialDrawInstances(destroyedBatchMaterials.AsArray()); destroyedBatchMaterials.Dispose(); - - Profiler.EndSample(); } public void DestroyMeshes(NativeArray destroyedInstanceIDs) @@ -415,7 +458,7 @@ public void DestroyMeshes(NativeArray destroyedInstanceIDs) if (destroyedInstanceIDs.Length == 0) return; - Profiler.BeginSample("DestroyMeshes"); + using var _ = k_DestroyMeshes.Auto(); foreach (EntityId instanceID in destroyedInstanceIDs) { @@ -426,13 +469,11 @@ public void DestroyMeshes(NativeArray destroyedInstanceIDs) m_BRG.UnregisterMesh(meshData.meshID); } } - - Profiler.EndSample(); } public void BuildBatches(NativeArray instances) { - Profiler.BeginSample("BuildBatches"); + using var _ = k_BuildBatches.Auto(); DestroyDrawInstances(instances); @@ -453,13 +494,11 @@ public void BuildBatches(NativeArray instances) ref drawInstances); m_DrawInstanceData.NeedsRebuild(); - - Profiler.EndSample(); } public void RegisterAndBuildBatches(NativeArray instances, in MeshRendererUpdateBatch updateBatch) { - Profiler.BeginSample("RegisterAndBuildBatches"); + using var _ = k_RegisterAndBuildBatches.Auto(); if (updateBatch.HasAnyComponent(MeshRendererComponentMask.Material)) RegisterMaterials(updateBatch.materialIDs); @@ -468,8 +507,6 @@ public void RegisterAndBuildBatches(NativeArray instances, in Me RegisterMeshes(updateBatch.meshIDs); BuildBatches(instances); - - Profiler.EndSample(); } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/GPUInstanceDataBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/GPUInstanceDataBuffer.cs index 70a83ee54ee..adf0ed4727f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/GPUInstanceDataBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/GPUInstanceDataBuffer.cs @@ -6,8 +6,9 @@ using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; -using UnityEngine.Profiling; namespace UnityEngine.Rendering { @@ -27,6 +28,22 @@ enum GPUInstanceDataBufferConstants // See GPU Archetype PR for details https://github.cds.internal.unity3d.com/unity/unity/pull/50000 internal class GPUInstanceDataBuffer : IDisposable { + /// + /// Maps CPU instance handles to their packed GPU indices in parallel using the archetype + /// prefix-sum table. Results are written into the caller-provided gpuIndices array + /// for use by the upload scatter pass. + /// + static readonly ProfilerMarker k_QueryInstanceGPUIndices = + new ProfilerMarker(ProfilerCategory.Render, "QueryInstanceGPUIndices", MarkerFlags.VerbosityAdvanced); + + /// + /// Uploads dirty per-instance component data to the GPU buffer through a scatter-write compute + /// shader. Includes CPU-side buffer setup and an immediate command buffer flush. Cost scales + /// with the number of instances and written component types. + /// + static readonly ProfilerMarker k_UploadGPUInstanceData = + new ProfilerMarker(ProfilerCategory.Render, "UploadGPUInstanceData", MarkerFlags.VerbosityAdvanced); + //@ For now 1Gb but this is should be smaller for OpenGL ES 3.1 public const int MaxGPUInstancDataBufferSize = 1024 * 1024 * 1024; @@ -148,7 +165,7 @@ public void QueryInstanceGPUIndices(in RenderWorld renderWorld, NativeArray scatterGPUIndices) @@ -170,7 +185,7 @@ public void UploadDataToGPU(CommandBuffer cmd, GraphicsBuffer uploadBuffer, in G if (uploadData.length == 0) return; - Profiler.BeginSample("UploadGPUInstanceData"); + using var _ = k_UploadGPUInstanceData.Auto(); Assert.IsTrue(scatterGPUIndices.Length <= uploadData.length); @@ -214,8 +229,6 @@ public void UploadDataToGPU(CommandBuffer cmd, GraphicsBuffer uploadBuffer, in G Graphics.ExecuteCommandBuffer(cmd); cmd.Clear(); - - Profiler.EndSample(); } public void SetGPULayout(CommandBuffer cmd, ref GPUArchetypeManager archetypeManager, in GPUInstanceDataBufferLayout newLayout, bool submitCmdBuffer) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/InstanceDataSystem.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/InstanceDataSystem.cs index a743ae0569c..78f0c8c9941 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/InstanceDataSystem.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/CoreDataSystems/InstanceDataSystem.cs @@ -5,8 +5,8 @@ using Unity.Jobs; using Unity.Mathematics; using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; -using UnityEngine.Profiling; namespace UnityEngine.Rendering { @@ -44,6 +44,91 @@ internal partial class InstanceDataSystem : IDisposable private readonly int[] m_ScratchWindParamAddressArray = new int[k_STMaxWindParamsCount * 4]; + /// + /// Runs light probe interpolation and tetrahedron cache update jobs for all instances in + /// the probe update queue. Computes SH coefficients and occlusion values per instance. + /// Cost scales with the number of instances that use blended light probes. + /// + static readonly ProfilerMarker k_InterpolateProbesAndUpdateTetrahedronCache = + new ProfilerMarker(ProfilerCategory.Render, "InterpolateProbesAndUpdateTetrahedronCache", MarkerFlags.VerbosityAdvanced); + + /// + /// Uploads SH and occlusion probe data to the GPU instance buffer via a compute shader + /// scatter-write. Includes a ComputeBuffer.SetData call and an immediate dispatch. + /// + static readonly ProfilerMarker k_DispatchProbeUpdateCommand = + new ProfilerMarker(ProfilerCategory.Render, "DispatchProbeUpdateCommand", MarkerFlags.VerbosityAdvanced); + + /// + /// Uploads previous-frame transform matrices to the GPU instance buffer via a compute + /// shader scatter-write to enable per-object motion vectors. Includes a + /// ComputeBuffer.SetData call and an immediate dispatch. + /// + static readonly ProfilerMarker k_DispatchMotionUpdateCommand = + new ProfilerMarker(ProfilerCategory.Render, "DispatchMotionUpdateCommand", MarkerFlags.VerbosityAdvanced); + + /// + /// Uploads object-to-world and world-to-object matrices to the GPU instance buffer via + /// a compute shader scatter-write. Optionally uploads bounding spheres when enabled. + /// Includes ComputeBuffer.SetData calls and an immediate dispatch. + /// + static readonly ProfilerMarker k_DispatchTransformUpdateCommand = + new ProfilerMarker(ProfilerCategory.Render, "DispatchTransformUpdateCommand", MarkerFlags.VerbosityAdvanced); + + /// + /// Copies current-frame SpeedTree wind parameters into the history slots in the GPU + /// instance buffer via a compute shader scatter-write, enabling wind continuity across + /// frames. + /// + static readonly ProfilerMarker k_DispatchWindDataCopyHistory = + new ProfilerMarker(ProfilerCategory.Render, "DispatchWindDataCopyHistory", MarkerFlags.VerbosityAdvanced); + + /// + /// Transfers CPU staging buffers to ComputeBuffer slots on the GPU synchronously. + /// Appears inside each dispatch marker; cost scales with the size of the data being + /// uploaded and stalls the CPU until the transfer completes. + /// + static readonly ProfilerMarker k_ComputeBufferSetData = + new ProfilerMarker(ProfilerCategory.Render, "ComputeBuffer.SetData", MarkerFlags.VerbosityAdvanced); + + /// + /// Allocates temporary NativeArray staging buffers for the transform and probe + /// update queues. Allocates additional probe arrays only when any instance uses blended + /// light probes. + /// + static readonly ProfilerMarker k_AllocateBuffers = + new ProfilerMarker(ProfilerCategory.Render, "AllocateBuffers", MarkerFlags.VerbosityAdvanced); + + /// + /// Runs the TransformUpdateJob and optionally the ProbesUpdateJob in + /// parallel, writing transform packets and SH data into the staging queues consumed by + /// the subsequent GPU dispatch commands. + /// + static readonly ProfilerMarker k_UpdateTransformsAndProbes = + new ProfilerMarker(ProfilerCategory.Render, "UpdateTransformsAndProbes", MarkerFlags.VerbosityAdvanced); + + /// + /// Runs UpdateRendererInstancesJob in parallel to write bounds, LOD group, + /// render settings, and other per-instance renderer data into the render world for the + /// given update batch. + /// + static readonly ProfilerMarker k_UpdateInstanceData = + new ProfilerMarker(ProfilerCategory.Render, "UpdateInstanceData", MarkerFlags.VerbosityAdvanced); + + /// + /// Looks up the InstanceHandle for each renderer entity ID in parallel using the + /// renderer-to-instance map, writing results into the caller-provided instances array. + /// + static readonly ProfilerMarker k_QueryRendererInstances = + new ProfilerMarker(ProfilerCategory.Render, "QueryRendererInstances", MarkerFlags.VerbosityAdvanced); + + /// + /// Recomputes the ground-truth total tree count from renderer settings and asserts it + /// matches the cached value. Only runs when deep validation is enabled. + /// + static readonly ProfilerMarker k_DeepValidateTotalTreeCount = + new ProfilerMarker(ProfilerCategory.Render, "DeepValidate.TotalTreeCount", MarkerFlags.VerbosityAdvanced); + public NativeReference archetypeManager => m_ArchetypeManager; public ref DefaultGPUComponents defaultGPUComponents => ref m_DefaultGPUComponents; public bool hasBoundingSpheres => m_EnableBoundingSpheres; @@ -202,7 +287,7 @@ private void InterpolateProbesAndUpdateTetrahedronCache(int queueCount, NativeAr NativeArray probeUpdateDataQueue, NativeArray probeOcclusionUpdateDataQueue) { - Profiler.BeginSample("InterpolateProbesAndUpdateTetrahedronCache"); + using var _ = k_InterpolateProbesAndUpdateTetrahedronCache.Auto(); ScheduleInterpolateProbesAndUpdateTetrahedronCache(queueCount, probeUpdateInstanceQueue, @@ -211,8 +296,6 @@ private void InterpolateProbesAndUpdateTetrahedronCache(int queueCount, NativeAr probeUpdateDataQueue, probeOcclusionUpdateDataQueue) .Complete(); - - Profiler.EndSample(); } private void DispatchProbeUpdateCommand(int queueCount, @@ -220,17 +303,19 @@ private void DispatchProbeUpdateCommand(int queueCount, NativeArray probeUpdateDataQueue, NativeArray probeOcclusionUpdateDataQueue) { - Profiler.BeginSample("DispatchProbeUpdateCommand"); + using var _ = k_DispatchProbeUpdateCommand.Auto(); + EnsureProbeBuffersCapacity(queueCount); var gpuIndices = new NativeArray(queueCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); m_InstanceDataBuffer.QueryInstanceGPUIndices(m_RenderWorld, probeInstanceQueue.GetSubArray(0, queueCount), gpuIndices); - Profiler.BeginSample("ComputeBuffer.SetData"); - m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, queueCount); - m_ProbeUpdateDataQueueBuffer.SetData(probeUpdateDataQueue, 0, 0, queueCount); - m_ProbeOcclusionUpdateDataQueueBuffer.SetData(probeOcclusionUpdateDataQueue, 0, 0, queueCount); - Profiler.EndSample(); + using (k_ComputeBufferSetData.Auto()) + { + m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, queueCount); + m_ProbeUpdateDataQueueBuffer.SetData(probeUpdateDataQueue, 0, 0, queueCount); + m_ProbeOcclusionUpdateDataQueueBuffer.SetData(probeOcclusionUpdateDataQueue, 0, 0, queueCount); + } m_TransformUpdateCS.SetInt(InstanceTransformUpdateIDs._ProbeUpdateQueueCount, queueCount); m_TransformUpdateCS.SetInt(InstanceTransformUpdateIDs._SHUpdateVec4Offset, m_InstanceDataBuffer.GetComponentGPUUIntOffset(m_DefaultGPUComponents.shCoefficients)); @@ -241,20 +326,21 @@ private void DispatchProbeUpdateCommand(int queueCount, m_TransformUpdateCS.Dispatch(m_ProbeUpdateKernel, (queueCount + 63) / 64, 1, 1); gpuIndices.Dispose(); - Profiler.EndSample(); } private void DispatchMotionUpdateCommand(int motionQueueCount, NativeArray transformInstanceQueue) { - Profiler.BeginSample("DispatchMotionUpdateCommand"); + using var _ = k_DispatchMotionUpdateCommand.Auto(); + EnsureTransformBuffersCapacity(motionQueueCount); var gpuIndices = new NativeArray(motionQueueCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); m_InstanceDataBuffer.QueryInstanceGPUIndices(m_RenderWorld, transformInstanceQueue.GetSubArray(0, motionQueueCount), gpuIndices); - Profiler.BeginSample("ComputeBuffer.SetData"); - m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, motionQueueCount); - Profiler.EndSample(); + using (k_ComputeBufferSetData.Auto()) + { + m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, motionQueueCount); + } m_TransformUpdateCS.SetInt(InstanceTransformUpdateIDs._TransformUpdateQueueCount, motionQueueCount); m_TransformUpdateCS.SetInt(InstanceTransformUpdateIDs._TransformUpdateOutputL2WVec4Offset, m_InstanceDataBuffer.GetComponentGPUUIntOffset(m_DefaultGPUComponents.objectToWorld)); @@ -266,7 +352,6 @@ private void DispatchMotionUpdateCommand(int motionQueueCount, NativeArray updateDataQueue, NativeArray boundingSphereUpdateDataQueue) { - Profiler.BeginSample("DispatchTransformUpdateCommand"); + using var _ = k_DispatchTransformUpdateCommand.Auto(); + EnsureTransformBuffersCapacity(transformQueueCount); int transformQueueDataSize; @@ -296,12 +382,13 @@ private void DispatchTransformUpdateCommand(bool initialize, var gpuIndices = new NativeArray(transformQueueCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); m_InstanceDataBuffer.QueryInstanceGPUIndices(m_RenderWorld, transformInstanceQueue.GetSubArray(0, transformQueueCount), gpuIndices); - Profiler.BeginSample("ComputeBuffer.SetData"); - m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, transformQueueCount); - m_TransformUpdateDataQueueBuffer.SetData(updateDataQueue, 0, 0, transformQueueDataSize); - if (m_EnableBoundingSpheres) - m_BoundingSpheresUpdateDataQueueBuffer.SetData(boundingSphereUpdateDataQueue, 0, 0, transformQueueCount); - Profiler.EndSample(); + using (k_ComputeBufferSetData.Auto()) + { + m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, transformQueueCount); + m_TransformUpdateDataQueueBuffer.SetData(updateDataQueue, 0, 0, transformQueueDataSize); + if (m_EnableBoundingSpheres) + m_BoundingSpheresUpdateDataQueueBuffer.SetData(boundingSphereUpdateDataQueue, 0, 0, transformQueueCount); + } m_TransformUpdateCS.SetInt(InstanceTransformUpdateIDs._TransformUpdateQueueCount, transformQueueCount); m_TransformUpdateCS.SetInt(InstanceTransformUpdateIDs._TransformUpdateOutputL2WVec4Offset, m_InstanceDataBuffer.GetComponentGPUUIntOffset(m_DefaultGPUComponents.objectToWorld)); @@ -320,21 +407,21 @@ private void DispatchTransformUpdateCommand(bool initialize, m_TransformUpdateCS.Dispatch(kernel, (transformQueueCount + 63) / 64, 1, 1); gpuIndices.Dispose(); - Profiler.EndSample(); } private void DispatchWindDataCopyHistoryCommand(NativeArray gpuIndices) { - Profiler.BeginSample("DispatchWindDataCopyHistory"); + using var _ = k_DispatchWindDataCopyHistory.Auto(); int kernel = m_WindDataCopyHistoryKernel; int instancesCount = gpuIndices.Length; EnsureIndexQueueBufferCapacity(instancesCount); - Profiler.BeginSample("ComputeBuffer.SetData"); - m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, instancesCount); - Profiler.EndSample(); + using (k_ComputeBufferSetData.Auto()) + { + m_UpdateIndexQueueBuffer.SetData(gpuIndices, 0, 0, instancesCount); + } m_WindDataUpdateCS.SetInt(InstanceWindDataUpdateIDs._WindDataQueueCount, instancesCount); for (int i = 0; i < k_STMaxWindParamsCount; ++i) @@ -347,8 +434,6 @@ private void DispatchWindDataCopyHistoryCommand(NativeArray gp m_WindDataUpdateCS.SetBuffer(kernel, InstanceWindDataUpdateIDs._WindDataUpdateIndexQueue, m_UpdateIndexQueueBuffer); m_WindDataUpdateCS.SetBuffer(kernel, InstanceWindDataUpdateIDs._WindDataBuffer, m_InstanceDataBuffer.nativeBuffer); m_WindDataUpdateCS.Dispatch(kernel, (instancesCount + 63) / 64, 1, 1); - - Profiler.EndSample(); } private unsafe void UpdateInstanceMotionsDataInternal() @@ -384,7 +469,7 @@ private unsafe void UpdateInstanceTransformsData(bool initialize, if (instances.Length == 0) return; - Profiler.BeginSample("AllocateBuffers"); + k_AllocateBuffers.Begin(); var transformUpdateInstanceQueue = new NativeArray(instances.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); // When we reinitialize we have the current and the previous matrices per transform. var transformUpdateDataQueue = new NativeArray(initialize ? instances.Length * 2 : instances.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); @@ -406,11 +491,11 @@ private unsafe void UpdateInstanceTransformsData(bool initialize, probeOcclusionUpdateDataQueue = new NativeArray(instances.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); } - Profiler.EndSample(); + k_AllocateBuffers.End(); var transformJobRanges = JaggedJobRange.FromSpanWithMaxBatchSize(jaggedLocalToWorldMatrices, TransformUpdateJob.MaxBatchSize, Allocator.TempJob); - Profiler.BeginSample("UpdateTransformsAndProbes"); + k_UpdateTransformsAndProbes.Begin(); var transformQueueCount = 0; int probesQueueCount = 0; @@ -448,7 +533,7 @@ private unsafe void UpdateInstanceTransformsData(bool initialize, JobHandle.CombineDependencies(transformJobHandle, probesJobHandle).Complete(); - Profiler.EndSample(); + k_UpdateTransformsAndProbes.End(); if (probesQueueCount > 0) { @@ -681,7 +766,8 @@ public unsafe void FreeInstances(NativeArray instances) public void UpdateInstanceData(NativeArray instances, in MeshRendererUpdateBatch updateBatch, NativeParallelHashMap lodGroupDataMap) { - Profiler.BeginSample("UpdateInstanceData"); + using var _ = k_UpdateInstanceData.Auto(); + Assert.IsTrue(instances.Length == updateBatch.TotalLength); var jobRanges = JaggedJobRange.FromSpanWithRelaxedBatchSize(updateBatch.instanceIDs, 128, Allocator.TempJob); @@ -697,7 +783,6 @@ public void UpdateInstanceData(NativeArray instances, in MeshRen .RunParallel(jobRanges); jobRanges.Dispose(); - Profiler.EndSample(); } public GPUInstanceUploadData CreateInstanceUploadData(GPUComponentHandle component, int capacity, Allocator allocator) @@ -817,9 +902,10 @@ public void QueryRendererInstances(JaggedSpan jaggedRenderers, NativeArray instances, UnsafeAtomicCounter32 notFoundInstancesCount = default) { - Profiler.BeginSample("QueryRendererInstances"); - ScheduleQueryRendererInstancesJob(jaggedRenderers, instances, notFoundInstancesCount).Complete(); - Profiler.EndSample(); + using (k_QueryRendererInstances.Auto()) + { + ScheduleQueryRendererInstancesJob(jaggedRenderers, instances, notFoundInstancesCount).Complete(); + } } public JobHandle ScheduleQueryRendererInstancesJob(NativeArray renderers, NativeArray instances) @@ -928,14 +1014,13 @@ public void ValidateTotalTreeCount() if (!GPUResidentDrawer.EnableDeepValidation) return; - Profiler.BeginSample("DeepValidate.TotalTreeCount"); - - int totalTreeCountTruth = InstanceDataSystemBurst.ComputeTotalTreeCount(m_RenderWorld.rendererSettings); - - if (totalTreeCount != totalTreeCountTruth) - Debug.LogError($"Cached total tree count ({totalTreeCount}) does not match total tree count truth ({totalTreeCountTruth})."); + using (k_DeepValidateTotalTreeCount.Auto()) + { + int totalTreeCountTruth = InstanceDataSystemBurst.ComputeTotalTreeCount(m_RenderWorld.rendererSettings); - Profiler.EndSample(); + if (totalTreeCount != totalTreeCountTruth) + Debug.LogError($"Cached total tree count ({totalTreeCount}) does not match total tree count truth ({totalTreeCountTruth})."); + } #pragma warning restore CS0162 } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/LODGroupProcessor.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/LODGroupProcessor.cs index 1c1f870b031..45f31146213 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/LODGroupProcessor.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/LODGroupProcessor.cs @@ -1,13 +1,29 @@ #if !UNITY_WEBGL_RENDERER_ONLY using Unity.Collections; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; -using UnityEngine.Profiling; namespace UnityEngine.Rendering { internal class LODGroupProcessor { + /// + /// Frees GPU and CPU state for a set of destroyed LOD group instances by delegating to + /// LODGroupDataSystem.FreeLODGroups. + /// + static readonly ProfilerMarker k_DestroyLODGroupInstances = + new ProfilerMarker(ProfilerCategory.Render, "DestroyLODGroupInstances", MarkerFlags.VerbosityAdvanced); + + /// + /// Processes a LOD group update batch that allocates GPU instances for new groups and writes + /// group settings, reference point, world-space size, and LOD buffer data. Transform-only + /// batches skip allocation and update position and size only. + /// + static readonly ProfilerMarker k_ProcessLODGroupUpdateBatch = + new ProfilerMarker(ProfilerCategory.Render, "ProcessLODGroupUpdateBatch", MarkerFlags.VerbosityAdvanced); + private GPUDrivenProcessor m_GPUDrivenProcessor; private LODGroupDataSystem m_LODGroupDataSystem; @@ -19,9 +35,10 @@ public LODGroupProcessor(GPUDrivenProcessor gpuDrivenProcessor, GPUResidentConte public void DestroyInstances(NativeArray destroyedIDs) { - Profiler.BeginSample("DestroyLODGroupInstances"); - m_LODGroupDataSystem.FreeLODGroups(destroyedIDs); - Profiler.EndSample(); + using (k_DestroyLODGroupInstances.Auto()) + { + m_LODGroupDataSystem.FreeLODGroups(destroyedIDs); + } } public void ProcessGameObjectChanges(NativeArray changedLODGroups, bool transformOnly) @@ -34,7 +51,7 @@ public void ProcessUpdateBatch(in LODGroupUpdateBatch updateBatch) if (updateBatch.TotalLength == 0) return; - Profiler.BeginSample("ProcessLODGroupUpdateBatch"); + using var _ = k_ProcessLODGroupUpdateBatch.Auto(); if (updateBatch.updateMode == LODGroupUpdateBatchMode.MightIncludeNewInstances) { @@ -55,8 +72,6 @@ public void ProcessUpdateBatch(in LODGroupUpdateBatch updateBatch) m_LODGroupDataSystem.UpdateLODGroupTransforms(updateBatch); } - - Profiler.EndSample(); } void ProcessGameObjectUpdateBatch(in GPUDrivenLODGroupData inputData) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/MeshRendererProcessor.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/MeshRendererProcessor.cs index 69891f90688..0d5222a4f06 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/MeshRendererProcessor.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/MeshRendererProcessor.cs @@ -6,8 +6,8 @@ using Unity.Jobs; using Unity.Mathematics; using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; -using UnityEngine.Profiling; namespace UnityEngine.Rendering { @@ -20,6 +20,101 @@ public struct GPUComponentUploadSource public int componentSize; } + /// + /// Resolves renderer entity IDs to instance handles, removes their draw instances from + /// the culling batcher, then frees the instance handles from the instance data system. + /// + static readonly ProfilerMarker k_DestroyMeshRendererInstances = + new ProfilerMarker(ProfilerCategory.Render, "DestroyMeshRendererInstances", MarkerFlags.VerbosityAdvanced); + + /// + /// Compares incoming material and mesh data against the cached maps and returns the + /// subsets whose GPU-relevant data actually changed. Early-outs if nothing changed, + /// avoiding unnecessary renderer queries downstream. + /// + static readonly ProfilerMarker k_GetMaterialsAndMeshesWithChangedData = + new ProfilerMarker(ProfilerCategory.Render, "GetMaterialsAndMeshesWithChangedData", MarkerFlags.VerbosityAdvanced); + + /// + /// Sorts the excluded renderer ID array in parallel. A prerequisite for the binary-search + /// exclusion check in FindRenderersFromMaterialsOrMeshes. + /// + static readonly ProfilerMarker k_ProcessRendererMaterialAndMeshChangesSort = + new ProfilerMarker(ProfilerCategory.Render, "ProcessRendererMaterialAndMeshChanges.Sort", MarkerFlags.VerbosityAdvanced); + + /// + /// Scans all registered renderers to find those referencing any changed material or mesh, + /// excluding renderers in the sorted exclusion list. Cost scales with total registered + /// renderer count, not just the number of changed materials or meshes. + /// + static readonly ProfilerMarker k_FindRenderersFromMaterialsOrMeshes = + new ProfilerMarker(ProfilerCategory.Render, "FindRenderersFromMaterialsOrMeshes", MarkerFlags.VerbosityAdvanced); + + /// + /// Queries instance handles for all affected renderers, then calls + /// BuildBatches to rebuild their draw batches with the new material or mesh data. + /// + static readonly ProfilerMarker k_UpdateRenderers = + new ProfilerMarker(ProfilerCategory.Render, "UpdateRenderers"); + + /// + /// Processes a mesh renderer update batch end-to-end: allocates or reallocates GPU + /// instances, updates instance data, uploads component overrides, initializes or updates + /// transforms, and rebuilds draw batches. Skips stages not required by the batch's + /// component mask and update type. + /// + static readonly ProfilerMarker k_ProcessMeshRendererUpdateBatch = + new ProfilerMarker(ProfilerCategory.Render, "ProcessMeshRendererUpdateBatch"); + + /// + /// Writes per-instance GPU component override values into a CPU staging buffer via + /// parallel jobs, uploads the buffer to the GPU, then scatter-writes each component + /// into the instance data buffer. + /// + static readonly ProfilerMarker k_UploadGPUComponentOverrides = + new ProfilerMarker(ProfilerCategory.Render, "UploadGPUComponentOverrides", MarkerFlags.VerbosityAdvanced); + + /// + /// Verifies that no GPU archetype changes occurred for the updated instances by + /// re-evaluating renderer settings, lightmap, and GPU component masks. Only runs + /// when is enabled; skips + /// early if no archetype-affecting components are present in the batch. + /// + static readonly ProfilerMarker k_DeepValidationGPUArchetypesDidNotChange = + new ProfilerMarker(ProfilerCategory.Render, "DeepValidation.GPUArchetypesDidNotChange", MarkerFlags.VerbosityAdvanced); + + /// + /// Computes a GPU archetype handle for each instance in the update batch. When + /// blend probe usage, lightmap usage, and tree exclusion are all fully known, + /// resolves to a single shared archetype handle instead of one per instance. + /// + static readonly ProfilerMarker k_ComputeInstanceGPUArchetypes = + new ProfilerMarker(ProfilerCategory.Render, "ComputeInstanceGPUArchetypes", MarkerFlags.VerbosityAdvanced); + + /// + /// Builds the GPU component override upload source array from the jagged per-component + /// update list in the update batch. Skipped entirely when no GPU component overrides + /// are present. + /// + static readonly ProfilerMarker k_BuildGPUComponentOverrideUploadSources = + new ProfilerMarker(ProfilerCategory.Render, "BuildGPUComponentOverrideUploadSources", MarkerFlags.VerbosityAdvanced); + + /// + /// Completes all parallel component write jobs before uploading the buffer to the GPU. + /// This is a synchronous CPU stall; cost scales with the number of GPU component + /// override entries scheduled in the batch. + /// + static readonly ProfilerMarker k_SyncWriteGPUComponentJobs = + new ProfilerMarker(ProfilerCategory.Render, "SyncWriteGPUComponentJobs", MarkerFlags.VerbosityAdvanced); + + /// + /// Verifies that no instance in the batch uses blend probe lighting. Only runs when + /// is enabled; iterates all + /// instances in the batch to check their light probe usage. + /// + static readonly ProfilerMarker k_DeepValidationNoInstanceUsesBlendProbes = + new ProfilerMarker(ProfilerCategory.Render, "DeepValidation.NoInstanceUsesBlendProbes", MarkerFlags.VerbosityAdvanced); + private GPUDrivenProcessor m_GPUDrivenProcessor; private InstanceCullingBatcher m_CullingBatcher; private NativeReference m_ArchetypeManager; @@ -52,13 +147,14 @@ public void DestroyInstances(NativeArray destroyedRenderers) if (destroyedRenderers.Length == 0) return; - Profiler.BeginSample("DestroyMeshRendererInstances"); - var destroyedInstances = new NativeArray(destroyedRenderers.Length, Allocator.TempJob); - m_InstanceDataSystem.QueryRendererInstances(destroyedRenderers, destroyedInstances); - m_CullingBatcher.DestroyDrawInstances(destroyedInstances); - m_InstanceDataSystem.FreeInstances(destroyedInstances); - destroyedInstances.Dispose(); - Profiler.EndSample(); + using (k_DestroyMeshRendererInstances.Auto()) + { + var destroyedInstances = new NativeArray(destroyedRenderers.Length, Allocator.TempJob); + m_InstanceDataSystem.QueryRendererInstances(destroyedRenderers, destroyedInstances); + m_CullingBatcher.DestroyDrawInstances(destroyedInstances); + m_InstanceDataSystem.FreeInstances(destroyedInstances); + destroyedInstances.Dispose(); + } } public void ProcessGameObjectChanges(NativeArray changedRenderers) @@ -97,10 +193,13 @@ public void ProcessRendererMaterialAndMeshChanges(NativeArray excluded return; // Update the material/mesh maps and retrieve the IDs of the materials/meshes for which the data actually changed. - Profiler.BeginSample("GetMaterialsAndMeshesWithChangedData"); - NativeHashSet materialsWithChangedData = m_CullingBatcher.UpdateMaterialData(changedMaterials, changedMaterialDatas, Allocator.TempJob); - NativeHashSet meshesWithChangedData = m_CullingBatcher.UpdateMeshData(changedMeshes, Allocator.TempJob); - Profiler.EndSample(); + NativeHashSet materialsWithChangedData; + NativeHashSet meshesWithChangedData; + using (k_GetMaterialsAndMeshesWithChangedData.Auto()) + { + materialsWithChangedData = m_CullingBatcher.UpdateMaterialData(changedMaterials, changedMaterialDatas, Allocator.TempJob); + meshesWithChangedData = m_CullingBatcher.UpdateMeshData(changedMeshes, Allocator.TempJob); + } if (materialsWithChangedData.Count == 0 && meshesWithChangedData.Count == 0) { @@ -112,17 +211,21 @@ public void ProcessRendererMaterialAndMeshChanges(NativeArray excluded var sortedExcludedRenderers = new NativeArray(excludedRenderers, Allocator.TempJob); if (sortedExcludedRenderers.Length > 0) { - Profiler.BeginSample("ProcessRendererMaterialAndMeshChanges.Sort"); - sortedExcludedRenderers.Reinterpret().ParallelSort().Complete(); - Profiler.EndSample(); + using (k_ProcessRendererMaterialAndMeshChangesSort.Auto()) + { + sortedExcludedRenderers.Reinterpret().ParallelSort().Complete(); + } } - Profiler.BeginSample("FindRenderersFromMaterialsOrMeshes"); - var (renderersWithChangedMaterials, renderersWithChangeMeshes) = FindRenderersFromMaterialsOrMeshes(sortedExcludedRenderers, - materialsWithChangedData, - meshesWithChangedData, - Allocator.TempJob); - Profiler.EndSample(); + (NativeList renderersWithChangedMaterials, NativeList renderersWithChangeMeshes) rendererPair; + using (k_FindRenderersFromMaterialsOrMeshes.Auto()) + { + rendererPair = FindRenderersFromMaterialsOrMeshes(sortedExcludedRenderers, + materialsWithChangedData, + meshesWithChangedData, + Allocator.TempJob); + } + var (renderersWithChangedMaterials, renderersWithChangeMeshes) = rendererPair; materialsWithChangedData.Dispose(); meshesWithChangedData.Dispose(); @@ -135,25 +238,26 @@ public void ProcessRendererMaterialAndMeshChanges(NativeArray excluded return; } - Profiler.BeginSample("UpdateRenderers"); - var changedMaterialsCount = renderersWithChangedMaterials.Length; - var changedMeshesCount = renderersWithChangeMeshes.Length; - var totalCount = changedMaterialsCount + changedMeshesCount; - - var changedRenderers = new NativeArray(totalCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); - NativeArray.Copy(renderersWithChangedMaterials.AsArray(), changedRenderers, changedMaterialsCount); - NativeArray.Copy(renderersWithChangeMeshes.AsArray(), changedRenderers.GetSubArray(changedMaterialsCount, changedMeshesCount), changedMeshesCount); - - var changedInstances = new NativeArray(totalCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); - m_InstanceDataSystem.QueryRendererInstances(changedRenderers, changedInstances); - - m_CullingBatcher.BuildBatches(changedInstances); - - changedRenderers.Dispose(); - changedInstances.Dispose(); - renderersWithChangedMaterials.Dispose(); - renderersWithChangeMeshes.Dispose(); - Profiler.EndSample(); + using (k_UpdateRenderers.Auto()) + { + var changedMaterialsCount = renderersWithChangedMaterials.Length; + var changedMeshesCount = renderersWithChangeMeshes.Length; + var totalCount = changedMaterialsCount + changedMeshesCount; + + var changedRenderers = new NativeArray(totalCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + NativeArray.Copy(renderersWithChangedMaterials.AsArray(), changedRenderers, changedMaterialsCount); + NativeArray.Copy(renderersWithChangeMeshes.AsArray(), changedRenderers.GetSubArray(changedMaterialsCount, changedMeshesCount), changedMeshesCount); + + var changedInstances = new NativeArray(totalCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + m_InstanceDataSystem.QueryRendererInstances(changedRenderers, changedInstances); + + m_CullingBatcher.BuildBatches(changedInstances); + + changedRenderers.Dispose(); + changedInstances.Dispose(); + renderersWithChangedMaterials.Dispose(); + renderersWithChangeMeshes.Dispose(); + } } private (NativeList renderersWithMaterials, NativeList renderersWithMeshes) @@ -186,7 +290,7 @@ public unsafe void ProcessUpdateBatch(ref MeshRendererUpdateBatch updateBatch) if (updateBatch.TotalLength == 0) return; - Profiler.BeginSample("ProcessMeshRendererUpdateBatch"); + using var _ = k_ProcessMeshRendererUpdateBatch.Auto(); MeshRendererUpdateType updateType = updateBatch.updateType; bool anyInstanceUseBlendProbes = updateBatch.blendProbesUsage != MeshRendererUpdateBatch.BlendProbesUsage.AllDisabled; @@ -278,12 +382,11 @@ public unsafe void ProcessUpdateBatch(ref MeshRendererUpdateBatch updateBatch) instances.Dispose(); archetypes.Dispose(); componentUploadSources.Dispose(); - Profiler.EndSample(); } unsafe NativeArray ComputeInstanceGPUArchetypes(ref MeshRendererUpdateBatch updateBatch, GPUComponentSet overrideComponentSet, Allocator allocator) { - using (new ProfilerMarker("ComputeInstanceGPUArchetypes").Auto()) + using (k_ComputeInstanceGPUArchetypes.Auto()) { bool useSharedGPUArchetype = updateBatch.blendProbesUsage != MeshRendererUpdateBatch.BlendProbesUsage.Unknown && updateBatch.lightmapUsage != MeshRendererUpdateBatch.LightmapUsage.Unknown @@ -317,7 +420,7 @@ unsafe NativeArray BuildGPUComponentOverrideUploadSour return default; } - using (new ProfilerMarker("BuildGPUComponentOverrideUploadSources").Auto()) + using (k_BuildGPUComponentOverrideUploadSources.Auto()) { NativeArray uploadSources = new NativeArray(componentUpdates.Length, allocator); GPUComponentSet componentSet = default; @@ -334,7 +437,7 @@ void UploadGPUComponentOverrides(GPUComponentSet componentSet, NativeArray 0); - Profiler.BeginSample("UploadGPUComponentOverrides"); + using var _ = k_UploadGPUComponentOverrides.Auto(); GPUInstanceUploadData uploadData = m_InstanceDataSystem.CreateInstanceUploadData(componentSet, instances.Length, Allocator.TempJob); @@ -351,7 +454,7 @@ void UploadGPUComponentOverrides(GPUComponentSet componentSet, NativeArray instances) if (!GPUResidentDrawer.EnableDeepValidation) return; - using (new ProfilerMarker("DeepValidation.NoInstanceUsesBlendProbes").Auto()) + using (k_DeepValidationNoInstanceUsesBlendProbes.Auto()) { if (AnyInstanceUseBlendProbes(instances)) Debug.LogError("One instance has LightProbeUsage == LightProbeUsage.BlendProbes whereas it wasn't expected."); @@ -595,7 +697,7 @@ void ValidateGPUArchetypesDidNotChange(NativeArray instances, if (!GPUResidentDrawer.EnableDeepValidation) return; - using (new ProfilerMarker("DeepValidation.GPUArchetypesDidNotChange").Auto()) + using (k_DeepValidationGPUArchetypesDidNotChange.Auto()) { bool archetypeMightHaveChanged = updateBatch.HasAnyComponent(MeshRendererComponentMask.RendererSettings | MeshRendererComponentMask.Lightmap diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/SpeedTreeWindGPUDataUpdater.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/SpeedTreeWindGPUDataUpdater.cs index f909590f078..d9a47272913 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/SpeedTreeWindGPUDataUpdater.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/SpeedTreeWindGPUDataUpdater.cs @@ -2,15 +2,33 @@ #if ENABLE_TERRAIN_MODULE using System; using Unity.Collections; -using UnityEngine.Profiling; -using UnityEngine.Assertions; using Unity.Collections.LowLevel.Unsafe; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; +using UnityEngine.Assertions; namespace UnityEngine.Rendering { internal class SpeedTreeWindGPUDataUpdater : IDisposable { + /// + /// Queries compacted visibility masks to collect visible SpeedTree instances, then + /// triggers wind simulation updates and GPU uploads for them. In edit mode, processes + /// only newly-visible trees. In play mode, processes all visible trees every frame. + /// + static readonly ProfilerMarker k_UpdateGPUData = + new ProfilerMarker(ProfilerCategory.Render, "SpeedTreeGPUWindDataUpdater.UpdateGPUData", MarkerFlags.VerbosityAdvanced); + + /// + /// Advances SpeedTree wind simulation state for each visible tree, writes all wind + /// parameter vectors into a CPU staging buffer, uploads the buffer to the GPU, and + /// scatter-writes wind params into the instance data buffer. Called twice when + /// newly-visible trees need history initialization. + /// + static readonly ProfilerMarker k_UpdateSpeedTreeWindAndUploadWindParamsToGPU = + new ProfilerMarker(ProfilerCategory.Render, "SpeedTreeGPUWindDataUpdater.UpdateSpeedTreeWindAndUploadWindParamsToGPU", MarkerFlags.VerbosityAdvanced); + private InstanceDataSystem m_InstanceDataSystem; private InstanceCuller m_Culler; private ParallelBitArray m_ProcessedThisFrameTreeBits; @@ -48,7 +66,7 @@ public void UpdateGPUData() if (!compactedVisibilityMasks.IsCreated) return; - Profiler.BeginSample("SpeedTreeGPUWindDataUpdater.UpdateGPUData"); + using var _ = k_UpdateGPUData.Auto(); int maxInstancesCount = m_InstanceDataSystem.indexToHandle.Length; @@ -66,7 +84,7 @@ public void UpdateGPUData() if (visibleTreeRenderers.Length > 0) { - Profiler.BeginSample("SpeedTreeGPUWindDataUpdater.UpdateSpeedTreeWindAndUploadWindParamsToGPU"); + k_UpdateSpeedTreeWindAndUploadWindParamsToGPU.Begin(); // Become visible trees is a subset of visible trees. var becomeVisibleTreeRendererIDs = visibleTreeRenderers.AsArray().GetSubArray(0, becomeVisibleTreeInstancesCount); @@ -77,13 +95,11 @@ public void UpdateGPUData() UpdateSpeedTreeWindAndUploadWindParamsToGPU(visibleTreeRenderers.AsArray(), visibleTreeInstances.AsArray(), history: false); - Profiler.EndSample(); + k_UpdateSpeedTreeWindAndUploadWindParamsToGPU.End(); } visibleTreeRenderers.Dispose(); visibleTreeInstances.Dispose(); - - Profiler.EndSample(); } private unsafe void UpdateSpeedTreeWindAndUploadWindParamsToGPU(NativeArray treeRenderers, NativeArray treeInstances, bool history) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/WorldProcessor.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/WorldProcessor.cs index 1ad321d486e..8fe66256d0f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/WorldProcessor.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/SceneProcessors/WorldProcessor.cs @@ -3,12 +3,109 @@ using Unity.Burst; using Unity.Collections; using Unity.Jobs; -using UnityEngine.Profiling; +using Unity.Profiling; +using Unity.Profiling.LowLevel; namespace UnityEngine.Rendering { internal class WorldProcessor : IDisposable { + /// + /// Runs the full per-frame world update: fetches all pending scene changes, processes + /// camera, LOD group, mesh renderer, material, and mesh events, then flushes all queued + /// update batches and motion updates. + /// + static readonly ProfilerMarker k_Update = + new ProfilerMarker(ProfilerCategory.Render, "WorldProcessor.Update"); + + /// + /// Drains all pending change records from the ObjectDispatcher for meshes, + /// materials, cameras, LOD groups, mesh renderers, and their transforms into temporary + /// native arrays for processing this frame. + /// + static readonly ProfilerMarker k_FetchAllChanges = + new ProfilerMarker(ProfilerCategory.Render, "FetchAllChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Registers newly added cameras with and removes destroyed cameras from the instance + /// data system. + /// + static readonly ProfilerMarker k_ProcessCameraChanges = + new ProfilerMarker(ProfilerCategory.Render, "ProcessCameraChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Disables GPU-driven rendering for renderers that use unsupported materials, then + /// destroys their GPU and CPU instances. + /// + static readonly ProfilerMarker k_DestroyUnsupportedRenderers = + new ProfilerMarker(ProfilerCategory.Render, "DestroyUnsupportedRenderers", MarkerFlags.VerbosityAdvanced); + + /// + /// Queries all renderer instances that reference each destroyed mesh, removes their draw + /// instances from the culling batcher, then unregisters the meshes from the + /// BatchRendererGroup. + /// + static readonly ProfilerMarker k_DestroyMeshes = + new ProfilerMarker(ProfilerCategory.Render, "DestroyMeshes", MarkerFlags.VerbosityAdvanced); + + /// + /// Fetches and processes full LOD group data (settings, bounds, and LOD buffer) for all + /// structurally changed LOD groups, allocating new GPU instances as needed. + /// + static readonly ProfilerMarker k_ProcessLODGroupChanges = + new ProfilerMarker(ProfilerCategory.Render, "ProcessLODGroupChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Updates world-space reference point and size for LOD groups whose transforms changed + /// without structural changes, skipping full reallocation. + /// + static readonly ProfilerMarker k_ProcessLODGroupTransformChanges = + new ProfilerMarker(ProfilerCategory.Render, "ProcessLODGroupTransformChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Fetches full renderer data and dispatches a mesh renderer update batch for all + /// structurally changed renderers, including instance allocation and draw batch rebuild. + /// + static readonly ProfilerMarker k_ProcessMeshRendererChanges = + new ProfilerMarker(ProfilerCategory.Render, "ProcessMeshRendererChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Dispatches a transform-only mesh renderer update for renderers whose local-to-world + /// matrices changed without structural changes, skipping instance reallocation. + /// + static readonly ProfilerMarker k_ProcessMeshRendererTransformChanges = + new ProfilerMarker(ProfilerCategory.Render, "ProcessMeshRendererTransformChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Finds all renderers affected by changed materials or meshes, then rebuilds their draw + /// batches. Cost scales with total registered renderer count when scanning for affected + /// renderers, not just the number of changed assets. + /// + static readonly ProfilerMarker k_ProcessRendererMaterialAndMeshChanges = + new ProfilerMarker(ProfilerCategory.Render, "ProcessRendererMaterialAndMeshChanges", MarkerFlags.VerbosityAdvanced); + + /// + /// Partitions changed and destroyed materials into supported, unsupported, and destroyed + /// buckets, and extracts GPU-relevant material data for the supported subset. + /// + static readonly ProfilerMarker k_ClassifyMaterials = + new ProfilerMarker(ProfilerCategory.Render, "ClassifyMaterials", MarkerFlags.VerbosityAdvanced); + + /// + /// Filters the changed mesh ID list down to meshes that are actually referenced by + /// registered renderers, discarding untracked assets early to avoid redundant processing. + /// + static readonly ProfilerMarker k_FindOnlyUsedMeshes = + new ProfilerMarker(ProfilerCategory.Render, "FindOnlyUsedMeshes", MarkerFlags.VerbosityAdvanced); + + /// + /// Scans all registered renderer instances to find those referencing any newly + /// unsupported material. Cost scales with total registered renderer count, not just the + /// number of unsupported materials. + /// + static readonly ProfilerMarker k_FindUnsupportedRenderers = + new ProfilerMarker(ProfilerCategory.Render, "FindUnsupportedRenderers", MarkerFlags.VerbosityAdvanced); + private GPUDrivenProcessor m_GPUDrivenProcessor; private ObjectDispatcher m_ObjectDispatcher; private InstanceDataSystem m_InstanceDataSystem; @@ -54,24 +151,37 @@ public void Dispose() public void Update() { - Profiler.BeginSample("WorldProcessor.Update"); - - Profiler.BeginSample("FetchAllChanges"); - var meshDataSorted = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, sortByInstanceID: true, noScriptingArray: true); - var materialData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); - var cameraData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); - var lodGroupData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); - var lodGroupTransformData = m_ObjectDispatcher.GetTransformChangesAndClear(ObjectDispatcher.TransformTrackingType.GlobalTRS, Allocator.TempJob); - var rendererData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); - var transformChanges = m_ObjectDispatcher.GetTransformChangesAndClear(ObjectDispatcher.TransformTrackingType.GlobalTRS, Allocator.TempJob); - Profiler.EndSample(); + using var _ = k_Update.Auto(); + + TypeDispatchData meshDataSorted = default; + TypeDispatchData materialData = default; + TypeDispatchData cameraData = default; + TypeDispatchData lodGroupData = default; + TransformDispatchData lodGroupTransformData = default; + TypeDispatchData rendererData = default; + TransformDispatchData transformChanges = default; + + // Variables assigned outside the using block so they remain in scope below; + // the fetch calls are native allocations and do not throw in practice, but we + // still want the marker closed even if an unexpected exception occurs. + using (k_FetchAllChanges.Auto()) + { + meshDataSorted = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, sortByInstanceID: true, noScriptingArray: true); + materialData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); + cameraData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); + lodGroupData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); + lodGroupTransformData = m_ObjectDispatcher.GetTransformChangesAndClear(ObjectDispatcher.TransformTrackingType.GlobalTRS, Allocator.TempJob); + rendererData = m_ObjectDispatcher.GetTypeChangesAndClear(Allocator.TempJob, noScriptingArray: true); + transformChanges = m_ObjectDispatcher.GetTransformChangesAndClear(ObjectDispatcher.TransformTrackingType.GlobalTRS, Allocator.TempJob); + } if (cameraData.changedID.Length > 0) { - Profiler.BeginSample("ProcessCameraChanges"); - m_InstanceDataSystem.AddCameras(cameraData.changedID); - m_InstanceDataSystem.RemoveCameras(cameraData.destroyedID); - Profiler.EndSample(); + using (k_ProcessCameraChanges.Auto()) + { + m_InstanceDataSystem.AddCameras(cameraData.changedID); + m_InstanceDataSystem.RemoveCameras(cameraData.destroyedID); + } } ClassifyMaterials(materialData.changedID, @@ -88,10 +198,11 @@ public void Update() if (unsupportedRenderers.Length > 0) { - Profiler.BeginSample("DestroyUnsupportedRenderers"); - m_GPUDrivenProcessor.DisableGPUDrivenRendering(unsupportedRenderers.AsArray()); - m_MeshRendererProcessor.DestroyInstances(unsupportedRenderers.AsArray()); - Profiler.EndSample(); + using (k_DestroyUnsupportedRenderers.Auto()) + { + m_GPUDrivenProcessor.DisableGPUDrivenRendering(unsupportedRenderers.AsArray()); + m_MeshRendererProcessor.DestroyInstances(unsupportedRenderers.AsArray()); + } } m_Batcher.DestroyMaterials(destroyedMaterials.AsArray()); @@ -99,28 +210,31 @@ public void Update() if (meshDataSorted.destroyedID.Length > 0) { - Profiler.BeginSample("DestroyMeshes"); - var destroyedMeshInstances = new NativeList(Allocator.TempJob); - m_InstanceDataSystem.ScheduleQuerySortedMeshInstancesJob(meshDataSorted.destroyedID, destroyedMeshInstances).Complete(); - m_Batcher.DestroyDrawInstances(destroyedMeshInstances.AsArray()); - //@ Check if we need to update instance bounds and light probe sampling positions after mesh is destroyed. - m_Batcher.DestroyMeshes(meshDataSorted.destroyedID); - destroyedMeshInstances.Dispose(); - Profiler.EndSample(); + using (k_DestroyMeshes.Auto()) + { + var destroyedMeshInstances = new NativeList(Allocator.TempJob); + m_InstanceDataSystem.ScheduleQuerySortedMeshInstancesJob(meshDataSorted.destroyedID, destroyedMeshInstances).Complete(); + m_Batcher.DestroyDrawInstances(destroyedMeshInstances.AsArray()); + //@ Check if we need to update instance bounds and light probe sampling positions after mesh is destroyed. + m_Batcher.DestroyMeshes(meshDataSorted.destroyedID); + destroyedMeshInstances.Dispose(); + } } if (lodGroupData.changedID.Length > 0) { - Profiler.BeginSample("ProcessLODGroupChanges"); - m_LODGroupProcessor.ProcessGameObjectChanges(lodGroupData.changedID, transformOnly: false); - Profiler.EndSample(); + using (k_ProcessLODGroupChanges.Auto()) + { + m_LODGroupProcessor.ProcessGameObjectChanges(lodGroupData.changedID, transformOnly: false); + } } if (lodGroupTransformData.transformedID.Length > 0) { - Profiler.BeginSample("ProcessLODGroupTransformChanges"); - m_LODGroupProcessor.ProcessGameObjectChanges(lodGroupTransformData.transformedID, transformOnly: true); - Profiler.EndSample(); + using (k_ProcessLODGroupTransformChanges.Auto()) + { + m_LODGroupProcessor.ProcessGameObjectChanges(lodGroupTransformData.transformedID, transformOnly: true); + } } if (lodGroupData.destroyedID.Length > 0) @@ -128,27 +242,30 @@ public void Update() if (rendererData.changedID.Length > 0) { - Profiler.BeginSample("ProcessMeshRendererChanges"); - m_MeshRendererProcessor.ProcessGameObjectChanges(rendererData.changedID); - Profiler.EndSample(); + using (k_ProcessMeshRendererChanges.Auto()) + { + m_MeshRendererProcessor.ProcessGameObjectChanges(rendererData.changedID); + } } if (transformChanges.transformedID.Length > 0) { - Profiler.BeginSample("ProcessMeshRendererTransformChanges"); - m_MeshRendererProcessor.ProcessGameObjectTransformChanges(transformChanges); - Profiler.EndSample(); + using (k_ProcessMeshRendererTransformChanges.Auto()) + { + m_MeshRendererProcessor.ProcessGameObjectTransformChanges(transformChanges); + } } if (rendererData.destroyedID.Length > 0) m_MeshRendererProcessor.DestroyInstances(rendererData.destroyedID); - Profiler.BeginSample("ProcessRendererMaterialAndMeshChanges"); - m_MeshRendererProcessor.ProcessRendererMaterialAndMeshChanges(rendererData.changedID, - changedMaterials.AsArray(), - changedMaterialDatas.AsArray(), - changedMeshes.AsArray()); - Profiler.EndSample(); + using (k_ProcessRendererMaterialAndMeshChanges.Auto()) + { + m_MeshRendererProcessor.ProcessRendererMaterialAndMeshChanges(rendererData.changedID, + changedMaterials.AsArray(), + changedMaterialDatas.AsArray(), + changedMeshes.AsArray()); + } try { @@ -177,8 +294,6 @@ public void Update() cameraData.Dispose(); materialData.Dispose(); meshDataSorted.Dispose(); - - Profiler.EndSample(); } public void PushMeshRendererUpdateBatches(NativeArray batches) @@ -256,45 +371,47 @@ public void ClassifyMaterials(NativeArray allChangedMaterials, out NativeList changedMaterialDatas, Allocator allocator) { - Profiler.BeginSample("ClassifyMaterials"); - - WorldProcessorBurst.ClassifyMaterials(m_Batcher.materialMap, - allChangedMaterials, - allDestroyedMaterials, - out changedMaterials, - out unsupportedMaterials, - out destroyedMaterials, - out changedMaterialDatas, - allocator); - - Profiler.EndSample(); + using (k_ClassifyMaterials.Auto()) + { + WorldProcessorBurst.ClassifyMaterials(m_Batcher.materialMap, + allChangedMaterials, + allDestroyedMaterials, + out changedMaterials, + out unsupportedMaterials, + out destroyedMaterials, + out changedMaterialDatas, + allocator); + } } public NativeList FindOnlyUsedMeshes(NativeArray changedMeshes, Allocator allocator) { NativeList usedMeshes; - Profiler.BeginSample("FindOnlyUsedMeshes"); - WorldProcessorBurst.FindOnlyUsedMeshes(m_Batcher.meshMap, changedMeshes, allocator, out usedMeshes); - Profiler.EndSample(); + using (k_FindOnlyUsedMeshes.Auto()) + { + WorldProcessorBurst.FindOnlyUsedMeshes(m_Batcher.meshMap, changedMeshes, allocator, out usedMeshes); + } return usedMeshes; } private NativeList FindUnsupportedRenderers(NativeArray unsupportedMaterials, Allocator allocator) { - Profiler.BeginSample("FindUnsupportedRenderers"); - - var unsupportedRenderers = new NativeList(allocator); + NativeList unsupportedRenderers; - if (unsupportedMaterials.Length > 0) + using (k_FindUnsupportedRenderers.Auto()) { - ref RenderWorld renderWorld = ref m_InstanceDataSystem.renderWorld; + unsupportedRenderers = new NativeList(allocator); + + if (unsupportedMaterials.Length > 0) + { + ref RenderWorld renderWorld = ref m_InstanceDataSystem.renderWorld; - WorldProcessorBurst.FindUnsupportedRenderers(unsupportedMaterials, renderWorld.materialIDArrays, renderWorld.instanceIDs, ref unsupportedRenderers); + WorldProcessorBurst.FindUnsupportedRenderers(unsupportedMaterials, renderWorld.materialIDArrays, renderWorld.instanceIDs, ref unsupportedRenderers); + } } - Profiler.EndSample(); return unsupportedRenderers; } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickIndex.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickIndex.cs index 6465850c3d8..29647e41221 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickIndex.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickIndex.cs @@ -2,10 +2,11 @@ using System; using System.Diagnostics; using System.Collections.Generic; -using UnityEngine.Profiling; -using System.Collections; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; +using Unity.Profiling; +using Unity.Profiling.LowLevel; +using System.Collections; using Chunk = UnityEngine.Rendering.ProbeBrickPool.BrickChunkAlloc; using CellIndexInfo = UnityEngine.Rendering.ProbeReferenceVolume.CellIndexInfo; @@ -13,6 +14,23 @@ namespace UnityEngine.Rendering { internal class ProbeBrickIndex { + /// + /// Allocates the physical index ComputeBuffer, the backing CPU + /// NativeArray, and the chunk free-list, then runs Clear to + /// zero-initialize the buffer. Cost scales with the memory budget. + /// + static readonly ProfilerMarker k_CreateProbeBrickIndex = + new ProfilerMarker(ProfilerCategory.Render, "Create ProbeBrickIndex", + MarkerFlags.VerbosityAdvanced); + + /// + /// Zeroes the physical index CPU array, marks all index chunks as free, and resets the + /// dirty range so the full buffer is re-uploaded on the next GPU sync. + /// + static readonly ProfilerMarker k_ClearIndex = + new ProfilerMarker(ProfilerCategory.Render, "Clear Index", + MarkerFlags.VerbosityAdvanced); + // a few constants internal const int kMaxSubdivisionLevels = 7; // 3 bits internal const int kIndexChunkSize = 243; @@ -94,7 +112,7 @@ int SizeOfPhysicalIndexFromBudget(ProbeVolumeTextureMemoryBudget memoryBudget) internal ProbeBrickIndex(ProbeVolumeTextureMemoryBudget memoryBudget) { - Profiler.BeginSample("Create ProbeBrickIndex"); + using var _ = k_CreateProbeBrickIndex.Auto(); m_CenterRS = new Vector3Int(0, 0, 0); m_NeedUpdateIndexComputeBuffer = false; @@ -111,7 +129,6 @@ internal ProbeBrickIndex(ProbeVolumeTextureMemoryBudget memoryBudget) estimatedVMemCost = physicalBufferSize * sizeof(int); Clear(); - Profiler.EndSample(); } public int GetRemainingChunkCount() @@ -150,7 +167,7 @@ void UpdateDebugData() internal void Clear() { - Profiler.BeginSample("Clear Index"); + using var _ = k_ClearIndex.Auto(); m_IndexChunks.SetAll(false); m_AvailableChunkCount = m_ChunksCount; @@ -166,8 +183,6 @@ internal void Clear() m_UpdateMinIndex = 0; m_UpdateMaxIndex = m_PhysicalIndexBufferData.Length - 1; } - - Profiler.EndSample(); } internal void GetRuntimeResources(ref ProbeReferenceVolume.RuntimeResources rr) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs index 846cea2e3d4..a6c51c68d2e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeBrickPool.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Collections.Generic; -using UnityEngine.Profiling; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Experimental.Rendering; using Cell = UnityEngine.Rendering.ProbeReferenceVolume.Cell; using CellStreamingScratchBuffer = UnityEngine.Rendering.ProbeReferenceVolume.CellStreamingScratchBuffer; @@ -10,6 +11,15 @@ namespace UnityEngine.Rendering { internal class ProbeBrickPool { + /// + /// Allocates all SH data texture arrays (L0/L1, optional L2), validity, sky occlusion, + /// sky shading direction, probe occlusion, and rendering layer textures based on the + /// memory budget and enabled feature set. + /// + static readonly ProfilerMarker k_CreateProbeBrickPool = + new ProfilerMarker(ProfilerCategory.Render, "Create ProbeBrickPool", + MarkerFlags.VerbosityAdvanced); + internal static readonly int _Out_L0_L1Rx = Shader.PropertyToID("_Out_L0_L1Rx"); internal static readonly int _Out_L1G_L1Ry = Shader.PropertyToID("_Out_L1G_L1Ry"); internal static readonly int _Out_L1B_L1Rz = Shader.PropertyToID("_Out_L1B_L1Rz"); @@ -182,7 +192,8 @@ internal Texture GetProbeOcclusionTexture() internal ProbeBrickPool(ProbeVolumeTextureMemoryBudget memoryBudget, ProbeVolumeSHBands shBands, bool allocateValidityData = false, bool allocateRenderingLayerData = false, bool allocateSkyOcclusion = false, bool allocateSkyShadingData = false, bool allocateProbeOcclusionData = false) { - Profiler.BeginSample("Create ProbeBrickPool"); + using var _ = k_CreateProbeBrickPool.Auto(); + m_NextFreeChunk.x = m_NextFreeChunk.y = m_NextFreeChunk.z = 0; m_SHBands = shBands; @@ -198,8 +209,6 @@ internal ProbeBrickPool(ProbeVolumeTextureMemoryBudget memoryBudget, ProbeVolume AllocatePool(width, height, depth); m_AvailableChunkCount = (m_Pool.width / (kChunkSizeInBricks * kBrickProbeCountPerDim)) * (m_Pool.height / kBrickProbeCountPerDim) * (m_Pool.depth / kBrickProbeCountPerDim); - - Profiler.EndSample(); } internal void AllocatePool(int width, int height, int depth) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs index 0aa31c37efa..49774189332 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs @@ -3,22 +3,17 @@ #endif using System; -using System.Diagnostics; using System.Collections.Generic; +using System.Diagnostics; using System.Reflection; -using UnityEngine.Profiling; -using UnityEngine.SceneManagement; -using Chunk = UnityEngine.Rendering.ProbeBrickPool.BrickChunkAlloc; -using Brick = UnityEngine.Rendering.ProbeBrickIndex.Brick; using Unity.Collections; -using Unity.Profiling; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Experimental.Rendering; - -#if UNITY_EDITOR -using System.Linq.Expressions; -using UnityEditor; -#endif +using UnityEngine.SceneManagement; +using Brick = UnityEngine.Rendering.ProbeBrickIndex.Brick; +using Chunk = UnityEngine.Rendering.ProbeBrickPool.BrickChunkAlloc; namespace UnityEngine.Rendering { @@ -794,6 +789,16 @@ public bool skyOcclusionShadingDirection int m_CBShaderID = Shader.PropertyToID("ShaderVariablesProbeVolumes"); + /// + /// Performs a one-time initialization that allocates the brick pool, blending pool, brick + /// index (plus defrag index when GPU streaming is enabled), global indirection textures, + /// and the intermediate data location. Cost depends on memory budget and enabled + /// features (L2, sky occlusion, rendering layers). + /// + static readonly ProfilerMarker k_InitializeReferenceVolume = + new ProfilerMarker(ProfilerCategory.Render, "Initialize Reference Volume", + MarkerFlags.VerbosityAdvanced); + ProbeVolumeTextureMemoryBudget m_MemoryBudget; ProbeVolumeBlendingTextureMemoryBudget m_BlendingMemoryBudget; ProbeVolumeSHBands m_SHBands; @@ -1668,7 +1673,8 @@ void InitProbeReferenceVolume() if (!m_ProbeReferenceVolumeInit) { - Profiler.BeginSample("Initialize Reference Volume"); + using var _ = k_InitializeReferenceVolume.Auto(); + m_Pool = new ProbeBrickPool(m_MemoryBudget, m_SHBands, allocateValidityData: true, useRenderingLayers, skyOcclusion, skyOcclusionShadingDirection, probeOcclusion); m_BlendingPool = new ProbeBrickBlendingPool(m_BlendingMemoryBudget, m_SHBands, probeOcclusion); @@ -1691,8 +1697,6 @@ void InitProbeReferenceVolume() m_PositionOffsets[i] = i * probeDelta; m_PositionOffsets[m_PositionOffsets.Length - 1] = 1.0f; - Profiler.EndSample(); - m_ProbeReferenceVolumeInit = true; ClearDebugData(); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs index 766765db7e0..b724ace5bca 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.SceneManagement; #if UNITY_EDITOR @@ -11,6 +13,58 @@ namespace UnityEngine.Rendering struct GIContributors { #if UNITY_EDITOR + /// + /// Collects all GI-contributing renderers and terrains from the scene (or selection). + /// For terrains, also resolves tree prototype meshes and computes per-instance bounds. + /// Cost scales with total scene renderer and terrain count. + /// + static readonly ProfilerMarker k_FindGIContributors = + new ProfilerMarker(ProfilerCategory.Render, "GIContributors.Find", MarkerFlags.VerbosityAdvanced); + + /// + /// Iterates all scene renderers returned by FindObjectsByType, filtering to + /// those that are active, LOD0, have a MeshFilter, and contribute GI. + /// + static readonly ProfilerMarker k_FindRenderers = + new ProfilerMarker(ProfilerCategory.Render, "Find Renderers", MarkerFlags.VerbosityAdvanced); + + /// + /// Iterates all scene terrains returned by FindObjectsByType, filtering to + /// those that are active and have valid terrain data, and resolves their tree prototypes. + /// + static readonly ProfilerMarker k_FindTerrains = + new ProfilerMarker(ProfilerCategory.Render, "Find Terrains", MarkerFlags.VerbosityAdvanced); + + /// + /// Filters the full GI contributor lists to those overlapping a given baking cell and + /// at least one probe volume, applying both spatial bounds and per-probe-volume size and + /// layer mask rules. + /// + static readonly ProfilerMarker k_FilterGIContributors = + new ProfilerMarker(ProfilerCategory.Render, "Filter GIContributors", MarkerFlags.VerbosityAdvanced); + + /// + /// Tests each renderer's bounds against the cell AABB and all probe volumes, keeping + /// only those that pass the OBB-AABB intersection and the minimum bounding-volume-size + /// filter. + /// + static readonly ProfilerMarker k_FilterRenderers = + new ProfilerMarker(ProfilerCategory.Render, "Filter Renderers", MarkerFlags.VerbosityAdvanced); + + /// + /// Tests each terrain's bounds against the cell AABB and probe volumes, then culls + /// individual tree instances for each prototype. Cost scales with terrain tree instance count + /// when trees are present. + /// + static readonly ProfilerMarker k_FilterTerrains = + new ProfilerMarker(ProfilerCategory.Render, "Filter Terrains", MarkerFlags.VerbosityAdvanced); + + /// + /// Filters the full GI contributor lists by layer mask only, without spatial bounds + /// checks. Used when per-cell spatial culling is not required. + /// + static readonly ProfilerMarker k_FilterGIContributorsLayerMask = + new ProfilerMarker(ProfilerCategory.Render, "Filter GIContributors LayerMask", MarkerFlags.VerbosityAdvanced); static GIContributors Create() { @@ -102,7 +156,7 @@ public static GIContributors Find(ContributorFilter filter, Scene? scene = null) if (filter == ContributorFilter.Scene && scene == null) return default; - Profiling.Profiler.BeginSample("GIContributors.Find"); + using var _ = k_FindGIContributors.Auto(); var contributors = GIContributors.Create(); @@ -220,30 +274,30 @@ void PushTerrain(Terrain terrain) #pragma warning disable CS0618 // Type or member is obsolete var renderers = Object.FindObjectsByType(FindObjectsSortMode.InstanceID); #pragma warning restore CS0618 // Type or member is obsolete - Profiling.Profiler.BeginSample($"Find Renderers ({renderers.Length})"); - foreach (var renderer in renderers) + using (k_FindRenderers.Auto()) { - if (filter != ContributorFilter.Scene || renderer.gameObject.scene == scene) - PushRenderer(renderer); + foreach (var renderer in renderers) + { + if (filter != ContributorFilter.Scene || renderer.gameObject.scene == scene) + PushRenderer(renderer); + } } - Profiling.Profiler.EndSample(); #if ENABLE_TERRAIN_MODULE #pragma warning disable CS0618 // Type or member is obsolete var terrains = Object.FindObjectsByType(FindObjectsSortMode.InstanceID); #pragma warning restore CS0618 // Type or member is obsolete - Profiling.Profiler.BeginSample($"Find Terrains ({terrains.Length})"); - foreach (var terrain in terrains) + using (k_FindTerrains.Auto()) { - if (filter != ContributorFilter.Scene || terrain.gameObject.scene == scene) - PushTerrain(terrain); + foreach (var terrain in terrains) + { + if (filter != ContributorFilter.Scene || terrain.gameObject.scene == scene) + PushTerrain(terrain); + } } - - Profiling.Profiler.EndSample(); #endif } - Profiling.Profiler.EndSample(); return contributors; } @@ -267,11 +321,11 @@ static bool DiscardedByProbeVolume(ProbeVolume pv, ProbeVolumeBakingSet bakingSe public GIContributors Filter(ProbeVolumeBakingSet bakingSet, Bounds cellBounds, ProbeVolumeWithBoundsList probeVolumes) { - Profiling.Profiler.BeginSample("Filter GIContributors"); + k_FilterGIContributors.Begin(); var contributors = GIContributors.Create(); - Profiling.Profiler.BeginSample($"Filter Renderers ({renderers.Count})"); + k_FilterRenderers.Begin(); foreach (var renderer in renderers) { if (!cellBounds.Intersects(renderer.bounds)) @@ -291,10 +345,10 @@ public GIContributors Filter(ProbeVolumeBakingSet bakingSet, Bounds cellBounds, break; } } - Profiling.Profiler.EndSample(); + k_FilterRenderers.End(); #if ENABLE_TERRAIN_MODULE - Profiling.Profiler.BeginSample($"Filter Terrains ({terrains.Count})"); + k_FilterTerrains.Begin(); foreach (var terrain in terrains) { if (!cellBounds.Intersects(terrain.boundsWithTrees)) @@ -383,16 +437,16 @@ public GIContributors Filter(ProbeVolumeBakingSet bakingSet, Bounds cellBounds, }; contributors.terrains.Add(terrainContrib); } - Profiling.Profiler.EndSample(); + k_FilterTerrains.End(); #endif - Profiling.Profiler.EndSample(); + k_FilterGIContributors.End(); return contributors; } public GIContributors FilterLayerMaskOnly(LayerMask layerMask) { - Profiling.Profiler.BeginSample("Filter GIContributors LayerMask"); + k_FilterGIContributorsLayerMask.Begin(); var contributors = GIContributors.Create(); @@ -436,7 +490,7 @@ public GIContributors FilterLayerMaskOnly(LayerMask layerMask) } #endif - Profiling.Profiler.EndSample(); + k_FilterGIContributorsLayerMask.End(); return contributors; } #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs index b6bdfcad844..01c6aea2a6f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs @@ -1,5 +1,7 @@ using System; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.PathTracing.Core; using UnityEngine.PathTracing.Integration; using UnityEngine.Rendering; @@ -9,6 +11,14 @@ namespace UnityEngine.PathTracing.Lightmapping { internal static class BakeLightmapDriver { + /// + /// Profiles a single per-instance lightmap accumulation step, spanning GBuffer sampling, + /// path-tracing dispatch, and all output integrators (direct, indirect, AO, validity, shadow mask). + /// + static readonly ProfilerMarker k_AccumulateLightmapInstance = + new ProfilerMarker(ProfilerCategory.Render, "AccumulateLightmapInstance", + MarkerFlags.Default | MarkerFlags.SampleGPU); + public class LightmapBakeState { public uint SampleIndex; @@ -270,7 +280,7 @@ internal static uint AccumulateLightmapInstance( } // accumulate the lightmap texel - cmd.BeginSample("AccumulateLightmapInstance"); + cmd.BeginSample(k_AccumulateLightmapInstance); switch (integratedOutputType) { @@ -430,7 +440,7 @@ internal static uint AccumulateLightmapInstance( break; } } - cmd.EndSample("AccumulateLightmapInstance"); + cmd.EndSample(k_AccumulateLightmapInstance); //LightmapIntegrationHelpers.LogGraphicsBuffer(cmd, lightmappingContext.ExpandedOutput, "expandedOutput", LightmapIntegrationHelpers.LogBufferType.Float4); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapExpansion.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapExpansion.cs index 3c9ff09da7e..284fb572212 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapExpansion.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapExpansion.cs @@ -1,4 +1,6 @@ using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.PathTracing.Core; using UnityEngine.PathTracing.Integration; using UnityEngine.Rendering; @@ -39,6 +41,47 @@ internal static class ExpansionShaderIDs internal static class ExpansionHelpers { + /// + /// Clears the expanded output buffer to zero before the accumulation loop begins. + /// + static readonly ProfilerMarker k_ClearExpanded = + new ProfilerMarker(ProfilerCategory.Render, "Clear (Expanded)", + MarkerFlags.Default | MarkerFlags.SampleGPU); + + /// + /// Traces rays from each lightmap texel into the scene to populate the GBuffer with + /// world-space hit data. This ray-tracing dispatch is a prerequisite for all + /// subsequent accumulation passes. + /// + static readonly ProfilerMarker k_UVSampling = + new ProfilerMarker(ProfilerCategory.Render, "UV Sampling", + MarkerFlags.Default | MarkerFlags.SampleGPU); + + /// + /// Compacts the GBuffer by stream-compacting out invalid (missed-ray) texels so the + /// accumulation dispatch only processes valid hits. + /// + static readonly ProfilerMarker k_CompactGBuffer = + new ProfilerMarker(ProfilerCategory.Render, "Compact GBuffer", + MarkerFlags.Default | MarkerFlags.SampleGPU); + + /// + /// Performs one stage of the parallel-reduction sum over expanded sample groups. + /// Called repeatedly in a loop where each invocation halves the remaining group count + /// until all samples within each texel are summed. + /// + static readonly ProfilerMarker k_BinarySum = + new ProfilerMarker(ProfilerCategory.Render, "Binary Sum", + MarkerFlags.Default | MarkerFlags.SampleGPU); + + /// + /// Copies the accumulated, reduced texel values from the expanded buffer into the + /// final lightmap texture at the correct instance offset and chunk bounds. + /// + static readonly ProfilerMarker k_CopyToLightmap = + new ProfilerMarker(ProfilerCategory.Render, "Copy to Lightmap", + MarkerFlags.Default | MarkerFlags.SampleGPU); + static internal int PopulateAccumulationIndirectDispatch(CommandBuffer cmd, ComputeShader populateShader, int populateKernel, uint expandedSampleWidth, GraphicsBuffer compactedGbufferLength, GraphicsBuffer accumulationDispatchBuffer) { cmd.SetComputeIntParam(populateShader, ExpansionShaderIDs.ExpandedTexelSampleWidth, (int)expandedSampleWidth); @@ -67,9 +110,9 @@ static internal int ClearExpandedOutput(CommandBuffer cmd, ComputeShader clearEx // Clear the output buffers. cmd.SetComputeIntParam(clearExpandedOutput, ExpansionShaderIDs.Float4BufferLength, expandedOutput.count); cmd.SetComputeBufferParam(clearExpandedOutput, clearExpandedOutputKernel, ExpansionShaderIDs.Float4Buffer, expandedOutput); - cmd.BeginSample("Clear (Expanded)"); + cmd.BeginSample(k_ClearExpanded); cmd.DispatchCompute(clearExpandedOutput, clearExpandedOutputKernel, clearDispatchBuffer, 0); - cmd.EndSample("Clear (Expanded)"); + cmd.EndSample(k_ClearExpanded); //LightmapIntegrationHelpers.LogGraphicsBuffer(cmd, expandedOutput, "expandedOutput", LogBufferType.Float4); return 1; } @@ -113,9 +156,9 @@ static internal void GenerateGBuffer( // dispatch the shader Debug.Assert(gBufferShader is HardwareRayTracingShader || GraphicsHelpers.DivUp((int)chunkSize, gBufferShader.GetThreadGroupSizes().x) < 65536, "Chunk size is too large for the shader to handle."); - cmd.BeginSample("UV Sampling"); + cmd.BeginSample(k_UVSampling); gBufferShader.Dispatch(cmd, traceScratchBuffer, chunkSize * expandedSampleWidth, 1, 1); - cmd.EndSample("UV Sampling"); + cmd.EndSample(k_UVSampling); //LightmapIntegrationHelpers.LogGraphicsBuffer(cmd, gBuffer, "gBuffer", LogBufferType.HitEntry); } @@ -178,9 +221,9 @@ static internal int CompactGBuffer(CommandBuffer cmd, ComputeShader compactGBuff cmd.SetComputeTextureParam(compactGBuffer, compactGBufferKernel, UVFallbackBufferBuilderShaderIDs.UvFallback, uvFallbackBuffer.UVFallbackRT); cmd.SetComputeBufferParam(compactGBuffer, compactGBufferKernel, ExpansionShaderIDs.CompactedGBuffer, compactedTexelIndices); cmd.SetComputeBufferParam(compactGBuffer, compactGBufferKernel, ExpansionShaderIDs.CompactedGBufferLength, compactedGBufferLength); - cmd.BeginSample("Compact GBuffer"); + cmd.BeginSample(k_CompactGBuffer); cmd.DispatchCompute(compactGBuffer, compactGBufferKernel, GraphicsHelpers.DivUp((int)chunkSize, gbuf_x), 1, 1); - cmd.EndSample("Compact GBuffer"); + cmd.EndSample(k_CompactGBuffer); //System.Console.WriteLine($"compactGBufferThreadGroupSizeX: {gbuf_x}"); //LightmapIntegrationHelpers.LogGraphicsBuffer(cmd, compactedGBufferLength, "compactedGBufferLength", LogBufferType.UInt); @@ -213,9 +256,9 @@ static internal int ReduceExpandedOutput(CommandBuffer cmd, ComputeShader binary while (groupSize < expandedSampleWidth) { cmd.SetComputeIntParam(binaryGroupSumLeftShader, ExpansionShaderIDs.BinaryGroupSize, groupSize); - cmd.BeginSample("Binary Sum"); + cmd.BeginSample(k_BinarySum); cmd.DispatchCompute(binaryGroupSumLeftShader, binaryGroupSumLeftKernel, reduceDispatch, 0); - cmd.EndSample("Binary Sum"); + cmd.EndSample(k_BinarySum); groupSize *= 2; dispatches++; } @@ -248,9 +291,9 @@ static internal int CopyToLightmap(CommandBuffer cmd, ComputeShader copyToLightm cmd.SetComputeIntParam(copyToLightmap, ExpansionShaderIDs.ChunkOffsetY, (int)chunkOffset.y); copyToLightmap.GetKernelThreadGroupSizes(copyToLightmapKernel, out uint copyx, out uint _, out _); - cmd.BeginSample("Copy to Lightmap"); + cmd.BeginSample(k_CopyToLightmap); cmd.DispatchCompute(copyToLightmap, copyToLightmapKernel, copyDispatch, 0); - cmd.EndSample("Copy to Lightmap"); + cmd.EndSample(k_CopyToLightmap); return 1; } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegration.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegration.cs index 82e1ab53650..6b86b67ad98 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegration.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegration.cs @@ -1,4 +1,6 @@ using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.PathTracing.Core; using UnityEngine.PathTracing.Lightmapping; using UnityEngine.Rendering; @@ -11,6 +13,22 @@ internal enum AntiAliasingType { Stochastic, SuperSampling }; internal static class LightmapIntegratorShaderIDs { + /// + /// Profiles a single ray-tracing accumulation pass over expanded (super-sampled) texel data, + /// shared across all lightmap integrator types (direct, indirect, AO, validity, shadow mask). + /// + public static readonly ProfilerMarker k_AccumulationExpanded = + new ProfilerMarker(ProfilerCategory.Render, "Accumulation (Expanded)", + MarkerFlags.Default | MarkerFlags.SampleGPU); + + /// + /// Profiles the GBuffer debug visualization pass that writes world-space hit data + /// from the expanded GBuffer into a lightmap-sized output buffer. + /// + public static readonly ProfilerMarker k_GBufferDebug = + new ProfilerMarker(ProfilerCategory.Render, "GBuffer Debug", + MarkerFlags.Default | MarkerFlags.SampleGPU); + public static readonly int LightmapInOut = Shader.PropertyToID("g_LightmapInOut"); public static readonly int DirectionalInOut = Shader.PropertyToID("g_DirectionalInOut"); public static readonly int AdaptiveInOut = Shader.PropertyToID("g_AdaptiveInOut"); @@ -219,9 +237,9 @@ public void Accumulate( for (int lightIndexInCell = 0; lightIndexInCell < loopCount; ++lightIndexInCell) { _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.LightIndexInCell, lightIndexInCell); - cmd.BeginSample("Accumulation (Expanded)"); + cmd.BeginSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); _accumulationShader.Dispatch(cmd, traceScratchBuffer, _accumulationDispatchBuffer); - cmd.EndSample("Accumulation (Expanded)"); + cmd.EndSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); } } } @@ -488,9 +506,9 @@ public void Accumulate( { _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.SampleOffset, (int)currentSampleCountPerTexel); _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.MaxLocalSampleCount, (int)sampleCountToTakePerTexel); - cmd.BeginSample("Accumulation (Expanded)"); + cmd.BeginSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); _accumulationShader.Dispatch(cmd, traceScratchBuffer, _accumulationDispatchBuffer); - cmd.EndSample("Accumulation (Expanded)"); + cmd.EndSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); } } @@ -615,9 +633,9 @@ public void Accumulate( { _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.SampleOffset, (int)currentSampleCountPerTexel); _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.MaxLocalSampleCount, (int)sampleCountToTakePerTexel); - cmd.BeginSample("Accumulation (Expanded)"); + cmd.BeginSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); _accumulationShader.Dispatch(cmd, traceScratchBuffer, _accumulationDispatchBuffer); - cmd.EndSample("Accumulation (Expanded)"); + cmd.EndSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); } } @@ -728,9 +746,9 @@ public void Accumulate( { _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.SampleOffset, (int)currentSampleCountPerTexel); _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.MaxLocalSampleCount, (int)sampleCountToTakePerTexel); - cmd.BeginSample("Accumulation (Expanded)"); + cmd.BeginSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); _accumulationShader.Dispatch(cmd, traceScratchBuffer, _accumulationDispatchBuffer); - cmd.EndSample("Accumulation (Expanded)"); + cmd.EndSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); } } @@ -844,9 +862,9 @@ public void Accumulate( { _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.SampleOffset, (int)currentSampleCountPerTexel); _accumulationShader.SetIntParam(cmd, LightmapIntegratorShaderIDs.MaxLocalSampleCount, (int)sampleCountToTakePerTexel); - cmd.BeginSample("Accumulation (Expanded)"); + cmd.BeginSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); _accumulationShader.Dispatch(cmd, traceScratchBuffer, _accumulationDispatchBuffer); - cmd.EndSample("Accumulation (Expanded)"); + cmd.EndSample(LightmapIntegratorShaderIDs.k_AccumulationExpanded); } } @@ -912,9 +930,9 @@ public void Accumulate( // Its time to repopulate the indirect dispatch buffers. Use the compacted size for this. ExpansionHelpers.PopulateAccumulationIndirectDispatch(cmd, _expansionHelpers, _populateAccumulationDispatchKernel, expandedSampleWidth, compactedGbufferLength, _accumulationDispatchBuffer); - cmd.BeginSample("GBuffer Debug"); + cmd.BeginSample(LightmapIntegratorShaderIDs.k_GBufferDebug); _accumulationShader.Dispatch(cmd, null, _accumulationDispatchBuffer); - cmd.EndSample("GBuffer Debug"); + cmd.EndSample(LightmapIntegratorShaderIDs.k_GBufferDebug); } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegrationHelpers.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegrationHelpers.cs index 8dc6a280ab8..c9bd145971c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegrationHelpers.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapIntegrationHelpers.cs @@ -3,6 +3,8 @@ using System.IO; using System.Reflection; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; using UnityEngine.Rendering; using UnityEngine.Rendering.UnifiedRayTracing; @@ -11,6 +13,14 @@ namespace UnityEngine.PathTracing.Lightmapping { internal static class LightmapIntegrationHelpers { + /// + /// Profiles the box filtering pass applied to the blue channel of the lightmap output, + /// used to smooth validity values through an indirect compute dispatch. + /// + static readonly ProfilerMarker k_BoxFiltering = + new ProfilerMarker(ProfilerCategory.Render, "BoxFiltering", + MarkerFlags.Default | MarkerFlags.SampleGPU); + internal class ComputeHelpers { internal ComputeShader ComputeHelperShader = null; @@ -509,7 +519,7 @@ public static void ReferenceBoxFilterRenderTexture(CommandBuffer cmd, ComputeSha public static void ReferenceBoxFilterBlueChannelRenderTexture(CommandBuffer cmd, ComputeShader referenceBoxFilterBlueChannelShader, int referenceBoxFilterBlueChannelKernel, RenderTargetIdentifier inOut, int width, int height, int radius, GraphicsBuffer indirectDispatchBuffer) { - cmd.BeginSample("BoxFiltering"); + cmd.BeginSample(k_BoxFiltering); cmd.GetTemporaryRT(ComputeHelpers.ShaderIDs.TextureOut, width, height, 0, FilterMode.Point, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear, 1, true); cmd.SetComputeTextureParam(referenceBoxFilterBlueChannelShader, referenceBoxFilterBlueChannelKernel, ComputeHelpers.ShaderIDs.SourceTexture, inOut); cmd.SetComputeTextureParam(referenceBoxFilterBlueChannelShader, referenceBoxFilterBlueChannelKernel, ComputeHelpers.ShaderIDs.TextureOut, ComputeHelpers.ShaderIDs.TextureOut); @@ -519,7 +529,7 @@ public static void ReferenceBoxFilterBlueChannelRenderTexture(CommandBuffer cmd, cmd.DispatchCompute(referenceBoxFilterBlueChannelShader, referenceBoxFilterBlueChannelKernel, indirectDispatchBuffer, 0); cmd.CopyTexture(ComputeHelpers.ShaderIDs.TextureOut, inOut); // TODO(jesper): dont do copy cmd.ReleaseTemporaryRT(ComputeHelpers.ShaderIDs.TextureOut); - cmd.EndSample("BoxFiltering"); + cmd.EndSample(k_BoxFiltering); } // Computes the region of a lightmap that is occupied by the pixels of a specific instance, diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapResourceCache.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapResourceCache.cs index 0e7d4006c09..d2eacf62158 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapResourceCache.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmapResourceCache.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.PathTracing.Core; using UnityEngine.PathTracing.Integration; using UnityEngine.Rendering; @@ -9,6 +11,14 @@ namespace UnityEngine.PathTracing.Lightmapping { internal class LightmapIntegrationResourceCache : IDisposable { + /// + /// Profiles the build of the UV acceleration structure (BVH) over UV-space triangles, + /// used to resolve lightmap texels to world-space positions in ray tracing. + /// + static readonly ProfilerMarker k_BuildUVAccelerationStructure = + new ProfilerMarker(ProfilerCategory.Render, "Build UVAccelerationStructure", + MarkerFlags.Default | MarkerFlags.SampleGPU); + private Dictionary _meshToUVMesh = new(); private Dictionary _meshToUVAccelerationStructure = new(); private Dictionary _meshToUVFallbackBuffer = new(); @@ -96,12 +106,12 @@ internal bool AddResources( ulong uvASHash = Util.EntityIDToUlong(uvMesh.Mesh.GetEntityId()); if (!_meshToUVAccelerationStructure.TryGetValue(uvASHash, out UVAccelerationStructure uvAS)) { - cmd.BeginSample("Build UVAccelerationStructure"); + cmd.BeginSample(k_BuildUVAccelerationStructure); UVAccelerationStructure newUVAS = new(); newUVAS.Build(cmd, context, uvMesh, BuildFlags.None); _meshToUVAccelerationStructure.Add(uvASHash, newUVAS); uvAS = newUVAS; - cmd.EndSample("Build UVAccelerationStructure"); + cmd.EndSample(k_BuildUVAccelerationStructure); } // UVFallbackBuffer var uvFBKey = new UVFallbackBufferKey(instance.TexelSize.x, instance.TexelSize.y, uvMesh.Mesh.GetEntityId()); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/UVFallbackBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/UVFallbackBuffer.cs index 3d869a80cee..bd16cd722bb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/UVFallbackBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/UVFallbackBuffer.cs @@ -1,6 +1,8 @@ using System; using System.IO; using Unity.Mathematics; +using Unity.Profiling; +using Unity.Profiling.LowLevel; using UnityEngine.PathTracing.Core; using UnityEngine.PathTracing.Lightmapping; using UnityEngine.Rendering; @@ -31,6 +33,14 @@ internal static class UVFallbackBufferBuilderShaderIDs internal class UVFallbackBufferBuilder : IDisposable { + /// + /// Profiles the build of the UV fallback buffer used for conservative rasterization + /// of UV charts when ray tracing is not available. + /// + static readonly ProfilerMarker k_BuildUVFallbackBuffer = + new ProfilerMarker(ProfilerCategory.Render, "Build UVFallbackBuffer", + MarkerFlags.Default | MarkerFlags.SampleGPU); + private GraphicsBuffer _vertexBuffer; private Material _uvFallbackBufferMaterial; @@ -54,7 +64,7 @@ public void Build( float heightScale, Mesh uvMesh) { - cmd.BeginSample("Build UVFallbackBuffer"); + cmd.BeginSample(k_BuildUVFallbackBuffer, uvFallbackRT); Debug.Assert((UInt64)width * (UInt64)height < uint.MaxValue); Debug.Assert(uvFallbackRT.format == RenderTextureFormat.RGFloat); @@ -89,7 +99,7 @@ public void Build( cmd.SetGlobalFloat(UVFallbackBufferBuilderShaderIDs.HeightScale, heightScale); cmd.DrawProcedural(Matrix4x4.identity, _uvFallbackBufferMaterial, 0, MeshTopology.Triangles, (int)uvMesh.GetTotalIndexCount()); - cmd.EndSample("Build UVFallbackBuffer"); + cmd.EndSample(k_BuildUVFallbackBuffer); GraphicsHelpers.Flush(cmd); } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs new file mode 100644 index 00000000000..30f216f293d --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Profiling; + +namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler +{ + internal partial class NativePassCompiler + { + /// + /// Marks the initialization of per-compilation context data by allocating pass and resource + /// arrays sized to the pass count. Cost scales with pass count and resource count in the + /// render graph. + /// + internal static readonly ProfilerMarker k_SetupContextData = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_SetupContextData"); + + /// + /// Marks construction of the pass dependency graph from the recorded render graph pass + /// list. Iterates every pass to resolve resource read/write relationships. Cost scales + /// with total pass count and the number of resource attachments for each pass. + /// + internal static readonly ProfilerMarker k_BuildGraph = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_BuildGraph"); + + /// + /// Marks dead-code elimination of render passes. Removes passes whose outputs are never + /// consumed and have no side effects. Cost scales with total pass count and the depth of + /// resource dependency chains. + /// + internal static readonly ProfilerMarker k_CullNodes = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_CullNodes"); + + /// + /// Marks the pass-merging phase that combines compatible raster passes into a single + /// native render pass. Reduces load/store operations on tile-based hardware. Cost + /// scales with pass count and render target compatibility checks. + /// + internal static readonly ProfilerMarker k_TryMergeNativePasses = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_TryMergeNativePasses"); + + /// + /// Marks the forward and backward traversal that computes the first and last use of + /// each resource. Results drive resource lifetime, async-compute fence placement, and + /// memoryless eligibility. Cost scales with pass count and total resource reference count. + /// + internal static readonly ProfilerMarker k_FindResourceUsageRanges = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_FindResourceUsageRanges"); + + /// + /// Marks the backward traversal that propagates texture UV origin (top-left or + /// bottom-left) through the native pass graph. Ensures correct blit and resolve + /// operations on platforms with flipped coordinate spaces. Cost scales with native + /// pass count and attachment count. + /// + internal static readonly ProfilerMarker k_PropagateTextureUVOrigin = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_PropagateTextureUVOrigin"); + + /// + /// Marks the scan that identifies transient resources eligible for memoryless + /// (tile-local) allocation. Only runs on hardware that supports memoryless textures. + /// Cost scales with native pass count and the number of transient attachments. + /// + internal static readonly ProfilerMarker k_DetectMemorylessResources = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_DetectMemorylessResources"); + + /// + /// Marks the per-pass resource initialization step that allocates and clears transient + /// render targets before their first use. Cost depends on the number of resources + /// created per pass and whether a clear blit is required. + /// + internal static readonly ProfilerMarker k_ExecuteInitializeResources = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_ExecuteInitializeResources"); + + /// + /// Marks determination of load and store actions for each attachment in a native render + /// pass. Evaluates clear, load, discard, and store policies per attachment. Cost scales + /// with attachment count and the complexity of merged subpass configurations. + /// + internal static readonly ProfilerMarker k_PrepareNativePass = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_PrepareNativePass"); + + /// + /// Marks emission of the BeginRenderPass command into the command buffer. Configures + /// attachment descriptors, MSAA, dimensions, and load/store actions for each attachment. + /// Cost scales with attachment count and MSAA resolve complexity. + /// + internal static readonly ProfilerMarker k_ExecuteBeginRenderPassCommand = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_ExecuteBeginRenderpassCommand"); + + /// + /// Marks per-pass resource destruction after the last pass that uses each transient + /// resource. Releases render targets, temporary allocations, and pooled objects. Cost + /// scales with the number of resources destroyed per pass. + /// + internal static readonly ProfilerMarker k_ExecuteDestroyResources = + new ProfilerMarker(ProfilerCategory.Render, "Inl_NRPRGComp_ExecuteDestroyResources"); + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs.meta new file mode 100644 index 00000000000..94922d380f3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Markers.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7f119af5504869344b06b06ee6f1d011 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs index 7a2f498a412..8b86ede0af3 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; +using Unity.Profiling; namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { @@ -184,6 +185,7 @@ void SetPassStatesForNativePass(int nativePassId) NativePassData.SetPassStatesForNativePass(contextData, nativePassId); } + [Obsolete("This enum is deprecated and will be removed in a future release. Please use ProfilerMarkers NRPRGComp_* instead.")] internal enum NativeCompilerProfileId { NRPRGComp_PrepareNativePass, @@ -221,7 +223,7 @@ void ValidatePasses() void SetupContextData(RenderGraphResourceRegistry resources) { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_SetupContextData))) + using (k_SetupContextData.Auto()) { contextData.Initialize(resources, k_EstimatedPassCount); } @@ -351,7 +353,7 @@ void BuildGraph() ctx.passData.ResizeUninitialized(passes.Count); // Build up the context graph and keep track of nodes we encounter that can't be culled - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_BuildGraph))) + using (k_BuildGraph.Auto()) { for (int passId = 0; passId < passes.Count; passId++) { @@ -468,11 +470,11 @@ void BuildGraph() void CullUnusedRenderGraphPasses() { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_CullNodes))) - { - if (graph.disablePassCulling) - return; + if (graph.disablePassCulling) + return; + using (k_CullNodes.Auto()) + { // Must come first CullRenderGraphPassesWithNoSideEffect(); @@ -613,7 +615,7 @@ void TryMergeNativePasses() { var ctx = contextData; - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_TryMergeNativePasses))) + using (k_TryMergeNativePasses.Auto()) { // Try to merge raster passes into the currently active native pass. This will not do pass reordering yet // so it is simply greedy trying to add the next pass to a currently active one. @@ -853,7 +855,7 @@ void FindResourceUsageRangeAndSynchronization() { var ctx = contextData; - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_FindResourceUsageRanges))) + using (k_FindResourceUsageRanges.Auto()) { // Algorithm is in two steps, traversing the list of passes twice @@ -1087,7 +1089,7 @@ void PrepareNativeRenderPasses() void PropagateTextureUVOrigin() { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_PropagateTextureUVOrigin))) + using (k_PropagateTextureUVOrigin.Auto()) { // Work backwards through the native pass list and propagate the texture uv origin we store with to // any texture attachments that are not explicitly known (usually intermediate memoryless attachments). @@ -1156,7 +1158,7 @@ static bool IsGlobalTextureInPass(RenderGraphPass pass, in ResourceHandle handle void DetectMemoryLessResources() { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_DetectMemorylessResources))) + using (k_DetectMemorylessResources.Auto()) { // No need to go further if we don't support memoryless textures if (!SystemInfo.supportsMemorylessTextures) @@ -1256,7 +1258,7 @@ private bool ExecuteInitializeResource(InternalRenderGraphContext rgContext, Ren { bool haveGfxCommandsBeenAddedToCmd = false; - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_ExecuteInitializeResources))) + using (k_ExecuteInitializeResources.Auto()) { resources.forceManualClearOfResource = true; @@ -1337,7 +1339,7 @@ private bool ExecuteInitializeResource(InternalRenderGraphContext rgContext, Ren void DetermineLoadStoreActions(ref NativePassData nativePass) { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_PrepareNativePass))) + using (k_PrepareNativePass.Auto()) { ref readonly var firstGraphPass = ref contextData.passData.ElementAt(nativePass.firstGraphPass); ref readonly var lastGraphPass = ref contextData.passData.ElementAt(nativePass.lastGraphPass); @@ -1736,7 +1738,7 @@ private void ValidateAttachment(in RenderTargetInfo attRenderTargetInfo, RenderG internal unsafe void ExecuteBeginRenderPass(InternalRenderGraphContext rgContext, RenderGraphResourceRegistry resources, ref NativePassData nativePass) { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_ExecuteBeginRenderpassCommand))) + using (k_ExecuteBeginRenderPassCommand.Auto()) { ref var attachments = ref nativePass.attachments; var attachmentCount = attachments.size; @@ -1911,7 +1913,7 @@ internal unsafe void ExecuteBeginRenderPass(InternalRenderGraphContext rgContext private void ExecuteDestroyResource(InternalRenderGraphContext rgContext, RenderGraphResourceRegistry resources, ref PassData pass) { - using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_ExecuteDestroyResources))) + using (k_ExecuteDestroyResources.Auto()) { // Unsafe pass might soon use temporary render targets, // users can also use temporary data in their render graph execute nodes using public RenderGraphObjectPool API diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs index 24e64b37177..15f940be607 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs @@ -10,7 +10,7 @@ public partial class RenderGraph internal NativePassCompiler CompileNativeRenderGraph(int graphHash) { - using (new ProfilingScope(m_RenderGraphContext.cmd, RenderGraphProfilerMarkers.CompileRenderGraph)) + using (RenderGraphProfilerMarkers.CompileRenderGraph.Auto()) { if (nativeCompiler == null) nativeCompiler = new NativePassCompiler(m_CompilationCache); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs index 4a7568118c0..9cedff3d8fa 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs @@ -1443,7 +1443,7 @@ internal string GetTextureName(in TextureHandle textureHandle) // Internal for testing purpose only. internal int ComputeGraphHash() { - using (new ProfilingScope(RenderGraphProfilerMarkers.ComputeHashRenderGraph)) + using (RenderGraphProfilerMarkers.ComputeHashRenderGraph.Auto()) { var hash128 = HashFNV1A32.Create(); for (int i = 0; i < m_RenderPasses.Count; ++i) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphProfilerMarkers.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphProfilerMarkers.cs index cd2f5c9b089..48a92e67888 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphProfilerMarkers.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphProfilerMarkers.cs @@ -12,19 +12,19 @@ internal static class RenderGraphProfilerMarkers /// Compiles the native render graph from the recorded pass list, resolving resource /// lifetimes, merging compatible passes, and allocating transient render targets. /// - public static readonly ProfilingSampler CompileRenderGraph = ProfilingSampler.Create(nameof(CompileRenderGraph), MarkerFlags.Default); - - /// - /// Executes the compiled native render graph, dispatching each pass's render commands - /// through the command buffer with automatic resource barriers and load/store actions. - /// - public static readonly ProfilingSampler ExecuteRenderGraph = ProfilingSampler.Create(nameof(ExecuteRenderGraph), MarkerFlags.Default); + public static readonly ProfilerMarker CompileRenderGraph = new ProfilerMarker(ProfilerCategory.Render, "Inl_CompileRenderGraph"); /// /// Computes an FNV-1a hash of all recorded render graph passes and their resource /// dependencies, used to detect unchanged graphs and skip recompilation. /// CPU-only marker — no GPU sampling. /// - public static readonly ProfilingSampler ComputeHashRenderGraph = ProfilingSampler.Create(nameof(ComputeHashRenderGraph), MarkerFlags.VerbosityAdvanced); + public static readonly ProfilerMarker ComputeHashRenderGraph = new ProfilerMarker(ProfilerCategory.Render, "Inl_ComputeHashRenderGraph", MarkerFlags.VerbosityAdvanced); + + /// + /// Executes the compiled native render graph, dispatching each pass's render commands + /// through the command buffer with automatic resource barriers and load/store actions. + /// + public static readonly ProfilingSampler ExecuteRenderGraph = ProfilingSampler.Create(nameof(ExecuteRenderGraph), MarkerFlags.Default); } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs b/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs index 6677f23a897..3b999047638 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs @@ -1,4 +1,5 @@ using System; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; @@ -944,14 +945,27 @@ public ComputeShader taaCS } /// - /// Profiling identifiers associated with STP's passes + /// Uploads the STP constant buffer and dispatches the setup compute shader at input + /// resolution, sampling input color, depth, and motion to produce intermediate color, + /// depth-motion, luma, convergence, and feedback textures for subsequent passes. + /// Kernel width doubles on Qualcomm GPUs to maximize FP16 ALU efficiency. /// - enum ProfileId - { - StpSetup, - StpPreTaa, - StpTaa - } + static readonly ProfilingSampler k_StpSetup = ProfilingSampler.Create("StpSetup", MarkerFlags.Default); + + /// + /// Dispatches the Pre-TAA compute shader at input resolution to compute per-texel + /// blending weights from the intermediate convergence data, and writes updated luma + /// and convergence history textures consumed by the TAA pass. + /// + static readonly ProfilingSampler k_StpPreTaa = ProfilingSampler.Create("StpPreTaa", MarkerFlags.Default); + + /// + /// Dispatches the TAA compute shader at output resolution to temporally + /// accumulate and upscale the frame using the intermediate color, blending weights, + /// prior feedback, depth-motion, and convergence textures. This is the most expensive + /// of the three STP passes because it runs at the upscaled target resolution. + /// + static readonly ProfilingSampler k_StpTaa = ProfilingSampler.Create("StpTaa", MarkerFlags.Default); /// /// Integer value used to identify when STP is running on a Qualcomm GPU @@ -1106,7 +1120,7 @@ public static TextureHandle Execute(RenderGraph renderGraph, ref Config config) SetupData setupData; - using (var builder = renderGraph.AddComputePass("STP Setup", out var passData, ProfilingSampler.Get(ProfileId.StpSetup))) + using (var builder = renderGraph.AddComputePass("STP Setup", out var passData, k_StpSetup)) { passData.cs = runtimeResources.setupCS; passData.cs.shaderKeywords = null; @@ -1209,7 +1223,7 @@ public static TextureHandle Execute(RenderGraph renderGraph, ref Config config) PreTaaData preTaaData; - using (var builder = renderGraph.AddComputePass("STP Pre-TAA", out var passData, ProfilingSampler.Get(ProfileId.StpPreTaa))) + using (var builder = renderGraph.AddComputePass("STP Pre-TAA", out var passData, k_StpPreTaa)) { passData.cs = runtimeResources.preTaaCS; passData.cs.shaderKeywords = null; @@ -1272,7 +1286,7 @@ public static TextureHandle Execute(RenderGraph renderGraph, ref Config config) TaaData taaData; - using (var builder = renderGraph.AddComputePass("STP TAA", out var passData, ProfilingSampler.Get(ProfileId.StpTaa))) + using (var builder = renderGraph.AddComputePass("STP TAA", out var passData, k_StpTaa)) { passData.cs = runtimeResources.taaCS; passData.cs.shaderKeywords = null; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/GPUSort/GPUSort.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/GPUSort/GPUSort.cs index ee23a3ab8cc..a2c50b983f8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/GPUSort/GPUSort.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/GPUSort/GPUSort.cs @@ -1,4 +1,5 @@ using System; +using Unity.Profiling.LowLevel; using UnityEngine.Assertions; // Ref: https://poniesandlight.co.uk/reflect/bitonic_merge_sort/ @@ -22,6 +23,36 @@ enum Stage BigDisperse } + /// + /// Dispatches the initial bitonic merge sort within each workgroup (up to 2048 elements + /// in each group). Called once per sort. Subsequent passes use the Big/Local Flip and + /// Disperse stages. + /// + static readonly ProfilingSampler k_LocalBMS = ProfilingSampler.Create("LocalBMS", MarkerFlags.Default); + + /// + /// Dispatches the disperse step confined to a single workgroup once the sub-sequence + /// length falls within the 2048-element workgroup boundary. Terminates the inner + /// per-level loop early, avoiding the costlier cross-workgroup BigDisperse dispatch. + /// + static readonly ProfilingSampler k_LocalDisperse = ProfilingSampler.Create("LocalDisperse", MarkerFlags.Default); + + /// + /// Dispatches the cross-workgroup flip step that mirrors and compares elements across + /// the full sort sequence. Called once per doubling of the merge height. Each invocation + /// count grows as O(log n). + /// + static readonly ProfilingSampler k_BigFlip = ProfilingSampler.Create("BigFlip", MarkerFlags.Default); + + /// + /// Dispatches the cross-workgroup disperse step that propagates comparisons across + /// workgroup boundaries. Called for each inner-loop level where the sub-sequence + /// length exceeds 2048. Each invocation count grows as O(log² n). + /// + static readonly ProfilingSampler k_BigDisperse = ProfilingSampler.Create("BigDisperse", MarkerFlags.Default); + + static readonly ProfilingSampler[] k_StageMarkers = { k_LocalBMS, k_LocalDisperse, k_BigFlip, k_BigDisperse }; + private SystemResources resources; /// @@ -47,7 +78,7 @@ void DispatchStage(CommandBuffer cmd, Args args, uint h, Stage stage) Assert.IsNotNull(resources.computeAsset); // When the is no geometry, instead of computing the distance field, we clear it with a big value. - using (new ProfilingScope(cmd, ProfilingSampler.Get(stage))) + using (new ProfilingScope(cmd, k_StageMarkers[(int)stage], resources.computeAsset)) { #if false m_SortCS.enabledKeywords = new[] { keywords[(int)stage] }; From eb3bd5b71122232065e709b1d2a1ae683f4be368 Mon Sep 17 00:00:00 2001 From: April Roszkowski Date: Thu, 2 Apr 2026 09:42:09 +0000 Subject: [PATCH 20/88] [UUM-135644] Allow shader-build-settings-compatible enum keywords in Shader Graph --- .../Editor/Data/Graphs/ShaderKeyword.cs | 74 +++++++-- .../Editor/Data/Implementation/NodeUtils.cs | 2 +- .../Editor/Data/Nodes/Utility/KeywordNode.cs | 33 ++-- .../Editor/Data/Util/KeywordCollector.cs | 16 +- .../Editor/Data/Util/KeywordUtil.cs | 11 +- .../ShaderInputPropertyDrawer.cs | 57 ++++++- .../Editor/Generation/Data/KeywordEntry.cs | 3 + .../CommonAssets/Editor/KeywordTests.cs | 148 ++++++++++++------ .../CommonAssets/Graphs/Keywords.shadergraph | 4 +- .../Assets/Scenes/InputNodes.unity | 4 +- .../BuildSettingCompatibleEnumKeyword.mat | 141 +++++++++++++++++ ...BuildSettingCompatibleEnumKeyword.mat.meta | 8 + ...ldSettingCompatibleEnumKeyword.shadergraph | 3 + ...tingCompatibleEnumKeyword.shadergraph.meta | 20 +++ .../Graphs/Input/Basic/EnumKeyword.mat | 141 +++++++++++++++++ .../Graphs/Input/Basic/EnumKeyword.mat.meta | 8 + .../Input/Basic/EnumKeyword.shadergraph | 3 + .../Input/Basic/EnumKeyword.shadergraph.meta | 20 +++ .../ProjectSettings/GraphicsSettings.asset | 37 ++++- 19 files changed, 641 insertions(+), 92 deletions(-) create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat.meta create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph.meta create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat.meta create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph create mode 100644 Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph.meta diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderKeyword.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderKeyword.cs index 1cbab74f7de..2bc1f332194 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderKeyword.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderKeyword.cs @@ -68,6 +68,9 @@ public KeywordType keywordType internal bool IsDynamic => m_KeywordDefinition == KeywordDefinition.DynamicBranch; + // If true, indicates that ShaderGraph may pre-compute permutations containing this keyword + internal bool IsPermutable => !IsDynamic && !IsShaderBuildSettingsCompatible; + [SerializeField] private KeywordDefinition m_KeywordDefinition = KeywordDefinition.ShaderFeature; @@ -104,6 +107,8 @@ public List entries set => m_Entries = value; } + public bool HasNoneEntry => entries.Count > 0 && entries[0].IsNoneKeyword; + [SerializeField] private int m_Value; @@ -116,6 +121,17 @@ public int value [SerializeField] private bool m_IsEditable = true; // this serializes !isBuiltIn + [SerializeField] + private bool m_IsShaderBuildSettingsCompatible = true; + + // Note that if this field is true, we must effectively treat this keyword as a dynamic branch for code gen + // purposes as its definition may be overridden by project settings. + public bool IsShaderBuildSettingsCompatible + { + get => m_IsShaderBuildSettingsCompatible; + set => m_IsShaderBuildSettingsCompatible = value; + } + public bool isBuiltIn { get => !m_IsEditable; @@ -130,6 +146,21 @@ public bool isBuiltIn internal override ConcreteSlotValueType concreteShaderValueType => keywordType.ToConcreteSlotValueType(); + public IEnumerable<(KeywordEntry entry, int value)> GetEntriesExcludingNone() + { + for (int i = HasNoneEntry ? 1 : 0; i < entries.Count; ++i) + yield return (entries[i], i); + } + + // Enumerates the enum's entries in the order one would emit 'if', 'else if', and 'else' branches + public IEnumerable<(KeywordEntry entry, int value)> GetEntriesInBranchOrder() + { + foreach (var entry in GetEntriesExcludingNone()) + yield return entry; + if (HasNoneEntry) + yield return (entries[0], 0); + } + public override string GetOldDefaultReferenceName() { // _ON suffix is required for exposing Boolean type to Material @@ -184,10 +215,16 @@ public string GetKeywordPreviewDeclarationString() case KeywordType.Boolean: return $"#define {referenceName} {(value == 0 ? "false" : " true")}"; case KeywordType.Enum: - string result = $"#define {referenceName}_{entries[value].referenceName} true"; - for (int i = 0; i < entries.Count; ++i) - if (i != value) - result += $"\n#define {referenceName}_{entries[i].referenceName} false"; + string result = entries[value].IsNoneKeyword ? + string.Empty : $"#define {referenceName}_{entries[value].referenceName} true"; + foreach ((KeywordEntry entry, int entryValue) in GetEntriesExcludingNone()) + { + if (entryValue != value) + { + string newline = result.Length == 0 ? string.Empty : "\n"; + result += $"{newline}#define {referenceName}_{entry.referenceName} false"; + } + } return result; default: throw new ArgumentOutOfRangeException(); @@ -196,9 +233,19 @@ public string GetKeywordPreviewDeclarationString() else switch (keywordType) { case KeywordType.Boolean: - return value == 1 ? $"#define {referenceName}" : string.Empty; + return value == 1 ? $"#define {referenceName} true" : $"static const bool {referenceName} = false;"; case KeywordType.Enum: - return $"#define {referenceName}_{entries[value].referenceName}"; + string enumResult = entries[value].IsNoneKeyword ? + string.Empty : $"#define {referenceName}_{entries[value].referenceName} true"; + foreach ((KeywordEntry entry, int entryValue) in GetEntriesExcludingNone()) + { + if (entryValue != value) + { + string newline = enumResult.Length == 0 ? string.Empty : "\n"; + enumResult += $"{newline}static const bool {referenceName}_{entry.referenceName} = false;"; + } + } + return enumResult; default: throw new ArgumentOutOfRangeException(); } @@ -219,16 +266,17 @@ internal override ShaderInput Copy() keywordScope = keywordScope, entries = entries, keywordStages = keywordStages, - overrideReferenceName = overrideReferenceName + overrideReferenceName = overrideReferenceName, + IsShaderBuildSettingsCompatible = IsShaderBuildSettingsCompatible, }; } - public override int latestVersion => 1; + public override int latestVersion => 2; public override void OnAfterDeserialize(string json) { if (sgVersion == 0) { - // we now allow keywords to control whether they are exposed (for Material control) or not. + // Version 1 allows keywords to control whether they are exposed (for Material control) or not. // old exposable keywords set their exposed state to maintain previous behavior // (where bool keywords only showed up in the material when ending in "_ON") if (isExposable) @@ -240,6 +288,14 @@ public override void OnAfterDeserialize(string json) } ChangeVersion(1); } + if (sgVersion < 2) + { + // Version 2 marks the point at which we changed KeywordNode code gen to be compatible with + // Shader Build Settings. Legacy shader graphs should default to incompatible KeywordNode + // code gen. + IsShaderBuildSettingsCompatible = false; + ChangeVersion(2); + } } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs b/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs index 76d95aedd8f..4ea6d2d7758 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs @@ -118,7 +118,7 @@ public static void DepthFirstCollectNodesFromNode(ICollection x.Key == keywordNode.keyword).FirstOrDefault(); ids = new int[] { keywordNode.GetSlotIdForPermutation(valueInPermutation) }; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs index dbd19e58051..c31561cb0bb 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs @@ -140,7 +140,8 @@ void UpdatePorts() public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { var outputSlot = FindOutputSlot(OutputSlotId); - if (keyword.keywordDefinition == KeywordDefinition.DynamicBranch) + if (keyword.keywordDefinition == KeywordDefinition.DynamicBranch + || keyword.IsShaderBuildSettingsCompatible) { switch (keyword.keywordType) { @@ -151,16 +152,23 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo break; case KeywordType.Enum: sb.AppendLine(string.Format($"{outputSlot.concreteValueType.ToShaderString()} {GetVariableNameForSlot(OutputSlotId)};")); - for(int i = 0; i < keyword.entries.Count; ++i) + int i = 0; + foreach ((KeywordEntry entry, int entryValue) in keyword.GetEntriesInBranchOrder()) { - var keywordEntry = keyword.entries[i]; - string keywordName = $"{keyword.referenceName}_{keywordEntry.referenceName}"; - var value = GetSlotValue(keywordEntry.id, generationMode); - sb.AppendLine(string.Format($"{(i != 0 ? "else" : "")} if({keywordName}) {GetVariableNameForSlot(OutputSlotId)} = {value};")); + string keywordName = $"{keyword.referenceName}_{entry.referenceName}"; + var value = GetSlotValue(entry.id, generationMode); + string assignment = $"{GetVariableNameForSlot(OutputSlotId)} = {value};"; + if (i == 0) + sb.AppendLine($"if ({keywordName}) {assignment}"); + else if (i == keyword.entries.Count - 1) + sb.AppendLine($"else {assignment}"); + else + sb.AppendLine($"else if ({keywordName}) {assignment}"); + ++i; } break; } - } + } else switch (keyword.keywordType) { case KeywordType.Boolean: @@ -180,12 +188,13 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo case KeywordType.Enum: { // Iterate all entries in the keyword - for (int i = 0; i < keyword.entries.Count; i++) + int i = 0; + foreach ((KeywordEntry entry, int entryValue) in keyword.GetEntriesInBranchOrder()) { // Insert conditional if (i == 0) { - sb.AppendLine($"#if defined({keyword.referenceName}_{keyword.entries[i].referenceName})"); + sb.AppendLine($"#if defined({keyword.referenceName}_{entry.referenceName})"); } else if (i == keyword.entries.Count - 1) { @@ -193,12 +202,14 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo } else { - sb.AppendLine($"#elif defined({keyword.referenceName}_{keyword.entries[i].referenceName})"); + sb.AppendLine($"#elif defined({keyword.referenceName}_{entry.referenceName})"); } // Append per-slot code - var value = GetSlotValue(GetSlotIdForPermutation(new KeyValuePair(keyword, i)), generationMode); + var value = GetSlotValue(GetSlotIdForPermutation(new KeyValuePair(keyword, entryValue)), generationMode); sb.AppendLine(string.Format($"{outputSlot.concreteValueType.ToShaderString()} {GetVariableNameForSlot(OutputSlotId)} = {value};")); + + ++i; } // End condition diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordCollector.cs b/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordCollector.cs index 6f4dcbb8a5e..7e0cd195ba9 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordCollector.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordCollector.cs @@ -25,7 +25,7 @@ public void AddShaderKeyword(ShaderKeyword chunk) keywords.Add(chunk); - if (!chunk.IsDynamic) + if (chunk.IsPermutable) permutableKeywords.Add(chunk); } @@ -67,21 +67,29 @@ public void CalculateKeywordPermutations() for (int i = 0; i < permutableKeywords.Count; i++) { - currentPermutation.Add(new KeyValuePair(permutableKeywords[i], 0)); + var firstEntryValue = GetEntryValues(permutableKeywords[i]).First(); + currentPermutation.Add(new KeyValuePair(permutableKeywords[i], firstEntryValue)); } // Recursively permute keywords PermuteKeywords(permutableKeywords, currentPermutation, 0); } + IEnumerable GetEntryValues(ShaderKeyword keyword) + { + if (keyword.keywordType == KeywordType.Enum) + return keyword.GetEntriesInBranchOrder().Select(x => x.value); + else + return new int[] { 0, 1 }; + } + void PermuteKeywords(List keywords, List> currentPermutation, int currentIndex) { if (currentIndex == keywords.Count) return; // Iterate each possible keyword at the current index - int entryCount = keywords[currentIndex].keywordType == KeywordType.Enum ? keywords[currentIndex].entries.Count : 2; - for (int i = 0; i < entryCount; i++) + foreach (int i in GetEntryValues(keywords[currentIndex])) { // Set the index in the current permutation to the correct value currentPermutation[currentIndex] = new KeyValuePair(keywords[currentIndex], i); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs b/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs index cf65282f808..bcf7aa5c881 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs @@ -233,15 +233,20 @@ public static void GetKeywordPermutationDeclarations(ShaderStringBuilder sb, Lis // Iterate all keywords that are part of the permutation for (int i = 0; i < permutations[p].Count; i++) { + (ShaderKeyword keyword, int entryValue) = permutations[p][i]; + // When previous keyword was inserted subsequent requires && string and = appendAnd ? " && " : string.Empty; - switch (permutations[p][i].Key.keywordType) + switch (keyword.keywordType) { case KeywordType.Enum: { - sb.Append($"{and}defined({permutations[p][i].Key.referenceName}_{permutations[p][i].Key.entries[permutations[p][i].Value].referenceName})"); - appendAnd = true; + if (!keyword.entries[entryValue].IsNoneKeyword) + { + sb.Append($"{and}defined({keyword.referenceName}_{keyword.entries[entryValue].referenceName})"); + appendAnd = true; + } break; } case KeywordType.Boolean: diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs index fdd036d609e..48cfd26f2d7 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs @@ -1722,6 +1722,19 @@ void BuildKeywordFields(PropertySheet propertySheet, ShaderInput shaderInput) propertySheet.Add(help); } + var isShaderBuildSettingsCompatibleDrawer = new ToggleDataPropertyDrawer(); + propertySheet.Add(isShaderBuildSettingsCompatibleDrawer.CreateGUI( + newValue => + { + this._preChangeValueCallback("Change Keyword Allow Definition Override"); + keyword.IsShaderBuildSettingsCompatible = newValue.isOn; + this._postChangeValueCallback(modificationScope: ModificationScope.Graph); + }, + new ToggleData(keyword.IsShaderBuildSettingsCompatible), + "Allow Definition Override", + out VisualElement isShaderBuildSettingsCompatibleToggle, + tooltip: "Indicates whether this keyword's definition can be overridden by the project's shader build settings.")); + typeField.SetEnabled(!keyword.isBuiltIn); { var isOverridablePropertyDrawer = new ToggleDataPropertyDrawer(); @@ -1730,15 +1743,15 @@ void BuildKeywordFields(PropertySheet propertySheet, ShaderInput shaderInput) propertySheet.Add(isOverridablePropertyDrawer.CreateGUI( newValue => { - this._preChangeValueCallback("Change Keyword Is Overridable"); + this._preChangeValueCallback("Change Keyword Allow State Override"); keyword.keywordScope = newValue.isOn ? KeywordScope.Global : KeywordScope.Local; }, new ToggleData(toggleState), - "Is Overridable", + "Allow State Override", out keywordScopeField, - tooltip: "Indicate whether this keyword's state can be overridden through the Shader.SetKeyword scripting interface.")); + tooltip: "Indicates whether this keyword's state can be overridden through the Shader.SetKeyword scripting interface.")); keywordScopeField.SetEnabled(enabledState); } BuildExposedField(propertySheet); @@ -1794,6 +1807,24 @@ void BuildEnumKeywordField(PropertySheet propertySheet, ShaderKeyword keyword) // Clamp value between entry list int value = Mathf.Clamp(keyword.value, 0, keyword.entries.Count - 1); + // Include "none" entry + var includeNoneDrawer = new ToggleDataPropertyDrawer(); + propertySheet.Add(includeNoneDrawer.CreateGUI( + (newValue) => + { + this._preChangeValueCallback("Change Include None Value"); + if (newValue.isOn) + keyword.entries.Insert(0, new KeywordEntry(GetFirstUnusedKeywordID(), "None", string.Empty)); + else + keyword.entries.RemoveAll(entry => entry.IsNoneKeyword); + this._postChangeValueCallback(); + this._keywordChangedCallback(); + }, + new ToggleData(keyword.HasNoneEntry), + "Include \"none\" entry", + out VisualElement includeNoneToggle, + tooltip: "Indicates whether the enum can assume a \"none\" value as indicated by the \"_\" keyword.")); + // Default field var field = new PopupField(keyword.entries.Select(x => x.displayName).ToList(), value); field.RegisterValueChangedCallback(evt => @@ -2044,6 +2075,7 @@ void KeywordAddCallbacks() { KeywordEntry entry = ((KeywordEntry)m_KeywordReorderableList.list[index]); EditorGUI.BeginChangeCheck(); + EditorGUI.BeginDisabled(entry.IsNoneKeyword); Rect displayRect = new Rect(rect.x, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight); var displayName = EditorGUI.DelayedTextField(displayRect, entry.displayName, EditorStyles.label); @@ -2052,6 +2084,7 @@ void KeywordAddCallbacks() var referenceName = EditorGUI.TextField(new Rect(rect.x + rect.width / 2, rect.y, rect.width / 2, EditorGUIUtility.singleLineHeight), entry.referenceName, keyword.isBuiltIn ? EditorStyles.label : greyLabel); + EditorGUI.EndDisabled(); if (EditorGUI.EndChangeCheck()) { this._preChangeValueCallback("Edit Enum Keyword Entry"); @@ -2177,6 +2210,24 @@ void KeywordRemoveEntry(ReorderableList list) void KeywordReorderEntries(ReorderableList list) { + if (shaderInput is not ShaderKeyword keyword) + return; + + // Ensure that the "none" entry is always at position 0 + int noneEntryIndex = 0; + for (; noneEntryIndex < list.list.Count; ++noneEntryIndex) + { + KeywordEntry entry = (KeywordEntry)list.list[noneEntryIndex]; + if (entry.IsNoneKeyword) + break; + } + if (0 < noneEntryIndex && noneEntryIndex < list.list.Count) + { + object noneEntry = list.list[noneEntryIndex]; + list.list.RemoveAt(noneEntryIndex); + list.list.Insert(0, noneEntry); + } + this._preChangeValueCallback("Reorder Keyword Entry"); this._postChangeValueCallback(true); this._keywordChangedCallback(); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Data/KeywordEntry.cs b/Packages/com.unity.shadergraph/Editor/Generation/Data/KeywordEntry.cs index 41bc0e3787e..e21b1cb234f 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Data/KeywordEntry.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Data/KeywordEntry.cs @@ -10,6 +10,9 @@ internal struct KeywordEntry public string displayName; public string referenceName; + // Is this entry the "none" keyword (i.e. "_") + public bool IsNoneKeyword => string.IsNullOrEmpty(referenceName); + // In this case, we will handle the actual IDs later public KeywordEntry(string displayName, string referenceName) { diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Editor/KeywordTests.cs b/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Editor/KeywordTests.cs index d20d11b0ce5..5621937bcf7 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Editor/KeywordTests.cs +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Editor/KeywordTests.cs @@ -12,21 +12,33 @@ namespace UnityEditor.ShaderGraph.UnitTests [TestFixture] internal class KeywordTests { - const string kExpectedPreviewDeclaration = @"#define BOOLEAN_E0DB5C9A_ON -#define ENUM_F6B920FA_A -#define ENUM_7ECD6A43_D + const string kExpectedPreviewDeclaration = @"#define BOOLEAN_E0DB5C9A_ON true +static const bool BOOLEAN_12C0E932_ON = false; +static const bool ENUM_F6B920FA_A = false; +static const bool ENUM_F6B920FA_B = false; +static const bool ENUM_F6B920FA_C = false; +#define ENUM_7ECD6A43_D true +static const bool ENUM_7ECD6A43_A = false; +static const bool ENUM_7ECD6A43_B = false; +static const bool ENUM_7ECD6A43_C = false; #define _DYNAMIC_BOOLEAN false #define _DYNAMIC_ENUM_A true #define _DYNAMIC_ENUM_B false #define _DYNAMIC_ENUM_C false +#define _COMPATIBLE_BOOLEAN true +#define _COMPATIBLE_ENUM_A true +static const bool _COMPATIBLE_ENUM_B = false; +static const bool _COMPATIBLE_ENUM_C = false; "; const string kExpectedForRealsDeclaration = @"#pragma shader_feature_local _ BOOLEAN_E0DB5C9A_ON #pragma multi_compile _ BOOLEAN_12C0E932_ON -#pragma shader_feature_local ENUM_F6B920FA_A ENUM_F6B920FA_B ENUM_F6B920FA_C +#pragma shader_feature_local _ ENUM_F6B920FA_A ENUM_F6B920FA_B ENUM_F6B920FA_C #pragma multi_compile ENUM_7ECD6A43_A ENUM_7ECD6A43_B ENUM_7ECD6A43_C ENUM_7ECD6A43_D #pragma dynamic_branch_local _ _DYNAMIC_BOOLEAN #pragma dynamic_branch_local _DYNAMIC_ENUM_A _DYNAMIC_ENUM_B _DYNAMIC_ENUM_C +#pragma shader_feature_local _ _COMPATIBLE_BOOLEAN +#pragma shader_feature_local _COMPATIBLE_ENUM_A _COMPATIBLE_ENUM_B _COMPATIBLE_ENUM_C "; static string kExpectedPermutationDeclaration = @"#if defined(BOOLEAN_E0DB5C9A_ON) && defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) @@ -53,78 +65,110 @@ internal class KeywordTests #define KEYWORD_PERMUTATION_10 #elif defined(BOOLEAN_E0DB5C9A_ON) && defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_11 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_12 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_13 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_14 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_15 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_16 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_17 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_18 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_19 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_20 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_21 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_22 -#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_23 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_24 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_25 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_26 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_27 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_28 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_29 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_30 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_E0DB5C9A_ON) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_31 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_32 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_33 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_34 -#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_35 -#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_36 -#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_37 -#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_38 -#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_39 -#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_40 -#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_41 -#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_42 -#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_D) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_43 -#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_A) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_A) #define KEYWORD_PERMUTATION_44 -#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_B) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_B) #define KEYWORD_PERMUTATION_45 -#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_C) +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_C) #define KEYWORD_PERMUTATION_46 -#else +#elif defined(BOOLEAN_12C0E932_ON) && defined(ENUM_7ECD6A43_D) #define KEYWORD_PERMUTATION_47 +#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_A) + #define KEYWORD_PERMUTATION_48 +#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_B) + #define KEYWORD_PERMUTATION_49 +#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_C) + #define KEYWORD_PERMUTATION_50 +#elif defined(ENUM_F6B920FA_A) && defined(ENUM_7ECD6A43_D) + #define KEYWORD_PERMUTATION_51 +#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_A) + #define KEYWORD_PERMUTATION_52 +#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_B) + #define KEYWORD_PERMUTATION_53 +#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_C) + #define KEYWORD_PERMUTATION_54 +#elif defined(ENUM_F6B920FA_B) && defined(ENUM_7ECD6A43_D) + #define KEYWORD_PERMUTATION_55 +#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_A) + #define KEYWORD_PERMUTATION_56 +#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_B) + #define KEYWORD_PERMUTATION_57 +#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_C) + #define KEYWORD_PERMUTATION_58 +#elif defined(ENUM_F6B920FA_C) && defined(ENUM_7ECD6A43_D) + #define KEYWORD_PERMUTATION_59 +#elif defined(ENUM_7ECD6A43_A) + #define KEYWORD_PERMUTATION_60 +#elif defined(ENUM_7ECD6A43_B) + #define KEYWORD_PERMUTATION_61 +#elif defined(ENUM_7ECD6A43_C) + #define KEYWORD_PERMUTATION_62 +#else + #define KEYWORD_PERMUTATION_63 #endif "; @@ -306,19 +350,19 @@ public void CanGetPermutationMapPerNode() int booleanAIndex = descendentNodes.IndexOf(booleanANode); List booleanAPermutations = keywordPermutationsPerNode[booleanAIndex]; - Assert.AreEqual(24, booleanAPermutations.Count, "Boolean A had incorrect permutations."); + Assert.AreEqual(32, booleanAPermutations.Count, "Boolean A had incorrect permutations."); int booleanBIndex = descendentNodes.IndexOf(booleanBNode); List booleanBPermutations = keywordPermutationsPerNode[booleanBIndex]; - Assert.AreEqual(48, booleanBPermutations.Count, "Boolean B had incorrect permutations."); + Assert.AreEqual(64, booleanBPermutations.Count, "Boolean B had incorrect permutations."); int enumAIndex = descendentNodes.IndexOf(enumANode); List enumAPermutations = keywordPermutationsPerNode[enumAIndex]; - Assert.AreEqual(12, enumAPermutations.Count, "Enum A had incorrect permutations."); + Assert.AreEqual(16, enumAPermutations.Count, "Enum A had incorrect permutations."); int enumBIndex = descendentNodes.IndexOf(enumBNode); List enumBPermutations = keywordPermutationsPerNode[enumBIndex]; - Assert.AreEqual(24, enumBPermutations.Count, "Enum B had incorrect permutations."); + Assert.AreEqual(32, enumBPermutations.Count, "Enum B had incorrect permutations."); } [Test] @@ -339,10 +383,10 @@ public void KeywordEnumCanAddAndRemovePort() Assert.Fail("One or more Keywords Nodes not in graph."); } - KeywordEntry newEntry1 = new KeywordEntry(4, "D", "D"); - KeywordEntry newEntry2 = new KeywordEntry(5, "E", "E"); - KeywordEntry newEntry3 = new KeywordEntry(6, "F", "F"); - KeywordEntry newEntry4 = new KeywordEntry(5, "E", "E"); + KeywordEntry newEntry1 = new KeywordEntry(14, "D", "D"); + KeywordEntry newEntry2 = new KeywordEntry(15, "E", "E"); + KeywordEntry newEntry3 = new KeywordEntry(16, "F", "F"); + KeywordEntry newEntry4 = new KeywordEntry(15, "E", "E"); enumAKeyword.entries.Add(newEntry1); @@ -350,13 +394,13 @@ public void KeywordEnumCanAddAndRemovePort() enumAKeyword.entries.Add(newEntry3); enumBKeyword.entries.Add(newEntry4); - Assert.AreEqual(6, enumAKeyword.entries.Count, "Enum A Keyword has incorrect # of entries after adding"); + Assert.AreEqual(7, enumAKeyword.entries.Count, "Enum A Keyword has incorrect # of entries after adding"); Assert.AreEqual(5, enumBKeyword.entries.Count, "Enum B Keyword has incorrect # of entries after adding"); enumANode.UpdateNode(); enumBNode.UpdateNode(); - Assert.AreEqual(7, enumANode.GetSlots().Count(), "Enum A Node has incorrect # of entries after adding"); + Assert.AreEqual(8, enumANode.GetSlots().Count(), "Enum A Node has incorrect # of entries after adding"); Assert.AreEqual(6, enumBNode.GetSlots().Count(), "Enum B Node has incorrect # of entries after adding"); enumAKeyword.entries.Remove(newEntry1); @@ -364,13 +408,13 @@ public void KeywordEnumCanAddAndRemovePort() enumAKeyword.entries.Remove(newEntry3); enumBKeyword.entries.Remove(newEntry4); - Assert.AreEqual(3, enumAKeyword.entries.Count, "Enum A Keyword has incorrect # of entries after removing"); + Assert.AreEqual(4, enumAKeyword.entries.Count, "Enum A Keyword has incorrect # of entries after removing"); Assert.AreEqual(4, enumBKeyword.entries.Count, "Enum B Keyword has incorrect # of entries after removing"); enumANode.UpdateNode(); enumBNode.UpdateNode(); - Assert.AreEqual(4, enumANode.GetSlots().Count(), "Enum A Node has incorrect # of entries after removing"); + Assert.AreEqual(5, enumANode.GetSlots().Count(), "Enum A Node has incorrect # of entries after removing"); Assert.AreEqual(5, enumBNode.GetSlots().Count(), "Enum B Node has incorrect # of entries after removing"); } } diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Graphs/Keywords.shadergraph b/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Graphs/Keywords.shadergraph index 46c5cabb1fc..3f5d1bd45fe 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Graphs/Keywords.shadergraph +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/CommonAssets/Graphs/Keywords.shadergraph @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8bed5b5361fb5b8f277ddb5791266188ec2ed95a7350e46e5b8a5fa69b5305dc -size 41697 +oid sha256:017cbdb6d89ee9ccceb9a0893dd79fa59b6cbca5e0547bb6b485f1cec53d8386 +size 54472 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Scenes/InputNodes.unity b/Tests/SRPTests/Projects/ShaderGraph/Assets/Scenes/InputNodes.unity index dc0c88f7073..60fcb540061 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Assets/Scenes/InputNodes.unity +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Scenes/InputNodes.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09de40ee4b70e3f4c9e9fdde8728c632bdd1bf4b34f193b6295a9ccfc59b1e70 -size 441490 +oid sha256:559894acec3a2646b55efb2ea7d6c6408f0126fad66d042e94043387748616b2 +size 447643 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat new file mode 100644 index 00000000000..aacb4a4aa72 --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat @@ -0,0 +1,141 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-4248922376544952985 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: BuildSettingCompatibleEnumKeyword + m_Shader: {fileID: -6465566751694194690, guid: b98824ba3d9ce484f9b7020eaeb8f45c, + type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _INPUTNODESENUMKEYWORD_B + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _INPUTNODESENUMKEYWORD: 1 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueControl: 0 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat.meta b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat.meta new file mode 100644 index 00000000000..189a25bd14c --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7e135ce1fc2f1e2468b796d6d1a6dc15 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph new file mode 100644 index 00000000000..5f0de2dac29 --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce168d0370ac0e7407c2189fdc438b43fc0cce78e9f3cabcaadf8377ff2d457e +size 16288 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph.meta b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph.meta new file mode 100644 index 00000000000..8ee8eab756b --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/BuildSettingCompatibleEnumKeyword.shadergraph.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: b98824ba3d9ce484f9b7020eaeb8f45c +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} + useAsTemplate: 0 + exposeTemplateAsShader: 0 + indexedData: {instanceID: 0} + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat new file mode 100644 index 00000000000..909e00b6ce9 --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat @@ -0,0 +1,141 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-4248922376544952985 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: EnumKeyword + m_Shader: {fileID: -6465566751694194690, guid: 48808af23a2e5db4ea94a9710cbe9e87, + type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _INPUTNODESENUMKEYWORD_B + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _INPUTNODESENUMKEYWORD: 1 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueControl: 0 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat.meta b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat.meta new file mode 100644 index 00000000000..7b147c63361 --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c711b1f2a36ce8447ae0683ca4ed0fbf +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph new file mode 100644 index 00000000000..140c0c67f8a --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd343fcda4c191d7698c905d3056985e420827288d1216f7f6c5a619e95ba79a +size 15445 diff --git a/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph.meta b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph.meta new file mode 100644 index 00000000000..6e83211e971 --- /dev/null +++ b/Tests/SRPTests/Projects/ShaderGraph/Assets/Testing/IntegrationTests/Graphs/Input/Basic/EnumKeyword.shadergraph.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: 48808af23a2e5db4ea94a9710cbe9e87 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} + useAsTemplate: 0 + exposeTemplateAsShader: 0 + indexedData: {instanceID: 0} + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 diff --git a/Tests/SRPTests/Projects/ShaderGraph/ProjectSettings/GraphicsSettings.asset b/Tests/SRPTests/Projects/ShaderGraph/ProjectSettings/GraphicsSettings.asset index e93833a2c10..d3e9be93f9b 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/ProjectSettings/GraphicsSettings.asset +++ b/Tests/SRPTests/Projects/ShaderGraph/ProjectSettings/GraphicsSettings.asset @@ -3,7 +3,7 @@ --- !u!30 &1 GraphicsSettings: m_ObjectHideFlags: 0 - serializedVersion: 12 + serializedVersion: 16 m_Deferred: m_Mode: 1 m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} @@ -13,9 +13,6 @@ GraphicsSettings: m_ScreenSpaceShadows: m_Mode: 1 m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} - m_LegacyDeferred: - m_Mode: 1 - m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} m_DepthNormals: m_Mode: 1 m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} @@ -28,6 +25,7 @@ GraphicsSettings: m_LensFlare: m_Mode: 1 m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_VideoShadersIncludeMode: 2 m_AlwaysIncludedShaders: - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} @@ -36,6 +34,16 @@ GraphicsSettings: - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} m_PreloadedShaders: [] + m_PreloadShadersBatchTimeLimit: -1 + m_GraphicsStateCollection: {fileID: 0} + m_CollectionStartupAction: 0 + m_TraceSavePath: TracedCollection + m_TraceSendToEditor: 1 + m_AdditionalWarmupCollections: [] + m_WarmupAsync: 1 + m_EnableCacheMissTracing: 0 + m_WarmupProgressivelyLimit: -1 + m_CacheMissCollectionPath: CacheMissCollection m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} m_CustomRenderPipeline: {fileID: 11400000, guid: 9c068d834ef325345b87395bd103e074, @@ -48,6 +56,8 @@ GraphicsSettings: m_LightmapStripping: 0 m_FogStripping: 0 m_InstancingStripping: 0 + m_BrgStripping: 0 + m_DefaultLightBaker: 0 m_LightmapKeepPlain: 1 m_LightmapKeepDirCombined: 1 m_LightmapKeepDynamicPlain: 1 @@ -58,5 +68,22 @@ GraphicsSettings: m_FogKeepExp: 1 m_FogKeepExp2: 1 m_AlbedoSwatchInfos: [] + m_RenderPipelineGlobalSettingsMap: + UnityEngine.Rendering.Universal.UniversalRenderPipeline: {fileID: 11400000, guid: 35bc433cead364605bb59ecbb49e64e3, + type: 2} + m_ShaderBuildSettings: + keywordDeclarationOverrides: + - keywords: + - name: _INPUTNODESBUILDSETTINGCOMPATIBLEENUMKEYWORD_A + keepInBuild: 1 + - name: _INPUTNODESBUILDSETTINGCOMPATIBLEENUMKEYWORD_B + keepInBuild: 1 + variantGenerationMode: 3 + numInternalDefines: 0 + defines: [] m_LightsUseLinearIntensity: 1 - m_LightsUseColorTemperature: 0 + m_LightsUseColorTemperature: 1 + m_LogWhenShaderIsCompiled: 0 + m_LightProbeOutsideHullStrategy: 0 + m_CameraRelativeLightCulling: 0 + m_CameraRelativeShadowCulling: 0 From 1dbdd5cd942a42766cce6c9a5ab57ebccfa05669 Mon Sep 17 00:00:00 2001 From: Yorgos Petkakis Date: Thu, 2 Apr 2026 13:12:24 +0000 Subject: [PATCH 21/88] Remove GTF's dependency to the Test Protocol Package --- .../Projects/BatchRendererGroup_HDRP/Packages/manifest.json | 1 + .../Projects/BatchRendererGroup_URP/Packages/manifest.json | 1 + .../BuiltInGraphicsTest_Foundation/Packages/manifest.json | 1 + .../Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json | 1 + Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json | 1 + Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json | 1 + Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json | 1 + Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json | 1 + Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json | 1 + Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json | 1 + .../Projects/ShaderGraphUniversalStereo/Packages/manifest.json | 1 + .../Projects/UniversalGraphicsTest_2D/Packages/manifest.json | 1 + .../UniversalGraphicsTest_Foundation/Packages/manifest.json | 1 + .../UniversalGraphicsTest_Lighting/Packages/manifest.json | 1 + .../UniversalGraphicsTest_PostPro/Packages/manifest.json | 1 + .../UniversalGraphicsTest_Terrain/Packages/manifest.json | 1 + .../Projects/VisualEffectGraph_HDRP/Packages/manifest.json | 1 + .../Projects/VisualEffectGraph_URP/Packages/manifest.json | 1 + 18 files changed, 18 insertions(+) diff --git a/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json b/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json index 3339c35995c..bd6a0bf0577 100644 --- a/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json @@ -4,6 +4,7 @@ "dependencies": { "com.unity.collections": "2.1.0-pre.12", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.mathematics": "1.2.1", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", diff --git a/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json b/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json index 3e2768933cf..502642ad240 100644 --- a/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "disableProjectUpdate": true, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.collections": "2.1.0-pre.12", "com.unity.mathematics": "1.2.1", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json index 3b579cbe242..c362edb6515 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json @@ -5,6 +5,7 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.38", "com.unity.ide.visualstudio": "2.0.7", "com.unity.ide.vscode": "1.1.3", diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json index 3b579cbe242..c362edb6515 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json @@ -5,6 +5,7 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.38", "com.unity.ide.visualstudio": "2.0.7", "com.unity.ide.vscode": "1.1.3", diff --git a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json index d4b346e3c46..2186089ad1b 100644 --- a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json @@ -3,6 +3,7 @@ "disableProjectUpdate": true, "dependencies": { "com.unity.ide.visualstudio": "2.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", "com.unity.render-pipelines.high-definition-config": "file:../../../../../Packages/com.unity.render-pipelines.high-definition-config", diff --git a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json index 99b80c5deca..29d69aaa116 100644 --- a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json @@ -1,6 +1,7 @@ { "enableLockFile": false, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.rider": "3.0.16", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json index b7267aaf0f2..ad0460ec806 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "dependencies": { "com.unity.collections": "1.4.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.16", "com.unity.ide.visualstudio": "2.0.22", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json index bbfd8b8e53e..33db285f4bb 100644 --- a/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "disableProjectUpdate": true, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.feature.development": "1.0.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json index 649d341987b..edbcd4dd71f 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "disableProjectUpdate": true, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.17", "com.unity.ide.visualstudio": "2.0.17", "com.unity.postprocessing": "3.5.3", diff --git a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json index eba38df28a9..6c2af918bad 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json @@ -1,6 +1,7 @@ { "enableLockFile": false, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.vscode": "1.1.3", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json index 95f08794467..d5c8b87b384 100644 --- a/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "dependencies": { "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.visualstudio": "2.0.1", "com.unity.ide.vscode": "1.2.0", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json index 32bf3156f5f..09e6e7b63c0 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json @@ -6,6 +6,7 @@ "com.unity.2d.tilemap": "1.0.0", "com.unity.cinemachine": "2.10.7", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.feature.2d": "file:../../../../../Packages/com.unity.feature.2d", "com.unity.ide.rider": "3.0.38", "com.unity.ide.visualstudio": "2.0.25", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json index e3112bf26e8..f2014e649f0 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json @@ -5,6 +5,7 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "2.0.9", "com.unity.nuget.newtonsoft-json": "2.0.1-preview.1", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json index e8a1d139857..ab8ef8af0dc 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json @@ -5,6 +5,7 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "2.0.9", "com.unity.nuget.newtonsoft-json": "2.0.1-preview.1", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json index ff227eecbc5..b218ccb4e92 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json @@ -5,6 +5,7 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "2.0.9", "com.unity.nuget.newtonsoft-json": "2.0.1-preview.1", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json index 79dd32eebe8..b0e4eb02b1d 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json @@ -5,6 +5,7 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "2.0.11", "com.unity.nuget.newtonsoft-json": "2.0.1-preview.1", diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json index b6e6a257511..d624e57972c 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "disableProjectUpdate": true, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.22", "com.unity.ide.visualstudio": "2.0.18", "com.unity.inputsystem": "1.19.0", diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json b/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json index 161ef3def1b..b3d34ee226e 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json @@ -2,6 +2,7 @@ "enableLockFile": false, "disableProjectUpdate": true, "dependencies": { + "com.unity.external.test-protocol": "2.0.0-exp.2", "com.unity.ide.rider": "3.0.22", "com.unity.ide.visualstudio": "2.0.18", "com.unity.performance.profile-analyzer": "1.3.3", From d026e6311cd34cedb599dd018f1865cefadbaa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Carr=C3=A8re?= Date: Thu, 2 Apr 2026 19:40:17 +0000 Subject: [PATCH 22/88] docg-8474: Remove screenshots --- .../com.unity.shadergraph/Documentation~/Dropdown-Node.md | 7 +------ .../images/sg-subgraph-dropdown-node-example-2.png | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md b/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md index 673a8da0249..b3a396266f5 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md @@ -2,9 +2,7 @@ The Dropdown node is a node representation of a Dropdown property. It allows you to create a custom dropdown menu on a Subgraph node in its parent Shader Graph. You can specify the number of options that appear in the dropdown menu, and their names. -After you create a Dropdown property and add a Dropdown node to a Subgraph, the Subgraph node in any parent Shader Graph displays with a dropdown control: - -![An image of the Graph window, that displays a parent Shader Graph with a Subgraph node. The Subgraph node has a dropdown menu because the Subgraph has a Dropdown property and contains a Dropdown node.](images/sg-subgraph-dropdown-node-example.png) +After you create a Dropdown property and add a Dropdown node to a Subgraph, the Subgraph node in any parent Shader Graph displays with a dropdown control. ## Create Node menu category @@ -29,8 +27,6 @@ To add a Subgraph Dropdown node to a Subgraph: 8. (Optional) In the **Default** list, select the default Entry that you want Shader Graph to select on your property. -![An image of the Graph window, that displays a Dropdown node in the Graph Editor. The Dropdown property is selected in the Blackboard and the Graph Inspector shows the available options for configuring the Dropdown property.](images/sg-subgraph-dropdown-node.png) - ## Ports > [!NOTE] @@ -51,7 +47,6 @@ In the following example, a Subgraph Dropdown node changes the UV channel it sen ![An image of the Graph window. The first input port on a Subgraph Dropdown node connects to a UV node and receives UV0. The second input port connects to a UV node and receives UV1. The Subgraph Dropdown node sends its output to the Subgraph's Output node.](images/sg-subgraph-dropdown-node-example-2.png) - ## Related nodes diff --git a/Packages/com.unity.shadergraph/Documentation~/images/sg-subgraph-dropdown-node-example-2.png b/Packages/com.unity.shadergraph/Documentation~/images/sg-subgraph-dropdown-node-example-2.png index 27394e14280..c928ce4bab9 100644 --- a/Packages/com.unity.shadergraph/Documentation~/images/sg-subgraph-dropdown-node-example-2.png +++ b/Packages/com.unity.shadergraph/Documentation~/images/sg-subgraph-dropdown-node-example-2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:18252904d309889384190ba6c9ce4b5ebca2d96a37f73471bf25eccb65346ed0 -size 61729 +oid sha256:f6048f062eb2ccb61aef3bb6009c4685cd46b39eb7dd04653fb1deaa776849bc +size 64166 From 50579ab002d072986845ca5707c350baa736d2fa Mon Sep 17 00:00:00 2001 From: Thomas Zeng Date: Fri, 3 Apr 2026 12:45:11 +0000 Subject: [PATCH 23/88] Added SubpassDepth support to URP shaders and RenderObjects feature --- .../RenderGraph/Compiler/PassesData.cs | 96 +++++++++- .../RenderGraph.ExceptionMessages.cs | 14 +- .../Runtime/RenderGraph/RenderGraph.cs | 2 +- .../RenderGraph/RenderGraphBuilders.cs | 50 ++++-- .../RenderObjectsPassFeatureEditor.cs | 79 ++++++++- .../Editor/ShaderBuildPreprocessor.cs | 15 ++ .../ShaderGraph/Nodes/FetchSceneDepthNode.cs | 165 ++++++++++++++++++ .../Nodes/FetchSceneDepthNode.cs.meta | 2 + .../ShaderGraph/Targets/UniversalTarget.cs | 1 + .../Templates/SharedCode.template.hlsl | 1 + .../Editor/ShaderScriptableStripper.cs | 21 +++ ...rainSurfaceDescriptionInputs.template.hlsl | 1 + .../Runtime/Passes/RenderObjectsPass.cs | 64 ++++++- .../Runtime/RendererFeatures/RenderObjects.cs | 10 ++ .../Runtime/UniversalRenderPipelineCore.cs | 11 ++ .../ShaderLibrary/DeclareDepthTexture.hlsl | 19 ++ .../ShaderLibrary/ShaderGraphFunctions.hlsl | 20 +++ .../Editor/ShaderBuildPreprocessorTests.cs | 21 +++ .../Data/Graphs/ScreenPositionMaterialSlot.cs | 6 +- .../Data/Graphs/ShaderGraphRequirements.cs | 17 ++ .../Interfaces/IMayRequireScreenPosition.cs | 11 ++ .../Editor/Data/Nodes/AbstractMaterialNode.cs | 5 + .../Editor/Data/Nodes/CodeFunctionNode.cs | 3 + .../Editor/Data/Nodes/Utility/SubGraphNode.cs | 12 +- .../Editor/Data/Util/ScreenSpaceType.cs | 10 +- .../Generation/Processors/GenerationUtils.cs | 14 +- .../Processors/ShaderGeneratorNames.cs | 1 + .../TargetResources/FieldDependencies.cs | 1 + .../TargetResources/StructFields.cs | 4 + .../Generation/TargetResources/Structs.cs | 2 + .../Templates/SharedCode.template.hlsl | 1 + ...uildSurfaceDescriptionInputs.template.hlsl | 1 + ...BuildVertexDescriptionInputs.template.hlsl | 1 + .../Editor/Importers/ShaderGraphImporter.cs | 1 + .../Importers/ShaderSubGraphImporter.cs | 4 + .../URPAssets/DefaultURPAsset.asset | 15 +- ...365_RenderObject_DepthInputAttachment.meta | 8 + ...65_RenderObject_DepthInputAttachment.unity | 3 + ...nderObject_DepthInputAttachment.unity.meta | 7 + .../CustomFetchDepth.shader | 82 +++++++++ .../CustomFetchDepth.shader.meta | 9 + .../Custom_FetchDepth.mat | 137 +++++++++++++++ .../Custom_FetchDepth.mat.meta | 8 + .../FetchDepth.shadergraph | 3 + .../FetchDepth.shadergraph.meta | 20 +++ .../RenderObject_DepthInputAttachment.asset | 100 +++++++++++ ...nderObject_DepthInputAttachment.asset.meta | 8 + .../SG_FetchDepth.mat | 138 +++++++++++++++ .../SG_FetchDepth.mat.meta | 8 + .../ProjectSettings/EditorBuildSettings.asset | 6 +- 50 files changed, 1190 insertions(+), 48 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs index dcd5e27dc3e..9702e4920fd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs @@ -741,6 +741,15 @@ public NativePassData(ref PassData pass, CompilerContextData ctx) primitiveShadingRateCombiner = pass.primitiveShadingRateCombiner; fragmentShadingRateCombiner = pass.fragmentShadingRateCombiner; + // Depth input attachment needs special handling if the native pass doesn't have depth but has depth input attachment + // Backend require depth input attachment to be set as depth attachment. + // Jira work tracking the depth input attachment only use case investigation (not set as depth attachment): https://jira.unity3d.com/projects/GXR/issues/GXR-214 + bool fragmentInfoHasDepthInputAttachment = extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment) && pass.numFragmentInputs > 0; + if (!hasDepth && fragmentInfoHasDepthInputAttachment) + { + AddDepthAttachmentFromDepthInputAttachment(ctx, ctx.fragmentData[pass.firstFragmentInput]); + } + // Graph pass is added as the first native subpass TryMergeNativeSubPass(ctx, ref this, ref pass); } @@ -1242,7 +1251,7 @@ static bool CanMergeNativeSubPass(CompilerContextData contextData, ref NativePas } // Check if depth is used as input attachment - if (passToMerge.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment) && nativePass.hasDepth) + if (passToMerge.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment)) { // Depth input attachments are read-only flags = SubPassFlags.ReadOnlyDepth; @@ -1367,7 +1376,7 @@ public static void TryMergeNativeSubPass(CompilerContextData contextData, ref Na } // Check if depth is used as input attachment - if (passToMerge.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment) && nativePass.hasDepth) + if (passToMerge.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment)) { // Depth input attachments are read-only desc.flags = SubPassFlags.ReadOnlyDepth; @@ -1400,6 +1409,80 @@ public static void TryMergeNativeSubPass(CompilerContextData contextData, ref Na passToMerge.nativeSubPassIndex = nativePass.numNativeSubPasses - 1; } + // Setup depth input attachment as depth attachment for the native pass + void AddDepthAttachmentFromDepthInputAttachment(CompilerContextData contextData, in PassFragmentData depthInputAttachment) + { + // If there is already depth. No need to setup depth. + Debug.Assert(!hasDepth); + + // Try find the input attachment in native pass fragments list. + int depthInputAttachmentIdx = -1; + for (int fragmentId = 0; fragmentId < fragments.size; ++fragmentId) + { + if (PassFragmentData.SameSubResource(fragments[fragmentId], depthInputAttachment)) + { + depthInputAttachmentIdx = fragmentId; + break; + } + } + + // Rare case, depth input attachment is the first attachment but it is not used as depth attachment. + if (depthInputAttachmentIdx == 0) + { + // Set it as depth attachment. We are done. + hasDepth = true; + return; + } + // attachment is not added to native fragments list yet + else if(depthInputAttachmentIdx == -1) + { + // Add it to attachment list and. + fragments.Add(depthInputAttachment); + + // If depth is the only attachment of the native pass, set it as depth attachment. We are done + if (fragments.size == 1) + { + hasDepth = true; + return; + } + // In this case, we are adding depth input attachment to a native pass with other existing attachments + depthInputAttachmentIdx = fragments.size - 1; + } + + // Place the depth input attachment as the first attachment and set it as depth attachment. + (fragments[0], fragments[depthInputAttachmentIdx]) = (fragments[depthInputAttachmentIdx], fragments[0]); + hasDepth = true; + + // Update previous subpasses descriptor + for (var nativeSubPassIndex = firstNativeSubPass; nativeSubPassIndex < firstNativeSubPass + numNativeSubPasses; nativeSubPassIndex++) + { + ref var subPassDesc = ref contextData.nativeSubPassData.ElementAt(nativeSubPassIndex); + + // Updating subpass color outputs + for (int i = 0; i < subPassDesc.colorOutputs.Length; i++) + { + if (subPassDesc.colorOutputs[i] == 0) + { + subPassDesc.colorOutputs[i] = depthInputAttachmentIdx; + } + } + + // Updating subpass color inputs (framebuffer fetch) + for (int i = 0; i < subPassDesc.inputs.Length; i++) + { + if (subPassDesc.inputs[i] == 0) + { + subPassDesc.inputs[i] = depthInputAttachmentIdx; + } + } + } + + if (hasShadingRateImage && shadingRateImageIndex == 0) + { + shadingRateImageIndex = depthInputAttachmentIdx; + } + } + // Call this function while merging a graph pass and you need to add the depth attachment used by this graph pass // Make sure to call it before adding the rest of the graph pass attachments and its generated subpass void AddDepthAttachmentFirstDuringMerge(CompilerContextData contextData, in PassFragmentData depthAttachment) @@ -1492,6 +1575,15 @@ public static PassBreakAudit TryMerge(CompilerContextData contextData, int activ nativePass.AddDepthAttachmentFirstDuringMerge(contextData, contextData.fragmentData[passToMerge.firstFragment]); } + // Depth input attachment needs special handling if the native pass doesn't have depth and merges with a graph pass that has depth input attachment + // Backend require depth input attachment to be set as depth attachment. + // Jira work tracking the depth input attachment only use case investigation (not set as depth attachment): https://jira.unity3d.com/projects/GXR/issues/GXR-214 + bool fragmentInfoHasDepthInputAttachment = passToMerge.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment) && passToMerge.numFragmentInputs > 0; + if (!nativePass.hasDepth && fragmentInfoHasDepthInputAttachment) + { + nativePass.AddDepthAttachmentFromDepthInputAttachment(contextData, contextData.fragmentData[passToMerge.firstFragmentInput]); + } + // Update versions and flags of existing attachments and // add any new attachments foreach (ref readonly var newAttach in passToMerge.Fragments(contextData)) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs index e3a5449b384..3846a80e08d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs @@ -134,8 +134,18 @@ internal static string DepthInputAttachmentNotSupported(string passName) => internal static string DepthInputAttachmentWithWriteAccess(string passName) => $"In pass '{passName}' - " + - $"Depth attachment has Write access but ExtendedFeatureFlags.DepthAttachmentAsInputAttachment is set. " + - $"Depth input attachments must be read-only. Remove write access from the depth attachment."; + $"Depth attachment has Write access but ExtendedFeatureFlags.DepthAttachmentAsInputAttachment is set." + + $"Depth input attachment must be read-only. Remove write access from the depth attachment."; + + internal static string DepthInputAttachmentWithInvalidIndex(string passName) => + $"In pass '{passName}' - " + + $"Depth attachment must be set to index 0 when ExtendedFeatureFlags.DepthAttachmentAsInputAttachment is set."; + + internal static string DepthInputAttachmentWithColorFormat(string passName) => + $"In pass '{passName}' - " + + $"Color attachment is set to index 0 but ExtendedFeatureFlags.DepthAttachmentAsInputAttachment is set. " + + $"Index 0 is reserved for the depth when the flag is set. Remove the extended feature flag or set a depth attachment"; + // RenderGraphPass internal const string k_MoreThanOneResourceForMRTIndex = diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs index 9cedff3d8fa..8c13e6d56df 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs @@ -63,7 +63,7 @@ public enum ExtendedFeatureFlags ///On Meta XR, this flag can be set to use MSAA shader resolve in the last subpass of a render pass. MultisampledShaderResolve = 1 << 2, /// - /// Indicates this pass uses depth texture as input attachment (framebuffer fetch with depth). + /// Indicates this pass uses depth texture as both input attachment(framebuffer fetch) and depth attachment. /// Required before calling SetInputAttachment() with a depth texture. /// DepthAttachmentAsInputAttachment = 1 << 3, diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs index 86ae8377c15..9bbb3af7864 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs @@ -76,27 +76,41 @@ public void Setup(RenderGraphPass renderPass, RenderGraphResourceRegistry resour } [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] - private void CheckDepthInputAttachmentFlagEnabled() + private void CheckInputAttachment(int index, bool isDepth) { if (RenderGraph.enableValidityChecks) { - if (!m_RenderPass.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment)) + if (isDepth) { - throw new InvalidOperationException( - RenderGraphExceptionMessages.DepthInputAttachmentNotEnabled(m_RenderPass.name)); - } - } - } + // Check ExtendedFeatureFlags + if (!m_RenderPass.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment)) + { + throw new InvalidOperationException( + RenderGraphExceptionMessages.DepthInputAttachmentNotEnabled(m_RenderPass.name)); + } - [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] - private void CheckDepthInputAttachmentSupported() - { - if (RenderGraph.enableValidityChecks) - { - if (!SystemInfo.supportsDepthAttachmentAsInputAttachment) + // Check Systeminfo + if (!SystemInfo.supportsDepthAttachmentAsInputAttachment) + { + throw new InvalidOperationException( + RenderGraphExceptionMessages.DepthInputAttachmentNotSupported(m_RenderPass.name)); + } + + // Check Index. + if (index != 0) + { + throw new InvalidOperationException( + RenderGraphExceptionMessages.DepthInputAttachmentWithInvalidIndex(m_RenderPass.name)); + } + } + else { - throw new InvalidOperationException( - RenderGraphExceptionMessages.DepthInputAttachmentNotSupported(m_RenderPass.name)); + // Check invalid input attachment use case for color + if (m_RenderPass.extendedFeatureFlags.HasFlag(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment) && index == 0) + { + throw new InvalidOperationException( + RenderGraphExceptionMessages.DepthInputAttachmentWithColorFormat(m_RenderPass.name)); + } } } } @@ -556,17 +570,15 @@ public void SetInputAttachment(TextureHandle tex, int index, AccessFlags flags, CheckFrameBufferFetchEmulationIsSupported(tex); - // Check if this is a depth texture - requires DepthAttachmentAsInputAttachment feature flag m_Resources.GetRenderTargetInfo(tex.handle, out var info); if (GraphicsFormatUtility.IsDepthFormat(info.format)) { - CheckDepthInputAttachmentFlagEnabled(); - CheckDepthInputAttachmentSupported(); + CheckInputAttachment(index, true); CheckUseFragment(tex, true); } else { - // Note: Regular color input attachments don't require extended feature flags - supported everywhere + CheckInputAttachment(index, false); CheckUseFragment(tex, false); } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/RenderObjectsPassFeatureEditor.cs b/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/RenderObjectsPassFeatureEditor.cs index 5b2861bfa4b..95bc0b496d6 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/RenderObjectsPassFeatureEditor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/RenderObjectsPassFeatureEditor.cs @@ -52,6 +52,7 @@ internal class Styles public static GUIContent overrideDepth = new GUIContent("Depth", "Select this option to specify how this Renderer Feature affects or uses the values in the Depth buffer."); public static GUIContent writeDepth = new GUIContent("Write Depth", "Choose to write depth to the screen."); public static GUIContent depthState = new GUIContent("Depth Test", "Choose a new depth test function."); + public static GUIContent depthInputAttachment = new GUIContent("Set As Input Attachment", "Enable depth input attachment for efficient tile-based depth reading (DX12/Vulkan only). Depth will be read-only."); //Camera Settings public static GUIContent overrideCamera = new GUIContent("Camera", "Override camera matrices. Toggling this setting will make camera use perspective projection."); @@ -86,6 +87,7 @@ internal class Styles private SerializedProperty m_OverrideDepth; private SerializedProperty m_WriteDepth; private SerializedProperty m_DepthState; + private SerializedProperty m_DepthInputAttachment; //Stencil props private SerializedProperty m_StencilSettings; //Caemra props @@ -140,6 +142,7 @@ private void Init(SerializedProperty property) m_OverrideDepth = property.FindPropertyRelative("overrideDepthState"); m_WriteDepth = property.FindPropertyRelative("enableWrite"); m_DepthState = property.FindPropertyRelative("depthCompareFunction"); + m_DepthInputAttachment = property.FindPropertyRelative("depthInputAttachment"); //Stencil m_StencilSettings = property.FindPropertyRelative("stencilSettings"); @@ -179,6 +182,20 @@ public override void OnGUI(Rect rect, SerializedProperty property, GUIContent la m_Callback.intValue = selectedValue; rect.y += Styles.defaultLineSpace; + // Validate Event is compatible with Depth Input Attachment + // Depth is only available after opaque rendering + if (m_OverrideDepth.boolValue && m_DepthInputAttachment.boolValue) + { + // AfterRenderingOpaques = 250 + if (m_Callback.intValue < (int)RenderPassEvent.AfterRenderingOpaques) + { + Rect helpBoxRect = rect; + helpBoxRect.height = EditorGUIUtility.singleLineHeight * 2; + EditorGUI.HelpBox(helpBoxRect, "Depth Input Attachment requires Event to be set to 'AfterRenderingOpaques' or later. Depth is only available after the opaque pass.", MessageType.Error); + rect.y += helpBoxRect.height + EditorGUIUtility.standardVerticalSpacing; + } + } + DoFilters(ref rect); m_RenderFoldout.value = EditorGUI.Foldout(rect, m_RenderFoldout.value, Styles.renderHeader, true); @@ -194,8 +211,12 @@ public override void OnGUI(Rect rect, SerializedProperty property, GUIContent la DoDepthOverride(ref rect); rect.y += Styles.defaultLineSpace; //Override stencil - EditorGUI.PropertyField(rect, m_StencilSettings); - rect.y += EditorGUI.GetPropertyHeight(m_StencilSettings); + //Hide override stencil checkbox when depth input attachment is enabled. + if (!m_DepthInputAttachment.boolValue) + { + EditorGUI.PropertyField(rect, m_StencilSettings); + rect.y += EditorGUI.GetPropertyHeight(m_StencilSettings); + } //Override camera DoCameraOverride(ref rect); rect.y += Styles.defaultLineSpace; @@ -276,10 +297,27 @@ void DoDepthOverride(ref Rect rect) { rect.y += Styles.defaultLineSpace; EditorGUI.indentLevel++; - //Write depth - EditorGUI.PropertyField(rect, m_WriteDepth, Styles.writeDepth); + + // Add depth input attachment checkbox first (nested under Override Depth) + EditorGUI.PropertyField(rect, m_DepthInputAttachment, Styles.depthInputAttachment); rect.y += Styles.defaultLineSpace; - //Depth testing options + + // Show help box when enabled + if (m_DepthInputAttachment.boolValue) + { + Rect helpBoxRect = EditorGUI.IndentedRect(rect); + helpBoxRect.height = EditorGUIUtility.singleLineHeight * 2; + EditorGUI.HelpBox(helpBoxRect, "Depth Input Attachment will ignore Depth and Stencil overrides.", MessageType.Info); + rect.y += helpBoxRect.height + EditorGUIUtility.standardVerticalSpacing; + } + + // Hide write depth checkbox when depth input attachment is enabled. + if (!m_DepthInputAttachment.boolValue) + { + EditorGUI.PropertyField(rect, m_WriteDepth, Styles.writeDepth); + rect.y += Styles.defaultLineSpace; + } + EditorGUI.PropertyField(rect, m_DepthState, Styles.depthState); EditorGUI.indentLevel--; } @@ -318,12 +356,37 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent height += Styles.defaultLineSpace * (m_FiltersFoldout.value ? m_FilterLines : 1); height += m_FiltersFoldout.value ? EditorGUI.GetPropertyHeight(m_ShaderPasses) : 0; - height += Styles.defaultLineSpace; // add line for overrides dropdown + height += Styles.defaultLineSpace; // add line for Event dropdown + + // Add height for Event validation error when Input Attachment is enabled with incompatible Event + if (m_OverrideDepth.boolValue && m_DepthInputAttachment.boolValue) + { + if (m_Callback.intValue < (int)RenderPassEvent.AfterRenderingOpaques) + { + height += (EditorGUIUtility.singleLineHeight * 2) + EditorGUIUtility.standardVerticalSpacing; + } + } + if (m_RenderFoldout.value) { height += Styles.defaultLineSpace * m_MaterialLines; - height += Styles.defaultLineSpace * (m_OverrideDepth.boolValue ? m_DepthLines : 1); - height += EditorGUI.GetPropertyHeight(m_StencilSettings); + + int depthLines = 1; + if (m_OverrideDepth.boolValue) + { + depthLines = m_DepthLines; + if (m_DepthInputAttachment.boolValue) + { + // Add help box height (2 line + spacing) + height += (EditorGUIUtility.singleLineHeight) * 2 + EditorGUIUtility.standardVerticalSpacing; + // Write depth is hidden + depthLines = depthLines - 1; + } + } + height += Styles.defaultLineSpace * (m_OverrideDepth.boolValue ? depthLines : 1); + if (!m_DepthInputAttachment.boolValue) + height += EditorGUI.GetPropertyHeight(m_StencilSettings); + height += Styles.defaultLineSpace * (m_OverrideCamera.boolValue ? m_CameraLines : 1); } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs index 88cf82b3eb4..cf15167d986 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs @@ -79,6 +79,7 @@ enum ShaderFeatures : long #if URP_SCREEN_SPACE_REFLECTION ScreenSpaceReflection = (1L << 54), #endif + RenderObjectDepthInputAttachment = (1L << 55), All = ~0 } @@ -932,6 +933,20 @@ internal static ShaderFeatures GetSupportedShaderFeaturesFromRendererFeatures(re if (decal.requiresDecalLayers) shaderFeatures |= ShaderFeatures.DecalLayers; } + + // Render Object Feature + RenderObjects renderObject = rendererFeature as RenderObjects; + if (renderObject != null && rendererRequirements.isUniversalRenderer) + { + // We don't add disabled renderer features if "Strip Unused Variants" is enabled. + if (!renderObject.isActive) + continue; + + RenderObjects.RenderObjectsSettings renderObjectSettings = renderObject.settings; + + if (renderObjectSettings.depthInputAttachment) + shaderFeatures |= ShaderFeatures.RenderObjectDepthInputAttachment; + } } // If using rendering layers, enable the appropriate feature diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs new file mode 100644 index 00000000000..a2f8913b11c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs @@ -0,0 +1,165 @@ +using System.Reflection; +using UnityEngine; +using UnityEditor.Graphing; +using UnityEditor.ShaderGraph.Drawing.Controls; +using UnityEditor.Rendering; +using UnityEngine.Rendering.Universal; +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph +{ + /// + /// ShaderGraph node for fetching scene depth using input attachments. + /// This node reads depth directly from tile memory at the current fragment position. + /// + [SRPFilter(typeof(UniversalRenderPipeline))] + [Title("Input", "Scene", "Fetch Scene Depth")] + sealed class FetchSceneDepthNode : CodeFunctionNode, IMayRequireDepthTexture + { + const string kOutputSlotName = "Out"; + public const int OutputSlotId = 0; + + [SerializeField] + private DepthSamplingMode m_DepthSamplingMode = DepthSamplingMode.Linear01; + + [EnumControl("Sampling Mode")] + public DepthSamplingMode depthSamplingMode + { + get { return m_DepthSamplingMode; } + set + { + if (m_DepthSamplingMode == value) + return; + + m_DepthSamplingMode = value; + Dirty(ModificationScope.Graph); + } + } + + private static ShaderKeyword DepthAsInputAttachment; + + private static ShaderKeyword DepthAsInputAttachmentMSAA; + + public FetchSceneDepthNode() + { + name = "Fetch Scene Depth"; + synonyms = new string[] { "input attachment", "framebuffer fetch", "tile memory" }; + + DepthAsInputAttachment = new ShaderKeyword() + { + displayName = "Depth As Input Attachment", + keywordType = KeywordType.Enum, + keywordDefinition = KeywordDefinition.MultiCompile, + keywordScope = KeywordScope.Global, + keywordStages = KeywordShaderStage.Fragment, + entries = new List + { + new KeywordEntry() { displayName = "Off", referenceName = "" }, + new KeywordEntry() { displayName = "Depth As Input Attachment", referenceName = "DEPTH_AS_INPUT_ATTACHMENT" }, + new KeywordEntry() { displayName = "Depth As Input Attachment MSAA", referenceName = "DEPTH_AS_INPUT_ATTACHMENT_MSAA" }, + }, + }; + + UpdateNodeAfterDeserialization(); + } + + public override bool hasPreview { get { return false; } } + + public override void CollectShaderKeywords(KeywordCollector keywords, GenerationMode generationMode) + { + base.CollectShaderKeywords(keywords, generationMode); + + // Add keywords requires by this node + keywords.AddShaderKeyword(DepthAsInputAttachment); + } + + protected override MethodInfo GetFunctionToConvert() + { + switch (m_DepthSamplingMode) + { + case DepthSamplingMode.Raw: + return GetType().GetMethod("Unity_FetchSceneDepth_Raw", BindingFlags.Static | BindingFlags.NonPublic); + case DepthSamplingMode.Eye: + return GetType().GetMethod("Unity_FetchSceneDepth_Eye", BindingFlags.Static | BindingFlags.NonPublic); + case DepthSamplingMode.Linear01: + default: + return GetType().GetMethod("Unity_FetchSceneDepth_Linear01", BindingFlags.Static | BindingFlags.NonPublic); + } + } + + static string Unity_FetchSceneDepth_Linear01( + [Slot(0, Binding.ClipPosition, true, ShaderStageCapability.Fragment)] Vector4 clipPos, + [Slot(1, Binding.None, ShaderStageCapability.Fragment)] out Vector1 Out) + { + return +@" +{ + #if defined(DEPTH_AS_INPUT_ATTACHMENT) || defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + // Fetch depth from tile memory using input attachment + float rawDepth = shadergraph_LWFetchSceneDepth(clipPos.xy); + Out = Linear01Depth(rawDepth, _ZBufferParams); + #else + // There is explicitly no fallback here. + Out = 0; + #endif +} +"; + } + + static string Unity_FetchSceneDepth_Raw( + [Slot(0, Binding.ClipPosition, true, ShaderStageCapability.Fragment)] Vector4 clipPos, + [Slot(1, Binding.None, ShaderStageCapability.Fragment)] out Vector1 Out) + { + return +@" +{ + #if defined(DEPTH_AS_INPUT_ATTACHMENT) || defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + // Fetch raw depth from tile memory using input attachment + Out = shadergraph_LWFetchSceneDepth(clipPos.xy); + #else + // There is explicitly no fallback here. + Out = 0; + #endif +} +"; + } + + static string Unity_FetchSceneDepth_Eye( + [Slot(0, Binding.ClipPosition, true, ShaderStageCapability.Fragment)] Vector4 clipPos, + [Slot(1, Binding.None, ShaderStageCapability.Fragment)] out Vector1 Out) + { + return +@" +{ + #if defined(DEPTH_AS_INPUT_ATTACHMENT) || defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + // Fetch depth from tile memory using input attachment + float rawDepth = shadergraph_LWFetchSceneDepth(clipPos.xy); + { + Out = LinearEyeDepth(rawDepth, _ZBufferParams); + } + #else + { + // There is explicitly no fallback here. + Out = 0; + } + #endif +} +"; + } + + public bool RequiresDepthTexture(ShaderStageCapability stageCapability) + { + return true; + } + + public override void ValidateNode() + { + base.ValidateNode(); + + owner.AddValidationError(objectId, + "Fetch Scene Depth uses input attachments to read depth directly from tile memory. " + + "For texture-based depth sampling, use 'Sample Scene Depth' node instead.", + Rendering.ShaderCompilerMessageSeverity.Warning); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs.meta new file mode 100644 index 00000000000..c74dde91967 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 383388eb8e7f51946878082841068a3e \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs index 86b25f5d134..941d3a1464e 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs @@ -1722,6 +1722,7 @@ static class CorePragmas public static readonly PragmaCollection Forward = new PragmaCollection { { Pragma.Target(ShaderModel.Target20) }, + { Pragma.TargetForKeyword(ShaderModel.Target45, ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT_MSAA) }, { Pragma.MultiCompileInstancing }, { Pragma.InstancingOptions(InstancingOptions.RenderingLayer) }, { Pragma.Vertex("vert") }, diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Templates/SharedCode.template.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Templates/SharedCode.template.hlsl index 3c17b8e9333..fb43aa0f767 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Templates/SharedCode.template.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Templates/SharedCode.template.hlsl @@ -66,6 +66,7 @@ SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input) $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition = output.PixelPosition.xy / _ScaledScreenParams.xy; $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition.y = 1.0f - output.NDCPosition.y; + $SurfaceDescriptionInputs.ClipPosition: output.ClipPosition = input.positionCS.xy; $SurfaceDescriptionInputs.uv0: output.uv0 = input.texCoord0; $SurfaceDescriptionInputs.uv1: output.uv1 = input.texCoord1; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs index 387aefc1931..4f396807bd4 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs @@ -199,6 +199,8 @@ public bool PassHasKeyword(LocalKeyword keyword) LocalKeyword m_Instancing; LocalKeyword m_DotsInstancing; LocalKeyword m_ProceduralInstancing; + LocalKeyword m_DepthAsInputAttachment; + LocalKeyword m_DepthAsInputAttachmentMSAA; private LocalKeyword TryGetLocalKeyword(Shader shader, string name) { @@ -251,6 +253,8 @@ private void InitializeLocalShaderKeywords([DisallowNull] Shader shader) m_EditorVisualization = TryGetLocalKeyword(shader, ShaderKeywordStrings.EDITOR_VISUALIZATION); m_LODFadeCrossFade = TryGetLocalKeyword(shader, ShaderKeywordStrings.LOD_FADE_CROSSFADE); m_LightCookies = TryGetLocalKeyword(shader, ShaderKeywordStrings.LightCookies); + m_DepthAsInputAttachment = TryGetLocalKeyword(shader, ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT); + m_DepthAsInputAttachmentMSAA = TryGetLocalKeyword(shader, ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT_MSAA); m_ScreenCoordOverride = TryGetLocalKeyword(shader, ShaderKeywordStrings.SCREEN_COORD_OVERRIDE); m_LightmapBicubicSampling = TryGetLocalKeyword(shader, ShaderKeywordStrings.LIGHTMAP_BICUBIC_SAMPLING); @@ -830,6 +834,20 @@ internal bool StripUnusedFeatures_XRMotionVector(ref IShaderScriptableStrippingD return strippingData.stripUnusedXRVariants; } + internal bool StripUnusedFeatures_RenderObjectDepthInputAttachment(ref IShaderScriptableStrippingData strippingData) + { + if (!strippingData.IsShaderFeatureEnabled(ShaderFeatures.RenderObjectDepthInputAttachment)) + { + if (strippingData.IsKeywordEnabled(m_DepthAsInputAttachment)) + return true; + + if (strippingData.IsKeywordEnabled(m_DepthAsInputAttachmentMSAA)) + return true; + } + + return false; + } + internal bool StripUnusedFeatures_CrossFadeLod(ref IShaderScriptableStrippingData strippingData) { if (!strippingData.IsKeywordEnabled(m_LODFadeCrossFade)) @@ -961,6 +979,9 @@ internal bool StripUnusedFeatures(ref IShaderScriptableStrippingData strippingDa if (StripUnusedFeatures_XRMotionVector(ref strippingData)) return true; + if (StripUnusedFeatures_RenderObjectDepthInputAttachment(ref strippingData)) + return true; + return false; } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Terrain/BuildTerrainSurfaceDescriptionInputs.template.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/Terrain/BuildTerrainSurfaceDescriptionInputs.template.hlsl index 8b1e92177a7..403fc786a45 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Terrain/BuildTerrainSurfaceDescriptionInputs.template.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/Terrain/BuildTerrainSurfaceDescriptionInputs.template.hlsl @@ -55,6 +55,7 @@ SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input) $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition = output.PixelPosition.xy / _ScreenParams.xy; $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition.y = 1.0f - output.NDCPosition.y; + $SurfaceDescriptionInputs.ClipPosition: output.ClipPosition = input.positionCS.xy; $SurfaceDescriptionInputs.uv0: output.uv0 = input.texCoord0; $SurfaceDescriptionInputs.uv1: output.uv1 = input.texCoord1; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/RenderObjectsPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/RenderObjectsPass.cs index 48728e66ec3..029f728281f 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/RenderObjectsPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/RenderObjectsPass.cs @@ -38,6 +38,13 @@ public partial class RenderObjectsPass : ScriptableRenderPass List m_ShaderTagIdList = new List(); private PassData m_PassData; + /// + /// Indicates whether this pass should use depth as input attachment. + /// When enabled, depth is read from tile memory instead of texture sampling (DX12, Vulkan only). + /// Requires depth to be read-only (no depth writes). + /// + private bool m_DepthInputAttachment; + /// /// Sets the write and comparison function for depth. /// @@ -60,6 +67,18 @@ public void SetDepthState(bool writeEnabled, CompareFunction function = CompareF m_RenderStateBlock.depthState = new DepthState(writeEnabled, function); } + /// + /// Sets whether this pass should use depth as input attachment. + /// This enables subpass depth reading on supported platforms (DX12, Vulkan). + /// When enabled, depth will be set as read-only in the RenderGraph. + /// + /// True to enable depth input attachment + internal void SetDepthInputAttachment(bool enable) + { + // The shader stripping relies on knowing about the feature, not the pass. So this can't correctly work if the pass is not added by the RenderObject feature. + m_DepthInputAttachment = enable; + } + /// /// Sets up the stencil settings for the pass. /// @@ -187,6 +206,8 @@ private class PassData // Required for code sharing purpose between RG and non-RG. internal RendererList rendererList; + + internal bool depthInputAttachment; } private void InitPassData(UniversalCameraData cameraData, ref PassData passData) @@ -237,9 +258,20 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.color = resourceData.activeColorTexture; builder.SetRenderAttachment(resourceData.activeColorTexture, 0, AccessFlags.Write); - // TODO: Take into account user-specific settings to decide depth flag - if (cameraData.imageScalingMode != ImageScalingMode.Upscaling || passData.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing) + + // Configure depth attachment based on input attachment setting + if (m_DepthInputAttachment && SystemInfo.supportsDepthAttachmentAsInputAttachment) + { + // Input attachment mode: depth is read-only, accessed from tile memory + builder.SetExtendedFeatureFlags(ExtendedFeatureFlags.DepthAttachmentAsInputAttachment); + builder.SetInputAttachment(resourceData.activeDepthTexture, 0, AccessFlags.Read); + passData.depthInputAttachment = true; + } + else if (cameraData.imageScalingMode != ImageScalingMode.Upscaling || passData.renderPassEvent != RenderPassEvent.AfterRenderingPostProcessing) + { builder.SetRenderAttachmentDepth(resourceData.activeDepthTexture, AccessFlags.ReadWrite); + passData.depthInputAttachment = false; + } TextureHandle mainShadowsTexture = resourceData.mainShadowsTexture; TextureHandle additionalShadowsTexture = resourceData.additionalShadowsTexture; @@ -287,9 +319,35 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.SetRenderFunc(static (PassData data, RasterGraphContext rgContext) => { var isYFlipped = RenderingUtils.IsHandleYFlipped(rgContext, in data.color); + + // Set shader keywords for depth input attachment + if (data.depthInputAttachment) + { + switch (data.cameraData.cameraTargetDescriptor.msaaSamples) + { + case 8: + case 4: + case 2: + rgContext.cmd.SetKeyword(ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT, false); + rgContext.cmd.SetKeyword(ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT_MSAA, true); + break; + // MSAA disabled + default: + rgContext.cmd.SetKeyword(ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT, true); + rgContext.cmd.SetKeyword(ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT_MSAA, false); + break; + } + } + else + { + // Ensure keywords are disabled + rgContext.cmd.SetKeyword(ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT, false); + rgContext.cmd.SetKeyword(ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT_MSAA, false); + } + ExecutePass(data, rgContext.cmd, data.rendererListHdl, isYFlipped); }); } } } -} \ No newline at end of file +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/RenderObjects.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/RenderObjects.cs index 31e8f07f545..41c4b085f9f 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/RenderObjects.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/RenderObjects.cs @@ -119,6 +119,12 @@ public enum OverrideMaterialMode /// The camera settings to use. /// public CustomCameraSettings cameraSettings = new CustomCameraSettings(); + + /// + /// Enable depth input attachment for efficient tile-based depth reading. + /// Only valid when is true. + /// + public bool depthInputAttachment = false; } /// @@ -237,6 +243,10 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD if (renderingData.cameraData.cameraType == CameraType.Preview || UniversalRenderer.IsOffscreenDepthTexture(ref renderingData.cameraData)) return; + + bool enableDepthInputAttachment = settings.depthInputAttachment; + renderObjectsPass.SetDepthInputAttachment(enableDepthInputAttachment); + renderer.EnqueuePass(renderObjectsPass); } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 8637f9634d0..700457aaffa 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -995,6 +995,9 @@ internal static class ShaderGlobalKeywords public static GlobalKeyword META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP; #endif public static GlobalKeyword APPLICATION_SPACE_WARP_MOTION_TRANSPARENT; + public static GlobalKeyword DEPTH_AS_INPUT_ATTACHMENT; + public static GlobalKeyword DEPTH_AS_INPUT_ATTACHMENT_MSAA; + // TODO: Move following keywords to Local keywords? // https://docs.unity3d.com/ScriptReference/Rendering.LocalKeyword.html //public static GlobalKeyword TonemapACES; @@ -1116,6 +1119,8 @@ public static void InitializeShaderGlobalKeywords() ShaderGlobalKeywords.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP); #endif ShaderGlobalKeywords.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT = GlobalKeyword.Create(ShaderKeywordStrings.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT); + ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT = GlobalKeyword.Create(ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT); + ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT_MSAA = GlobalKeyword.Create(ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT_MSAA); } } @@ -1473,6 +1478,12 @@ public static class ShaderKeywordStrings /// Keyword used for Multi Sampling Anti-Aliasing (MSAA) with 4 per pixel sample count. public const string Msaa4 = "_MSAA_4"; + + /// Keyword used for depth as input attachment. + public const string DEPTH_AS_INPUT_ATTACHMENT = "DEPTH_AS_INPUT_ATTACHMENT"; + + /// Keyword used for depth as input attachment MSAA. + public const string DEPTH_AS_INPUT_ATTACHMENT_MSAA = "DEPTH_AS_INPUT_ATTACHMENT_MSAA"; } public sealed partial class UniversalRenderPipeline diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl index 695f6f00a47..3b0746c5cff 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl @@ -9,6 +9,25 @@ float4 _CameraDepthTexture_TexelSize; // 2023.3 Deprecated. This is for backwards compatibility. Remove in the future. #define sampler_CameraDepthTexture sampler_PointClamp +// Framebuffer fetch API for depth input attachment +#if defined(DEPTH_AS_INPUT_ATTACHMENT) + FRAMEBUFFER_INPUT_X_FLOAT(0); + + float FetchSceneDepth(float2 fragCoord) + { + float depth = LOAD_FRAMEBUFFER_INPUT_X(0, fragCoord).r; + return depth; + } +#elif defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + FRAMEBUFFER_INPUT_X_FLOAT_MS(0); + + float FetchSceneDepth(float2 fragCoord, int sampleIndx) + { + float depth = LOAD_FRAMEBUFFER_INPUT_X_MS(0, sampleIndx, fragCoord).r; + return depth; + } +#endif + float SampleSceneDepth(float2 uv) { uv = ClampAndScaleUVForBilinear(UnityStereoTransformScreenSpaceTex(uv), _CameraDepthTexture_TexelSize.xy); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl index aa1e314bd5f..bfe78fe13d4 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl @@ -35,6 +35,26 @@ float shadergraph_LWSampleSceneDepth(float2 uv) #endif } +#if defined(DEPTH_AS_INPUT_ATTACHMENT) + float shadergraph_LWFetchSceneDepth(float2 fragCoord) + { + #if defined(REQUIRE_DEPTH_TEXTURE) + return FetchSceneDepth(fragCoord); + #else + return 0; + #endif + } +#elif defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + float shadergraph_LWFetchSceneDepth(float2 fragCoord) + { + #if defined(REQUIRE_DEPTH_TEXTURE) + return FetchSceneDepth(fragCoord, 0); + #else + return 0; + #endif + } +#endif + float3 shadergraph_LWSampleSceneColor(float2 uv) { #if defined(REQUIRE_OPAQUE_TEXTURE) diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs index a982f5e86af..28ec988257d 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs @@ -1257,5 +1257,26 @@ public void TestGetSupportedShaderFeaturesFromRendererFeatures_Decals() expected = ShaderFeatures.DecalGBuffer | ShaderFeatures.DecalNormalBlendHigh; m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); } + + + [Test] + public void TestGetSupportedShaderFeaturesFromRendererFeatures_RenderObject() + { + RenderObjects renderObjectFeature = ScriptableObject.CreateInstance(); + renderObjectFeature.settings.depthInputAttachment = true; + m_TestHelper.rendererFeatures.Add(renderObjectFeature); + + // Initial + RendererRequirements rendererRequirements = m_TestHelper.defaultRendererRequirements; + ShaderFeatures actual = m_TestHelper.GetSupportedShaderFeaturesFromRendererFeatures(rendererRequirements); + ShaderFeatures expected = ShaderFeatures.RenderObjectDepthInputAttachment; + m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); + + m_TestHelper.rendererFeatures[0].SetActive(false); + rendererRequirements = m_TestHelper.defaultRendererRequirements; + actual = m_TestHelper.GetSupportedShaderFeaturesFromRendererFeatures(rendererRequirements); + expected = ShaderFeatures.None; + m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); + } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs index 10673d1b7d9..b1760465944 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs @@ -7,7 +7,7 @@ namespace UnityEditor.ShaderGraph { [Serializable] - class ScreenPositionMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition, IMayRequireNDCPosition, IMayRequirePixelPosition + class ScreenPositionMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition, IMayRequireNDCPosition, IMayRequirePixelPosition, IMayRequireClipPosition { [SerializeField] ScreenSpaceType m_ScreenSpaceType; @@ -52,6 +52,10 @@ public bool RequiresPixelPosition(ShaderStageCapability stageCapability) { return !isConnected && screenSpaceType.RequiresPixelPosition(); } + public bool RequiresClipPosition(ShaderStageCapability stageCapability) + { + return !isConnected && screenSpaceType.RequiresClipPosition(); + } public override void CopyValuesFrom(MaterialSlot foundSlot) { diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs index feb6713b6ae..3b4e80cbbc3 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs @@ -18,6 +18,7 @@ public struct ShaderGraphRequirements [SerializeField] bool m_RequiresScreenPosition; [SerializeField] bool m_RequiresNDCPosition; [SerializeField] bool m_RequiresPixelPosition; + [SerializeField] bool m_RequiresClipPosition; [SerializeField] bool m_RequiresVertexColor; [SerializeField] bool m_RequiresFaceSign; [SerializeField] List m_RequiresMeshUVs; @@ -103,6 +104,15 @@ public bool requiresPixelPosition internal set { m_RequiresPixelPosition = value; } } + /// + /// Indicates this shader graph requires clip space position. + /// + public bool requiresClipPosition + { + get { return m_RequiresClipPosition; } + internal set { m_RequiresClipPosition = value; } + } + public bool requiresVertexColor { get { return m_RequiresVertexColor; } @@ -190,6 +200,7 @@ internal ShaderGraphRequirements Union(ShaderGraphRequirements other) newReqs.m_RequiresScreenPosition = other.m_RequiresScreenPosition | m_RequiresScreenPosition; newReqs.m_RequiresNDCPosition = other.m_RequiresNDCPosition | m_RequiresNDCPosition; newReqs.m_RequiresPixelPosition = other.m_RequiresPixelPosition | m_RequiresPixelPosition; + newReqs.m_RequiresClipPosition = other.m_RequiresClipPosition | m_RequiresClipPosition; newReqs.m_RequiresVertexColor = other.m_RequiresVertexColor | m_RequiresVertexColor; newReqs.m_RequiresFaceSign = other.m_RequiresFaceSign | m_RequiresFaceSign; newReqs.m_RequiresDepthTexture = other.m_RequiresDepthTexture | m_RequiresDepthTexture; @@ -286,6 +297,9 @@ private static void FromSlot(MaterialSlot node, ref ShaderGraphRequirements reqs if (!reqs.m_RequiresInstanceID && node is IMayRequireInstanceID r) reqs.m_RequiresInstanceID = r.RequiresInstanceID(stageCapability); + if (!reqs.m_RequiresClipPosition && node is IMayRequireClipPosition s) + reqs.m_RequiresClipPosition = s.RequiresClipPosition(stageCapability); + if (!reqs.m_RequiresUITK && node is IMayRequireUITK w) reqs.m_RequiresUITK = w.RequiresUITK(stageCapability); } @@ -380,6 +394,9 @@ internal static ShaderGraphRequirements FromNodes(IEnumerable nodes, Shade if (!reqs.m_RequiresInstanceID && node is IMayRequireInstanceID r) reqs.m_RequiresInstanceID = r.RequiresInstanceID(stageCapability); + if (!reqs.m_RequiresClipPosition && node is IMayRequireClipPosition s) + reqs.m_RequiresClipPosition = s.RequiresClipPosition(stageCapability); + if (!reqs.m_RequiresUITK && node is IMayRequireUITK w) reqs.m_RequiresUITK = w.RequiresUITK(stageCapability); } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs b/Packages/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs index 0a2c02ebfb0..3b325bf4d6f 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireScreenPosition.cs @@ -17,6 +17,11 @@ interface IMayRequirePixelPosition bool RequiresPixelPosition(ShaderStageCapability stageCapability = ShaderStageCapability.All); } + interface IMayRequireClipPosition + { + bool RequiresClipPosition(ShaderStageCapability stageCapability = ShaderStageCapability.All); + } + static class MayRequireScreenPositionExtensions { public static bool RequiresScreenPosition(this MaterialSlot slot, ShaderStageCapability stageCapability = ShaderStageCapability.All) @@ -36,5 +41,11 @@ public static bool RequiresPixelPosition(this MaterialSlot slot, ShaderStageCapa var mayRequirePixelPosition = slot as IMayRequirePixelPosition; return mayRequirePixelPosition?.RequiresPixelPosition(stageCapability) ?? false; } + + public static bool RequiresClipPosition(this MaterialSlot slot, ShaderStageCapability stageCapability = ShaderStageCapability.All) + { + var mayRequireClipPosition = slot as IMayRequireClipPosition; + return mayRequireClipPosition?.RequiresClipPosition(stageCapability) ?? false; + } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs index 09e7ae121a9..108662d2231 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs @@ -406,6 +406,11 @@ public void GetSlots(List foundSlots) where T : MaterialSlot } } + public virtual void CollectShaderKeywords(KeywordCollector keywords, GenerationMode generationMode) + { + + } + public virtual void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode) { foreach (var inputSlot in this.GetInputSlots()) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs index eb08971407b..52b32b58151 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs @@ -108,6 +108,7 @@ protected enum Binding MeshUV6, MeshUV7, ScreenPosition, + ClipPosition, ObjectSpaceViewDirection, ViewSpaceViewDirection, WorldSpaceViewDirection, @@ -350,6 +351,8 @@ private static MaterialSlot CreateBoundSlot(Binding attributeBinding, int slotId return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.UV7, shaderStageCapability, hidden); case Binding.ScreenPosition: return new ScreenPositionMaterialSlot(slotId, displayName, shaderOutputName, ScreenSpaceType.Default, shaderStageCapability, hidden); + case Binding.ClipPosition: + return new ScreenPositionMaterialSlot(slotId, displayName, shaderOutputName, ScreenSpaceType.Clip, shaderStageCapability, hidden); case Binding.ObjectSpaceViewDirection: return new ViewDirectionMaterialSlot(slotId, displayName, shaderOutputName, CoordinateSpace.Object, shaderStageCapability, hidden); case Binding.ViewSpaceViewDirection: diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs index 28f5e7f0055..0beea6615c0 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/SubGraphNode.cs @@ -723,8 +723,10 @@ public AbstractShaderProperty GetShaderProperty(int id) return null; } - public void CollectShaderKeywords(KeywordCollector keywords, GenerationMode generationMode) + public override void CollectShaderKeywords(KeywordCollector keywords, GenerationMode generationMode) { + base.CollectShaderKeywords(keywords, generationMode); + if (asset == null) return; @@ -831,6 +833,14 @@ public bool RequiresPixelPosition(ShaderStageCapability stageCapability) return asset.requirements.requiresPixelPosition; } + public bool RequiresClipPosition(ShaderStageCapability stageCapability) + { + if (asset == null) + return false; + + return asset.requirements.requiresClipPosition; + } + public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability) { if (asset == null) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/ScreenSpaceType.cs b/Packages/com.unity.shadergraph/Editor/Data/Util/ScreenSpaceType.cs index 810a955110e..fbaa608f3da 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/ScreenSpaceType.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Util/ScreenSpaceType.cs @@ -6,7 +6,8 @@ enum ScreenSpaceType Raw, // screenpos.xyzw ==> scales on distance, requires divide by w Center, // Default, but remapped to [-1, 1] Tiled, // frac(Center) - Pixel // Default * _ScreenParams.xy; [0 .. width-1, 0.. height-1] + Pixel, // Default * _ScreenParams.xy; [0 .. width-1, 0.. height-1] + Clip // positionCS.xy }; static class ScreenSpaceTypeExtensions @@ -23,6 +24,8 @@ public static string ToValueAsVariable(this ScreenSpaceType screenSpaceType) return string.Format("frac($precision4((IN.{0}.x * 2 - 1) * _ScreenParams.x / _ScreenParams.y, IN.{0}.y * 2 - 1, 0, 0))", ShaderGeneratorNames.NDCPosition); case ScreenSpaceType.Pixel: return string.Format("$precision4(IN.{0}.xy, 0, 0)", ShaderGeneratorNames.PixelPosition); + case ScreenSpaceType.Clip: + return string.Format("$precision4(IN.{0}.xy, 0, 0)", ShaderGeneratorNames.ClipPosition); default: // ScreenSpaceType.Default (i.e. Normalized Device Coordinates) return string.Format("$precision4(IN.{0}.xy, 0, 0)", ShaderGeneratorNames.NDCPosition); } @@ -42,5 +45,10 @@ public static bool RequiresPixelPosition(this ScreenSpaceType screenSpaceType) { return (screenSpaceType == ScreenSpaceType.Pixel); } + + public static bool RequiresClipPosition(this ScreenSpaceType screenSpaceType) + { + return (screenSpaceType == ScreenSpaceType.Clip); + } } } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs index e64e1b0f20e..a15d510e9fa 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs @@ -523,6 +523,7 @@ static ConditionalField[] GetConditionalFieldsFromVertexRequirements(ShaderGraph new ConditionalField(StructFields.VertexDescriptionInputs.ScreenPosition, requirements.requiresScreenPosition), new ConditionalField(StructFields.VertexDescriptionInputs.NDCPosition, requirements.requiresNDCPosition), new ConditionalField(StructFields.VertexDescriptionInputs.PixelPosition, requirements.requiresPixelPosition), + new ConditionalField(StructFields.VertexDescriptionInputs.ClipPosition, requirements.requiresClipPosition), new ConditionalField(StructFields.VertexDescriptionInputs.VertexColor, requirements.requiresVertexColor), @@ -603,6 +604,7 @@ static ConditionalField[] GetConditionalFieldsFromPixelRequirements(ShaderGraphR new ConditionalField(StructFields.SurfaceDescriptionInputs.ScreenPosition, requirements.requiresScreenPosition), new ConditionalField(StructFields.SurfaceDescriptionInputs.NDCPosition, requirements.requiresNDCPosition), new ConditionalField(StructFields.SurfaceDescriptionInputs.PixelPosition, requirements.requiresPixelPosition), + new ConditionalField(StructFields.SurfaceDescriptionInputs.ClipPosition, requirements.requiresClipPosition), new ConditionalField(StructFields.SurfaceDescriptionInputs.VertexColor, requirements.requiresVertexColor), new ConditionalField(StructFields.SurfaceDescriptionInputs.FaceSign, requirements.requiresFaceSign), @@ -950,6 +952,9 @@ internal static void GenerateSurfaceInputStruct(ShaderStringBuilder sb, ShaderGr if (requirements.requiresPixelPosition) sb.AppendLine("float2 {0};", ShaderGeneratorNames.PixelPosition); + if (requirements.requiresClipPosition) + sb.AppendLine("float2 {0};", ShaderGeneratorNames.ClipPosition); + if (requirements.requiresFaceSign) sb.AppendLine("float {0};", ShaderGeneratorNames.FaceSign); @@ -1002,6 +1007,9 @@ internal static void GenerateSurfaceInputTransferCode(ShaderStringBuilder sb, Sh if (requirements.requiresPixelPosition) sb.AppendLine($"{variableName}.{ShaderGeneratorNames.PixelPosition} = IN.{ShaderGeneratorNames.PixelPosition};"); + if (requirements.requiresClipPosition) + sb.AppendLine($"{variableName}.{ShaderGeneratorNames.ClipPosition} = IN.{ShaderGeneratorNames.ClipPosition};"); + if (requirements.requiresFaceSign) sb.AppendLine($"{variableName}.{ShaderGeneratorNames.FaceSign} = IN.{ShaderGeneratorNames.FaceSign};"); @@ -1173,11 +1181,7 @@ static void GenerateDescriptionForNode( } activeNode.CollectShaderProperties(shaderProperties, mode); - - if (activeNode is SubGraphNode subGraphNode) - { - subGraphNode.CollectShaderKeywords(shaderKeywords, mode); - } + activeNode.CollectShaderKeywords(shaderKeywords, mode); } static void GenerateSurfaceDescriptionRemap( diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderGeneratorNames.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderGeneratorNames.cs index 0b30d25ffbc..fb906279812 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderGeneratorNames.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderGeneratorNames.cs @@ -11,6 +11,7 @@ static class ShaderGeneratorNames public const string ScreenPosition = "ScreenPosition"; public const string NDCPosition = "NDCPosition"; // normalized device coordinates, [0,1] across view, origin in lower left public const string PixelPosition = "PixelPosition"; // pixel coordinates + public const string ClipPosition = "ClipPosition"; public const string VertexColor = "VertexColor"; public const string FaceSign = "FaceSign"; public const string TimeParameters = "TimeParameters"; diff --git a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/FieldDependencies.cs b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/FieldDependencies.cs index 07908ecd449..4210d6df1ac 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/FieldDependencies.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/FieldDependencies.cs @@ -58,6 +58,7 @@ internal static class FieldDependencies new FieldDependency(StructFields.VertexDescriptionInputs.ScreenPosition, StructFields.VertexDescriptionInputs.WorldSpacePosition), new FieldDependency(StructFields.VertexDescriptionInputs.NDCPosition, StructFields.VertexDescriptionInputs.ScreenPosition), new FieldDependency(StructFields.VertexDescriptionInputs.PixelPosition, StructFields.VertexDescriptionInputs.NDCPosition), + new FieldDependency(StructFields.VertexDescriptionInputs.ClipPosition, StructFields.VertexDescriptionInputs.WorldSpacePosition), new FieldDependency(StructFields.VertexDescriptionInputs.uv0, StructFields.Attributes.uv0), new FieldDependency(StructFields.VertexDescriptionInputs.uv1, StructFields.Attributes.uv1), diff --git a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/StructFields.cs b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/StructFields.cs index 4b71dead6b8..c12f4cddfc6 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/StructFields.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/StructFields.cs @@ -160,6 +160,8 @@ public struct VertexDescriptionInputs subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor PixelPosition = new FieldDescriptor(VertexDescriptionInputs.name, "PixelPosition", "", ShaderValueType.Float2, subscriptOptions: StructFieldOptions.Optional); + public static FieldDescriptor ClipPosition = new FieldDescriptor(VertexDescriptionInputs.name, "ClipPosition", "", ShaderValueType.Float2, + subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor uv0 = new FieldDescriptor(VertexDescriptionInputs.name, "uv0", "", ShaderValueType.Float4, subscriptOptions: StructFieldOptions.Optional); @@ -262,6 +264,8 @@ public struct SurfaceDescriptionInputs subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor PixelPosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "PixelPosition", "", ShaderValueType.Float2, subscriptOptions: StructFieldOptions.Optional); + public static FieldDescriptor ClipPosition = new FieldDescriptor(SurfaceDescriptionInputs.name, "ClipPosition", "", ShaderValueType.Float2, + subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor uv0 = new FieldDescriptor(SurfaceDescriptionInputs.name, "uv0", "", ShaderValueType.Float4, subscriptOptions: StructFieldOptions.Optional); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Structs.cs b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Structs.cs index 96e89ea84d1..68012b3ef4e 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Structs.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Structs.cs @@ -69,6 +69,7 @@ internal static class Structs StructFields.VertexDescriptionInputs.ScreenPosition, StructFields.VertexDescriptionInputs.NDCPosition, StructFields.VertexDescriptionInputs.PixelPosition, + StructFields.VertexDescriptionInputs.ClipPosition, StructFields.VertexDescriptionInputs.uv0, StructFields.VertexDescriptionInputs.uv1, @@ -129,6 +130,7 @@ internal static class Structs StructFields.SurfaceDescriptionInputs.ScreenPosition, StructFields.SurfaceDescriptionInputs.NDCPosition, StructFields.SurfaceDescriptionInputs.PixelPosition, + StructFields.SurfaceDescriptionInputs.ClipPosition, StructFields.SurfaceDescriptionInputs.uv0, StructFields.SurfaceDescriptionInputs.uv1, diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Templates/SharedCode.template.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Templates/SharedCode.template.hlsl index 58c542d97be..b7aedaab5fa 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Templates/SharedCode.template.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Templates/SharedCode.template.hlsl @@ -55,6 +55,7 @@ SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input) $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition = output.PixelPosition.xy / _ScreenParams.xy; $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition.y = 1.0f - output.NDCPosition.y; + $SurfaceDescriptionInputs.ClipPosition: output.ClipPosition = input.positionCS.xy; $SurfaceDescriptionInputs.uv0: output.uv0 = input.texCoord0; $SurfaceDescriptionInputs.uv1: output.uv1 = input.texCoord1; diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildSurfaceDescriptionInputs.template.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildSurfaceDescriptionInputs.template.hlsl index f98d4b10de6..9dff91b99af 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildSurfaceDescriptionInputs.template.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildSurfaceDescriptionInputs.template.hlsl @@ -55,6 +55,7 @@ SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input) $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition = output.PixelPosition.xy / _ScreenParams.xy; $SurfaceDescriptionInputs.NDCPosition: output.NDCPosition.y = 1.0f - output.NDCPosition.y; + $SurfaceDescriptionInputs.ClipPosition: output.ClipPosition = input.positionCS.xy; #if defined(UNITY_UIE_INCLUDED) diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildVertexDescriptionInputs.template.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildVertexDescriptionInputs.template.hlsl index c0d2819192b..a446e1c99a3 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildVertexDescriptionInputs.template.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Templates/BuildVertexDescriptionInputs.template.hlsl @@ -33,6 +33,7 @@ VertexDescriptionInputs BuildVertexDescriptionInputs(Attributes input) $VertexDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(output.WorldSpacePosition), _ProjectionParams.x); $VertexDescriptionInputs.NDCPosition: output.NDCPosition = output.ScreenPosition.xy / output.ScreenPosition.w; $VertexDescriptionInputs.PixelPosition: output.PixelPosition = float2(output.NDCPosition.x, 1.0f - output.NDCPosition.y) * GetScaledScreenParams().xy; + $VertexDescriptionInputs.ClipPosition: output.ClipPosition = TransformWorldToHClip(output.WorldSpacePosition).xy; $VertexDescriptionInputs.uv0: output.uv0 = input.uv0; $VertexDescriptionInputs.uv1: output.uv1 = input.uv1; $VertexDescriptionInputs.uv2: output.uv2 = input.uv2; diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index f064ccdeea6..de28301d0cf 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -847,6 +847,7 @@ void AddCoordinateSpaceSnippets(InterpolatorType interpolatorType, Func r.requiresScreenPosition, $"float4 {ShaderGeneratorNames.ScreenPosition}"); AddRequirementsSnippet(r => r.requiresNDCPosition, $"float2 {ShaderGeneratorNames.NDCPosition}"); AddRequirementsSnippet(r => r.requiresPixelPosition, $"float2 {ShaderGeneratorNames.PixelPosition}"); + AddRequirementsSnippet(r => r.requiresClipPosition, $"float2 {ShaderGeneratorNames.ClipPosition}"); AddRequirementsSnippet(r => r.requiresFaceSign, $"float4 {ShaderGeneratorNames.FaceSign}"); foreach (var uvChannel in EnumInfo.values) diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index 3180dd05335..934dedde9b0 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -271,6 +271,10 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph, ShaderGraphImp if (childrenSet.Add(subGraphGuid)) subGraphNode.CollectShaderKeywords(keywordCollector, GenerationMode.ForReals); } + else + { + node.CollectShaderKeywords(keywordCollector, GenerationMode.ForReals); + } if (node.hasError) { diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/CommonAssets/URPAssets/DefaultURPAsset.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/CommonAssets/URPAssets/DefaultURPAsset.asset index 02dfba9decd..2b02e15de26 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/CommonAssets/URPAssets/DefaultURPAsset.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/CommonAssets/URPAssets/DefaultURPAsset.asset @@ -12,8 +12,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3} m_Name: DefaultURPAsset m_EditorClassIdentifier: - k_AssetVersion: 12 - k_AssetPreviousVersion: 12 + k_AssetVersion: 13 + k_AssetPreviousVersion: 13 m_RendererType: 1 m_RendererData: {fileID: 0} m_RendererDataList: @@ -58,6 +58,7 @@ MonoBehaviour: - {fileID: 11400000, guid: 030c8301f2c12b94fa730f3f402b803e, type: 2} - {fileID: 11400000, guid: 07cb18bb06b5e43c09f9c046804bde0d, type: 2} - {fileID: 11400000, guid: 6810122dc0f8d244faf9c3cd24516686, type: 2} + - {fileID: 11400000, guid: 862b6ef7a19e7474182799ea247b13a5, type: 2} m_DefaultRendererIndex: 0 m_RequireDepthTexture: 1 m_RequireOpaqueTexture: 1 @@ -93,6 +94,7 @@ MonoBehaviour: m_AdditionalLightsShadowResolutionTierHigh: 512 m_ReflectionProbeBlending: 0 m_ReflectionProbeBoxProjection: 0 + m_ReflectionProbeAtlas: 0 m_ShadowDistance: 56 m_ShadowCascadeCount: 4 m_Cascade2Split: 0.25 @@ -113,7 +115,6 @@ MonoBehaviour: m_MixedLightingSupported: 0 m_SupportsLightCookies: 0 m_SupportsLightLayers: 0 - m_DebugLevel: 0 m_StoreActionsOptimization: 0 m_UseAdaptivePerformance: 1 m_ColorGradingMode: 0 @@ -146,6 +147,8 @@ MonoBehaviour: m_PrefilteringModeForwardPlus: 0 m_PrefilteringModeDeferredRendering: 1 m_PrefilteringModeScreenSpaceOcclusion: 0 + m_PrefilteringModeScreenSpaceReflection: 1 + m_PrefilterWriteSmoothness: 1 m_PrefilterDebugKeywords: 1 m_PrefilterWriteRenderingLayers: 1 m_PrefilterHDROutput: 1 @@ -167,8 +170,14 @@ MonoBehaviour: m_PrefilterSoftShadowsQualityHigh: 0 m_PrefilterSoftShadows: 0 m_PrefilterScreenCoord: 1 + m_PrefilterScreenSpaceIrradiance: 0 m_PrefilterNativeRenderPass: 0 m_PrefilterUseLegacyLightmaps: 0 + m_PrefilterBicubicLightmapSampling: 0 + m_PrefilterReflectionProbeRotation: 0 + m_PrefilterReflectionProbeBlending: 0 + m_PrefilterReflectionProbeBoxProjection: 0 + m_PrefilterReflectionProbeAtlas: 0 m_ShaderVariantLogLevel: 0 m_ShadowCascades: 3 m_Textures: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.meta new file mode 100644 index 00000000000..4654ed3689a --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e0a79b33dc1e7bb4ca34100a39423ace +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity new file mode 100644 index 00000000000..91b25bba660 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26fbe4f59a3c47e50bced76de114b189b19ecf57f9359d130a2bc5ab817f48cf +size 26766 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity.meta new file mode 100644 index 00000000000..e4dc1545b7e --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c5d866532f4790f4c8c1a680624f3fa4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader new file mode 100644 index 00000000000..d59cd96b570 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader @@ -0,0 +1,82 @@ +Shader "CustomFetchDepth" +{ + SubShader + { + Tags + { + "RenderType" = "Opaque" + "RenderPipeline" = "UniversalPipeline" + } + + Pass + { + Name "CustomFetchDepth" + + ZWrite On + ZTest LEqual + Cull Off + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FragDepthVisualization + #pragma target 4.5 + #pragma multi_compile _ DEPTH_AS_INPUT_ATTACHMENT DEPTH_AS_INPUT_ATTACHMENT_MSAA + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" + + // ------------------------------------- + struct Attributes + { + float4 positionOS : POSITION; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + UNITY_VERTEX_OUTPUT_STEREO + }; + + Varyings Vert(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.positionCS = TransformObjectToHClip(input.positionOS.xyz); + return output; + } + +#if defined(DEPTH_AS_INPUT_ATTACHMENT) + float4 FragDepthVisualization(Varyings input) : SV_Target0 + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float depth = FetchSceneDepth(input.positionCS.xy); + return float4(depth, 0.0f, 0.0f, 1.0); + } +#elif defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + float4 FragDepthVisualization(Varyings input) : SV_Target0 + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + // Read depth directly from the framebuffer at the current fragment location + // No texture sampling required - this reads from the input attachment + float depth = FetchSceneDepth(input.positionCS.xy, 0); + return float4(depth, 0.0f, 0.0f, 1.0); + } +#else + + float4 FragDepthVisualization(Varyings input) : SV_Target0 + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + // no fallback + float depth = 0; + + return float4(depth, 0.0f, 0.0f, 1.0); + } +#endif + ENDHLSL + } + } +} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader.meta new file mode 100644 index 00000000000..c19a46415cf --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1601cce885647ac47ae7bae34deaf4fb +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat new file mode 100644 index 00000000000..33b2eac4ae8 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Custom_FetchDepth + m_Shader: {fileID: 4800000, guid: 1601cce885647ac47ae7bae34deaf4fb, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &7562756935574919560 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat.meta new file mode 100644 index 00000000000..df22c3ce2b9 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/Custom_FetchDepth.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e8eb7b4037d7db848ab5cf1884ebfe5c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph new file mode 100644 index 00000000000..21e297ba6fc --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fab479cc1da0be28122477d4a8437f2527ee05b73b97d575e18bc5c9dccda34 +size 14157 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph.meta new file mode 100644 index 00000000000..0dabee3be24 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/FetchDepth.shadergraph.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: 50a2293b91742d340b05671b864c4b9d +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} + useAsTemplate: 0 + exposeTemplateAsShader: 0 + indexedData: {instanceID: 0} + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset new file mode 100644 index 00000000000..822a679b87c --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset @@ -0,0 +1,100 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2806408014439770714 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6b3d386ba5cd94485973aee1479b272e, type: 3} + m_Name: RenderObjects + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.RenderObjects + m_Active: 1 + settings: + passTag: RenderObjects + Event: 500 + filterSettings: + RenderQueueType: 0 + LayerMask: + serializedVersion: 2 + m_Bits: 384 + PassNames: [] + overrideMaterial: {fileID: 0} + overrideMaterialPassIndex: 0 + overrideShader: {fileID: 0} + overrideShaderPassIndex: 0 + overrideMode: 1 + overrideDepthState: 1 + depthCompareFunction: 4 + enableWrite: 1 + stencilSettings: + overrideStencilState: 0 + stencilReference: 0 + stencilCompareFunction: 8 + passOperation: 0 + failOperation: 0 + zFailOperation: 0 + cameraSettings: + overrideCamera: 0 + restoreCamera: 1 + offset: {x: 0, y: 0, z: 0, w: 0} + cameraFieldOfView: 60 + useDepthInputAttachment: 1 +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de640fe3d0db1804a85f9fc8f5cadab6, type: 3} + m_Name: RenderObject_DepthInputAttachment + m_EditorClassIdentifier: + debugShaders: + debugReplacementPS: {fileID: 4800000, guid: cf852408f2e174538bcd9b7fda1c5ae7, type: 3} + hdrDebugViewPS: {fileID: 4800000, guid: 573620ae32aec764abd4d728906d2587, type: 3} + probeVolumeSamplingDebugComputeShader: {fileID: 7200000, guid: 53626a513ea68ce47b59dc1299fe3959, type: 3} + probeVolumeResources: + probeVolumeDebugShader: {fileID: 0} + probeVolumeFragmentationDebugShader: {fileID: 0} + probeVolumeOffsetDebugShader: {fileID: 0} + probeVolumeSamplingDebugShader: {fileID: 0} + probeSamplingDebugMesh: {fileID: 0} + probeSamplingDebugTexture: {fileID: 0} + probeVolumeBlendStatesCS: {fileID: 0} + m_RendererFeatures: + - {fileID: -2806408014439770714} + m_RendererFeatureMap: a61582a4c7a20dd9 + xrSystemData: {fileID: 0} + postProcessData: {fileID: 0} + m_AssetVersion: 3 + m_PrepassLayerMask: + serializedVersion: 2 + m_Bits: 55 + m_OpaqueLayerMask: + serializedVersion: 2 + m_Bits: 55 + m_TransparentLayerMask: + serializedVersion: 2 + m_Bits: 55 + m_DefaultStencilState: + overrideStencilState: 0 + stencilReference: 0 + stencilCompareFunction: 8 + passOperation: 2 + failOperation: 0 + zFailOperation: 0 + m_ShadowTransparentReceive: 1 + m_RenderingMode: 0 + m_DepthPrimingMode: 0 + m_CopyDepthMode: 0 + m_DepthAttachmentFormat: 0 + m_DepthTextureFormat: 0 + m_AccurateGbufferNormals: 0 + m_IntermediateTextureMode: 0 + m_TileOnlyMode: 0 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset.meta new file mode 100644 index 00000000000..26dbda33dea --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/RenderObject_DepthInputAttachment.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 862b6ef7a19e7474182799ea247b13a5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat new file mode 100644 index 00000000000..aa5ded4d4e6 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat @@ -0,0 +1,138 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SG_FetchDepth + m_Shader: {fileID: -6465566751694194690, guid: 50a2293b91742d340b05671b864c4b9d, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueControl: 0 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &2224514092178066150 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat.meta new file mode 100644 index 00000000000..60115810366 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/SG_FetchDepth.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 71c1e96da0804a04188239914cc8ed3a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/ProjectSettings/EditorBuildSettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/ProjectSettings/EditorBuildSettings.asset index c46f35eacbf..fb48cb6279b 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/ProjectSettings/EditorBuildSettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/ProjectSettings/EditorBuildSettings.asset @@ -569,6 +569,8 @@ EditorBuildSettings: - enabled: 1 path: Assets/Scenes/364_Cubemap_Mipmaps.unity guid: f737a52042020b04683b9cccd9b4a5b5 + - enabled: 1 + path: Assets/Scenes/365_RenderObject_DepthInputAttachment.unity + guid: c5d866532f4790f4c8c1a680624f3fa4 m_configObjects: - com.unity.xr.management.loader_settings: {fileID: 11400000, guid: 20e925b8abdd424429b17f709e9d00f8, - type: 2} + com.unity.xr.management.loader_settings: {fileID: 11400000, guid: 20e925b8abdd424429b17f709e9d00f8, type: 2} From 49f68115ba7077ea866848356c2817a63b0daee3 Mon Sep 17 00:00:00 2001 From: Kirill Titov Date: Fri, 3 Apr 2026 12:45:11 +0000 Subject: [PATCH 24/88] Fixed Default Volume profile bugs --- .../Runtime/Volume/VolumeComponent.cs | 19 - .../Runtime/Volume/VolumeManager.cs | 34 +- .../Runtime/Volume/VolumeProfile.cs | 23 +- .../Volumes/VolumeComponentDecorators.cs | 18 + .../Volumes/VolumeComponentDecorators.cs.meta | 3 + .../Editor/Volumes/VolumeComponentTests.cs | 13 - .../VolumeProfileGlobalDefaultTests.cs | 329 +++++++++++++++++ .../VolumeProfileGlobalDefaultTests.cs.meta | 11 + .../Editor/Volumes/VolumeProfileUtilsTests.cs | 331 ++++++++++++++++++ .../Volumes/VolumeProfileUtilsTests.cs.meta | 3 + .../Volumes/ObsoleteVolumeComponent.cs | 10 + .../Volumes/ObsoleteVolumeComponent.cs.meta | 3 + .../TestRenderPipelineAssetForVolume.cs | 14 + .../TestRenderPipelineAssetForVolume.cs.meta | 3 + .../Runtime/Volumes/VolumeManagerTests.cs | 17 +- 15 files changed, 765 insertions(+), 66 deletions(-) create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs.meta create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs.meta create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs.meta create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs.meta create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs create mode 100644 Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs index f9c60fcdda3..c125c1c7bf9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs @@ -328,25 +328,6 @@ internal void SetOverridesTo(IEnumerable enumerable, bool state } } - /// - /// A custom hashing function that Unity uses to compare the state of parameters. - /// - /// A computed hash code for the current instance. - public override int GetHashCode() - { - unchecked - { - //return parameters.Aggregate(17, (i, p) => i * 23 + p.GetHash()); - - int hash = 17; - - for (int i = 0; i < parameterList.Length; i++) - hash = hash * 23 + parameterList[i].GetHashCode(); - - return hash; - } - } - /// /// Returns true if any of the volume properites has been overridden. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs index dce529e4e28..9f073eb82a4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs @@ -272,16 +272,14 @@ public void Initialize(VolumeProfile globalDefaultVolumeProfile = null, VolumePr void InitializeBaseTypesArray(VolumeProfile globalDefaultVolumeProfile = null) { using var profilerScope = k_ProfilerMarkerInitializeBaseTypesArray.Auto(); -#if UNITY_EDITOR - LoadBaseTypesByReflection(GraphicsSettings.currentRenderPipelineAssetType); -#else +#if !UNITY_EDITOR if (globalDefaultVolumeProfile == null) { var defaultVolumeProfileSettings = GraphicsSettings.GetRenderPipelineSettings(); globalDefaultVolumeProfile = defaultVolumeProfileSettings?.defaultVolumeProfile; } - LoadBaseTypes(globalDefaultVolumeProfile); #endif + LoadBaseTypes(GraphicsSettings.currentRenderPipelineAssetType, globalDefaultVolumeProfile); } //This is called by test where the basetypes are tuned for the purpose of the test. @@ -323,7 +321,7 @@ public void Deinitialize() /// The VolumeProfile to use as the global default profile. public void SetGlobalDefaultProfile(VolumeProfile profile) { - LoadBaseTypes(profile); + LoadBaseTypes(GraphicsSettings.currentRenderPipelineAssetType, profile); globalDefaultProfile = profile; EvaluateVolumeDefaultState(); } @@ -435,8 +433,9 @@ public void DestroyStack(VolumeStack stack) /// 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. /// This will be called only once at runtime on app boot /// + /// The Pipeline Type used to check if each VolumeComponent is supported. /// The global default volume profile to use to build the base component type array. - internal void LoadBaseTypes(VolumeProfile globalDefaultVolumeProfile) + internal void LoadBaseTypesByDefaultVolume(Type rpType, VolumeProfile globalDefaultVolumeProfile) { if (globalDefaultVolumeProfile == null) { @@ -446,13 +445,13 @@ internal void LoadBaseTypes(VolumeProfile globalDefaultVolumeProfile) using (ListPool.Get(out var list)) { - var pipelineAssetType = GraphicsSettings.currentRenderPipelineAssetType; foreach (var comp in globalDefaultVolumeProfile.components) { - if (comp == null) continue; + if (comp == null) + continue; var componentType = comp.GetType(); - if (!SupportedOnRenderPipelineAttribute.IsTypeSupportedOnRenderPipeline(componentType, pipelineAssetType)) + if (!SupportedOnRenderPipelineAttribute.IsTypeSupportedOnRenderPipeline(componentType, rpType)) continue; list.Add(componentType); @@ -481,15 +480,30 @@ internal Type[] LoadBaseTypesByReflection(Type pipelineAssetType) if (!SupportedOnRenderPipelineAttribute.IsTypeSupportedOnRenderPipeline(t, pipelineAssetType)) continue; + if (t.GetCustomAttribute() != null) + continue; + list.Add(t); } - m_BaseComponentTypeArray = list.ToArray(); } return m_BaseComponentTypeArray; } #endif + /// + /// Helper to choose a type loading depending if we are in Editor and Standalone. + /// + /// The Pipeline Type used to check if each VolumeComponent is supported. + /// The global default volume profile to use to build the base component type array. + void LoadBaseTypes(Type pipelineAssetType, VolumeProfile globalDefaultVolumeProfile = null) + { +#if UNITY_EDITOR + LoadBaseTypesByReflection(pipelineAssetType); +#else + LoadBaseTypesByDefaultVolume(pipelineAssetType, globalDefaultVolumeProfile); +#endif + } internal void InitializeVolumeComponents() { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs index 53d2a302c32..38e3e6f29cf 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs @@ -321,33 +321,16 @@ public bool TryGetAllSubclassOf(Type type, List result) return count != result.Count; } - /// - /// A custom hashing function that Unity uses to compare the state of parameters. - /// - /// A computed hash code for the current instance. - public override int GetHashCode() - { - unchecked - { - int hash = 17; - - for (int i = 0; i < components.Count; i++) - hash = hash * 23 + components[i].GetHashCode(); - - return hash; - } - } - internal int GetComponentListHashCode() { unchecked { - int hash = 17; + var hashCode = HashFNV1A32.Create(); for (int i = 0; i < components.Count; i++) - hash = hash * 23 + components[i].GetType().GetHashCode(); + hashCode.Append(components[i].GetType().GetHashCode()); - return hash; + return hashCode.value; } } diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs new file mode 100644 index 00000000000..95c23b8e41c --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using UnityEngine.Rendering; + +namespace UnityEditor.Rendering.Tests +{ + [HideInInspector] + class VolumeComponentDecorators : VolumeComponent + { + [Tooltip("Increase to make the noise texture appear bigger and less")] + public FloatParameter _NoiseTileSize = new FloatParameter(25.0f); + + [InspectorName("Color")] + public ColorParameter _FogColor = new ColorParameter(Color.grey); + + [InspectorName("Size and occurrence"), Tooltip("Increase to make patches SMALLER, and frequent")] + public ClampedFloatParameter _HighNoiseSpaceFreq = new ClampedFloatParameter(0.1f, 0.1f, 1f); + } +} diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs.meta b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs.meta new file mode 100644 index 00000000000..d42961ea33c --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentDecorators.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 74d25b75408549bba46eab8384cee0e7 +timeCreated: 1773675891 \ No newline at end of file diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentTests.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentTests.cs index a91ca59de60..4803aa2dbb7 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentTests.cs +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeComponentTests.cs @@ -310,19 +310,6 @@ public string[] AdditionalProperties(Type volumeComponentType) #region Decorators Handling Test - [HideInInspector] - class VolumeComponentDecorators : VolumeComponent - { - [Tooltip("Increase to make the noise texture appear bigger and less")] - public FloatParameter _NoiseTileSize = new FloatParameter(25.0f); - - [InspectorName("Color")] - public ColorParameter _FogColor = new ColorParameter(Color.grey); - - [InspectorName("Size and occurrence"), Tooltip("Increase to make patches SMALLER, and frequent")] - public ClampedFloatParameter _HighNoiseSpaceFreq = new ClampedFloatParameter(0.1f, 0.1f, 1f); - } - readonly (string displayName, string tooltip)[] k_ExpectedResults = { (string.Empty, "Increase to make the noise texture appear bigger and less"), diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs new file mode 100644 index 00000000000..809bb1159ab --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs @@ -0,0 +1,329 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Tests; +using UnityEngine.TestTools; +using Object = UnityEngine.Object; + +namespace UnityEditor.Rendering.Tests +{ + [TestFixture] + public class VolumeProfileGlobalDefaultTests + { + VolumeManager m_VolumeManager; + List m_AssetsToDelete; + + readonly string m_AssetPath = $"Assets/{nameof(TestRenderPipelineAssetForVolume)}.asset"; + RenderPipelineAsset m_RenderPipelineAsset; + + [UnityOneTimeSetUp] + public IEnumerator OneTimeSetup() + { + m_RenderPipelineAsset = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(m_RenderPipelineAsset, m_AssetPath); + GraphicsSettings.defaultRenderPipeline = m_RenderPipelineAsset; + Assume.That(GraphicsSettings.currentRenderPipeline, Is.InstanceOf()); + + var camera = new GameObject("TestCamera").AddComponent(); + camera.Render(); + yield return null; + Object.DestroyImmediate(camera.gameObject); + Assume.That(RenderPipelineManager.currentPipeline, Is.InstanceOf()); + + m_VolumeManager = VolumeManager.instance; + Assume.That(m_VolumeManager, Is.Not.Null); + } + + [UnityOneTimeTearDown] + public IEnumerator OneTimeTearDown() + { + GraphicsSettings.defaultRenderPipeline = null; + AssetDatabase.DeleteAsset(m_AssetPath); + + Assume.That(m_VolumeManager, Is.Not.Null); + if (m_VolumeManager.isInitialized) + m_VolumeManager.Deinitialize(); + + yield return null; + } + + [SetUp] + public void SetUp() + { + if (m_VolumeManager.isInitialized) + m_VolumeManager.Deinitialize(); + + m_AssetsToDelete = new List(); + } + + [TearDown] + public void TearDown() + { + foreach (var assetPath in m_AssetsToDelete) + { + if (AssetDatabase.LoadAssetAtPath(assetPath) != null) + AssetDatabase.DeleteAsset(assetPath); + } + + m_AssetsToDelete.Clear(); + } + + VolumeProfile CreateProfileAsset(string name, params Type[] componentTypes) + { + string assetPath = $"Assets/{name}.asset"; + var profile = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(profile, assetPath); + + foreach (var type in componentTypes) + { + profile.Add(type); + } + + AssetDatabase.SaveAssets(); + m_AssetsToDelete.Add(assetPath); + return profile; + } + + [Test] + public void UpdateGlobalDefaultVolumeProfile_HandlesProfileSwitch() + { + // Create first profile with components 1 and 2 + var profile1 = CreateProfileAsset( + "DefaultProfile_Switch1", + typeof(CopyPasteTestComponent1), + typeof(CopyPasteTestComponent2) + ); + + // Initialize with first profile + m_VolumeManager.Initialize(profile1); + var initialTypes = m_VolumeManager.baseComponentTypeArray; + + // Create second profile with components 2 and 3 (different set) + var profile2 = CreateProfileAsset( + "DefaultProfile_Switch2", + typeof(CopyPasteTestComponent2), + typeof(CopyPasteTestComponent3) + ); + + // Switch to second profile + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profile2); + + // Verify VolumeManager updated correctly + Assert.IsTrue(m_VolumeManager.isInitialized); + var newTypes = m_VolumeManager.baseComponentTypeArray; + Assert.IsNotNull(newTypes); + + Assert.That(newTypes.Length, Is.EqualTo(initialTypes.Length)); + // Verify components are still properly sorted after switch + for (int i = 1; i < newTypes.Length; i++) + { + Assert.That(newTypes[i], Is.EqualTo(initialTypes[i]), + $"Types not sorted the same way after profile switch. This could break existing VolumeStack."); + } + } + + [Test] + public void UpdateGlobalDefaultVolumeProfile_VolumeManagerUpdateDoesNotThrow() + { + // Create and set default profile + var profile = CreateProfileAsset( + "DefaultProfile_NoThrow", + typeof(CopyPasteTestComponent1), + typeof(CopyPasteTestComponent2) + ); + + m_VolumeManager.Initialize(profile); + + // Create a camera for volume update + var cameraGO = new GameObject("TestCamera"); + var camera = cameraGO.AddComponent(); + LayerMask layerMask = 1; + + try + { + // This should not throw with the bug fixes + Assert.DoesNotThrow(() => + { + m_VolumeManager.Update(camera.transform, layerMask); + }, "VolumeManager.Update should not throw after setting global default profile"); + + // Verify stack is valid + Assert.IsNotNull(m_VolumeManager.stack); + } + finally + { + Object.DestroyImmediate(cameraGO); + } + } + + [Test] + public void UpdateGlobalDefaultVolumeProfile_MultipleUpdatesSameProfile() + { + // Create profile + var profile = CreateProfileAsset( + "DefaultProfile_MultiUpdate", + typeof(CopyPasteTestComponent1) + ); + + m_VolumeManager.Initialize(profile); + + // Update multiple times - should not cause issues + Assert.DoesNotThrow(() => + { + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profile); + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profile); + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profile); + }, "Multiple updates with same profile should not throw"); + + Assert.IsTrue(m_VolumeManager.isInitialized); + } + + [Test] + public void SwitchingProfiles_WithDifferentComponents_MaintainsStability() + { + var cameraGO = new GameObject("TestCamera"); + var camera = cameraGO.AddComponent(); + LayerMask layerMask = 1; + + try + { + // Profile A: Components 1, 2 + var profileA = CreateProfileAsset( + "ProfileA", + typeof(CopyPasteTestComponent1), + typeof(CopyPasteTestComponent2) + ); + + m_VolumeManager.Initialize(profileA); + m_VolumeManager.Update(camera.transform, layerMask); + + var typesA = m_VolumeManager.baseComponentTypeArray.ToList(); + Assume.That(typesA.Count, Is.GreaterThan(0)); + + // Profile B: Components 2, 3 (partial overlap) + var profileB = CreateProfileAsset( + "ProfileB", + typeof(CopyPasteTestComponent2), + typeof(CopyPasteTestComponent3) + ); + + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profileB); + + // Update should still work without errors + Assert.DoesNotThrow(() => + { + m_VolumeManager.Update(camera.transform, layerMask); + }, "Update after profile switch should not throw"); + + var typesB = m_VolumeManager.baseComponentTypeArray.ToList(); + Assume.That(typesB.Count, Is.GreaterThan(0)); + + // Profile C: Components 1, 3 (no overlap with B except potentially base types) + var profileC = CreateProfileAsset( + "ProfileC", + typeof(CopyPasteTestComponent1), + typeof(CopyPasteTestComponent3) + ); + + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profileC); + + // Update should still work + Assert.DoesNotThrow(() => + { + m_VolumeManager.Update(camera.transform, layerMask); + }, "Update after second profile switch should not throw"); + + // Back to Profile A + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profileA); + + Assert.DoesNotThrow(() => + { + m_VolumeManager.Update(camera.transform, layerMask); + }, "Update after switching back to original profile should not throw"); + + var typesAAfter = m_VolumeManager.baseComponentTypeArray; + Assert.IsNotNull(typesAAfter); + } + finally + { + Object.DestroyImmediate(cameraGO); + } + } + + [Test] + public void EnsureAllOverridesForDefaultProfile_HandlesComponentAddition() + { + // Create profile with one component + var profile = CreateProfileAsset( + "ProfileForEnsure", + typeof(CopyPasteTestComponent1) + ); + + int initialComponentCount = profile.components.Count; + + // Create a default value source with additional components + var defaultSource = CreateProfileAsset( + "DefaultSource", + typeof(CopyPasteTestComponent1), + typeof(CopyPasteTestComponent2), + typeof(CopyPasteTestComponent3) + ); + + // This should add missing components to the profile + VolumeProfileUtils.EnsureAllOverridesForDefaultProfile(profile, defaultSource); + + Assert.IsNotNull(profile.components); + Assert.Greater(profile.components.Count, initialComponentCount); + } + + [Test] + public void VolumeStack_RemainsValid_AfterProfileSwitch() + { + var cameraGO = new GameObject("TestCamera"); + var camera = cameraGO.AddComponent(); + LayerMask layerMask = 1; + + try + { + // Initial profile + var profile1 = CreateProfileAsset( + "StackValidProfile1", + typeof(CopyPasteTestComponent1) + ); + + m_VolumeManager.Initialize(profile1); + m_VolumeManager.Update(camera.transform, layerMask); + + var stack = m_VolumeManager.stack; + Assert.IsNotNull(stack); + + // Switch profile + var profile2 = CreateProfileAsset( + "StackValidProfile2", + typeof(CopyPasteTestComponent2) + ); + + VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(profile2); + m_VolumeManager.Update(camera.transform, layerMask); + + // Stack should still be valid + Assert.IsNotNull(m_VolumeManager.stack); + + // Should be able to update again without issues + Assert.DoesNotThrow(() => + { + m_VolumeManager.Update(camera.transform, layerMask); + m_VolumeManager.Update(camera.transform, layerMask); + }); + } + finally + { + Object.DestroyImmediate(cameraGO); + } + } + } +} diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs.meta b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs.meta new file mode 100644 index 00000000000..87d658e03fc --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileGlobalDefaultTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f8e9c4d5b6a3f1e2d4c5a6b7e8f9a0b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs new file mode 100644 index 00000000000..394030df80e --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs @@ -0,0 +1,331 @@ +using System; +using System.Linq; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Tests; + +namespace UnityEditor.Rendering.Tests +{ + [TestFixture] + public class VolumeProfileUtilsTests + { + #region CopyValuesToComponent Tests + + [Test] + public void CopyValuesToComponent_CopiesAllParameters_WhenCopyOnlyOverriddenParamsIsFalse() + { + using var componentScope1 = new VolumeComponentScope(out var source); + source.p1.value = 10f; + source.p1.overrideState = true; + source.p2.value = 20; + source.p2.overrideState = false; + + using var componentScope2 = new VolumeComponentScope(out var target); + target.p1.value = 0f; + target.p2.value = 0; + + VolumeProfileUtils.CopyValuesToComponent(source, target, false); + + Assert.AreEqual(10f, target.p1.value); + Assert.AreEqual(20, target.p2.value); + } + + [Test] + public void CopyValuesToComponent_CopiesOnlyOverriddenParameters_WhenCopyOnlyOverriddenParamsIsTrue() + { + using var componentScope1 = new VolumeComponentScope(out var source); + source.p1.value = 10f; + source.p1.overrideState = true; + source.p2.value = 20; + source.p2.overrideState = false; + + using var componentScope2 = new VolumeComponentScope(out var target); + target.p1.value = 0f; + target.p2.value = 0; + + VolumeProfileUtils.CopyValuesToComponent(source, target, true); + + Assert.AreEqual(10f, target.p1.value); + Assert.AreEqual(0, target.p2.value); + } + + [Test] + public void CopyValuesToComponent_HandlesNullTargetComponent_Gracefully() + { + var source = ScriptableObject.CreateInstance(); + source.p1.value = 10f; + + Assert.DoesNotThrow(() => + VolumeProfileUtils.CopyValuesToComponent(source, null, false)); + + ScriptableObject.DestroyImmediate(source); + } + + #endregion + + #region CreateNewComponent Tests + + [Test] + public void CreateNewComponent_CreatesComponentWithCorrectType() + { + var component = VolumeProfileUtils.CreateNewComponent(typeof(CopyPasteTestComponent1)); + + Assert.IsNotNull(component); + Assert.AreEqual(typeof(CopyPasteTestComponent1), component.GetType()); + + ScriptableObject.DestroyImmediate(component); + } + + [Test] + public void CreateNewComponent_SetsCorrectHideFlags() + { + var component = VolumeProfileUtils.CreateNewComponent(typeof(CopyPasteTestComponent1)); + + Assert.IsTrue((component.hideFlags & HideFlags.HideInInspector) != 0); + Assert.IsTrue((component.hideFlags & HideFlags.HideInHierarchy) != 0); + + ScriptableObject.DestroyImmediate(component); + } + + [Test] + public void CreateNewComponent_SetsCorrectName() + { + var component = VolumeProfileUtils.CreateNewComponent(typeof(CopyPasteTestComponent1)); + + Assert.AreEqual("CopyPasteTestComponent1", component.name); + + ScriptableObject.DestroyImmediate(component); + } + + #endregion + + #region EnsureAllOverridesForDefaultProfile Tests + + [Test] + public void EnsureAllOverridesForDefaultProfile_EnablesAllOverrideStates() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + + var component = profile.Add(); + component.p1.overrideState = false; + component.p2.overrideState = false; + + VolumeProfileUtils.EnsureAllOverridesForDefaultProfile(profile); + + Assert.IsTrue(component.p1.overrideState); + Assert.IsTrue(component.p2.overrideState); + } + + [Test] + public void EnsureAllOverridesForDefaultProfile_ActivatesAllComponents() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + + var component = profile.Add(); + component.active = false; + + VolumeProfileUtils.EnsureAllOverridesForDefaultProfile(profile); + + Assert.IsTrue(component.active); + } + + [Test] + public void EnsureAllOverridesForDefaultProfile_UsesDefaultValueSourceWhenProvided() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + using var volumeProfileScope2 = new VolumeProfileScope(out var defaultValueSource, "DefaultTestProfile"); + + profile.Add(); + + var defaultComponent = defaultValueSource.Add(); + defaultComponent.p1.value = 999f; + defaultComponent.p1.overrideState = true; + + VolumeProfileUtils.EnsureAllOverridesForDefaultProfile(profile, defaultValueSource); + + Assert.IsTrue(profile.TryGet(out var resultComponent)); + Assert.AreEqual(999f, resultComponent.p1.value); + } + + [Test] + public void TryEnsureAllOverridesForDefaultProfile_ReturnsTrue_WhenChangesAreMade() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + + var component = profile.Add(); + component.p1.overrideState = false; + + bool result = VolumeProfileUtils.TryEnsureAllOverridesForDefaultProfile(profile); + + Assert.IsTrue(result); + } + + [Test] + public void TryEnsureAllOverridesForDefaultProfile_ReturnsFalse_WhenNoChangesNeeded() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + + VolumeProfileUtils.TryEnsureAllOverridesForDefaultProfile(profile); + + bool result = VolumeProfileUtils.TryEnsureAllOverridesForDefaultProfile(profile); + + Assert.IsFalse(result); + } + + #endregion + + #region SetComponentEditorsExpanded Tests + + [Test] + public void SetComponentEditorsExpanded_SetsAllEditorsToExpanded() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + profile.Add(); + profile.Add(); + + var editors = profile.components + .Select(c => (VolumeComponentEditor)Editor.CreateEditor(c, typeof(VolumeComponentEditor))) + .ToList(); + + foreach (var editor in editors) + editor.expanded = false; + + VolumeProfileUtils.SetComponentEditorsExpanded(editors, true); + + foreach (var editor in editors) + Assert.IsTrue(editor.expanded); + + foreach (var editor in editors) + UnityEngine.Object.DestroyImmediate(editor); + } + + [Test] + public void SetComponentEditorsExpanded_SetsAllEditorsToCollapsed() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + profile.Add(); + profile.Add(); + + var editors = profile.components + .Select(c => (VolumeComponentEditor)Editor.CreateEditor(c, typeof(VolumeComponentEditor))) + .ToList(); + + foreach (var editor in editors) + editor.expanded = true; + + VolumeProfileUtils.SetComponentEditorsExpanded(editors, false); + + foreach (var editor in editors) + Assert.IsFalse(editor.expanded); + + foreach (var editor in editors) + UnityEngine.Object.DestroyImmediate(editor); + } + + #endregion + + #region VolumeProfile Hashcode Tests + + [Test] + public void VolumeProfile_GetComponentListHashCode_IsStable() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + + profile.Add(); + profile.Add(); + + // Get hash multiple times - should be consistent + int hash1 = profile.GetComponentListHashCode(); + int hash2 = profile.GetComponentListHashCode(); + int hash3 = profile.GetComponentListHashCode(); + + Assert.AreEqual(hash1, hash2, "Hash changed between calls"); + Assert.AreEqual(hash2, hash3, "Hash changed between calls"); + } + + [Test] + public void VolumeComponent_HashCode_DoesNotChangeWithParameterValues() + { + // This test ensures that VolumeComponent.GetHashCode() doesn't change + // when only parameter values change (not the structure). + using var componentScope1 = new VolumeComponentScope(out var component1); + using var componentScope2 = new VolumeComponentScope(out var component2); + + component1.p1.value = 100f; + component1.p2.value = 200; + + component2.p1.value = 999f; + component2.p2.value = 888; + + int initialHash1 = component1.GetHashCode(); + int initialHash2 = component2.GetHashCode(); + + component1.p1.value = 555f; + component2.p2.value = 333; + + int afterChangeHash1 = component1.GetHashCode(); + int afterChangeHash2 = component2.GetHashCode(); + + Assert.AreEqual(initialHash1, afterChangeHash1, + "Component hash should not change when only parameter values change"); + Assert.AreEqual(initialHash2, afterChangeHash2, + "Component hash should not change when only parameter values change"); + } + + [Test] + public void VolumeProfile_HashCode_DoesNotChangeWithParameterValues() + { + using var volumeProfileScope = new VolumeProfileScope(out var profile); + + var comp1 = profile.Add(); + comp1.p1.value = 100f; + + int initialHash = profile.GetHashCode(); + comp1.p1.value = 999f; + + int afterChangeHash = profile.GetHashCode(); + + Assert.AreEqual(initialHash, afterChangeHash, + "Profile hash should not change when only component parameter values change"); + } + + #endregion + + readonly struct VolumeComponentScope : IDisposable + where T : VolumeComponent + { + readonly T m_Component; + + public VolumeComponentScope(out T component) + { + component = ScriptableObject.CreateInstance(); + m_Component = component; + } + + public void Dispose() + { + ScriptableObject.DestroyImmediate(m_Component); + } + } + + readonly struct VolumeProfileScope : IDisposable + { + public readonly VolumeProfile profile; + readonly string m_AssetPath; + + public VolumeProfileScope(out VolumeProfile outProfile, string assetName = "TestProfile") + { + m_AssetPath = $"Assets/{assetName}.asset"; + profile = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(profile, m_AssetPath); + outProfile = profile; + } + + public void Dispose() + { + AssetDatabase.DeleteAsset(m_AssetPath); + } + } + } +} diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs.meta b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs.meta new file mode 100644 index 00000000000..69a620413f7 --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Editor/Volumes/VolumeProfileUtilsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b863824ddc854ed8b646ee9c09695f56 +timeCreated: 1773407021 \ No newline at end of file diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs new file mode 100644 index 00000000000..7e75cda5a87 --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs @@ -0,0 +1,10 @@ +using System; + +namespace UnityEngine.Rendering.Tests +{ + [Obsolete("Obsolete test component.", false)] + public class ObsoleteVolumeComponent : VolumeComponent + { + public FloatParameter p1 = new FloatParameter(0f); + } +} diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs.meta b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs.meta new file mode 100644 index 00000000000..3495ba460de --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/ObsoleteVolumeComponent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e2726922c6f74fc2844a2606044a7bb2 +timeCreated: 1773672100 \ No newline at end of file diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs new file mode 100644 index 00000000000..fc054d4e3cf --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace UnityEngine.Rendering.Tests +{ + public class TestRenderPipelineAssetForVolume : RenderPipelineAsset + { + protected override RenderPipeline CreatePipeline() + { + return new TestRenderPipeline(); + } + } + + public class TestRenderPipeline : RenderPipeline { } +} diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs.meta b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs.meta new file mode 100644 index 00000000000..509cfdc6d2a --- /dev/null +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/TestRenderPipelineAssetForVolume.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 589466ff6b744ad7a0381063e386b1ad +timeCreated: 1773672437 \ No newline at end of file diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/VolumeManagerTests.cs b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/VolumeManagerTests.cs index bee767114bc..9e33e336709 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/VolumeManagerTests.cs +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Assets/Tests/Runtime/Volumes/VolumeManagerTests.cs @@ -209,15 +209,24 @@ public void DefaultProfilesAreAppliedToDefaultState() volumeManager.SetCustomDefaultProfiles(new List { m_VolumeProfile3 }); Assert.AreEqual(TestVolume.k_OverrideValue3, GetDefaultState().param.value); - + volumeManager.SetGlobalDefaultProfile(null); - Assert.IsNull(GetDefaultState()); // No global default profile - default state should be null even if quality and custom defaults are set, as global is the base for the default state + if (Application.isEditor) + Assert.AreEqual(TestVolume.k_OverrideValue3, GetDefaultState().param.value); + else + Assert.IsNull(GetDefaultState()); // No global default profile - default state should be null even if quality and custom defaults are set, as global is the base for the default state volumeManager.SetQualityDefaultProfile(null); - Assert.IsNull(GetDefaultState()); // No global default profile - default state should be null even if quality and custom defaults are set, as global is the base for the default state + if (Application.isEditor) + Assert.AreEqual(TestVolume.k_OverrideValue3, GetDefaultState().param.value); + else + Assert.IsNull(GetDefaultState()); // No global default profile - default state should be null even if quality and custom defaults are set, as global is the base for the default state volumeManager.SetCustomDefaultProfiles(null); - Assert.IsNull(GetDefaultState()); // No global default profile - default state should be null even if quality and custom defaults are set, as global is the base for the default state + if (Application.isEditor) + Assert.AreEqual(TestVolume.k_DefaultValue, GetDefaultState().param.value); + else + Assert.IsNull(GetDefaultState()); // No global default profile - default state should be null even if quality and custom defaults are set, as global is the base for the default state } [Test] From 9ff68e6f23a2a13b8da03df2e2899b8b58c2672f Mon Sep 17 00:00:00 2001 From: Paul Demeulenaere Date: Fri, 3 Apr 2026 12:45:12 +0000 Subject: [PATCH 25/88] [VFX] Performance Tests Trimming --- .../Editor/VFXPerformanceEditorTests.cs | 59 ++++++++++++++++++- ...erformanceUseGraphicsTestCasesAttribute.cs | 56 ++++++++++++++++-- 2 files changed, 107 insertions(+), 8 deletions(-) diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Editor/VFXPerformanceEditorTests.cs b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Editor/VFXPerformanceEditorTests.cs index 4c294da9c72..b453053ca3e 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Editor/VFXPerformanceEditorTests.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Editor/VFXPerformanceEditorTests.cs @@ -36,6 +36,39 @@ public void Clear() EditorSettings.asyncShaderCompilation = m_PreviousAsyncShaderCompilation; } + static readonly string[] kVisualEffectAssetSelectionForPerformance = new string[] + { + "24_MotionVector", + "23_ParameterBinders", + "HDRP_VolumetricOutput", + "20_SpawnerLoop", + "HDRPFog", + "LitCapsules", + "SmokeSGAndRegular", + "VFX - CustomInterpolator", + "VFX - VertexRotation", + "ScreenAndWorldPos", + "006_StripAttributes", + "17_GPUEvent_Simple", + "VFX - Keywords", + "018_Collision", + "11_SpaceBis", + "007_MeshSampling", + "028_BaseColorMap", + "103_Lit", + "014_PositionBlock", + "105_MotionVectors", + "103_StdPrimitive", + "106_URPDecalsReceiver", + "025_ShaderKeywords", + "102_ShaderGraphShadow", + "102_RenderDepth", + "007_MeshSampling_Skinned", + "100_Fog", + "014_PositionBlock_ZeroScale", + + }; + static IEnumerable allVisualEffectAsset { get @@ -44,10 +77,32 @@ static IEnumerable allVisualEffectAsset foreach (var guid in vfxAssetsGuid) { var assetPath = AssetDatabase.GUIDToAssetPath(guid); - yield return System.IO.Path.GetFileNameWithoutExtension(assetPath); + + bool found = false; + foreach (var filteredAsset in kVisualEffectAssetSelectionForPerformance) + { + if (assetPath.Contains(filteredAsset, System.StringComparison.OrdinalIgnoreCase)) + { + found = true; + break; + } + } + + if (found) + yield return System.IO.Path.GetFileNameWithoutExtension(assetPath); } } } + static string[] s_SelectedVisualEffectAsset; + static IEnumerable SelectedVisualEffectAsset + { + get + { + if (s_SelectedVisualEffectAsset == null) + s_SelectedVisualEffectAsset = new List(allVisualEffectAsset).ToArray(); + return s_SelectedVisualEffectAsset; + } + } //Expecting only one value in this field in editor mode, it's actually a dummy variadic parameter to help filter in observer database static IEnumerable allActiveSRP @@ -257,7 +312,7 @@ public void Backup_And_Restore([ValueSource(nameof(allActiveSRP))] string srp, [ static readonly string[] allForceShaderValidation = { "ShaderValidation_On", "ShaderValidation_Off" }; [Timeout(k_BuildTimeout), Version(k_Version), Test, Performance] - public void Compilation([ValueSource(nameof(allActiveSRP))] string srp, /*[ValueSource("allForceShaderValidation")] string forceShaderValidationModeName,*/ [ValueSource("allCompilationMode")] string compilationModeName, [ValueSource("allVisualEffectAsset")] string vfxAssetPath) + public void Compilation([ValueSource(nameof(allActiveSRP))] string srp, /*[ValueSource("allForceShaderValidation")] string forceShaderValidationModeName,*/ [ValueSource("allCompilationMode")] string compilationModeName, [ValueSource(nameof(SelectedVisualEffectAsset))] string vfxAssetPath) { VFXCompilationMode compilationMode; Enum.TryParse(compilationModeName, out compilationMode); diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Runtime/VFXPerformanceUseGraphicsTestCasesAttribute.cs b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Runtime/VFXPerformanceUseGraphicsTestCasesAttribute.cs index e0228def7ff..7ba6675c885 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Runtime/VFXPerformanceUseGraphicsTestCasesAttribute.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/PerformanceTests/Runtime/VFXPerformanceUseGraphicsTestCasesAttribute.cs @@ -1,3 +1,4 @@ +using System; using NUnit.Framework.Interfaces; using UnityEngine.TestTools; using NUnit.Framework.Internal; @@ -37,17 +38,60 @@ public static string GetPrefix() return currentSRP.name; } + static readonly string[] kVisualEffectAssetSelectionForPerformance = new string[] + { + "009_MultiCamera", + "009_ReadAttributeInSpawner", + "015_FixedTime", + "018_CollisionScaledPrimitive", + "025_Flipbook", + "025_ShaderKeywords", + "026_InstancingGPUevents", + "028_BaseColorMap", + "08_Shadows", + "100_Fog", + "104_ShaderGraphGenerationFTP", + "105_MotionVectors", + "106_URPDecals", + "106_URPDecalsReceiver", + "24_MotionVector", + "28_CameraProject", + "35_ShaderGraphGenerationFTP", + "38_SortingKeys", + "39_SmokeLighting", + "40_InstancingSplitCompute", + "43_OddNegativeScale", + "Collision", + "HDRP_VolumetricOutput", + "Instancing", + "SimpleLit", + "SubgraphContexts", + "Timeline" + }; + public override IEnumerable GetTestCases(IMethodInfo methodInfo, ITest suite) { var testCases = base.GetTestCases(methodInfo, suite); - foreach (var testCase in testCases) { - yield return testCase with - { - Name = GetPrefix() + "." + testCase.Name, - FullName = testCase.FullName.Replace(testCase.Name, GetPrefix() + "." + testCase.Name), - }; + bool found = false; + foreach (var filteredAsset in kVisualEffectAssetSelectionForPerformance) + { + if (testCase.Name.Contains(filteredAsset, StringComparison.OrdinalIgnoreCase)) + { + found = true; + break; + } + } + + if (found) + { + yield return testCase with + { + Name = GetPrefix() + "." + testCase.Name, + FullName = testCase.FullName.Replace(testCase.Name, GetPrefix() + "." + testCase.Name), + }; + } } } } From 2aedb6ee8d0557fb09ff796d03164b43862ea97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Duverne?= Date: Fri, 3 Apr 2026 16:26:32 +0000 Subject: [PATCH 26/88] DOCG-7573 - Shader Graph documentation for Custom Material Property Drawers sample --- .../Documentation~/Property-Types.md | 2 +- ...raph-Sample-Custom-Lighting-Get-Started.md | 2 +- .../Shader-Graph-Sample-Custom-Lighting.md | 4 +- ...Sample-Custom-Material-Property-Drawers.md | 81 +++++++++++++++++++ .../Shader-Graph-Sample-Feature-Examples.md | 4 +- .../Shader-Graph-Sample-Node-Reference.md | 5 ++ ...Shader-Graph-Sample-Procedural-Patterns.md | 19 +++++ .../Shader-Graph-Sample-Production-Ready.md | 6 +- .../Shader-Graph-Sample-Terrain.md | 2 +- .../Shader-Graph-Sample-UGUI-Shaders.md | 7 +- .../ShaderGraph-Samples-Import.md | 15 ++++ .../Documentation~/ShaderGraph-Samples.md | 73 +++-------------- .../Documentation~/TableOfContents.md | 4 + .../images/CustomLightingSample.png | 3 - .../images/CustomMaterialPropertySample.png | 3 - .../images/FeatureExamplesSample.png | 3 - .../Documentation~/images/Patterns_Page.png | 3 - .../images/ProductionReadySample.png | 3 - .../Documentation~/images/TerrainSample.png | 3 - .../Documentation~/images/UIToolsSample.png | 3 - 20 files changed, 149 insertions(+), 96 deletions(-) create mode 100644 Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Material-Property-Drawers.md create mode 100644 Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Node-Reference.md create mode 100644 Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Procedural-Patterns.md create mode 100644 Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples-Import.md delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/CustomLightingSample.png delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/CustomMaterialPropertySample.png delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/FeatureExamplesSample.png delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/Patterns_Page.png delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/ProductionReadySample.png delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/TerrainSample.png delete mode 100644 Packages/com.unity.shadergraph/Documentation~/images/UIToolsSample.png diff --git a/Packages/com.unity.shadergraph/Documentation~/Property-Types.md b/Packages/com.unity.shadergraph/Documentation~/Property-Types.md index fdd6c030211..e432a1b79c7 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Property-Types.md +++ b/Packages/com.unity.shadergraph/Documentation~/Property-Types.md @@ -21,7 +21,7 @@ All properties have the following common parameters in addition to those specifi | **Preview Value** | Sets a value to use for preview in the Shader Graph window, only when you set **Scope** to **Global**. | | **Show In Inspector** | Displays the property in the material Inspector when enabled.
If you disable this option, it includes an `[HideInInspector]` attribute to the material property (refer to [Properties block reference in ShaderLab](https://docs.unity3d.com/Manual/SL-Properties.html#material-property-attributes) for more details). | | **Read Only** | Marks the property as non-editable in the material Inspector by adding the [`PerRendererData`](https://docs.unity3d.com/ScriptReference/Rendering.ShaderPropertyFlags.html) attribute. | -| **Custom Attributes** | Enables attachment of custom scripted drawers or decorators to extend the material property UI, such as adding static headers or complex controls.
The **Custom Material Property Drawers** sample, available in the Package Manager among other [Shader Graph samples](ShaderGraph-Samples.md), shows how to display a Vector2 as a min/max slider, for example.

**Note**: When you declare the custom functions in the script, make sure to suffix their names with `Drawer` or `Decorator`.

In the list, use **+** or **-** to add or remove entries. Each entry corresponds to a function call which requires the following parameters:
  • **Name**: A shorthened version of the function name, without its `Drawer` or `Decorator` suffix.
  • **Value**: The input values for the function as the script expects them.
**Note**: A property can only have one drawer at any given time. | +| **Custom Attributes** | Enables attachment of custom scripted drawers or decorators to extend the material property UI, such as adding static headers or complex controls.
The [Custom Material Property Drawers](Shader-Graph-Sample-Custom-Material-Property-Drawers.md) sample shows how to display a Vector2 as a min/max slider, for example.

**Note**: When you declare the custom functions in the script, make sure to suffix their names with `Drawer` or `Decorator`.

In the list, use **+** or **-** to add or remove entries. Each entry corresponds to a function call which requires the following parameters:
  • **Name**: A shortened version of the function name, without its `Drawer` or `Decorator` suffix.
  • **Value**: The input values for the function as the script expects them.
**Note**: A property can only have one drawer at any given time. | | **Use Custom Binding** | Turns the property into a bound input port for connection to the [**Branch On Input Connection**](Branch-On-Input-Connection-Node.md) node. In the **Label** field, enter the label for the default value that displays on your Subgraph node's port binding in its parent Shader Graph.
This property is available only in sub graphs. | ## Float diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Get-Started.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Get-Started.md index e12e7c57273..b2019a44869 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Get-Started.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting-Get-Started.md @@ -3,7 +3,7 @@ Use the templates and sub graphs included in the **Custom Lighting** sample to get started with lighting model customization in Shader Graph. > [!NOTE] -> To use the **Custom Lighting** templates and sub graphs, you first need to [import the sample in your project](ShaderGraph-Samples.md#add-samples). +> To use the **Custom Lighting** templates and sub graphs, you first need to [import the sample in your project](ShaderGraph-Samples-Import.md). ## Start from a shader graph template diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting.md index 10402c4e975..51af075393d 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Lighting.md @@ -1,6 +1,4 @@ -# Custom Lighting - -![An example scene with custom lighting effects.](images/CustomLightingSample.png) +# Custom Lighting sample Use the additional templates and sub graphs provided in the **Custom Lighting** sample to get started with lighting model customization in Shader Graph. diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Material-Property-Drawers.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Material-Property-Drawers.md new file mode 100644 index 00000000000..979d848e691 --- /dev/null +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Custom-Material-Property-Drawers.md @@ -0,0 +1,81 @@ +## Custom Material Property Drawers sample + +Learn how to use custom attributes in Shader Graph to improve the display and usability of property controls in the material's Inspector window. + +The Custom Material Property Drawers sample includes a shader graph based material set up for adjustable color gradient and noise. This example shows how to achieve the following in the material Inspector UI with Shader Graph: + +* Hide or display a basic material color property. +* Display a Vector2 property as a min/max slider. +* Display a help box for a property. + +## Before you start + +To access the Custom Material Property Drawers sample, follow these steps: + +1. [Import](ShaderGraph-Samples-Import.md) the Custom Material Property Drawers sample in your project. + +1. In the Project window, open the `Assets/Samples/Shader Graph//Custom Material Property Drawers` folder. + +1. Open the `RemapDrawerExample` shader graph asset. + +## Hide or display a property in the material Inspector UI + +To hide or display a material property from the shader graph in the material Inspector UI, follow these steps: + +1. In the [Shader Graph window](Shader-Graph-Window.md), in the [Blackboard](Blackboard.md), select a property, for example **InnerColor**. + +1. In the [Graph Inspector](Internal-Inspector.md), in the **Node Settings** tab, disable **Show in Inspector**. + +1. Save the graph. + +1. In the Project window, select the `RemapDrawerExample` material variant asset. + +1. In the Inspector window, notice that the **InnerColor** property isn't displayed, contrary to the other properties of the graph. + +1. In the [Shader Graph window](Shader-Graph-Window.md), re-enable **Show in Inspector** for the **InnerColor** property. + +1. Save the graph. + +1. In the Inspector window, notice that the **InnerColor** property is now displayed. + +## Display a material property as a min/max range slider + +To learn how to display a material property as a min/max range slider in the material Inspector UI, follow these steps: + +1. In the [Shader Graph window](Shader-Graph-Window.md), in the [Blackboard](Blackboard.md), select the **Range** property. + +1. In the [Graph Inspector](Internal-Inspector.md), in the **Node Settings** tab, notice the following: + + * The **Custom Attributes** include an entry named **Remap**, which modifies the **Range** property's appearance in the material UI based on a script provided with the sample. + * The attribute includes no parameter values for the called function. For more information, refer to the sticky note besides the **Range** property instance in the graph. + +1. In the Project window, open the `Editor` subfolder. + +1. Select the `RemapDrawer` C# file. + +1. In the Inspector window, notice the following: + + * The C# file includes a set of custom functions named `RemapDrawer` to display a Vector2 as a min/max slider. + * The function names include a `Drawer` suffix while in the shader graph the **Range** property excludes this suffix to call the functions. + +## Display a help box in the material Inspector UI + +To learn how to display a help box in the material Inspector UI, follow these steps: + +1. In the [Shader Graph window](Shader-Graph-Window.md), in the [Blackboard](Blackboard.md), select the **NoiseRange** property. + +1. In the [Graph Inspector](Internal-Inspector.md), in the **Node Settings** tab, notice the following: + + * The **Custom Attributes** include an entry named **Remap** (previously described) and a second one named **HelpBox**, which adds a help box to the **NoiseRange** property in the material UI based on a second script provided with the sample. + * The two attributes include specific parameter values for the called functions. For more information, refer to the sticky note under the **NoiseRange** property instance in the graph. + +1. In the Project window, still in the `Editor` subfolder, select the `HelpBoxDecorator` C# file. + +1. In the Inspector window, notice the following: + + * The C# file includes a set of custom functions named `HelpBoxDecorator` to draw a message box in the material UI. + * The function names include a `Decorator` suffix while in the shader graph the **NoiseRange** property excludes this suffix to call the functions. + +## Additional resources + +* [Property attribute reference](Property-Types.md) \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md index 3d55aace82f..dcd94cf7223 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md @@ -1,7 +1,9 @@ -# Feature Examples +# Feature Examples sample The Shader Graph Feature Examples sample content is a collection of Shader Graph assets that demonstrate how to achieve common techniques and effects in Shader Graph. The goal of this sample pack is to help users see what is required to achieve specific effects and provide examples to make it easier for users to learn. +Each sample contains notes that describe what the shader does. Most of the shaders have their core functionality in a subgraph, so you can copy and paste them into your own shader graphs. + The sample content is broken into the following categories: - **Blending Masks** - these samples generate masks based on characteristics of the surface - such as height, facing angle, or distance from the camera. diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Node-Reference.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Node-Reference.md new file mode 100644 index 00000000000..f4be3cad408 --- /dev/null +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Node-Reference.md @@ -0,0 +1,5 @@ +# Node Reference sample + +This set of Shader Graph assets provides reference material for the nodes available in the Shader Graph node library. + +Each graph contains a description for a specific node, examples of how it can be used, and useful tips. Some example assets also show a break-down of the math that the node is doing. You can use these samples along with the documentation to learn more about the behavior of individual nodes. diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Procedural-Patterns.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Procedural-Patterns.md new file mode 100644 index 00000000000..4ce9b80a025 --- /dev/null +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Procedural-Patterns.md @@ -0,0 +1,19 @@ +# Procedural Patterns sample + +This collection of Assets showcases various procedural techniques possible with Shader Graph. Use them directly in your Project, or edit them to create other procedural patterns. + +This collection includes the following patterns: + +* Bacteria +* Brick +* Dots +* Grid +* Herringbone +* Hex Lattice +* Houndstooth +* Smooth Wave +* Spiral +* Stripes +* Truchet +* Whirl +* Zig Zag diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Production-Ready.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Production-Ready.md index 7a116cc5839..112a4aa68bc 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Production-Ready.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Production-Ready.md @@ -1,8 +1,6 @@ -# Production Ready Shaders +# Production Ready Shaders sample -The Shader Graph Production Ready Shaders sample is a collection of Shader Graph shader assets that are ready to be used out of the box or modified to suit your needs. You can take them apart and learn from them, or just drop them directly into your project and use them as they are. The sample also includes a step-by-step tutorial for how to combine several of the shaders to create a forest stream environment. - -The sample content is broken into the following categories: +The Shader Graph Production Ready Shaders sample is a collection of Shader Graph shader assets that are ready to be used out of the box or modified to suit your needs. You can take them apart and learn from them, or just drop them directly into your project and use them as they are. The sample includes the Shader Graph versions of the HDRP and URP Lit shaders. It also includes a step-by-step tutorial for how to combine several of the shaders to create a forest stream environment. | Topic | Description | |:------|:--------------| diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Terrain.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Terrain.md index c6de4e6ec06..26ab4981b46 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Terrain.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Terrain.md @@ -1,4 +1,4 @@ -# Terrain Shaders +# Terrain Shaders sample The Terrain Shaders sample shows you how to design your own terrain material solutions and customize them to fit your specific goals and performance budgets. Possibilities include high quality tile repetition break-up solutions, detail mapping, smooth blending with the distant material, parallax mapping, auto materials, triplanar projection, and more. diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-UGUI-Shaders.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-UGUI-Shaders.md index e77ef30e74f..4bea29cf4bc 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-UGUI-Shaders.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-UGUI-Shaders.md @@ -1,11 +1,10 @@ -# UGUI Shaders -![The Shader Graph UGUI Shaders: A collection of Shader Graph subgraphs that serve as building blocks for building user interface elements.](images/UIToolsSample.png) +# UGUI Shaders sample -The Shader Graph UGUI Shaders sample is a collection of Shader Graph subgraphs that serve as building blocks for building user interface elements. They speed up the process of building widgets, buttons, and backgrounds for the user interface of your project. Using these tools, you can build dynamic, procedural UI elements that don’t require any texture memory and scale correctly for any resolution screen. +The Shader Graph UGUI Shaders sample is a collection of Shader Graph subgraphs that you can use to build user interface elements. They speed up the process of building widgets, buttons, and backgrounds for the user interface of your project. With these tools, you can build dynamic, procedural UI elements that don’t require any texture memory and scale correctly for any resolution screen. In addition to the subgraphs, the sample also includes example buttons, indicators, and backgrounds built using the subgraphs. The examples show how the subgraphs function in context and help you learn how to use them. -We have two main objectives with this sample set: +This sample set covers two main objectives: - Demonstrate Shader Graph’s ability to create dynamic, resolution-independent user interface elements in a wide variety of shapes and styles. diff --git a/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples-Import.md b/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples-Import.md new file mode 100644 index 00000000000..e0b88cf4f3f --- /dev/null +++ b/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples-Import.md @@ -0,0 +1,15 @@ +# Import Shader Graph samples + +To import a Shader Graph sample to your project: + +1. In the main menu, go to **Window** > **Package Management** > **Package Manager**. + +1. Select **Shader Graph** from the list of packages. + +1. In the **Samples** section, select **Import** next to a sample. + +To open a sample, go to the `Assets/Samples/Shader Graph//` folder. + +## Additional resources + +* [Shader Graph samples](ShaderGraph-Samples.md) diff --git a/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples.md b/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples.md index 7dc00155b2d..0c722469884 100644 --- a/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples.md +++ b/Packages/com.unity.shadergraph/Documentation~/ShaderGraph-Samples.md @@ -1,62 +1,15 @@ # Shader Graph samples -## Description - -The Shader Graph package offers sample Assets, which you can download through **Package Manager**. When you import these samples, Unity places the files in your Project's Asset folder. The files contain examples that demonstrate how to use Shader Graph features. - -## Add samples - -To add samples to your project: - -1. In the main menu, go to **Window** > **Package Management** > **Package Manager**. - -1. Select **Shader Graph** from the list of packages. - -1. In the **Samples** section, select **Import** next to a sample. - -1. Open the sample assets from the `Assets/Samples/Shader Graph//` folder. - -## Available samples - -The following samples are currently available for Shader Graph. - -| Procedural Patterns | -|:--------------------| -|![A visual overview of Procedural Patterns](images/Patterns_Page.png) | -| This collection of Assets showcases various procedural techniques possible with Shader Graph. Use them directly in your Project, or edit them to create other procedural patterns. The patterns in this collection are: Bacteria, Brick, Dots, Grid, Herringbone, Hex Lattice, Houndstooth, Smooth Wave, Spiral, Stripes, Truchet, Whirl, Zig Zag. | - - -| Node Reference | -|:--------------------| -|![A visual overview of Node Reference](images/NodeReferenceSamples.png) | -| This set of Shader Graph assets provides reference material for the nodes available in the Shader Graph node library. Each graph contains a description for a specific node, examples of how it can be used, and useful tips. Some example assets also show a break-down of the math that the node is doing. You can use these samples along with the documentation to learn more about the behavior of individual nodes. | - -| [Feature Examples](Shader-Graph-Sample-Feature-Examples.md) | -|:--------------------| -|![A visual overview of Feature Examples](images/FeatureExamplesSample.png) | -| This is a collection of over 30 Shader Graph files. Each file demonstrates a specific shader technique such as angle blending, triplanar projection, parallax mapping, and custom lighting. While you won’t use these shaders directly in your project, you can use them to quickly learn and understand the various techniques, and recreate them into your own work. Each file contains notes that describe what the shader is doing, and most of the shaders are set up with the core functionality contained in a subgraph that’s easy to copy and paste directly into your own shader. The sample also has extensive documentation describing each of the samples to help you learn. - -| [Production Ready Shaders](Shader-Graph-Sample-Production-Ready.md) | -|:--------------------| -|![A visual example of Production Ready Shaders](images/ProductionReadySample.png) | -| The Shader Graph Production Ready Shaders sample is a collection of Shader Graph shader assets that are ready to be used out of the box or modified to suit your needs. You can take them apart and learn from them, or just drop them directly into your project and use them as they are. The sample includes the Shader Graph versions of the HDRP and URP Lit shaders. It also includes a step-by-step tutorial for how to combine several of the shaders to create a forest stream environment. - -| [UGUI Shaders](Shader-Graph-Sample-UGUI-Shaders.md) | -|:--------------------| -|![A visual example of UGUI Shaders](images/UIToolsSample.png) | -| The Shader Graph UGUI Shaders sample is a collection of Shader Graph subgraphs that you can use to build user interface elements. They speed up the process of building widgets, buttons, and backgrounds for the user interface of your project. With these tools, you can build dynamic, procedural UI elements that don’t require any texture memory and scale correctly for any resolution screen. In addition to the subgraphs, the sample also includes example buttons, indicators, and backgrounds built with the subgraphs. The examples show how the subgraphs function in context and help you learn how to use them. - -| Custom Material Property Drawers | -|:--------------------| -|![An example result of Custom Material Property Drawers in a material's Inspector](images/CustomMaterialPropertySample.png) | -| This sample contains an example of a Custom Material Property Drawer that allows using a Min/Max Slider to control a Vector2 x and y values, often used for range remapping. It comes with a documented Shader Graph example. | - -| [Custom Lighting](Shader-Graph-Sample-Custom-Lighting.md) | -|:--------------------| -|![A visual example of Custom Lighting](images/CustomLightingSample.png) | -| The Shader Graph Custom Lighting sample shows how you can create your own custom lighting model in Shader Graph and provides dozens of example templates, shaders, and subgraphs to help you get started with your own custom lighting. - -| [Terrain Shaders](Shader-Graph-Sample-Terrain-Shaders.md) | -|:--------------------| -|![A visual overview of Terrain Shaders](images/TerrainSample.png) | -| The Shader Graph Terrain Sample provides example shaders to learn from and subgraphs that you can use to build your own terrain shaders. Custom terrain shaders can use more advanced features like hexagon tile break-up, parallax occlusion mapping, or triplanar projection. Or you can use techniques like array texture sampling or alternate texture packing methods to make the shader cheaper to render than the default one. Whether you're making faster or more advanced terrain shaders, this sample will help you get the results you're looking for. | +The Shader Graph package offers many different samples that demonstrate how to use Shader Graph features in various contexts. + +| Topic | Description | +| :--- | :--- | +| [Import Shader Graph samples](ShaderGraph-Samples-Import.md) | Learn how to import the Shader Graph samples to your project. | +| [Procedural Patterns sample](Shader-Graph-Sample-Procedural-Patterns.md) | Learn how to generate patterns procedurally with Shader Graph. | +| [Node Reference sample](Shader-Graph-Sample-Node-Reference.md) | Learn in context about the nodes from the Shader Graph [node library](Node-Library.md). | +| [Feature Examples sample](Shader-Graph-Sample-Feature-Examples.md) | Learn about shader techniques such as angle blending, triplanar projection, parallax mapping, and custom lighting. | +| [Production Ready Shaders sample](Shader-Graph-Sample-Production-Ready.md) | Learn how to create production ready shader graphs that emulate terrain vegetation, rock details, water effects, weather effects, and other post-processing effects. | +| [UGUI Shaders sample](Shader-Graph-Sample-UGUI-Shaders.md) | Learn how to build user interface elements with Shader Graph. | +| [Custom Material Property Drawers sample](Shader-Graph-Sample-Custom-Material-Property-Drawers.md) | Learn how to set up a shader graph to display a property in the form of a min/max slider and add a help box in the material's Inspector UI. | +| [Custom Lighting sample](Shader-Graph-Sample-Custom-Lighting.md) | Learn how to create custom lighting models in Shader Graph. | +| [Terrain Shaders sample](Shader-Graph-Sample-Terrain.md) | Learn how to build terrain shaders with Shader Graph. | diff --git a/Packages/com.unity.shadergraph/Documentation~/TableOfContents.md b/Packages/com.unity.shadergraph/Documentation~/TableOfContents.md index 0d7951780ae..6fac9b7bfc4 100644 --- a/Packages/com.unity.shadergraph/Documentation~/TableOfContents.md +++ b/Packages/com.unity.shadergraph/Documentation~/TableOfContents.md @@ -332,6 +332,9 @@ * [Block Nodes](Block-Node.md) * [Built In Blocks](Built-In-Blocks.md) * [Samples](ShaderGraph-Samples.md) + * [Import Shader Graph samples](ShaderGraph-Samples-Import.md) + * [Procedural Patterns](Shader-Graph-Sample-Procedural-Patterns.md) + * [Node Reference](Shader-Graph-Sample-Node-Reference.md) * [Feature Examples](Shader-Graph-Sample-Feature-Examples.md) * [Production Ready Shaders](Shader-Graph-Sample-Production-Ready.md) * [Lit Shaders](Shader-Graph-Sample-Production-Ready-Lit.md) @@ -354,6 +357,7 @@ * [How to create a functioning button](Shader-Graph-Sample-UGUI-Shaders-How-tos-Button.md) * [How to make shapes that adapt to the aspect ratio of the UI element](Shader-Graph-Sample-UGUI-Shaders-How-tos-aspect-ratio.md) * [Notes on performance](Shader-Graph-Sample-UGUI-Shaders-Notes-on-performance.md) + * [Custom Material Property Drawers](Shader-Graph-Sample-Custom-Material-Property-Drawers.md) * [Custom Lighting](Shader-Graph-Sample-Custom-Lighting.md) * [Introduction to lighting model customization](Shader-Graph-Sample-Custom-Lighting-Introduction.md) * [Get started with the Custom Lighting sample](Shader-Graph-Sample-Custom-Lighting-Get-Started.md) diff --git a/Packages/com.unity.shadergraph/Documentation~/images/CustomLightingSample.png b/Packages/com.unity.shadergraph/Documentation~/images/CustomLightingSample.png deleted file mode 100644 index 0f80bcbed91..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/CustomLightingSample.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c1a4908dc0b7f545277d7c17a1781d8f50e3f0bc169d19ce1797735fc1ca8361 -size 1757481 diff --git a/Packages/com.unity.shadergraph/Documentation~/images/CustomMaterialPropertySample.png b/Packages/com.unity.shadergraph/Documentation~/images/CustomMaterialPropertySample.png deleted file mode 100644 index b3d579cf309..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/CustomMaterialPropertySample.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce4e64a90c51363b9a566360ff87d17d6376ee7da66fdf86cb126193514920da -size 20288 diff --git a/Packages/com.unity.shadergraph/Documentation~/images/FeatureExamplesSample.png b/Packages/com.unity.shadergraph/Documentation~/images/FeatureExamplesSample.png deleted file mode 100644 index 9139d57712f..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/FeatureExamplesSample.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6aeaadd082abdddb0e587581b0c7b798bdc484d8c6b3950126e2b83bbd6c19ff -size 3156929 diff --git a/Packages/com.unity.shadergraph/Documentation~/images/Patterns_Page.png b/Packages/com.unity.shadergraph/Documentation~/images/Patterns_Page.png deleted file mode 100644 index 88b3ac132e3..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/Patterns_Page.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:acece1dd1d3bfa615d0142a38b64a8c89712a52c818b6662900199560e9e2051 -size 270125 diff --git a/Packages/com.unity.shadergraph/Documentation~/images/ProductionReadySample.png b/Packages/com.unity.shadergraph/Documentation~/images/ProductionReadySample.png deleted file mode 100644 index 4136b1629b4..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/ProductionReadySample.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d1bb398012dea3eff931b645eff8f196f51a427de742b6caecb851e1e2f8f31c -size 10945662 diff --git a/Packages/com.unity.shadergraph/Documentation~/images/TerrainSample.png b/Packages/com.unity.shadergraph/Documentation~/images/TerrainSample.png deleted file mode 100644 index 74591b5a267..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/TerrainSample.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:db4cecb9d9f4eb105aa4328e814035c3b6e647a5aa25d3b494a29acae562b7c4 -size 1735927 diff --git a/Packages/com.unity.shadergraph/Documentation~/images/UIToolsSample.png b/Packages/com.unity.shadergraph/Documentation~/images/UIToolsSample.png deleted file mode 100644 index 06117091dc8..00000000000 --- a/Packages/com.unity.shadergraph/Documentation~/images/UIToolsSample.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5365cddaecf086f33ed0c94de6e938ef006de58e6514e9dc289cfed5807a56fa -size 554758 From 1f99c1190e691d93d574afb8f815f0d1acf166e9 Mon Sep 17 00:00:00 2001 From: Anjali Nabar Date: Mon, 6 Apr 2026 13:47:33 +0000 Subject: [PATCH 27/88] Document variable rate shading --- Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs index d49f60326b4..d3cedefc8bc 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs @@ -38,6 +38,11 @@ class VisualizationPassData /// /// Check if conversion of color texture to shading rate image is supported. /// Convenience to abstract all capabilities checks. + /// + /// The `IsColorMaskTextureConversionSupported` method checks for the following: + ///- 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. + ///- Compute shader support through [SystemInfo.supportsComputeShaders](xref:UnityEngine.Device.SystemInfo.supportsComputeShaders) + ///- 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 manually. /// /// Returns true if conversion of color texture to shading rate image is supported, false otherwise. public static bool IsColorMaskTextureConversionSupported() From b3af07845faeb987ec59b7ce40485c2039dfb1e8 Mon Sep 17 00:00:00 2001 From: Qing Gu Date: Tue, 7 Apr 2026 10:09:09 +0000 Subject: [PATCH 28/88] Add UV scaling and offset support for Quad View in XR rendering --- .../Runtime/XR/XRLayout.cs | 19 +++++ .../Runtime/XR/XRLayoutStack.cs | 2 + .../Runtime/XR/XRPass.cs | 32 +++++++ .../Runtime/XR/XRSystem.cs | 83 +++++++++++++++++-- .../Passes/PostProcess/UberPostProcessPass.cs | 51 ++++++++++-- .../Runtime/PostProcessUtils.cs | 18 ++++ .../RendererFeatures/OnTilePostProcessPass.cs | 36 +++++++- .../RendererFeatures/OnTileUberPost.shader | 29 +++++-- .../Shaders/PostProcessing/UberPost.shader | 28 +++++-- 9 files changed, 271 insertions(+), 27 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayout.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayout.cs index ce4fc8a2087..f4a85623ea2 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayout.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayout.cs @@ -10,6 +10,24 @@ public class XRLayout { readonly List<(Camera, XRPass)> m_ActivePasses = new List<(Camera, XRPass)>(); + /// + /// State container for Quad View rendering, used to cache data across render passes. + /// + public QuadViewState quadView; + + /// + /// Contains cached state for Quad View XR rendering. + /// Quad View is an XR rendering mode where peripheral (outer) and foveal (inner) views are rendered separately. + /// + public struct QuadViewState + { + /// + /// Cached vignette center from the peripheral (outer) view pass. + /// Used by the inner view pass to ensure vignette effect is consistent across both views. + /// + public Vector4 cachedPeripheralVignetteCenter; + } + /// /// Configure the layout to render from the specified camera by generating passes from the the connected XR device. /// @@ -76,6 +94,7 @@ internal void Clear() } m_ActivePasses.Clear(); + quadView = default; } internal void LogDebugInfo() diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayoutStack.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayoutStack.cs index 6e07b1f6b47..c6758437337 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayoutStack.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRLayoutStack.cs @@ -15,6 +15,8 @@ public XRLayout New() return layout; } + public bool hasLayout => m_Stack.Count > 0; + public XRLayout top => m_Stack.Peek(); public void Release() diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs index e38e229fc12..744c714e614 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs @@ -26,6 +26,8 @@ public struct XRPassCreateInfo internal bool hasMotionVectorPass; internal bool spaceWarpRightHandedNDC; internal bool isLastCameraPass; + internal Vector4 uvScales; + internal Vector4 uvOffsets; #if ENABLE_VR && ENABLE_XR_MODULE internal UnityEngine.XR.XRDisplaySubsystem.XRRenderPass xrSdkRenderPass; @@ -54,6 +56,8 @@ public XRPass() m_OcclusionMesh = new XROcclusionMesh(this); m_VisibleMesh = new XRVisibleMesh(this); isLastCameraPass = true; // default to last camera pass when creating from default constructor + uvScales = Vector4.one; + uvOffsets = Vector4.zero; } /// @@ -137,6 +141,32 @@ public bool supportsFoveatedRendering /// public bool isLastCameraPass { get; private set; } + /// + /// The scale factors used to map the current view's UV coordinates to the + /// peripheral (outset) view's UV space during post-processing. + /// xy = left eye (scale x, scale y), zw = right eye (scale x, scale y). + /// + /// + /// Used in Quad View foveated rendering where the high-resolution inner patch + /// occupies a specific sub-region of the physical eye buffer. + /// Formula: mappedUV = uv * uvScales + uvOffsets + /// Only applicable to the inner pass; outer pass uses (1,1,1,1). + /// + public Vector4 uvScales { get; private set; } + + /// + /// The translation offsets used to map the current view's UV coordinates to the + /// peripheral (outset) view's UV space during post-processing. + /// xy = left eye (offset x, offset y), zw = right eye (offset x, offset y). + /// + /// + /// Used in Quad View foveated rendering where the high-resolution inner patch + /// occupies a specific sub-region of the physical eye buffer. + /// Formula: mappedUV = uv * uvScales + uvOffsets + /// Only applicable to the inner pass; outer pass uses (0,0,0,0). + /// + public Vector4 uvOffsets { get; private set; } + /// /// Index of the pass inside the frame. /// @@ -558,6 +588,8 @@ public void InitBase(XRPassCreateInfo createInfo) occlusionMeshScale = createInfo.occlusionMeshScale; foveatedRenderingInfo = createInfo.foveatedRenderingInfo; isLastCameraPass = createInfo.isLastCameraPass; + uvScales = createInfo.uvScales; + uvOffsets = createInfo.uvOffsets; } internal void AddView(XRView xrView) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs index 9d9d1a97fda..85f720981dd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs @@ -321,6 +321,12 @@ public static XRLayout NewLayout() return s_Layout.New(); } + /// + /// Returns the current active XR layout, or null if none is active. + /// Used by render passes to access cross-camera XR state like Quad View parameters. + /// + public static XRLayout currentLayout => s_Layout.hasLayout ? s_Layout.top : null; + /// /// Used by the render pipeline to complete the XR layout at the end of the frame. /// @@ -430,15 +436,77 @@ void AddViewToPass(XRPass xrPass, XRDisplaySubsystem.XRRenderPass renderPass, in xrPass.AddView(BuildView(renderPass, renderParam)); } - for (int renderPassIndex = 0; renderPassIndex < s_Display.GetRenderPassCount(); ++renderPassIndex) + // Helper: extract frustum extents from projection matrix. + // Returns Vector4(width, height, left, top) at unit depth. + static Vector4 ExtractFrustumBoundsFromProjection(Matrix4x4 proj) + { + float width = 2.0f / proj[0, 0]; + float height = 2.0f / proj[1, 1]; + float left = (proj[0, 2] - 1.0f) / proj[0, 0]; + float top = (1 - proj[1, 2]) / proj[1, 1]; + + return new Vector4(width, height, left, top); + } + + Vector4 ExtractViewBounds(XRDisplaySubsystem.XRRenderPass renderPass, int renderParamIndex) + { + renderPass.GetRenderParameter(camera, renderParamIndex, out var renderParam); + var proj = renderParam.projection; + return ExtractFrustumBoundsFromProjection(proj); + } + + int renderPassCount = s_Display.GetRenderPassCount(); + + // Pre-calculate view bounds for quad view (2 passes × 2 views) using fixed-size stack variables + // This avoids List allocations that would cause GC pressure every frame + Vector4 pass0View0Bounds = default, pass0View1Bounds = default; + Vector4 pass1View0Bounds = default, pass1View1Bounds = default; + bool isQuadViewSetup = renderPassCount == 2; + if (isQuadViewSetup) + { + s_Display.GetRenderPass(0, out var pass0); + s_Display.GetRenderPass(1, out var pass1); + if (pass0.GetRenderParameterCount() >= 2 && pass1.GetRenderParameterCount() >= 2) + { + pass0View0Bounds = ExtractViewBounds(pass0, 0); + pass0View1Bounds = ExtractViewBounds(pass0, 1); + pass1View0Bounds = ExtractViewBounds(pass1, 0); + pass1View1Bounds = ExtractViewBounds(pass1, 1); + } + else + { + isQuadViewSetup = false; + } + } + + for (int renderPassIndex = 0; renderPassIndex < renderPassCount; ++renderPassIndex) { s_Display.GetRenderPass(renderPassIndex, out var renderPass); s_Display.GetCullingParameters(camera, renderPass.cullingPassIndex, out var cullingParams); int renderParameterCount = renderPass.GetRenderParameterCount(); + bool isLastPass = renderPassIndex == renderPassCount - 1; + // This parameter makes sure we are in 2 pass quad view's second pass, which is the only case we need to apply special UV scale and offset. + bool isQuadViewLastPass = isLastPass && isQuadViewSetup; + Vector4 uvScales = Vector4.one; + Vector4 uvOffsets = Vector4.zero; + if (isQuadViewLastPass) + { + // Calculate UV scales and offsets from pre-computed view bounds + uvScales.x = pass1View0Bounds.x / pass0View0Bounds.x; + uvScales.y = pass1View0Bounds.y / pass0View0Bounds.y; + uvScales.z = pass1View1Bounds.x / pass0View1Bounds.x; + uvScales.w = pass1View1Bounds.y / pass0View1Bounds.y; + + uvOffsets.x = (pass1View0Bounds.z - pass0View0Bounds.z) / pass0View0Bounds.x; + uvOffsets.y = -(pass1View0Bounds.w - pass0View0Bounds.w) / pass0View0Bounds.y; + uvOffsets.z = (pass1View1Bounds.z - pass0View1Bounds.z) / pass0View1Bounds.x; + uvOffsets.w = -(pass1View1Bounds.w - pass0View1Bounds.w) / pass0View1Bounds.y; + } + if (CanUseSinglePass(camera, renderPass)) { - var createInfo = BuildPass(renderPass, cullingParams, layout, renderPassIndex == s_Display.GetRenderPassCount() - 1); + var createInfo = BuildPass(renderPass, cullingParams, layout, renderPassIndex == s_Display.GetRenderPassCount() - 1, uvScales, uvOffsets); var xrPass = s_PassAllocator(createInfo); for (int renderParamIndex = 0; renderParamIndex < renderParameterCount; ++renderParamIndex) @@ -452,7 +520,7 @@ void AddViewToPass(XRPass xrPass, XRDisplaySubsystem.XRRenderPass renderPass, in { for (int renderParamIndex = 0; renderParamIndex < renderParameterCount; ++renderParamIndex) { - var createInfo = BuildPass(renderPass, cullingParams, layout, renderPassIndex == s_Display.GetRenderPassCount() - 1); + var createInfo = BuildPass(renderPass, cullingParams, layout, renderPassIndex == s_Display.GetRenderPassCount() - 1, uvScales, uvOffsets); var xrPass = s_PassAllocator(createInfo); AddViewToPass(xrPass, renderPass, renderParamIndex); layout.AddPass(camera, xrPass); @@ -515,7 +583,6 @@ static XRView BuildView(XRDisplaySubsystem.XRRenderPass renderPass, XRDisplaySub { // Convert viewport from normalized to screen space Rect viewport = renderParameter.viewport; - viewport.x *= renderPass.renderTargetScaledWidth; viewport.width *= renderPass.renderTargetScaledWidth; viewport.y *= renderPass.renderTargetScaledHeight; @@ -542,8 +609,8 @@ private static RenderTextureDescriptor XrRenderTextureDescToUnityRenderTextureDe return rtDesc; } - static XRPassCreateInfo BuildPass(XRDisplaySubsystem.XRRenderPass xrRenderPass, ScriptableCullingParameters cullingParameters, XRLayout layout, bool isLastPass) - { + static XRPassCreateInfo BuildPass(XRDisplaySubsystem.XRRenderPass xrRenderPass, ScriptableCullingParameters cullingParameters, XRLayout layout, bool isLastPass, Vector4 uvScales, Vector4 uvOffsets) + { XRPassCreateInfo passInfo = new XRPassCreateInfo { renderTarget = xrRenderPass.renderTarget, @@ -562,7 +629,9 @@ static XRPassCreateInfo BuildPass(XRDisplaySubsystem.XRRenderPass xrRenderPass, copyDepth = xrRenderPass.shouldFillOutDepth, spaceWarpRightHandedNDC = xrRenderPass.spaceWarpRightHandedNDC, xrSdkRenderPass = xrRenderPass, - isLastCameraPass = isLastPass + isLastCameraPass = isLastPass, + uvScales = uvScales, + uvOffsets = uvOffsets }; return passInfo; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs index e0a9b0e9a3a..e72a80a6801 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs @@ -1,4 +1,5 @@ using System; +using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; using System.Runtime.CompilerServices; // AggressiveInlining @@ -225,7 +226,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer if(data.chromaticAberration.IsActive()) data.chromaticAberration.Apply(material); - data.vignette.Apply(material, cameraData.xr); + data.vignette.Apply(material); if(data.filmGrain.IsActive()) data.filmGrain.Apply(material); @@ -262,8 +263,14 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer RenderingUtils.SetupOffscreenUIViewportParams(material, ref cameraData.pixelRect, data.isFinalPass && cameraData.resolveFinalTarget); } - // Done with Uber, blit it #if ENABLE_VR && ENABLE_XR_MODULE + // Setup XR UV remapping for Quad View (used by all screen-space effects) + if (cameraData.xr != null && cameraData.xr.enabled && cameraData.xr.singlePassEnabled) + { + PostProcessUtils.SetupXRUVRemapping(material, cameraData.xr); + } + + // Done with Uber, blit it if (cameraData.xr.enabled && cameraData.xr.hasValidVisibleMesh) PostProcessUtils.ScaleViewportAndDrawVisibilityMesh(context, data.sourceTexture, data.destinationTexture, data.cameraData, material, data.isFinalPass); else @@ -510,24 +517,51 @@ internal struct VignetteParams { public Vector4 vignetteParams1; public Vector4 vignetteParams2; +#if ENABLE_VR && ENABLE_XR_MODULE + public Vector4 vignetteXRCenter; + public bool hasXRCenter; +#endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Setup(Vignette vignette, int width, int height, Experimental.Rendering.XRPass xrPass) { CalcVignetteParams(vignette, width, height, xrPass, out vignetteParams1, out vignetteParams2); +#if ENABLE_VR && ENABLE_XR_MODULE + hasXRCenter = false; + if (xrPass != null && xrPass.enabled && xrPass.singlePassEnabled) + { + hasXRCenter = true; + Vector2 center = vignetteParams2; + var xrLayout = XRSystem.currentLayout; + + if (xrLayout != null && xrPass.viewCount > 1 && xrPass.multipassId == 1 && xrPass.isLastCameraPass) + { + // Second pass (inner views): Reuse the cached peripheral vignette center + // This ensures vignette is calculated in the outer UV space after remapping + vignetteXRCenter = xrLayout.quadView.cachedPeripheralVignetteCenter; + } + else + { + // First pass (peripheral/outer views): Calculate and cache the vignette center + vignetteXRCenter = xrPass.ApplyXRViewCenterOffset(center); + if (xrLayout != null) + xrLayout.quadView.cachedPeripheralVignetteCenter = vignetteXRCenter; + } + } +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Apply(Material material, Experimental.Rendering.XRPass xrPass) + public void Apply(Material material) { material.SetVector(ShaderConstants._Vignette_Params1, vignetteParams1); material.SetVector(ShaderConstants._Vignette_Params2, vignetteParams2); #if ENABLE_VR && ENABLE_XR_MODULE - if (xrPass != null && xrPass.enabled && xrPass.singlePassEnabled) + if (hasXRCenter) { - Vector2 center = vignetteParams2; - material.SetVector(ShaderConstants._Vignette_ParamsXR, xrPass.ApplyXRViewCenterOffset(center)); + material.SetVector(ShaderConstants._Vignette_ParamsXR, vignetteXRCenter); } #endif } @@ -546,6 +580,11 @@ static public void CalcVignetteParams(Vignette vignette, int width, int height, // center since the version of the shader that is not single-pass will use the value in _Vignette_Params2 center = xrPass.ApplyXRViewCenterOffset(center); } + if (xrPass != null && xrPass.singlePassEnabled && xrPass.viewCount > 1 && xrPass.multipassId == 1 && xrPass.isLastCameraPass) + { + // In quad view we need to also apply the aspect ratio correction to the vignette as the UV remapping will cause it to be stretched/squashed if not corrected + aspectRatio *= xrPass.uvScales.y / xrPass.uvScales.x; + } #endif vignetteParams1 = new Vector4( diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs index af57ad732aa..ec2edf5bfcb 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs @@ -275,6 +275,21 @@ internal static void SetupHDROutput(Material material, HDROutputUtils.HDRDisplay } #endregion +#if ENABLE_VR && ENABLE_XR_MODULE + /// + /// Configures UV remapping for Quad View multi-resolution rendering in XR. + /// Sets shader parameters for screen-space effects to align with inner view coordinates. + /// + /// The material to configure. + /// The XR pass containing UV scale/offset parameters. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void SetupXRUVRemapping(Material material, XRPass xrPass) + { + material.SetVector(ShaderConstants._Quad_View_Uv_Remap_scalesXR, xrPass.uvScales); + material.SetVector(ShaderConstants._Quad_View_Uv_Remap_offsetsXR, xrPass.uvOffsets); + } +#endif + #region Blit [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -399,6 +414,9 @@ static class ShaderConstants public static readonly int _BlueNoise_Texture = Shader.PropertyToID("_BlueNoise_Texture"); public static readonly int _Dithering_Params = Shader.PropertyToID("_Dithering_Params"); + public static readonly int _Quad_View_Uv_Remap_scalesXR = Shader.PropertyToID("_Quad_View_Uv_Remap_scalesXR"); + public static readonly int _Quad_View_Uv_Remap_offsetsXR = Shader.PropertyToID("_Quad_View_Uv_Remap_offsetsXR"); + public static readonly int _SourceSize = Shader.PropertyToID("_SourceSize"); } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs index 62a82ea6803..1601c312cff 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs @@ -14,7 +14,6 @@ public class OnTilePostProcessPass : ScriptableRenderPass ///
internal readonly bool k_SupportsMultisampleShaderResolve = false; internal bool m_UseTextureReadFallback = false; - RTHandle m_UserLut; Material m_OnTileUberMaterial; static readonly int s_BlitScaleBias = Shader.PropertyToID("_BlitScaleBias"); @@ -23,6 +22,9 @@ public class OnTilePostProcessPass : ScriptableRenderPass PostProcessData m_PostProcessData; Texture2D[] m_FilmGrainTextures; + // Cache vignette center from peripheral (outer) pass for quad view + static Vector4 s_CachedPeripheralVignetteCenter = Vector4.zero; + const string m_PassName = "On Tile Post Processing"; const string m_FallbackPassName = "On Tile Post Processing (sampling fallback) "; @@ -119,6 +121,14 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.UseFastSRGBLinearConversion, postProcessingData.useFastSRGBLinearConversion); CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings._ENABLE_ALPHA_OUTPUT, cameraData.isAlphaOutputEnabled); +#if ENABLE_VR && ENABLE_XR_MODULE + // Setup XR UV remapping for Quad View (used by all screen-space effects) + if (cameraData.xr != null && cameraData.xr.enabled && cameraData.xr.singlePassEnabled) + { + PostProcessUtils.SetupXRUVRemapping(m_OnTileUberMaterial, cameraData.xr); + } +#endif + int shaderPass; if (m_UseTextureReadFallback) @@ -332,11 +342,33 @@ void SetupVignette(Material material, XRPass xrPass, int width, int height, Vign if (xrPass != null && xrPass.enabled) { if (xrPass.singlePassEnabled) - material.SetVector(ShaderConstants._Vignette_ParamsXR, xrPass.ApplyXRViewCenterOffset(center)); + { + Vector4 vignetteXRCenter; + var xrLayout = XRSystem.currentLayout; + + if (xrLayout != null && xrPass.viewCount > 1 && xrPass.multipassId == 1 && xrPass.isLastCameraPass) + { + // Second pass (inner views): Reuse the cached peripheral vignette center + // This ensures vignette is calculated in the outer UV space after remapping + vignetteXRCenter = xrLayout.quadView.cachedPeripheralVignetteCenter; + // In quad view we need to also apply the aspect ratio correction to the vignette as the UV remapping will cause it to be stretched/squashed if not corrected + aspectRatio *= xrPass.uvScales.y / xrPass.uvScales.x; + } + else + { + // First pass (peripheral/outer views): Calculate and cache the vignette center + vignetteXRCenter = xrPass.ApplyXRViewCenterOffset(center); + if (xrLayout != null) + xrLayout.quadView.cachedPeripheralVignetteCenter = vignetteXRCenter; + } + material.SetVector(ShaderConstants._Vignette_ParamsXR, vignetteXRCenter); + } else + { // In multi-pass mode we need to modify the eye center with the values from .xy of the corrected // center since the version of the shader that is not single-pass will use the value in _Vignette_Params2 center = xrPass.ApplyXRViewCenterOffset(center); + } } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader index 3d4e8497585..c05121c3c88 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader @@ -33,6 +33,8 @@ Shader "OnTileUberPost" float4 _Vignette_Params2; #ifdef USING_STEREO_MATRICES float4 _Vignette_ParamsXR; + float4 _Quad_View_Uv_Remap_scalesXR; // xy = Eye0 scale, zw = Eye1 scale + float4 _Quad_View_Uv_Remap_offsetsXR; // xy = Eye0 offset, zw = Eye1 offset #endif float2 _Grain_Params; float4 _Grain_TilingParams; @@ -40,12 +42,16 @@ Shader "OnTileUberPost" float4 _HDROutputLuminanceParams; #define VignetteColor _Vignette_Params1.xyz - #ifdef USING_STEREO_MATRICES +#ifdef USING_STEREO_MATRICES #define VignetteCenterEye0 _Vignette_ParamsXR.xy #define VignetteCenterEye1 _Vignette_ParamsXR.zw - #else + #define QuadViewUvRemapEye0Scale _Quad_View_Uv_Remap_scalesXR.xy + #define QuadViewUvRemapEye1Scale _Quad_View_Uv_Remap_scalesXR.zw + #define QuadViewUvRemapEye0Offset _Quad_View_Uv_Remap_offsetsXR.xy + #define QuadViewUvRemapEye1Offset _Quad_View_Uv_Remap_offsetsXR.zw +#else #define VignetteCenter _Vignette_Params2.xy - #endif +#endif #define VignetteIntensity _Vignette_Params2.z #define VignetteSmoothness _Vignette_Params2.w #define VignetteRoundness _Vignette_Params1.w @@ -83,6 +89,15 @@ Shader "OnTileUberPost" } #endif + // Remapped UV for screen-space effects in Quad View + float2 uvRemapped = uv; +#ifdef USING_STEREO_MATRICES + // Select per-eye scale and offset for robust handling of asymmetric projection matrices + const float2 quadViewScale = unity_StereoEyeIndex == 0 ? QuadViewUvRemapEye0Scale : QuadViewUvRemapEye1Scale; + const float2 quadViewOffset = unity_StereoEyeIndex == 0 ? QuadViewUvRemapEye0Offset : QuadViewUvRemapEye1Offset; + uvRemapped = uv * quadViewScale + quadViewOffset; +#endif + // To save on variants we use an uniform branch for vignette. This may have performance impact on lower end platforms UNITY_BRANCH if (VignetteIntensity > 0) @@ -93,17 +108,17 @@ Shader "OnTileUberPost" const float2 VignetteCenter = unity_StereoEyeIndex == 0 ? VignetteCenterEye0 : VignetteCenterEye1; #endif - color = ApplyVignette(color, uv, VignetteCenter, VignetteIntensity, VignetteRoundness, VignetteSmoothness, VignetteColor); + color = ApplyVignette(color, uvRemapped, VignetteCenter, VignetteIntensity, VignetteRoundness, VignetteSmoothness, VignetteColor); } // Color grading is always enabled when post-processing/uber is active { color = ApplyColorGrading(color, PostExposure, TEXTURE2D_ARGS(_InternalLut, sampler_LinearClamp), LutParams, TEXTURE2D_ARGS(_UserLut, sampler_LinearClamp), UserLutParams, UserLutContribution, PaperWhite, OneOverPaperWhite); } - + #if _FILM_GRAIN { - color = ApplyGrain(color, uv, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset, OneOverPaperWhite); + color = ApplyGrain(color, uvRemapped, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset, OneOverPaperWhite); } #endif @@ -123,7 +138,7 @@ Shader "OnTileUberPost" #if _DITHERING { - color = ApplyDithering(color, uv, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset, PaperWhite, OneOverPaperWhite); + color = ApplyDithering(color, uvRemapped, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset, PaperWhite, OneOverPaperWhite); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UberPost.shader b/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UberPost.shader index 8a793dc0605..7225df20367 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UberPost.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UberPost.shader @@ -65,6 +65,8 @@ Shader "Hidden/Universal Render Pipeline/UberPost" float4 _Vignette_Params2; #ifdef USING_STEREO_MATRICES float4 _Vignette_ParamsXR; + float4 _Quad_View_Uv_Remap_scalesXR; // xy = Eye0 scale, zw = Eye1 scale + float4 _Quad_View_Uv_Remap_offsetsXR; // xy = Eye0 offset, zw = Eye1 offset #endif float2 _Grain_Params; float4 _Grain_TilingParams; @@ -92,6 +94,10 @@ Shader "Hidden/Universal Render Pipeline/UberPost" #ifdef USING_STEREO_MATRICES #define VignetteCenterEye0 _Vignette_ParamsXR.xy #define VignetteCenterEye1 _Vignette_ParamsXR.zw + #define QuadViewUvRemapEye0Scale _Quad_View_Uv_Remap_scalesXR.xy + #define QuadViewUvRemapEye1Scale _Quad_View_Uv_Remap_scalesXR.zw + #define QuadViewUvRemapEye0Offset _Quad_View_Uv_Remap_offsetsXR.xy + #define QuadViewUvRemapEye1Offset _Quad_View_Uv_Remap_offsetsXR.zw #else #define VignetteCenter _Vignette_Params2.xy #endif @@ -160,9 +166,21 @@ Shader "Hidden/Universal Render Pipeline/UberPost" { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + // Original UV for back buffer sampling (no Quad View remapping) float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.texcoord)); float2 uvDistorted = DistortUV(uv); + // Remapped UV for screen-space effects in Quad View (vignette, bloom, grain, etc.) + float2 uvRemapped = uv; + float2 uvRemappedDistorted = uvDistorted; + #ifdef USING_STEREO_MATRICES + // Select per-eye scale and offset for robust handling of asymmetric projection matrices + const float2 quadViewScale = unity_StereoEyeIndex == 0 ? QuadViewUvRemapEye0Scale : QuadViewUvRemapEye1Scale; + const float2 quadViewOffset = unity_StereoEyeIndex == 0 ? QuadViewUvRemapEye0Offset : QuadViewUvRemapEye1Offset; + uvRemapped = uv * quadViewScale + quadViewOffset; + uvRemappedDistorted = DistortUV(uvRemapped); + #endif + // NOTE: Hlsl specifies missing input.a to fill 1 (0 for .rgb). // InputColor is a "bottom" layer for alpha output. half4 inputColor = SampleColor(ClampUVForBilinear(SCREEN_COORD_REMOVE_SCALEBIAS(uvDistorted), _BlitTexture_TexelSize.xy)); @@ -221,7 +239,7 @@ Shader "Hidden/Universal Render Pipeline/UberPost" // considering we use a cover-style scale on the dirt texture the difference // isn't massive so we chose to save a few ALUs here instead in case lens // distortion is active. - half3 dirt = SAMPLE_TEXTURE2D(_LensDirt_Texture, sampler_LinearClamp, uvDistorted * LensDirtScale + LensDirtOffset).xyz; + half3 dirt = SAMPLE_TEXTURE2D(_LensDirt_Texture, sampler_LinearClamp, uvRemappedDistorted * LensDirtScale + LensDirtOffset).xyz; dirt *= LensDirtIntensity; color += dirt * bloom.xyz; } @@ -247,7 +265,7 @@ Shader "Hidden/Universal Render Pipeline/UberPost" const float2 VignetteCenter = unity_StereoEyeIndex == 0 ? VignetteCenterEye0 : VignetteCenterEye1; #endif - color = ApplyVignette(color, uvDistorted, VignetteCenter, VignetteIntensity, VignetteRoundness, VignetteSmoothness, VignetteColor); + color = ApplyVignette(color, uvRemappedDistorted, VignetteCenter, VignetteIntensity, VignetteRoundness, VignetteSmoothness, VignetteColor); } // Color grading is always enabled when post-processing/uber is active @@ -257,7 +275,7 @@ Shader "Hidden/Universal Render Pipeline/UberPost" #if _FILM_GRAIN { - color = ApplyGrain(color, uv, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset, OneOverPaperWhite); + color = ApplyGrain(color, uvRemapped, TEXTURE2D_ARGS(_Grain_Texture, sampler_LinearRepeat), GrainIntensity, GrainResponse, GrainScale, GrainOffset, OneOverPaperWhite); } #endif @@ -277,7 +295,7 @@ Shader "Hidden/Universal Render Pipeline/UberPost" #if _DITHERING { - color = ApplyDithering(color, uv, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset, PaperWhite, OneOverPaperWhite); + color = ApplyDithering(color, uvRemapped, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset, PaperWhite, OneOverPaperWhite); // Assume color > 0 and prevent 0 - ditherNoise. // Negative colors can cause problems if fed back to the postprocess via render to FP16 texture. color = max(color, 0); @@ -317,7 +335,7 @@ Shader "Hidden/Universal Render Pipeline/UberPost" #if defined(DEBUG_DISPLAY) half4 debugColor = 0; - if(CanDebugOverrideOutputColor(half4(color, 1), uv, debugColor)) + if(CanDebugOverrideOutputColor(half4(color, 1), uvRemapped, debugColor)) { return debugColor; } From 24b8ee7d6d805b5efd63533fdd7ce280fb526c47 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:19 +0000 Subject: [PATCH 29/88] Updated `DiffusionProfileList` to work with CoreCLR --- .../Runtime/Lighting/DiffusionProfileList.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/DiffusionProfileList.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/DiffusionProfileList.cs index b321084ec34..774aebea85e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/DiffusionProfileList.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/DiffusionProfileList.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers; namespace UnityEngine.Rendering.HighDefinition { @@ -41,9 +42,6 @@ internal void ReplaceWithArray(DiffusionProfileSettings[] profileSettingsArray) [Serializable] public sealed class DiffusionProfileSettingsParameter : VolumeParameter { - static System.Buffers.ArrayPool s_ArrayPool = - System.Buffers.ArrayPool.Create(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, 5); - // To accumulate diffusion profiles when resolving stack and not make a new allocation everytime, // We allocate once an array with max size, and store the ammount of slots used here. internal DiffusionProfileSettings[] accumulatedArray = null; @@ -99,7 +97,7 @@ public override void SetValue(VolumeParameter parameter) /// The interpolation factor in range [0,1]. public override void Interp(DiffusionProfileSettings[] from, DiffusionProfileSettings[] to, float t) { - m_Value = s_ArrayPool.Rent(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT); + m_Value = ArrayPool.Shared.Rent(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT); accumulatedCount = 0; @@ -134,7 +132,7 @@ public override void Interp(DiffusionProfileSettings[] from, DiffusionProfileSet m_Value[i] = null; if (accumulatedArray != null) - s_ArrayPool.Return(accumulatedArray); + ArrayPool.Shared.Return(accumulatedArray); accumulatedArray = m_Value; } @@ -144,7 +142,7 @@ public override void Interp(DiffusionProfileSettings[] from, DiffusionProfileSet public override void Release() { if (accumulatedArray != null) - s_ArrayPool.Return(accumulatedArray); + ArrayPool.Shared.Return(accumulatedArray); accumulatedArray = null; } } From d4309b0633a56637b41feb48191cb642f6d5f20b Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:20 +0000 Subject: [PATCH 30/88] Updated `BilateralUpsample` to work with CoreCLR --- .../Lighting/ScreenSpaceLighting/BilateralUpsampleDef.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsampleDef.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsampleDef.cs index 1f76efce700..9f1d3c23398 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsampleDef.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsampleDef.cs @@ -33,18 +33,18 @@ internal class BilateralUpsample // {-1.0, 1.0}, {0.0, 1.0}, {1.0, 1.0} // Set of pre-generated weights (L->R, T->B). After experimentation, the final weighting function is exp(-distance^2) - static internal float[] distanceBasedWeights_3x3 = new float[] { 0.324652f, 0.535261f, 0.119433f, 0.535261f, 0.882497f, 0.196912f, 0.119433f, 0.196912f, 0.0439369f, + internal static readonly float[] distanceBasedWeights_3x3 = new float[] { 0.324652f, 0.535261f, 0.119433f, 0.535261f, 0.882497f, 0.196912f, 0.119433f, 0.196912f, 0.0439369f, 0.119433f, 0.535261f, 0.324652f, 0.196912f, 0.882497f, 0.535261f, 0.0439369f, 0.196912f, 0.119433f, 0.119433f, 0.196912f, 0.0439369f, 0.535261f, 0.882497f, 0.196912f, 0.324652f, 0.535261f, 0.119433f, 0.0439369f, 0.196912f, 0.119433f, 0.196912f, 0.882497f, 0.535261f, 0.119433f, 0.535261f, 0.324652f}; // Set of pre-generated weights (L->R, T->B). After experimentation, the final weighting function is exp(-distance^2) - static internal float[] distanceBasedWeights_2x2 = new float[] { 0.324652f, 0.535261f, 0.535261f, 0.882497f, + internal static readonly float[] distanceBasedWeights_2x2 = new float[] { 0.324652f, 0.535261f, 0.535261f, 0.882497f, 0.535261f, 0.324652f, 0.882497f, 0.535261f, 0.535261f, 0.882497f, 0.324652f, 0.535261f, 0.882497f, 0.535261f, 0.535261f, 0.324652f}; - static internal float[] tapOffsets_2x2 = new float[] { -1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + internal static readonly float[] tapOffsets_2x2 = new float[] { -1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; From 2818e623752de73189fd48f6c0a542541a26569b Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:21 +0000 Subject: [PATCH 31/88] Updated `EyeCausticLUTGen` to work with CoreCRL --- .../Runtime/Material/Eye/EyeCausticLUTGen.cs | 116 +++++++++--------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeCausticLUTGen.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeCausticLUTGen.cs index 04be1a9e516..6b4b3506de2 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeCausticLUTGen.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Eye/EyeCausticLUTGen.cs @@ -7,31 +7,31 @@ internal class EyeCausticLUT { static class Uniforms { - internal static int _OutputWidth = Shader.PropertyToID("_OutputWidth"); - internal static int _OutputHeight = Shader.PropertyToID("_OutputHeight"); - internal static int _OutputDepth = Shader.PropertyToID("_OutputDepth"); - internal static int _OutputSlice = Shader.PropertyToID("_OutputSlice"); - internal static int _UseCorneaSymmetryMirroring = Shader.PropertyToID("_UseCorneaSymmetryMirroring"); - internal static int _ExtraScleraMargin = Shader.PropertyToID("_ExtraScleraMargin"); + internal static readonly int _OutputWidth = Shader.PropertyToID("_OutputWidth"); + internal static readonly int _OutputHeight = Shader.PropertyToID("_OutputHeight"); + internal static readonly int _OutputDepth = Shader.PropertyToID("_OutputDepth"); + internal static readonly int _OutputSlice = Shader.PropertyToID("_OutputSlice"); + internal static readonly int _UseCorneaSymmetryMirroring = Shader.PropertyToID("_UseCorneaSymmetryMirroring"); + internal static readonly int _ExtraScleraMargin = Shader.PropertyToID("_ExtraScleraMargin"); - internal static int _LightWidth = Shader.PropertyToID("_LightWidth"); - internal static int _LightHeight = Shader.PropertyToID("_LightHeight"); - internal static int _LightDistance = Shader.PropertyToID("_LightDistance"); + internal static readonly int _LightWidth = Shader.PropertyToID("_LightWidth"); + internal static readonly int _LightHeight = Shader.PropertyToID("_LightHeight"); + internal static readonly int _LightDistance = Shader.PropertyToID("_LightDistance"); - internal static int _LightLuminousFlux = Shader.PropertyToID("_LightLuminousFlux"); - internal static int _LightGrazingAngleCos = Shader.PropertyToID("_LightGrazingAngleCos"); + internal static readonly int _LightLuminousFlux = Shader.PropertyToID("_LightLuminousFlux"); + internal static readonly int _LightGrazingAngleCos = Shader.PropertyToID("_LightGrazingAngleCos"); - internal static int _CorneaFlatteningFactor = Shader.PropertyToID("_CorneaFlatteningFactor"); - internal static int _CorneaApproxPrimitive = Shader.PropertyToID("_CorneaApproxPrimitive"); - internal static int _CorneaPowerFactor = Shader.PropertyToID("_CorneaPowerFactor"); + internal static readonly int _CorneaFlatteningFactor = Shader.PropertyToID("_CorneaFlatteningFactor"); + internal static readonly int _CorneaApproxPrimitive = Shader.PropertyToID("_CorneaApproxPrimitive"); + internal static readonly int _CorneaPowerFactor = Shader.PropertyToID("_CorneaPowerFactor"); - internal static int _RandomNumbers = Shader.PropertyToID("_RandomNumbers"); + internal static readonly int _RandomNumbers = Shader.PropertyToID("_RandomNumbers"); - internal static int _NumberOfSamplesAccumulated = Shader.PropertyToID("_NumberOfSamplesAccumulated"); + internal static readonly int _NumberOfSamplesAccumulated = Shader.PropertyToID("_NumberOfSamplesAccumulated"); - internal static int _GeneratedSamplesBuffer = Shader.PropertyToID("_GeneratedSamplesBuffer"); + internal static readonly int _GeneratedSamplesBuffer = Shader.PropertyToID("_GeneratedSamplesBuffer"); - internal static int _OutputLutTex = Shader.PropertyToID("_OutputLutTex"); + internal static readonly int _OutputLutTex = Shader.PropertyToID("_OutputLutTex"); public static readonly int _PreIntegratedEyeCaustic = Shader.PropertyToID("_PreIntegratedEyeCaustic"); } @@ -65,17 +65,19 @@ enum CorneaApproximationPrimitive private const int LUT_GEN_NUMBER_OF_DISPATCHES = 512 * 32; private const int LUT_GEN_SAMPLES_PER_SLICE = LUT_GEN_NUMBER_OF_DISPATCHES * LUT_GEN_KERNEL_SIZE; - private static ComputeShader s_Shader; - private static int[] s_Kernels = new int[3]; + private ComputeShader m_Shader; + private int m_SampleCausticKernel; + private int m_CopyToLUTKernel; + private int m_ClearBufferKernel; private void CreateLUTGenResources() { - if (s_Shader == null) + if (m_Shader == null) { - s_Shader = GraphicsSettings.GetRenderPipelineSettings().eyeMaterialCS; - s_Kernels[0] = s_Shader.FindKernel("SampleCaustic"); - s_Kernels[1] = s_Shader.FindKernel("CopyToLUT"); - s_Kernels[2] = s_Shader.FindKernel("ClearBuffer"); + m_Shader = GraphicsSettings.GetRenderPipelineSettings().eyeMaterialCS; + m_SampleCausticKernel = m_Shader.FindKernel("SampleCaustic"); + m_CopyToLUTKernel = m_Shader.FindKernel("CopyToLUT"); + m_ClearBufferKernel = m_Shader.FindKernel("ClearBuffer"); } @@ -110,6 +112,8 @@ private void FreeLUTGenResources() { randomSamplesBuffer.Release(); generatedLutStagingBuffer.Release(); + + m_Shader = null; } private void GenerateLUT() @@ -145,30 +149,30 @@ private void GenerateLUTForSlice(int currentDepthSlice) samples.Dispose(); CommandBuffer cmd = CommandBufferPool.Get(); - int kernel = s_Kernels[0]; + int kernel = m_SampleCausticKernel; - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputWidth, lutWidth); - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputHeight, lutHeight); - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputSlice, currentDepthSlice); - cmd.SetComputeFloatParam(s_Shader, Uniforms._ExtraScleraMargin, lutExtraScleraMargin); - cmd.SetComputeFloatParam(s_Shader, Uniforms._UseCorneaSymmetryMirroring, useCorneaSymmetryMirroring ? 1 : 0); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputWidth, lutWidth); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputHeight, lutHeight); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputSlice, currentDepthSlice); + cmd.SetComputeFloatParam(m_Shader, Uniforms._ExtraScleraMargin, lutExtraScleraMargin); + cmd.SetComputeFloatParam(m_Shader, Uniforms._UseCorneaSymmetryMirroring, useCorneaSymmetryMirroring ? 1 : 0); - cmd.SetComputeFloatParam(s_Shader, Uniforms._LightWidth, lightSize); - cmd.SetComputeFloatParam(s_Shader, Uniforms._LightHeight, lightSize); - cmd.SetComputeFloatParam(s_Shader, Uniforms._LightDistance, lightDistance); + cmd.SetComputeFloatParam(m_Shader, Uniforms._LightWidth, lightSize); + cmd.SetComputeFloatParam(m_Shader, Uniforms._LightHeight, lightSize); + cmd.SetComputeFloatParam(m_Shader, Uniforms._LightDistance, lightDistance); float cosGrazingAngle = Mathf.Cos(Mathf.PI * 0.5f + Mathf.Deg2Rad * lightDipBelowHorizonDegrees); - cmd.SetComputeFloatParam(s_Shader, Uniforms._LightGrazingAngleCos, cosGrazingAngle ); - cmd.SetComputeFloatParam(s_Shader, Uniforms._LightLuminousFlux, lightLuminousFlux ); + cmd.SetComputeFloatParam(m_Shader, Uniforms._LightGrazingAngleCos, cosGrazingAngle ); + cmd.SetComputeFloatParam(m_Shader, Uniforms._LightLuminousFlux, lightLuminousFlux ); - cmd.SetComputeIntParam(s_Shader, Uniforms._CorneaApproxPrimitive, (int)selectedCorneaApproxPrim); - cmd.SetComputeFloatParam(s_Shader, Uniforms._CorneaFlatteningFactor, corneaFlatteningFactor); - cmd.SetComputeFloatParam(s_Shader, Uniforms._CorneaPowerFactor, corneaPowerFactor); + cmd.SetComputeIntParam(m_Shader, Uniforms._CorneaApproxPrimitive, (int)selectedCorneaApproxPrim); + cmd.SetComputeFloatParam(m_Shader, Uniforms._CorneaFlatteningFactor, corneaFlatteningFactor); + cmd.SetComputeFloatParam(m_Shader, Uniforms._CorneaPowerFactor, corneaPowerFactor); - cmd.SetComputeBufferParam(s_Shader, kernel, Uniforms._RandomNumbers, randomSamplesBuffer); + cmd.SetComputeBufferParam(m_Shader, kernel, Uniforms._RandomNumbers, randomSamplesBuffer); - cmd.SetComputeBufferParam(s_Shader, kernel, Uniforms._GeneratedSamplesBuffer, generatedLutStagingBuffer); + cmd.SetComputeBufferParam(m_Shader, kernel, Uniforms._GeneratedSamplesBuffer, generatedLutStagingBuffer); - cmd.DispatchCompute(s_Shader, kernel, LUT_GEN_NUMBER_OF_DISPATCHES, 1, 1); + cmd.DispatchCompute(m_Shader, kernel, LUT_GEN_NUMBER_OF_DISPATCHES, 1, 1); Graphics.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); @@ -179,19 +183,19 @@ void CopyFromStagingToLUT(int currentDepthSlice) int sampleCount = LUT_GEN_SAMPLES_PER_SLICE; CommandBuffer cmd = CommandBufferPool.Get(); - int kernel = s_Kernels[1]; + int kernel = m_CopyToLUTKernel; - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputWidth, lutWidth); - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputHeight, lutHeight); - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputDepth, lutDepth); - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputSlice, currentDepthSlice); - cmd.SetComputeIntParam(s_Shader, Uniforms._NumberOfSamplesAccumulated, sampleCount); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputWidth, lutWidth); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputHeight, lutHeight); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputDepth, lutDepth); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputSlice, currentDepthSlice); + cmd.SetComputeIntParam(m_Shader, Uniforms._NumberOfSamplesAccumulated, sampleCount); - cmd.SetComputeBufferParam(s_Shader, kernel, Uniforms._GeneratedSamplesBuffer, generatedLutStagingBuffer); - cmd.SetComputeTextureParam(s_Shader, kernel, Uniforms._OutputLutTex, generatedLUT); + cmd.SetComputeBufferParam(m_Shader, kernel, Uniforms._GeneratedSamplesBuffer, generatedLutStagingBuffer); + cmd.SetComputeTextureParam(m_Shader, kernel, Uniforms._OutputLutTex, generatedLUT); - cmd.DispatchCompute(s_Shader, kernel, (lutWidth + 7) / 8, + cmd.DispatchCompute(m_Shader, kernel, (lutWidth + 7) / 8, (lutHeight + 7) / 8, 1); Graphics.ExecuteCommandBuffer(cmd); @@ -202,16 +206,16 @@ void CopyFromStagingToLUT(int currentDepthSlice) void ClearStaging() { CommandBuffer cmd = CommandBufferPool.Get(); - int kernel = s_Kernels[2]; + int kernel = m_ClearBufferKernel; int entries = lutWidth * lutHeight; - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputWidth, lutWidth); - cmd.SetComputeIntParam(s_Shader, Uniforms._OutputHeight, lutHeight); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputWidth, lutWidth); + cmd.SetComputeIntParam(m_Shader, Uniforms._OutputHeight, lutHeight); - cmd.SetComputeBufferParam(s_Shader, kernel, Uniforms._GeneratedSamplesBuffer, generatedLutStagingBuffer); + cmd.SetComputeBufferParam(m_Shader, kernel, Uniforms._GeneratedSamplesBuffer, generatedLutStagingBuffer); - cmd.DispatchCompute(s_Shader, kernel, (entries + 63) / 64, 1, 1); + cmd.DispatchCompute(m_Shader, kernel, (entries + 63) / 64, 1, 1); Graphics.ExecuteCommandBuffer(cmd); From 9928e199b2413d7c8618fa03fa97a8eb93e2b1e7 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:22 +0000 Subject: [PATCH 32/88] Updated `Hammersley` to work with CoreCLR --- .../Runtime/ShaderLibrary/Sampling/Hammersley.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/ShaderLibrary/Sampling/Hammersley.cs b/Packages/com.unity.render-pipelines.core/Runtime/ShaderLibrary/Sampling/Hammersley.cs index 5c04c2d5722..eaaf94f2653 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/ShaderLibrary/Sampling/Hammersley.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/ShaderLibrary/Sampling/Hammersley.cs @@ -7,7 +7,7 @@ namespace UnityEngine.Rendering /// public static class Hammersley { - static float[] k_Hammersley2dSeq16 = { + static readonly float[] k_Hammersley2dSeq16 = { 0.00000000f, 0.00000000f, 0.0f, 0.0f, 0.06250000f, 0.50000000f, 0.0f, 0.0f, 0.12500000f, 0.25000000f, 0.0f, 0.0f, @@ -26,7 +26,7 @@ public static class Hammersley 0.93750000f, 0.93750000f, 0.0f, 0.0f, }; - static float[] k_Hammersley2dSeq32 = { + static readonly float[] k_Hammersley2dSeq32 = { 0.00000000f, 0.00000000f, 0.0f, 0.0f, 0.03125000f, 0.50000000f, 0.0f, 0.0f, 0.06250000f, 0.25000000f, 0.0f, 0.0f, @@ -61,7 +61,7 @@ public static class Hammersley 0.96875000f, 0.96875000f, 0.0f, 0.0f, }; - static float[] k_Hammersley2dSeq64 = { + static readonly float[] k_Hammersley2dSeq64 = { 0.00000000f, 0.00000000f, 0.0f, 0.0f, 0.01562500f, 0.50000000f, 0.0f, 0.0f, 0.03125000f, 0.25000000f, 0.0f, 0.0f, @@ -128,7 +128,7 @@ public static class Hammersley 0.98437500f, 0.98437500f, 0.0f, 0.0f, }; - static float[] k_Hammersley2dSeq256 = { + static readonly float[] k_Hammersley2dSeq256 = { 0.00000000f, 0.00000000f, 0.0f, 0.0f, 0.00390625f, 0.50000000f, 0.0f, 0.0f, 0.00781250f, 0.25000000f, 0.0f, 0.0f, @@ -423,7 +423,7 @@ unsafe struct Hammersley2dSeq256 /// /// Initializing Hammersley constants. /// - unsafe public static void Initialize() + public static unsafe void Initialize() { Hammersley2dSeq16 hammersley2DSeq16 = new Hammersley2dSeq16(); Hammersley2dSeq32 hammersley2DSeq32 = new Hammersley2dSeq32(); From 754eeb1938fe3ff96d2703e0c6bf5b85cf481779 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:22 +0000 Subject: [PATCH 33/88] Updated `Decal` and `DecalSystem` to work with CoreCLR --- .../Runtime/Lighting/LightLoop/LightLoop.cs | 11 +- .../Runtime/Material/Decal/Decal.cs | 14 +- .../Runtime/Material/Decal/DecalSystem.cs | 134 ++++++++++-------- .../RenderPipeline/HDRenderPipeline.Debug.cs | 4 +- .../HDRenderPipeline.LightLoop.cs | 2 +- .../HDRenderPipeline.Prepass.cs | 6 +- .../HDRenderPipeline.RenderGraph.cs | 2 +- .../RenderPipeline/HDRenderPipeline.cs | 18 +-- .../Water/HDRenderPipeline.WaterSystem.cs | 2 +- 9 files changed, 107 insertions(+), 86 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs index 35daf905b17..041c5432078 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs @@ -1719,7 +1719,7 @@ bool PrepareLightsForGPU(ScriptableRenderContext renderContext, m_DebugSelectedLightShadowIndex = -1; m_DebugSelectedLightShadowCount = 0; - int decalDatasCount = Math.Min(DecalSystem.m_DecalDatasCount, m_MaxDecalsOnScreen); + int decalDatasCount = Math.Min(DecalSystem.instance.DecalDatasCount, m_MaxDecalsOnScreen); // We must clear the shadow requests before checking if they are any visible light because we would have requests from the last frame executed in the case where we don't see any lights m_ShadowManager.Clear(); @@ -1768,11 +1768,14 @@ bool PrepareLightsForGPU(ScriptableRenderContext renderContext, if (decalDatasCount > 0) { + var bounds = DecalSystem.instance.Bounds; + var lightVolumes = DecalSystem.instance.LightVolumes; + for (int i = 0; i < decalDatasCount; i++) { for (int viewIndex = 0; viewIndex < hdCamera.viewCount; ++viewIndex) { - m_GpuLightsBuilder.AddLightBounds(viewIndex, DecalSystem.m_Bounds[i], DecalSystem.m_LightVolumes[i]); + m_GpuLightsBuilder.AddLightBounds(viewIndex, in bounds[i], in lightVolumes[i]); } } } @@ -1953,7 +1956,7 @@ unsafe void UpdateShaderVariablesGlobalLightLoop(ref ShaderVariablesGlobal cb, H cb._WorldAreaLightCount = (uint)(m_WorldLights.rectLightCount + m_WorldLights.lineLightCount + m_WorldLights.discLightCount); cb._WorldEnvLightCount = (uint)m_WorldLights.envLightCount; - cb._DecalCount = (uint)DecalSystem.m_DecalDatasCount; + cb._DecalCount = (uint)DecalSystem.instance.DecalDatasCount; HDAdditionalLightData sunLightData = GetHDAdditionalLightData(m_CurrentSunLight); bool sunLightShadow = sunLightData != null && m_CurrentShadowSortedSunLightIndex >= 0; cb._DirectionalShadowIndex = sunLightShadow ? m_CurrentShadowSortedSunLightIndex : -1; @@ -1987,7 +1990,7 @@ void PushLightDataGlobalParams(CommandBuffer cmd) m_LightLoopLightData.directionalLightData.SetData(m_GpuLightsBuilder.directionalLights, 0, 0, m_GpuLightsBuilder.directionalLightCount); m_LightLoopLightData.lightData.SetData(m_GpuLightsBuilder.lights, 0, 0, m_GpuLightsBuilder.lightsCount); m_LightLoopLightData.envLightData.SetData(m_lightList.envLights); - m_LightLoopLightData.decalData.SetData(DecalSystem.m_DecalDatas, 0, 0, Math.Min(DecalSystem.m_DecalDatasCount, m_MaxDecalsOnScreen)); // don't add more than the size of the buffer + m_LightLoopLightData.decalData.SetData(DecalSystem.instance.DecalDatas, 0, 0, Math.Min(DecalSystem.instance.DecalDatasCount, m_MaxDecalsOnScreen)); // don't add more than the size of the buffer for (int viewId = 0; viewId < m_GpuLightsBuilder.lightsPerViewCount; ++viewId) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.cs index 92d2a412d2e..b629df45133 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.cs @@ -41,18 +41,12 @@ public enum DecalAtlasTextureType //----------------------------------------------------------------------------- // should this be combined into common class shared with Lit.cs??? - static public int GetMaterialDBufferCount() { return (int)DBufferMaterial.Count; } + public static int GetMaterialDBufferCount() => (int)DBufferMaterial.Count; - static GraphicsFormat[] m_RTFormat = { GraphicsFormat.R8G8B8A8_SRGB, GraphicsFormat.R8G8B8A8_UNorm, GraphicsFormat.R8G8B8A8_UNorm, GraphicsFormat.R8G8_UNorm }; - static GraphicsFormat[] m_RTFormatHP = { GraphicsFormat.R8G8B8A8_SRGB, GraphicsFormat.R16G16B16A16_SFloat, GraphicsFormat.R8G8B8A8_UNorm, GraphicsFormat.R8G8_UNorm }; + const int k_RTFormatMask = (int)GraphicsFormat.R8G8B8A8_SRGB << 0 | (int)GraphicsFormat.R8G8B8A8_UNorm << 8 | (int)GraphicsFormat.R8G8B8A8_UNorm << 16 | (int)GraphicsFormat.R8G8_UNorm << 24; + const int k_RTFormatMaskHP = (int)GraphicsFormat.R8G8B8A8_SRGB << 0 | (int)GraphicsFormat.R16G16B16A16_SFloat << 8 | (int)GraphicsFormat.R8G8B8A8_UNorm << 16 | (int)GraphicsFormat.R8G8_UNorm << 24; - static public void GetMaterialDBufferDescription(out GraphicsFormat[] RTFormat) - { - HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline; - bool hp = hdPipeline.currentPlatformRenderPipelineSettings.supportSurfaceGradient && - hdPipeline.currentPlatformRenderPipelineSettings.decalNormalBufferHP; - RTFormat = hp ? m_RTFormatHP : m_RTFormat; - } + public static GraphicsFormat GetMaterialDBufferDescription(int index, bool useHighPrecision) => (GraphicsFormat)(0xFF & (useHighPrecision ? k_RTFormatMaskHP : k_RTFormatMask ) >> (index << 3)); } // normal to world only uses 3x3 for actual matrix so some data is packed in the unused space diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs index 4ee2c610e39..31c49a565aa 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs @@ -42,7 +42,7 @@ static class DecalShaderIds public class CullResult : IDisposable { - int m_NumResults; + int m_NumResults; public int numResults { @@ -190,7 +190,6 @@ void Dispose(bool disposing) } public const int kInvalidIndex = -1; - public static readonly EntityId kNullMaterialIndex = EntityId.None; public class DecalHandle { public DecalHandle(int index, EntityId materialID) @@ -212,16 +211,8 @@ public static bool IsValid(DecalHandle handle) public int m_Index; // identifies decal within the set } - static DecalSystem m_Instance; - static public DecalSystem instance - { - get - { - if (m_Instance == null) - m_Instance = new DecalSystem(); - return m_Instance; - } - } + static DecalSystem s_Instance; + public static DecalSystem instance => s_Instance ??= new DecalSystem(); private const int kDefaultDrawDistance = 1000; public int DrawDistance @@ -289,10 +280,10 @@ public Camera CurrentCamera private const int kDrawIndexedBatchSize = 250; // cube mesh bounds for decal - static Vector4 kMin = new Vector4(-0.5f, -0.5f, -0.5f, 1.0f); - static Vector4 kMax = new Vector4(0.5f, 0.5f, 0.5f, 1.0f); + static readonly Vector4 kMin = new Vector4(-0.5f, -0.5f, -0.5f, 1.0f); + static readonly Vector4 kMax = new Vector4(0.5f, 0.5f, 0.5f, 1.0f); - static public Mesh m_DecalMesh = null; + Mesh m_DecalMesh = null; // These bit flags allow one to have cluster(s) of decals with different culling algorithm. // Both types of clusters are created if raytracing is enabled for SSR/SSGI. @@ -306,25 +297,36 @@ public enum DecalCullingMode WorldspaceBasedCulling = 1 << 1 } - static public DecalCullingMode m_CullingMode = DecalCullingMode.ViewspaceBasedCulling; + DecalCullingMode m_CullingMode = DecalCullingMode.ViewspaceBasedCulling; + + public DecalCullingMode CullingMode + { + get => m_CullingMode; + set => m_CullingMode = value; + } // clustered draw data - static public DecalData[] m_DecalDatas = new DecalData[kDecalBlockSize]; - static public SFiniteLightBound[] m_Bounds = new SFiniteLightBound[kDecalBlockSize]; - static public LightVolumeData[] m_LightVolumes = new LightVolumeData[kDecalBlockSize]; - static public TextureScaleBias[] m_DiffuseTextureScaleBias = new TextureScaleBias[kDecalBlockSize]; - static public TextureScaleBias[] m_NormalTextureScaleBias = new TextureScaleBias[kDecalBlockSize]; - static public TextureScaleBias[] m_MaskTextureScaleBias = new TextureScaleBias[kDecalBlockSize]; - static public Vector4[] m_BaseColor = new Vector4[kDecalBlockSize]; + DecalData[] m_DecalDatas = new DecalData[kDecalBlockSize]; + SFiniteLightBound[] m_Bounds = new SFiniteLightBound[kDecalBlockSize]; + LightVolumeData[] m_LightVolumes = new LightVolumeData[kDecalBlockSize]; + TextureScaleBias[] m_DiffuseTextureScaleBias = new TextureScaleBias[kDecalBlockSize]; + TextureScaleBias[] m_NormalTextureScaleBias = new TextureScaleBias[kDecalBlockSize]; + TextureScaleBias[] m_MaskTextureScaleBias = new TextureScaleBias[kDecalBlockSize]; + Vector4[] m_BaseColor = new Vector4[kDecalBlockSize]; + + public DecalData[] DecalDatas => m_DecalDatas; + public SFiniteLightBound[] Bounds => m_Bounds; + public LightVolumeData[] LightVolumes => m_LightVolumes; // Clustered decal world space info -- useful when m_CullingMode is set to WorldspaceBasedCulling // This data is cached and can be queried for algorithms doing their own clustering (e.g. path tracing). - static public Vector3[] m_DecalDatasWSPositions = new Vector3[kDecalBlockSize]; - static public Vector3[] m_DecalDatasWSRanges = new Vector3[kDecalBlockSize]; + Vector3[] m_DecalDatasWSPositions = new Vector3[kDecalBlockSize]; + Vector3[] m_DecalDatasWSRanges = new Vector3[kDecalBlockSize]; - static public int m_DecalDatasCount = 0; + int m_DecalDatasCount = 0; + public int DecalDatasCount => m_DecalDatasCount; - static public float[] m_BoundingDistances = new float[1]; + float[] m_BoundingDistances = new float[1]; private Dictionary m_DecalSets = new Dictionary(); private List m_DecalSetsRenderList = new List(); // list of visible decalsets sorted by material draw order @@ -332,11 +334,11 @@ public enum DecalCullingMode // current camera private Camera m_Camera; - static public int m_DecalsVisibleThisFrame = 0; + int m_DecalsVisibleThisFrame = 0; private Texture2DAtlas m_Atlas = null; - public bool m_AllocationSuccess = true; - public bool m_PrevAllocationSuccess = true; + bool m_AllocationSuccess = true; + bool m_PrevAllocationSuccess = true; private int m_GlobalDrawDistance = kDefaultDrawDistance; @@ -345,10 +347,10 @@ public enum DecalCullingMode private bool m_ShaderGraphSaveRequested = false; #endif - static public int GetDecalCount(HDCamera hdCamera) + public static int GetDecalCount(HDCamera hdCamera) { if ((hdCamera.IsPathTracingEnabled() || hdCamera.IsRayTracingEnabled()) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) - return m_DecalDatasCount; + return instance.m_DecalDatasCount; return 0; } @@ -358,7 +360,8 @@ public Texture2DAtlas Atlas { if (m_Atlas == null) { - m_Atlas = new Texture2DAtlas(HDUtils.hdrpSettings.decalSettings.atlasWidth, HDUtils.hdrpSettings.decalSettings.atlasHeight, GraphicsFormat.R8G8B8A8_UNorm, name: "DecalSystemAtlas"); + var decalSettings = HDUtils.hdrpSettings.decalSettings; + m_Atlas = new Texture2DAtlas(decalSettings.atlasWidth, decalSettings.atlasHeight, GraphicsFormat.R8G8B8A8_UNorm, name: "DecalSystemAtlas"); } return m_Atlas; } @@ -477,7 +480,7 @@ public bool UpdateTexture(Decal.DecalAtlasTextureType type) private List m_ShaderGraphList = new List(); private List m_ShaderGraphVertexCount = new List(); - static public bool IsHDRenderPipelineDecal(Shader shader) + public static bool IsHDRenderPipelineDecal(Shader shader) { // Warning: accessing Shader.name generate 48B of garbage at each frame, we want to avoid that in the future return shader.name == "HDRP/Decal"; @@ -486,13 +489,13 @@ static public bool IsHDRenderPipelineDecal(Shader shader) const string kIdentifyHDRPDecal = "_Unity_Identify_HDRP_Decal"; // Non alloc version of IsHDRenderPipelineDecal (Slower but does not generate garbage) - static public bool IsHDRenderPipelineDecal(Material material) + public static bool IsHDRenderPipelineDecal(Material material) { // Check if the material has a marker _Unity_Identify_HDRP_Decal return material.HasProperty(kIdentifyHDRPDecal); } - static public bool IsDecalMaterial(Material material) + public static bool IsDecalMaterial(Material material) { // Check if the material has at least one pass from the decal.shader / Shader Graph (shader stripping can remove one or more passes) foreach (var passName in s_MaterialDecalPassNames) @@ -833,12 +836,12 @@ public void BeginCull(CullRequest.Set cullRequest) ResolveUpdateJob(); // let the culling group code do some of the heavy lifting for global draw distance - m_BoundingDistances[0] = DecalSystem.instance.DrawDistance; + instance.m_BoundingDistances[0] = instance.DrawDistance; m_NumResults = 0; var cullingGroup = CullingGroupManager.instance.Alloc(); cullingGroup.targetCamera = instance.CurrentCamera; cullingGroup.SetDistanceReferencePoint(cullingGroup.targetCamera.transform.position); - cullingGroup.SetBoundingDistances(m_BoundingDistances); + cullingGroup.SetBoundingDistances(instance.m_BoundingDistances); cullingGroup.SetBoundingSpheres(m_CachedBoundingSpheres); cullingGroup.SetBoundingSphereCount(m_DecalsCount); @@ -870,6 +873,9 @@ private void GetDecalVolumeDataAndBound(Matrix4x4 decalToWorld, Matrix4x4 worldT var influenceForwardVS = worldToView.MultiplyVector(influenceZ / influenceExtents.z); var influencePositionVS = worldToView.MultiplyPoint(pos); // place the mesh pivot in the center + var m_DecalDatasCount = instance.m_DecalDatasCount; + + var m_Bounds = instance.m_Bounds; m_Bounds[m_DecalDatasCount].center = influencePositionVS; m_Bounds[m_DecalDatasCount].boxAxisX = influenceRightVS * influenceExtents.x; m_Bounds[m_DecalDatasCount].boxAxisY = influenceUpVS * influenceExtents.y; @@ -880,6 +886,7 @@ private void GetDecalVolumeDataAndBound(Matrix4x4 decalToWorld, Matrix4x4 worldT // The culling system culls pixels that are further // than a threshold to the box influence extents. // So we use an arbitrary threshold here (k_BoxCullingExtentOffset) + var m_LightVolumes = instance.m_LightVolumes; m_LightVolumes[m_DecalDatasCount].lightCategory = (uint)LightCategory.Decal; m_LightVolumes[m_DecalDatasCount].lightVolume = (uint)LightVolumeType.Box; m_LightVolumes[m_DecalDatasCount].featureFlags = (uint)LightFeatureFlags.Env; @@ -927,19 +934,19 @@ private Matrix4x4 GetEncodedNormalToWorldMatrix(Matrix4x4 original, int DecalInd return result; } - public void CreateDrawData(IntScalableSetting transparentTextureResolution) + public void CreateDrawData(IntScalableSetting transparentTextureResolution, DecalSystem decalSystem) { int maxTextureSize = 0; NativeArray cachedDecalToWorld = m_DecalToWorlds.Reinterpret(); NativeArray cachedNormalToWorld = m_NormalToWorlds.Reinterpret(); - Vector3 cameraPos = instance.CurrentCamera.transform.position; - var camera = instance.CurrentCamera; + var camera = decalSystem.CurrentCamera; + Vector3 cameraPos = camera.transform.position; Matrix4x4 worldToView = HDRenderPipeline.WorldToCamera(camera); /* Prepare data for the DBuffer drawing */ - if ((DecalSystem.m_CullingMode & DecalCullingMode.ViewspaceBasedCulling) != 0) + if ((decalSystem.m_CullingMode & DecalCullingMode.ViewspaceBasedCulling) != 0) { int cullingMask = camera.cullingMask; ulong sceneCullingMask = HDUtils.GetSceneCullingMaskFromCamera(camera); @@ -991,9 +998,17 @@ public void CreateDrawData(IntScalableSetting transparentTextureResolution) /* Prepare data for clustered decals */ // Depending on the culling mode, we consider the decals that survived culling or all of them. - bool useWorldspaceCluster = (DecalSystem.m_CullingMode & DecalCullingMode.WorldspaceBasedCulling) != 0; + bool useWorldspaceCluster = (decalSystem.m_CullingMode & DecalCullingMode.WorldspaceBasedCulling) != 0; int decalsToConsider = useWorldspaceCluster ? m_DecalsCount : m_NumResults; + var m_DecalDatas = decalSystem.m_DecalDatas; + var m_DiffuseTextureScaleBias = decalSystem.m_DiffuseTextureScaleBias; + var m_NormalTextureScaleBias = decalSystem.m_NormalTextureScaleBias; + var m_MaskTextureScaleBias = decalSystem.m_MaskTextureScaleBias; + var m_DecalDatasWSPositions = decalSystem.m_DecalDatasWSPositions; + var m_DecalDatasWSRanges = decalSystem.m_DecalDatasWSRanges; + ref var m_DecalDatasCount = ref decalSystem.m_DecalDatasCount; + bool anyClusteredDecalsPresent = false; for (int resultIndex = 0; resultIndex < decalsToConsider; resultIndex++) { @@ -1041,7 +1056,7 @@ public void CreateDrawData(IntScalableSetting transparentTextureResolution) // only add if any projectors in this decal set will be clustered, doesn't actually allocate textures in the atlas yet, this is because we want all the textures in the list so we can optimize the packing if (anyClusteredDecalsPresent) { - AddToTextureList(ref instance.m_TextureList); + AddToTextureList(ref decalSystem.m_TextureList); if (!m_IsHDRenderPipelineDecal) { ShaderGraphData data; @@ -1052,7 +1067,7 @@ public void CreateDrawData(IntScalableSetting transparentTextureResolution) data.passIndex = m_cachedAtlasProjectorPassValue; data.updateTexture = m_UpdateShaderGraphTexture; data.propertyBlock = m_PropertyBlock; - instance.m_ShaderGraphList.Add(data); + decalSystem.m_ShaderGraphList.Add(data); if (m_MaxShaderGraphTextureSize != maxTextureSize) { @@ -1093,7 +1108,7 @@ public void AddToTextureList(ref List textureList) } } - public void RenderIntoDBuffer(CommandBuffer cmd) + public void RenderIntoDBuffer(Mesh decalMesh, CommandBuffer cmd) { if (m_Material == null || m_cachedProjectorPassValue == -1 || (m_NumResults == 0)) return; @@ -1105,7 +1120,7 @@ public void RenderIntoDBuffer(CommandBuffer cmd) { m_PropertyBlock.SetMatrixArray(HDShaderIDs._NormalToWorldID, m_NormalToWorld[batchIndex]); m_PropertyBlock.SetFloatArray(HDMaterialProperties.kDecalLayerMaskFromDecal, m_DecalLayerMasks[batchIndex]); - cmd.DrawMeshInstanced(m_DecalMesh, 0, m_Material, m_cachedProjectorPassValue, m_DecalToWorld[batchIndex], kDrawIndexedBatchSize, m_PropertyBlock); + cmd.DrawMeshInstanced(decalMesh, 0, m_Material, m_cachedProjectorPassValue, m_DecalToWorld[batchIndex], kDrawIndexedBatchSize, m_PropertyBlock); totalToDraw -= kDrawIndexedBatchSize; } @@ -1113,11 +1128,11 @@ public void RenderIntoDBuffer(CommandBuffer cmd) { m_PropertyBlock.SetMatrixArray(HDShaderIDs._NormalToWorldID, m_NormalToWorld[batchIndex]); m_PropertyBlock.SetFloatArray(HDMaterialProperties.kDecalLayerMaskFromDecal, m_DecalLayerMasks[batchIndex]); - cmd.DrawMeshInstanced(m_DecalMesh, 0, m_Material, m_cachedProjectorPassValue, m_DecalToWorld[batchIndex], totalToDraw, m_PropertyBlock); + cmd.DrawMeshInstanced(decalMesh, 0, m_Material, m_cachedProjectorPassValue, m_DecalToWorld[batchIndex], totalToDraw, m_PropertyBlock); } } - public void RenderForwardEmissive(CommandBuffer cmd) + public void RenderForwardEmissive(Mesh decalMesh, CommandBuffer cmd) { if (m_Material == null || m_cachedProjectorEmissivePassValue == -1 || m_NumResults == 0) return; @@ -1129,7 +1144,7 @@ public void RenderForwardEmissive(CommandBuffer cmd) { m_PropertyBlock.SetMatrixArray(HDShaderIDs._NormalToWorldID, m_NormalToWorld[batchIndex]); m_PropertyBlock.SetFloatArray(HDMaterialProperties.kDecalLayerMaskFromDecal, m_DecalLayerMasks[batchIndex]); - cmd.DrawMeshInstanced(m_DecalMesh, 0, m_Material, m_cachedProjectorEmissivePassValue, m_DecalToWorld[batchIndex], kDrawIndexedBatchSize, m_PropertyBlock); + cmd.DrawMeshInstanced(decalMesh, 0, m_Material, m_cachedProjectorEmissivePassValue, m_DecalToWorld[batchIndex], kDrawIndexedBatchSize, m_PropertyBlock); totalToDraw -= kDrawIndexedBatchSize; } @@ -1137,7 +1152,7 @@ public void RenderForwardEmissive(CommandBuffer cmd) { m_PropertyBlock.SetMatrixArray(HDShaderIDs._NormalToWorldID, m_NormalToWorld[batchIndex]); m_PropertyBlock.SetFloatArray(HDMaterialProperties.kDecalLayerMaskFromDecal, m_DecalLayerMasks[batchIndex]); - cmd.DrawMeshInstanced(m_DecalMesh, 0, m_Material, m_cachedProjectorEmissivePassValue, m_DecalToWorld[batchIndex], totalToDraw, m_PropertyBlock); + cmd.DrawMeshInstanced(decalMesh, 0, m_Material, m_cachedProjectorEmissivePassValue, m_DecalToWorld[batchIndex], totalToDraw, m_PropertyBlock); } } @@ -1278,10 +1293,10 @@ public DecalHandle AddDecal(DecalProjector decalProjector) var material = decalProjector.material; DecalSet decalSet = null; - EntityId key = material != null ? material.GetEntityId() : kNullMaterialIndex; + EntityId key = material != null ? material.GetEntityId() : EntityId.None; if (!m_DecalSets.TryGetValue(key, out decalSet)) { - SetupMipStreamingSettings(material, true); + SetupMipStreamingSettings(material, true); decalSet = new DecalSet(material); m_DecalSets.Add(key, decalSet); } @@ -1384,7 +1399,7 @@ public void RenderIntoDBuffer(CommandBuffer cmd) foreach (var decalSet in m_DecalSetsRenderList) { - decalSet.RenderIntoDBuffer(cmd); + decalSet.RenderIntoDBuffer(m_DecalMesh, cmd); } } @@ -1395,7 +1410,7 @@ public void RenderForwardEmissive(CommandBuffer cmd) foreach (var decalSet in m_DecalSetsRenderList) { - decalSet.RenderForwardEmissive(cmd); + decalSet.RenderForwardEmissive(m_DecalMesh, cmd); } } @@ -1661,7 +1676,7 @@ public void CreateDrawData() IntScalableSetting textureResolutionSetting = transparentTextureResolution; foreach (var decalSet in m_DecalSetsRenderList) - decalSet.CreateDrawData(textureResolutionSetting); + decalSet.CreateDrawData(textureResolutionSetting, this); } public void Cleanup() @@ -1706,6 +1721,13 @@ public void UpdateTransparentShaderGraphs() { m_ShaderGraphSaveRequested = true; } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_Instance?.Cleanup(); + s_Instance = null; + } #endif } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs index 3d315a648ee..98b3eb6ec38 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Debug.cs @@ -1646,7 +1646,7 @@ TextureHandle RenderDebugViewMaterial(RenderGraph renderGraph, CullingResults cu #endif passData.outputDepth = depth; builder.SetRenderAttachmentDepth(depth, AccessFlags.ReadWrite); - + builder.AllowGlobalStateModification(true); // When rendering debug material we shouldn't rely on a depth prepass for optimizing the alpha clip test. As it is control on the material inspector side @@ -1657,7 +1657,7 @@ TextureHandle RenderDebugViewMaterial(RenderGraph renderGraph, CullingResults cu passData.transparentRendererList = renderGraph.CreateRendererList(CreateTransparentRendererListDesc(cull, hdCamera.camera, m_AllTransparentPassNames, rendererConfiguration: m_CurrentRendererConfigurationBakedLighting, stateBlock: m_DepthStateNoWrite)); builder.UseRendererList(passData.transparentRendererList); - passData.decalsEnabled = (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) && (DecalSystem.m_DecalDatasCount > 0); + passData.decalsEnabled = (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) && (DecalSystem.instance.DecalDatasCount > 0); if (m_CurrentDebugDisplaySettings.data.lightingDebugSettings.tileClusterDebug == TileClusterDebug.Cluster) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 4909219fe7f..169b19e21f9 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -450,7 +450,7 @@ unsafe void PrepareBuildGPULightListPassData( } } - var decalDatasCount = Math.Min(DecalSystem.m_DecalDatasCount, m_MaxDecalsOnScreen); + var decalDatasCount = Math.Min(DecalSystem.instance.DecalDatasCount, m_MaxDecalsOnScreen); cb.g_iNrVisibLights = totalLightCount; cb.g_screenSize = hdCamera.screenSize; // TODO remove and use global one. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs index 6d5e91b3c9d..ec351667d45 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs @@ -1325,8 +1325,8 @@ internal struct DBufferOutput void SetupDBufferTargets(RenderGraph renderGraph, bool use4RTs, ref PrepassOutput output, IUnsafeRenderGraphBuilder builder, bool canReadBoundDepthBuffer) { - GraphicsFormat[] rtFormat; - Decal.GetMaterialDBufferDescription(out rtFormat); + bool useHighPrecision = currentPlatformRenderPipelineSettings.supportSurfaceGradient && + currentPlatformRenderPipelineSettings.decalNormalBufferHP; output.dbuffer.dBufferCount = use4RTs ? 4 : 3; // for alpha compositing, color is cleared to 0, alpha to 1 @@ -1334,7 +1334,7 @@ void SetupDBufferTargets(RenderGraph renderGraph, bool use4RTs, ref PrepassOutpu for (int dbufferIndex = 0; dbufferIndex < output.dbuffer.dBufferCount; ++dbufferIndex) { output.dbuffer.mrt[dbufferIndex] = renderGraph.CreateTexture( - new TextureDesc(Vector2.one, true, true) { format = rtFormat[dbufferIndex], name = s_DBufferNames[dbufferIndex], clearBuffer = true, clearColor = s_DBufferClearColors[dbufferIndex] }); + new TextureDesc(Vector2.one, true, true) { format = Decal.GetMaterialDBufferDescription(dbufferIndex, useHighPrecision), name = s_DBufferNames[dbufferIndex], clearBuffer = true, clearColor = s_DBufferClearColors[dbufferIndex] }); builder.SetRenderAttachment(output.dbuffer.mrt[dbufferIndex], dbufferIndex); } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs index 66cc7b9f0a2..abf522bd605 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs @@ -1282,7 +1282,7 @@ void RenderForwardTransparent(RenderGraph renderGraph, // enable d-buffer flag value is being interpreted more like enable decals in general now that we have clustered // decal datas count is 0 if no decals affect transparency - passData.decalsEnabled = (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) && (DecalSystem.m_DecalDatasCount > 0); + passData.decalsEnabled = (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) && (DecalSystem.instance.DecalDatasCount > 0); passData.renderMotionVecForTransparent = NeedMotionVectorForTransparent(hdCamera.frameSettings); passData.colorMaskTransparentVel = colorMaskTransparentVel; passData.volumetricLighting = volumetricLighting; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index d54b2a27449..c69ee655b9e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2767,18 +2767,20 @@ AOVRequestData aovRequest { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DBufferPrepareDrawData))) { + DecalSystem decalSystem = DecalSystem.instance; + // TODO: update singleton with DecalCullResults - DecalSystem.instance.CurrentCamera = hdCamera.camera; // Singletons are extremely dangerous... + decalSystem.CurrentCamera = hdCamera.camera; // Singletons are extremely dangerous... if (hdCamera.IsPathTracingEnabled()) - DecalSystem.m_CullingMode = DecalSystem.DecalCullingMode.WorldspaceBasedCulling; + decalSystem.CullingMode = DecalSystem.DecalCullingMode.WorldspaceBasedCulling; else if (hdCamera.IsRayTracingEnabled()) - DecalSystem.m_CullingMode = DecalSystem.DecalCullingMode.WorldspaceBasedCulling | DecalSystem.DecalCullingMode.ViewspaceBasedCulling; + decalSystem.CullingMode = DecalSystem.DecalCullingMode.WorldspaceBasedCulling | DecalSystem.DecalCullingMode.ViewspaceBasedCulling; else - DecalSystem.m_CullingMode = DecalSystem.DecalCullingMode.ViewspaceBasedCulling; - DecalSystem.instance.LoadCullResults(decalCullingResults); - DecalSystem.instance.UpdateCachedMaterialData(); // textures, alpha or fade distances could've changed - DecalSystem.instance.CreateDrawData(); // prepare data is separate from draw - DecalSystem.instance.UpdateTextureAtlas(cmd); // as this is only used for transparent pass, would've been nice not to have to do this if no transparent renderers are visible, needs to happen after CreateDrawData + decalSystem.CullingMode = DecalSystem.DecalCullingMode.ViewspaceBasedCulling; + decalSystem.LoadCullResults(decalCullingResults); + decalSystem.UpdateCachedMaterialData(); // textures, alpha or fade distances could've changed + decalSystem.CreateDrawData(); // prepare data is separate from draw + decalSystem.UpdateTextureAtlas(cmd); // as this is only used for transparent pass, would've been nice not to have to do this if no transparent renderers are visible, needs to happen after CreateDrawData } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs index 52af4c5307e..d0161ccbcc6 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs @@ -848,7 +848,7 @@ void PrepareWaterGBufferData(IUnsafeRenderGraphBuilder builder, HDCamera hdCamer PrepareWaterRenderingData(passData, hdCamera); // Buffers - passData.decalsEnabled = (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) && (DecalSystem.m_DecalDatasCount > 0); + passData.decalsEnabled = (hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals)) && (DecalSystem.instance.DecalDatasCount > 0); passData.layeredOffsetsBuffer = lightLists.perVoxelOffset; builder.UseBuffer(passData.layeredOffsetsBuffer, AccessFlags.Read); passData.logBaseBuffer = lightLists.perTileLogBaseTweak; From eb1e01cd8cd48511504f680628d2b748c0ad05cf Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:22 +0000 Subject: [PATCH 34/88] Updated `CompositionManager` and `CompositorCameraRegistery` to work with CoreCLR --- .../Runtime/Compositor/CompositionManager.cs | 68 +++++++++++-------- .../Compositor/CompositorCameraRegistry.cs | 51 ++++++++------ 2 files changed, 71 insertions(+), 48 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs index c753884ee8b..726401eb864 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionManager.cs @@ -106,10 +106,7 @@ public bool enableOutput public Shader shader { get => m_Shader; - set - { - m_Shader = value; - } + set => m_Shader = value; } [SerializeField] Shader m_Shader; @@ -145,11 +142,15 @@ public bool shaderPropertiesAreDirty { set { +#if UNITY_EDITOR m_ShaderPropertiesAreDirty = true; +#endif } } +#if UNITY_EDITOR internal bool m_ShaderPropertiesAreDirty = false; +#endif internal Matrix4x4 m_ViewProjMatrix; internal Matrix4x4 m_ViewProjMatrixFlipped; @@ -158,10 +159,7 @@ public bool shaderPropertiesAreDirty ShaderVariablesGlobal m_ShaderVariablesGlobalCB = new ShaderVariablesGlobal(); - int m_RecorderTempRT = Shader.PropertyToID("TempRecorder"); - - // Built-in Color.black has an alpha of 1, so defien here a fully transparent black - static Color s_TransparentBlack = new Color(0, 0, 0, 0); + static readonly int _RecorderTempRT = Shader.PropertyToID("TempRecorder"); #region Validation public bool ValidateLayerListOrder(int oldIndex, int newIndex) @@ -463,7 +461,7 @@ public void OnDisable() enableOutput = false; } - static string s_CompositorGlobalVolumeName = "__Internal_Global_Composition_Volume"; + const string k_CompositorGlobalVolumeName = "__Internal_Global_Composition_Volume"; // Setup a global volume used for chroma keying, alpha injection etc void SetupGlobalCompositorVolume() @@ -472,7 +470,7 @@ void SetupGlobalCompositorVolume() // Instead of using one volume per layer/camera, we setup one global volume and we store the data in the camera // This way the compositor has to use only one layer/volume for N cameras (instead of N). - m_CompositorGameObject = new GameObject(s_CompositorGlobalVolumeName) { hideFlags = HideFlags.HideAndDontSave }; + m_CompositorGameObject = new GameObject(k_CompositorGlobalVolumeName) { hideFlags = HideFlags.HideAndDontSave }; Volume globalPPVolume = m_CompositorGameObject.AddComponent(); globalPPVolume.gameObject.layer = 31; AlphaInjection injectAlphaNode = globalPPVolume.profile.Add(); @@ -497,7 +495,7 @@ public void UpdateLayerSetup() SetupLayerPriorities(); } - static HDRenderPipelineAsset m_CurrentAsset; + HDRenderPipelineAsset m_CurrentAsset; // LateUpdate is called once per frame void LateUpdate() @@ -772,8 +770,7 @@ void ResizeCallback(ScriptableRenderContext cntx, List cameras) void InternalRender(ScriptableRenderContext cntx) { - HDRenderPipeline renderPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline; - if (enableOutput && renderPipeline != null) + if (enableOutput && RenderPipelineManager.currentPipeline is HDRenderPipeline renderPipeline) { List cameras = new List(1); foreach (var layer in m_InputLayers) @@ -832,7 +829,7 @@ void CustomRender(ScriptableRenderContext context, HDCamera camera) if (layer.clearsBackGround) { cmd.SetRenderTarget(layer.GetRenderTarget()); - cmd.ClearRenderTarget(false, true, s_TransparentBlack); + cmd.ClearRenderTarget(false, true, Color.clear); } } } @@ -874,20 +871,20 @@ void CustomRender(ScriptableRenderContext context, HDCamera camera) if (recorderCaptureActions != null) { var format = m_InputLayers[0].GetRenderTarget().format; - cmd.GetTemporaryRT(m_RecorderTempRT, camera.camera.pixelWidth, camera.camera.pixelHeight, 0, FilterMode.Point, format); + cmd.GetTemporaryRT(_RecorderTempRT, camera.camera.pixelWidth, camera.camera.pixelHeight, 0, FilterMode.Point, format); if (isFullscreen) { - CoreUtils.DrawFullScreen(cmd, m_Material, m_RecorderTempRT, shaderPassId: materialPass); + CoreUtils.DrawFullScreen(cmd, m_Material, _RecorderTempRT, shaderPassId: materialPass); } else { m_ShaderVariablesGlobalCB._ViewProjMatrix = m_ViewProjMatrixFlipped; ConstantBuffer.PushGlobal(cmd, m_ShaderVariablesGlobalCB, HDShaderIDs._ShaderVariablesGlobal); - cmd.Blit(null, m_RecorderTempRT, m_Material, materialPass); + cmd.Blit(null, _RecorderTempRT, m_Material, materialPass); for (recorderCaptureActions.Reset(); recorderCaptureActions.MoveNext();) { - recorderCaptureActions.Current(m_RecorderTempRT, cmd); + recorderCaptureActions.Current(_RecorderTempRT, cmd); } } } @@ -920,7 +917,7 @@ void CustomRender(ScriptableRenderContext context, HDCamera camera) /// Returns true if this camera is used to render in more than one layer internal bool IsThisCameraShared(Camera camera) { - if (camera == null) + if (!camera) { return false; } @@ -938,11 +935,12 @@ internal bool IsThisCameraShared(Camera camera) return count > 1; } - static public Camera GetSceneCamera() + public static Camera GetSceneCamera() { - if (Camera.main != null) + Camera main = Camera.main; + if (main) { - return Camera.main; + return main; } foreach (var camera in Camera.allCameras) { @@ -955,7 +953,7 @@ static public Camera GetSceneCamera() return null; } - static public Camera CreateCamera(string cameraName) + public static Camera CreateCamera(string cameraName) { var newCameraGameObject = new GameObject(cameraName) { @@ -968,9 +966,17 @@ static public Camera CreateCamera(string cameraName) } private static CompositionManager s_CompositorInstance; - public static CompositionManager GetInstance() => s_CompositorInstance ??= FindAnyObjectByType(FindObjectsInactive.Include); - static public Vector4 GetAlphaScaleAndBiasForCamera(HDCamera hdCamera) + public static CompositionManager GetInstance() + { + if (!s_CompositorInstance) + { + s_CompositorInstance = FindAnyObjectByType(FindObjectsInactive.Include); + } + return s_CompositorInstance; + } + + public static Vector4 GetAlphaScaleAndBiasForCamera(HDCamera hdCamera) { AdditionalCompositorData compositorData = null; hdCamera.camera.TryGetComponent(out compositorData); @@ -998,7 +1004,7 @@ static public Vector4 GetAlphaScaleAndBiasForCamera(HDCamera hdCamera) /// /// The input camera /// The color buffer that will be used to draw on top, or null if not a stacked camera - static internal Texture GetClearTextureForStackedCamera(HDCamera hdCamera) + internal static Texture GetClearTextureForStackedCamera(HDCamera hdCamera) { if (hdCamera.camera.TryGetComponent(out var compositorData)) { @@ -1012,7 +1018,7 @@ static internal Texture GetClearTextureForStackedCamera(HDCamera hdCamera) /// /// The input camera /// The depth buffer that will be used to draw on top, or null if not a stacked camera - static internal RenderTexture GetClearDepthForStackedCamera(HDCamera hdCamera) + internal static RenderTexture GetClearDepthForStackedCamera(HDCamera hdCamera) { if (hdCamera.camera.TryGetComponent(out var compositorData)) { @@ -1052,5 +1058,13 @@ void UnRegisterCustomPasses() m_CurrentAsset.compositorCustomVolumeComponentsList.Remove(); } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_CompositorInstance = null; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositorCameraRegistry.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositorCameraRegistry.cs index 4a78f576ac4..90bc90cd7fb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositorCameraRegistry.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositorCameraRegistry.cs @@ -8,35 +8,42 @@ namespace UnityEngine.Rendering.HighDefinition.Compositor // Required to properly manage cameras that are deleted or "ressurected" by undo/redo operations. class CompositorCameraRegistry { - static List s_CompositorManagedCameras = new List(); - static private CompositorCameraRegistry s_CompositorCameraRegistry; - static public CompositorCameraRegistry GetInstance() => - s_CompositorCameraRegistry ?? (s_CompositorCameraRegistry = new CompositorCameraRegistry()); + static CompositorCameraRegistry s_CompositorCameraRegistry; + + public static CompositorCameraRegistry GetInstance() => s_CompositorCameraRegistry ??= new CompositorCameraRegistry(); + + List m_CompositorManagedCameras = new List(); // Keeps track of compositor allocated cameras internal void RegisterInternalCamera(Camera camera) { - s_CompositorManagedCameras.Add(camera); + m_CompositorManagedCameras.Add(camera); } internal void UnregisterInternalCamera(Camera camera) { - s_CompositorManagedCameras.Remove(camera); + m_CompositorManagedCameras.Remove(camera); + } + + void Clear() + { + CleanUpCameraOrphans(); + m_CompositorManagedCameras.Clear(); } // Checks for any compositor allocated cameras that are now unused and frees their resources. internal void CleanUpCameraOrphans(List layers = null) { - s_CompositorManagedCameras.RemoveAll(x => x == null); + m_CompositorManagedCameras.RemoveAll(x => x == null); - for (int i = s_CompositorManagedCameras.Count - 1; i >= 0; i--) + for (int i = m_CompositorManagedCameras.Count - 1; i >= 0; i--) { bool found = false; if (layers != null) { foreach (var layer in layers) { - if (s_CompositorManagedCameras[i].Equals(layer.camera)) + if (m_CompositorManagedCameras[i].Equals(layer.camera)) { found = true; break; @@ -45,16 +52,17 @@ internal void CleanUpCameraOrphans(List layers = null) } // If the camera is not used by any layer anymore, then destroy it - if (found == false && s_CompositorManagedCameras[i] != null) + if (found == false && m_CompositorManagedCameras[i] != null) { - var cameraData = s_CompositorManagedCameras[i].GetComponent(); + var cameraData = m_CompositorManagedCameras[i].GetComponent(); if (cameraData) { CoreUtils.Destroy(cameraData); } - s_CompositorManagedCameras[i].targetTexture = null; - CoreUtils.Destroy(s_CompositorManagedCameras[i]); - s_CompositorManagedCameras.RemoveAt(i); + + m_CompositorManagedCameras[i].targetTexture = null; + CoreUtils.Destroy(m_CompositorManagedCameras[i]); + m_CompositorManagedCameras.RemoveAt(i); } } @@ -62,20 +70,21 @@ internal void CleanUpCameraOrphans(List layers = null) { foreach (var layer in layers) { - if (layer != null && !s_CompositorManagedCameras.Contains(layer.camera)) + if (layer != null && !m_CompositorManagedCameras.Contains(layer.camera)) { - s_CompositorManagedCameras.Add(layer.camera); + m_CompositorManagedCameras.Add(layer.camera); } } } } - internal void PrinCameraIDs() +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() { - for (int i = s_CompositorManagedCameras.Count - 1; i >= 0; i--) - { - var id = s_CompositorManagedCameras[i] ? s_CompositorManagedCameras[i].GetEntityId() : EntityId.None; - } + s_CompositorCameraRegistry?.Clear(); + s_CompositorCameraRegistry = null; } +#endif } } From f4a7fe119ce9722f2fc84a249f1c7006e530f199 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:23 +0000 Subject: [PATCH 35/88] Updated `HDComputeThickness` to work with CoreCLR --- .../RenderPipeline/HDComputeThickness.cs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDComputeThickness.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDComputeThickness.cs index e8734bd2c28..9d2ff1ba7d6 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDComputeThickness.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDComputeThickness.cs @@ -31,33 +31,22 @@ public enum ComputeThicknessResolution /// public sealed class HDComputeThickness { - private static HDComputeThickness m_Instance = null; + private static HDComputeThickness s_Instance = null; private TextureHandle m_ThicknessArrayRT; private GraphicsBuffer m_ReindexMapCB; - private uint m_UsedLayersCountCurrentFrame; /// /// Max RT of Thickness we can computed in a single frame /// // Should be paired with: COMPUTE_THICKNESS_MAX_LAYER_COUNT in // 'Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl' - public static uint computeThicknessMaxLayer = 32; // bitscount(LayerMask) + public static readonly uint computeThicknessMaxLayer = 32; // bitscount(LayerMask) /// /// Current unique instance /// - public static HDComputeThickness Instance - { - get - { - if (m_Instance == null) - { - m_Instance = new HDComputeThickness(); - } - return m_Instance; - } - } + public static HDComputeThickness Instance => s_Instance ??= new HDComputeThickness(); private HDComputeThickness() { @@ -98,5 +87,20 @@ public GraphicsBuffer GetReindexMap() { return m_ReindexMapCB; } + + void Clear() + { + m_ReindexMapCB = null; + m_ThicknessArrayRT = TextureHandle.nullHandle; + } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_Instance?.Clear(); + s_Instance = null; + } +#endif } } From faea3006e055b8954dcb30997350a6cf098d2f12 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:23 +0000 Subject: [PATCH 36/88] Updated `GlobalPostProcessingQualitySettings` to work with CoreCLR --- .../GlobalPostProcessingQualitySettings.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalPostProcessingQualitySettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalPostProcessingQualitySettings.cs index 65190473a9e..fde705cb72b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalPostProcessingQualitySettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/GlobalPostProcessingQualitySettings.cs @@ -57,7 +57,7 @@ internal static int GetScalableSettingLevelParameterValue(int level, bool useOve [Serializable] public sealed class GlobalPostProcessingQualitySettings { - static int s_QualitySettingCount = ScalableSettingLevelParameter.LevelCount; + const int k_QualitySettingCount = ScalableSettingLevelParameter.LevelCount; internal GlobalPostProcessingQualitySettings() { @@ -123,44 +123,44 @@ internal GlobalPostProcessingQualitySettings() /* Depth of field */ /// Depth of field near blur sample count for each quality level. The array must have one entry per scalable setting level, and elements must be between 3 and 8. [Range(3, 8)] - public int[] NearBlurSampleCount = new int[s_QualitySettingCount]; + public int[] NearBlurSampleCount = new int[k_QualitySettingCount]; /// Depth of field near blur maximum radius for each quality level. The array must have one entry per scalable setting level, and elements must be between 0 and 8. [Range(0, 8)] - public float[] NearBlurMaxRadius = new float[s_QualitySettingCount]; + public float[] NearBlurMaxRadius = new float[k_QualitySettingCount]; /// Depth of field far blur sample count for each quality level. The array must have one entry per scalable setting level, and elements must be between 3 and 16. [Range(3, 16)] - public int[] FarBlurSampleCount = new int[s_QualitySettingCount]; + public int[] FarBlurSampleCount = new int[k_QualitySettingCount]; /// Depth of field far blur maximum radius for each quality level. The array must have one entry per scalable setting level, and elements must be between 0 and 16. [Range(0, 16)] - public float[] FarBlurMaxRadius = new float[s_QualitySettingCount]; + public float[] FarBlurMaxRadius = new float[k_QualitySettingCount]; /// Depth of field resolution for each quality level. The array must have one entry per scalable setting level. - public DepthOfFieldResolution[] DoFResolution = new DepthOfFieldResolution[s_QualitySettingCount]; + public DepthOfFieldResolution[] DoFResolution = new DepthOfFieldResolution[k_QualitySettingCount]; /// Use Depth of field high quality filtering for each quality level. The array must have one entry per scalable setting level. - public bool[] DoFHighQualityFiltering = new bool[s_QualitySettingCount]; + public bool[] DoFHighQualityFiltering = new bool[k_QualitySettingCount]; /// Use physically based Depth of field for each quality level. The array must have one entry per scalable setting level. - public bool[] DoFPhysicallyBased = new bool[s_QualitySettingCount]; + public bool[] DoFPhysicallyBased = new bool[k_QualitySettingCount]; /// Adjust the number of samples in the physically based depth of field depending on the radius of the blur. Higher values will decrease the noise but increase the rendering cost. [Range(0.25f, 4f)] - public float[] AdaptiveSamplingWeight = new float[s_QualitySettingCount]; + public float[] AdaptiveSamplingWeight = new float[k_QualitySettingCount]; /// Adjust near blur CoC based on depth distance when manual, non-physical mode is used for each quality level. The array must have one entry per scalable setting level. - public bool[] LimitManualRangeNearBlur = new bool[s_QualitySettingCount]; + public bool[] LimitManualRangeNearBlur = new bool[k_QualitySettingCount]; /* Motion Blur */ /// Motion Blur sample count for each quality level. The array must have one entry per scalable setting level, and elements must above 2. [Min(2)] - public int[] MotionBlurSampleCount = new int[s_QualitySettingCount]; + public int[] MotionBlurSampleCount = new int[k_QualitySettingCount]; /* Bloom */ /// Bloom resolution for each quality level. The array must have one entry per scalable setting level. - public BloomResolution[] BloomRes = new BloomResolution[s_QualitySettingCount]; + public BloomResolution[] BloomRes = new BloomResolution[k_QualitySettingCount]; /// Bloom high quality filtering for each quality level. The array must have one entry per scalable setting level. - public bool[] BloomHighQualityFiltering = new bool[s_QualitySettingCount]; + public bool[] BloomHighQualityFiltering = new bool[k_QualitySettingCount]; /// Bloom high quality prefiltering for each quality level. The array must have one entry per scalable setting level. - public bool[] BloomHighQualityPrefiltering = new bool[s_QualitySettingCount]; + public bool[] BloomHighQualityPrefiltering = new bool[k_QualitySettingCount]; /* Chromatic Aberration */ /// Chromatic aberration maximum sample count for each quality level. The array must have one entry per scalable setting level, and elements must be between 3 and 24. [Range(3, 24)] - public int[] ChromaticAberrationMaxSamples = new int[s_QualitySettingCount]; + public int[] ChromaticAberrationMaxSamples = new int[k_QualitySettingCount]; } } From f1a34a5a15855a743610c136c5be684105360346 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:24 +0000 Subject: [PATCH 37/88] Updated `HDRenderPipeline.VolumetricLighting` to work with CoreCLR --- .../HDRenderPipeline.VolumetricLighting.cs | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs index a9e43f6fb3f..ea00ba29abf 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs @@ -323,11 +323,10 @@ public partial class HDRenderPipeline // This size is shared between all cameras to create the volumetric 3D textures static Vector3Int s_CurrentVolumetricBufferSize; - static readonly ShaderTagId[] s_VolumetricFogPassNames = { HDShaderPassNames.s_VolumetricFogVFXName, HDShaderPassNames.s_FogVolumeVoxelizeName }; - // Is the feature globally disabled? bool m_SupportVolumetrics = false; + ShaderTagId[] m_VolumetricFogPassNames; Vector4[] m_PackedCoeffs; ZonalHarmonicsL2 m_PhaseZH; Vector2[] m_xySeq; @@ -349,7 +348,7 @@ public partial class HDRenderPipeline Matrix4x4[] m_PixelCoordToViewDirWS; - static internal void SafeDestroy(ref RenderTexture rt) + internal static void SafeDestroy(ref RenderTexture rt) { if (rt != null) { @@ -381,7 +380,7 @@ static void ComputeVolumetricFogSliceCountAndScreenFraction(Fog fog, out int sli } } - static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float voxelSize) + static Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float voxelSize) { var controller = hdCamera.volumeStack.GetComponent(); Debug.Assert(controller != null); @@ -412,7 +411,7 @@ static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref return new Vector3Int(w, h, d); } - static internal VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdCamera) + static VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdCamera) { var controller = hdCamera.volumeStack.GetComponent(); Debug.Assert(controller != null); @@ -428,7 +427,7 @@ static internal VBufferParameters ComputeVolumetricBufferParameters(HDCamera hdC voxelSize); } - static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) + internal static void ReinitializeVolumetricBufferParams(HDCamera hdCamera) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; @@ -457,7 +456,7 @@ static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) // This function relies on being called once per camera per frame. // The results are undefined otherwise. - static internal void UpdateVolumetricBufferParams(HDCamera hdCamera) + internal static void UpdateVolumetricBufferParams(HDCamera hdCamera) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; @@ -487,7 +486,7 @@ static internal void UpdateVolumetricBufferParams(HDCamera hdCamera) // Do not access 'rt.name', it allocates memory every time... // Have to manually cache and pass the name. - static internal void ResizeVolumetricBuffer(ref RTHandle rt, string name, int viewportWidth, int viewportHeight, int viewportDepth) + internal static void ResizeVolumetricBuffer(ref RTHandle rt, string name, int viewportWidth, int viewportHeight, int viewportDepth) { Debug.Assert(rt != null); @@ -650,7 +649,7 @@ TextureHandle GenerateMaxZPass(RenderGraph renderGraph, HDCamera hdCamera, in Te return TextureHandle.nullHandle; } - static internal void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int bufferCount) + internal static void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int bufferCount) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; @@ -673,7 +672,7 @@ static internal void CreateVolumetricHistoryBuffers(HDCamera hdCamera, int buffe hdCamera.volumetricHistoryIsValid = false; } - static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) + internal static void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) { if (hdCamera.volumetricHistoryBuffers == null) return; @@ -691,7 +690,7 @@ static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) // Must be called AFTER UpdateVolumetricBufferParams. static readonly string[] volumetricHistoryBufferNames = new string[2] { "VBufferHistory0", "VBufferHistory1" }; - static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera) + internal static void ResizeVolumetricHistoryBuffers(HDCamera hdCamera) { if (!hdCamera.IsVolumetricReprojectionEnabled()) return; @@ -763,6 +762,7 @@ void InitializeVolumetricLighting() m_VolumetricLightingCS = runtimeShaders.volumetricLightingCS; m_VolumetricLightingFilteringCS = runtimeShaders.volumetricLightingFilteringCS; + m_VolumetricFogPassNames = new[] { HDShaderPassNames.s_VolumetricFogVFXName, HDShaderPassNames.s_FogVolumeVoxelizeName }; m_PackedCoeffs = new Vector4[7]; m_PhaseZH = new ZonalHarmonicsL2(); m_PhaseZH.coeffs = new float[3]; @@ -936,7 +936,7 @@ void PrepareVisibleLocalVolumetricFogList(HDCamera hdCamera, CommandBuffer cmd) } } - unsafe void UpdateShaderVariableslVolumetrics(ref ShaderVariablesVolumetric cb, HDCamera hdCamera, in Vector4 resolution, int maxSliceCount, bool updateVoxelizationFields = false) + unsafe void UpdateShaderVariablesVolumetrics(ref ShaderVariablesVolumetric cb, HDCamera hdCamera, in Vector4 resolution, int maxSliceCount, bool updateVoxelizationFields = false) { var fog = hdCamera.volumeStack.GetComponent(); var vFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; @@ -1085,7 +1085,7 @@ unsafe TextureHandle ClearAndHeightFogVoxelizationPass(RenderGraph renderGraph, passData.resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); - UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, passData.resolution, maxSliceCount, true); + UpdateShaderVariablesVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, passData.resolution, maxSliceCount, true); passData.volumetricCB = m_ShaderVariablesVolumetricCB; passData.densityBuffer = renderGraph.CreateTexture(new TextureDesc(s_CurrentVolumetricBufferSize.x, s_CurrentVolumetricBufferSize.y, false, false) @@ -1173,7 +1173,7 @@ unsafe TextureHandle FogVolumeAndVFXVoxelizationPass(RenderGraph renderGraph, { builder.AllowPassCulling(true); - var vfxFogVolumeRendererListDesc = new RendererListDesc(s_VolumetricFogPassNames, cullingResults, hdCamera.camera) + var vfxFogVolumeRendererListDesc = new RendererListDesc(m_VolumetricFogPassNames, cullingResults, hdCamera.camera) { rendererConfiguration = PerObjectData.None, renderQueueRange = HDRenderQueue.k_RenderQueue_All, @@ -1190,7 +1190,7 @@ unsafe TextureHandle FogVolumeAndVFXVoxelizationPass(RenderGraph renderGraph, passData.viewportSize = currParams.viewportSize; var cvp = currParams.viewportSize; var res = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y);; - UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, res, maxSliceCount, true); + UpdateShaderVariablesVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, res, maxSliceCount, true); passData.volumetricCB = m_ShaderVariablesVolumetricCB; passData.fogOverdrawDebugEnabled = fogOverdrawDebugEnabled; if (fogOverdrawDebugEnabled) @@ -1395,7 +1395,7 @@ TextureHandle VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdCamera, passData.filteringNeedsExtraBuffer = !(SystemInfo.IsFormatSupported(GraphicsFormat.R16G16B16A16_SFloat, GraphicsFormatUsage.LoadStore)); ComputeVolumetricFogSliceCountAndScreenFraction(fog, out var maxSliceCount, out _); - UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, passData.resolution, maxSliceCount); + UpdateShaderVariablesVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, passData.resolution, maxSliceCount); passData.volumetricCB = m_ShaderVariablesVolumetricCB; passData.lightListCB = m_ShaderVariablesLightListCB; @@ -1528,5 +1528,13 @@ void PrepareAndPushVolumetricCBufferForVFXUpdate(CommandBuffer cmd, HDCamera hdC ConstantBuffer.PushGlobal(cmd, m_ShaderVariablesVolumetricCB, HDShaderIDs._ShaderVariablesVolumetric); } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad_VolumetricLighting() + { + s_CurrentVolumetricBufferSize = default; + } +#endif } } // namespace UnityEngine.Rendering.HighDefinition From ccefde943ea22bd2e108aa6862730a7cf1c2d499 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:24 +0000 Subject: [PATCH 38/88] Updated `HDRuntimeReflectionSystem` to work with CoreCLR --- .../Lighting/Reflection/HDRuntimeReflectionSystem.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDRuntimeReflectionSystem.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDRuntimeReflectionSystem.cs index 2111c935a15..7a4039f8ee4 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDRuntimeReflectionSystem.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDRuntimeReflectionSystem.cs @@ -26,16 +26,14 @@ static HDRuntimeReflectionSystem() #endif - static HDRuntimeReflectionSystem k_instance = new HDRuntimeReflectionSystem(); - // We must use a static constructor and only set the system in the Initialize method // in case this method is called multiple times. // This will be the case when entering play mode without performing the domain reload. - [RuntimeInitializeOnLoadMethod] - static void Initialize() + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() { if (GraphicsSettings.currentRenderPipeline is HDRenderPipelineAsset) - ScriptableRuntimeReflectionSystemSettings.system = k_instance; + ScriptableRuntimeReflectionSystemSettings.system = new HDRuntimeReflectionSystem(); } // Note: method bool TickRealtimeProbes() will create GC.Alloc due to Unity binding code From 603f9c628a9c0d5b15704101d0433a5c904a85ae Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:25 +0000 Subject: [PATCH 39/88] Updated `LocalVolumetricFogManager` to work with CoreCLR --- .../LocalVolumetricFogManager.cs | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs index add8df63f90..62e9d265891 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs @@ -11,18 +11,10 @@ namespace UnityEngine.Rendering.HighDefinition class LocalVolumetricFogManager { // Allocate graphics buffers by chunk to avoid reallocating them too often - private static readonly int k_IndirectBufferChunkSize = 50; + private const int k_IndirectBufferChunkSize = 50; - static LocalVolumetricFogManager m_Manager; - public static LocalVolumetricFogManager manager - { - get - { - if (m_Manager == null) - m_Manager = new LocalVolumetricFogManager(); - return m_Manager; - } - } + static LocalVolumetricFogManager s_Manager; + public static LocalVolumetricFogManager manager => s_Manager ??= new LocalVolumetricFogManager(); List m_Volumes = null; @@ -137,6 +129,28 @@ public List PrepareLocalVolumetricFogData(CommandBuffer cmd, public bool IsInitialized() => globalIndirectBuffer != null && globalIndirectBuffer.IsValid(); + void Cleanup() + { + m_Volumes.Clear(); + m_Volumes = null; + + CleanupGraphicsBuffers(); + + globalIndirectBuffer = null; + globalIndirectionBuffer = null; + volumetricMaterialIndexBuffer = null; + volumetricMaterialDataBuffer = null; + } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_Manager?.Cleanup(); + s_Manager = null; + } +#endif + public static class RegisterLocalVolumetricFogEarlyUpdate { #if UNITY_EDITOR @@ -153,10 +167,10 @@ internal static void Init() internal static void PrepareFogDrawCalls() { - if (!LocalVolumetricFogManager.manager?.IsInitialized() ?? true) + if (!LocalVolumetricFogManager.s_Manager?.IsInitialized() ?? true) return; - var volumes = LocalVolumetricFogManager.m_Manager.m_Volumes; + var volumes = LocalVolumetricFogManager.s_Manager.m_Volumes; for (int i = 0; i < volumes.Count; i++) volumes[i].PrepareDrawCall(i); } From 9c914b32a5862b10e6c324e1c252352baf876bc9 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:25 +0000 Subject: [PATCH 40/88] Updated `MaterialDebug`, `MaterialExtension`, `MaterialPool`, and `MaterialQuality` to work with CoreCLR --- .../PathTracing/MaterialPool/MaterialPool.cs | 12 +++++++ .../Runtime/Utilities/MaterialQuality.cs | 6 ++-- .../Runtime/Debug/MaterialDebug.cs | 33 +++++++++++++++++-- .../Runtime/Material/MaterialExtension.cs | 2 +- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/MaterialPool/MaterialPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/MaterialPool/MaterialPool.cs index fa1133969f5..ba6a476fecd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/MaterialPool/MaterialPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/MaterialPool/MaterialPool.cs @@ -791,5 +791,17 @@ private static Mesh CreateQuadMesh() return mesh; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + if (_planeMesh) + { + Object.Destroy(_planeMesh); + _planeMesh = null; + } + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/MaterialQuality.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/MaterialQuality.cs index 998adac6d64..9b1d0c356f1 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/MaterialQuality.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/MaterialQuality.cs @@ -27,7 +27,7 @@ public static class MaterialQualityUtilities /// /// Keywords strings for Material Quality levels. /// - public static string[] KeywordNames = + public static readonly string[] KeywordNames = { "MATERIAL_QUALITY_LOW", "MATERIAL_QUALITY_MEDIUM", @@ -37,12 +37,12 @@ public static class MaterialQualityUtilities /// /// String representation of the MaterialQuality enum. /// - public static string[] EnumNames = Enum.GetNames(typeof(MaterialQuality)); + public static readonly string[] EnumNames = Enum.GetNames(typeof(MaterialQuality)); /// /// Keywords for Material Quality levels. /// - public static ShaderKeyword[] Keywords = + public static readonly ShaderKeyword[] Keywords = { new ShaderKeyword(KeywordNames[0]), new ShaderKeyword(KeywordNames[1]), diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/MaterialDebug.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/MaterialDebug.cs index bd4f82a99d9..0f0e9e47949 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/MaterialDebug.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/MaterialDebug.cs @@ -153,7 +153,7 @@ public class MaterialDebugSettings /// List of material debug views values. public static int[] debugViewMaterialGBufferValues = null; - static Dictionary s_MaterialPropertyMap = new Dictionary(); + static Dictionary s_MaterialPropertyMap = null; /// Current material shared properties debug view. public MaterialSharedProperty debugViewMaterialCommonValue = MaterialSharedProperty.None; @@ -163,6 +163,34 @@ static MaterialDebugSettings() BuildDebugRepresentation(); } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + isDebugViewMaterialInit = false; + + debugViewMaterialStrings = null; + debugViewMaterialValues = null; + debugViewEngineStrings = null; + debugViewEngineValues = null; + debugViewMaterialVaryingStrings = null; + debugViewMaterialVaryingValues = null; + debugViewMaterialPropertiesStrings = null; + debugViewMaterialPropertiesValues = null; + debugViewMaterialTextureStrings = null; + debugViewMaterialTextureValues = null; + + debugViewMaterialGBufferStrings = null; + debugViewMaterialGBufferValues = null; + + s_MaterialPropertyMap?.Clear(); + s_MaterialPropertyMap = null; + + // Static constructors do not get called again + BuildDebugRepresentation(); + } +#endif + // className include the additional "/" static void FillWithProperties(Type type, ref List debugViewMaterialStringsList, ref List debugViewMaterialValuesList, string className = "") { @@ -422,6 +450,7 @@ static void BuildDebugRepresentation() } } + s_MaterialPropertyMap = new Dictionary(); foreach (var key in materialPropertyMap.Keys) { s_MaterialPropertyMap[key] = materialPropertyMap[key].ToArray(); @@ -500,7 +529,7 @@ internal set const int kDebugViewMaterialBufferLength = 10; //buffer must be in float as there is no SetGlobalIntArray in API - static float[] s_DebugViewMaterialOffsetedBuffer = new float[kDebugViewMaterialBufferLength + 1]; //first is used size + static readonly float[] s_DebugViewMaterialOffsetedBuffer = new float[kDebugViewMaterialBufferLength + 1]; //first is used size // Reminder: _DebugViewMaterial[i] // i==0 -> the size used in the buffer diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs index e4bcfb9cb32..b656c35fb6c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/MaterialExtension.cs @@ -316,7 +316,7 @@ internal enum ShaderID // list of methods for resetting keywords internal delegate void MaterialResetter(Material material); - internal static Dictionary k_PlainShadersMaterialResetters = new Dictionary() + internal static readonly Dictionary k_PlainShadersMaterialResetters = new Dictionary() { { ShaderID.Lit, LitAPI.ValidateMaterial }, { ShaderID.LitTesselation, LitAPI.ValidateMaterial }, From 3ce6914ae88be129303458f0d23160b45ba44346 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:26 +0000 Subject: [PATCH 41/88] Updated `SkyManager` and `SkySettings` to work with CoreCLR --- .../Runtime/Sky/SkyManager.cs | 66 +++++++++++-------- .../Runtime/Sky/SkySettings.cs | 11 +++- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index 6368a13487a..249890d0413 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -79,7 +79,7 @@ public class BuiltinSkyParameters /// Current debug dsplay settings. public DebugDisplaySettings debugSettings; /// Null color buffer render target identifier. - public static RenderTargetIdentifier nullRT = -1; + public static readonly RenderTargetIdentifier nullRT = -1; /// Index of the current cubemap face to render (Unknown for texture2D). public CubemapFace cubemapFace = CubemapFace.Unknown; /// Fallback for structured buffer of CelestialBodyData. @@ -175,16 +175,16 @@ class SkyManager public VolumeStack lightingOverrideVolumeStack { get; private set; } public LayerMask lightingOverrideLayerMask { get; private set; } = -1; - static Dictionary m_SkyTypesDict = null; - public static Dictionary skyTypesDict { get { if (m_SkyTypesDict == null) UpdateSkyTypes(); return m_SkyTypesDict; } } + static Dictionary s_SkyTypesDict = null; + public static Dictionary skyTypesDict { get { if (s_SkyTypesDict == null) UpdateSkyTypes(); return s_SkyTypesDict; } } - static Dictionary m_CloudTypesDict = null; - public static Dictionary cloudTypesDict { get { if (m_CloudTypesDict == null) UpdateCloudTypes(); return m_CloudTypesDict; } } + static Dictionary s_CloudTypesDict = null; + public static Dictionary cloudTypesDict { get { if (s_CloudTypesDict == null) UpdateCloudTypes(); return s_CloudTypesDict; } } // This list will hold the static lighting sky that should be used for baking ambient probe. // We can have multiple but we only want to use the one from the active scene - private static Dictionary m_StaticLightingSkies = new (); - private static StaticLightingSky m_ActiveStaticSky; + private static Dictionary s_StaticLightingSkies = new(); + private static StaticLightingSky s_ActiveStaticSky; // Only show the procedural sky upgrade message once static bool logOnce = true; @@ -288,9 +288,9 @@ internal static VolumetricClouds GetVolumetricClouds(VolumeStack stack) static void UpdateSkyTypes() { - if (m_SkyTypesDict == null) + if (s_SkyTypesDict == null) { - m_SkyTypesDict = new Dictionary(); + s_SkyTypesDict = new Dictionary(); var skyTypes = CoreUtils.GetAllTypesDerivedFrom().Where(t => !t.IsAbstract); foreach (Type skyType in skyTypes) @@ -310,13 +310,13 @@ static void UpdateSkyTypes() } Type value; - if (m_SkyTypesDict.TryGetValue(uniqueID, out value)) + if (s_SkyTypesDict.TryGetValue(uniqueID, out value)) { Debug.LogWarningFormat("SkyUniqueID {0} used in class {1} is already used in class {2}. Class won't be registered as an available sky.", uniqueID, skyType, value); continue; } - m_SkyTypesDict.Add(uniqueID, skyType); + s_SkyTypesDict.Add(uniqueID, skyType); } } } @@ -324,9 +324,9 @@ static void UpdateSkyTypes() static void UpdateCloudTypes() { - if (m_CloudTypesDict == null) + if (s_CloudTypesDict == null) { - m_CloudTypesDict = new Dictionary(); + s_CloudTypesDict = new Dictionary(); var types = CoreUtils.GetAllTypesDerivedFrom().Where(t => !t.IsAbstract); foreach (Type type in types) @@ -346,13 +346,13 @@ static void UpdateCloudTypes() } Type value; - if (m_CloudTypesDict.TryGetValue(uniqueID, out value)) + if (s_CloudTypesDict.TryGetValue(uniqueID, out value)) { Debug.LogWarningFormat("CloudUniqueID {0} used in class {1} is already used in class {2}. Class won't be registered as an available cloud type.", uniqueID, type, value); continue; } - m_CloudTypesDict.Add(uniqueID, type); + s_CloudTypesDict.Add(uniqueID, type); } } } @@ -1273,7 +1273,7 @@ public void UpdateEnvironment(RenderGraph renderGraph, HDCamera hdCamera, Light // because we only maintain one static sky. Since we don't care that the static lighting may be a bit different in the preview we never recompute // and we use the one from the main camera. bool forceStaticUpdate = false; - m_ActiveStaticSky = m_StaticLightingSkies.GetValueOrDefault(SceneManager.GetActiveScene().GetHashCode(), null); + s_ActiveStaticSky = s_StaticLightingSkies.GetValueOrDefault(SceneManager.GetActiveScene().GetHashCode(), null); #if UNITY_EDITOR // In the editor, we might need the static sky ready for baking lightmaps/lightprobes regardless of the current ambient mode so we force it to update in this case if it's not been computed yet.. // We always force an update of the static sky when we're in scene view mode. Previous behaviour was to prevent forced updates if the hash of the static sky was non-null, but this was preventing @@ -1283,11 +1283,11 @@ public void UpdateEnvironment(RenderGraph renderGraph, HDCamera hdCamera, Light #endif if ((ambientMode == SkyAmbientMode.Static || forceStaticUpdate) && hdCamera.camera.cameraType != CameraType.Preview) { - if (m_ActiveStaticSky != null) + if (s_ActiveStaticSky != null) { - m_StaticLightingSky.skySettings = m_ActiveStaticSky.skySettings; - m_StaticLightingSky.cloudSettings = m_ActiveStaticSky.cloudSettings; - m_StaticLightingSky.volumetricClouds = m_ActiveStaticSky.volumetricClouds; + m_StaticLightingSky.skySettings = s_ActiveStaticSky.skySettings; + m_StaticLightingSky.cloudSettings = s_ActiveStaticSky.cloudSettings; + m_StaticLightingSky.volumetricClouds = s_ActiveStaticSky.volumetricClouds; } UpdateEnvironment(renderGraph, hdCamera, m_StaticLightingSky, sunLight, m_StaticSkyUpdateRequired || m_UpdateRequired, true, true, SkyAmbientMode.Static); m_StaticSkyUpdateRequired = false; @@ -1657,12 +1657,12 @@ public TextureHandle RenderOpaqueAtmosphericScattering(RenderGraph renderGraph, } } - static public StaticLightingSky GetStaticLightingSky() + public static StaticLightingSky GetStaticLightingSky() { - return m_ActiveStaticSky; + return s_ActiveStaticSky; } - static public void RegisterStaticLightingSky(StaticLightingSky staticLightingSky) + public static void RegisterStaticLightingSky(StaticLightingSky staticLightingSky) { #if UNITY_EDITOR if (staticLightingSky.staticLightingSkyUniqueID == (int)SkyType.Procedural && !skyTypesDict.TryGetValue((int)SkyType.Procedural, out var dummy)) @@ -1672,12 +1672,12 @@ static public void RegisterStaticLightingSky(StaticLightingSky staticLightingSky } #endif - m_StaticLightingSkies[staticLightingSky.gameObject.scene.GetHashCode()] = staticLightingSky; + s_StaticLightingSkies[staticLightingSky.gameObject.scene.GetHashCode()] = staticLightingSky; } - static public void UnRegisterStaticLightingSky(StaticLightingSky staticLightingSky) + public static void UnRegisterStaticLightingSky(StaticLightingSky staticLightingSky) { - m_StaticLightingSkies.Remove(staticLightingSky.gameObject.scene.GetHashCode()); + s_StaticLightingSkies.Remove(staticLightingSky.gameObject.scene.GetHashCode()); } public Texture2D ExportSkyToTexture(Camera camera) @@ -1781,6 +1781,20 @@ void OnBakeStarted() DynamicGI.UpdateEnvironment(); } + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_ActiveStaticSky = null; + + s_CloudTypesDict?.Clear(); + s_CloudTypesDict = null; + + s_SkyTypesDict?.Clear(); + s_SkyTypesDict = null; + + s_StaticLightingSkies?.Clear(); + s_StaticLightingSkies = new(); + } #endif } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkySettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkySettings.cs index ddf87b336e0..405ff2b0e7e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkySettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkySettings.cs @@ -141,7 +141,7 @@ public abstract class SkySettings : VolumeComponent /// /// The camera we want to use to compute the hash of the sky. /// The hash code of the sky parameters. - virtual public int GetHashCode(Camera camera) + public virtual int GetHashCode(Camera camera) { // By default we don't need to consider the camera position. return GetHashCode(); @@ -256,5 +256,14 @@ internal virtual Vector3 EvaluateAtmosphericAttenuation(Vector3 sunDirection, Ve { return Vector3.one; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + skyUniqueIDs?.Clear(); + skyUniqueIDs = new Dictionary(); + } +#endif } } From a8c59fb481d18b42043cab865c4c92c8e3afa5d2 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:26 +0000 Subject: [PATCH 42/88] Updated `STP` and `UpscalerUtils` to work with CoreCLR --- .../Runtime/STP/STP.cs | 19 +++++++++---------- .../RenderPass/UpscalerUtils.cs | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs b/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs index 3b999047638..f6de29f3202 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/STP/STP.cs @@ -130,21 +130,12 @@ public struct PerViewConfig /// const int kMaxPerViewConfigs = 2; - /// - /// Static allocation of per-view configurations - /// - static PerViewConfig[] s_PerViewConfigs = new PerViewConfig[kMaxPerViewConfigs]; - /// /// Static allocation of per-view configurations /// Users are expected to populate this during STP configuration and then assign it to the relevant /// configuration structure field(s) to avoid unnecessary allocations. /// - public static PerViewConfig[] perViewConfigs - { - get { return s_PerViewConfigs; } - set { s_PerViewConfigs = value; } - } + public static PerViewConfig[] perViewConfigs { get; set; } = new PerViewConfig[kMaxPerViewConfigs]; /// /// Top-level configuration structure required for STP execution @@ -1351,5 +1342,13 @@ public static TextureHandle Execute(RenderGraph renderGraph, ref Config config) return taaData.output; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + perViewConfigs = new PerViewConfig[kMaxPerViewConfigs]; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/UpscalerUtils.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/UpscalerUtils.cs index 0b3ff3a4f4a..68aa7ffa424 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/UpscalerUtils.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/UpscalerUtils.cs @@ -43,7 +43,7 @@ public void Dispose() } //Amount of inactive frames dlss has rendered before we clean / destroy the plugin state. - private static UInt64 sMaximumFrameExpiration = 400; + private const UInt64 sMaximumFrameExpiration = 400; private Dictionary m_CameraStates = new Dictionary(); private List m_InvalidCameraKeys = new List(); From 47264703468d88429abde9ebf757125b49f226bd Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:26 +0000 Subject: [PATCH 43/88] Updated `SPTDistribution` to work with CoreCLR --- .../SphericalCapPivot/SPTDistribution.cs | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SphericalCapPivot/SPTDistribution.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SphericalCapPivot/SPTDistribution.cs index f24c18e8265..9672b607389 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SphericalCapPivot/SPTDistribution.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SphericalCapPivot/SPTDistribution.cs @@ -4,18 +4,11 @@ namespace UnityEngine.Rendering.HighDefinition { partial class SPTDistribution { + static readonly int _PivotData = Shader.PropertyToID(nameof(_PivotData)); + static SPTDistribution s_Instance; - public static SPTDistribution instance - { - get - { - if (s_Instance == null) - s_Instance = new SPTDistribution(); - - return s_Instance; - } - } + public static SPTDistribution instance => s_Instance ??= new SPTDistribution(); int m_refCounting; @@ -79,7 +72,24 @@ public void Cleanup() public void Bind(CommandBuffer cmd) { - cmd.SetGlobalTexture("_PivotData", m_PivotData); + cmd.SetGlobalTexture(_PivotData, m_PivotData); + } + + void Clear() + { + m_refCounting = 0; + + CoreUtils.Destroy(m_PivotData); + m_PivotData = null; + } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_Instance?.Clear(); + s_Instance = null; } +#endif } } From 152435fac4e2486d89e75c3b5dc8c53676b1a89b Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:26 +0000 Subject: [PATCH 44/88] Updated `UVOverlapDetection` to work with CoreCLR --- .../Lightmapping/UVOverlapDetection.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Lightmapping/UVOverlapDetection.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Lightmapping/UVOverlapDetection.cs index ce229eb2d04..19bf4996868 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Lightmapping/UVOverlapDetection.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Lightmapping/UVOverlapDetection.cs @@ -15,17 +15,17 @@ internal class UVOverlapDetection : IDisposable { private static class ShaderProperties { - public static int TextureSize = Shader.PropertyToID("_TextureSize"); - public static int PerPixelChart = Shader.PropertyToID("_PerPixelChart"); - public static int InstanceIndex = Shader.PropertyToID("_InstanceIndex"); - public static int EdgeCount = Shader.PropertyToID("_EdgeCount"); - public static int TriangleEdges = Shader.PropertyToID("_TriangleEdges"); - public static int ChartIndices = Shader.PropertyToID("_ChartIndices"); - public static int OverlapPixels = Shader.PropertyToID("_OverlapPixels"); - public static int OverlapInstances = Shader.PropertyToID("_OverlapInstances"); - public static int TileX = Shader.PropertyToID("_TileX"); - public static int TileY = Shader.PropertyToID("_TileY"); - public static int TileSize = Shader.PropertyToID("_TileSize"); + public static readonly int TextureSize = Shader.PropertyToID("_TextureSize"); + public static readonly int PerPixelChart = Shader.PropertyToID("_PerPixelChart"); + public static readonly int InstanceIndex = Shader.PropertyToID("_InstanceIndex"); + public static readonly int EdgeCount = Shader.PropertyToID("_EdgeCount"); + public static readonly int TriangleEdges = Shader.PropertyToID("_TriangleEdges"); + public static readonly int ChartIndices = Shader.PropertyToID("_ChartIndices"); + public static readonly int OverlapPixels = Shader.PropertyToID("_OverlapPixels"); + public static readonly int OverlapInstances = Shader.PropertyToID("_OverlapInstances"); + public static readonly int TileX = Shader.PropertyToID("_TileX"); + public static readonly int TileY = Shader.PropertyToID("_TileY"); + public static readonly int TileSize = Shader.PropertyToID("_TileSize"); } private int _lightmapResolution; From 60bf7f5a115d70b68b21be9b3d9b95ead985f906 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:27 +0000 Subject: [PATCH 45/88] Updated `ReflectionSystemParameters` to work with CoreCLR --- .../Runtime/Lighting/Reflection/ReflectionSystemParameters.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionSystemParameters.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionSystemParameters.cs index c159ade8d15..55de41e1682 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionSystemParameters.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionSystemParameters.cs @@ -5,7 +5,7 @@ namespace UnityEngine.Rendering.HighDefinition /// struct ReflectionSystemParameters { - public static ReflectionSystemParameters Default = new ReflectionSystemParameters + public static readonly ReflectionSystemParameters Default = new ReflectionSystemParameters { maxPlanarReflectionProbePerCamera = 128, maxActivePlanarReflectionProbe = 512, From 27e322861b86183ba63a7212760ff6250ddf532c Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:27 +0000 Subject: [PATCH 46/88] Updated `ShaderVariablesRaytracing` to work with CoreCLR --- .../Raytracing/Shaders/ShaderVariablesRaytracing.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.cs index 83b9f9771cd..99c6c446af3 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/ShaderVariablesRaytracing.cs @@ -3,10 +3,10 @@ namespace UnityEngine.Rendering.HighDefinition [GenerateHLSL] class HDLightClusterDefinitions { - public static Vector3Int s_ClusterSize = new Vector3Int(64, 32, 64); - public static int s_ClusterCellCount = s_ClusterSize.x * s_ClusterSize.y * s_ClusterSize.z; + public static readonly Vector3Int s_ClusterSize = new Vector3Int(64, 32, 64); + public static readonly int s_ClusterCellCount = s_ClusterSize.x * s_ClusterSize.y * s_ClusterSize.z; - public static int s_CellMetaDataSize = 5; + public static readonly int s_CellMetaDataSize = 5; } [GenerateHLSL(needAccessors = false, generateCBuffer = true, constantRegister = (int)ConstantRegister.RayTracing)] From ce1c35237ee6f370cca34f2f5e6224e0b9add987 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 7 Apr 2026 17:59:27 +0000 Subject: [PATCH 47/88] Updated `VolumetricClouds` to work with CoreCLR --- .../Runtime/Lighting/VolumetricClouds/VolumetricClouds.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.cs index 73577389642..b6aa9ff1fed 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.cs @@ -29,7 +29,7 @@ public struct AnimationData public static AnimationData animationData { get => HDRenderPipeline.currentPipeline.volumetricClouds.m_CloudsAnimationData; - set { HDRenderPipeline.currentPipeline.volumetricClouds.m_CloudsAnimationData = value; } + set => HDRenderPipeline.currentPipeline.volumetricClouds.m_CloudsAnimationData = value; } /// From 813babb7bc1f02a5f48294c249c8d18c6ee72026 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Tue, 7 Apr 2026 17:59:28 +0000 Subject: [PATCH 48/88] [Port] [Forward] Fix dark screen HDR output and missing variants in HDRP Rendering Debugger --- .../BuildProcessors/HDRPPreprocessShaders.cs | 4 ++- .../Shaders/CompositeWithUIAndOETF.shader | 4 +++ .../HDRenderPipeline.RenderGraph.cs | 31 +++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs index 089d7f33e38..62c38f1671a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs @@ -167,7 +167,9 @@ protected override bool DoShadersStripper(HDRenderPipelineAsset hdrpAsset, Shade return true; // If we are transparent we use cluster lighting and not tile lighting - if (inputData.shaderKeywordSet.IsEnabled(m_TileLighting)) + // Exception: Keep tile lighting variants when DEBUG_DISPLAY is enabled for rendering debugger (only if stripDebugVariants is false) + if (inputData.shaderKeywordSet.IsEnabled(m_TileLighting) && + (stripDebugVariants || !inputData.shaderKeywordSet.IsEnabled(m_DebugDisplay))) return true; } else // Opaque diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/CompositeWithUIAndOETF.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/CompositeWithUIAndOETF.shader index 830e7e13ec4..f037942be65 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/CompositeWithUIAndOETF.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/CompositeWithUIAndOETF.shader @@ -8,6 +8,7 @@ Shader "Hidden/HDRP/CompositeUI" #pragma multi_compile_local_fragment _ APPLY_AFTER_POST #pragma multi_compile_local _ DISABLE_TEXTURE2D_X_ARRAY #pragma multi_compile_local_fragment _ BLIT_SINGLE_SLICE + #pragma multi_compile_local_fragment _ HDR_COLORSPACE_CONVERSION HDR_ENCODING HDR_COLORSPACE_CONVERSION_AND_ENCODING #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" @@ -96,6 +97,9 @@ Shader "Hidden/HDRP/CompositeUI" float4 uiValue = SAMPLE_TEXTURE2D_X_LOD(_UITexture, s_point_clamp_sampler, uiCoord, 0); #endif + #if defined(HDR_COLORSPACE_CONVERSION) + outColor.rgb = RotateRec709ToOutputSpace(outColor.rgb) * _PaperWhite; + #endif outColor.rgb = SceneUIComposition(uiValue, outColor.rgb, _PaperWhite, _MaxNits); outColor.rgb = OETF(outColor.rgb, _MaxNits); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs index abf522bd605..846053d93a7 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs @@ -143,6 +143,24 @@ void RecordRenderGraph(RenderRequest renderRequest, colorBuffer = RenderDebugViewMaterial(m_RenderGraph, cullingResults, hdCamera, gpuLightListOutput, prepassOutput.dbuffer, prepassOutput.gbuffer, prepassOutput.depthBuffer, vtFeedbackBuffer); colorBuffer = ResolveMSAAColor(m_RenderGraph, hdCamera, colorBuffer); + + bool rendersOffscreenUI = !m_OffscreenUIRenderedInCurrentFrame && HDROutputActiveForCameraType(hdCamera) && SupportedRenderingFeatures.active.rendersUIOverlay; + if (rendersOffscreenUI) + { + uiBuffer = RenderHDROffscreenUI(m_RenderGraph, hdCamera, renderContext); + m_OffscreenUIRenderedInCurrentFrame = true; + } + else + { + // We do not render offscreen ui for the rest of cameras. + uiBuffer = m_OffscreenUIRenderedInCurrentFrame ? m_RenderGraph.ImportTexture(m_OffscreenUIColorBuffer.Value) : m_RenderGraph.defaultResources.blackTextureXR; + } + + bool blitsOffscreenUICover = rendersOffscreenUI && m_RequireOffscreenUICoverPrepass; + if (blitsOffscreenUICover) + { + BlitFullscreenUIToOffscreen(m_RenderGraph, colorBackBuffer, uiBuffer, hdCamera); + } } else if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && pathTracing.enable.value && hdCamera.camera.cameraType != CameraType.Preview && GetRayTracingState() && GetRayTracingClusterState()) { @@ -258,7 +276,7 @@ void RecordRenderGraph(RenderRequest renderRequest, colorBuffer = RenderTransparency(m_RenderGraph, hdCamera, renderContext, colorBuffer, prepassOutput.resolvedNormalBuffer, vtFeedbackBuffer, currentColorPyramid, volumetricLighting, rayCountTexture, opticalFogTransmittance, m_SkyManager.GetSkyReflection(hdCamera), gpuLightListOutput, transparentPrepass, ref prepassOutput, shadowResult, cullingResults, customPassCullingResults, aovRequest, aovCustomPassBuffers); - bool rendersOffscreenUI = !m_OffscreenUIRenderedInCurrentFrame && HDROutputActiveForCameraType(hdCamera) && SupportedRenderingFeatures.active.rendersUIOverlay && !NeedHDRDebugMode(m_CurrentDebugDisplaySettings); + bool rendersOffscreenUI = !m_OffscreenUIRenderedInCurrentFrame && HDROutputActiveForCameraType(hdCamera) && SupportedRenderingFeatures.active.rendersUIOverlay; if (rendersOffscreenUI) { uiBuffer = RenderHDROffscreenUI(m_RenderGraph, hdCamera, renderContext); @@ -516,6 +534,7 @@ class FinalBlitPassData public Vector4 offscreenUIViewportParams; public bool applyAfterPP; public CubemapFace cubemapFace; + public bool postProcessEnabled; public TextureHandle uiTexture; public TextureHandle afterPostProcessTexture; @@ -557,14 +576,17 @@ void BlitFinalCameraTexture(RenderGraph renderGraph, HDCamera hdCamera, in Textu // Pick the right material based off XR rendering using texture arrays and if we are dealing with a single slice at the moment or processing all slices automatically. passData.blitMaterial = (TextureXR.useTexArray && passData.srcTexArraySlice >= 0) ? m_FinalBlitWithOETFTexArraySingleSlice : m_FinalBlitWithOETF; GetHDROutputParameters(HDRDisplayInformationForCamera(hdCamera), HDRDisplayColorGamutForCamera(hdCamera), m_Tonemapping, out passData.hdrOutputParmeters, out var unused); + GetOffscreenUIViewportParams(hdCamera, out passData.offscreenUIViewportParams); passData.uiTexture = uiTexture; builder.UseTexture(passData.uiTexture, AccessFlags.Read); passData.applyAfterPP = hdCamera.frameSettings.IsEnabled(FrameSettingsField.AfterPostprocess) && !NeedHDRDebugMode(m_CurrentDebugDisplaySettings); + passData.postProcessEnabled = m_PostProcessEnabled; } else { passData.hdrOutputParmeters = new Vector4(-1.0f, -1.0f, -1.0f, -1.0f); + passData.postProcessEnabled = false; } builder.SetRenderFunc( @@ -585,7 +607,12 @@ void BlitFinalCameraTexture(RenderGraph renderGraph, HDCamera hdCamera, in Textu propertyBlock.SetVector(HDShaderIDs._OffscreenUIViewportParams, data.offscreenUIViewportParams); propertyBlock.SetInt(HDShaderIDs._BlitTexArraySlice, data.srcTexArraySlice); - HDROutputUtils.ConfigureHDROutput(data.blitMaterial, data.colorGamut, HDROutputUtils.Operation.ColorEncoding); + HDROutputUtils.Operation hdrOperation = HDROutputUtils.Operation.ColorEncoding; + if (!data.postProcessEnabled) + { + hdrOperation |= HDROutputUtils.Operation.ColorConversion; + } + HDROutputUtils.ConfigureHDROutput(data.blitMaterial, data.colorGamut, hdrOperation); if (data.applyAfterPP) { From 33607e80894e96049adcf2b63b47487d41c94555 Mon Sep 17 00:00:00 2001 From: Apoorva Joshi Date: Tue, 7 Apr 2026 17:59:28 +0000 Subject: [PATCH 49/88] Make BaseShaderGUI.DrawShaderGraphProperties public --- .../Editor/ShaderGUI/BaseShaderGUI.cs | 6 +++++- .../Editor/ShaderGUI/ShaderGraphLitGUI.cs | 2 +- .../Editor/ShaderGUI/ShaderGraphTerrainLitGUI.cs | 2 +- .../Editor/ShaderGUI/ShaderGraphUnlitGUI.cs | 2 +- .../Editor/ShaderGUI/ShadergraphSpriteGUI.cs | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/BaseShaderGUI.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/BaseShaderGUI.cs index dd311527a25..fe38acc41e8 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/BaseShaderGUI.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/BaseShaderGUI.cs @@ -542,7 +542,11 @@ public void ShaderPropertiesGUI(Material material) //////////////////////////////////// #region DrawingFunctions - internal void DrawShaderGraphProperties(Material material, IEnumerable properties) + /// + /// Draws the Shader Graph properties for the given material. + /// + /// The material properties to draw. + public void DrawShaderGraphProperties(IEnumerable properties) { if (properties == null) return; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphLitGUI.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphLitGUI.cs index 6e84c65cd3c..9e2047dc679 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphLitGUI.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphLitGUI.cs @@ -67,7 +67,7 @@ public override void DrawSurfaceOptions(Material material) // material main surface inputs public override void DrawSurfaceInputs(Material material) { - DrawShaderGraphProperties(material, properties); + DrawShaderGraphProperties(properties); } public override void DrawAdvancedOptions(Material material) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphTerrainLitGUI.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphTerrainLitGUI.cs index b4d119861d8..7d06c21c935 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphTerrainLitGUI.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphTerrainLitGUI.cs @@ -21,7 +21,7 @@ public override void FindProperties(MaterialProperty[] properties) public override void DrawSurfaceInputs(Material material) { - DrawShaderGraphProperties(material, properties); + DrawShaderGraphProperties(properties); } } } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphUnlitGUI.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphUnlitGUI.cs index 5e4e95dcc7b..9331030c30f 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphUnlitGUI.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShaderGraphUnlitGUI.cs @@ -37,7 +37,7 @@ public override void ValidateMaterial(Material material) // material main surface inputs public override void DrawSurfaceInputs(Material material) { - DrawShaderGraphProperties(material, properties); + DrawShaderGraphProperties(properties); } public override void DrawAdvancedOptions(Material material) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShadergraphSpriteGUI.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShadergraphSpriteGUI.cs index 0384ff111b0..2d0997ece77 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShadergraphSpriteGUI.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/ShadergraphSpriteGUI.cs @@ -24,7 +24,7 @@ public override void FindProperties(MaterialProperty[] properties) public override void DrawSurfaceInputs(Material material) { - DrawShaderGraphProperties(material, properties); + DrawShaderGraphProperties(properties); } } } From 7254740f7bc9f8b73f1c7fbaf095f29f1ebbdefb Mon Sep 17 00:00:00 2001 From: Apoorva Joshi Date: Tue, 7 Apr 2026 17:59:29 +0000 Subject: [PATCH 50/88] Fix Height Transition slider not appearing on HDRP Layered Lit materials --- .../Editor/Material/UIBlocks/LitSurfaceInputsUIBlock.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/LitSurfaceInputsUIBlock.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/LitSurfaceInputsUIBlock.cs index cd635bf7a89..d2ffea7eb88 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/LitSurfaceInputsUIBlock.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/LitSurfaceInputsUIBlock.cs @@ -242,7 +242,6 @@ internal class Styles Features m_Features; int m_LayerCount; int m_LayerIndex; - bool m_UseHeightBasedBlend; bool isLayeredLit => m_LayerCount > 1; @@ -654,7 +653,7 @@ void DrawLayerOptionsGUI() materialEditor.ShaderProperty(useMainLayerInfluence, Styles.useMainLayerInfluenceModeText); materialEditor.ShaderProperty(useHeightBasedBlend, Styles.useHeightBasedBlendText); - if (m_UseHeightBasedBlend) + if (useHeightBasedBlend.floatValue > 0.0f) { EditorGUI.indentLevel++; materialEditor.ShaderProperty(heightTransition, Styles.heightTransition); From 79409d5c8dd0c71cfb65b7804c06ad910d16eb24 Mon Sep 17 00:00:00 2001 From: Sebastien Phaneuf Date: Tue, 7 Apr 2026 20:42:11 +0000 Subject: [PATCH 51/88] Search table view multi edit fixes --- .../Lighting/LightingSearchColumnProviders.cs | 5 + .../HDLightingSearchColumnProviders.cs | 238 +++++++----------- .../HDLightingSearchColumnProvidersTests.cs | 9 +- 3 files changed, 105 insertions(+), 147 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs index fb5500a16c0..0807c39e532 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs @@ -308,6 +308,7 @@ internal static string GetBakingMode(ProbeVolumeBakingSet bakingSet) internal static void SetBakingMode(ProbeVolumeBakingSet bakingSet, string mode) { + Undo.RecordObject(bakingSet, "Change Baking Mode"); bakingSet.singleSceneMode = (mode == "Single Scene"); } @@ -318,6 +319,7 @@ internal static int GetSkyOcclusionBakingSamples(ProbeVolumeBakingSet bakingSet) internal static void SetSkyOcclusionBakingSamples(ProbeVolumeBakingSet bakingSet, int samples) { + Undo.RecordObject(bakingSet, "Change Occlusion Baking"); bakingSet.skyOcclusionBakingSamples = samples; } @@ -334,6 +336,7 @@ internal static void SetVolumeMode(GameObject go, string mode) if (!go.TryGetComponent(out var volume)) return; + Undo.RecordObject(volume, "Change Volume Mode"); volume.isGlobal = (mode == "Global"); } @@ -350,6 +353,7 @@ internal static void SetVolumeProfile(GameObject go, VolumeProfile profile) if (!go.TryGetComponent(out var volume)) return; + Undo.RecordObject(volume, "Change Volume Profile"); volume.sharedProfile = profile; } @@ -368,6 +372,7 @@ internal static void SetLightShape(GameObject go, LightType value) if (IsLightShapeApplicable(value)) { + Undo.RecordObject(light, "Change light Shape"); light.type = value; } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/HDLightingSearchColumnProviders.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/HDLightingSearchColumnProviders.cs index 2a6ead6f038..15cfc3d5bfc 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/HDLightingSearchColumnProviders.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/HDLightingSearchColumnProviders.cs @@ -255,23 +255,18 @@ public static void ReflectionProbeResolutionSearchColumnProvider(SearchColumn co HDLightingSearchDataAccessors.SetReflectionProbeResolution(go, data); }; - column.cellCreator = _ => CreateImguiContainer(); - column.binder = (args, ve) => + column.drawer = args => { var go = args.item.data as GameObject ?? args.item.ToObject(); if (go == null || !go.TryGetComponent(out var hdProbe)) { - ve.visible = false; - return; + return args.value; } var reflectionProbeResolutionData = (HDLightingSearchDataAccessors.ReflectionProbeResolutionData)args.value; - - var imguiContainer = ve.Q(); switch (hdProbe.type) { case ProbeSettings.ProbeType.ReflectionProbe: - imguiContainer.onGUIHandler = () => { var rect = EditorGUILayout.GetControlRect(false, k_ImguiContainerHeight); var leftRect = new Rect(rect.x, rect.y, rect.width * k_RectLeftWidthRatio, rect.height); @@ -279,9 +274,7 @@ public static void ReflectionProbeResolutionSearchColumnProvider(SearchColumn co GUILayout.BeginHorizontal("box", GUILayout.ExpandWidth(true)); - EditorGUI.BeginChangeCheck(); - var (level, useOverride) = SerializedScalableSettingValueUI.LevelFieldGUI(leftRect, GUIContent.none, ScalableSettingSchema.GetSchemaOrNull(ScalableSettingSchemaId.With3Levels), reflectionProbeResolutionData.level, reflectionProbeResolutionData.useOverride); - + var (level, useOverride) = SerializedScalableSettingValueUI.LevelFieldGUI(leftRect, GUIContent.none, ScalableSettingSchema.GetSchemaOrNull(ScalableSettingSchemaId.With3Levels), reflectionProbeResolutionData.level, reflectionProbeResolutionData.useOverride); Enum overrideLevel; if (reflectionProbeResolutionData.useOverride) { @@ -294,54 +287,46 @@ public static void ReflectionProbeResolutionSearchColumnProvider(SearchColumn co overrideLevel = EditorGUI.EnumFlagsField(rightRect, reflectionProbeResolutionData.overrideLevel); } } - if(EditorGUI.EndChangeCheck()) - { - reflectionProbeResolutionData.level = level; - reflectionProbeResolutionData.useOverride = useOverride; - reflectionProbeResolutionData.overrideLevel = (CubeReflectionResolution)overrideLevel; - column.setter?.Invoke(new SearchColumnEventArgs(args.item, args.context, column) { value = reflectionProbeResolutionData }); - } + + reflectionProbeResolutionData.level = level; + reflectionProbeResolutionData.useOverride = useOverride; + reflectionProbeResolutionData.overrideLevel = (CubeReflectionResolution)overrideLevel; GUILayout.EndHorizontal(); }; break; case ProbeSettings.ProbeType.PlanarProbe: default: - imguiContainer.onGUIHandler = () => - { - var rect = EditorGUILayout.GetControlRect(false, k_ImguiContainerHeight); - var leftRect = new Rect(rect.x, rect.y, rect.width * k_RectLeftWidthRatio, rect.height); - var rightRect = new Rect(rect.x + rect.width * k_RectLeftWidthRatio, rect.y, rect.width * k_RectRightWidthRatio, rect.height); + { + var rect = EditorGUILayout.GetControlRect(false, k_ImguiContainerHeight); + var leftRect = new Rect(rect.x, rect.y, rect.width * k_RectLeftWidthRatio, rect.height); + var rightRect = new Rect(rect.x + rect.width * k_RectLeftWidthRatio, rect.y, rect.width * k_RectRightWidthRatio, rect.height); - GUILayout.BeginHorizontal("box", GUILayout.ExpandWidth(true)); + GUILayout.BeginHorizontal("box", GUILayout.ExpandWidth(true)); - EditorGUI.BeginChangeCheck(); - var (level, useOverride) = SerializedScalableSettingValueUI.LevelFieldGUI(leftRect, GUIContent.none, ScalableSettingSchema.GetSchemaOrNull(ScalableSettingSchemaId.With3Levels), reflectionProbeResolutionData.level, reflectionProbeResolutionData.useOverride); - - Enum overrideLevel; - if (reflectionProbeResolutionData.useOverride) - { - overrideLevel = EditorGUI.EnumPopup(rightRect, reflectionProbeResolutionData.overrideLevel); - } - else - { - using (new EditorGUI.DisabledScope(true)) - { - overrideLevel = EditorGUI.EnumFlagsField(rightRect, reflectionProbeResolutionData.overrideLevel); - } - } - if (EditorGUI.EndChangeCheck()) + var (level, useOverride) = SerializedScalableSettingValueUI.LevelFieldGUI(leftRect, GUIContent.none, ScalableSettingSchema.GetSchemaOrNull(ScalableSettingSchemaId.With3Levels), reflectionProbeResolutionData.level, reflectionProbeResolutionData.useOverride); + Enum overrideLevel; + if (reflectionProbeResolutionData.useOverride) + { + overrideLevel = EditorGUI.EnumPopup(rightRect, reflectionProbeResolutionData.overrideLevel); + } + else + { + using (new EditorGUI.DisabledScope(true)) { - reflectionProbeResolutionData.level = level; - reflectionProbeResolutionData.useOverride = useOverride; - reflectionProbeResolutionData.overrideLevel = (CubeReflectionResolution)overrideLevel; - column.setter?.Invoke(new SearchColumnEventArgs(args.item, args.context, column) { value = reflectionProbeResolutionData }); + overrideLevel = EditorGUI.EnumFlagsField(rightRect, reflectionProbeResolutionData.overrideLevel); } + } + + reflectionProbeResolutionData.level = level; + reflectionProbeResolutionData.useOverride = useOverride; + reflectionProbeResolutionData.overrideLevel = (CubeReflectionResolution)overrideLevel; - GUILayout.EndHorizontal(); - }; + GUILayout.EndHorizontal(); break; + } } + return reflectionProbeResolutionData; }; } @@ -369,55 +354,42 @@ public static void ContactShadowsSearchColumnProvider(SearchColumn column) HDLightingSearchDataAccessors.SetContactShadowsData(go, data); }; - column.cellCreator = _ => CreateImguiContainer(); - column.binder = (args, ve) => + column.drawer = args => { var go = args.item.data as GameObject ?? args.item.ToObject(); if (go == null || !go.TryGetComponent(out _)) { - ve.visible = false; - return; + return null; } - ve.visible = true; var contactShadowsData = (HDLightingSearchDataAccessors.ContactShadowsData)args.value; - var imguiContainer = ve.Q(); - imguiContainer.onGUIHandler = () => + var rect = EditorGUILayout.GetControlRect(false, k_ImguiContainerHeight); + var leftRect = new Rect(rect.x, rect.y, rect.width - k_ToggleWidth - 4f, rect.height); + var rightRect = new Rect(rect.xMax - k_ToggleWidth, rect.y, k_ToggleWidth, rect.height); + var (level, useOverride) = SerializedScalableSettingValueUI.LevelFieldGUI( + leftRect, + GUIContent.none, + ScalableSettingSchema.GetSchemaOrNull(ScalableSettingSchemaId.With3Levels), + contactShadowsData.level, + contactShadowsData.useOverride); + + contactShadowsData.level = level; + contactShadowsData.useOverride = useOverride; + + if (contactShadowsData.useOverride) { - var rect = EditorGUILayout.GetControlRect(false, k_ImguiContainerHeight); - var leftRect = new Rect(rect.x, rect.y, rect.width - k_ToggleWidth - 4f, rect.height); - var rightRect = new Rect(rect.xMax - k_ToggleWidth, rect.y, k_ToggleWidth, rect.height); - - EditorGUI.BeginChangeCheck(); - var (level, useOverride) = SerializedScalableSettingValueUI.LevelFieldGUI( - leftRect, - GUIContent.none, - ScalableSettingSchema.GetSchemaOrNull(ScalableSettingSchemaId.With3Levels), - contactShadowsData.level, - contactShadowsData.useOverride); - - contactShadowsData.level = level; - contactShadowsData.useOverride = useOverride; - - if (contactShadowsData.useOverride) - { - contactShadowsData.overrideValue = EditorGUI.Toggle(rightRect, contactShadowsData.overrideValue); - } - else - { - var hdrp = HDRenderPipeline.currentAsset; - var defaultValue = HDAdditionalLightData.ScalableSettings.UseContactShadow(hdrp); - using (new EditorGUI.DisabledScope(true)) - { - contactShadowsData.overrideValue = EditorGUI.Toggle(rightRect, defaultValue[contactShadowsData.level]); - } - } - - if (EditorGUI.EndChangeCheck()) + contactShadowsData.overrideValue = EditorGUI.Toggle(rightRect, contactShadowsData.overrideValue); + } + else + { + var hdrp = HDRenderPipeline.currentAsset; + var defaultValue = HDAdditionalLightData.ScalableSettings.UseContactShadow(hdrp); + using (new EditorGUI.DisabledScope(true)) { - column.setter?.Invoke(new SearchColumnEventArgs(args.item, args.context, column) { value = contactShadowsData }); + contactShadowsData.overrideValue = EditorGUI.Toggle(rightRect, defaultValue[contactShadowsData.level]); } - }; + } + return contactShadowsData; }; } @@ -435,58 +407,28 @@ public static void ShadowResolutionSearchColumnProvider(SearchColumn column) column.setter = args => { - if (args.value is not HDLightingSearchDataAccessors.ShadowResolutionData data) + if (args.value is not ShadowResolutionOption option) return; var go = args.item.data as GameObject ?? args.item.ToObject(); if (go == null) return; - HDLightingSearchDataAccessors.SetShadowResolutionData(go, data); + HDLightingSearchDataAccessors.SetShadowResolutionData(go, option); }; - column.cellCreator = _ => CreateImguiContainer(); - column.binder = (args, ve) => + column.drawer = args => { var go = args.item.data as GameObject ?? args.item.ToObject(); if (go == null || !go.TryGetComponent(out _)) { - ve.visible = false; - return; + return null; } - ve.visible = true; - var shadowResolutionData = (HDLightingSearchDataAccessors.ShadowResolutionData)args.value; - var imguiContainer = ve.Q(); - imguiContainer.onGUIHandler = () => - { - var rect = EditorGUILayout.GetControlRect(false, 20); - var currentOption = shadowResolutionData.useOverride - ? ShadowResolutionOption.Custom - : shadowResolutionData.level switch - { - <= 0 => ShadowResolutionOption.Low, - 1 => ShadowResolutionOption.Medium, - _ => ShadowResolutionOption.High - }; - - EditorGUI.BeginChangeCheck(); - var newOption = (ShadowResolutionOption)EditorGUI.EnumPopup(rect, currentOption); - if (EditorGUI.EndChangeCheck()) - { - if (newOption == ShadowResolutionOption.Custom) - { - shadowResolutionData.useOverride = true; - } - else - { - shadowResolutionData.useOverride = false; - shadowResolutionData.level = (int)newOption; - } - - column.setter?.Invoke(new SearchColumnEventArgs(args.item, args.context, column) { value = shadowResolutionData }); - } - }; + var currentOption = (ShadowResolutionOption)args.value; + var rect = EditorGUILayout.GetControlRect(false, 20); + var newOption = (ShadowResolutionOption)EditorGUI.EnumPopup(rect, currentOption); + return newOption; }; } @@ -580,13 +522,6 @@ public static void LightModeSearchColumnProvider(SearchColumn column) }; } - static VisualElement CreateImguiContainer() - { - var visualElement = new VisualElement() { style = { height = k_ImguiContainerHeight } }; - visualElement.Add(new IMGUIContainer() { style = { height = k_ImguiContainerHeight } }); - return visualElement; - } - static class HDLightingSearchDataAccessors { internal struct ReflectionProbeResolutionData @@ -603,12 +538,6 @@ internal struct ContactShadowsData public bool overrideValue; } - internal struct ShadowResolutionData - { - public int level; - public bool useOverride; - } - internal static float GetLightIntensity(GameObject go) { if (!go.TryGetComponent(out var light)) @@ -636,6 +565,7 @@ internal static void SetLightIntensity(GameObject go, float intensity) if (!LightUnitUtils.IsLightUnitSupported(lightType, lightUnit)) return; + Undo.RecordObject(light, "Change light intensity"); light.intensity = LightUnitUtils.ConvertIntensity(light, intensity, lightUnit, nativeUnit); } @@ -655,6 +585,7 @@ internal static void SetLightIntensityUnit(GameObject go, LightUnit unit) if (!LightUnitUtils.IsLightUnitSupported(light.type, unit)) return; + Undo.RecordObject(light, "Change light intensity unit"); light.lightUnit = unit; // Mark the light component as dirty so Unity's change detection system @@ -700,15 +631,20 @@ internal static ContactShadowsData GetContactShadowsData(GameObject go) return contactShadowsData; } - internal static ShadowResolutionData GetShadowResolutionData(GameObject go) + internal static ShadowResolutionOption GetShadowResolutionData(GameObject go) { - var shadowResolutionData = new ShadowResolutionData(); if (!go.TryGetComponent(out var lightData)) - return shadowResolutionData; + return ShadowResolutionOption.Custom; - shadowResolutionData.level = lightData.shadowResolution.level; - shadowResolutionData.useOverride = lightData.shadowResolution.useOverride; - return shadowResolutionData; + var currentOption = lightData.shadowResolution.useOverride + ? ShadowResolutionOption.Custom + : lightData.shadowResolution.level switch + { + <= 0 => ShadowResolutionOption.Low, + 1 => ShadowResolutionOption.Medium, + _ => ShadowResolutionOption.High + }; + return currentOption; } internal static void SetReflectionProbeResolution(GameObject go, ReflectionProbeResolutionData reflectionProbeResolutionData) @@ -716,6 +652,7 @@ internal static void SetReflectionProbeResolution(GameObject go, ReflectionProbe if (!go.TryGetComponent(out var hdProbe)) return; + Undo.RecordObject(hdProbe, "Change reflection probe resolution"); switch (hdProbe.type) { case ProbeSettings.ProbeType.ReflectionProbe: @@ -737,18 +674,27 @@ internal static void SetContactShadowsData(GameObject go, ContactShadowsData con if (!go.TryGetComponent(out var lightData)) return; + Undo.RecordObject(lightData, "Change contact shadow data"); lightData.useContactShadow.level = contactShadowsData.level; lightData.useContactShadow.useOverride = contactShadowsData.useOverride; lightData.useContactShadow.@override = contactShadowsData.overrideValue; } - internal static void SetShadowResolutionData(GameObject go, ShadowResolutionData shadowResolutionData) + internal static void SetShadowResolutionData(GameObject go, ShadowResolutionOption newOption) { if (!go.TryGetComponent(out var lightData)) return; - lightData.shadowResolution.level = shadowResolutionData.level; - lightData.shadowResolution.useOverride = shadowResolutionData.useOverride; + Undo.RecordObject(lightData, "Change shadow resolution"); + if (newOption == ShadowResolutionOption.Custom) + { + lightData.shadowResolution.useOverride = true; + } + else + { + lightData.shadowResolution.useOverride = false; + lightData.shadowResolution.level = (int)newOption; + } lightData.RefreshCachedShadow(); } @@ -765,6 +711,7 @@ internal static void SetRayTracingMode(GameObject go, UnityEngine.Experimental.R if (!go.TryGetComponent(out var meshRenderer)) return; + Undo.RecordObject(meshRenderer, "Change ray tracing mode"); meshRenderer.rayTracingMode = value; } @@ -785,6 +732,8 @@ internal static void SetLightMode(GameObject go, LightmapBakeType value) return; if (light.type == LightType.Tube || light.type == LightType.Disc) return; + + Undo.RecordObject(light, "Change light mode"); light.lightmapBakeType = value; EditorUtility.SetDirty(light); } @@ -809,6 +758,7 @@ internal static void SetLightShape(GameObject go, LightType value) if (IsLightShapeApplicable(value)) { + Undo.RecordObject(light, "Change light shape"); light.type = value; if (!LightUnitUtils.IsLightUnitSupported(value, light.lightUnit)) diff --git a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDLightingSearchColumnProvidersTests.cs b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDLightingSearchColumnProvidersTests.cs index 698c272abeb..566970cae25 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDLightingSearchColumnProvidersTests.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDLightingSearchColumnProvidersTests.cs @@ -418,7 +418,7 @@ public void ShadowResolution_Column_Getter_ReturnsShadowResolutionData() var getterResult = column.getter(args); Assert.IsNotNull(getterResult, "Getter should return a value"); - Assert.IsTrue(getterResult.GetType().Name.Contains("ShadowResolutionData"), "Getter should return ShadowResolutionData"); + Assert.IsTrue(getterResult.GetType().Name.Contains("ShadowResolutionOption"), "Getter should return ShadowResolutionOption"); } #endregion @@ -587,8 +587,11 @@ public void AllHDRPColumns_HaveValidConfiguration() }, $"Column initialization for {columnType} should not throw"); Assert.IsNotNull(column.getter, $"Column {columnType} should have a getter"); - Assert.IsNotNull(column.cellCreator, $"Column {columnType} should have a cell creator"); - Assert.IsNotNull(column.binder, $"Column {columnType} should have a binder"); + if (column.drawer == null) + { + Assert.IsNotNull(column.cellCreator, $"Column {columnType} should have a cell creator"); + Assert.IsNotNull(column.binder, $"Column {columnType} should have a binder"); + } Assert.IsNotNull(column.setter, $"Column {columnType} should have a setter"); } } From f84c9556dde84d1d1a83ed9001e3629ddb780f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Chapelain?= Date: Wed, 8 Apr 2026 00:53:45 +0000 Subject: [PATCH 52/88] [SRP] Fix warning on tutorial SRP Blank templates --- .../Assets/TutorialInfo/Scripts/Editor/ReadmeEditor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Editor/ReadmeEditor.cs b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Editor/ReadmeEditor.cs index f983e049c09..8ac4656ae69 100644 --- a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Editor/ReadmeEditor.cs +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Editor/ReadmeEditor.cs @@ -10,9 +10,8 @@ [InitializeOnLoad] public class ReadmeEditor : Editor { - static string s_ShowedReadmeSessionStateName = "ReadmeEditor.showedReadme"; - - static string s_ReadmeSourceDirectory = "Assets/TutorialInfo"; + static readonly string s_ShowedReadmeSessionStateName = "ReadmeEditor.showedReadme"; + static readonly string s_ReadmeSourceDirectory = "Assets/TutorialInfo"; const float k_Space = 16f; From dcbb44a369a46b9a7c9ac0ca9805b8d5de056289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Chapelain?= Date: Wed, 8 Apr 2026 08:21:15 +0000 Subject: [PATCH 53/88] [SRP] Fix building errors with RSUV sample --- .../Scripts/VertexAnimationTextureBaker.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.core/Samples~/RendererShaderUserValue_Common/Scripts/VertexAnimationTextureBaker.cs b/Packages/com.unity.render-pipelines.core/Samples~/RendererShaderUserValue_Common/Scripts/VertexAnimationTextureBaker.cs index ff61acfc6c2..6156d7c18ba 100644 --- a/Packages/com.unity.render-pipelines.core/Samples~/RendererShaderUserValue_Common/Scripts/VertexAnimationTextureBaker.cs +++ b/Packages/com.unity.render-pipelines.core/Samples~/RendererShaderUserValue_Common/Scripts/VertexAnimationTextureBaker.cs @@ -1,3 +1,4 @@ +#if UNITY_EDITOR using UnityEngine; using UnityEditor; using System.Collections.Generic; @@ -122,4 +123,5 @@ void BakeVATArray(GameObject target, List clips, int fps) Debug.Log($"VAT Array (RGBAHalf) baked: {path} with {clips.Count} clips. Max frames = {maxFrames}"); } -} \ No newline at end of file +} +#endif \ No newline at end of file From 5a841a8602ce235bfe7c0120ba9356d7292d03d5 Mon Sep 17 00:00:00 2001 From: Jesper Mortensen Date: Wed, 8 Apr 2026 14:17:16 +0000 Subject: [PATCH 54/88] Fix UUM-133347: Enable shadow radius for pyramid lights in light baking --- .../Editor/PathTracing/BakeInputToWorldConversion.cs | 4 +++- .../Runtime/Lighting/GlobalIlluminationUtils.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs index c4f800a120f..89ac8f38bcd 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs @@ -319,7 +319,9 @@ static Vector2 GetPyramidLightRect(float coneAngleInRads, float pyramidAspectRad static float GetLightShadowRadius(UnityEngine.LightType lightType, in LightData lightData) { - return (Util.IsPunctualLightType(lightType) && lightType != UnityEngine.LightType.Pyramid && lightType != UnityEngine.LightType.Box) ? lightData.shape0 : 0.0f; + if (lightType == UnityEngine.LightType.Pyramid) + return lightData.shape1; // For pyramid lights, shadow radius is in shape1 (shape0 is aspect ratio) + return (Util.IsPunctualLightType(lightType) && lightType != UnityEngine.LightType.Box) ? lightData.shape0 : 0.0f; } internal static void InjectEnvironmentLight( diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/GlobalIlluminationUtils.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/GlobalIlluminationUtils.cs index 69b76f48fec..0cfa1069ef7 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/GlobalIlluminationUtils.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/GlobalIlluminationUtils.cs @@ -134,6 +134,11 @@ public static bool LightDataGIExtract(Light light, ref LightDataGI lightDataGI) pyramid.entityId = light.GetEntityId(); pyramid.shadow = light.shadows != LightShadows.None; pyramid.mode = lightMode; +#if UNITY_EDITOR + pyramid.sphereRadius = light.shadows != LightShadows.None ? light.shapeRadius : 0.0f; +#else + pyramid.sphereRadius = 0.0f; +#endif pyramid.position = light.transform.position; pyramid.orientation = light.transform.rotation; pyramid.color = directColor; From 8b6a5c0e2562403930ffb86cc01277a326321c28 Mon Sep 17 00:00:00 2001 From: Paul Demeulenaere Date: Wed, 8 Apr 2026 14:17:17 +0000 Subject: [PATCH 55/88] [VFX] Add Test Coverage for Readback --- .../Scenes/Readback_ParticleCount.unity | 3 + .../Scenes/Readback_ParticleCount.unity.meta | 7 + .../Readback_ParticleCount_01_Simple.vfx | 3 + .../Readback_ParticleCount_01_Simple.vfx.meta | 16 +++ .../Readback_ParticleCount_02_GPUEvent.vfx | 3 + ...eadback_ParticleCount_02_GPUEvent.vfx.meta | 16 +++ .../Tests/Runtime/VFXRuntimeTests.cs | 127 +++++++++++++++++- .../HDRP_VisualEffectsGraph_GraphicsTests.cs | 1 + 8 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity create mode 100644 Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity.meta create mode 100644 Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx create mode 100644 Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx.meta create mode 100644 Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx create mode 100644 Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx.meta diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity new file mode 100644 index 00000000000..76c4ce37dac --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3102ad7d47a502c9ac99221e2df5169c5d31f8652085331cb52289a4bfe0e85 +size 13264 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity.meta b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity.meta new file mode 100644 index 00000000000..dd2901d1b58 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ebcba28bbe1f6dc47bc4cf3e85e53efa +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: scene_in_assetbundle + assetBundleVariant: diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx new file mode 100644 index 00000000000..cd326cfeef1 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cad10e689479a01ff75ca3c574ac156bd5cb778fb47d33bbf2cc767835f479bd +size 72110 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx.meta b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx.meta new file mode 100644 index 00000000000..0330be0ed05 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_01_Simple.vfx.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: b165df6abbc86014794d373dbb099075 +VisualEffectImporter: + externalObjects: {} + serializedVersion: 2 + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 + useAsTemplate: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx new file mode 100644 index 00000000000..a3dbc805ba9 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49ee57589629026efcee5f9a8df4c22c4b20a3f60de8bd6b1ed1ce6eb2be1e6d +size 153063 diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx.meta b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx.meta new file mode 100644 index 00000000000..0e0e0db09a2 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount_02_GPUEvent.vfx.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 9da5694681a0d6d4abb5684a6e85677a +VisualEffectImporter: + externalObjects: {} + serializedVersion: 2 + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 + useAsTemplate: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/VFXRuntimeTests.cs b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/VFXRuntimeTests.cs index 7ecb3d624fe..16fd0a4003f 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/VFXRuntimeTests.cs +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Tests/Runtime/VFXRuntimeTests.cs @@ -24,7 +24,7 @@ public class VFXRuntimeTests AssetBundle m_AssetBundle; [OneTimeSetUp] - public void SetUp() + public void OneTimeSetUp() { m_AssetBundle = AssetBundleHelper.Load("scene_in_assetbundle"); } @@ -779,8 +779,131 @@ public IEnumerator Cover_ReloadAssetCacheIfNeeded() yield return null; } - [OneTimeTearDown] + int m_PreviousCaptureFrameRate; + float m_PreviousFixedTimeStep; + float m_PreviousMaxDeltaTime; + [SetUp] + public void Init() + { + m_PreviousCaptureFrameRate = Time.captureFramerate; + m_PreviousFixedTimeStep = VFXManager.fixedTimeStep; + m_PreviousMaxDeltaTime = VFXManager.maxDeltaTime; + } + + static string[] kVerify_AliveParticleCount_ReadbackCase = new []{"01_Simple", "02_GPUEvent"}; + + enum TrendState + { + Rising, + Plateau, + Falling + } + static bool IsUpPlateauDown(List<(int frame, int count)> curve, int eps = 8) + { + var state = TrendState.Rising; + for (var i = 1; i < curve.Count; i++) + { + var diff = curve[i].count - curve[i - 1].count; + if (diff > eps) + { + if (state != TrendState.Rising) + return false; + } + else if (diff < -eps) + { + state = TrendState.Falling; + } + else + { + if (state == TrendState.Rising) + state = TrendState.Plateau; + } + } + return state == TrendState.Falling; + } + + [UnityTest, Description("Cover internal behavior linked to readback of alive particle count")] + public IEnumerator Verify_AliveParticleCount_Readback([ValueSource(nameof(kVerify_AliveParticleCount_ReadbackCase))] string currentName) + { + //Prepare + SceneManagement.SceneManager.LoadScene("Packages/com.unity.testing.visualeffectgraph/Scenes/Readback_ParticleCount.unity"); + yield return null; + + var baseName = "Cover_Readback_ParticleCount_"; + var gameObject = GameObject.Find(baseName + currentName); + Assert.IsNotNull(gameObject); + for (int i = 0; i < SceneManagement.SceneManager.sceneCount; i++) + { + var scene = SceneManagement.SceneManager.GetSceneAt(i); + var roots = scene.GetRootGameObjects(); + foreach (var rootGameObject in roots) + { + var currentVfx = rootGameObject.GetComponent(); + if (currentVfx != null) + rootGameObject.SetActive(false); + } + } + + int captureFrameRate = 120; + float period = 1.0f / captureFrameRate; + Time.captureFramerate = captureFrameRate; + VFXManager.fixedTimeStep = period; + VFXManager.maxDeltaTime = period; + yield return null; + + var vfx = gameObject.GetComponent(); + Assert.IsNotNull(vfx); + Assert.IsFalse(vfx.aliveParticleCount > 0); + Assert.IsFalse(vfx.HasAnySystemAwake()); + gameObject.SetActive(true); + + //Wait for the first particle spawned before starting the recording + int maxFrame = 64; + while (maxFrame-- > 0 && vfx.aliveParticleCount <= 0) + { + yield return null; + } + Assert.IsTrue(maxFrame > 0); + Assert.IsTrue(vfx.aliveParticleCount > 0); + Assert.IsTrue(vfx.HasAnySystemAwake()); + + maxFrame = captureFrameRate * 6; + int currentFrame = 0; + var readbackCount = new List<(int frame,int count)>(maxFrame); + readbackCount.Add((0, vfx.aliveParticleCount)); + do + { + yield return null; + if (readbackCount[^1].count != vfx.aliveParticleCount) + readbackCount.Add((currentFrame, vfx.aliveParticleCount)); + } while (++currentFrame < maxFrame && vfx.aliveParticleCount != 0); + + //Every test should produce an Uluru shaped signal + bool valid = IsUpPlateauDown(readbackCount); + Assert.IsTrue(valid, $"Unexpected particle count signal: {string.Join(", ", readbackCount)}"); + + Assert.IsTrue(currentFrame < maxFrame); + Assert.IsTrue(vfx.aliveParticleCount == 0); + + //Wait for all system sleeping + maxFrame = 128; + while (maxFrame-- > 0 && vfx.HasAnySystemAwake()) + yield return null; + Assert.IsTrue(maxFrame > 0); + Assert.IsFalse(vfx.aliveParticleCount > 0); + Assert.IsFalse(vfx.HasAnySystemAwake()); + } + + [TearDown] public void TearDown() + { + Time.captureFramerate = m_PreviousCaptureFrameRate; + VFXManager.fixedTimeStep = m_PreviousFixedTimeStep; + VFXManager.maxDeltaTime = m_PreviousMaxDeltaTime; + } + + [OneTimeTearDown] + public void OneTimeTearDown() { AssetBundleHelper.Unload(m_AssetBundle); } diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs index 2f33b42bc36..6fbc7dae4c4 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs @@ -40,6 +40,7 @@ public class VFXGraphicsTests [IgnoreGraphicsTest("Timeline_FirstFrame", "No reference images provided")] [IgnoreGraphicsTest("NamedObject_ExposedProperties", "No reference images provided")] [IgnoreGraphicsTest("PrewarmCompute", "No reference images provided")] + [IgnoreGraphicsTest("Readback_ParticleCount", "No reference images provided")] [MockHmdSetup(99)] [AssetBundleSetup] From a43f5936467d3c58bca7ce7633407dd7471a4e1a Mon Sep 17 00:00:00 2001 From: Pema Malling Date: Thu, 9 Apr 2026 01:07:15 +0000 Subject: [PATCH 56/88] Fix HiZ marcher on OpenGL for URP SSR --- .../Runtime/Textures/TextureXR.cs | 1 + .../ShaderLibrary/TextureXR.hlsl | 2 +- .../ScreenSpaceReflectionPass.cs | 12 ++++-- ...creenSpaceReflectionPersistentResources.cs | 9 ++++ .../ScreenSpaceReflectionRendererFeature.cs | 14 ++++-- .../ComputeScreenSpaceReflection.hlsl | 9 ++-- .../Shaders/Utils/BlitFullPrecision.shader | 43 +++++++++++++++++++ .../Utils/BlitFullPrecision.shader.meta | 9 ++++ 8 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Textures/TextureXR.cs b/Packages/com.unity.render-pipelines.core/Runtime/Textures/TextureXR.cs index 2e12b56c106..52eab9e0f46 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Textures/TextureXR.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Textures/TextureXR.cs @@ -44,6 +44,7 @@ public static bool useTexArray case GraphicsDeviceType.Vulkan: case GraphicsDeviceType.Metal: case GraphicsDeviceType.OpenGLES3: + case GraphicsDeviceType.OpenGLCore: return true; default: diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl index 00635d88764..70c672c537d 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl @@ -7,7 +7,7 @@ // single-pass doule-wide is deprecated // Must be in sync with C# with property useTexArray in TextureXR.cs -#if (defined(SHADER_API_D3D11) && !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_GAMECORE)) || defined(SHADER_API_PSSL) || defined(SHADER_API_VULKAN) || defined(SHADER_API_METAL) +#if (defined(SHADER_API_D3D11) && !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_GAMECORE)) || defined(SHADER_API_PSSL) || defined(SHADER_API_VULKAN) || defined(SHADER_API_METAL) || defined(SHADER_API_GLES3) || (defined(SHADER_API_GLCORE) && !defined(SHADER_API_SWITCH) && !defined(SHADER_API_SWITCH2)) #define UNITY_TEXTURE2D_X_ARRAY_SUPPORTED #endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs index 4cabadbde5c..86b8c69be41 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs @@ -81,6 +81,7 @@ internal static class ShaderConstants // Private Variables Material m_Material; + Material m_BlitMaterial; LocalKeywordSet m_LocalKeywords; bool m_AfterOpaque; @@ -117,9 +118,10 @@ public void Dispose() m_MipGenerator.Release(); } - internal bool Setup(ScriptableRenderer renderer, Material material, bool afterOpaque, UniversalRenderingData renderingData, CameraType cameraType) + internal bool Setup(ScriptableRenderer renderer, Material material, Material blitMaterial, bool afterOpaque, UniversalRenderingData renderingData, CameraType cameraType) { m_AfterOpaque = afterOpaque; + m_BlitMaterial = blitMaterial; if (m_Material != material) { @@ -159,7 +161,7 @@ internal bool Setup(ScriptableRenderer renderer, Material material, bool afterOp ConfigureInput(requiredInputs); - return m_Material != null; + return m_Material != null && m_BlitMaterial != null; } @@ -253,7 +255,8 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer { using (new RenderGraphProfilingScope(renderGraph, m_DepthPyramidSampler)) { - renderGraph.AddBlitPass(cameraDepthTexture, depthPyramidTexture, new(1f, 2f), Vector2.zero, filterMode: BlitFilterMode.ClampNearest, passName: "Copy depth to mip 0"); + var blitParam = new BlitMaterialParameters(cameraDepthTexture, depthPyramidTexture, new(1f, 2f), Vector2.zero, m_BlitMaterial, 0); + renderGraph.AddBlitPass(blitParam, passName: "Copy depth to mip 0"); m_PackedMipChainInfo.ComputePackedMipChainInfo(new Vector2Int(cameraData.cameraTargetDescriptor.width / (int)settings.resolution.value, cameraData.cameraTargetDescriptor.height / (int)settings.resolution.value), 0); m_MipGenerator.RenderMinDepthPyramid(renderGraph, depthPyramidTexture, ref m_PackedMipChainInfo); } @@ -441,7 +444,8 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer if (settings.upscalingMethod == UpscalingMethod.None) { - renderGraph.AddBlitPass(ssrTexture, upscaleTexture, Vector2.one, Vector2.zero, passName: "Nearest", filterMode: RenderGraphModule.Util.RenderGraphUtils.BlitFilterMode.ClampNearest); + var blitParam = new BlitMaterialParameters(ssrTexture, upscaleTexture, Vector2.one, Vector2.zero, m_BlitMaterial, 0); + renderGraph.AddBlitPass(blitParam, passName: "Nearest"); } else if (settings.upscalingMethod == UpscalingMethod.Kawase) { diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs index 24db207ece8..020cbfbc10d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs @@ -12,12 +12,21 @@ class ScreenSpaceReflectionPersistentResources : IRenderPipelineResources [SerializeField] [ResourcePath("Shaders/Utils/ComputeScreenSpaceReflection.shader")] Shader m_Shader; + [SerializeField] [ResourcePath("Shaders/Utils/BlitFullPrecision.shader")] + Shader m_BlitShader; + public Shader Shader { get => m_Shader; set => this.SetValueAndNotify(ref m_Shader, value); } + public Shader BlitShader + { + get => m_BlitShader; + set => this.SetValueAndNotify(ref m_BlitShader, value); + } + public bool isAvailableInPlayerBuild => true; [SerializeField] [HideInInspector] diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs index 165157c34cb..cf354590ca6 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs @@ -19,6 +19,9 @@ public class ScreenSpaceReflectionRendererFeature : ScriptableRendererFeature Shader m_Shader = null; Material m_Material = null; + Shader m_BlitShader = null; + Material m_BlitMaterial = null; + /// public override void Create() { @@ -33,6 +36,7 @@ protected override void Dispose(bool disposing) m_TransparentDepthNormalPass = null; m_SSRPass = null; CoreUtils.Destroy(m_Material); + CoreUtils.Destroy(m_BlitMaterial); } /// @@ -58,7 +62,7 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD if (!settings.linearMarching.value && !SystemInfo.supportsComputeShaders) Debug.LogWarning("Screen Space Reflection settings are incompatible with the current platform. Linear Marching must be enabled on platforms without computer shader support. Falling back to linear marching."); - bool shouldAdd = m_SSRPass.Setup(renderer, m_Material, afterOpaque, universalRenderingData, universalCameraData.cameraType); + bool shouldAdd = m_SSRPass.Setup(renderer, m_Material, m_BlitMaterial, afterOpaque, universalRenderingData, universalCameraData.cameraType); if (shouldAdd) { if (settings.ShouldRenderTransparents()) @@ -80,7 +84,7 @@ bool TryPrepareResources(LayerMask transparentLayerMask, ScreenSpaceReflectionVo m_TransparentDepthNormalPass = new(RenderPassEvent.AfterRenderingPrePasses, RenderQueueRange.transparent, transparentLayerMask); } - if (m_Shader == null) + if (m_Shader == null || m_BlitShader == null) { if (!GraphicsSettings.TryGetRenderPipelineSettings(out var ssrPersistentResources)) { @@ -90,12 +94,16 @@ bool TryPrepareResources(LayerMask transparentLayerMask, ScreenSpaceReflectionVo } m_Shader = ssrPersistentResources.Shader; + m_BlitShader = ssrPersistentResources.BlitShader; } if (m_Material == null && m_Shader != null) m_Material = CoreUtils.CreateEngineMaterial(m_Shader); - if (m_Material == null) + if (m_BlitMaterial == null && m_BlitShader != null) + m_BlitMaterial = CoreUtils.CreateEngineMaterial(m_BlitShader); + + if (m_Material == null || m_BlitMaterial == null) { Debug.LogError($"{GetType().Name}.AddRenderPasses(): Missing material. {name} render pass will not be added."); return false; diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl index 5d5222cedae..299a22ca5d3 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl @@ -217,7 +217,7 @@ bool TraceScreenSpaceRayHiZ( float3 raySign = float3(rcpRayDir.x >= 0 ? 1 : -1, rcpRayDir.y >= 0 ? 1 : -1, rcpRayDir.z >= 0 ? 1 : -1); - bool rayTowardsEye = rcpRayDir.z >= 0; + bool rayTowardsEye = COMPARE_DEVICE_DEPTH_CLOSEREQUAL(rcpRayDir.z, 0); // Extend and clip the end point to the frustum. float tMax; @@ -230,7 +230,10 @@ bool TraceScreenSpaceRayHiZ( bounds.y = (rcpRayDir.y >= 0) ? screenSize.y - halfTexel : halfTexel; // If we do not want to intersect the skybox, it is more efficient to not trace too far. float maxDepth = (_ReflectSky != 0) ? -0.00000024 : 0.00000024; // 2^-22 - bounds.z = (rcpRayDir.z >= 0) ? 1 : maxDepth; + #if !defined(UNITY_REVERSED_Z) + maxDepth = 1.0-maxDepth; + #endif + bounds.z = rayTowardsEye ? (1.0-UNITY_RAW_FAR_CLIP_VALUE) : maxDepth; float3 dist = bounds * rcpRayDir - (rayOrigin * rcpRayDir); tMax = Min3(dist.x, dist.y, dist.z); @@ -326,7 +329,7 @@ bool TraceScreenSpaceRayHiZ( } // Treat intersections with the sky as misses. - miss = miss || ((_ReflectSky == 0) && (rayPos.z == 0)); + miss = miss || ((_ReflectSky == 0) && (rayPos.z == UNITY_RAW_FAR_CLIP_VALUE)); hit = hit && !miss; rayHitPosNDC = float3(floor(rayPos.xy) / screenSize + (0.5 / screenSize), rayPos.z); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader new file mode 100644 index 00000000000..4ac4053f381 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader @@ -0,0 +1,43 @@ +Shader "Hidden/Universal/BlitFullPrecision" +{ + HLSLINCLUDE + #pragma target 2.0 + #pragma editor_sync_compilation + + #define USE_FULL_PRECISION_BLIT_TEXTURE + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + ENDHLSL + + SubShader + { + Tags{ "RenderPipeline" = "UniversalPipeline" } + + // 0: Nearest + Pass + { + ZWrite Off ZTest Always Blend Off Cull Off + Name "Nearest" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FragNearest + ENDHLSL + } + + // 1: Bilinear + Pass + { + ZWrite Off ZTest Always Blend Off Cull Off + Name "Bilinear" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FragBilinear + ENDHLSL + } + } + + Fallback Off +} diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader.meta new file mode 100644 index 00000000000..3d8e1b004c5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/BlitFullPrecision.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 815c625bb9d4fe240a4ccf42ca3899cb +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: From e0e284f1b6dfa1519f5b754306427267a972a5de Mon Sep 17 00:00:00 2001 From: Ludovic Theobald Date: Thu, 9 Apr 2026 01:07:17 +0000 Subject: [PATCH 57/88] [VFX] Fix root allocations and implement memory profiler meta data for VFX --- .../Editor/Compiler/VFXGraphCompiledData.cs | 6 ++++-- .../Editor/Data/VFXDataParticle.cs | 9 ++++----- .../Editor/Inspector/VFXAssetEditor.cs | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs index 827fac12367..bea24d4030b 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs @@ -648,7 +648,8 @@ private static void FillSpawner(Dictionary outContextSpaw capacity = 1u, stride = graph.GlobalEventAttributes.First().offset.structure, layout = graph.GlobalEventAttributes.ToArray(), - initialData = ComputeArrayOfStructureInitialData(graph.GlobalEventAttributes, vfxGraph) + initialData = ComputeArrayOfStructureInitialData(graph.GlobalEventAttributes, vfxGraph), + debugName = $"VFXSpawnerAttributeBuffer_{it.index}" }); } foreach (var spawnContext in spawners) @@ -1265,7 +1266,8 @@ public VFXCompileOutput Compile(VFXCompilationMode compilationMode, bool enableS capacity = 1u, layout = m_ExpressionGraph.GlobalEventAttributes.ToArray(), stride = m_ExpressionGraph.GlobalEventAttributes.Any() ? m_ExpressionGraph.GlobalEventAttributes.First().offset.structure : 0u, - initialData = ComputeArrayOfStructureInitialData(m_ExpressionGraph.GlobalEventAttributes, m_Graph) + initialData = ComputeArrayOfStructureInitialData(m_ExpressionGraph.GlobalEventAttributes, m_Graph), + debugName = "VFXGlobalEventAttributeBuffer" }); var contextSpawnToSpawnInfo = new Dictionary(); diff --git a/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs b/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs index 5337c336742..db211b9da28 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs @@ -15,7 +15,7 @@ interface ILayoutProvider string GetCodeOffset(VFXAttribute attrib, uint capacity, string index, string instanceIndex); uint GetBufferSize(uint capacity); - VFXGPUBufferDesc GetBufferDesc(uint capacity, ComputeBufferMode mode = ComputeBufferMode.Immutable); + VFXGPUBufferDesc GetBufferDesc(uint capacity, ComputeBufferMode mode, string debugName); } class StructureOfArrayProvider : ILayoutProvider @@ -145,7 +145,7 @@ public uint GetBufferSize(uint capacity) return (uint)m_BucketOffsets.LastOrDefault() + capacity * (uint)m_BucketSizes.LastOrDefault(); } - public VFXGPUBufferDesc GetBufferDesc(uint capacity, ComputeBufferMode mode = ComputeBufferMode.Immutable) + public VFXGPUBufferDesc GetBufferDesc(uint capacity, ComputeBufferMode mode = ComputeBufferMode.Immutable, string debugName = "VFXAttributeBuffer") { var layout = m_AttributeLayout.Select(o => new VFXLayoutElementDesc() { @@ -160,7 +160,7 @@ public VFXGPUBufferDesc GetBufferDesc(uint capacity, ComputeBufferMode mode = Co }); return new VFXGPUBufferDesc() { - debugName = "VFXAttributeBuffer", + debugName = debugName, target = GraphicsBuffer.Target.Raw, size = GetBufferSize(capacity), stride = 4, @@ -873,7 +873,7 @@ public override void FillDescs( } attributeSourceBufferIndex = outBufferDescs.Count; - outBufferDescs.Add(m_layoutAttributeSource.GetBufferDesc(staticSourceCount, ComputeBufferMode.Dynamic)); + outBufferDescs.Add(m_layoutAttributeSource.GetBufferDesc(staticSourceCount, ComputeBufferMode.Dynamic, "VFXSourceAttributeBuffer")); } if (attributeSourceBufferIndex != -1) @@ -890,7 +890,6 @@ public override void FillDescs( if (hasKill) { systemFlag |= VFXSystemFlag.SystemHasKill; - if (!hasStrip) // No dead list for strips { deadListBufferIndex = outBufferDescs.Count; diff --git a/Packages/com.unity.visualeffectgraph/Editor/Inspector/VFXAssetEditor.cs b/Packages/com.unity.visualeffectgraph/Editor/Inspector/VFXAssetEditor.cs index c1aec112305..2fb0e1cb796 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Inspector/VFXAssetEditor.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Inspector/VFXAssetEditor.cs @@ -263,7 +263,6 @@ private void CreateVisualEffect() m_VisualEffectGO = new GameObject("VisualEffect (Preview)"); - m_VisualEffectGO.hideFlags = HideFlags.DontSave; m_VisualEffect = m_VisualEffectGO.AddComponent(); m_VisualEffect.pause = true; m_RemainingFramesToRender = 1; @@ -276,6 +275,8 @@ private void CreateVisualEffect() VisualEffectAsset vfxTarget = target as VisualEffectAsset; m_VisualEffect.visualEffectAsset = vfxTarget; + m_VisualEffectGO.hideFlags = HideFlags.DontSave; + m_CurrentBounds = new Bounds(Vector3.zero, Vector3.one); m_Distance = null; m_Angles = Vector2.zero; From 1a0ad9eeec255a9b5666c5addfb7bb09e239ce17 Mon Sep 17 00:00:00 2001 From: Paul Demeulenaere Date: Thu, 9 Apr 2026 01:07:26 +0000 Subject: [PATCH 58/88] [VFX] Disable Instable GraphicsTest on Switch --- .../Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs index 6fbc7dae4c4..4366d6bc71f 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/Tests/HDRP_VisualEffectsGraph_GraphicsTests.cs @@ -28,6 +28,7 @@ public class VFXGraphicsTests [IgnoreGraphicsTest("026_RWBuffer", "Unstable: https://jira.unity3d.com/browse/UUM-119810")] [IgnoreGraphicsTest("36_SkinnedSDF", "See UUM-66822 and VFXG-539", RuntimePlatform.GameCoreXboxOne, RuntimePlatform.Switch)] [IgnoreGraphicsTest("39_SmokeLighting_APV", "Too many bindings when using APVs", RuntimePlatform.Switch)] + [IgnoreGraphicsTest("44_SDFBakerSlices", "See UUM-139282", RuntimePlatform.Switch)] [IgnoreGraphicsTest("102_ShadergraphShadow", "See UUM-96202", RuntimePlatform.Switch)] [IgnoreGraphicsTest("015_FixedTime", "See UUM-109089", RuntimePlatform.Switch)] [IgnoreGraphicsTest("DebugAlbedo", "Onscreen assert", RuntimePlatform.Switch2)] From 5cb5d5f8c19af7bf6ff1cc7bbe2c519edca073c2 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Thu, 9 Apr 2026 15:04:01 +0000 Subject: [PATCH 59/88] Updated `WaterDecal` and `WaterSurface` to work with CoreCLR --- .../Runtime/Water/WaterDecal/WaterDecal.cs | 9 +++ .../Water/WaterSurface/WaterSurface.cs | 60 ++++++++++++------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs index c60fba01840..224c299d2cf 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs @@ -163,5 +163,14 @@ private void OnDisable() UnregisterInstance(this); } #endregion + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + instances?.Clear(); + instances = new List(); + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs index abec4991a27..28ff702373d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs @@ -1,10 +1,11 @@ using System; +using System.Buffers; using System.Collections.Generic; -using UnityEditor; using Unity.Mathematics; using UnityEngine.Serialization; #if UNITY_EDITOR +using UnityEditor; using UnityEditor.SceneManagement; #endif @@ -87,39 +88,58 @@ public partial class WaterSurface : MonoBehaviour #region Instance Management // Management to avoid memory allocations at fetch time // NOTE: instances tracks active instances, disabled instances can exist and are not included. - internal static HashSet instances = new HashSet(); + static HashSet instances = new HashSet(); internal static WaterSurface[] instancesAsArray = null; - internal static int instanceCount = 0; + internal static int instanceCount => instances.Count; - internal static void RegisterInstance(WaterSurface surface) + static void RegisterInstance(WaterSurface surface) { - instances.Add(surface); - instanceCount = instances.Count; - if (instanceCount > 0) + if (instances.Add(surface)) { - instancesAsArray = new WaterSurface[instanceCount]; + if (instancesAsArray == null || instanceCount > instancesAsArray.Length) + { + if (instancesAsArray != null) + { + ArrayPool.Shared.Return(instancesAsArray, true); + } + + instancesAsArray = ArrayPool.Shared.Rent(instanceCount); + } + instances.CopyTo(instancesAsArray); } - else - { - instancesAsArray = null; - } } - internal static void UnregisterInstance(WaterSurface surface) + static void UnregisterInstance(WaterSurface surface) { - instances.Remove(surface); - instanceCount = instances.Count; - if (instanceCount > 0) + if (instances.Remove(surface)) { - instancesAsArray = new WaterSurface[instanceCount]; - instances.CopyTo(instancesAsArray); + if (instanceCount > 0) + { + instances.CopyTo(instancesAsArray); + } + else + { + ArrayPool.Shared.Return(instancesAsArray, true); + instancesAsArray = null; + } } - else + } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + instances?.Clear(); + instances = new HashSet(); + + if (instancesAsArray != null) { + ArrayPool.Shared.Return(instancesAsArray, true); instancesAsArray = null; } } +#endif #endregion #region Water General @@ -209,7 +229,7 @@ internal static void UnregisterInstance(WaterSurface surface) public float tessellationFactorFadeRange = 1850.0f; #if UNITY_EDITOR - static internal bool IsWaterMaterial(Material material) + internal static bool IsWaterMaterial(Material material) { return material.shader.FindSubshaderTagValue(0, (ShaderTagId)"ShaderGraphTargetId").name == "WaterSubTarget"; } From d80c2c63c3cf8268086fd09d72fdb9e525afd7cf Mon Sep 17 00:00:00 2001 From: Arttu Peltonen Date: Thu, 9 Apr 2026 15:04:01 +0000 Subject: [PATCH 60/88] Reset static variables for CoreCLR / Fast Enter Play Mode (SRP Core Team, render-pipelines.core package) --- .../Runtime/Camera/FreeCamera.cs | 18 ++++++------- .../CommandBuffers/CommandBufferHelpers.cs | 6 +++++ .../Runtime/Common/CommandBufferPool.cs | 8 ++++++ .../Runtime/Common/ComponentSingleton.cs | 25 ++++++++++++++++++ .../Runtime/Common/ConstantBuffer.cs | 10 ++++++- .../Runtime/Common/ContextContainer.cs | 5 ++++ .../Common/DynamicResolutionHandler.cs | 21 +++++++++++++++ .../Debugging/DebugDisplaySettingsVolumes.cs | 2 +- .../Runtime/Debugging/DebugShapes.cs | 8 ++++++ .../Runtime/Debugging/DebugUI.Fields.cs | 2 +- .../Runtime/Debugging/DebugUpdater.cs | 8 ++++++ .../Debugging/FrameTiming/FrameTimeSample.cs | 12 ++++----- .../Runtime/Debugging/MousePositionDebug.cs | 8 ++++++ .../Runtime/Debugging/ProfilingScope.cs | 2 +- .../Runtime/Deprecated.cs | 12 ++++++--- .../Compiler/FixedAttachmentArray.cs | 2 +- .../Compiler/NativePassCompiler.cs | 8 +++++- .../Debug/RenderGraphDebugSession.cs | 14 ++++++++-- .../RenderGraphPlayerRemoteDebugSession.cs | 1 + .../RenderGraph.ExceptionMessages.cs | 4 ++- .../Runtime/RenderGraph/RenderGraph.cs | 23 +++++++++++++--- .../RenderGraphCompilationCache.cs | 18 +++++++++---- .../RenderGraph/RenderGraphObjectPool.cs | 26 ++++++++++++++----- .../Runtime/RenderGraph/RenderGraphPass.cs | 9 +++++++ ...enderGraphResourceAccelerationStructure.cs | 2 +- .../RenderGraph/RenderGraphResourceBuffer.cs | 2 +- .../RenderGraph/RenderGraphResourcePool.cs | 2 +- .../RenderGraphResourceRegistry.cs | 13 +++++++--- .../RenderGraph/RenderGraphResourceTexture.cs | 10 ++++++- .../RenderGraph/RenderGraphResources.cs | 10 ++++++- .../RenderGraph/RenderGraphUtilsBlit.cs | 12 +++++++-- .../RenderPipelineGlobalSettings.cs | 3 +++ .../Runtime/Textures/RTHandle.cs | 8 ++++++ .../Runtime/Textures/RTHandles.cs | 9 +++++++ .../Runtime/Utilities/Blitter.cs | 23 +++++++++++++++- .../Runtime/Utilities/CameraCaptureBridge.cs | 11 +++++++- .../Runtime/Utilities/ColorUtils.cs | 16 ++++++++++-- .../Runtime/Utilities/CoreUtils.cs | 14 +++++++--- .../Runtime/Volume/VolumeDebugData.cs | 10 ++++--- .../Runtime/RenderPipeline/Utility/HDUtils.cs | 10 +++++++ 40 files changed, 342 insertions(+), 65 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Camera/FreeCamera.cs b/Packages/com.unity.render-pipelines.core/Runtime/Camera/FreeCamera.cs index b8978bbfb7d..57195bd2f22 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Camera/FreeCamera.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Camera/FreeCamera.cs @@ -38,15 +38,15 @@ public class FreeCamera : MonoBehaviour public float m_Turbo = 10.0f; #if !USE_INPUT_SYSTEM - private static string kMouseX = "Mouse X"; - private static string kMouseY = "Mouse Y"; - private static string kRightStickX = "Controller Right Stick X"; - private static string kRightStickY = "Controller Right Stick Y"; - private static string kVertical = "Vertical"; - private static string kHorizontal = "Horizontal"; - - private static string kYAxis = "YAxis"; - private static string kSpeedAxis = "Speed Axis"; + private static readonly string kMouseX = "Mouse X"; + private static readonly string kMouseY = "Mouse Y"; + private static readonly string kRightStickX = "Controller Right Stick X"; + private static readonly string kRightStickY = "Controller Right Stick Y"; + private static readonly string kVertical = "Vertical"; + private static readonly string kHorizontal = "Horizontal"; + + private static readonly string kYAxis = "YAxis"; + private static readonly string kSpeedAxis = "Speed Axis"; #endif #if USE_INPUT_SYSTEM diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs index 3f7ddbc3310..5fcfad7dac0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.CompilerServices; +using Unity.Scripting.LifecycleManagement; using UnityEngine.VFX; namespace UnityEngine.Rendering @@ -9,8 +10,13 @@ namespace UnityEngine.Rendering /// public struct CommandBufferHelpers { + // These variables are just wrappers for the CommandBuffer supplied to methods below, so their state doesn't need + // to be reset when entering play mode. + [NoAutoStaticsCleanup] internal static RasterCommandBuffer rasterCmd = new RasterCommandBuffer(null, null, false); + [NoAutoStaticsCleanup] internal static ComputeCommandBuffer computeCmd = new ComputeCommandBuffer(null, null, false); + [NoAutoStaticsCleanup] internal static UnsafeCommandBuffer unsafeCmd = new UnsafeCommandBuffer(null, null, false); /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/CommandBufferPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/CommandBufferPool.cs index 649b817ebae..5c70744e2da 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/CommandBufferPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/CommandBufferPool.cs @@ -10,6 +10,14 @@ public static class CommandBufferPool { static ObjectPool s_BufferPool = new ObjectPool(null, x => x.Clear()); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_BufferPool = new ObjectPool(null, x => x.Clear()); + } +#endif + /// /// Get a new Command Buffer. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/ComponentSingleton.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/ComponentSingleton.cs index 49c92e94aa5..03d9bd5a323 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/ComponentSingleton.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/ComponentSingleton.cs @@ -1,5 +1,26 @@ +using System; +using System.Collections.Generic; + namespace UnityEngine.Rendering { +#if UNITY_EDITOR + static class ComponentSingletonRegistry + { + static readonly List s_Instances = new(); + + internal static void Register(Component instance) => s_Instances.Add(instance); + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + foreach (var instance in s_Instances) + if (instance != null) + CoreUtils.Destroy(instance.gameObject); + s_Instances.Clear(); + } + } +#endif + // Use this class to get a static instance of a component // Mainly used to have a default instance @@ -11,6 +32,7 @@ public static class ComponentSingleton where TType : Component { static TType s_Instance = null; + /// /// Instance of the required component type. /// @@ -28,6 +50,9 @@ public static TType instance go.SetActive(false); s_Instance = go.AddComponent(); +#if UNITY_EDITOR + ComponentSingletonRegistry.Register(s_Instance); +#endif } return s_Instance; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs index 9ecd81cec2c..d9a4ae3c6e5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/ConstantBuffer.cs @@ -8,7 +8,15 @@ namespace UnityEngine.Rendering /// public class ConstantBuffer { - static List m_RegisteredConstantBuffers = new List(); + static readonly List m_RegisteredConstantBuffers = new List(); + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + ReleaseAll(); + } +#endif /// /// Update the GPU data of the constant buffer and bind it globally via a command buffer. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/ContextContainer.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/ContextContainer.cs index 402ee01b7ca..10539653ff7 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/ContextContainer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/ContextContainer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Unity.Mathematics; +using Unity.Scripting.LifecycleManagement; namespace UnityEngine.Rendering { @@ -152,10 +153,14 @@ public void Dispose() m_ActiveItemIndices.Clear(); } + // Static s_TypeCount and TypeId.value fields don't need to be reset when entering playmode. + // s_TypeCount is only incremented by the static initialization of TypeId.value. + [NoAutoStaticsCleanup] static uint s_TypeCount; static class TypeId { + [NoAutoStaticsCleanup] public static uint value = s_TypeCount++; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/DynamicResolutionHandler.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/DynamicResolutionHandler.cs index 86bb4d0d255..39588bb4dcd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/DynamicResolutionHandler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/DynamicResolutionHandler.cs @@ -627,5 +627,26 @@ public float GetLowResMultiplier(float targetLowRes, float minimumThreshold) return Mathf.Clamp(thresholdPercentage / m_CurrentFraction, 0.0f, 1.0f); } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_ActiveScalerSlot = DynamicResScalerSlot.User; + s_ScalerContainers = new ScalerContainer[(int)DynamicResScalerSlot.Count] + { + new ScalerContainer() { type = DynamicResScalePolicyType.ReturnsMinMaxLerpFactor, method = DefaultDynamicResMethod }, + new ScalerContainer() { type = DynamicResScalePolicyType.ReturnsMinMaxLerpFactor, method = DefaultDynamicResMethod } + }; + s_CameraUpscaleFilters = new Dictionary(); + s_CameraInstances = new Dictionary(CameraDictionaryMaxcCapacity); + s_DefaultInstance = new DynamicResolutionHandler(); + s_ActiveCameraId = EntityId.None; + s_ActiveInstance = s_DefaultInstance; + s_ActiveInstanceDirty = true; + s_GlobalHwFraction = 1.0f; + s_GlobalHwUpresActive = false; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugDisplaySettingsVolumes.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugDisplaySettingsVolumes.cs index 3619e4dbf17..386a393a697 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugDisplaySettingsVolumes.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugDisplaySettingsVolumes.cs @@ -429,7 +429,7 @@ internal static DebugUI.Widget CreateVolumeParameterWidget(string name, bool isR return new DebugUI.Value() { displayName = name, getter = () => Strings.parameterNotCalculated, }; } - static DebugUI.Value s_EmptyDebugUIValue = new DebugUI.Value { getter = () => string.Empty }; + static readonly DebugUI.Value s_EmptyDebugUIValue = new DebugUI.Value { getter = () => string.Empty }; struct VolumeParameterChain { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugShapes.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugShapes.cs index c9f37764a14..77bbdd049e1 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugShapes.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugShapes.cs @@ -6,6 +6,14 @@ public partial class DebugShapes // Singleton static DebugShapes s_Instance = null; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_Instance = null; + } +#endif + /// Singleton instance static public DebugShapes instance { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs index a2a052bbc3b..385e6af9984 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs @@ -782,7 +782,7 @@ public int[] enumValues // Space-delimit PascalCase (https://stackoverflow.com/questions/155303/net-how-can-you-split-a-caps-delimited-string-into-an-array) - static Regex s_NicifyRegEx = new("([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", RegexOptions.Compiled); + static readonly Regex s_NicifyRegEx = new("([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", RegexOptions.Compiled); /// /// Automatically fills the enum names with a given diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUpdater.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUpdater.cs index 850c5e595f3..f69d80fc0c6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUpdater.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUpdater.cs @@ -71,6 +71,14 @@ static void DisableRuntime() #if !USE_INPUT_SYSTEM static DebugUpdater s_Instance = null; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_Instance = null; + } +#endif + void Update() { DebugManager debugManager = DebugManager.instance; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/FrameTiming/FrameTimeSample.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/FrameTiming/FrameTimeSample.cs index 3870d757afe..4a250890e9c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/FrameTiming/FrameTimeSample.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/FrameTiming/FrameTimeSample.cs @@ -49,32 +49,32 @@ internal void Add(FrameTimeSample sample) // Helper functions - static Func s_SampleValueAdd = (float value, float other) => + static readonly Func s_SampleValueAdd = (float value, float other) => { return value + other; }; - static Func s_SampleValueMin = (float value, float other) => + static readonly Func s_SampleValueMin = (float value, float other) => { return other > 0 ? Mathf.Min(value, other) : value; }; - static Func s_SampleValueMax = (float value, float other) => + static readonly Func s_SampleValueMax = (float value, float other) => { return Mathf.Max(value, other); }; - static Func s_SampleValueCountValid = (float value, float other) => + static readonly Func s_SampleValueCountValid = (float value, float other) => { return other > 0 ? value + 1 : value; }; - static Func s_SampleValueEnsureValid = (float value, float other) => + static readonly Func s_SampleValueEnsureValid = (float value, float other) => { return other > 0 ? value : 0; }; - static Func s_SampleValueDivide = (float value, float other) => + static readonly Func s_SampleValueDivide = (float value, float other) => { return other > 0 ? value / other : 0; }; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/MousePositionDebug.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/MousePositionDebug.cs index 26758b4ccec..4184d76d3d4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/MousePositionDebug.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/MousePositionDebug.cs @@ -16,6 +16,14 @@ public class MousePositionDebug // Singleton private static MousePositionDebug s_Instance = null; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_Instance = null; + } +#endif + /// /// Singleton instance. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/ProfilingScope.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/ProfilingScope.cs index bbec0d62378..d0f2d584ac9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/ProfilingScope.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/ProfilingScope.cs @@ -14,7 +14,7 @@ namespace UnityEngine.Rendering { class TProfilingSampler : ProfilingSampler where TEnum : Enum { - internal static Dictionary> samples = new Dictionary>(); + internal static readonly Dictionary> samples = new Dictionary>(); static TProfilingSampler() { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs b/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs index 5375653abfe..c686d83d006 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using Unity.Scripting.LifecycleManagement; using UnityEngine.Assertions; namespace UnityEngine.Rendering @@ -31,9 +32,11 @@ public interface IShaderVariantSettings public abstract partial class VolumeDebugSettings { + // Obsolete unused API to be removed, does not support Fast Enter Playmode. + [NoAutoStaticsCleanup] static List s_ComponentTypes; /// List of Volume component types. - [Obsolete("Please use volumeComponentsPathAndType instead, and get the second element of the tuple #from(2022.2)")] + [Obsolete("Please use volumeComponentsPathAndType instead, and get the second element of the tuple. Note: Not compatible with Fast Enter Playmode. #from(2022.2)")] public static List componentTypes { get @@ -68,14 +71,15 @@ public static string ComponentDisplayName(Type component) /// /// The list of the additional camera datas /// - [Obsolete("Cameras are auto registered/unregistered, use property cameras #from(2022.2)")] + [Obsolete("Cameras are auto registered/unregistered, use property cameras. Note: Not compatible with Fast Enter Playmode. #from(2022.2)")] + [NoAutoStaticsCleanup] protected static List additionalCameraDatas { get; private set; } = new List(); /// /// Register the camera for the Volume Debug. /// /// The AdditionalCameraData of the camera to be registered. - [Obsolete("Cameras are auto registered/unregistered #from(2022.2)")] + [Obsolete("Cameras are auto registered/unregistered. Note: Not compatible with Fast Enter Playmode. #from(2022.2)")] public static void RegisterCamera(T additionalCamera) { if (!additionalCameraDatas.Contains(additionalCamera)) @@ -86,7 +90,7 @@ public static void RegisterCamera(T additionalCamera) /// Unregister the camera for the Volume Debug. /// /// The AdditionalCameraData of the camera to be registered. - [Obsolete("Cameras are auto registered/unregistered #from(2022.2)")] + [Obsolete("Cameras are auto registered/unregistered. Note: Not compatible with Fast Enter Playmode. #from(2022.2)")] public static void UnRegisterCamera(T additionalCamera) { if (additionalCameraDatas.Contains(additionalCamera)) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/FixedAttachmentArray.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/FixedAttachmentArray.cs index 34101d71f65..faa04208ec7 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/FixedAttachmentArray.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/FixedAttachmentArray.cs @@ -14,7 +14,7 @@ public struct FixedAttachmentArray where DataType : unmanaged /// /// Returns an empty array. /// - public static FixedAttachmentArray Empty = new FixedAttachmentArray(0); + public static readonly FixedAttachmentArray Empty = new FixedAttachmentArray(0); /// /// The maximum number of elements that can be stored in the array. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs index 8b86ede0af3..92772424e19 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; +using Unity.Scripting.LifecycleManagement; using Unity.Profiling; namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler @@ -39,6 +40,7 @@ internal struct RenderGraphInputInfo // Contains the index of the non culled passes for native render passes that has at least one pass culled. internal NativeList m_NonCulledPassIndicesForRasterPasses; + [NoAutoStaticsCleanup] internal static bool s_ForceGenerateAuditsForTests = false; public NativePassCompiler(RenderGraphCompilationCache cache) @@ -583,7 +585,7 @@ void CullRenderGraphPassesWritingOnlyUnusedResources() producerData.culled = true; producerData.DisconnectFromResources(ctx, unusedVersionedResourceIdCullingStack, type); } - else + else { // Producer is still necessary for now, but if the previous version is only implicitly read by it to write the unused resource // then we can consider this version useless as well and add it to the stack. @@ -1333,7 +1335,11 @@ private bool ExecuteInitializeResource(InternalRenderGraphContext rgContext, Ren } #if UNITY_EDITOR || DEVELOPMENT_BUILD + // s_EmptyLoadAudit and s_EmptyStoreAudit don't need to be reset when entering playmode. In practical terms, + // they are read-only, but we can't actually mark them readonly due to ref var usage in DetermineLoadStoreActions. + [NoAutoStaticsCleanup] static LoadAudit s_EmptyLoadAudit = new LoadAudit(LoadReason.InvalidReason); + [NoAutoStaticsCleanup] static StoreAudit s_EmptyStoreAudit = new StoreAudit(StoreReason.InvalidReason); #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugSession.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugSession.cs index f3c8eb8ce08..8bcf4dc5ad5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugSession.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugSession.cs @@ -141,6 +141,16 @@ protected void InvalidateData() static RenderGraphDebugSession s_CurrentDebugSession; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + onRegisteredGraphsChanged = null; + onDebugDataUpdated = null; + s_CurrentDebugSession = null; + } +#endif + public static bool hasActiveDebugSession => s_CurrentDebugSession?.isActive ?? false; public static RenderGraphDebugSession currentDebugSession => s_CurrentDebugSession; @@ -171,7 +181,7 @@ public static void EndSession() } } - public static List s_EmptyRegisteredGraphs = new(); + public static readonly List s_EmptyRegisteredGraphs = new(); public static List GetRegisteredGraphs() { if (s_CurrentDebugSession == null || s_CurrentDebugSession.debugDataContainer == null) @@ -182,7 +192,7 @@ public static List GetRegisteredGraphs() return s_CurrentDebugSession.debugDataContainer.GetRenderGraphs(); } - public static List s_EmptyExecutions = new(); + public static readonly List s_EmptyExecutions = new(); public static List GetExecutions(string graphName) { if (s_CurrentDebugSession == null || s_CurrentDebugSession.debugDataContainer == null) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphPlayerRemoteDebugSession.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphPlayerRemoteDebugSession.cs index 07020b820a5..edbfc438c2e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphPlayerRemoteDebugSession.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphPlayerRemoteDebugSession.cs @@ -29,6 +29,7 @@ public RenderGraphPlayerRemoteDebugSession() : base() public override void Dispose() { base.Dispose(); + onDebugDataUpdated -= SendDebugDataToEditor; PlayerConnection.instance.UnregisterConnection(OnEditorConnected); PlayerConnection.instance.UnregisterDisconnection(OnEditorDisconnected); m_MessageHandler.UnregisterAll(); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs index 3846a80e08d..171a56b4876 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Diagnostics; +using Unity.Scripting.LifecycleManagement; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler; @@ -9,7 +10,8 @@ public partial class RenderGraph { internal static class RenderGraphExceptionMessages { - internal static bool enableCaller = true; + [NoAutoStaticsCleanup] + internal static bool enableCaller = true; // Only used from tests internal const string k_RenderGraphExecutionError = "Render Graph Execution error"; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs index 8c13e6d56df..208f415dc53 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; +using Unity.Scripting.LifecycleManagement; using UnityEngine.Experimental.Rendering; using UnityEngine.Scripting.APIUpdating; // Typedef for the in-engine RendererList API (to avoid conflicts with the experimental version) @@ -174,7 +175,8 @@ public struct RasterGraphContext : IDerivedRendergraphContext ///Render Graph pool used for temporary data. public RenderGraphObjectPool renderGraphPool { get => wrappedContext.renderGraphPool; } - static internal RasterCommandBuffer rastercmd = new RasterCommandBuffer(null, null, false); + [NoAutoStaticsCleanup] + static internal readonly RasterCommandBuffer rastercmd = new RasterCommandBuffer(null, null, false); /// public void FromInternalContext(InternalRenderGraphContext context) @@ -217,7 +219,7 @@ public class ComputeGraphContext : IDerivedRendergraphContext ///Render Graph pool used for temporary data. public RenderGraphObjectPool renderGraphPool { get => wrappedContext.renderGraphPool; } - static internal ComputeCommandBuffer computecmd = new ComputeCommandBuffer(null, null, false); + static internal readonly ComputeCommandBuffer computecmd = new ComputeCommandBuffer(null, null, false); /// public void FromInternalContext(InternalRenderGraphContext context) @@ -260,7 +262,7 @@ public class UnsafeGraphContext : IDerivedRendergraphContext ///Render Graph pool used for temporary data. public RenderGraphObjectPool renderGraphPool { get => wrappedContext.renderGraphPool; } - internal static UnsafeCommandBuffer unsCmd = new UnsafeCommandBuffer(null, null, false); + internal static readonly UnsafeCommandBuffer unsCmd = new UnsafeCommandBuffer(null, null, false); /// public void FromInternalContext(InternalRenderGraphContext context) { @@ -387,7 +389,7 @@ public partial class RenderGraph // When a RenderGraph is created, an entry is added to this dictionary. When that RenderGraph renders something, // and a debug session is active, an entry is added to the list of executions for that RenderGraph using the executionId // as the key. So when you render multiple times with the same executionId, only one DebugExecutionItem is created. - static Dictionary> s_RegisteredExecutions = new (); + static readonly Dictionary> s_RegisteredExecutions = new (); #region Public Interface /// Name of the Render Graph. @@ -1652,6 +1654,19 @@ internal void ClearGlobalBindings() m_RenderGraphContext.cmd.SetGlobalTexture(globalTex.Key, defaultResources.blackTexture); } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_RegisteredExecutions.Clear(); + s_EnableCompilationCachingForTests = null; + onGraphRegistered = null; + onGraphUnregistered = null; + onExecutionRegistered = null; + s_DebugSessionWasActive = false; + } +#endif } /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs index e50667882fb..51bc425876b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs @@ -26,7 +26,7 @@ static int HashEntryComparer(HashEntry a, HashEntry b) return 0; } - static DynamicArray>.SortComparer s_NativeEntryComparer = HashEntryComparer; + static readonly DynamicArray>.SortComparer s_NativeEntryComparer = HashEntryComparer; const int k_CachedGraphCount = 20; @@ -38,13 +38,20 @@ public RenderGraphCompilationCache() } } - // Avoid GC in lambda. - static int s_Hash; + // Looping manually instead of using DynamicArray.FindIndex to avoid GC caused by the lambda capture of the hash + static int FindHashEntryIndex(DynamicArray> hashEntries, int hash) + { + for (int i = 0; i < hashEntries.size; ++i) + { + if (hashEntries[i].hash == hash) + return i; + } + return -1; + } bool GetCompilationCache(int hash, int frameIndex, out CompilerContextData outGraph, DynamicArray> hashEntries, Stack pool, DynamicArray>.SortComparer comparer) { - s_Hash = hash; - int index = hashEntries.FindIndex(value => value.hash == s_Hash); + int index = FindHashEntryIndex(hashEntries, hash); if (index != -1) { ref var entry = ref hashEntries[index]; @@ -119,4 +126,5 @@ public void Cleanup() nativeCompiledGraphs[i].Dispose(); } } + } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs index 13146be82f2..8622722e6b0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs @@ -9,12 +9,12 @@ namespace UnityEngine.Rendering.RenderGraphModule /// public sealed class RenderGraphObjectPool { - // Only used to clear all existing pools at once from here when needed - static DynamicArray s_AllocatedPools = new DynamicArray(); + // Only used to clear all existing pools at once from here when needed + static readonly DynamicArray s_AllocatedPools = new DynamicArray(); // Non abstract class instead of an interface to store it in a DynamicArray class SharedObjectPoolBase - { + { public SharedObjectPoolBase() {} public virtual void Clear() {} } @@ -22,7 +22,7 @@ public virtual void Clear() {} class SharedObjectPool : SharedObjectPoolBase where T : class, new() { private static readonly Pool.ObjectPool s_Pool = AllocatePool(); - + private static Pool.ObjectPool AllocatePool() { var newPool = new Pool.ObjectPool(() => new T(), null, null); @@ -39,7 +39,7 @@ public override void Clear() { s_Pool.Clear(); } - + /// /// Get a new instance from the pool. /// @@ -110,12 +110,12 @@ internal void ReleaseAllTempAlloc() m_AllocatedMaterialPropertyBlocks.Clear(); } - + internal bool IsEmpty() { return m_AllocatedArrays.Count == 0 && m_AllocatedMaterialPropertyBlocks.Count == 0; } - + // Regular pooling API. Only internal use for now internal T Get() where T : class, new() { @@ -137,5 +137,17 @@ internal void Cleanup() foreach (var pool in s_AllocatedPools) pool.Clear(); } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + foreach (var pool in s_AllocatedPools) + pool.Clear(); + + // s_AllocatedPools is populated by generic class instantiation of SharedObjectPool when the static + // variable s_Pool is initialized, and won't re-register without domain reload, so it should not be cleared. + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs index a2d3a91110d..4d798db298e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Collections.Generic; using System.Runtime.CompilerServices; +using Unity.Scripting.LifecycleManagement; namespace UnityEngine.Rendering.RenderGraphModule { @@ -658,6 +659,8 @@ public override int GetRenderFuncHash() internal sealed class RenderGraphPass : BaseRenderGraphPass where PassData : class, new() { + // Variable is reused by overwriting its contents in FromInternalContext() before usage, so no need to reset it when entering play mode. + [NoAutoStaticsCleanup] internal static RenderGraphContext c = new RenderGraphContext(); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -681,6 +684,8 @@ public override void Release(RenderGraphObjectPool pool) internal sealed class ComputeRenderGraphPass : BaseRenderGraphPass where PassData : class, new() { + // Variable is reused by overwriting its contents in FromInternalContext() before usage, so no need to reset it when entering play mode. + [NoAutoStaticsCleanup] internal static ComputeGraphContext c = new ComputeGraphContext(); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -704,6 +709,8 @@ public override void Release(RenderGraphObjectPool pool) internal sealed class RasterRenderGraphPass : BaseRenderGraphPass where PassData : class, new() { + // Variable is reused by overwriting its contents in FromInternalContext() before usage, so no need to reset it when entering play mode. + [NoAutoStaticsCleanup] internal static RasterGraphContext c = new RasterGraphContext(); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -727,6 +734,8 @@ public override void Release(RenderGraphObjectPool pool) internal sealed class UnsafeRenderGraphPass : BaseRenderGraphPass where PassData : class, new() { + // Variable is reused by overwriting its contents in FromInternalContext() before usage, so no need to reset it when entering play mode. + [NoAutoStaticsCleanup] internal static UnsafeGraphContext c = new UnsafeGraphContext(); [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceAccelerationStructure.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceAccelerationStructure.cs index 19c76e5d4bd..7a874272985 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceAccelerationStructure.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceAccelerationStructure.cs @@ -10,7 +10,7 @@ namespace UnityEngine.Rendering.RenderGraphModule [MovedFrom(true, "UnityEngine.Experimental.Rendering.RenderGraphModule", "UnityEngine.Rendering.RenderGraphModule")] public readonly struct RayTracingAccelerationStructureHandle { - private static RayTracingAccelerationStructureHandle s_NullHandle = new RayTracingAccelerationStructureHandle(); + private static readonly RayTracingAccelerationStructureHandle s_NullHandle = new RayTracingAccelerationStructureHandle(); /// /// Returns a null ray tracing acceleration structure handle diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceBuffer.cs index 6a4158d0bd9..dc86cba0045 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceBuffer.cs @@ -14,7 +14,7 @@ public readonly struct BufferHandle // Minor Warning: This calls the zeroing constructor this means that the embedded ResourceHandle struct will also be zero-ed // which then means ResourceHandle.type will be set to zero == Texture. As this is an "invalid" bufferhandle I guess setting it // to type texture just makes it even more properly invalid and not a big issue. But something to keep in mind for tooling/logging. - private static BufferHandle s_NullHandle = new BufferHandle(); + private static readonly BufferHandle s_NullHandle = new BufferHandle(); /// /// Returns a null graphics buffer handle diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs index 108e43673b9..4bc03381bee 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs @@ -143,7 +143,7 @@ public int GetNumResourcesAvailable() return totalResources; } - static List s_ToRemoveList = new List(32); + static readonly List s_ToRemoveList = new List(32); public override void PurgeUnusedResources(int currentFrameIndex) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs index 7b9e9fc9ed5..b0d94603442 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs @@ -96,6 +96,14 @@ internal static RenderGraphResourceRegistry current } } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + m_CurrentRegistry = null; + } +#endif + delegate bool ResourceCreateCallback(InternalRenderGraphContext rgContext, IRenderGraphResource res); delegate void ResourceCallback(InternalRenderGraphContext rgContext, IRenderGraphResource res); @@ -361,7 +369,7 @@ internal void IncrementReadCount(in ResourceHandle res) CheckHandleValidity(res); m_RenderGraphResources[res.iType].resourceArray[res.index].IncrementReadCount(); } - + internal ResourceHandle GetLatestVersionHandle(in ResourceHandle res) { CheckHandleValidity(res); @@ -668,8 +676,7 @@ internal TextureHandle ImportBackbuffer(RenderTargetIdentifier rt, in RenderTarg return texHandle; } - static RenderTargetIdentifier emptyId = RenderTargetIdentifier.Invalid; - static RenderTargetIdentifier builtinCameraRenderTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget); + static readonly RenderTargetIdentifier emptyId = RenderTargetIdentifier.Invalid; [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] private void ValidateRenderTarget(in ResourceHandle res) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs index f740680ab70..0390f482d31 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs @@ -99,7 +99,7 @@ internal enum TextureUVOriginSelection [MovedFrom(true, "UnityEngine.Experimental.Rendering.RenderGraphModule", "UnityEngine.Rendering.RenderGraphModule")] public readonly struct TextureHandle : IEquatable { - private static TextureHandle s_NullHandle = new TextureHandle(); + private static readonly TextureHandle s_NullHandle = new TextureHandle(); /// /// Returns a null texture handle @@ -562,6 +562,14 @@ class TextureResource : RenderGraphResource { static int m_TextureCreationIndex; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + m_TextureCreationIndex = 0; + } +#endif + internal TextureUVOriginSelection textureUVOrigin; public override string GetName() diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs index d38957db6e5..1de34a72e54 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs @@ -38,6 +38,14 @@ internal enum RenderGraphResourceType static uint s_CurrentValidBit = 1; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_CurrentValidBit = 1; + } +#endif + public int index { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -98,7 +106,7 @@ public bool IsNull() return false; } - static public void NewFrame(int executionIndex) + public static void NewFrame(int executionIndex) { uint previousValidBit = s_CurrentValidBit; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs index 425d509fb96..3c2a0562b9e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs @@ -10,7 +10,15 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util /// public static partial class RenderGraphUtils { - static MaterialPropertyBlock s_PropertyBlock = new MaterialPropertyBlock(); + static readonly MaterialPropertyBlock s_PropertyBlock = new MaterialPropertyBlock(); + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_PropertyBlock.Clear(); + } +#endif /// /// Checks if the shader features required by the MSAA version of the copy pass is supported on current platform. @@ -134,7 +142,7 @@ class CopyPassData /// function please use the AddBlitPass function. To verify whether the copy pass is supported for the intended operation, use the CanAddCopyPass function. /// /// When XR is active, array textures containing both eyes will be automatically copied. - /// + /// /// /// The RenderGraph adding this pass to. /// The texture the data is copied from. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderPipeline/RenderPipelineGlobalSettings.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderPipeline/RenderPipelineGlobalSettings.cs index 5c81cf533a3..82a4a430212 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderPipeline/RenderPipelineGlobalSettings.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderPipeline/RenderPipelineGlobalSettings.cs @@ -1,4 +1,5 @@ using System; +using Unity.Scripting.LifecycleManagement; #if UNITY_EDITOR using UnityEditor.Rendering; #endif @@ -23,6 +24,8 @@ public abstract class RenderPipelineGlobalSettings() as TGlobalRenderPipelineSettings; #else public static TGlobalRenderPipelineSettings instance => s_Instance.Value; + + [NoAutoStaticsCleanup] private static Lazy s_Instance = new (() => GraphicsSettings.GetSettingsForRenderPipeline() as TGlobalRenderPipelineSettings); #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandle.cs b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandle.cs index 3e2da0ef31f..10838395b5d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandle.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandle.cs @@ -20,6 +20,14 @@ public struct RTHandleStaticHelpers /// public static RTHandle s_RTHandleWrapper; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_RTHandleWrapper = null; + } +#endif + /// /// Set static RTHandle wrapper given a RTid. The static RTHandle wrapper is treated as external handle in RTHandleSystem /// Get the static wrapper through `RTHandleStaticHelpers.s_RTHandleWrapper`. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs index d4c2679220c..64f16f5e15a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs @@ -12,6 +12,15 @@ public static class RTHandles { static RTHandleSystem s_DefaultInstance = new RTHandleSystem(); +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_DefaultInstance?.Dispose(); + s_DefaultInstance = new RTHandleSystem(); + } +#endif + /// /// Maximum allocated width of the default RTHandle System /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs index b25f67b2c69..636c79f1607 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs @@ -108,6 +108,27 @@ enum BlitColorAndDepthPassNames static int[] s_BlitShaderPassIndicesMap; static int[] s_BlitColorAndDepthShaderPassIndicesMap; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_Copy = null; + s_Blit = null; + s_BlitTexArray = null; + s_BlitTexArraySingleSlice = null; + s_BlitColorAndDepth = null; + s_PropertyBlock.Clear(); + s_TriangleMesh = null; + s_QuadMesh = null; + s_DecodeHdrKeyword = default; + s_ResolveDepthMSAA2X = default; + s_ResolveDepthMSAA4X = default; + s_ResolveDepthMSAA8X = default; + s_BlitShaderPassIndicesMap = null; + s_BlitColorAndDepthShaderPassIndicesMap = null; + } +#endif + /// /// Initializes the Blitter resources. This must be called once before any use. /// @@ -553,7 +574,7 @@ public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scale /// Blitter.BlitTexture2D(cmd, source, new Vector4(1, 0.5, 0, 0.5), 4, false); /// ]]> /// - + public static void BlitTexture2D(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear) { BlitTexture2D(cmd.m_WrappedCommandBuffer, source, scaleBias, mipLevel, bilinear); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CameraCaptureBridge.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CameraCaptureBridge.cs index 52c4cae23ce..5797abc79de 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CameraCaptureBridge.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CameraCaptureBridge.cs @@ -14,10 +14,19 @@ private class CameraEntry internal IEnumerator> cachedEnumerator; } - private static Dictionary actionDict = new(); + private static readonly Dictionary actionDict = new(); private static bool _enabled; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + actionDict.Clear(); + _enabled = false; + } +#endif + /// /// Enable camera capture. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ColorUtils.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ColorUtils.cs index 0108d562cd2..0c77810c31c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ColorUtils.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ColorUtils.cs @@ -7,18 +7,30 @@ namespace UnityEngine.Rendering /// public static class ColorUtils { + const float k_LightMeterCalibrationConstant = 12.5f; + const float k_LensAttenuation = 0.65f; + /// /// Calibration constant (K) used for our virtual reflected light meter. Modifying this will lead to a change on how average scene luminance /// gets mapped to exposure. /// - static public float s_LightMeterCalibrationConstant = 12.5f; + public static float s_LightMeterCalibrationConstant = k_LightMeterCalibrationConstant; /// /// Factor used for our lens system w.r.t. exposure calculation. Modifying this will lead to a change on how linear exposure /// multipliers are computed from EV100 values (and viceversa). s_LensAttenuation models transmission attenuation and lens vignetting. /// Note that according to the standard ISO 12232, a lens saturates at s_LensAttenuation = 0.78f (under ISO 100). /// - static public float s_LensAttenuation = 0.65f; + public static float s_LensAttenuation = k_LensAttenuation; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_LightMeterCalibrationConstant = k_LightMeterCalibrationConstant; + s_LensAttenuation = k_LensAttenuation; + } +#endif /// /// Scale applied to exposure caused by lens imperfection. It is computed from s_LensAttenuation as follow: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs index 441f1d9c7c6..eaae6c32bcd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using UnityEngine.Experimental.Rendering; using System.Runtime.CompilerServices; +using Unity.Scripting.LifecycleManagement; #if UNITY_6000_5_OR_NEWER using UnityEngine.Assemblies; #endif @@ -15,7 +16,6 @@ namespace UnityEngine.Rendering { - using static UnityEngine.Rendering.HableCurve; using UnityObject = UnityEngine.Object; /// @@ -139,6 +139,7 @@ public static class Priorities [Obsolete(obsoletePriorityMessage)] public const int gameObjectMenuPriority = 10; + [NoAutoStaticsCleanup] static Cubemap m_BlackCubeTexture; /// /// Black cubemap texture. @@ -159,6 +160,7 @@ public static Cubemap blackCubeTexture } } + [NoAutoStaticsCleanup] static Cubemap m_MagentaCubeTexture; /// /// Magenta cubemap texture. @@ -179,6 +181,7 @@ public static Cubemap magentaCubeTexture } } + [NoAutoStaticsCleanup] static CubemapArray m_MagentaCubeTextureArray; /// /// Black cubemap array texture. @@ -202,6 +205,7 @@ public static CubemapArray magentaCubeTextureArray } } + [NoAutoStaticsCleanup] static Cubemap m_WhiteCubeTexture; /// /// White cubemap texture. @@ -222,6 +226,7 @@ public static Cubemap whiteCubeTexture } } + [NoAutoStaticsCleanup] static RenderTexture m_EmptyUAV; /// /// Empty 1x1 texture usable as a dummy UAV. @@ -241,6 +246,7 @@ public static RenderTexture emptyUAV } } + [NoAutoStaticsCleanup] static GraphicsBuffer m_EmptyBuffer; /// /// Empty 4-Byte buffer resource usable as a dummy. @@ -258,6 +264,7 @@ public static GraphicsBuffer emptyBuffer } } + [NoAutoStaticsCleanup] static Texture3D m_BlackVolumeTexture; /// /// Black 3D texture. @@ -278,6 +285,7 @@ public static Texture3D blackVolumeTexture } } + [NoAutoStaticsCleanup] internal static Texture3D m_WhiteVolumeTexture; /// @@ -430,7 +438,7 @@ public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] c { SetRenderTarget(cmd, colorBuffers, depthBuffer, clearFlag, Color.clear); } - + /// /// Set the current multiple render texture. /// @@ -1383,7 +1391,7 @@ public static IEnumerable GetAllTypesDerivedFrom() var baseType = typeof(T); foreach (var type in GetAllAssemblyTypes()) { - if (type.IsSubclassOf(baseType)) + if (type.IsSubclassOf(baseType)) derivedTypes.Add(type); } return derivedTypes; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeDebugData.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeDebugData.cs index 7dad87b04aa..c960012f691 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeDebugData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeDebugData.cs @@ -1,26 +1,28 @@ using System; using System.Collections.Generic; using System.Reflection; +using Unity.Scripting.LifecycleManagement; namespace UnityEngine.Rendering { #if UNITY_EDITOR || DEVELOPMENT_BUILD internal static class VolumeDebugData { + [NoAutoStaticsCleanup] // Cache for reflection data, no need to reset static Lazy> debugIds = new(() => new Dictionary()); - + internal static string GetVolumeParameterDebugId(VolumeParameter parameter) { return debugIds.Value.TryGetValue(parameter.fieldHash, out var debugId) ? debugId : string.Empty; } - + internal static void AddVolumeParameterDebugId(VolumeParameter parameter, FieldInfo field) { var fieldHash = field.GetHashCode(); parameter.fieldHash = fieldHash; if (debugIds.Value.ContainsKey(fieldHash)) return; - + var displayInfo = field.GetCustomAttribute(true); var debugId = displayInfo != null ? displayInfo.name : field.Name; #if UNITY_EDITOR @@ -30,4 +32,4 @@ internal static void AddVolumeParameterDebugId(VolumeParameter parameter, FieldI } } #endif -} \ No newline at end of file +} diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index 19f71d4057e..95b8b940828 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -94,6 +94,16 @@ public static RTHandle clearTexture3DRTH } } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + CoreUtils.Destroy(m_ClearTexture3D); + m_ClearTexture3D = null; + m_ClearTexture3DRTH = null; + } +#endif + /// /// Returns the HDRP default blit material. /// From 9d6967363e4ccb7db751c234e0af20cef013e560 Mon Sep 17 00:00:00 2001 From: Francois Fournel Date: Fri, 10 Apr 2026 00:52:08 +0000 Subject: [PATCH 61/88] [CBD] Remove Mesh Build Usage --- .../Scenes/007_Mesh_Not_Readable.fbx.meta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/007_Mesh_Not_Readable.fbx.meta b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/007_Mesh_Not_Readable.fbx.meta index fef3730bbbc..50db1f6f02e 100644 --- a/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/007_Mesh_Not_Readable.fbx.meta +++ b/Tests/SRPTests/Packages/com.unity.testing.visualeffectgraph/Scenes/007_Mesh_Not_Readable.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29861b71a58cb3d1415ccab0a8f2b50fdbe5d3cc7c8223210862dad0926df15d +oid sha256:ca9a8fff4848f062bd46d29fa726dafc0a9c9b868d9353ea36460dee3da89fab size 2461 From b306d9ce69a03399bb7b50fc76592429f3081109 Mon Sep 17 00:00:00 2001 From: Ludovic Theobald Date: Fri, 10 Apr 2026 00:52:14 +0000 Subject: [PATCH 62/88] [VFX] Workaround FXC bug with early out in SG VertMesh --- .../Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl index d262e944a3d..a2ff90e9a6c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl @@ -151,16 +151,20 @@ VaryingsMeshType VertMesh(AttributesMesh input, float3 worldSpaceOffset #ifdef HAVE_VFX_MODIFICATION ZERO_INITIALIZE(AttributesElement, element); - + bool cull = false; // Flag instead of direct early-return due to some compiler bug (UUM-128594) if(!GetMeshAndElementIndex(input, element)) - return output; // Culled index. + cull = true; // Culled index. #if UNITY_ANY_INSTANCING_ENABLED output.instanceID = input.instanceID; //Transfer again because we modify it in GetMeshAndElementIndex #endif - if(!GetInterpolatorAndElementData(input, output, element)) - return output; // Dead particle. + UNITY_BRANCH + if (!cull) + cull = !GetInterpolatorAndElementData(input, output, element); + + if (cull) + return output; // Culled or dead particle. SetupVFXMatrices(element, output); #endif From 06ec59927e4c4c0f898a92f9b60b7644f0621e6f Mon Sep 17 00:00:00 2001 From: Tyler Fan Date: Fri, 10 Apr 2026 03:49:19 +0000 Subject: [PATCH 63/88] [Adaptive Performance] clamp cameraTargetDescriptor value to 1 --- .../Runtime/UniversalRenderPipeline.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 1952d11bc49..a4866eba9ae 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -2614,17 +2614,17 @@ static void ApplyAdaptivePerformance(UniversalCameraData cameraData) // TODO if (!cameraData.xr.enabled) { - cameraData.cameraTargetDescriptor.width = (int)(cameraData.camera.pixelWidth * cameraData.renderScale); - cameraData.cameraTargetDescriptor.height = (int)(cameraData.camera.pixelHeight * cameraData.renderScale); + cameraData.cameraTargetDescriptor.width = Mathf.Max(1, (int)(cameraData.pixelWidth * cameraData.renderScale)); + cameraData.cameraTargetDescriptor.height = Mathf.Max(1, (int)(cameraData.pixelHeight * cameraData.renderScale)); #if ENABLE_UPSCALER_FRAMEWORK IUpscaler activeUpscaler = upscaling.activeUpscaler; if (activeUpscaler != null) // An IUpscaler is active. { // It might want to change the pre-upscale resolution. Negotiate with it. - Vector2Int res = new Vector2Int(cameraData.cameraTargetDescriptor.width, cameraData.scaledHeight); + Vector2Int res = new Vector2Int(cameraData.cameraTargetDescriptor.width, cameraData.cameraTargetDescriptor.height); activeUpscaler.NegotiatePreUpscaleResolution(ref res, new Vector2Int(cameraData.pixelWidth, cameraData.pixelHeight)); - cameraData.cameraTargetDescriptor.width = res.x; - cameraData.cameraTargetDescriptor.height = res.y; + cameraData.cameraTargetDescriptor.width = Mathf.Max(1, res.x); + cameraData.cameraTargetDescriptor.height = Mathf.Max(1, res.y); } #endif cameraData.scaledWidth = cameraData.cameraTargetDescriptor.width; From 0b98c56ef654b2b3332cff9294b6ed677d4230fb Mon Sep 17 00:00:00 2001 From: Pema Malling Date: Fri, 10 Apr 2026 07:47:06 +0000 Subject: [PATCH 64/88] Fix color bleeding near edge of screen with HDRP SSGI --- .../RaytracingIndirectDiffuse.compute | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute index db2839f382b..d6292090c79 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/IndirectDiffuse/RaytracingIndirectDiffuse.compute @@ -222,11 +222,8 @@ NeighborTapData GetNeighborTapDataSample_HR(uint2 groupThreadId, int2 offset) return GetNeighborTapDataSample_HR(OffsetToLDSAdress_HR(groupThreadId, offset)); } -NeighborTapData GetNeighborTapDataSample_HR_NOLDS(uint2 fulLResCoord, int2 offset) +NeighborTapData GetNeighborTapDataSample_HR_NOLDS(uint2 tapCoord) { - int2 tapCoord = (fulLResCoord / 2 + offset) * 2; - tapCoord = int2(clamp(tapCoord.x, 0, (int)_ScreenSize.x - 1), clamp(tapCoord.y, 0, (int)_ScreenSize.y - 1)); - NeighborTapData outVal; outVal.lighting = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, tapCoord / 2).xyz; outVal.linearDepth = Linear01Depth(LOAD_TEXTURE2D_X(_DepthTexture, tapCoord).x, _ZBufferParams); @@ -278,11 +275,15 @@ void IndirectDiffuseIntegrationUpscaleHalfRes(uint3 dispatchThreadId : SV_Dispat { for(int x = -HALF_RES_OUT_REGION_SIZE; x < HALF_RES_OUT_REGION_SIZE; ++x) { + int2 tapCoord = (targetCoord / 2 + int2(x,y)) * 2; + if (any(tapCoord < 0) || any(tapCoord >= _ScreenSize.xy)) + continue; + #ifndef WITHOUT_LDS // Grab the neighbor data NeighborTapData neighborData = GetNeighborTapDataSample_HR(groupThreadId, int2(x,y)); #else - NeighborTapData neighborData = GetNeighborTapDataSample_HR_NOLDS(targetCoord, int2(x,y)); + NeighborTapData neighborData = GetNeighborTapDataSample_HR_NOLDS(tapCoord); #endif // Evaluate the weight of this neighbor float weight = EvaluateNeighborWeight(neighborData, normalData.normalWS, linearDepth); @@ -416,6 +417,10 @@ void IndirectDiffuseIntegrationUpscaleFullRes(uint3 dispatchThreadId : SV_Dispat { for(int x = -FULL_RES_OUT_REGION_SIZE; x < FULL_RES_OUT_REGION_SIZE; ++x) { + int2 tapCoord = targetCoord + int2(x,y); + if (any(tapCoord < 0) || any(tapCoord >= _ScreenSize.xy)) + continue; + #ifndef WITHOUT_LDS // Grab the neighbor data NeighborTapData neighborData = GetNeighborTapDataSample_FR(groupThreadId, int2(x,y)); From 452450b1af69caea13da7bf702c6c7c505c5fb09 Mon Sep 17 00:00:00 2001 From: Layla Arab Date: Fri, 10 Apr 2026 07:47:09 +0000 Subject: [PATCH 65/88] Suppress 'potentially uninitialized variable' warning in UnifiedRT TraceRay.hlsl --- .../Runtime/UnifiedRayTracing/TraceRay.hlsl | 1 + 1 file changed, 1 insertion(+) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl index b9bcd02df1a..efaad78efe8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl @@ -151,6 +151,7 @@ struct HitContext namespace UnifiedRT { #pragma warning(disable : 3557) // prevent warning when the "while (rayQuery.Proceed())" loop is unrolled +#pragma warning(disable : 4000) // suppress FXC warnings about potentially uninitialized variables void TraceRay(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags, inout UNIFIED_RT_PAYLOAD payload) { From f4f67bdd6fd57d9a80b240acb4009888d5dc3242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20V=C3=A1zquez?= Date: Fri, 10 Apr 2026 11:10:11 +0000 Subject: [PATCH 66/88] [URP]Project Auditor - Adding validations for the URP setup and known settings missconfiguration. --- .../Editor/Tools/Project Auditor.meta | 8 + .../DefaultVolumeProfileValidation.cs | 34 + .../DefaultVolumeProfileValidation.cs.meta | 2 + .../DuplicateRendererFeaturesAnalyzer.cs | 59 ++ .../DuplicateRendererFeaturesAnalyzer.cs.meta | 2 + .../GlobalSettingsAssetAnalyzer.cs | 41 + .../GlobalSettingsAssetAnalyzer.cs.meta | 2 + .../Project Auditor/HDREnabledValidation.cs | 76 ++ .../HDREnabledValidation.cs.meta | 2 + .../InactiveRendererFeaturesAnalyzer.cs | 40 + .../InactiveRendererFeaturesAnalyzer.cs.meta | 2 + .../InvalidRendererIndexAnalyzer.cs | 82 ++ .../InvalidRendererIndexAnalyzer.cs.meta | 2 + .../LinearColorSpaceAnalyzer.cs | 37 + .../LinearColorSpaceAnalyzer.cs.meta | 2 + .../Tools/Project Auditor/MSAAValidation.cs | 86 ++ .../Project Auditor/MSAAValidation.cs.meta | 2 + .../MaterialMigrationValidation.cs | 69 ++ .../MaterialMigrationValidation.cs.meta | 2 + .../MissingAssignedRenderPipeline.cs | 50 + .../MissingAssignedRenderPipeline.cs.meta | 2 + .../MissingRendererFeaturesAnalyzer.cs | 45 + .../MissingRendererFeaturesAnalyzer.cs.meta | 2 + .../Project Auditor/ProjectAuditorGraphics.cs | 84 ++ .../ProjectAuditorGraphics.cs.meta | 2 + .../RendererAssignmentValidation.cs | 76 ++ .../RendererAssignmentValidation.cs.meta | 2 + .../Project Auditor/SRPBatcherValidation.cs | 77 ++ .../SRPBatcherValidation.cs.meta | 2 + .../StaticBatchingWithSRPBatcherAnalyzer.cs | 62 ++ ...aticBatchingWithSRPBatcherAnalyzer.cs.meta | 2 + .../URPAssetLastVersionValidation.cs | 50 + .../URPAssetLastVersionValidation.cs.meta | 2 + .../URPProjectAuditorUtilities.cs | 44 + .../URPProjectAuditorUtilities.cs.meta | 2 + .../Data/UniversalRenderPipelineAsset.cs | 2 +- .../Tests/Editor/Tools/ProjectAuditor.meta | 8 + .../URPSettingsAnalyzerTests.cs | 942 ++++++++++++++++++ .../URPSettingsAnalyzerTests.cs.meta | 2 + 39 files changed, 2007 insertions(+), 1 deletion(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/ProjectAuditor.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/ProjectAuditor/URPSettingsAnalyzerTests.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/ProjectAuditor/URPSettingsAnalyzerTests.cs.meta diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor.meta new file mode 100644 index 00000000000..085defae732 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ac2f288d1072e2947a1704bffbd5cdee +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs new file mode 100644 index 00000000000..fdf9b3e494f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Global Settings")] + class DefaultVolumeProfileAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0202 = nameof(URP0202); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0202, + "URP: Default Volume Profile is not assigned", + Areas.Quality, + "The default Volume Profile is not assigned in Graphics Settings. Without a default volume profile, post-processing and other volume-based effects may not work correctly. This setting is configured in Project Settings > Graphics > URP.", + "Assign a default Volume Profile in Project Settings > Graphics > URP section" + ) + { + DefaultSeverity = Severity.Warning, + }; + + public IEnumerable EnumerateIssues() + { + var settings = GraphicsSettings.GetRenderPipelineSettings(); + + // If settings is null, we're not in URP or settings haven't been initialized + if (settings != null && settings.volumeProfile == null) + yield return new RenderingSettingsIssue(URP0202); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs.meta new file mode 100644 index 00000000000..b74ef89fe30 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DefaultVolumeProfileValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9c1c7f7878446834aab8c4fd0a79397e \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs new file mode 100644 index 00000000000..f30a3cad4f7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; +using Unity.ProjectAuditor.Editor; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Renderer")] + class DuplicateRendererFeaturesAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0103 = nameof(URP0103); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0103, + "URP: Duplicate features with DisallowMultipleRendererFeature", + Areas.Quality, + "Some Renderer Features are marked with [DisallowMultipleRendererFeature] attribute but appear multiple times in a renderer. This can cause unexpected behavior or rendering issues.", + "Remove duplicate renderer features that are marked with DisallowMultipleRendererFeature attribute" + ) + { + DefaultSeverity = Severity.Error, + }; + + public IEnumerable EnumerateIssues() + { + var rendererDataAssets = URPProjectAuditorUtilities.GetAllRendererDataAssets(); + + foreach (var rendererData in rendererDataAssets) + { + if (rendererData == null || rendererData.rendererFeatures == null) + continue; + + var featureTypeCounts = new Dictionary(); + + foreach (var feature in rendererData.rendererFeatures) + { + if (feature == null) + continue; + + var featureType = feature.GetType(); + var attribute = featureType.GetCustomAttribute(); + + if (attribute != null) + { + if (!featureTypeCounts.ContainsKey(featureType)) + featureTypeCounts[featureType] = 0; + + featureTypeCounts[featureType]++; + + if (featureTypeCounts[featureType] > 1) + yield return new RenderingSettingsIssue(URP0103); // Found duplicate + } + } + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs.meta new file mode 100644 index 00000000000..feb025e9606 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/DuplicateRendererFeaturesAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c2f338207dfcc51409b62af3ad45954d \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs new file mode 100644 index 00000000000..eb7353333dc --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Global Settings")] + class GlobalSettingsAssetAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0201 = nameof(URP0201); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0201, + "URP: URP Global Settings Asset is not assigned", + Areas.Quality, + "The Universal Render Pipeline Global Settings asset is not assigned or is invalid. Global Settings contains important configuration such as rendering layer names and shader stripping settings. Without it, some URP features may not work correctly.", + "Ensure URP Global Settings asset" + ) + { + DefaultSeverity = Severity.Error, + Fixer = FixGlobalSettings, + }; + + public IEnumerable EnumerateIssues() + { + var settings = GraphicsSettings.GetRenderPipelineSettings(); + + // If settings is null, we're not in URP or settings haven't been initialized + if (UniversalRenderPipelineGlobalSettings.instance == null) + yield return new RenderingSettingsIssue(URP0201); + } + + public static bool FixGlobalSettings(ReportItem issue, AnalysisParams context) + { + UniversalRenderPipelineGlobalSettings.Ensure(); + return true; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs.meta new file mode 100644 index 00000000000..4ae48fa5ab6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/GlobalSettingsAssetAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b9a1cfdb2f471544d93cc82d90cd225e \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs new file mode 100644 index 00000000000..6c901f8d42f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using Unity.ProjectAuditor.Editor.Core; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("URP Assets")] + class HDREnabledValidation : IRenderingSettingsAnalyzer + { + internal const string URP0004 = nameof(URP0004); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0004, + "URP: HDR is enabled", + Areas.GPU | Areas.Quality, + "HDR (High Dynamic Range) is enabled in a URP Asset for mobile platforms. HDR rendering can be very intensive on low-end mobile GPUs.", + "Disable HDR in the URP Asset." + ) + { + Platforms = new SerializableEnum[] { + new(BuildTarget.Android), + new(BuildTarget.iOS), + new(BuildTarget.Switch) + }, + MessageFormat = "URP: HDR is enabled in {0}.asset in {1}", + DefaultSeverity = Severity.Warning, + Fixer = FixHDR + }; + + public IEnumerable EnumerateIssues() + { + // Check default render pipeline + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset && urpAsset.supportsHDR) + { + yield return new RenderingSettingsIssue(URP0004, assetName: urpAsset.name); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset qualityUrpAsset && qualityUrpAsset.supportsHDR) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0004, level, name); + } + } + + public static bool FixHDR(ReportItem issue, AnalysisParams context) + { + bool fixedAny = false; + + var configuredAssets = GraphicsSettings.allConfiguredRenderPipelines; + + foreach (var asset in configuredAssets) + { + if (asset is UniversalRenderPipelineAsset urpAsset && urpAsset.supportsHDR) + { + urpAsset.supportsHDR = false; + EditorUtility.SetDirty(urpAsset); + fixedAny = true; + } + } + + return fixedAny; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs.meta new file mode 100644 index 00000000000..7b182a05440 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/HDREnabledValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: eeea0853b4ef4054ea6842de40031a6d \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs new file mode 100644 index 00000000000..f8fe8fdeaaa --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Renderer")] + class InactiveRendererFeaturesAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0104 = nameof(URP0104); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0104, + "URP: Inactive renderer features detected", + Areas.Quality | Areas.Memory, + "One or more renderer data assets contain inactive renderer features. Consider removing them if they are not needed.", + "Remove inactive renderer features or activate them if they should be used" + ) + { + DefaultSeverity = Severity.Warning, + }; + + public IEnumerable EnumerateIssues() + { + var rendererDataAssets = URPProjectAuditorUtilities.GetAllRendererDataAssets(); + + foreach (var rendererData in rendererDataAssets) + { + if (rendererData == null || rendererData.rendererFeatures == null) + continue; + + foreach (var feature in rendererData.rendererFeatures) + { + if (feature != null && !feature.isActive) + yield return new RenderingSettingsIssue(URP0104); + } + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs.meta new file mode 100644 index 00000000000..20260a42863 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InactiveRendererFeaturesAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1088471fc1e09ab4cba93811ddb5300c \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs new file mode 100644 index 00000000000..24465892610 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Renderer")] + class InvalidRendererIndexAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0101 = nameof(URP0101); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0101, + "URP: Invalid renderer index assigned", + Areas.Quality, + "One or more URP assets have a default renderer index that is out of bounds for their renderer list. This will cause rendering failures as the pipeline cannot find a valid renderer to use.", + "Check the default renderer index in each URP asset and ensure it's within the valid range of available renderers" + ) + { + DefaultSeverity = Severity.Error, + MessageFormat = "URP: Invalid renderer index assigned in {0}.asset in {1}", + }; + + public IEnumerable EnumerateIssues() + { + // Check default render pipeline + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset && !IsRendererIndexValid(urpAsset)) + { + if (!IsRendererIndexValid(urpAsset)) + yield return new RenderingSettingsIssue(URP0101, assetName:urpAsset.name); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset qualityUrpAsset && !IsRendererIndexValid(qualityUrpAsset)) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0101, level, name); + } + } + + static bool IsRendererIndexValid(UniversalRenderPipelineAsset urpAsset) + { + if (urpAsset == null) + return true; // Nothing to check + + // Get the renderer data list + var rendererDataList = urpAsset.m_RendererDataList; + if (rendererDataList == null || rendererDataList.Length == 0) + { + // If there are no renderers, any index is invalid + return false; + } + + // Get the default renderer index + int defaultRendererIndex = urpAsset.m_DefaultRendererIndex; + + // Check if the index is out of bounds + if (defaultRendererIndex < 0 || defaultRendererIndex >= rendererDataList.Length) + { + return false; + } + + // Check if the renderer at that index is null + if (rendererDataList[defaultRendererIndex] == null) + { + return false; + } + + return true; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs.meta new file mode 100644 index 00000000000..3097ef9a58e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/InvalidRendererIndexAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 087033380c2ca7e40b7290d8b763bab7 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs new file mode 100644 index 00000000000..cc658fa1f02 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Other")] + class LinearColorSpaceAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0401 = nameof(URP0401); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0401, + "URP: Linear Color Space should be used", + Areas.Quality, + "The project is using Gamma color space. Linear color space is required for physically accurate rendering in URP. Gamma color space can cause incorrect lighting calculations and color artifacts.", + "Change Color Space to Linear in Project Settings > Player > Other Settings > Color Space" + ) + { + Fixer = FixColorSpace, + DefaultSeverity = Severity.Error, + }; + + public IEnumerable EnumerateIssues() + { + if (PlayerSettings.colorSpace != ColorSpace.Linear) + yield return new RenderingSettingsIssue(URP0401); + } + + public static bool FixColorSpace(ReportItem issue, AnalysisParams context) + { + PlayerSettings.colorSpace = ColorSpace.Linear; + return true; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs.meta new file mode 100644 index 00000000000..1e5a601853c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/LinearColorSpaceAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9e086170170d88246a57c1d20b829abb \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs new file mode 100644 index 00000000000..1dc70f69dc7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using Unity.ProjectAuditor.Editor.Core; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("URP Assets")] + class MSAAValidation : IRenderingSettingsAnalyzer + { + internal const string URP0005 = nameof(URP0005); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0005, + "URP: MSAA is set to 4x or 8x", + Areas.GPU | Areas.Quality, + "Anti Aliasing (MSAA) is set to 4x or 8x in a URP Asset for mobile platforms. MSAA 4x/8x rendering can be intensive on low-end mobile GPUs.", + "Decrease Anti Aliasing (MSAA) value to 2x in the URP Asset." + ) + { + Platforms = new SerializableEnum[] { + new(BuildTarget.Android), + new(BuildTarget.iOS), + new(BuildTarget.Switch) + }, + MessageFormat = "URP: MSAA is set to 4x or 8x in {0}.asset in {1}", + DefaultSeverity = Severity.Warning, + Fixer = FixMSAA + }; + + internal static int GetMsaaSampleCountSetting(RenderPipelineAsset renderPipeline) + { + return renderPipeline is UniversalRenderPipelineAsset urpAsset ? urpAsset.msaaSampleCount : -1; + } + + public IEnumerable EnumerateIssues() + { + // Check default render pipeline + if (GetMsaaSampleCountSetting(GraphicsSettings.defaultRenderPipeline) >= 4) + { + yield return new RenderingSettingsIssue(URP0005); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (GetMsaaSampleCountSetting(QualitySettings.renderPipeline) >= 4) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0005, level, name); + } + } + + public static bool FixMSAA(ReportItem issue, AnalysisParams context) + { + bool fixedAny = false; + + if (GetMsaaSampleCountSetting(GraphicsSettings.defaultRenderPipeline) >= 4) + { + (GraphicsSettings.defaultRenderPipeline as UniversalRenderPipelineAsset).msaaSampleCount = 2; + EditorUtility.SetDirty(GraphicsSettings.defaultRenderPipeline); + fixedAny = true; + } + + QualitySettings.ForEach(() => + { + if (GetMsaaSampleCountSetting(QualitySettings.renderPipeline) >= 4) + { + (QualitySettings.renderPipeline as UniversalRenderPipelineAsset).msaaSampleCount = 2; + EditorUtility.SetDirty(QualitySettings.renderPipeline); + fixedAny = true; + } + }); + + return fixedAny; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs.meta new file mode 100644 index 00000000000..f7e38d8d2a1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MSAAValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0a19c63278396994eb3b7ae5114089d2 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs new file mode 100644 index 00000000000..e0c2629a769 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Other")] + class UnmigratedMaterialsAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0402 = nameof(URP0402); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0402, + "URP: Materials: Materials using Built-in shaders detected", + Areas.Quality | Areas.GPU, + "One or more materials in the project are still using Built-in render pipeline shaders. These materials should be converted to use URP-optimized shaders for better performance and compatibility. Use the Render Pipeline Converter (Window > Rendering > Render Pipeline Converter) to upgrade materials.", + "Convert materials to URP using Window > Rendering > Render Pipeline Converter" + ) + { + DefaultSeverity = Severity.Warning, + }; + + public IEnumerable EnumerateIssues() + { + if (!CheckForUnmigratedMaterials()) + yield return new RenderingSettingsIssue(URP0402); + } + + static bool CheckForUnmigratedMaterials() + { + // Get all built-in to URP upgraders + var upgraders = BuiltInToURP3DMaterialUpgrader.FetchMaterialUpgraders(); + if (upgraders == null || upgraders.Count == 0) + return true; // No upgraders defined, consider valid + + // Build a set of old shader paths that should be upgraded + var builtInShaderPaths = new HashSet(); + foreach (var upgrader in upgraders) + { + if (!string.IsNullOrEmpty(upgrader.OldShaderPath)) + { + builtInShaderPaths.Add(upgrader.OldShaderPath); + } + } + + if (builtInShaderPaths.Count == 0) + return true; // No old shaders to check + + // Find all materials in the project + var materials = AssetDatabaseHelper.FindAssets(); + foreach (var material in materials) + { + if (material != null && material.shader != null) + { + var shaderName = material.shader.name; + + // Check if this material is using a built-in shader that should be upgraded + if (builtInShaderPaths.Contains(shaderName)) + { + return false; // Found an unmigrated material + } + } + } + + return true; // All materials are using URP shaders + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs.meta new file mode 100644 index 00000000000..4d986955a77 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MaterialMigrationValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 11d0515733dd0344aa0a2e9979b11fd6 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs new file mode 100644 index 00000000000..54567282b88 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("URP Assets")] + class MissingAssignedRenderPipeline : IRenderingSettingsAnalyzer + { + internal const string URP0001 = nameof(URP0001); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0001, + "URP: Missing URP asset assigned", + Areas.Quality, + "Missing URP asset assigned. When a quality level has no render pipeline asset set, it will fall back to the default Graphics Settings asset. This can cause inconsistent rendering behavior across quality levels or fallback to Built-in Render Pipeline", + "Assign a URP asset to all quality levels in Project Settings > Quality and a Default Render Pipeline in Project Settings > Graphics." + ) + { + MessageFormat = "URP: Missing URP asset assigned {0} in {1}", + DefaultSeverity = Severity.Warning, + }; + + public IEnumerable EnumerateIssues() + { + // Check default render pipeline + if (GraphicsSettings.defaultRenderPipeline is not UniversalRenderPipelineAsset urpAsset) + { + yield return new RenderingSettingsIssue(URP0001); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is not UniversalRenderPipelineAsset qualityUrpAsset) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0001, level, name); + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs.meta new file mode 100644 index 00000000000..43b7bd84063 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingAssignedRenderPipeline.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 038072bcd540e8d4b8712ce4a32dafbb \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs new file mode 100644 index 00000000000..9718194c1a1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("Renderer")] + class MissingRendererFeaturesAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0102 = nameof(URP0102); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0102, + "URP: Missing or null renderer features", + Areas.Quality, + "One or more renderer data assets contain null or missing renderer features. This typically happens when scripts are deleted or there are compilation errors. This can cause rendering issues.", + "Open the renderer data asset and remove the missing features, or restore the missing scripts" + ) + { + DefaultSeverity = Severity.Error, + }; + + public IEnumerable EnumerateIssues() + { + if (!CheckForMissingFeatures()) + yield return new RenderingSettingsIssue(URP0102); + } + + static bool CheckForMissingFeatures() + { + var rendererDataAssets = URPProjectAuditorUtilities.GetAllRendererDataAssets(); + + foreach (var rendererData in rendererDataAssets) + { + if (rendererData == null) + continue; + + if (rendererData.rendererFeatures != null && rendererData.rendererFeatures.Contains(null)) + return false; // Found missing features + } + + return true; // No missing features + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs.meta new file mode 100644 index 00000000000..02b1c796856 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/MissingRendererFeaturesAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1cca62a04dbbcc4428357d5bd3335140 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs new file mode 100644 index 00000000000..b0074d0d3b9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using Unity.ProjectAuditor.Editor; +using Unity.ProjectAuditor.Editor.Core; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + internal struct RenderingSettingsIssue + { + public string id { get; set; } + public int? qualityLevel { get; set; } + public string assetName { get; set; } + + public RenderingSettingsIssue(string id, int? qualityLevel = null, string assetName = null) + { + this.id = id; + this.qualityLevel = qualityLevel; + this.assetName = assetName; + } + } + + internal interface IRenderingSettingsAnalyzer + { + public Descriptor Descriptor { get; } + public IEnumerable EnumerateIssues(); + } + + partial class SettingsAnalyzer : SettingsModuleAnalyzer + { + List m_Entries = new List(); + + public SettingsAnalyzer() + { + foreach (var types in TypeCache.GetTypesDerivedFrom()) + { + m_Entries.Add(Activator.CreateInstance(types) as IRenderingSettingsAnalyzer); + } + + // Sort by Descriptor.Id (alphabetically) + m_Entries.Sort((a, b) => string.Compare(a.Descriptor.Id, b.Descriptor.Id, StringComparison.Ordinal)); + } + + public override void Initialize(Action registerDescriptor) + { + foreach (var entry in m_Entries) + { + registerDescriptor(entry.Descriptor); + } + } + + static ReportItem CreateAssetSettingIssue(AnalysisContext context, int? qualityLevel, string name, string id) + { + string assetLocation = qualityLevel == null ? "Default Rendering Pipeline Asset" : + $"Rendering Pipeline Asset on Quality Level: '{QualitySettings.names[qualityLevel.Value]}'"; + return context.CreateIssue(IssueCategory.ProjectSetting, id, name, assetLocation) + .WithCustomProperties(new object[] { qualityLevel }) + .WithLocation(qualityLevel == null ? "Project/Graphics" : "Project/Quality"); + } + + static ReportItem CreateIssue(AnalysisContext context, string id) + { + return context.CreateIssue(IssueCategory.ProjectSetting, id) + .WithLocation("Project/Graphics"); + } + + public override IEnumerable Analyze(SettingsAnalysisContext context) + { + foreach (var entry in m_Entries) + { + foreach (var issue in entry.EnumerateIssues()) + { + if (string.IsNullOrEmpty(issue.id)) + throw new InvalidOperationException($"Issue id cannot be null or empty for {entry.Descriptor.Id}"); + + if (issue.qualityLevel == null && string.IsNullOrEmpty(issue.assetName)) + yield return CreateIssue(context, issue.id); + else + yield return CreateAssetSettingIssue(context, issue.qualityLevel, issue.assetName, issue.id); + } + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs.meta new file mode 100644 index 00000000000..ab8ac494316 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/ProjectAuditorGraphics.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 381d0513472fded4ead64160058a7490 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs new file mode 100644 index 00000000000..bf21b02e935 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("URP Assets")] + class NoRendererAssignedAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0002 = nameof(URP0002); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0002, + "URP: URP Asset has no renderer assigned", + Areas.Quality, + "One or more Universal Render Pipeline assets have no renderers assigned. Without a renderer, the pipeline cannot render anything and will result in a blank screen or errors.", + "Assign at least one renderer to each URP asset in Graphics and Quality Settings" + ) + { + DefaultSeverity = Severity.Error, + }; + + private bool CheckRenderers(UniversalRenderPipelineAsset urpAsset) + { + bool allHaveRenderers = true; + if (urpAsset.m_RendererDataList == null || urpAsset.m_RendererDataList.Length == 0) + { + allHaveRenderers = false; + } + else + { + // Check if all entries are null + bool hasValidRenderer = false; + foreach (var renderer in urpAsset.m_RendererDataList) + { + if (renderer != null) + { + hasValidRenderer = true; + break; + } + } + if (!hasValidRenderer) + allHaveRenderers = false; + } + + return allHaveRenderers; + } + + public IEnumerable EnumerateIssues() + { + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset) + { + if (!CheckRenderers(urpAsset)) + yield return new RenderingSettingsIssue(URP0002); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset qualityUrpAsset) + { + if (!CheckRenderers(qualityUrpAsset)) + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0002, level, name); + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs.meta new file mode 100644 index 00000000000..4048f9238ba --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/RendererAssignmentValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a6902e65c09c05348be988c7c41ec33e \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs new file mode 100644 index 00000000000..c5e1b5c8d3d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("SRP and Static Batching")] + class SRPBatcherAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0301 = nameof(URP0301); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0301, + "URP: SRP Batcher should be enabled", + Areas.GPU | Areas.Quality, + "Ensures that the Scriptable Render Pipeline Batcher is enabled on the URP Assets configured on Graphics and Quality Settings. This improves rendering performance significantly in many projects.", + "Enable the SRP Batcher on the used URP assets on Graphics and Quality Settings" + ) + { + Fixer = FixSRPBatcher, + DefaultSeverity = Severity.Warning, + MessageFormat = "URP: SRPBatcher disabled in {0}.asset in {1}", + }; + + public IEnumerable EnumerateIssues() + { + // Check default render pipeline + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset && !urpAsset.useSRPBatcher) + { + yield return new RenderingSettingsIssue(URP0301, assetName: urpAsset.name); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset urpAsset && !urpAsset.useSRPBatcher) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0301, level, name); + } + } + + public static bool FixSRPBatcher(ReportItem issue, AnalysisParams context) + { + bool fixedAny = false; + + // Fix default render pipeline in Graphics Settings + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset defaultUrpAsset) + { + defaultUrpAsset.useSRPBatcher = true; + EditorUtility.SetDirty(defaultUrpAsset); + fixedAny = true; + } + + // Fix all quality level render pipelines + QualitySettings.ForEach(() => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset urpAsset) + { + urpAsset.useSRPBatcher = true; + EditorUtility.SetDirty(urpAsset); + fixedAny = true; + } + }); + + return fixedAny; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs.meta new file mode 100644 index 00000000000..f09738b6257 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/SRPBatcherValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d1707b3fb9f15f24fa86f2640a14e64f \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs new file mode 100644 index 00000000000..0279475d5e2 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("SRP and Static Batching")] + class StaticBatchingWithSRPBatcherAnalyzer : IRenderingSettingsAnalyzer + { + internal const string URP0302 = nameof(URP0302); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0302, + "URP: Static Batching conflicts with SRP Batcher", + Areas.GPU | Areas.Quality, + "Static Batching is enabled while SRP Batcher is also enabled. Static Batching prevents the SRP Batcher from working efficiently, reducing performance. When using SRP Batcher, Static Batching should be disabled.", + "Disable Static Batching in Project Settings > Player > Other Settings > Static Batching" + ) + { + Fixer = FixStaticBatching, + DefaultSeverity = Severity.Warning, + MessageFormat = "URP: Static Batching conflicts with SRP Batcher enabled in {0}.asset in {1}", + }; + + + public IEnumerable EnumerateIssues() + { + bool staticBatchingEnabled = PlayerSettings.GetStaticBatchingForPlatform(EditorUserBuildSettings.activeBuildTarget); + if (!staticBatchingEnabled) + yield break; // Static Batching is disabled, no issue + + // Check default render pipeline + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset && urpAsset.useSRPBatcher) + { + yield return new RenderingSettingsIssue(URP0302, assetName: urpAsset.name); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset urpAsset && urpAsset.useSRPBatcher) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0302, level, name); + } + } + + public static bool FixStaticBatching(ReportItem issue, AnalysisParams context) + { + PlayerSettings.SetStaticBatchingForPlatform(EditorUserBuildSettings.activeBuildTarget, false); + return true; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs.meta new file mode 100644 index 00000000000..d4edc23c212 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/StaticBatchingWithSRPBatcherAnalyzer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c69f23236dc04e74490a4f1edc187ef2 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs new file mode 100644 index 00000000000..63a3ad2d01a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Unity.ProjectAuditor.Editor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + [Category("URP Assets")] + class URPAssetLastVersionValidation : IRenderingSettingsAnalyzer + { + internal const string URP0003 = nameof(URP0003); + + public Descriptor Descriptor { get; } = new Descriptor( + URP0003, + "URP: URP Asset are not at latest version", + Areas.Quality, + "One or more Universal Render Pipeline assets have no been upgraded to latest version.", + "Open the asset in the inspector to upgrade them to latest version." + ) + { + DefaultSeverity = Severity.Error, + MessageFormat = "URP: URP Asset is not at latest version in {0}.asset in {1}", + }; + + public IEnumerable EnumerateIssues() + { + // Check default render pipeline + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset && !urpAsset.IsAtLastVersion()) + { + yield return new RenderingSettingsIssue(URP0003); + } + + using (UnityEngine.Pool.ListPool<(int level, string name)>.Get(out var tmp)) + { + QualitySettings.ForEach((level, name) => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset urpAsset && !urpAsset.IsAtLastVersion()) + { + tmp.Add((level, name)); + } + }); + + foreach (var (level, name) in tmp) + yield return new RenderingSettingsIssue(URP0003, level, name); + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs.meta new file mode 100644 index 00000000000..0651b7fe654 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPAssetLastVersionValidation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0c9e13beeab0e3c4db1b5bd931db203a \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs new file mode 100644 index 00000000000..f80c6a9934e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace UnityEditor.Rendering.Universal.ProjectAuditor +{ + internal static class URPProjectAuditorUtilities + { + public static List GetAllRendererDataAssets() + { + var assets = new List(); + + // Get from Graphics Settings + if (GraphicsSettings.defaultRenderPipeline is UniversalRenderPipelineAsset urpAsset) + { + var rendererDataList = urpAsset.m_RendererDataList; + if (rendererDataList != null) + { + assets.AddRange(rendererDataList); + } + } + + // Get from Quality Settings + QualitySettings.ForEach(() => + { + if (QualitySettings.renderPipeline is UniversalRenderPipelineAsset qualityUrpAsset) + { + var rendererDataList = qualityUrpAsset.m_RendererDataList; + if (rendererDataList != null) + { + foreach (var data in rendererDataList) + { + if (data != null && !assets.Contains(data)) + assets.Add(data); + } + } + } + }); + + return assets; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs.meta b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs.meta new file mode 100644 index 00000000000..fbb9915b4da --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Project Auditor/URPProjectAuditorUtilities.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 37783e313f8379f4eb88183bbd9d2404 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs index 11f09275984..5f531d53921 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs @@ -425,7 +425,7 @@ public partial class UniversalRenderPipelineAsset : RenderPipelineAsset(); + GraphicsSettings.defaultRenderPipeline = urpAsset; + + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + var analyzer = new MissingAssignedRenderPipeline(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect issue when URP asset is assigned"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0002_NoRendererAssigned_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + + // Set renderer list to null + urpAsset.m_RendererDataList = null; + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new NoRendererAssignedAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1, issues.Count, "Should detect missing renderer"); + Assert.AreEqual("URP0002", analyzer.Descriptor.Id); + + // Cleanup + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0003_URPAssetNotAtLastVersion_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + urpAsset.k_AssetVersion--; + GraphicsSettings.defaultRenderPipeline = urpAsset; + + var analyzer = new URPAssetLastVersionValidation(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1, issues.Count, "Should detect not at last version asset"); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0003", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Error, analyzer.Descriptor.DefaultSeverity); + + // Cleanup + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0004_HDREnabled_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + urpAsset.supportsHDR = true; + GraphicsSettings.defaultRenderPipeline = urpAsset; + + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + var analyzer = new HDREnabledValidation(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect not at last version asset"); + + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0004", analyzer.Descriptor.Id); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("HDR")); + + // Cleanup + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0004_HDRDisabled_NoIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + urpAsset.supportsHDR = false; + GraphicsSettings.defaultRenderPipeline = urpAsset; + + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + var analyzer = new HDREnabledValidation(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect not at last version asset"); + + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0004", analyzer.Descriptor.Id); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("HDR")); + + // Cleanup + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0005_MSAA4x_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + + // Set MSAA to 4x + urpAsset.msaaSampleCount = 4; + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + var analyzer = new MSAAValidation(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect MSAA 4x"); + Assert.AreEqual("URP0005", analyzer.Descriptor.Id); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0005_MSAA8x_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Set MSAA to 8x + urpAsset.msaaSampleCount = 8; + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new MSAAValidation(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect MSAA 8x"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0005_MSAA2x_NoIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Set MSAA to 2x + urpAsset.msaaSampleCount = 2; + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new MSAAValidation(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect issue when MSAA is 2x or lower"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + #endregion + + #region Renderer Tests (0101-0200) + + [Test] + public void URP0101_InvalidRendererIndex_DetectsOutOfBounds() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Set invalid renderer index (out of bounds) + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 99; // Out of bounds + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new InvalidRendererIndexAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect invalid renderer index"); + Assert.AreEqual("URP0101", analyzer.Descriptor.Id); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0101_InvalidRendererIndex_DetectsNullRenderer() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Set renderer at index to null + urpAsset.m_RendererDataList = new ScriptableRendererData[] { null }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new InvalidRendererIndexAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect null renderer at valid index"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0101_ValidRendererIndex_NoIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Set valid renderer index + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new InvalidRendererIndexAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect issue with valid renderer index"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0102_MissingRendererFeatures_HasCorrectDescriptor() + { + var analyzer = new MissingRendererFeaturesAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0102", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Error, analyzer.Descriptor.DefaultSeverity); + } + + [Test] + public void URP0103_DuplicateRendererFeatures_HasCorrectDescriptor() + { + var analyzer = new DuplicateRendererFeaturesAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0103", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Error, analyzer.Descriptor.DefaultSeverity); + } + + [Test] + public void URP0104_InactiveRendererFeatures_HasCorrectDescriptor() + { + var analyzer = new InactiveRendererFeaturesAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0104", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Warning, analyzer.Descriptor.DefaultSeverity); + } + + #endregion + + #region Global Settings Tests (0201-0300) + + [Test] + public void URP0201_GlobalSettingsAsset_HasCorrectDescriptor() + { + var analyzer = new GlobalSettingsAssetAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0201", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Error, analyzer.Descriptor.DefaultSeverity); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("Global Settings")); + } + + [Test] + public void URP0202_DefaultVolumeProfile_HasCorrectDescriptor() + { + var analyzer = new DefaultVolumeProfileAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0202", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Warning, analyzer.Descriptor.DefaultSeverity); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("Volume Profile")); + } + + #endregion + + #region SRP and Static Batching Tests (0301-0400) + + [Test] + public void URP0301_SRPBatcherDisabled_HasCorrectDescriptor() + { + var analyzer = new SRPBatcherAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0301", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Warning, analyzer.Descriptor.DefaultSeverity); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("SRP Batcher")); + } + + [Test] + public void URP0301_SRPBatcherDisabled_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Disable SRP Batcher + urpAsset.useSRPBatcher = false; + + // Assign renderer to URP asset + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new SRPBatcherAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect disabled SRP Batcher"); + Assert.AreEqual("URP0301", analyzer.Descriptor.Id); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0301_SRPBatcherEnabled_NoIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Enable SRP Batcher + urpAsset.useSRPBatcher = true; + + // Assign renderer to URP asset + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + var analyzer = new SRPBatcherAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect issue when SRP Batcher is enabled"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0302_StaticBatchingConflict_HasCorrectDescriptor() + { + var analyzer = new StaticBatchingWithSRPBatcherAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0302", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Warning, analyzer.Descriptor.DefaultSeverity); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("Static Batching")); + } + + [Test] + public void URP0302_StaticBatchingDisabled_NoIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + urpAsset.useSRPBatcher = true; + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + PlayerSettings.SetStaticBatchingForPlatform(EditorUserBuildSettings.activeBuildTarget, false); + + var analyzer = new StaticBatchingWithSRPBatcherAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect issue when static batching is disabled"); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0302_StaticBatchingEnabledWithSRPBatcher_DetectsIssue() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Enable both SRP Batcher and Static Batching + urpAsset.useSRPBatcher = true; + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + GraphicsSettings.defaultRenderPipeline = urpAsset; + PlayerSettings.SetStaticBatchingForPlatform(EditorUserBuildSettings.activeBuildTarget, true); + + var analyzer = new StaticBatchingWithSRPBatcherAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect conflict when both SRP Batcher and Static Batching are enabled"); + Assert.AreEqual("URP0302", analyzer.Descriptor.Id); + + // Cleanup + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + #endregion + + #region Other Tests (0401+) + + [Test] + public void URP0401_LinearColorSpace_DetectsGammaSpace() + { + // Arrange + PlayerSettings.colorSpace = ColorSpace.Gamma; + var analyzer = new LinearColorSpaceAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1, issues.Count, "Should detect Gamma color space"); + Assert.AreEqual("URP0401", analyzer.Descriptor.Id); + } + + [Test] + public void URP0401_LinearColorSpace_NoIssueWhenLinear() + { + // Arrange + PlayerSettings.colorSpace = ColorSpace.Linear; + var analyzer = new LinearColorSpaceAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(0, issues.Count, "Should not detect issue when Linear color space is used"); + } + + [Test] + public void URP0402_UnmigratedMaterials_HasCorrectDescriptor() + { + var analyzer = new UnmigratedMaterialsAnalyzer(); + Assert.IsNotNull(analyzer.Descriptor); + Assert.AreEqual("URP0402", analyzer.Descriptor.Id); + Assert.AreEqual(Severity.Warning, analyzer.Descriptor.DefaultSeverity); + Assert.IsTrue(analyzer.Descriptor.Title.Contains("Materials")); + } + + #endregion + + #region Quality Settings Tests + + [Test] + public void URP0301_SRPBatcherDisabled_DetectsIssues() + { + // Arrange + var urpAsset = ScriptableObject.CreateInstance(); + var rendererData = ScriptableObject.CreateInstance(); + GraphicsSettings.defaultRenderPipeline = urpAsset; + for (int i = 0; i < QualitySettings.names.Length && i < m_PreviousQualitySettings.Length; i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = urpAsset; + } + + // Disable SRP Batcher + urpAsset.useSRPBatcher = false; + urpAsset.m_RendererDataList = new ScriptableRendererData[] { rendererData }; + urpAsset.m_DefaultRendererIndex = 0; + + // Set in quality settings instead of default + int currentQualityLevel = QualitySettings.GetQualityLevel(); + QualitySettings.renderPipeline = urpAsset; + + var analyzer = new SRPBatcherAnalyzer(); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.AreEqual(1 + QualitySettings.count, issues.Count, "Should detect disabled SRP Batcher in quality settings"); + + // Cleanup + QualitySettings.renderPipeline = m_PreviousQualitySettings[currentQualityLevel]; + UnityEngine.Object.DestroyImmediate(rendererData); + UnityEngine.Object.DestroyImmediate(urpAsset); + } + + [Test] + public void URP0001_MissingURPAsset_DetectsInMultipleQualityLevels() + { + // Arrange + var analyzer = new MissingAssignedRenderPipeline(); + int currentQualityLevel = QualitySettings.GetQualityLevel(); + + // Clear render pipeline in multiple quality levels + List clearedLevels = new List(); + for (int i = 0; i < Mathf.Min(2, QualitySettings.names.Length); i++) + { + QualitySettings.SetQualityLevel(i); + QualitySettings.renderPipeline = null; + clearedLevels.Add(i); + } + QualitySettings.SetQualityLevel(currentQualityLevel); + + // Act + var issues = analyzer.EnumerateIssues().ToList(); + + // Assert + Assert.IsTrue(issues.Count >= clearedLevels.Count, + $"Should detect missing URP asset in at least {clearedLevels.Count} quality level(s)"); + + // Cleanup happens in TearDown + } + + #endregion + + #region Integration Tests + + private IEnumerable GetAllAnalyzers() + { + var analyzerTypes = TypeCache.GetTypesDerivedFrom(); + foreach (var type in analyzerTypes) + { + if (!type.IsAbstract && !type.IsInterface) + { + yield return Activator.CreateInstance(type) as IRenderingSettingsAnalyzer; + } + } + } + + [Test] + public void AllAnalyzers_HaveUniqueDescriptorIds() + { + // Arrange + var analyzers = GetAllAnalyzers().ToList(); + + // Act + var descriptorIds = analyzers.Select(a => a.Descriptor.Id).ToList(); + var uniqueIds = descriptorIds.Distinct().ToList(); + + // Assert + Assert.AreEqual(descriptorIds.Count, uniqueIds.Count, + "All descriptor IDs should be unique. Duplicates found."); + } + + [Test] + public void AllAnalyzers_FollowNamingConvention() + { + // Arrange + var analyzers = GetAllAnalyzers(); + var idPattern = new Regex(@"^URP\d{4}$"); + + // Act & Assert + foreach (var analyzer in analyzers) + { + string id = analyzer.Descriptor.Id; + Assert.IsTrue(idPattern.IsMatch(id), + $"Descriptor ID '{id}' should match pattern 'URP####' where #### is a 4-digit number"); + } + } + + [Test] + public void AllAnalyzers_HaveValidDescriptors() + { + // Arrange + var analyzers = GetAllAnalyzers(); + + // Act & Assert + foreach (var analyzer in analyzers) + { + var descriptor = analyzer.Descriptor; + var typeName = analyzer.GetType().Name; + + Assert.IsNotNull(descriptor, $"{typeName}: Descriptor should not be null"); + Assert.IsFalse(string.IsNullOrEmpty(descriptor.Id), $"{typeName}: Descriptor ID should not be empty"); + Assert.IsFalse(string.IsNullOrEmpty(descriptor.Title), $"{typeName}: Descriptor Title should not be empty"); + Assert.IsFalse(string.IsNullOrEmpty(descriptor.Description), $"{typeName}: Descriptor Description should not be empty"); + Assert.IsFalse(string.IsNullOrEmpty(descriptor.Recommendation), $"{typeName}: Descriptor Recommendation should not be empty"); + } + } + + [Test] + public void AllAnalyzers_DescriptorIdsAreInValidRanges() + { + // Arrange + var analyzers = GetAllAnalyzers(); + var idPattern = new Regex(@"^URP(\d{4})$"); + + // Define valid ranges + var validRanges = new[] + { + (start: 1, end: 100, name: "URP Assets"), + (start: 101, end: 200, name: "Renderer"), + (start: 201, end: 300, name: "Global Settings"), + (start: 301, end: 400, name: "SRP and Static Batching"), + (start: 401, end: 9999, name: "Other") + }; + + // Act & Assert + foreach (var analyzer in analyzers) + { + string id = analyzer.Descriptor.Id; + var typeName = analyzer.GetType().Name; + var match = idPattern.Match(id); + + Assert.IsTrue(match.Success, $"{typeName}: Descriptor ID '{id}' should match pattern 'URP####'"); + + int numericId = int.Parse(match.Groups[1].Value); + + bool isInValidRange = validRanges.Any(range => numericId >= range.start && numericId <= range.end); + Assert.IsTrue(isInValidRange, + $"{typeName}: Descriptor ID '{id}' (numeric value: {numericId}) is not in any valid range. " + + $"Valid ranges are: {string.Join(", ", validRanges.Select(r => $"{r.name} ({r.start:D4}-{r.end:D4})"))}"); + } + } + + [Test] + public void AllAnalyzers_HaveCategoryAttribute() + { + // Arrange + var analyzerTypes = TypeCache.GetTypesDerivedFrom(); + + // Act & Assert + foreach (var type in analyzerTypes) + { + if (type.IsAbstract || type.IsInterface) + continue; + + var categoryAttr = type.GetCustomAttribute(); + Assert.IsNotNull(categoryAttr, $"{type.Name}: Should have [Category] attribute"); + + var validCategories = new[] { "URP Assets", "Renderer", "Global Settings", "SRP and Static Batching", "Other" }; + Assert.Contains(categoryAttr.Category, validCategories, + $"{type.Name}: Category '{categoryAttr.Category}' should be one of the valid categories"); + } + } + + [Test] + public void AllAnalyzers_DescriptorIdsMatchCategoryAttribute() + { + // Arrange + var analyzerTypes = TypeCache.GetTypesDerivedFrom(); + var idPattern = new Regex(@"^URP(\d{4})$"); + + // Act & Assert + foreach (var type in analyzerTypes) + { + if (type.IsAbstract || type.IsInterface) + continue; + + var analyzer = Activator.CreateInstance(type) as IRenderingSettingsAnalyzer; + string id = analyzer.Descriptor.Id; + var typeName = type.Name; + + // Get the Category attribute + var categoryAttr = type.GetCustomAttribute(); + Assert.IsNotNull(categoryAttr, $"{typeName}: Should have [Category] attribute"); + + string category = categoryAttr.Category; + var match = idPattern.Match(id); + + Assert.IsTrue(match.Success, $"{typeName}: Descriptor ID '{id}' should match pattern 'URP####'"); + + int numericId = int.Parse(match.Groups[1].Value); + var expectedRange = GetRangeForCategory(category); + + Assert.IsTrue(numericId >= expectedRange.start && numericId <= expectedRange.end, + $"{typeName}: ID {id} (numeric: {numericId}) should be in range {expectedRange.start:D4}-{expectedRange.end:D4} for category '{category}'"); + } + } + + [Test] + public void AllCategories_HaveAnalyzersInCorrectRanges() + { + // Arrange + var analyzerTypes = TypeCache.GetTypesDerivedFrom(); + var idPattern = new Regex(@"^URP(\d{4})$"); + var categoriesFound = new Dictionary>(); + + // Act + foreach (var type in analyzerTypes) + { + if (type.IsAbstract || type.IsInterface) + continue; + + var analyzer = Activator.CreateInstance(type) as IRenderingSettingsAnalyzer; + var categoryAttr = type.GetCustomAttribute(); + + if (categoryAttr != null) + { + var match = idPattern.Match(analyzer.Descriptor.Id); + if (match.Success) + { + int numericId = int.Parse(match.Groups[1].Value); + if (!categoriesFound.ContainsKey(categoryAttr.Category)) + categoriesFound[categoryAttr.Category] = new List<(string, int)>(); + + categoriesFound[categoryAttr.Category].Add((type.Name, numericId)); + } + } + } + + // Assert + foreach (var kvp in categoriesFound) + { + var category = kvp.Key; + var analyzers = kvp.Value; + var expectedRange = GetRangeForCategory(category); + + foreach (var (typeName, numericId) in analyzers) + { + Assert.IsTrue(numericId >= expectedRange.start && numericId <= expectedRange.end, + $"Category '{category}': {typeName} has ID {numericId:D4} which is outside expected range {expectedRange.start:D4}-{expectedRange.end:D4}"); + } + } + } + + private (int start, int end) GetRangeForCategory(string category) + { + return category switch + { + "URP Assets" => (1, 100), + "Renderer" => (101, 200), + "Global Settings" => (201, 300), + "SRP and Static Batching" => (301, 400), + "Other" => (401, 9999), + _ => throw new ArgumentException($"Unknown category: {category}") + }; + } + + #endregion + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/ProjectAuditor/URPSettingsAnalyzerTests.cs.meta b/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/ProjectAuditor/URPSettingsAnalyzerTests.cs.meta new file mode 100644 index 00000000000..de3db6ab103 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/ProjectAuditor/URPSettingsAnalyzerTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 729807ff59ce7944f978ddc8d3c09c8f \ No newline at end of file From c212a70b52fd07aa3025d6b436eb2a038475339c Mon Sep 17 00:00:00 2001 From: Ludovic Theobald Date: Fri, 10 Apr 2026 21:07:21 +0000 Subject: [PATCH 67/88] [VFX] Add ScrollView and resizable previews to the SDF Bake tool window --- .../Utilities/SDF/BakeTool/SDFBakeTool.cs | 86 +++++++++++++++---- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/Packages/com.unity.visualeffectgraph/Editor/Utilities/SDF/BakeTool/SDFBakeTool.cs b/Packages/com.unity.visualeffectgraph/Editor/Utilities/SDF/BakeTool/SDFBakeTool.cs index f4debf67a1e..6d6d1a8c09b 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Utilities/SDF/BakeTool/SDFBakeTool.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Utilities/SDF/BakeTool/SDFBakeTool.cs @@ -3,6 +3,7 @@ using UnityEditor.Rendering; using UnityEngine; using UnityEngine.Rendering; +using UnityEngine.UIElements; using Object = UnityEngine.Object; using UnityEngine.VFX.SDF; @@ -20,6 +21,9 @@ static void OpenWindow() [SerializeField] private SdfBakerSettings m_Settings; + private TwoPaneSplitView m_SplitView; + private IMGUIContainer m_MeshPreviewContainer; + private IMGUIContainer m_TexturePreviewContainer; private SerializedObject m_SettingsSO; private RenderTexture m_BakedSDF; @@ -97,7 +101,43 @@ private Mesh mesh private Vector3 m_ActualBoxSize; - protected void OnGUI() + protected void CreateGUI() + { + m_SplitView = new TwoPaneSplitView(1, 300f, TwoPaneSplitViewOrientation.Vertical); + m_SplitView.viewDataKey = "SDFBakeTool_MainSplit"; + m_SplitView.style.flexGrow = 1; + + // Top pane: scrollable controls panel. + var topPane = new VisualElement(); + topPane.style.flexGrow = 1; + topPane.style.minHeight = 50; + var scrollView = new ScrollView(ScrollViewMode.Vertical); + scrollView.style.flexGrow = 1; + scrollView.Add(new IMGUIContainer(DrawControls)); + topPane.Add(scrollView); + m_SplitView.Add(topPane); + + // Bottom pane: preview panels stacked vertically, each filling equal height. + var bottomPane = new VisualElement(); + bottomPane.style.flexDirection = FlexDirection.Column; + bottomPane.style.flexGrow = 1; + bottomPane.style.minHeight = 50; + + m_MeshPreviewContainer = new IMGUIContainer(UpdateMeshPreview); + m_MeshPreviewContainer.style.flexGrow = 1; + bottomPane.Add(m_MeshPreviewContainer); + + m_TexturePreviewContainer = new IMGUIContainer(UpdateTexture3dPreview); + m_TexturePreviewContainer.style.flexGrow = 1; + bottomPane.Add(m_TexturePreviewContainer); + + m_SplitView.Add(bottomPane); + rootVisualElement.Add(m_SplitView); + + UpdatePreviewVisibility(); + } + + private void DrawControls() { if (m_Settings == null) { @@ -107,6 +147,7 @@ protected void OnGUI() bool needsUpdate = false; Undo.RecordObject(this, "Settings Asset change"); Undo.RecordObject(m_Settings, "SDF Baker Parameter change"); + GUILayout.BeginHorizontal(); @@ -334,20 +375,29 @@ protected void OnGUI() GUILayout.BeginHorizontal(); previewObject = (PreviewChoice)EditorGUILayout.EnumPopup(Contents.previewChoice, previewObject); GUILayout.EndHorizontal(); - if ((previewObject & PreviewChoice.Mesh) != 0) - { - UpdateMeshPreview(); - } - - if ((previewObject & PreviewChoice.Texture) != 0) - { - UpdateTexture3dPreview(); - } + UpdatePreviewVisibility(); if (needsUpdate) EditorUtility.SetDirty(m_Settings); } + private void UpdatePreviewVisibility() + { + if (m_MeshPreviewContainer == null || m_TexturePreviewContainer == null || m_SplitView == null) + return; + + bool showMesh = (previewObject & PreviewChoice.Mesh) != 0; + bool showTexture = (previewObject & PreviewChoice.Texture) != 0; + + m_MeshPreviewContainer.style.display = showMesh ? DisplayStyle.Flex : DisplayStyle.None; + m_TexturePreviewContainer.style.display = showTexture ? DisplayStyle.Flex : DisplayStyle.None; + + if (showMesh || showTexture) + m_SplitView.UnCollapse(); + else + m_SplitView.CollapseChild(1); + } + private void UpdateTexture3dPreview() { if (m_BakedSDF) @@ -357,8 +407,11 @@ private void UpdateTexture3dPreview() GUILayout.BeginHorizontal(); m_TexturePreview.OnPreviewSettings(new Object[] { m_BakedSDF }); GUILayout.EndHorizontal(); - Rect rect = GUILayoutUtility.GetRect(100, 2000, 100, 2000, GUIStyle.none); - m_TexturePreview.OnPreviewGUI(rect, GUIStyle.none); + Rect rect = GUILayoutUtility.GetRect(0, float.MaxValue, 0, float.MaxValue, GUIStyle.none); + if (rect.height > 0 && rect.width > 0) + { + m_TexturePreview.OnPreviewGUI(rect, GUIStyle.none); + } EditorGUI.DropShadowLabel(rect, m_TexturePreview.GetInfoString()); } } @@ -375,15 +428,18 @@ private void UpdateMeshPreview() m_MeshPreview.sizeBoxReference = boxSizeReference; m_MeshPreview.actualSizeBox = m_ActualBoxSize; m_MeshPreview.centerBox = boxCenter; - m_MeshPreview?.OnPreviewGUI(GUILayoutUtility.GetRect(100, 2000, 100, 2000, GUIStyle.none), - GUIStyle.none); + Rect rect = GUILayoutUtility.GetRect(0, float.MaxValue, 0, float.MaxValue, GUIStyle.none); + if (rect.height > 0 && rect.width > 0) + { + m_MeshPreview?.OnPreviewGUI(rect, GUIStyle.none); + } } } private void OnEnable() { titleContent = Contents.title; - minSize = new Vector2(300.0f, 400.0f); + minSize = new Vector2(300f, 400f); if (m_Settings == null) { m_Settings = CreateInstance(); From bce70acfc38b2e2924e6738b98f6eb6f6843b495 Mon Sep 17 00:00:00 2001 From: Kenny Tan Date: Fri, 10 Apr 2026 21:07:22 +0000 Subject: [PATCH 68/88] [UUM-139229][URP 2D] Fix preview camera missing lighting and shadows --- .../Runtime/2D/Rendergraph/DrawLight2DPass.cs | 9 ++---- .../2D/Rendergraph/DrawRenderer2DPass.cs | 31 +++++++------------ .../Shaders/2D/Light2D.shader | 6 ++-- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawLight2DPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawLight2DPass.cs index 14adaf366f5..8a2b1de03f6 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawLight2DPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawLight2DPass.cs @@ -177,19 +177,16 @@ internal void Render(RenderGraph graph, ContextContainer frameData, int batchInd var layerBatch = frameData.Get().layerBatches[batchIndex]; DebugHandler debugHandler = GetActiveDebugHandler(cameraData); - var isDebugLightingActive = debugHandler?.IsLightingActive ?? true; + var isLightingActive = debugHandler?.IsLightingActive ?? true; #if UNITY_EDITOR if (cameraData.isSceneViewCamera && UnityEditor.SceneView.currentDrawingSceneView != null) - isDebugLightingActive &= UnityEditor.SceneView.currentDrawingSceneView.sceneLighting; - - if (cameraData.camera.cameraType == CameraType.Preview) - isDebugLightingActive = false; + isLightingActive &= UnityEditor.SceneView.currentDrawingSceneView.sceneLighting; #endif if (!layerBatch.lightStats.useLights || isVolumetric && !layerBatch.lightStats.useVolumetricLights || - !isDebugLightingActive) + !isLightingActive) return; // Render single RTs by for apis that don't support MRTs diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs index 91372f3983c..ccd9def2553 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawRenderer2DPass.cs @@ -31,7 +31,7 @@ private static void Execute(RasterGraphContext context, PassData passData) RendererLighting.SetLightShaderGlobals(cmd, passData.lightBlendStyles, passData.blendStyleIndices); #if UNITY_EDITOR - if (passData.isLitView) + if (passData.isLightingActive) #endif { if (passData.layerUseLights) @@ -79,7 +79,7 @@ class PassData internal bool activeDebugHandler; #if UNITY_EDITOR - internal bool isLitView; // Required for prefab view and preview camera + internal bool isLightingActive; // Required for prefab view and preview camera #endif } @@ -93,20 +93,13 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex Renderer2DData rendererData = frameData.Get().renderingData; var layerBatch = frameData.Get().layerBatches[batchIndex]; - bool isLitView = true; + DebugHandler debugHandler = GetActiveDebugHandler(cameraData); + var isLightingActive = debugHandler?.IsLightingActive ?? true; #if UNITY_EDITOR // Early out for prefabs if (cameraData.isSceneViewCamera && UnityEditor.SceneView.currentDrawingSceneView != null) - isLitView = UnityEditor.SceneView.currentDrawingSceneView.sceneLighting; - - // Early out for preview camera - if (cameraData.cameraType == CameraType.Preview) - isLitView = false; - - DebugHandler debugHandler = GetActiveDebugHandler(cameraData); - if (debugHandler != null) - isLitView = debugHandler.IsLightingActive; + isLightingActive = UnityEditor.SceneView.currentDrawingSceneView.sceneLighting; #endif // Preset global light textures for first batch @@ -114,14 +107,14 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex { using (var builder = graph.AddRasterRenderPass(k_SetLightBlendTexture, out var passData, m_SetLightBlendTextureProfilingSampler)) { - if (layerBatch.lightStats.useLights && isLitView) + if (layerBatch.lightStats.useLights && isLightingActive) { passData.lightTextures = universal2DResourceData.lightTextures[batchIndex]; for (var i = 0; i < passData.lightTextures.Length; i++) builder.UseTexture(passData.lightTextures[i]); } - SetGlobalLightTextures(graph, builder, frameData, batchIndex, isLitView); + SetGlobalLightTextures(graph, builder, frameData, batchIndex, isLightingActive); builder.AllowGlobalStateModification(true); @@ -143,7 +136,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex passData.isSceneLit = rendererData.lightCullResult.IsSceneLit(); passData.layerUseLights = layerBatch.lightStats.useLights; #if UNITY_EDITOR - passData.isLitView = isLitView; + passData.isLightingActive = isLightingActive; #endif var drawSettings = CreateDrawingSettings(k_ShaderTags, renderingData, cameraData, lightData, SortingCriteria.CommonTransparent); @@ -168,7 +161,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex builder.UseRendererList(passData.rendererList); } - if (passData.layerUseLights && isLitView) + if (passData.layerUseLights && isLightingActive) { passData.lightTextures = universal2DResourceData.lightTextures[batchIndex]; for (var i = 0; i < passData.lightTextures.Length; i++) @@ -189,7 +182,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex // Post set global light textures for next renderer pass var nextBatch = batchIndex + 1; if (nextBatch < universal2DResourceData.lightTextures.Length) - SetGlobalLightTextures(graph, builder, frameData, nextBatch, isLitView); + SetGlobalLightTextures(graph, builder, frameData, nextBatch, isLightingActive); builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => { @@ -198,13 +191,13 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex } } - void SetGlobalLightTextures(RenderGraph graph, IRasterRenderGraphBuilder builder, ContextContainer frameData, int batchIndex, bool isLitView) + void SetGlobalLightTextures(RenderGraph graph, IRasterRenderGraphBuilder builder, ContextContainer frameData, int batchIndex, bool isLightingActive) { Renderer2DData rendererData = frameData.Get().renderingData; var layerBatch = frameData.Get().layerBatches[batchIndex]; var lightTextures = frameData.Get().lightTextures[batchIndex]; - if (isLitView) + if (isLightingActive) { if (layerBatch.lightStats.useLights) { diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Light2D.shader b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Light2D.shader index c0d3d988160..531cf6cf339 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Light2D.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Light2D.shader @@ -71,7 +71,7 @@ Shader "Hidden/Light2D" half _InverseHDREmulationScale; - Varyings vert_shape_shared(float3 position, Attributes a) + Varyings vert_shape_shared(float3 position, Attributes a, PerLight2D light) { Varyings o = (Varyings)0; @@ -96,7 +96,7 @@ Shader "Hidden/Light2D" Varyings vert_provider(Attributes a, PerLight2D light) { - return vert_shape_shared(a.positionOS, a); + return vert_shape_shared(a.positionOS, a, light); } @@ -108,7 +108,7 @@ Shader "Hidden/Light2D" positionOS.x = positionOS.x + _L2D_FALLOFF_DISTANCE * a.color.r; positionOS.y = positionOS.y + _L2D_FALLOFF_DISTANCE * a.color.g; - return vert_shape_shared(positionOS, a); + return vert_shape_shared(positionOS, a, light); } Varyings vert_point(Attributes a, PerLight2D light) From 05712743f2f61761ac688d426775d31ea50b8062 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 10 Apr 2026 21:07:24 +0000 Subject: [PATCH 69/88] GFXLIGHT-1934 : Match SSR roughness / blur curve to reflection probes --- .../ScreenSpaceReflectionPass.cs | 1 - .../ShaderLibrary/ScreenSpaceReflectionCommon.hlsl | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs index 86b8c69be41..10e8274165b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs @@ -57,7 +57,6 @@ internal static class ShaderConstants internal static readonly int _MaxRaySteps = Shader.PropertyToID("_MaxRaySteps"); internal static readonly int _Downsample = Shader.PropertyToID("_Downsample"); internal static readonly int _ThicknessScaleAndBias = Shader.PropertyToID("_ThicknessScaleAndBias"); - internal static readonly int _ScreenSpaceReflectionFinalTexture = Shader.PropertyToID(k_ScreenSpaceReflectionTextureName); internal static readonly int _CameraProjections = Shader.PropertyToID("_CameraProjections"); internal static readonly int _CameraInverseProjections = Shader.PropertyToID("_CameraInverseProjections"); internal static readonly int _CameraInverseViewProjections = Shader.PropertyToID("_CameraInverseViewProjections"); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl index b9aac3a3216..811ce16660c 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ScreenSpaceReflectionCommon.hlsl @@ -32,11 +32,17 @@ float GetSSRTextureLastValidMipIndex() float GetSSRBlurConeHalfAngle(float perceptualRoughness) { float roughness = PerceptualRoughnessToRoughness(perceptualRoughness); - float roughnessSquared = roughness * roughness; - // Inspired by http://pascal.lecocq.home.free.fr/publications/lecocq_i3D2016_specularAreaLighting.pdf - float k = (1.0 - roughnessSquared) / (2.0 - roughnessSquared); - return (PI / 3.0) * sqrt(1 - 4.0 * k * k); + // Ref: "Moving Frostbite to PBR", p. 72. But using a different E value to match the reflection probe + // roughness curve. + // + // const float e = 0.85; + // return atan(e*roughness/(1.0 - e)); + + // (Hopefully) Faster polynomial approximation of above + float shininess = 1.0 - roughness; + float shininess2 = shininess * shininess; + return 0.2094 * (roughness + 5.6667 * (1.0 - shininess2 * shininess2)); } float GetSSRMipLevelFromPerceptualRoughness(float3 positionWS, float perceptualRoughness) From 740feca0ee6a3bc4b6a17257671e2f83dd8ea499 Mon Sep 17 00:00:00 2001 From: Rasmus Roenn Nielsen Date: Fri, 10 Apr 2026 21:07:26 +0000 Subject: [PATCH 70/88] Fix shader compilation warning (double definition of CellPatchIndexBufferType) --- .../Lighting/SurfaceCache/Estimation.hlsl | 4 +-- .../Lighting/SurfaceCache/PatchUtil.hlsl | 36 ++++++++----------- .../Lighting/SurfaceCache/PathTracing.hlsl | 4 +-- .../PatchAllocation.compute | 4 +-- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl index 1796b43e8db..3a0e8c68d13 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl @@ -1,7 +1,7 @@ -#define PATCH_UTIL_USE_RW_IRRADIANCE_BUFFER +#define PATCH_UTIL_USE_RW_PATCH_IRRADIANCE_BUFFER + #if BOUNCE_PATCH_ALLOCATION #define PATCH_UTIL_USE_RW_PATCH_GEOMETRY_BUFFER -#define PATCH_UTIL_USE_RW_CELL_INDEX_BUFFER #define PATCH_UTIL_USE_RW_CELL_PATCH_INDEX_BUFFER #define PATCH_UTIL_USE_RW_PATCH_CELL_INDEX_BUFFER #define PATCH_UTIL_USE_RW_CELL_ALLOCATION_MARK_BUFFER diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl index 0aff8bccbe5..7dd0461407c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl @@ -6,22 +6,10 @@ #include "Common.hlsl" #include "RingBuffer.hlsl" -#if defined(PATCH_UTIL_USE_RW_IRRADIANCE_BUFFER) -#define IrradianceBufferType RWStructuredBuffer +#if defined(PATCH_UTIL_USE_RW_PATCH_IRRADIANCE_BUFFER) +#define PatchIrradianceBufferType RWStructuredBuffer #else -#define IrradianceBufferType StructuredBuffer -#endif - -#if defined(PATCH_UTIL_USE_RW_CELL_INDEX_BUFFER) -#define CellPatchIndexBufferType RWStructuredBuffer -#else -#define CellPatchIndexBufferType StructuredBuffer -#endif - -#if defined(PATCH_UTIL_USE_RW_CELL_ALLOCATION_MARK_BUFFER) -#define CellAllocationMarkBufferType RWStructuredBuffer -#else -#define CellAllocationMarkBufferType StructuredBuffer +#define PatchIrradianceBufferType StructuredBuffer #endif #if defined(PATCH_UTIL_USE_RW_PATCH_GEOMETRY_BUFFER) @@ -37,11 +25,17 @@ #endif #if defined(PATCH_UTIL_USE_RW_CELL_PATCH_INDEX_BUFFER) -#define CellPatchndexBufferType RWStructuredBuffer +#define CellPatchIndexBufferType RWStructuredBuffer #else #define CellPatchIndexBufferType StructuredBuffer #endif +#if defined(PATCH_UTIL_USE_RW_CELL_ALLOCATION_MARK_BUFFER) +#define CellAllocationMarkBufferType RWStructuredBuffer +#else +#define CellAllocationMarkBufferType StructuredBuffer +#endif + namespace PatchUtil { static const uint invalidPatchIndex = UINT_MAX; // Must match C# side. @@ -311,7 +305,7 @@ namespace PatchUtil return result; } - bool ReadHemisphericalIrradiance(IrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, uint spatialResolution, uint cascadeIdx, uint3 volumeSpacePosition, float3 worldNormal, out SphericalHarmonics::RGBL1 resultIrradiance) + bool ReadHemisphericalIrradiance(PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, uint spatialResolution, uint cascadeIdx, uint3 volumeSpacePosition, float3 worldNormal, out SphericalHarmonics::RGBL1 resultIrradiance) { const uint directionIdx = GetDirectionIndex(worldNormal, volumeAngularResolution); const uint cellIdx = GetCellIndex(cascadeIdx, volumeSpacePosition, directionIdx, spatialResolution, volumeAngularResolution); @@ -361,7 +355,7 @@ namespace PatchUtil return patchIdx; } - bool ReadHemisphericalIrradiance(IrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, VolumeParamSet volumeParams, float3 worldPosition, float3 worldNormal, uint startCascadeIdx, out SphericalHarmonics::RGBL1 resultIrradiance) + bool ReadHemisphericalIrradiance(PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, VolumeParamSet volumeParams, float3 worldPosition, float3 worldNormal, uint startCascadeIdx, out SphericalHarmonics::RGBL1 resultIrradiance) { VolumePositionResolution posResolution = ResolveVolumePosition(worldPosition, volumeParams, startCascadeIdx); bool resultBool = false; @@ -377,7 +371,7 @@ namespace PatchUtil return resultBool; } - bool ReadHemisphericalIrradiance(IrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, VolumeParamSet volumeParams, float3 worldPosition, float3 worldNormal, out SphericalHarmonics::RGBL1 resultIrradiance) + bool ReadHemisphericalIrradiance(PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, VolumeParamSet volumeParams, float3 worldPosition, float3 worldNormal, out SphericalHarmonics::RGBL1 resultIrradiance) { const uint conservativeStartCascadeIdx = 0; return ReadHemisphericalIrradiance( @@ -390,7 +384,7 @@ namespace PatchUtil resultIrradiance); } - float3 ReadPlanarIrradiance(IrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, uint spatialResolution, uint cascadeIdx, uint3 volumeSpacePosition, float3 worldNormal) + float3 ReadPlanarIrradiance(PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, uint spatialResolution, uint cascadeIdx, uint3 volumeSpacePosition, float3 worldNormal) { SphericalHarmonics::RGBL1 resultIrradiance; bool resultBool = ReadHemisphericalIrradiance(patchIrradiances, cellPatchIndices, spatialResolution, cascadeIdx, volumeSpacePosition, worldNormal, resultIrradiance); @@ -400,7 +394,7 @@ namespace PatchUtil return invalidIrradiance; } - float3 ReadPlanarIrradiance(IrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, VolumeParamSet volumeParams, float3 worldPosition, float3 worldNormal) + float3 ReadPlanarIrradiance(PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, VolumeParamSet volumeParams, float3 worldPosition, float3 worldNormal) { VolumePositionResolution posResolution = ResolveVolumePosition(worldPosition, volumeParams); if (posResolution.isValid()) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl index 515e7af7432..55479d32ce6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl @@ -227,7 +227,7 @@ float3 OutgoingDirectionalBounceAndMultiBounceRadiance( float3 dirLightDirection, float3 dirLightIntensity, bool multiBounce, - IrradianceBufferType patchIrradiances, + PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, PatchUtil::VolumeParamSet volumeParams, float3 albedo, @@ -280,7 +280,7 @@ float3 IncomingEnviromentAndDirectionalBounceAndMultiBounceRadiance( bool multiBounce, TextureCube envTex, SamplerState envSampler, - IrradianceBufferType patchIrradiances, + PatchIrradianceBufferType patchIrradiances, PatchGeometryBufferType patchGeometries, RWStructuredBuffer patchStatistics, PatchUtil::PatchAllocationParamSet allocParams, diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute index 9e9a5499231..a57e2b4ad1c 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute @@ -1,8 +1,8 @@ #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal glcore ps5 #pragma kernel Allocate -#define PATCH_UTIL_USE_RW_IRRADIANCE_BUFFER -#define PATCH_UTIL_USE_RW_CELL_INDEX_BUFFER +#define PATCH_UTIL_USE_RW_PATCH_IRRADIANCE_BUFFER +#define PATCH_UTIL_USE_RW_CELL_PATCH_INDEX_BUFFER #define PATCH_UTIL_USE_RW_CELL_ALLOCATION_MARK_BUFFER #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" From 0e713681cc04a518d05a30c3cb5ff8ae0c7b5588 Mon Sep 17 00:00:00 2001 From: Camilo Pineda Date: Fri, 10 Apr 2026 21:30:04 +0000 Subject: [PATCH 71/88] Graphics/fix/uum 135643 remove unifiedraytracing asset bundle from urp template --- .../create-ray-tracing-context.md | 15 ++++++++++++++- .../GeometryPool/GeometryPoolKernels.compute.meta | 2 +- .../Common/Utilities/CopyBuffer.compute.meta | 2 +- .../RadeonRays/kernels/CopyPositions.compute.meta | 2 +- .../RadeonRays/kernels/bit_histogram.compute.meta | 2 +- .../kernels/block_reduce_part.compute.meta | 2 +- .../RadeonRays/kernels/block_scan.compute.meta | 2 +- .../RadeonRays/kernels/build_hlbvh.compute.meta | 2 +- .../kernels/restructure_bvh.compute.meta | 2 +- .../RadeonRays/kernels/scatter.compute.meta | 2 +- 10 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Documentation~/UnifiedRayTracing/create-ray-tracing-context.md b/Packages/com.unity.render-pipelines.core/Documentation~/UnifiedRayTracing/create-ray-tracing-context.md index baa4d4f9d87..ca17c94cb8c 100644 --- a/Packages/com.unity.render-pipelines.core/Documentation~/UnifiedRayTracing/create-ray-tracing-context.md +++ b/Packages/com.unity.render-pipelines.core/Documentation~/UnifiedRayTracing/create-ray-tracing-context.md @@ -35,7 +35,20 @@ rtResources.Load(); ``` **Note:** Since the Player doesn't give access to the Asset Database, this method only works in the Editor. -To load the [`RayTracingResources`](xref:UnityEngine.Rendering.UnifiedRayTracing.RayTracingResources) in the Player, you can also build the **unifiedraytracing** AssetBundle. For more information about how to build and load AssetBundles, refer to [AssetBundles](xref:AssetBundlesIntro). +To load the [`RayTracingResources`](xref:UnityEngine.Rendering.UnifiedRayTracing.RayTracingResources) in the Player, you can also build an AssetBundle that includes the following SRP Core files: +- Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute +- Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/copyPositions.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute +- Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute + +For more information about how to build and load AssetBundles, refer to [AssetBundles](xref:AssetBundlesIntro). + +Once the AssetBundle is built, you can load it using the following: ```C# var rtResources = new RayTracingResources(); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta index cc557f06e82..e17cc5f82d2 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta @@ -3,5 +3,5 @@ guid: 98e3d58cae7210c4786f67f504c9e899 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta index 11d24f17516..3019159bf4e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta @@ -3,5 +3,5 @@ guid: 1b95b5dcf48d1914c9e1e7405c7660e3 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta index c38dc07b130..5fc1c69bb8f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta @@ -3,5 +3,5 @@ guid: 1ad53a96b58d3c3488dde4f14db1aaeb ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta index 70fdcec3673..c9f5fa6abca 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta @@ -3,5 +3,5 @@ guid: 8670f7ce4b60cef43bed36148aa1b0a2 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta index b100a6c36fe..80fefc4585e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta @@ -3,5 +3,5 @@ guid: 4e034cc8ea2635c4e9f063e5ddc7ea7a ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta index 4d5a4a0920b..f14801f69fc 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta @@ -3,5 +3,5 @@ guid: 4d6d5de35fa45ef4a92119397a045cc9 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta index 971d99892e2..57b6939e4e0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta @@ -3,5 +3,5 @@ guid: 2d70cd6be91bd7843a39a54b51c15b13 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta index fb35c9df3bb..16e89b34855 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta @@ -3,5 +3,5 @@ guid: 56641cb88dcb31a4398a4997ef7a7a8c ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta index 0e873b73394..a35f3085641 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta @@ -3,5 +3,5 @@ guid: a2eaeefdac4637a44b734e85b7be9186 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: unifiedraytracing + assetBundleName: assetBundleVariant: From a26724dfc814f9f6ea34dc5dacaf841e2f7a194b Mon Sep 17 00:00:00 2001 From: Robin Bradley Date: Fri, 10 Apr 2026 21:30:04 +0000 Subject: [PATCH 72/88] [content automatically redacted] touching PlatformDependent folder --- .../Targets/UniversalDecalSubTarget.cs | 1 + .../Targets/UniversalLitSubTarget.cs | 1 + .../ShaderGraph/Targets/UniversalTarget.cs | 6 +++++ .../Targets/UniversalTerrainLitSubTarget.cs | 1 + .../Targets/UniversalUnlitSubTarget.cs | 1 + .../Runtime/DeferredLights.cs | 1 + .../ShaderLibrary/GBufferOutputFormat.hlsl | 25 +++++++++++++++++++ .../GBufferOutputFormat.hlsl.meta | 7 ++++++ .../Shaders/BakedLit.shader | 1 + .../Shaders/ComplexLit.shader | 1 + .../Shaders/Lit.shader | 1 + .../Shaders/Nature/SpeedTree7.shader | 1 + .../Shaders/Nature/SpeedTree7Billboard.shader | 1 + .../Shaders/Nature/SpeedTree8.shader | 2 +- .../Shaders/Particles/ParticlesLit.shader | 1 + .../Particles/ParticlesSimpleLit.shader | 1 + .../Shaders/SimpleLit.shader | 1 + .../Shaders/Terrain/TerrainLit.shader | 1 + .../Shaders/Terrain/TerrainLitAdd.shader | 1 + .../Shaders/Terrain/TerrainLitBase.shader | 1 + .../Shaders/Terrain/WavingGrass.shader | 1 + .../Terrain/WavingGrassBillboard.shader | 1 + .../Shaders/Unlit.shader | 1 + 23 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalDecalSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalDecalSubTarget.cs index b73a8719002..4864d96e608 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalDecalSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalDecalSubTarget.cs @@ -1121,6 +1121,7 @@ static class DecalIncludes // Post-graph { DecalPostgraph }, + { CoreIncludes.GBufferOutputFormat }, }; public static IncludeCollection ScenePicking = new IncludeCollection diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs index e2e0897433f..5b59c4cd96b 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs @@ -943,6 +943,7 @@ static class LitIncludes { CoreIncludes.CorePostgraph }, { kGBuffer, IncludeLocation.Postgraph }, { kPBRGBufferPass, IncludeLocation.Postgraph }, + { CoreIncludes.GBufferOutputFormat }, }; public static readonly IncludeCollection Meta = new IncludeCollection diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs index 941d3a1464e..da4a276f8b7 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs @@ -1778,6 +1778,7 @@ static class CoreIncludes const string kFog = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Fog.hlsl"; const string kRenderingLayers = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"; const string kProbeVolumes = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ProbeVolumeVariants.hlsl"; + const string kGbufferOutputFormat = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl"; public static readonly IncludeCollection CorePregraph = new IncludeCollection { @@ -1918,6 +1919,11 @@ static class CoreIncludes { { kLODCrossFade, IncludeLocation.Pregraph } }; + + public static readonly IncludeCollection GBufferOutputFormat = new IncludeCollection + { + { kGbufferOutputFormat, IncludeLocation.Postgraph, true } + }; } #endregion diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs index 2d3d217f03d..93e1dca4d3d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs @@ -1635,6 +1635,7 @@ static class TerrainCoreIncludes { TerrainCoreIncludes.CorePostgraph }, { TerrainCoreIncludes.kGBuffer, IncludeLocation.Postgraph }, { TerrainCoreIncludes.kPBRGBufferPass, IncludeLocation.Postgraph }, + { CoreIncludes.GBufferOutputFormat }, }; public static readonly IncludeCollection Meta = new IncludeCollection diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs index c2da6cb31c9..d7113dd9bc1 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs @@ -586,6 +586,7 @@ static class UnlitIncludes // Post-graph { CoreIncludes.CorePostgraph }, { kUnlitGBufferPass, IncludeLocation.Postgraph }, + { CoreIncludes.GBufferOutputFormat }, }; public static IncludeCollection LightingIncludes = new IncludeCollection diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs b/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs index 87ed0937c45..91a41f24f35 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs @@ -165,6 +165,7 @@ internal enum ClusterDeferredPasses internal int GBufferInputAttachmentCount { get { return 4 + (UseShadowMask ? 1 : 0); } } + // Keep these formats in sync with the formats in GBufferOutputFormat.hlsl internal GraphicsFormat GetGBufferFormat(int index) { if (index == GBufferAlbedoIndex) // sRGB albedo, materialFlags diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl new file mode 100644 index 00000000000..50a38ec224a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl @@ -0,0 +1,25 @@ +// This file contains functionality for letting the Unity Shader Compiler know what render target formats could be used +// The functionality provided here is intended to be used during in the material GBuffer pass. +#ifndef UNIVERSAL_GBUFFEROUTPUTFORMAT_INCLUDED +#define UNIVERSAL_GBUFFEROUTPUTFORMAT_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl" + +// Keep these formats in sync with the formats returned in DeferredLights.GetGBufferFormat +#pragma rendertarget_format_hint MRT0 R8G8B8A8_SRGB +#pragma rendertarget_format_hint MRT1 R8G8B8A8_SRGB +#pragma rendertarget_format_hint MRT2 R8G8B8A8_SRGB +#pragma rendertarget_format_hint MRT3 R8G8B8A8_SRGB,B10G11R11_UFloatPack32 +#pragma rendertarget_format_hint MRT4 R32_SFloat // Assume GBUFFER_FEATURE_DEPTH is always enabled at the moment. +#if defined(GBUFFER_FEATURE_RENDERING_LAYERS) +#pragma rendertarget_format_hint MRT5 R8_UInt, R16_UInt, R32_UInt +#if defined(GBUFFER_FEATURE_SHADOWMASK) +#pragma rendertarget_format_hint MRT6 B8G8R8A8_UNorm, R8G8B8A8_UNorm +#endif +#else // GBUFFER_FEATURE_RENDERING_LAYERS +#if defined(GBUFFER_FEATURE_SHADOWMASK) +#pragma rendertarget_format_hint MRT5 B8G8R8A8_UNorm, R8G8B8A8_UNorm +#endif +#endif + +#endif // UNIVERSAL_GBUFFEROUTPUTFORMAT_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta new file mode 100644 index 00000000000..a7178b5a276 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 87322610c9b88a64e8bce40c056d8116 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader index 89312d9872a..8d85c39e692 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader @@ -156,6 +156,7 @@ Shader "Universal Render Pipeline/Baked Lit" // Lighting include is needed because of GI #include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader index df538166845..bfbbc2fb189 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader @@ -328,6 +328,7 @@ Shader "Universal Render Pipeline/Complex Lit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader index 185de8e5fb5..42a1cc2031a 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader @@ -326,6 +326,7 @@ Shader "Universal Render Pipeline/Lit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader index 22527c1a269..6e1fddc57e4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader @@ -173,6 +173,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7" #include "SpeedTree7Input.hlsl" #include "SpeedTree7Passes.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader index bf07ebea661..f3b42d851f4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader @@ -117,6 +117,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7 Billboard" #include "SpeedTree7BillboardInput.hlsl" #include "SpeedTree7BillboardPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader index 36c36e442a8..aba67d1e63d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader @@ -171,7 +171,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #include "SpeedTree8Input.hlsl" #include "SpeedTree8Passes.hlsl" - + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader index 2fd8fa7a4f7..e167ab55fdc 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader @@ -242,6 +242,7 @@ Shader "Universal Render Pipeline/Particles/Lit" // Includes #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader index ee3139c9efd..3eade0b88e4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader @@ -247,6 +247,7 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" // Includes #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader index 0a76394a268..622cc282052 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader @@ -278,6 +278,7 @@ Shader "Universal Render Pipeline/Simple Lit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader index 63ef81f088b..4637e29b98a 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader @@ -205,6 +205,7 @@ Shader "Universal Render Pipeline/Terrain/Lit" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader index ed84d866e27..5205cf3a263 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader @@ -171,6 +171,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader index cb0001a9afc..6ec04dbb4da 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader @@ -165,6 +165,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader index 8c8160709ff..4ea0a5477bf 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader @@ -124,6 +124,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/WavingDoublePass" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader index 2225d078fb1..08aaf6d48e0 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader @@ -108,6 +108,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/BillboardWavingDoublePass #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader index 387802f5754..d46ef332d62 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader @@ -139,6 +139,7 @@ Shader "Universal Render Pipeline/Unlit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } From cf9c2a034ac5dd3ec13c42ed646706821a2c83ee Mon Sep 17 00:00:00 2001 From: Jesper Mortensen Date: Sat, 11 Apr 2026 04:04:41 +0000 Subject: [PATCH 73/88] Fix GFXLIGHT-2146: Adjust baking profile buffer sizes for Unity Compute Light Baker --- .../Editor/PathTracing/BakeInputSerialization.cs | 10 +++++----- .../Runtime/PathTracing/BakeLightmapDriver.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs index cb1340dc443..70c2c43dc6b 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs @@ -734,11 +734,11 @@ public static UInt64 TilingModeToLightmapExpandedBufferSize(TilingMode tilingMod // TODO: We need to change the naming of the entries in the enum see: https://jira.unity3d.com/browse/GFXFEAT-728 switch (tilingMode) { - case TilingMode.None: bufferSize = 1048576; break; // UI: Highest Performance - case TilingMode.Quarter: bufferSize = 524288; break; // UI: High Performance - case TilingMode.Sixteenth: bufferSize = 262144; break; // UI: Automatic (but it is not automatic) - case TilingMode.Sixtyfourth: bufferSize = 131072; break; // UI: Low Memory Usage - case TilingMode.TwoHundredFiftySixth: bufferSize = 65536; break; // UI: Lowest Memory Usage + case TilingMode.None: bufferSize = 2097152; break; // UI: Highest Performance + case TilingMode.Quarter: bufferSize = 1048576; break; // UI: High Performance + case TilingMode.Sixteenth: bufferSize = 524288; break; // UI: Automatic + case TilingMode.Sixtyfourth: bufferSize = 262144; break; // UI: Low Memory Usage + case TilingMode.TwoHundredFiftySixth: bufferSize = 131072; break; // UI: Lowest Memory Usage default: Debug.Assert(false, "Unknown tiling mode."); break; } return math.max(bufferSize, kMinBufferSize); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs index 01c6aea2a6f..89ac24ad0a4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/BakeLightmapDriver.cs @@ -83,7 +83,7 @@ public class LightmapBakeSettings public uint BounceCount = 4; public float AOMaxDistance = 1.0f; public float PushOff = 0.00001f; - public UInt64 ExpandedBufferSize = 262144; + public UInt64 ExpandedBufferSize = 524288; public LightSamplingMode DirectLightSamplingMode; public uint DirectRISCandidateCount; From b0ea30a20c21081e8ba8dbd28b1eaa58ecc26f96 Mon Sep 17 00:00:00 2001 From: Giulia Canu Date: Mon, 13 Apr 2026 08:34:12 +0000 Subject: [PATCH 74/88] [HDRP][XR] Update ClearBuffer2D to support XR views --- .../Runtime/Core/CoreResources/ClearBuffer2D.compute | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/ClearBuffer2D.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/ClearBuffer2D.compute index b52cd1f64fe..d4754113ccb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/ClearBuffer2D.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/ClearBuffer2D.compute @@ -12,6 +12,8 @@ RW_TEXTURE2D_X(float4, _Buffer2D); [numthreads(8, 8, 1)] void ClearBuffer2DMain(uint3 dispatchThreadID : SV_DispatchThreadID) { + UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadID.z); + if (any(dispatchThreadID.xy >= (uint2)_BufferSize.xy)) return; From dea3fee81e3a7a1dc39d308c40151e19d0d56208 Mon Sep 17 00:00:00 2001 From: Giulia Canu Date: Mon, 13 Apr 2026 17:09:08 +0000 Subject: [PATCH 75/88] [URP][HDRP] Add error messages when set Camera orthographic projection mode in XR --- .../BuildProcessors/HDRPProcessScene.cs | 46 +++++++++++++++++++ .../BuildProcessors/HDRPProcessScene.cs.meta | 2 + .../Camera/HDCameraUI.Drawers.cs | 19 ++++++++ ...nderPipelines.HighDefinition.Editor.asmdef | 4 +- .../Editor/BuildProcessors/URPProcessScene.cs | 43 +++++++++-------- ...UniversalRenderPipelineCameraUI.Drawers.cs | 11 +++++ 6 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs.meta diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs new file mode 100644 index 00000000000..af503d22b59 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs @@ -0,0 +1,46 @@ +#if ENABLE_VR && ENABLE_XR_MANAGEMENT +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +using UnityEditor.XR.Management; + +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.HighDefinition; + +namespace UnityEditor.Rendering.HighDefinition +{ + class HDRPProcessScene : IProcessSceneWithReport + { + public int callbackOrder => 0; + + public void OnProcessScene(UnityEngine.SceneManagement.Scene scene, BuildReport report) + { + if (!HDRPBuildData.instance.buildingPlayerForHDRenderPipeline) + return; + + var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); + var buildTargetSettings = XR.Management.XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup); + + if(buildTargetSettings == null || buildTargetSettings.AssignedSettings == null || buildTargetSettings.AssignedSettings.activeLoaders.Count <= 0) + return; + + GameObject[] roots = scene.GetRootGameObjects(); + foreach (GameObject root in roots) + { + Camera[] cameras = root.GetComponentsInChildren(); + foreach (Camera camera in cameras) + { + if (camera.TryGetComponent(out HDAdditionalCameraData cameraData)) + { + if (camera.orthographic && cameraData.xrRendering) + { + Debug.LogWarning($"One or more cameras have their projection set as Orthographic. This is not supported on XR and may produce artifacts at runtime. Please change the projection setting to Perspective to avoid issues."); + break; + } + } + } + } + } + } +} +#endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs.meta new file mode 100644 index 00000000000..58889b9ffd8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPProcessScene.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f9a96091c661d0742a99f9177805453c \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs index 348d8273e38..4e98fd31a87 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Drawers.cs @@ -1,3 +1,7 @@ +#if ENABLE_VR && ENABLE_XR_MANAGEMENT +using UnityEditor.XR; +#endif + using UnityEngine; using UnityEngine.Rendering.HighDefinition; @@ -27,13 +31,28 @@ public enum Expandable Environment = 1 << 6, } + static readonly ExpandedState k_ExpandedState = new ExpandedState(Expandable.Projection, "HDRP"); +#if ENABLE_VR && ENABLE_XR_MANAGEMENT + private static readonly CED.IDrawer OrthographicXRError = CED.Conditional( + (serialized, owner) => serialized.xrRendering.boolValue && serialized.baseCameraSettings.orthographic.boolValue, (serialized, owner) => + { + var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); + var buildTargetSettings = XR.Management.XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup); + if(buildTargetSettings != null && buildTargetSettings.AssignedSettings != null && buildTargetSettings.AssignedSettings.activeLoaders.Count > 0) + EditorGUILayout.HelpBox("Orthographic projection is not supported in XR. Please change the Camera Projection setting to Perspective to avoid rendering issues", MessageType.Warning); + }); +#endif + public static readonly CED.IDrawer SectionProjectionSettings = CED.FoldoutGroup( CameraUI.Styles.projectionSettingsHeaderContent, Expandable.Projection, k_ExpandedState, FoldoutOption.Indent, +#if ENABLE_VR && ENABLE_XR_MANAGEMENT + OrthographicXRError, +#endif CED.Group( CameraUI.Drawer_Projection ), diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Unity.RenderPipelines.HighDefinition.Editor.asmdef b/Packages/com.unity.render-pipelines.high-definition/Editor/Unity.RenderPipelines.HighDefinition.Editor.asmdef index 965e93a0edd..30144afa766 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Unity.RenderPipelines.HighDefinition.Editor.asmdef +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Unity.RenderPipelines.HighDefinition.Editor.asmdef @@ -17,6 +17,8 @@ "Unity.Rendering.Denoising.Runtime", "Unity.RenderPipelines.HighDefinition.Config.Runtime", "Unity.RenderPipelines.GPUDriven.Runtime", + "Unity.XR.Management.Editor", + "Unity.XR.Management", "Unity.InternalAPIEngineBridge.RenderPipelines.Core.Editor" ], "includePlatforms": [ @@ -36,7 +38,7 @@ }, { "name": "com.unity.xr.management", - "expression": "1.0.0", + "expression": "4.0.1", "define": "ENABLE_XR_MANAGEMENT" }, { diff --git a/Packages/com.unity.render-pipelines.universal/Editor/BuildProcessors/URPProcessScene.cs b/Packages/com.unity.render-pipelines.universal/Editor/BuildProcessors/URPProcessScene.cs index b6e9c20c9eb..3c966e4947d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/BuildProcessors/URPProcessScene.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/BuildProcessors/URPProcessScene.cs @@ -12,30 +12,15 @@ class URPProcessScene : IProcessSceneWithReport public void OnProcessScene(UnityEngine.SceneManagement.Scene scene, BuildReport report) { - bool usesURP = false; - if (GraphicsSettings.defaultRenderPipeline as UniversalRenderPipelineAsset != null) - { - // ^ The global pipeline is set to URP - usesURP = true; - } - else - { - // ^ The global pipeline isn't set to URP, but a quality setting could still use it - for (int i = 0; i < QualitySettings.count; i++) - { - if (QualitySettings.GetRenderPipelineAssetAt(i) as UniversalRenderPipelineAsset != null) - { - // ^ This quality setting uses URP - usesURP = true; - break; - } - } - } + bool usesURP = URPBuildData.instance.buildingPlayerForUniversalRenderPipeline; if (usesURP) { GameObject[] roots = scene.GetRootGameObjects(); - +#if XR_MANAGEMENT_4_0_1_OR_NEWER && ENABLE_VR && ENABLE_XR_MODULE + var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); + var buildTargetSettings = XR.Management.XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup); +#endif foreach (GameObject root in roots) { Light[] lights = root.GetComponentsInChildren(); @@ -58,6 +43,24 @@ public void OnProcessScene(UnityEngine.SceneManagement.Scene scene, BuildReport ); } } + +#if XR_MANAGEMENT_4_0_1_OR_NEWER && ENABLE_VR && ENABLE_XR_MODULE + if (buildTargetSettings != null && buildTargetSettings.AssignedSettings != null && buildTargetSettings.AssignedSettings.activeLoaders.Count > 0) + { + Camera[] cameras = root.GetComponentsInChildren(); + foreach (Camera camera in cameras) + { + if (camera.TryGetComponent(out UniversalAdditionalCameraData cameraData)) + { + if (camera.orthographic && cameraData.allowXRRendering) + { + Debug.LogWarning($"One or more cameras have their projection set as Orthographic. This is not supported on XR and may produce artifacts at runtime. Please change the projection setting to Perspective to avoid issues."); + break; + } + } + } + } +#endif } } } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs index 02d1a7aa5b9..bd17f413d6d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Drawers.cs @@ -73,7 +73,18 @@ static void DrawerProjection(UniversalRenderPipelineSerializedCamera p, Editor o bool pixelPerfectEnabled = camera.TryGetComponent(out var pixelPerfectCamera) && pixelPerfectCamera.enabled; if (pixelPerfectEnabled) EditorGUILayout.HelpBox(Styles.pixelPerfectInfo, MessageType.Info); +#if XR_MANAGEMENT_4_0_1_OR_NEWER && ENABLE_VR && ENABLE_XR_MODULE + if (p.baseCameraSettings.orthographic.boolValue && p.allowXRRendering.boolValue) + { + var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); + var buildTargetSettings = XR.Management.XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup); + if (buildTargetSettings != null && buildTargetSettings.AssignedSettings != null && buildTargetSettings.AssignedSettings.activeLoaders.Count > 0) + { + EditorGUILayout.HelpBox("Orthographic projection is not supported in XR. Please change the Camera Projection setting to Perspective to avoid rendering issues", MessageType.Warning); + } + } +#endif using (new EditorGUI.DisabledGroupScope(pixelPerfectEnabled)) CameraUI.Drawer_Projection(p, owner); } From 30e66f8b7537b657d761fbab1e0b9e20afc69222 Mon Sep 17 00:00:00 2001 From: Julien Amsellem Date: Mon, 13 Apr 2026 17:09:08 +0000 Subject: [PATCH 76/88] [VFX] Add a button to create a new ShaderGraph from an output context --- .../AssetCallbacks/CreateShaderGraph.cs | 15 ++-- .../Editor/Importers/ShaderGraphImporter.cs | 2 +- .../Importers/ShaderGraphImporterEditor.cs | 19 +++-- .../Views/Properties/ObjectPropertyRM.cs | 34 +++++++- .../UIResources/uss/ObjectPropertyRM.uss | 44 ---------- .../UIResources/uss/ObjectPropertyRM.uss.meta | 11 --- .../Editor/UIResources/uss/PropertyRM.uss | 5 ++ .../GraphViewTemplateWindowNonRegression.cs | 2 - .../Tests/GraphViewTemplateWindowOpening.cs | 46 +++++----- .../Tests/GraphViewTemplateWindowTest.cs | 20 +---- .../AllTests/Editor/Tests/VFXGUITests.cs | 39 +++++---- .../Editor/Tests/VFXSystemNamesTest.cs | 8 +- .../Editor/Tests/VFXViewWindowTests.cs | 84 +++++++++++++++++++ .../Editor/Tests/VFXViewWindowTests.cs.meta | 3 + 14 files changed, 199 insertions(+), 133 deletions(-) delete mode 100644 Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss delete mode 100644 Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss.meta create mode 100644 Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/VFXViewWindowTests.cs create mode 100644 Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/VFXViewWindowTests.cs.meta diff --git a/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderGraph.cs b/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderGraph.cs index ceedec4b761..892fbdf24fc 100644 --- a/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderGraph.cs +++ b/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderGraph.cs @@ -11,13 +11,13 @@ static class CreateShaderGraph [MenuItem("Assets/Create/Shader Graph/Blank Shader Graph", priority = CoreUtils.Sections.section1 + CoreUtils.Priorities.assetsCreateShaderMenuPriority)] public static void CreateBlankShaderGraph() { - CreateFromTemplate(null, string.Empty); + CreateFromTemplate(null, string.Empty, useProjectBrowserIfAvailable:true); } [MenuItem("Assets/Create/Shader Graph/From Template...")] public static void CreateFromTemplate() { - CreateFromTemplate(null); + CreateFromTemplate(null, useProjectBrowserIfAvailable:true); } /// @@ -26,8 +26,11 @@ public static void CreateFromTemplate() /// /// Callback to execute with the created shader graph asset. /// Shader Graph template file. Use string.Empty for Blank Shader Graph. + /// Defines a search query that will pre-filter the list of available templates + /// Defines a search query that will filter the list of available templates (and will be editable by the user) + /// When false, the save file dialog is used, otherwise the project window is used (if visible) /// New Shader Graph filename. - internal static void CreateFromTemplate(Action callback = null, string templateSourcePath = null, string filename = null, string hiddenSearchQuery = null, string initialSearchQuery = null) + internal static void CreateFromTemplate(Action callback, string templateSourcePath = null, string filename = null, string hiddenQuery = null, string initialQuery = null, bool useProjectBrowserIfAvailable = false) { if (!string.IsNullOrEmpty(templateSourcePath)) { @@ -44,7 +47,7 @@ internal static void CreateFromTemplate(Action callback = null, string t } } - bool projectWindowIsVisible = EditorWindow.HasOpenInstances(); + bool projectWindowIsVisible = useProjectBrowserIfAvailable && EditorWindow.HasOpenInstances(); NewGraphFromTemplateAction action = ScriptableObject.CreateInstance(); @@ -58,7 +61,7 @@ internal static void CreateFromTemplate(Action callback = null, string t if (templateSourcePath == null) { - GraphViewTemplateWindow.ShowCreateFromTemplate(shaderGraphTemplateHelper, action.CreateAndRenameGraphFromTemplate, showSaveDialog: !projectWindowIsVisible, hiddenSearchQuery: hiddenSearchQuery, initialSearchQuery: initialSearchQuery); + GraphViewTemplateWindow.ShowCreateFromTemplate(shaderGraphTemplateHelper, action.CreateAndRenameGraphFromTemplate, showSaveDialog: !projectWindowIsVisible, hiddenSearchQuery: hiddenQuery, initialSearchQuery: initialQuery); } else { @@ -87,7 +90,7 @@ internal static void CreateFromTemplate(Action callback = null, string t /// /// New Shader Graph filename. internal static void CreateGraphAndMaterialFromTemplate(Action callback = null, string templateSourcePath = null, string filename = null, string hiddenSearchQuery = null, string initialSearchQuery = null) { - CreateFromTemplate((template) => + CreateFromTemplate(template => { if (!string.IsNullOrEmpty(template)) { diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index de28301d0cf..249bfe118ce 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -77,7 +77,7 @@ Fallback Off [SerializeField] bool m_ExposeTemplateAsShader; - [SerializeField] + [SerializeField, HideInInspector] ShaderGraphIndexedData m_IndexedData; public bool UseAsTemplate diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs index e51b78257a6..d207fbf860b 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs @@ -167,7 +167,7 @@ GraphData GetGraphData(AssetImporter importer) } serializedObject.ApplyModifiedProperties(); - if (!hasFocus) + if (!hasFocus && !ObjectSelector.isVisible) { ApplyChanges(); } @@ -185,6 +185,8 @@ public override void OnEnable() public override void OnDisable() { base.OnDisable(); + // Also apply changes when the inspector is closed to ensure that any changes to the template settings are not lost. + ApplyChanges(); if (materialEditor != null) DestroyImmediate(materialEditor); } @@ -229,16 +231,19 @@ public static bool OnOpenAsset(EntityId entityId, int line) void ApplyChanges() { var importer = (AssetImporter)target; - if (needsSaveMetaFile) - { - AssetDatabase.ForceReserializeAssets(new []{ importer.assetPath }, ForceReserializeAssetsOptions.ReserializeMetadata); - } + if (needsReimport || needsSaveMetaFile) { + if (needsSaveMetaFile) + { + needsSaveMetaFile = false; + AssetDatabase.ForceReserializeAssets(new []{ importer.assetPath }, ForceReserializeAssetsOptions.ReserializeMetadata); + } + + needsReimport = false; AssetDatabase.ImportAsset(importer.assetPath); + } - needsSaveMetaFile = false; - needsReimport = false; } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/ObjectPropertyRM.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/ObjectPropertyRM.cs index d53e65e7fe5..f5e35468d3b 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/ObjectPropertyRM.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/ObjectPropertyRM.cs @@ -1,5 +1,8 @@ using System; + using UnityEditor.SearchService; +using UnityEditor.ShaderGraph; +using UnityEditor.ShaderGraph.Internal; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; @@ -13,8 +16,6 @@ class ObjectPropertyRM : PropertyRM public ObjectPropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { - styleSheets.Add(VFXView.LoadStyleSheet("ObjectPropertyRM")); - if (m_Provider.portType.IsSubclassOf(typeof(Texture))) { m_ObjectField = new ObjectField(ObjectNames.NicifyVariableName(controller.name)) { objectType = typeof(Texture), allowSceneObjects = false }; @@ -27,6 +28,17 @@ public ObjectPropertyRM(IPropertyRMProvider controller, float labelWidth) : base m_ObjectField.RegisterCallback>(OnValueChanged); Add(m_ObjectField); + + if (m_Provider.portType == typeof(ShaderGraphVfxAsset)) + { + var newButton = new Button(OnNewVFXShaderGraph) { name = "NewButton", text = "New..." }; + Add(newButton); + } + else if (m_Provider.portType == typeof(Shader)) + { + var newButton = new Button(OnNewShaderGraph) { name = "NewButton", text = "New..." }; + Add(newButton); + } } public override float GetPreferredControlWidth() => 140; @@ -82,5 +94,23 @@ private void OnShowObjectSelector() ObjectSelector.get.searchFilter = searchFilter; } + + private void OnNewVFXShaderGraph() => OnNewShaderGraphCommon(typeof(ShaderGraphVfxAsset), "shadergraph.vfx=\"supported\""); + private void OnNewShaderGraph() => OnNewShaderGraphCommon(typeof(Shader)); + + private void OnNewShaderGraphCommon(Type shaderType, string hiddenQuery = null) + { + void OnTemplateCreated(string assetPath) + { + if (!string.IsNullOrEmpty(assetPath)) + { + var shaderGraph = AssetDatabase.LoadAssetAtPath(assetPath, shaderType); + SetValue(shaderGraph); + NotifyValueChanged(); + } + } + + CreateShaderGraph.CreateFromTemplate(OnTemplateCreated, hiddenQuery: hiddenQuery); + } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss b/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss deleted file mode 100644 index 55ff4645f67..00000000000 --- a/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss +++ /dev/null @@ -1,44 +0,0 @@ -#PickIcon -{ - width: 12px; - height: 12px; - background-image: var(--unity-icons-picker); -} - -#PickButton -{ - margin: 0px 1px 0px -21px; - padding: 0; - border-width: 0; - border-bottom-left-radius: 0px; - border-top-left-radius: 0px; - width:16px; - height:15px; - justify-content: center; - align-items: center; - align-self: center; - background-color: var(--unity-colors-object_field_button-background); -} - -#PickLabel -{ - flex-grow: 1; - flex-shrink: 1; - margin: 1px 0; -} - - -#ValueIcon -{ - margin-left: 2px; - position: absolute; - align-self: center; - width: 12px; - height: 12px; -} - -#PickLabel > TextInput -{ - margin-right: 4px; - padding: 0 22px 0 18px; -} diff --git a/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss.meta b/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss.meta deleted file mode 100644 index 124da0506ed..00000000000 --- a/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/ObjectPropertyRM.uss.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b40791d0947b6d94fbabbb8da581185f -ScriptedImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 2 - userData: - assetBundleName: - assetBundleVariant: - script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} - disableValidation: 0 diff --git a/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/PropertyRM.uss b/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/PropertyRM.uss index fcc1ac1744d..a50a4f36680 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/PropertyRM.uss +++ b/Packages/com.unity.visualeffectgraph/Editor/UIResources/uss/PropertyRM.uss @@ -394,3 +394,8 @@ VFXColorField .colorcontainer .fieldContainer .unity-base-text-field__input { width: 36px; } + +#NewButton { + padding-top: 0; + margin-right: 0; +} diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowNonRegression.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowNonRegression.cs index b25cbd25c49..d4345de3ef8 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowNonRegression.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowNonRegression.cs @@ -30,7 +30,6 @@ public void SetUp() public IEnumerator UnitySetUp() { GraphViewTemplateWindowHelpers.SetLastUsedTemplatePref(); - GraphViewTemplateWindowHelpers.StopSearchIndexingTasks(); yield return null; } @@ -95,7 +94,6 @@ public IEnumerator VFXView_Create_From_No_Asset_Reuse_Same_View() // Find the "Create new Visual Effect Graph" button and click it var window = VFXViewWindow.GetAllWindows().First(); - GraphViewTemplateWindowHelpers.StopSearchIndexingTasks(); yield return OpenTemplateWindowNoAssetWindow(window); var templateWindow = EditorWindow.GetWindowDontShow(); var treeView = GraphViewTemplateWindowHelpers.GetTreeView(templateWindow); diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowOpening.cs b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowOpening.cs index a04fb4e892e..3515611c00c 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowOpening.cs +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Assets/AllTests/Editor/Tests/GraphViewTemplateWindowOpening.cs @@ -36,7 +36,6 @@ public GraphViewTemplateWindowOpening() [SetUp] public void SetUp() { - GraphViewTemplateWindowHelpers.StopSearchIndexingTasks(); while (EditorWindow.HasOpenInstances()) { EditorWindow.GetWindow()?.Close(); @@ -45,13 +44,6 @@ public void SetUp() AssetDatabase.Refresh(); } - [UnitySetUp] - public IEnumerator UnitySetUp() - { - GraphViewTemplateWindowHelpers.StopSearchIndexingTasks(); - yield return null; - } - [TearDown] public void TearDown() { @@ -63,22 +55,22 @@ public void TearDown() public IEnumerator Create_VFX_From_VFXGraph_Editor() { LoadTempGraph(); - yield return ClickButton(window.rootVisualElement, "create-button", EventModifiers.Control); - yield return CheckNewVFXIsCreated(); + yield return ClickButton(simulate, window.rootVisualElement, "create-button", modifier: EventModifiers.Control); + yield return CheckNewVFXIsCreated(simulate); } [UnityTest] public IEnumerator Create_VFX_From_VFXGraph_Editor_NoAsset() { yield return OpenTemplateWindowNoAssetWindow(); - yield return CheckNewVFXIsCreated(); + yield return CheckNewVFXIsCreated(simulate); } [UnityTest] public IEnumerator Create_VFX_From_VFXGraph_Editor_Cancel() { LoadTempGraph(); - yield return ClickButton(window.rootVisualElement, "create-button", EventModifiers.Control); + yield return ClickButton(simulate, window.rootVisualElement, "create-button", modifier: EventModifiers.Control); var templateWindow = EditorWindow.GetWindowDontShow(); Assert.NotNull(templateWindow); @@ -93,7 +85,7 @@ public IEnumerator Create_VFX_From_VFXGraph_Editor_Cancel() treeView.selectedIndex = 3; // Simulate click on cancel button - yield return ClickButton(templateWindow.rootVisualElement, "CancelButton"); + yield return ClickButton(simulate, templateWindow.rootVisualElement, "CancelButton"); Assert.AreEqual(0, mockSaveFileDialogHelper.CallCount); Assert.False(EditorWindow.HasOpenInstances()); @@ -105,7 +97,7 @@ public IEnumerator Create_VFX_From_Project_Browser() { yield return CreateWindowFromProjectBrowser(); - yield return CheckNewVFXIsCreated(); + yield return CheckNewVFXIsCreated(simulate); } [UnityTest] @@ -113,7 +105,7 @@ public IEnumerator Create_VFX_From_Inspector() { yield return CreateWindowFromInspector(); - yield return CheckNewVFXIsCreated(); + yield return CheckNewVFXIsCreated(simulate); } [UnityTest] @@ -126,7 +118,7 @@ public IEnumerator Insert_VFX_Template() Assert.AreEqual(0, m_Controller.contexts.Count()); // Get template dropdown from the VFX graph toolbar - yield return ClickButton(window.rootVisualElement, "create-button"); + yield return ClickButton(simulate, window.rootVisualElement, "create-button"); var templateWindow = EditorWindow.GetWindowDontShow(); Assert.NotNull(templateWindow); @@ -136,7 +128,7 @@ public IEnumerator Insert_VFX_Template() GraphViewTemplateWindowHelpers.TrySetSaveFileDialogHelper(templateWindow, mockSaveFileDialogHelper); // Simulate click on create button - yield return ClickButton(templateWindow.rootVisualElement, "CreateButton"); + yield return ClickButton(simulate, templateWindow.rootVisualElement, "CreateButton"); Assert.False(EditorWindow.HasOpenInstances()); Assert.AreEqual(0, mockSaveFileDialogHelper.CallCount); @@ -155,7 +147,7 @@ public IEnumerator Insert_VFX_Template_Cancel() Assert.AreEqual(0, m_Controller.contexts.Count()); // Get template dropdown from the VFX graph toolbar - yield return ClickButton(window.rootVisualElement, "create-button"); + yield return ClickButton(simulate, window.rootVisualElement, "create-button"); var templateWindow = EditorWindow.GetWindowDontShow(); Assert.NotNull(templateWindow); @@ -165,7 +157,7 @@ public IEnumerator Insert_VFX_Template_Cancel() GraphViewTemplateWindowHelpers.TrySetSaveFileDialogHelper(templateWindow, mockSaveFileDialogHelper); // Simulate click on cancel button - yield return ClickButton(templateWindow.rootVisualElement, "CancelButton"); + yield return ClickButton(simulate, templateWindow.rootVisualElement, "CancelButton"); Assert.False(EditorWindow.HasOpenInstances()); Assert.AreEqual(0, m_Controller.contexts.Count()); @@ -179,7 +171,7 @@ void LoadTempGraph() window.graphView.controller = m_Controller; } - internal static IEnumerator CheckNewVFXIsCreated() + internal static IEnumerator CheckNewVFXIsCreated(PanelSimulator panelSimulator) { // Make sure the project browser is opened var projectBrowser = EditorWindow.GetWindow(); @@ -204,7 +196,7 @@ internal static IEnumerator CheckNewVFXIsCreated() GraphViewTemplateWindowHelpers.TrySetSaveFileDialogHelper(templateWindow, new MockSaveFileDialogHelper(destinationPath)); // Simulate click on create button - yield return ClickButton(templateWindow.rootVisualElement, "CreateButton"); + yield return ClickButton(panelSimulator, templateWindow.rootVisualElement, "CreateButton"); Assert.False(EditorWindow.HasOpenInstances()); // Move focus to end new file name edition @@ -252,14 +244,22 @@ static List> GetTemplateTree(GraphViewTemp return treeView; }*/ - static IEnumerator ClickButton(VisualElement buttonParent, string buttonName, EventModifiers modifier = EventModifiers.None) + static IEnumerator ClickButton(PanelSimulator panelSimulator, VisualElement buttonParent, string buttonName, + EventModifiers modifier = EventModifiers.None) { foreach (var _ in Enumerable.Range(0, 10)) yield return null; var button = buttonParent.Q /// Shader used for the material /// Pass name for error messages. - /// A new Material instance using the provided shader. Null if the shader is not supported. - internal static Material LoadShader(Shader shader, string passName = "") + /// LogType for the message if the shader is not supported. + /// A new Material instance using the provided shader. Null if the shader is not supported or it's missing. + internal static Material LoadShader(Shader shader, string passName = "", LogType logLevel = LogType.Warning) { if (shader == null) { @@ -24,7 +25,7 @@ internal static Material LoadShader(Shader shader, string passName = "") } else if (!shader.isSupported) { - Debug.LogWarning($"Shader '{shader.name}' is not supported (in '{passName}'). PostProcessing render passes will not execute."); + Debug.unityLogger.Log(logLevel, $"Shader '{shader.name}' is not supported or has been stripped from the build (in '{passName}'). PostProcessing render passes will not execute."); return null; } @@ -34,6 +35,7 @@ internal static Material LoadShader(Shader shader, string passName = "") /// /// Creates a texture compatible with post-processing effects. /// + /// RenderGraph that creates the texture. /// Source texture for the texture descriptor. /// Texture name. From 3405fc68a2db6f8e4d43325ba38e4ba1b581ba37 Mon Sep 17 00:00:00 2001 From: Adrian Smith Date: Tue, 14 Apr 2026 01:39:37 +0000 Subject: [PATCH 78/88] Re-enabled Switch VT tests --- .../Assets/Scenes/003-VirtualTexturing.unity | 2 +- .../Tests/HDRP_Runtime_Graphics_Tests.cs | 10 +-- .../Switch2PlayerSettings.asset | 67 +++++++++++++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 Tests/SRPTests/Projects/HDRP_RuntimeTests/ProjectSettings/Switch2PlayerSettings.asset diff --git a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Scenes/003-VirtualTexturing.unity b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Scenes/003-VirtualTexturing.unity index c6d2c053b07..6e623841ce9 100644 --- a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Scenes/003-VirtualTexturing.unity +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Scenes/003-VirtualTexturing.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75322e26c3f689659347bb760430f3150dd2f941864fed28a07cbeec215eb905 +oid sha256:5f1dcd4564a3f3c7a124f0589fd794a44635866e92449ee0207f1dde2bb0f0f0 size 163338 diff --git a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs index f16eaa21860..0062521b693 100644 --- a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Assets/Tests/HDRP_Runtime_Graphics_Tests.cs @@ -67,14 +67,8 @@ public IEnumerable UnityOneTimeSetUp() )] [IgnoreGraphicsTest( "003-VirtualTexturing$", - "https://jira.unity3d.com/browse/UUM-131182 Both Switches fail on MultiThreaded (pass on Native Jobs)", - RuntimePlatform.Switch, RuntimePlatform.Switch2, RuntimePlatform.PS4, // Also unstable on PS4: https://jira.unity3d.com/browse/UUM-135501 - RenderingThreadingMode.MultiThreaded - )] - [IgnoreGraphicsTest( - "003-VirtualTexturing-Forward$", - "https://jira.unity3d.com/browse/UUM-131182 Switch fails on MultiThreaded (pass on Native Jobs)", - RuntimePlatform.Switch, + "https://jira.unity3d.com/browse/UUM-135501 Unstable on PS4", + RuntimePlatform.PS4, RenderingThreadingMode.MultiThreaded )] [IgnoreGraphicsTest( diff --git a/Tests/SRPTests/Projects/HDRP_RuntimeTests/ProjectSettings/Switch2PlayerSettings.asset b/Tests/SRPTests/Projects/HDRP_RuntimeTests/ProjectSettings/Switch2PlayerSettings.asset new file mode 100644 index 00000000000..7818563378f --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/ProjectSettings/Switch2PlayerSettings.asset @@ -0,0 +1,67 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 53 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21014, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.Switch2.Extensions.dll::UnityEditor.Switch2.Switch2PlayerSettings + m_SettingsVersion: 1 + m_SocketConfigEnabled: 0 + m_SocketMemoryPoolSize: 6144 + m_SocketAllocatorPoolSize: 128 + m_SocketConcurrencyLimit: 14 + m_TcpInitialSendBufferSize: 32 + m_TcpInitialReceiveBufferSize: 64 + m_TcpAutoSendBufferSizeMax: 256 + m_TcpAutoReceiveBufferSizeMax: 256 + m_UdpSendBufferSize: 9 + m_UdpReceiveBufferSize: 42 + m_SocketBufferEfficiency: 4 + m_SocketInitializeEnabled: 1 + m_NetworkInterfaceManagerInitializeEnabled: 1 + m_HTCSForPlayerConnectionDisabled: 0 + m_LTOSetting: 0 + m_UseCPUProfiler: 0 + m_EnableFileSystemTrace: 0 + m_PrimaryQueueCommandMemory: 4194304 + m_PrimaryQueueControlMemory: 65536 + m_PrimaryQueueComputeMemory: 262144 + m_ComputeQueueCommandMemory: 4194304 + m_ComputeQueueControlMemory: 16384 + m_ComputeQueueComputeMemory: 262144 + m_NVNShaderPoolsGranularity: 33554432 + m_NVNDefaultPoolsGranularity: 16777216 + m_NVNOtherPoolsGranularity: 16777216 + m_GpuScratchPoolGranularity: 2097152 + m_AllowGpuScratchShrinking: 0 + m_NVNMaxPublicTextureIDCount: 0 + m_NVNMaxPublicSamplerIDCount: 0 + m_KMaxWorkerMultiple: 8 + m_DisableAsyncCompute: 0 + m_EnableNxLegacyTextureLayout: 0 + m_ExperimentalNvnDeviceInitializeDlssFlag: 0 + m_CompilerFlags: + - + m_NMETAOverride: + m_ScreenResolutionBehavior: 2 + m_NativeFsCacheSize: 32 + m_IsHoldTypeHorizontal: 1 + m_SupportedNpadCount: 8 + m_EnableTouchScreen: 1 + m_NSODependencies: + m_MicroSleepForYieldTime: 25 + m_EnableRamDiskSupport: 0 + m_RamDiskSpaceSize: 12 + m_DockedResolution: 1 + m_HandheldResolution: 1 + m_SupportedNpadStyles: 4118 + m_ExtendedStructuredBufferBindings: 0 + m_CaStoreSource: 0 + m_CaStoreFilePath: From 8deab59697ec545f3b0bdcdf6e6c804846216521 Mon Sep 17 00:00:00 2001 From: Apoorva Joshi Date: Tue, 14 Apr 2026 01:39:41 +0000 Subject: [PATCH 79/88] Fix SSAO misaligned with dynamic resolution (ScalableBufferManager) --- .../ShaderLibrary/DeclareDepthTexture.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl index 3b0746c5cff..f6343389367 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl @@ -31,7 +31,7 @@ float4 _CameraDepthTexture_TexelSize; float SampleSceneDepth(float2 uv) { uv = ClampAndScaleUVForBilinear(UnityStereoTransformScreenSpaceTex(uv), _CameraDepthTexture_TexelSize.xy); - uint2 pixelCoord = uint2(uv * _CameraDepthTexture_TexelSize.zw); + uint2 pixelCoord = uint2(uv * _ScreenSize.xy); return LOAD_TEXTURE2D_X(_CameraDepthTexture, pixelCoord).r; } From d056c4f0e57a1f48a49d603e5830ae7f58f27ed5 Mon Sep 17 00:00:00 2001 From: Rasmus Roenn Nielsen Date: Tue, 14 Apr 2026 01:39:47 +0000 Subject: [PATCH 80/88] Fix jittering artifact in Surface Cache caused by "rank flipping" --- .../Lighting/SurfaceCache/Estimation.hlsl | 9 +- .../Lighting/SurfaceCache/Eviction.compute | 43 +++++---- .../Lighting/SurfaceCache/PatchUtil.hlsl | 92 +++++++++++++------ .../Lighting/SurfaceCache/PathTracing.hlsl | 52 ++++++----- .../Lighting/SurfaceCache/SurfaceCache.cs | 14 ++- .../SurfaceCache/TemporalFiltering.compute | 8 +- .../Debug.compute | 35 ++++--- .../PatchAllocation.compute | 36 ++++---- .../ScreenResolveLookup.compute | 2 +- 9 files changed, 175 insertions(+), 116 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl index 3a0e8c68d13..3db3f7400a5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Estimation.hlsl @@ -57,7 +57,7 @@ void ProcessAndStoreRadianceSample(RWStructuredBuffer SphericalHarmonics::CosineConvolve(radianceSample); PatchUtil::PatchStatisticsSet oldStats = patchStatistics[patchIdx]; - const uint oldUpdateCount = PatchUtil::GetUpdateCount(oldStats.patchCounters); + const uint oldUpdateCount = PatchUtil::GetUpdateCount(oldStats.counters); const uint newUpdateCount = min(oldUpdateCount + 1, PatchUtil::updateMax); const SphericalHarmonics::RGBL1 oldIrradiance = patchIrradiances[patchIdx]; @@ -79,9 +79,8 @@ void ProcessAndStoreRadianceSample(RWStructuredBuffer PatchUtil::PatchStatisticsSet newStats; newStats.mean = newL0ShortIrradiance; newStats.variance = newVariance; - newStats.patchCounters = oldStats.patchCounters; - PatchUtil::SetUpdateCount(newStats.patchCounters, newUpdateCount); - newStats.rank = oldStats.rank; + newStats.counters = oldStats.counters; + PatchUtil::SetUpdateCount(newStats.counters, newUpdateCount); patchStatistics[patchIdx] = newStats; } @@ -223,7 +222,7 @@ void Estimate(UnifiedRT::DispatchInfo dispatchInfo) QrngKronecker2D rng; const PatchUtil::PatchGeometry patchGeo = _PatchGeometries[patchIdx]; - bool enablePatchAllocation = (_PatchStatistics[patchIdx].rank == 0); + bool enablePatchAllocation = (PatchUtil::GetRank(_PatchStatistics[patchIdx].counters) == 0); MaterialPoolParamSet matPoolParams; matPoolParams.materialEntries = _MaterialEntries; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Eviction.compute b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Eviction.compute index e57d5f4de34..360d1cb9871 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Eviction.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Eviction.compute @@ -11,12 +11,7 @@ RWStructuredBuffer _PatchCellIndices; uint _RingConfigOffset; uint _FrameIdx; - -uint ModuloDistance(uint a, uint b, uint modulo) -{ - int dif = abs(int(a) - int(b)); - return min(dif, modulo - dif); -} +uint _BouncePatchAllocation; [numthreads(256, 1, 1)] void Evict(uint patchIdx : SV_DispatchThreadID) @@ -24,28 +19,32 @@ void Evict(uint patchIdx : SV_DispatchThreadID) if (!RingBuffer::IsPositionInUse(_RingConfigBuffer, _RingConfigOffset, patchIdx)) return; - const uint evictionThreshold = _PatchStatistics[patchIdx].rank == 0 ? 60 * 4 : 60 * 1; // patches allocated from bounce hits are evicted sooner - - // Reset all patches rank to 1 (that is not allowed to spawn more patches on bounces hit) - // Rank will be updated to 0 by the PatchAllocation.compute shader for patches that are seen from the camera - _PatchStatistics[patchIdx].rank = 1; - const uint cellIdx = _PatchCellIndices[patchIdx]; if (cellIdx == PatchUtil::invalidCellIndex) return; - const PatchUtil::PatchCounterSet counterSet = _PatchStatistics[patchIdx].patchCounters; - const uint lastAccessFrameIdx = PatchUtil::GetLastAccessFrame(counterSet); + PatchUtil::PatchStatisticsSet stats = _PatchStatistics[patchIdx]; - // Here we take into account that last frame access index is in [0, 2^16-1]. - // We use that the last frame index can never be later than current frame index. - const uint modulo = 65536; // 2^16 - const uint frameSinceLastUse = ModuloDistance(_FrameIdx % modulo, lastAccessFrameIdx, modulo); + const uint frameSinceLastAccess = PatchUtil::GetFramesSinceLastAccess(_FrameIdx, PatchUtil::GetLastAccessFrame(stats.counters)); - if (evictionThreshold < frameSinceLastUse) + if (PatchUtil::evictionThreshold < frameSinceLastAccess) { - _PatchCellIndices[patchIdx] = PatchUtil::invalidCellIndex; - _CellAllocationMarks[cellIdx] = 0; - _CellPatchIndices[cellIdx] = PatchUtil::invalidPatchIndex; + // If Bounce Patch Allocation is enabled, then rank 0 patches are + // first demoted to rank 1, then later they are evicted. + // If Bounce Patch Allocation is disabled we go directly to + // eviction. + if (_BouncePatchAllocation && PatchUtil::GetRank(stats.counters) == 0) + { + PatchUtil::SetRank(stats.counters, 1); + PatchUtil::SetLastAccessFrame(stats.counters, _FrameIdx); + _PatchStatistics[patchIdx] = stats; + } + else + { + _PatchCellIndices[patchIdx] = PatchUtil::invalidCellIndex; + _CellAllocationMarks[cellIdx] = 0; + _CellPatchIndices[cellIdx] = PatchUtil::invalidPatchIndex; + } } + } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl index 7dd0461407c..60dace7845e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PatchUtil.hlsl @@ -43,6 +43,7 @@ namespace PatchUtil static const uint volumeAngularResolution = 4; // Must match C# side. static const float3 invalidIrradiance = float3(-1, -1, -1); static const uint updateMax = 32; + static const uint evictionThreshold = 60 * 4; struct PatchGeometry { @@ -52,6 +53,10 @@ namespace PatchUtil struct PatchCounterSet { + // Layout + // 0x000000FF: Update count. + // 0x0000FF00: Rank. + // 0xFFFF0000: Last access frame. uint data; }; @@ -59,8 +64,7 @@ namespace PatchUtil { float3 mean; float3 variance; - PatchCounterSet patchCounters; - uint rank; + PatchCounterSet counters; }; struct VolumeParamSet @@ -81,14 +85,41 @@ namespace PatchUtil uint ringConfigOffset; }; - void Reset(inout PatchCounterSet set) + uint ModuloDistance(uint a, uint b, uint modulo) + { + int dif = abs(int(a) - int(b)); + return min(dif, modulo - dif); + } + + uint GetFramesSinceLastAccess(uint currentFrameIdx, uint patchLastAccessFrame) + { + // Here we take into account that last access frame index is in [0, 2^16-1]. + // We use that the last frame index can never be later than current frame index. + const uint modulo = 65536; // 2^16 + return ModuloDistance( + currentFrameIdx % modulo, + patchLastAccessFrame, + modulo); + } + + void Reset(out PatchCounterSet set) { set.data = 0; } uint GetUpdateCount(PatchCounterSet set) { - return set.data & 0xFFFF; + return set.data & 0xFF; + } + + uint GetRank(PatchCounterSet set) + { + return (set.data & 0xFF00) >> 8; + } + + void SetRank(inout PatchCounterSet set, uint rank) + { + set.data = (rank << 8) | (set.data & 0xFFFF00FF); } uint GetLastAccessFrame(PatchCounterSet set) @@ -98,7 +129,7 @@ namespace PatchUtil void SetUpdateCount(inout PatchCounterSet set, uint updateCount) { - set.data = updateCount | (set.data & 0xFFFF0000); + set.data = updateCount | (set.data & 0xFFFFFF00); } void SetLastAccessFrame(inout PatchCounterSet set, uint lastAccessFrame) @@ -113,9 +144,9 @@ namespace PatchUtil void WriteLastFrameAccess(RWStructuredBuffer statisticsSets, uint patchIdx, uint frameIdx) { - PatchCounterSet counterSet = statisticsSets[patchIdx].patchCounters; + PatchCounterSet counterSet = statisticsSets[patchIdx].counters; SetLastAccessFrame(counterSet, frameIdx); - statisticsSets[patchIdx].patchCounters = counterSet; + statisticsSets[patchIdx].counters = counterSet; } float GetVoxelSize(float voxelMinSize, uint cascadeIdx) @@ -166,14 +197,14 @@ namespace PatchUtil { // To avoid discontinuities near the cardinal axis directions, we apply an arbitrary rotation. // This is based on the assumption that surfaces oriented along the cardinal axis directions - // are most likely in a scene compared to other directions. + // are more likely in a scene compared to other directions. const float3x3 arbitraryRotation = float3x3( float3(0.34034f, -0.30925f, 0.888f), float3(-0.30925f, 0.85502f, 0.41629f), float3(-0.888f, -0.41629f, 0.19536f)); const float3 rotatedDirection = mul(arbitraryRotation, direction); - const uint2 angularSquarePos = min(uint2(3, 3), SphereToSquare(rotatedDirection) * angularResolution); + const uint2 angularSquarePos = min(uint2(angularResolution - 1, angularResolution - 1), SphereToSquare(rotatedDirection) * angularResolution); return angularSquarePos.y * angularResolution + angularSquarePos.x; } @@ -321,7 +352,7 @@ namespace PatchUtil return resultBool; } - uint FindPatchIndex(VolumeParamSet volumeParams, StructuredBuffer cellPatchIndices, float3 worldPosition, float3 worldNormal) + uint FindPatchIndex(VolumeParamSet volumeParams, CellPatchIndexBufferType cellPatchIndices, float3 worldPosition, float3 worldNormal) { VolumePositionResolution posResolution = ResolveVolumePosition(worldPosition, volumeParams); if (posResolution.isValid()) @@ -345,7 +376,7 @@ namespace PatchUtil } } - uint FindPatchIndexAndUpdateLastAccess(VolumeParamSet volumeParams, StructuredBuffer cellPatchIndices, RWStructuredBuffer patchStatisticSets, float3 worldPosition, float3 worldNormal, uint frameIdx) + uint FindPatchIndexAndUpdateLastAccess(VolumeParamSet volumeParams, CellPatchIndexBufferType cellPatchIndices, RWStructuredBuffer patchStatisticSets, float3 worldPosition, float3 worldNormal, uint frameIdx) { const uint patchIdx = FindPatchIndex(volumeParams, cellPatchIndices, worldPosition, worldNormal); if (patchIdx != invalidPatchIndex) @@ -384,12 +415,17 @@ namespace PatchUtil resultIrradiance); } + float3 EvalIrradiance(SphericalHarmonics::RGBL1 irradiance, float3 normal) + { + return max(0, SphericalHarmonics::Eval(irradiance, normal)); + } + float3 ReadPlanarIrradiance(PatchIrradianceBufferType patchIrradiances, CellPatchIndexBufferType cellPatchIndices, uint spatialResolution, uint cascadeIdx, uint3 volumeSpacePosition, float3 worldNormal) { SphericalHarmonics::RGBL1 resultIrradiance; bool resultBool = ReadHemisphericalIrradiance(patchIrradiances, cellPatchIndices, spatialResolution, cascadeIdx, volumeSpacePosition, worldNormal, resultIrradiance); if (resultBool) - return max(0, SphericalHarmonics::Eval(resultIrradiance, worldNormal)); + return EvalIrradiance(resultIrradiance, worldNormal); else return invalidIrradiance; } @@ -420,20 +456,16 @@ namespace PatchUtil PatchStatisticsSet InitPatchStatistics(float3 irradianceSeed, uint frameIndex, uint rank) { - PatchCounterSet counterSet; - Reset(counterSet); - PatchUtil::SetLastAccessFrame(counterSet, frameIndex); - PatchStatisticsSet stats; stats.mean = irradianceSeed; stats.variance = 0; - stats.patchCounters = counterSet; - stats.rank = rank; + Reset(stats.counters); + SetLastAccessFrame(stats.counters, frameIndex); + SetRank(stats.counters, rank); return stats; } - #if BOUNCE_PATCH_ALLOCATION void AllocatePatch( float3 worldPosition, @@ -461,17 +493,17 @@ namespace PatchUtil allocParams.cellAllocationMarks, cellIdx); - if (resolutionResult.code == PatchUtil::patchIndexResolutionCodeAllocationFailure || resolutionResult.code == PatchUtil::patchIndexResolutionCodeLookup) - return; - - PatchUtil::PatchGeometry geo; - geo.position = worldPosition; - geo.normal = worldNormal; - patchGeometries[resolutionResult.patchIdx] = geo; - - SphericalHarmonics::RGBL1 irradianceSeed = (SphericalHarmonics::RGBL1) 0; - patchIrradiances[resolutionResult.patchIdx] = irradianceSeed; - patchStatistics[resolutionResult.patchIdx] = PatchUtil::InitPatchStatistics(irradianceSeed.l0, frameIndex, /*rank*/ 1); + if (resolutionResult.code == PatchUtil::patchIndexResolutionCodeAllocationSuccess) + { + PatchUtil::PatchGeometry geo; + geo.position = worldPosition; + geo.normal = worldNormal; + patchGeometries[resolutionResult.patchIdx] = geo; + + SphericalHarmonics::RGBL1 irradianceSeed = (SphericalHarmonics::RGBL1)0; + patchIrradiances[resolutionResult.patchIdx] = irradianceSeed; + patchStatistics[resolutionResult.patchIdx] = PatchUtil::InitPatchStatistics(irradianceSeed.l0, frameIndex, /*rank*/ 1); + } } #endif } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl index 55479d32ce6..75c6c6cba64 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/PathTracing.hlsl @@ -232,9 +232,8 @@ float3 OutgoingDirectionalBounceAndMultiBounceRadiance( PatchUtil::VolumeParamSet volumeParams, float3 albedo, float3 emission, - out bool multiBounceSurfaceCacheMiss) + out uint bouncePatchIndex) { - multiBounceSurfaceCacheMiss = false; float3 radiance = 0.0f; if (any(dirLightIntensity != 0.0f)) @@ -248,21 +247,20 @@ float3 OutgoingDirectionalBounceAndMultiBounceRadiance( shadowRay.tMin = 0; shadowRay.tMax = FLT_MAX; - UnifiedRT::Hit hitResult2 = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, 0xFFFFFFFF, shadowRay, UnifiedRT::kRayFlagNone); - if (!hitResult2.IsValid()) + UnifiedRT::Hit hitResult = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, 0xFFFFFFFF, shadowRay, UnifiedRT::kRayFlagNone); + if (!hitResult.IsValid()) { radiance += dirLightIntensity * dot(-dirLightDirection, normal); } } } + bouncePatchIndex = PatchUtil::invalidPatchIndex; if (multiBounce) { - float3 cacheRead = PatchUtil::ReadPlanarIrradiance(patchIrradiances, cellPatchIndices, volumeParams, position, normal); - if (all(cacheRead != PatchUtil::invalidIrradiance)) - radiance += cacheRead; - else - multiBounceSurfaceCacheMiss = true; + bouncePatchIndex = PatchUtil::FindPatchIndex(volumeParams, cellPatchIndices, position, normal); + if (bouncePatchIndex != PatchUtil::invalidPatchIndex) + radiance += PatchUtil::EvalIrradiance(patchIrradiances[bouncePatchIndex], normal); } radiance *= albedo * INV_PI; @@ -304,7 +302,7 @@ float3 IncomingEnviromentAndDirectionalBounceAndMultiBounceRadiance( const float3 hitAlbedo = MaterialPool::LoadAlbedoWithBoost(matEntry, matPoolParams.albedoTextures, matPoolParams.albedoSampler, matPoolParams.atlasTexelSize, matPoolParams.albedoBoost, hitGeo.uv0, hitGeo.uv1); const float3 hitEmission = MaterialPool::LoadEmission(matEntry, matPoolParams.emissionTextures, matPoolParams.emissionSampler, matPoolParams.atlasTexelSize, hitGeo.uv0, hitGeo.uv1); - bool multiBounceSurfaceCacheMiss = false; + uint bouncePatchIndex; radiance = OutgoingDirectionalBounceAndMultiBounceRadiance( hitGeo.position, hitGeo.normal, @@ -318,20 +316,32 @@ float3 IncomingEnviromentAndDirectionalBounceAndMultiBounceRadiance( volumeParams, hitAlbedo, hitEmission, - multiBounceSurfaceCacheMiss); + bouncePatchIndex); #if BOUNCE_PATCH_ALLOCATION - if (multiBounceSurfaceCacheMiss && enablePatchAllocation) + if (enablePatchAllocation) { - PatchUtil::AllocatePatch( - hitGeo.position, - hitGeo.normal, - patchIrradiances, - patchGeometries, - patchStatistics, - allocParams, - volumeParams, - frameIndex); + if (bouncePatchIndex == PatchUtil::invalidPatchIndex) + { + PatchUtil::AllocatePatch( + hitGeo.position, + hitGeo.normal, + patchIrradiances, + patchGeometries, + patchStatistics, + allocParams, + volumeParams, + frameIndex); + } + else + { + PatchUtil::PatchCounterSet counters = patchStatistics[bouncePatchIndex].counters; + if (PatchUtil::GetRank(counters) == 1) + { + PatchUtil::SetLastAccessFrame(counters, frameIndex); + patchStatistics[bouncePatchIndex].counters = counters; + } + } } #endif } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs index f40ece7f15a..47a4f6d7d4f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs @@ -79,7 +79,7 @@ public SurfaceCachePatchList(uint capacity) _irradiances[1] = new GraphicsBuffer(GraphicsBuffer.Target.Structured, capacityInt, irradianceStride); _irradiances[2] = new GraphicsBuffer(GraphicsBuffer.Target.Structured, capacityInt, irradianceStride); - _statistics = new GraphicsBuffer(GraphicsBuffer.Target.Structured, capacityInt, sizeof(float) * 3 * 2 + sizeof(uint) + sizeof(uint)); + _statistics = new GraphicsBuffer(GraphicsBuffer.Target.Structured, capacityInt, sizeof(float) * 3 * 2 + sizeof(uint)); } public void Dispose() @@ -302,6 +302,7 @@ private class EvictionPassData internal GraphicsBuffer CellAllocationMarks; internal GraphicsBuffer CellPatchIndices; internal uint RingConfigOffset; + internal bool BouncePatchAllocation; internal uint FrameIdx; } @@ -385,7 +386,7 @@ private class TemporalFilterPassData internal int KernelIndex; internal uint3 ThreadGroupSize; internal GraphicsBuffer InputPatchIrradiances; - internal GraphicsBuffer OutputPatchIrradiances; + internal GraphicsBuffer InputOutputPatchIrradiances; internal GraphicsBuffer PatchStatistics; internal GraphicsBuffer RingConfigBuffer; internal uint PatchCapacity; @@ -396,6 +397,7 @@ private class TemporalFilterPassData internal static class ShaderIDs { public static readonly int _CellAllocationMarks = Shader.PropertyToID("_CellAllocationMarks"); + public static readonly int _BouncePatchAllocation = Shader.PropertyToID("_BouncePatchAllocation"); public static readonly int _CellPatchIndices = Shader.PropertyToID("_CellPatchIndices"); public static readonly int _MaterialEntries = Shader.PropertyToID("_MaterialEntries"); public static readonly int _AlbedoTextures = Shader.PropertyToID("_AlbedoTextures"); @@ -404,7 +406,6 @@ internal static class ShaderIDs public static readonly int _DirectionalLightIntensity = Shader.PropertyToID("_DirectionalLightIntensity"); public static readonly int _MaterialAtlasTexelSize = Shader.PropertyToID("_MaterialAtlasTexelSize"); public static readonly int _PunctualLightCount = Shader.PropertyToID("_PunctualLightCount"); - public static readonly int _TransmissionTextures = Shader.PropertyToID("_TransmissionTextures"); public static readonly int _EmissionTextures = Shader.PropertyToID("_EmissionTextures"); public static readonly int _VolumeTargetPos = Shader.PropertyToID("_VolumeTargetPos"); public static readonly int _EnvironmentCubemap = Shader.PropertyToID("_EnvironmentCubemap"); @@ -423,6 +424,7 @@ internal static class ShaderIDs public static readonly int _Radius = Shader.PropertyToID("_Radius"); public static readonly int _InputPatchIrradiances = Shader.PropertyToID("_InputPatchIrradiances"); public static readonly int _OutputPatchIrradiances = Shader.PropertyToID("_OutputPatchIrradiances"); + public static readonly int _InputOutputPatchIrradiances = Shader.PropertyToID("_InputOutputPatchIrradiances"); public static readonly int _PatchIrradiances = Shader.PropertyToID("_PatchIrradiances"); public static readonly int _FrameIdx = Shader.PropertyToID("_FrameIdx"); public static readonly int _CascadeOffsets = Shader.PropertyToID("_CascadeOffsets"); @@ -528,6 +530,7 @@ private void RecordEviction(RenderGraph renderGraph, uint frameIdx) passData.ThreadGroupSize = _resources.EvictionKernelGroupSize; passData.RingConfigBuffer = RingConfig.Buffer; passData.RingConfigOffset = RingConfig.OffsetA; + passData.BouncePatchAllocation = _estimationParams.BouncePatchAllocation; passData.PatchCellIndices = Patches.CellIndices; passData.PatchStatistics = Patches.Statistics; passData.CellAllocationMarks = Volume.CellAllocationMarks; @@ -580,7 +583,7 @@ private uint RecordFiltering(RenderGraph renderGraph, uint frameIdx) passData.KernelIndex = _resources.TemporalFilteringKernel; passData.ThreadGroupSize = _resources.TemporalFilteringKernelGroupSize; passData.InputPatchIrradiances = Patches.Irradiances[outputIrradianceBufferIdx]; - passData.OutputPatchIrradiances = Patches.Irradiances[2]; + passData.InputOutputPatchIrradiances = Patches.Irradiances[2]; passData.PatchStatistics = Patches.Statistics; passData.RingConfigBuffer = RingConfig.Buffer; passData.PatchCapacity = Patches.Capacity; @@ -814,7 +817,7 @@ static void FilterTemporally(TemporalFilterPassData data, ComputeGraphContext cg cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._RingConfigBuffer, data.RingConfigBuffer); cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._PatchStatistics, data.PatchStatistics); cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._InputPatchIrradiances, data.InputPatchIrradiances); - cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._OutputPatchIrradiances, data.OutputPatchIrradiances); + cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._InputOutputPatchIrradiances, data.InputOutputPatchIrradiances); cmd.SetComputeIntParam(shader, ShaderIDs._RingConfigOffset, (int)data.RingConfigOffset); cmd.SetComputeFloatParam(shader, ShaderIDs._ShortHysteresis, data.ShortHysteresis); @@ -875,6 +878,7 @@ static void Evict(EvictionPassData passData, ComputeGraphContext cgContext) cmd.SetComputeBufferParam(shader, kernelIndex, ShaderIDs._CellPatchIndices, passData.CellPatchIndices); cmd.SetComputeIntParam(shader, ShaderIDs._FrameIdx, (int)passData.FrameIdx); cmd.SetComputeIntParam(shader, ShaderIDs._RingConfigOffset, (int)passData.RingConfigOffset); + cmd.SetComputeIntParam(shader, ShaderIDs._BouncePatchAllocation, passData.BouncePatchAllocation ? 1 : 0); uint3 groupCount = DivUp(new uint3(passData.PatchCapacity, 1, 1), passData.ThreadGroupSize); cmd.DispatchCompute(shader, kernelIndex, (int)groupCount.x, (int)groupCount.y, 1); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/TemporalFiltering.compute b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/TemporalFiltering.compute index 9cb0cfd9bd6..1e8a3f99c3d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/TemporalFiltering.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/TemporalFiltering.compute @@ -10,7 +10,7 @@ StructuredBuffer _RingConfigBuffer; StructuredBuffer _InputPatchIrradiances; StructuredBuffer _PatchStatistics; -RWStructuredBuffer _OutputPatchIrradiances; +RWStructuredBuffer _InputOutputPatchIrradiances; uint _RingConfigOffset; float _ShortHysteresis; @@ -22,11 +22,11 @@ void FilterTemporally(uint patchIdx : SV_DispatchThreadID) return; const SphericalHarmonics::RGBL1 newIrradiance = _InputPatchIrradiances[patchIdx]; - const SphericalHarmonics::RGBL1 oldIrradiance = _OutputPatchIrradiances[patchIdx]; + const SphericalHarmonics::RGBL1 oldIrradiance = _InputOutputPatchIrradiances[patchIdx]; const PatchUtil::PatchStatisticsSet stats = _PatchStatistics[patchIdx]; - const uint updateCount = PatchUtil::GetUpdateCount(_PatchStatistics[patchIdx].patchCounters); + const uint updateCount = PatchUtil::GetUpdateCount(_PatchStatistics[patchIdx].counters); SphericalHarmonics::RGBL1 output = FilterTemporallyVarianceGuided(_ShortHysteresis, updateCount, stats.variance, stats.mean, newIrradiance, oldIrradiance); - _OutputPatchIrradiances[patchIdx] = output; + _InputOutputPatchIrradiances[patchIdx] = output; } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/Debug.compute b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/Debug.compute index 94e4c387a90..af76d5b0487 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/Debug.compute +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/Debug.compute @@ -44,26 +44,43 @@ float3 IsActuallyInf(float3 val) { [numthreads(8,8,1)] void Visualize(uint2 threadIdx : SV_DispatchThreadID) { + const float3 green = float3(0, 1, 0); + const float3 red = float3(1, 0, 0); + const float3 pink = float3(1, 0, 1); + const float3 white = float3(1, 1, 1); + const float3 yellow = float3(1, 1, 0); + uint2 screenSize; _ScreenDepths.GetDimensions(screenSize.x, screenSize.y); float3 output; - const float statusBarHeight = 0.05f; - if (float(threadIdx.y) / screenSize.y < statusBarHeight) + const float pixelPosYPercentage = float(threadIdx.y) / screenSize.y; + const float statusBarHeightPercentage = 0.05f; + if (pixelPosYPercentage < statusBarHeightPercentage) { const RingBuffer::Config ringConfig = RingBuffer::LoadConfig(_RingConfigBuffer, _RingConfigOffset); const uint patchIdx = float(threadIdx.x) / screenSize.x * patchCapacity; if (RingBuffer::IsPositionInUse(ringConfig, patchIdx)) { if (_PatchCellIndices[patchIdx] == PatchUtil::invalidCellIndex) - output = float3(1.0f, 0.0f, 0.0f); + { + output = red; + } else - output = float3(0.0f, 1.0f, 0.0f); + { + output = PatchUtil::GetRank(_PatchStatistics[patchIdx].counters) == 0 ? green : yellow; + if (pixelPosYPercentage < statusBarHeightPercentage * 0.5f) + { + PatchUtil::PatchStatisticsSet stats = _PatchStatistics[patchIdx]; + const uint frameSinceLastAccess = PatchUtil::GetFramesSinceLastAccess(_FrameIdx, PatchUtil::GetLastAccessFrame(stats.counters)); + output *= 1.0f - float(frameSinceLastAccess) / float(PatchUtil::evictionThreshold); + } + } } else { - output = float3(1.0f, 1.0f, 1.0f); + output = white; } } else @@ -72,10 +89,6 @@ void Visualize(uint2 threadIdx : SV_DispatchThreadID) if (ndcDepth == invalidNdcDepth) return; - const float3 green = float3(0, 1, 0); - const float3 red = float3(1, 0, 0); - const float3 pink = float3(1, 0, 1); - const float2 uv = (float2(threadIdx.xy) + 0.5f) / float2(screenSize); const float3 worldPos = ComputeWorldSpacePosition(uv, ndcDepth, _ClipToWorldTransform); const float3 worldShadedNormal = UnpackGBufferNormal(_ScreenShadedNormals[threadIdx.xy]); @@ -107,7 +120,7 @@ void Visualize(uint2 threadIdx : SV_DispatchThreadID) PatchUtil::WriteLastFrameAccess(_PatchStatistics, patchIdx, _FrameIdx); } - if (_ShowSamplePosition == 1 && hasPatch && length(worldPos - patchPos) < 0.12f) + if (_ShowSamplePosition == 1 && hasPatch && length(worldPos - patchPos) < 0.1f * PatchUtil::GetVoxelSize(_VolumeVoxelMinSize, posResolution.cascadeIdx)) { output = 30.0f; } @@ -174,7 +187,7 @@ void Visualize(uint2 threadIdx : SV_DispatchThreadID) { if (hasPatch) { - const PatchUtil::PatchCounterSet counterSet = _PatchStatistics[patchIdx].patchCounters; + const PatchUtil::PatchCounterSet counterSet = _PatchStatistics[patchIdx].counters; const uint updateCount = PatchUtil::GetUpdateCount(counterSet); const float s = float(updateCount) / PatchUtil::updateMax; const float3 redGreenMix = lerp(red, green, s); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute index a57e2b4ad1c..d523b912db9 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/PatchAllocation.compute @@ -144,19 +144,24 @@ void Allocate(uint2 lowResPixelPos : SV_DispatchThreadID) geo.position = sourceWorldPosition; geo.normal = sourceWorldFlatNormal; _PatchGeometries[resolutionResult.patchIdx] = geo; + } + if (resolutionResult.code == PatchUtil::patchIndexResolutionCodeLookup) + { // with this, we allow patches that were spawn from a hit bounce to, in turn, triger bounce allocation // once they are seen again by the camera - _PatchStatistics[resolutionResult.patchIdx].rank = 0; + PatchUtil::PatchStatisticsSet stats = _PatchStatistics[resolutionResult.patchIdx]; + if (PatchUtil::GetRank(stats.counters) != 0) + { + PatchUtil::SetRank(stats.counters, 0); + _PatchStatistics[resolutionResult.patchIdx] = stats; + } } - - if (resolutionResult.code == PatchUtil::patchIndexResolutionCodeAllocationSuccess) + else if (resolutionResult.code == PatchUtil::patchIndexResolutionCodeAllocationSuccess) { - PatchUtil::PatchCounterSet counterSet; - PatchUtil::Reset(counterSet); - PatchUtil::SetLastAccessFrame(counterSet, _FrameIdx); - + uint patchUpdateCount = 0; SphericalHarmonics::RGBL1 irradianceSeed = (SphericalHarmonics::RGBL1)0; + if (_FrameIdx != 0) { if (_UseMotionVectorSeeding) @@ -185,12 +190,12 @@ void Allocate(uint2 lowResPixelPos : SV_DispatchThreadID) seedLowResPixelPos); if (PatchUtil::IsValid(irradianceSeed)) - PatchUtil::SetUpdateCount(counterSet, PatchUtil::updateMax / 2); + patchUpdateCount = PatchUtil::updateMax / 2; #ifdef SEED_DEBUGGING else { irradianceSeed = (SphericalHarmonics::RGBL1)0; - PatchUtil::SetUpdateCount(counterSet, PatchUtil::updateMax); + patchUpdateCount = PatchUtil::updateMax; irradianceSeed.l0 = float3(10, 0, 0); } #endif @@ -198,7 +203,7 @@ void Allocate(uint2 lowResPixelPos : SV_DispatchThreadID) #ifdef SEED_DEBUGGING else { - PatchUtil::SetUpdateCount(counterSet, PatchUtil::updateMax); + patchUpdateCount = PatchUtil::updateMax; irradianceSeed.l0 = float3(0, 0, 10); } #endif @@ -215,13 +220,13 @@ void Allocate(uint2 lowResPixelPos : SV_DispatchThreadID) lowResPixelPos); if (PatchUtil::IsValid(irradianceSeed)) - PatchUtil::SetUpdateCount(counterSet, PatchUtil::updateMax / 2); + patchUpdateCount = PatchUtil::updateMax / 2; } #ifdef SEED_DEBUGGING // For debugging: Add color to unseeded patches. if (PatchUtil::GetUpdateCount(counterSet) == 0) { - PatchUtil::SetUpdateCount(counterSet, PatchUtil::updateMax); + patchUpdateCount = PatchUtil::updateMax; irradianceSeed.l0 = float3(0, 10, 0); } #endif @@ -229,11 +234,8 @@ void Allocate(uint2 lowResPixelPos : SV_DispatchThreadID) _PatchIrradiances0[resolutionResult.patchIdx] = irradianceSeed; _PatchIrradiances1[resolutionResult.patchIdx] = irradianceSeed; - PatchUtil::PatchStatisticsSet stats; - stats.mean = irradianceSeed.l0; - stats.variance = 0; - stats.patchCounters = counterSet; - stats.rank = 0; + PatchUtil::PatchStatisticsSet stats = PatchUtil::InitPatchStatistics(irradianceSeed.l0, _FrameIdx, 0); + PatchUtil::SetUpdateCount(stats.counters, patchUpdateCount); _PatchStatistics[resolutionResult.patchIdx] = stats; } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ScreenResolveLookup.compute b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ScreenResolveLookup.compute index 97857d3738b..176d5c85023 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ScreenResolveLookup.compute +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ScreenResolveLookup.compute @@ -93,7 +93,7 @@ void Lookup(uint2 lowResPixelPos : SV_DispatchThreadID) const float3 jitteredWorldDir = mul(orthoBasis, localJitteredDirection); uint patchIdx = PatchUtil::FindPatchIndex(volumeParams, _CellPatchIndices, jitteredWorldPos, jitteredWorldDir); - if (patchIdx != PatchUtil::invalidPatchIndex && _PatchStatistics[patchIdx].rank == 0) // rank used to exclude patches that are not visible from the camera + if (patchIdx != PatchUtil::invalidPatchIndex && PatchUtil::GetRank(_PatchStatistics[patchIdx].counters) == 0) // rank used to exclude patches that are not visible from the camera { PatchUtil::WriteLastFrameAccess(_PatchStatistics, patchIdx, _FrameIdx); SphericalHarmonics::AddMut(irradianceSum, _PatchIrradiances[patchIdx]); From 54090180d5dde8dfe48a2e4c57643d92b0eab375 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 14 Apr 2026 07:32:12 +0000 Subject: [PATCH 81/88] Updated `DecalProjector` and `DecalRendererFeature` to work with CoreCLR --- .../Runtime/Decal/DecalProjector.cs | 14 ++++++++++++++ .../RendererFeatures/DecalRendererFeature.cs | 13 +++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs index b136f041e9d..06ebdb6e210 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs @@ -435,5 +435,19 @@ void ISerializationCallbackReceiver.OnAfterDeserialize() version = Version.RenderingLayerMask; } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + onDecalAdd = null; + onDecalRemove = null; + onDecalPropertyChange = null; + onAllDecalPropertyChange = null; + onDecalMaterialChange = null; + + defaultMaterial = null; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs index 1d4cf6f903a..d0e2d7b5282 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs @@ -128,7 +128,7 @@ public void Release(DecalEntityManager decalEntityManager) public void Dispose() { - m_DecalEntityManager.Dispose(); + m_DecalEntityManager?.Dispose(); m_DecalEntityManager = null; m_ReferenceCounter = 0; @@ -182,7 +182,7 @@ private void OnDecalMaterialChange(DecalProjector decalProjector) [Icon("Packages/com.unity.render-pipelines.core/Editor/Icons/Processed/DecalProjector Icon.asset")] public partial class DecalRendererFeature : ScriptableRendererFeature { - private static SharedDecalEntityManager sharedDecalEntityManager { get; } = new SharedDecalEntityManager(); + private static SharedDecalEntityManager sharedDecalEntityManager = new SharedDecalEntityManager(); [SerializeField] private DecalSettings m_Settings = new DecalSettings(); @@ -557,5 +557,14 @@ private void ChangeAdaptivePerformanceDrawDistances() } #endif } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + sharedDecalEntityManager?.Dispose(); + sharedDecalEntityManager = new SharedDecalEntityManager(); + } +#endif } } From ab3734a87772e30ba67abceac2ca8b68f2d8d5f0 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Tue, 14 Apr 2026 12:06:29 +0000 Subject: [PATCH 82/88] Updated `TemporalAA` and `STP` to work with CoreCLR --- .../Passes/PostProcess/StpPostProcessPass.cs | 5 ++++- .../TemporalAntiAliasingPostProcessPass.cs | 5 ++++- .../Runtime/StpUtils.cs | 10 ++++++++- .../Runtime/TemporalAA.cs | 22 ++++++++++++++----- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/StpPostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/StpPostProcessPass.cs index abaaac1fe0c..55e7988291b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/StpPostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/StpPostProcessPass.cs @@ -12,6 +12,7 @@ internal sealed class StpPostProcessPass : PostProcessPass public const string k_UpscaledColorTargetName = "CameraColorUpscaledSTP"; Texture2D[] m_BlueNoise16LTex; bool m_IsValid; + uint m_WarnCounter; public StpPostProcessPass(Texture2D[] blueNoise16LTex) { @@ -20,6 +21,8 @@ public StpPostProcessPass(Texture2D[] blueNoise16LTex) m_BlueNoise16LTex = blueNoise16LTex; m_IsValid = m_BlueNoise16LTex != null && m_BlueNoise16LTex.Length > 0; + + m_WarnCounter = 0; } public override void Dispose() @@ -52,7 +55,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer { // Warn users if TAA and STP are disabled despite being requested if (cameraData.IsTemporalAARequested()) - TemporalAA.ValidateAndWarn(cameraData, isSTPRequested); + TemporalAA.ValidateAndWarn(cameraData, ref m_WarnCounter, isSTPRequested); return; } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/TemporalAntiAliasingPostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/TemporalAntiAliasingPostProcessPass.cs index 167bad51e2e..b7ca47b4a6e 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/TemporalAntiAliasingPostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/TemporalAntiAliasingPostProcessPass.cs @@ -10,6 +10,7 @@ internal sealed class TemporalAntiAliasingPostProcessPass : PostProcessPass Material m_Material; bool m_IsValid; + uint m_WarnCounter; public TemporalAntiAliasingPostProcessPass(Shader shader) { @@ -18,6 +19,8 @@ public TemporalAntiAliasingPostProcessPass(Shader shader) m_Material = PostProcessUtils.LoadShader(shader, passName); m_IsValid = m_Material != null; + + m_WarnCounter = 0; } public override void Dispose() @@ -49,7 +52,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer { // Warn users if TAA is disabled despite being requested if (cameraData.IsTemporalAARequested()) - TemporalAA.ValidateAndWarn(cameraData, false); + TemporalAA.ValidateAndWarn(cameraData, ref m_WarnCounter, false); return; } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/StpUtils.cs b/Packages/com.unity.render-pipelines.universal/Runtime/StpUtils.cs index 8f34940e331..5d1d1a1998f 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/StpUtils.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/StpUtils.cs @@ -113,7 +113,7 @@ static void PopulateStpConfig(UniversalCameraData cameraData, in TextureHandle i config.perViewConfigs = STP.perViewConfigs; } - static internal void Execute(RenderGraph renderGraph, UniversalResourceData resourceData, UniversalCameraData cameraData, in TextureHandle inputColor, in TextureHandle inputDepth, in TextureHandle inputMotion, in TextureHandle destination, Texture2D noiseTexture) + internal static void Execute(RenderGraph renderGraph, UniversalResourceData resourceData, UniversalCameraData cameraData, in TextureHandle inputColor, in TextureHandle inputDepth, in TextureHandle inputMotion, in TextureHandle destination, Texture2D noiseTexture) { var debugView = TextureHandle.nullHandle; int debugViewIndex = 0; @@ -141,5 +141,13 @@ static internal void Execute(RenderGraph renderGraph, UniversalResourceData reso PopulateStpConfig(cameraData, inputColor, inputDepth, inputMotion, debugViewIndex, debugView, destination, noiseTexture, out var config); STP.Execute(renderGraph, ref config); } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_JitterFunc = CalculateJitter; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/TemporalAA.cs b/Packages/com.unity.render-pipelines.universal/Runtime/TemporalAA.cs index 8a4c96f9a8c..b091b28106d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/TemporalAA.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/TemporalAA.cs @@ -291,7 +291,7 @@ internal static float[] CalculateFilterWeights(ref Settings settings) return taaFilterWeights; } - internal static GraphicsFormat[] AccumulationFormatList = new GraphicsFormat[] + internal static readonly GraphicsFormat[] AccumulationFormatList = new GraphicsFormat[] { GraphicsFormat.R16G16B16A16_SFloat, GraphicsFormat.B10G11R11_UFloatPack32, @@ -335,9 +335,7 @@ internal static RenderTextureDescriptor TemporalAADescFromCameraDesc(ref RenderT return taaDesc; } - static uint s_warnCounter = 0; - - internal static string ValidateAndWarn(UniversalCameraData cameraData, bool isSTPRequested = false) + internal static string ValidateAndWarn(UniversalCameraData cameraData, ref uint warnCounter, bool isSTPRequested = false) { string reasonWarning = null; @@ -375,9 +373,13 @@ internal static string ValidateAndWarn(UniversalCameraData cameraData, bool isST if (reasonWarning != null) { const int warningThrottleFrames = 60 * 1; // 60 FPS * 1 sec - if (s_warnCounter % warningThrottleFrames == 0) + if (warnCounter % warningThrottleFrames == 0) Debug.LogWarning("Disabling TAA " + (isSTPRequested ? "and STP " : "") + reasonWarning); - s_warnCounter++; + + unchecked + { + warnCounter++; + } } return reasonWarning; @@ -529,5 +531,13 @@ internal static void Render(RenderGraph renderGraph, Material taaMaterial, Unive cameraData.taaHistory.SetAccumulationVersion(multipassId, Time.frameCount); } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_JitterFunc = CalculateJitter; + } +#endif } } From 74b43d8be63d8a5bafd8ffe7a55a3c889c2fd063 Mon Sep 17 00:00:00 2001 From: Thomas Zeng Date: Wed, 15 Apr 2026 09:06:11 +0000 Subject: [PATCH 83/88] Fixed Subpass enum shader keyword does not match actual shader keyword. --- .../Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs | 6 +++--- .../Runtime/UniversalRenderPipelineCore.cs | 4 ++-- .../ShaderLibrary/DeclareDepthTexture.hlsl | 4 ++-- .../ShaderLibrary/ShaderGraphFunctions.hlsl | 4 ++-- .../CustomFetchDepth.shader | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs index a2f8913b11c..9acd1d28b2c 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Nodes/FetchSceneDepthNode.cs @@ -94,7 +94,7 @@ static string Unity_FetchSceneDepth_Linear01( return @" { - #if defined(DEPTH_AS_INPUT_ATTACHMENT) || defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + #if defined(_DEPTH_AS_INPUT_ATTACHMENT) || defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA) // Fetch depth from tile memory using input attachment float rawDepth = shadergraph_LWFetchSceneDepth(clipPos.xy); Out = Linear01Depth(rawDepth, _ZBufferParams); @@ -113,7 +113,7 @@ static string Unity_FetchSceneDepth_Raw( return @" { - #if defined(DEPTH_AS_INPUT_ATTACHMENT) || defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + #if defined(_DEPTH_AS_INPUT_ATTACHMENT) || defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA) // Fetch raw depth from tile memory using input attachment Out = shadergraph_LWFetchSceneDepth(clipPos.xy); #else @@ -131,7 +131,7 @@ static string Unity_FetchSceneDepth_Eye( return @" { - #if defined(DEPTH_AS_INPUT_ATTACHMENT) || defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) + #if defined(_DEPTH_AS_INPUT_ATTACHMENT) || defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA) // Fetch depth from tile memory using input attachment float rawDepth = shadergraph_LWFetchSceneDepth(clipPos.xy); { diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 700457aaffa..0acede52388 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -1480,10 +1480,10 @@ public static class ShaderKeywordStrings public const string Msaa4 = "_MSAA_4"; /// Keyword used for depth as input attachment. - public const string DEPTH_AS_INPUT_ATTACHMENT = "DEPTH_AS_INPUT_ATTACHMENT"; + public const string DEPTH_AS_INPUT_ATTACHMENT = "_DEPTH_AS_INPUT_ATTACHMENT"; /// Keyword used for depth as input attachment MSAA. - public const string DEPTH_AS_INPUT_ATTACHMENT_MSAA = "DEPTH_AS_INPUT_ATTACHMENT_MSAA"; + public const string DEPTH_AS_INPUT_ATTACHMENT_MSAA = "_DEPTH_AS_INPUT_ATTACHMENT_MSAA"; } public sealed partial class UniversalRenderPipeline diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl index f6343389367..413a772baf6 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl @@ -10,7 +10,7 @@ float4 _CameraDepthTexture_TexelSize; #define sampler_CameraDepthTexture sampler_PointClamp // Framebuffer fetch API for depth input attachment -#if defined(DEPTH_AS_INPUT_ATTACHMENT) +#if defined(_DEPTH_AS_INPUT_ATTACHMENT) FRAMEBUFFER_INPUT_X_FLOAT(0); float FetchSceneDepth(float2 fragCoord) @@ -18,7 +18,7 @@ float4 _CameraDepthTexture_TexelSize; float depth = LOAD_FRAMEBUFFER_INPUT_X(0, fragCoord).r; return depth; } -#elif defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) +#elif defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA) FRAMEBUFFER_INPUT_X_FLOAT_MS(0); float FetchSceneDepth(float2 fragCoord, int sampleIndx) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl index bfe78fe13d4..2eb83b3c1f9 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl @@ -35,7 +35,7 @@ float shadergraph_LWSampleSceneDepth(float2 uv) #endif } -#if defined(DEPTH_AS_INPUT_ATTACHMENT) +#if defined(_DEPTH_AS_INPUT_ATTACHMENT) float shadergraph_LWFetchSceneDepth(float2 fragCoord) { #if defined(REQUIRE_DEPTH_TEXTURE) @@ -44,7 +44,7 @@ float shadergraph_LWSampleSceneDepth(float2 uv) return 0; #endif } -#elif defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) +#elif defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA) float shadergraph_LWFetchSceneDepth(float2 fragCoord) { #if defined(REQUIRE_DEPTH_TEXTURE) diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader index d59cd96b570..a4227cfba25 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/365_RenderObject_DepthInputAttachment/CustomFetchDepth.shader @@ -20,7 +20,7 @@ Shader "CustomFetchDepth" #pragma vertex Vert #pragma fragment FragDepthVisualization #pragma target 4.5 - #pragma multi_compile _ DEPTH_AS_INPUT_ATTACHMENT DEPTH_AS_INPUT_ATTACHMENT_MSAA + #pragma multi_compile _ _DEPTH_AS_INPUT_ATTACHMENT _DEPTH_AS_INPUT_ATTACHMENT_MSAA #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" @@ -47,7 +47,7 @@ Shader "CustomFetchDepth" return output; } -#if defined(DEPTH_AS_INPUT_ATTACHMENT) +#if defined(_DEPTH_AS_INPUT_ATTACHMENT) float4 FragDepthVisualization(Varyings input) : SV_Target0 { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); @@ -55,7 +55,7 @@ Shader "CustomFetchDepth" float depth = FetchSceneDepth(input.positionCS.xy); return float4(depth, 0.0f, 0.0f, 1.0); } -#elif defined(DEPTH_AS_INPUT_ATTACHMENT_MSAA) +#elif defined(_DEPTH_AS_INPUT_ATTACHMENT_MSAA) float4 FragDepthVisualization(Varyings input) : SV_Target0 { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); From 2a2410babf1ddd917d57330e616743346c04edf7 Mon Sep 17 00:00:00 2001 From: Cal Chiu Date: Wed, 15 Apr 2026 11:48:11 +0000 Subject: [PATCH 84/88] [UUM-109492] Fixed UberPostProcess pass viewport scaling not accounting for subsequent custom pass presence --- .../Passes/PostProcess/UberPostProcessPass.cs | 10 +++++----- .../Runtime/PostProcessUtils.cs | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs index e72a80a6801..93303c995c4 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UberPostProcessPass.cs @@ -87,7 +87,7 @@ private class UberPostPassData internal FilmGrainParams filmGrain; internal DitheringParams dither; - internal bool isFinalPass; + internal bool isActiveTargetBackBuffer; internal bool useFastSRGBLinearConversion; internal bool requireSRGBConversionBlit; } @@ -194,7 +194,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.filmGrain.Setup(filmGrain, m_FilmGrainTextures, cameraData.pixelWidth, cameraData.pixelHeight); passData.dither.Setup(m_DitherTexture, cameraData.pixelWidth, cameraData.pixelHeight); } - passData.isFinalPass = m_IsFinalPass; + passData.isActiveTargetBackBuffer = resourceData.isActiveTargetBackBuffer; builder.SetRenderFunc(static (UberPostPassData data, RasterGraphContext context) => { @@ -260,7 +260,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer if(PostProcessUtils.RequireHDROutput(cameraData)) { PostProcessUtils.SetupHDROutput(material, cameraData.hdrDisplayInformation, cameraData.hdrDisplayColorGamut, data.tonemapping, data.hdrOperations, cameraData.rendersOverlayUI); - RenderingUtils.SetupOffscreenUIViewportParams(material, ref cameraData.pixelRect, data.isFinalPass && cameraData.resolveFinalTarget); + RenderingUtils.SetupOffscreenUIViewportParams(material, ref cameraData.pixelRect, data.isActiveTargetBackBuffer); } #if ENABLE_VR && ENABLE_XR_MODULE @@ -272,10 +272,10 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // Done with Uber, blit it if (cameraData.xr.enabled && cameraData.xr.hasValidVisibleMesh) - PostProcessUtils.ScaleViewportAndDrawVisibilityMesh(context, data.sourceTexture, data.destinationTexture, data.cameraData, material, data.isFinalPass); + PostProcessUtils.ScaleViewportAndDrawVisibilityMesh(context, data.sourceTexture, data.destinationTexture, data.cameraData, material, data.isActiveTargetBackBuffer); else #endif - PostProcessUtils.ScaleViewportAndBlit(context, data.sourceTexture, data.destinationTexture, data.cameraData, material, data.isFinalPass); + PostProcessUtils.ScaleViewportAndBlit(context, data.sourceTexture, data.destinationTexture, data.cameraData, material, data.isActiveTargetBackBuffer); }); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs index 22d84e6c07e..1f9aa2e2fb1 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs @@ -350,7 +350,7 @@ internal static void SetGlobalShaderSourceSize(CommandBuffer cmd, RTHandle sourc SetGlobalShaderSourceSize(CommandBufferHelpers.GetRasterCommandBuffer(cmd), source); } - internal static void ScaleViewport(RasterCommandBuffer cmd, RTHandle dest, UniversalCameraData cameraData, bool isFinalPass) + internal static void ScaleViewport(RasterCommandBuffer cmd, RTHandle dest, UniversalCameraData cameraData, bool isActiveTargetBackBuffer) { RenderTargetIdentifier cameraTarget = BuiltinRenderTextureType.CameraTarget; #if ENABLE_VR && ENABLE_XR_MODULE @@ -359,7 +359,7 @@ internal static void ScaleViewport(RasterCommandBuffer cmd, RTHandle dest, Unive #endif if (dest.nameID == cameraTarget || cameraData.targetTexture != null) { - if (!isFinalPass || !cameraData.resolveFinalTarget) + if (!isActiveTargetBackBuffer) { // Inside the camera stack the target is the shared intermediate target, which can be scaled with render scale. // camera.pixelRect is the viewport of the final target in pixels, so it cannot be used for the intermediate target. @@ -383,19 +383,19 @@ internal static void ScaleViewport(RasterCommandBuffer cmd, RTHandle dest, Unive } } - internal static void ScaleViewportAndBlit(RasterGraphContext context, in TextureHandle sourceTexture, in TextureHandle destTexture, UniversalCameraData cameraData, Material material, bool isFinalPass) + internal static void ScaleViewportAndBlit(RasterGraphContext context, in TextureHandle sourceTexture, in TextureHandle destTexture, UniversalCameraData cameraData, Material material, bool isActiveTargetBackBuffer) { Vector4 scaleBias = RenderingUtils.GetFinalBlitScaleBias(context, sourceTexture, destTexture); - ScaleViewport(context.cmd, destTexture, cameraData, isFinalPass); + ScaleViewport(context.cmd, destTexture, cameraData, isActiveTargetBackBuffer); Blitter.BlitTexture(context.cmd, sourceTexture, scaleBias, material, 0); } - internal static void ScaleViewportAndDrawVisibilityMesh(RasterGraphContext context, in TextureHandle sourceTexture, in TextureHandle destTexture, UniversalCameraData cameraData, Material material, bool isFinalPass) + internal static void ScaleViewportAndDrawVisibilityMesh(RasterGraphContext context, in TextureHandle sourceTexture, in TextureHandle destTexture, UniversalCameraData cameraData, Material material, bool isActiveTargetBackBuffer) { #if ENABLE_VR && ENABLE_XR_MODULE Vector4 scaleBias = RenderingUtils.GetFinalBlitScaleBias(context, sourceTexture, destTexture); - ScaleViewport(context.cmd, destTexture, cameraData, isFinalPass); + ScaleViewport(context.cmd, destTexture, cameraData, isActiveTargetBackBuffer); // Set property block for blit shader MaterialPropertyBlock xrPropertyBlock = XRSystemUniversal.GetMaterialPropertyBlock(); From 37966021ba531dcb6c5a0afdf298d5044ee901c1 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Wed, 15 Apr 2026 11:48:14 +0000 Subject: [PATCH 85/88] Updated `CloudLayer`, `CloudLayerRenderer`, and `CloudSettings` to work with CoreCLR --- .../Sky/CloudSystem/CloudLayer/CloudLayer.cs | 10 ++ .../CloudLayer/CloudLayerRenderer.cs | 156 ++++++++++++------ .../Runtime/Sky/CloudSystem/CloudSettings.cs | 20 ++- 3 files changed, 130 insertions(+), 56 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayer.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayer.cs index 78353e66ec1..06d0422e419 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayer.cs @@ -263,6 +263,14 @@ public override int GetHashCode() return hash; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_DefaultTexture = null; + } +#endif } /// Layer A. @@ -337,6 +345,8 @@ public override int GetHashCode() /// static void Init() { + CloudMap.s_DefaultTexture = null; + if (GraphicsSettings.TryGetRenderPipelineSettings(out var runtimeTextures)) { CloudMap.s_DefaultTexture = runtimeTextures.defaultCloudMap; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayerRenderer.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayerRenderer.cs index 85b275aea4f..99f25b2fb35 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayerRenderer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudLayer/CloudLayerRenderer.cs @@ -13,14 +13,14 @@ class CloudLayerRenderer : CloudRenderer private float lastTime = 0.0f; int m_LastPrecomputationParamHash; + ComputeShader m_BakeCloudTextureCS, m_BakeCloudShadowsCS; + int m_BakeCloudTextureKernel, m_BakeCloudShadowsKernel; static readonly int _CloudTexture = Shader.PropertyToID("_CloudTexture"); static readonly int _CloudShadows = Shader.PropertyToID("_CloudShadows"); static readonly int _FlowmapA = Shader.PropertyToID("_FlowmapA"), _FlowmapB = Shader.PropertyToID("_FlowmapB"); static readonly int _CloudMapA = Shader.PropertyToID("_CloudMapA"), _CloudMapB = Shader.PropertyToID("_CloudMapB"); static readonly int _AmbientProbeBuffer = Shader.PropertyToID("_AmbientProbeBuffer"); - static ComputeShader s_BakeCloudTextureCS, s_BakeCloudShadowsCS; - static int s_BakeCloudTextureKernel, s_BakeCloudShadowsKernel; static readonly Vector4[] s_VectorArray = new Vector4[2]; public RTHandle cloudTexture { get { return m_PrecomputedData.cloudTextureRT; } } @@ -38,20 +38,23 @@ public override void Build() m_CloudLayerMaterial = CoreUtils.CreateEngineMaterial(shaders.cloudLayerPS); - s_BakeCloudTextureCS = shaders.bakeCloudTextureCS; - s_BakeCloudTextureKernel = s_BakeCloudTextureCS.FindKernel("BakeCloudTexture"); + m_BakeCloudTextureCS = shaders.bakeCloudTextureCS; + m_BakeCloudTextureKernel = m_BakeCloudTextureCS.FindKernel("BakeCloudTexture"); - s_BakeCloudShadowsCS = shaders.bakeCloudShadowsCS; - s_BakeCloudShadowsKernel = s_BakeCloudShadowsCS.FindKernel("BakeCloudShadows"); + m_BakeCloudShadowsCS = shaders.bakeCloudShadowsCS; + m_BakeCloudShadowsKernel = m_BakeCloudShadowsCS.FindKernel("BakeCloudShadows"); } public override void Cleanup() { CoreUtils.Destroy(m_CloudLayerMaterial); + m_BakeCloudTextureCS = null; + m_BakeCloudShadowsCS = null; + if (m_PrecomputedData != null) { - s_PrecomputationCache.Release(m_LastPrecomputationParamHash); + PrecomputationCacheInstance.Release(m_LastPrecomputationParamHash); m_LastPrecomputationParamHash = 0; m_PrecomputedData = null; } @@ -62,8 +65,8 @@ bool UpdateCache(CloudLayer cloudLayer, Light sunLight) int currPrecomputationParamHash = cloudLayer.GetBakingHashCode(sunLight); if (currPrecomputationParamHash != m_LastPrecomputationParamHash) { - s_PrecomputationCache.Release(m_LastPrecomputationParamHash); - m_PrecomputedData = s_PrecomputationCache.Get(cloudLayer, currPrecomputationParamHash); + PrecomputationCacheInstance.Release(m_LastPrecomputationParamHash); + m_PrecomputedData = PrecomputationCacheInstance.Get(cloudLayer, currPrecomputationParamHash); m_LastPrecomputationParamHash = currPrecomputationParamHash; return true; } @@ -89,7 +92,7 @@ public override bool GetSunLightCookieParameters(CloudSettings settings, ref Coo } public override void RenderSunLightCookie(BuiltinSunCookieParameters builtinParams) - => m_PrecomputedData.BakeCloudShadows((CloudLayer)builtinParams.cloudSettings, builtinParams.sunLight, builtinParams.hdCamera, builtinParams.commandBuffer); + => m_PrecomputedData.BakeCloudShadows(this, (CloudLayer)builtinParams.cloudSettings, builtinParams.sunLight, builtinParams.hdCamera, builtinParams.commandBuffer); public override void RenderClouds(BuiltinSkyParameters builtinParams, bool renderForCubemap) { @@ -108,7 +111,7 @@ public override void RenderClouds(BuiltinSkyParameters builtinParams, bool rende if (!hdCamera.animateMaterials) cloudLayer.layerA.scrollFactor = cloudLayer.layerB.scrollFactor = 0.0f; - m_PrecomputedData.InitIfNeeded(cloudLayer, builtinParams.sunLight, hdCamera, builtinParams.commandBuffer); + m_PrecomputedData.InitIfNeeded(this, cloudLayer, builtinParams.sunLight, hdCamera, builtinParams.commandBuffer); m_CloudLayerMaterial.SetTexture(_CloudTexture, m_PrecomputedData.cloudTextureRT); // Parameters @@ -252,6 +255,18 @@ public void Release(int hash) } } } + + public void Clear() + { + foreach (var refCountData in m_CachedData.Values) + { + refCountData.refCount = 0; + refCountData.data.Release(); + m_DataPool.Release(refCountData); + } + + m_CachedData.Clear(); + } } class PrecomputationData @@ -280,10 +295,31 @@ public void Cache(int textureWidth, int textureHeight, RTHandle texture) height = textureHeight; rt = texture; } + + public void Clear() + { + width = 0; + height = 0; + + if (rt != null) + { + RTHandles.Release(rt); + rt = null; + } + } } - static TextureCache cloudTextureCache; - static TextureCache cloudShadowsCache; + static TextureCache s_CloudTextureCache; + static TextureCache s_CloudShadowsCache; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_CloudTextureCache.Clear(); + s_CloudShadowsCache.Clear(); + } +#endif bool initialized = false; int cloudTextureWidth, cloudTextureHeight, cloudShadowsResolution; public RTHandle cloudTextureRT = null; @@ -294,14 +330,14 @@ public void Allocate(CloudLayer cloudLayer) initialized = false; cloudTextureWidth = (int)cloudLayer.resolution.value; cloudTextureHeight = cloudLayer.upperHemisphereOnly.value ? cloudTextureWidth / 2 : cloudTextureWidth; - if (!cloudTextureCache.TryGet(cloudTextureWidth, cloudTextureHeight, ref cloudTextureRT)) + if (!s_CloudTextureCache.TryGet(cloudTextureWidth, cloudTextureHeight, ref cloudTextureRT)) cloudTextureRT = RTHandles.Alloc(cloudTextureWidth, cloudTextureHeight, TextureWrapMode.Repeat, TextureWrapMode.Clamp, slices: cloudLayer.NumLayers, colorFormat: GraphicsFormat.R16G16_SFloat, dimension: TextureDimension.Tex2DArray, enableRandomWrite: true, useMipMap: false, filterMode: FilterMode.Bilinear, name: "Cloud Texture"); cloudShadowsRT = null; cloudShadowsResolution = (int)cloudLayer.shadowResolution.value; - if (cloudLayer.CastShadows && !cloudShadowsCache.TryGet(cloudShadowsResolution, cloudShadowsResolution, ref cloudShadowsRT)) + if (cloudLayer.CastShadows && !s_CloudShadowsCache.TryGet(cloudShadowsResolution, cloudShadowsResolution, ref cloudShadowsRT)) cloudShadowsRT = RTHandles.Alloc(cloudShadowsResolution, cloudShadowsResolution, colorFormat: GraphicsFormat.B10G11R11_UFloatPack32, dimension: TextureDimension.Tex2D, enableRandomWrite: true, useMipMap: false, filterMode: FilterMode.Bilinear, name: "Cloud Shadows"); @@ -309,66 +345,73 @@ public void Allocate(CloudLayer cloudLayer) public void Release() { - cloudTextureCache.Cache(cloudTextureHeight, cloudTextureHeight, cloudTextureRT); - cloudShadowsCache.Cache(cloudShadowsResolution, cloudShadowsResolution, cloudShadowsRT); + s_CloudTextureCache.Cache(cloudTextureHeight, cloudTextureHeight, cloudTextureRT); + s_CloudShadowsCache.Cache(cloudShadowsResolution, cloudShadowsResolution, cloudShadowsRT); } - public bool InitIfNeeded(CloudLayer cloudLayer, Light sunLight, HDCamera hdCamera, CommandBuffer cmd) + public bool InitIfNeeded(CloudLayerRenderer cloudLayerRenderer, CloudLayer cloudLayer, Light sunLight, HDCamera hdCamera, CommandBuffer cmd) { if (initialized) return false; + var bakeCloudTextureCS = cloudLayerRenderer.m_BakeCloudTextureCS; + var bakeCloudTextureKernel = cloudLayerRenderer.m_BakeCloudTextureKernel; + Vector4 params1 = sunLight == null ? Vector3.zero : -sunLight.transform.forward; params1.w = (cloudLayer.upperHemisphereOnly.value ? 1.0f : -1.0f) * hdCamera.planet.radius; - cmd.SetComputeVectorParam(s_BakeCloudTextureCS, HDShaderIDs._Params, params1); - cmd.SetComputeTextureParam(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, _CloudTexture, cloudTextureRT); + cmd.SetComputeVectorParam(bakeCloudTextureCS, HDShaderIDs._Params, params1); + cmd.SetComputeTextureParam(bakeCloudTextureCS, bakeCloudTextureKernel, _CloudTexture, cloudTextureRT); - cmd.SetComputeTextureParam(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, _CloudMapA, cloudLayer.layerA.cloudMap.value); + cmd.SetComputeTextureParam(bakeCloudTextureCS, bakeCloudTextureKernel, _CloudMapA, cloudLayer.layerA.cloudMap.value); var paramsA = cloudLayer.layerA.GetBakingParameters(); if (cloudLayer.NumLayers == 1) { - s_BakeCloudTextureCS.DisableKeyword("USE_SECOND_CLOUD_LAYER"); - cmd.SetComputeVectorParam(s_BakeCloudTextureCS, HDShaderIDs._Params1, paramsA.Item1); - cmd.SetComputeVectorParam(s_BakeCloudTextureCS, HDShaderIDs._Params2, paramsA.Item2); + bakeCloudTextureCS.DisableKeyword("USE_SECOND_CLOUD_LAYER"); + cmd.SetComputeVectorParam(bakeCloudTextureCS, HDShaderIDs._Params1, paramsA.Item1); + cmd.SetComputeVectorParam(bakeCloudTextureCS, HDShaderIDs._Params2, paramsA.Item2); } else { - cmd.SetComputeTextureParam(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, _CloudMapB, cloudLayer.layerB.cloudMap.value); + cmd.SetComputeTextureParam(bakeCloudTextureCS, bakeCloudTextureKernel, _CloudMapB, cloudLayer.layerB.cloudMap.value); var paramsB = cloudLayer.layerB.GetBakingParameters(); - s_BakeCloudTextureCS.EnableKeyword("USE_SECOND_CLOUD_LAYER"); + bakeCloudTextureCS.EnableKeyword("USE_SECOND_CLOUD_LAYER"); s_VectorArray[0] = paramsA.Item1; s_VectorArray[1] = paramsB.Item1; - cmd.SetComputeVectorArrayParam(s_BakeCloudTextureCS, HDShaderIDs._Params1, s_VectorArray); + cmd.SetComputeVectorArrayParam(bakeCloudTextureCS, HDShaderIDs._Params1, s_VectorArray); s_VectorArray[0] = paramsA.Item2; s_VectorArray[1] = paramsB.Item2; - cmd.SetComputeVectorArrayParam(s_BakeCloudTextureCS, HDShaderIDs._Params2, s_VectorArray); + cmd.SetComputeVectorArrayParam(bakeCloudTextureCS, HDShaderIDs._Params2, s_VectorArray); } - cmd.SetComputeFloatParam(s_BakeCloudTextureCS, HDShaderIDs._Resolution, 1.0f / cloudTextureWidth); + cmd.SetComputeFloatParam(bakeCloudTextureCS, HDShaderIDs._Resolution, 1.0f / cloudTextureWidth); const int groupSizeX = 8; const int groupSizeY = 8; int threadGroupX = (cloudTextureWidth + (groupSizeX - 1)) / groupSizeX; int threadGroupY = (cloudTextureHeight + (groupSizeY - 1)) / groupSizeY; - cmd.DispatchCompute(s_BakeCloudTextureCS, s_BakeCloudTextureKernel, threadGroupX, threadGroupY, 1); + cmd.DispatchCompute(bakeCloudTextureCS, bakeCloudTextureKernel, threadGroupX, threadGroupY, 1); initialized = true; return true; } - public void BakeCloudShadows(CloudLayer cloudLayer, Light sunLight, HDCamera hdCamera, CommandBuffer cmd) + public void BakeCloudShadows(CloudLayerRenderer cloudLayerRenderer, CloudLayer cloudLayer, Light sunLight, HDCamera hdCamera, CommandBuffer cmd) { - InitIfNeeded(cloudLayer, sunLight, hdCamera, cmd); + InitIfNeeded(cloudLayerRenderer, cloudLayer, sunLight, hdCamera, cmd); + + var bakeCloudShadowsCS = cloudLayerRenderer.m_BakeCloudShadowsCS; + var bakeCloudShadowsKernel = cloudLayerRenderer.m_BakeCloudShadowsKernel; + Vector4 _Params = cloudLayer.shadowTint.value; _Params.w = cloudLayer.shadowMultiplier.value * 8.0f; // Parameters - cmd.SetComputeFloatParam(s_BakeCloudShadowsCS, HDShaderIDs._Resolution, 1.0f / cloudShadowsResolution); - cmd.SetComputeVectorParam(s_BakeCloudShadowsCS, HDShaderIDs._Params, _Params); + cmd.SetComputeFloatParam(bakeCloudShadowsCS, HDShaderIDs._Resolution, 1.0f / cloudShadowsResolution); + cmd.SetComputeVectorParam(bakeCloudShadowsCS, HDShaderIDs._Params, _Params); - cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _CloudTexture, cloudTextureRT); - cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _CloudShadows, cloudShadowsRT); + cmd.SetComputeTextureParam(bakeCloudShadowsCS, bakeCloudShadowsKernel, _CloudTexture, cloudTextureRT); + cmd.SetComputeTextureParam(bakeCloudShadowsCS, bakeCloudShadowsKernel, _CloudShadows, cloudShadowsRT); var _FlowmapParamA = cloudLayer.layerA.GetRenderingParameters(hdCamera); var _FlowmapParamB = cloudLayer.layerB.GetRenderingParameters(hdCamera); @@ -376,31 +419,31 @@ public void BakeCloudShadows(CloudLayer cloudLayer, Light sunLight, HDCamera hdC _FlowmapParamB.w = cloudLayer.opacity.value; s_VectorArray[0] = _FlowmapParamA; s_VectorArray[1] = _FlowmapParamB; - cmd.SetComputeVectorArrayParam(s_BakeCloudShadowsCS, HDShaderIDs._FlowmapParam, s_VectorArray); + cmd.SetComputeVectorArrayParam(bakeCloudShadowsCS, HDShaderIDs._FlowmapParam, s_VectorArray); s_VectorArray[0] = sunLight.transform.right; s_VectorArray[1] = sunLight.transform.up; s_VectorArray[0].w = cloudLayer.layerA.altitude.value; s_VectorArray[1].w = cloudLayer.layerB.altitude.value; - cmd.SetComputeVectorArrayParam(s_BakeCloudShadowsCS, HDShaderIDs._Params1, s_VectorArray); + cmd.SetComputeVectorArrayParam(bakeCloudShadowsCS, HDShaderIDs._Params1, s_VectorArray); - cmd.SetComputeVectorParam(s_BakeCloudShadowsCS, HDShaderIDs._SunDirection, -sunLight.transform.forward); + cmd.SetComputeVectorParam(bakeCloudShadowsCS, HDShaderIDs._SunDirection, -sunLight.transform.forward); - cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _FlowmapA, cloudLayer.layerA.flowmap.value); - cmd.SetComputeTextureParam(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, _FlowmapB, cloudLayer.layerB.flowmap.value); + cmd.SetComputeTextureParam(bakeCloudShadowsCS, bakeCloudShadowsKernel, _FlowmapA, cloudLayer.layerA.flowmap.value); + cmd.SetComputeTextureParam(bakeCloudShadowsCS, bakeCloudShadowsKernel, _FlowmapB, cloudLayer.layerB.flowmap.value); // Keywords bool enabled1 = cloudLayer.layerA.castShadows.value; var mode1 = cloudLayer.layerA.distortionMode.value; - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER1_OFF", !enabled1); - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER1_STATIC", enabled1 && mode1 == CloudDistortionMode.None); - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER1_PROCEDURAL", enabled1 && mode1 == CloudDistortionMode.Procedural); - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER1_FLOWMAP", enabled1 && mode1 == CloudDistortionMode.Flowmap); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER1_OFF", !enabled1); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER1_STATIC", enabled1 && mode1 == CloudDistortionMode.None); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER1_PROCEDURAL", enabled1 && mode1 == CloudDistortionMode.Procedural); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER1_FLOWMAP", enabled1 && mode1 == CloudDistortionMode.Flowmap); bool enabled2 = (cloudLayer.layers.value == CloudMapMode.Double) && cloudLayer.layerB.castShadows.value; var mode2 = cloudLayer.layerB.distortionMode.value; - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER2_OFF", !enabled2); - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER2_STATIC", enabled2 && mode2 == CloudDistortionMode.None); - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER2_PROCEDURAL", enabled2 && mode2 == CloudDistortionMode.Procedural); - CoreUtils.SetKeyword(s_BakeCloudShadowsCS, "LAYER2_FLOWMAP", enabled2 && mode2 == CloudDistortionMode.Flowmap); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER2_OFF", !enabled2); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER2_STATIC", enabled2 && mode2 == CloudDistortionMode.None); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER2_PROCEDURAL", enabled2 && mode2 == CloudDistortionMode.Procedural); + CoreUtils.SetKeyword(bakeCloudShadowsCS, "LAYER2_FLOWMAP", enabled2 && mode2 == CloudDistortionMode.Flowmap); // Dispatch const int groupSizeX = 8; @@ -408,12 +451,23 @@ public void BakeCloudShadows(CloudLayer cloudLayer, Light sunLight, HDCamera hdC int threadGroupX = (cloudShadowsResolution + (groupSizeX - 1)) / groupSizeX; int threadGroupY = (cloudShadowsResolution + (groupSizeY - 1)) / groupSizeY; - cmd.DispatchCompute(s_BakeCloudShadowsCS, s_BakeCloudShadowsKernel, threadGroupX, threadGroupY, 1); + cmd.DispatchCompute(bakeCloudShadowsCS, bakeCloudShadowsKernel, threadGroupX, threadGroupY, 1); cloudShadowsRT.rt.IncrementUpdateCount(); } } - static PrecomputationCache s_PrecomputationCache = new PrecomputationCache(); + static PrecomputationCache s_PrecomputationCache = null; + static PrecomputationCache PrecomputationCacheInstance => s_PrecomputationCache ??= new PrecomputationCache(); + PrecomputationData m_PrecomputedData; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_PrecomputationCache?.Clear(); + s_PrecomputationCache = null; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudSettings.cs index f02321bd609..48bb621c23e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudSystem/CloudSettings.cs @@ -28,14 +28,14 @@ public CloudUniqueID(int uniqueID) /// public abstract class CloudSettings : VolumeComponent { - static Dictionary cloudUniqueIDs = new Dictionary(); + static Dictionary s_CloudUniqueIDs = null; /// /// Returns the hash code of the cloud parameters. /// /// The camera we want to use to compute the hash of the cloud. /// The hash code of the cloud parameters. - virtual public int GetHashCode(Camera camera) + public virtual int GetHashCode(Camera camera) { // By default we don't need to consider the camera position. return GetHashCode(); @@ -60,13 +60,14 @@ public static int GetUniqueID() /// The unique ID for the requested cloud type. public static int GetUniqueID(Type type) { - int uniqueID; + s_CloudUniqueIDs ??= new Dictionary(); - if (!cloudUniqueIDs.TryGetValue(type, out uniqueID)) + int uniqueID; + if (!s_CloudUniqueIDs.TryGetValue(type, out uniqueID)) { var uniqueIDs = type.GetCustomAttributes(typeof(CloudUniqueID), false); uniqueID = (uniqueIDs.Length == 0) ? -1 : ((CloudUniqueID)uniqueIDs[0]).uniqueID; - cloudUniqueIDs[type] = uniqueID; + s_CloudUniqueIDs[type] = uniqueID; } return uniqueID; @@ -77,5 +78,14 @@ public static int GetUniqueID(Type type) /// /// The class type of the CloudRenderer associated with this Cloud Settings. public abstract Type GetCloudRendererType(); + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + static void ResetStaticsOnLoad() + { + s_CloudUniqueIDs?.Clear(); + s_CloudUniqueIDs = null; + } +#endif } } From 74761666dd1a7d1f5c869b152480c37e3ee2b5b0 Mon Sep 17 00:00:00 2001 From: Arttu Peltonen Date: Wed, 15 Apr 2026 20:41:32 +0000 Subject: [PATCH 86/88] Change URP ShaderGlobalKeywords to readonly and use static initialization --- .../Runtime/UniversalRenderPipelineCore.cs | 330 +++++++----------- 1 file changed, 121 insertions(+), 209 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 0acede52388..8cf4019f41c 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -64,7 +64,7 @@ internal enum ImageScalingMode /// /// Enumeration that indicates what kind of upscaling filter is being used /// - /// + /// #if ENABLE_UPSCALER_FRAMEWORK [Obsolete("ImageUpscalingFilter is no longer used #from(6000.3)")] #endif @@ -905,222 +905,134 @@ internal PostProcessingData(ContextContainer frameData) internal static class ShaderGlobalKeywords { - public static GlobalKeyword MainLightShadows; - public static GlobalKeyword MainLightShadowCascades; - public static GlobalKeyword MainLightShadowScreen; - public static GlobalKeyword CastingPunctualLightShadow; - public static GlobalKeyword AdditionalLightsVertex; - public static GlobalKeyword AdditionalLightsPixel; - public static GlobalKeyword ClusterLightLoop; - public static GlobalKeyword AdditionalLightShadows; - public static GlobalKeyword ReflectionProbeBoxProjection; - public static GlobalKeyword ReflectionProbeBlending; - public static GlobalKeyword ReflectionProbeAtlas; - public static GlobalKeyword ReflectionProbeRotation; - public static GlobalKeyword ScreenSpaceReflection; - public static GlobalKeyword SoftShadows; - public static GlobalKeyword SoftShadowsLow; - public static GlobalKeyword SoftShadowsMedium; - public static GlobalKeyword SoftShadowsHigh; - public static GlobalKeyword MixedLightingSubtractive; // Backward compatibility - public static GlobalKeyword LightmapShadowMixing; - public static GlobalKeyword ShadowsShadowMask; - public static GlobalKeyword LightLayers; - public static GlobalKeyword RenderPassEnabled; - public static GlobalKeyword BillboardFaceCameraPos; - public static GlobalKeyword LightCookies; - public static GlobalKeyword DepthNoMsaa; - public static GlobalKeyword DepthMsaa2; - public static GlobalKeyword DepthMsaa4; - public static GlobalKeyword DepthMsaa8; - public static GlobalKeyword DBufferMRT1; - public static GlobalKeyword DBufferMRT2; - public static GlobalKeyword DBufferMRT3; - public static GlobalKeyword DecalNormalBlendLow; - public static GlobalKeyword DecalNormalBlendMedium; - public static GlobalKeyword DecalNormalBlendHigh; - public static GlobalKeyword DecalLayers; - public static GlobalKeyword WriteRenderingLayers; - public static GlobalKeyword WriteSmoothness; - public static GlobalKeyword ScreenSpaceOcclusion; - public static GlobalKeyword ScreenSpaceIrradiance; - public static GlobalKeyword _SPOT; - public static GlobalKeyword _DIRECTIONAL; - public static GlobalKeyword _POINT; - public static GlobalKeyword _DEFERRED_STENCIL; - public static GlobalKeyword _DEFERRED_FIRST_LIGHT; - public static GlobalKeyword _DEFERRED_MAIN_LIGHT; - public static GlobalKeyword _GBUFFER_NORMALS_OCT; - public static GlobalKeyword _DEFERRED_MIXED_LIGHTING; - public static GlobalKeyword LIGHTMAP_ON; - public static GlobalKeyword DYNAMICLIGHTMAP_ON; - public static GlobalKeyword _ALPHATEST_ON; - public static GlobalKeyword DIRLIGHTMAP_COMBINED; - public static GlobalKeyword _DETAIL_MULX2; - public static GlobalKeyword _DETAIL_SCALED; - public static GlobalKeyword _CLEARCOAT; - public static GlobalKeyword _CLEARCOATMAP; - public static GlobalKeyword DEBUG_DISPLAY; - public static GlobalKeyword LOD_FADE_CROSSFADE; - public static GlobalKeyword USE_UNITY_CROSSFADE; - public static GlobalKeyword _EMISSION; - public static GlobalKeyword _RECEIVE_SHADOWS_OFF; - public static GlobalKeyword _SURFACE_TYPE_TRANSPARENT; - public static GlobalKeyword _ALPHAPREMULTIPLY_ON; - public static GlobalKeyword _ALPHAMODULATE_ON; - public static GlobalKeyword _NORMALMAP; - public static GlobalKeyword _ADD_PRECOMPUTED_VELOCITY; - public static GlobalKeyword EDITOR_VISUALIZATION; - public static GlobalKeyword FoveatedRenderingNonUniformRaster; - public static GlobalKeyword DisableTexture2DXArray; - public static GlobalKeyword BlitSingleSlice; - public static GlobalKeyword XROcclusionMeshCombined; - public static GlobalKeyword SCREEN_COORD_OVERRIDE; - public static GlobalKeyword DOWNSAMPLING_SIZE_2; - public static GlobalKeyword DOWNSAMPLING_SIZE_4; - public static GlobalKeyword DOWNSAMPLING_SIZE_8; - public static GlobalKeyword DOWNSAMPLING_SIZE_16; - public static GlobalKeyword EVALUATE_SH_MIXED; - public static GlobalKeyword EVALUATE_SH_VERTEX; - public static GlobalKeyword ProbeVolumeL1; - public static GlobalKeyword ProbeVolumeL2; - public static GlobalKeyword LIGHTMAP_BICUBIC_SAMPLING; - public static GlobalKeyword _OUTPUT_DEPTH; - public static GlobalKeyword LinearToSRGBConversion; - public static GlobalKeyword _ENABLE_ALPHA_OUTPUT; - public static GlobalKeyword ForwardPlus; // Backward compatibility. Deprecated in 6.1. + public static readonly GlobalKeyword MainLightShadows = GlobalKeyword.Create(ShaderKeywordStrings.MainLightShadows); + public static readonly GlobalKeyword MainLightShadowCascades = GlobalKeyword.Create(ShaderKeywordStrings.MainLightShadowCascades); + public static readonly GlobalKeyword MainLightShadowScreen = GlobalKeyword.Create(ShaderKeywordStrings.MainLightShadowScreen); + public static readonly GlobalKeyword CastingPunctualLightShadow = GlobalKeyword.Create(ShaderKeywordStrings.CastingPunctualLightShadow); + public static readonly GlobalKeyword AdditionalLightsVertex = GlobalKeyword.Create(ShaderKeywordStrings.AdditionalLightsVertex); + public static readonly GlobalKeyword AdditionalLightsPixel = GlobalKeyword.Create(ShaderKeywordStrings.AdditionalLightsPixel); + public static readonly GlobalKeyword ClusterLightLoop = GlobalKeyword.Create(ShaderKeywordStrings.ClusterLightLoop); + public static readonly GlobalKeyword AdditionalLightShadows = GlobalKeyword.Create(ShaderKeywordStrings.AdditionalLightShadows); + public static readonly GlobalKeyword ReflectionProbeBoxProjection = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeBoxProjection); + public static readonly GlobalKeyword ReflectionProbeBlending = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeBlending); + public static readonly GlobalKeyword ReflectionProbeAtlas = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeAtlas); + public static readonly GlobalKeyword ReflectionProbeRotation = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeRotation); + public static readonly GlobalKeyword ScreenSpaceReflection = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceReflection); + public static readonly GlobalKeyword SoftShadows = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadows); + public static readonly GlobalKeyword SoftShadowsLow = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsLow); + public static readonly GlobalKeyword SoftShadowsMedium = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsMedium); + public static readonly GlobalKeyword SoftShadowsHigh = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsHigh); + public static readonly GlobalKeyword MixedLightingSubtractive = GlobalKeyword.Create(ShaderKeywordStrings.MixedLightingSubtractive); // Backward compatibility + public static readonly GlobalKeyword LightmapShadowMixing = GlobalKeyword.Create(ShaderKeywordStrings.LightmapShadowMixing); + public static readonly GlobalKeyword ShadowsShadowMask = GlobalKeyword.Create(ShaderKeywordStrings.ShadowsShadowMask); + public static readonly GlobalKeyword LightLayers = GlobalKeyword.Create(ShaderKeywordStrings.LightLayers); + public static readonly GlobalKeyword RenderPassEnabled = GlobalKeyword.Create(ShaderKeywordStrings.RenderPassEnabled); + public static readonly GlobalKeyword BillboardFaceCameraPos = GlobalKeyword.Create(ShaderKeywordStrings.BillboardFaceCameraPos); + public static readonly GlobalKeyword LightCookies = GlobalKeyword.Create(ShaderKeywordStrings.LightCookies); + public static readonly GlobalKeyword DepthNoMsaa = GlobalKeyword.Create(ShaderKeywordStrings.DepthNoMsaa); + public static readonly GlobalKeyword DepthMsaa2 = GlobalKeyword.Create(ShaderKeywordStrings.DepthMsaa2); + public static readonly GlobalKeyword DepthMsaa4 = GlobalKeyword.Create(ShaderKeywordStrings.DepthMsaa4); + public static readonly GlobalKeyword DepthMsaa8 = GlobalKeyword.Create(ShaderKeywordStrings.DepthMsaa8); + public static readonly GlobalKeyword DBufferMRT1 = GlobalKeyword.Create(ShaderKeywordStrings.DBufferMRT1); + public static readonly GlobalKeyword DBufferMRT2 = GlobalKeyword.Create(ShaderKeywordStrings.DBufferMRT2); + public static readonly GlobalKeyword DBufferMRT3 = GlobalKeyword.Create(ShaderKeywordStrings.DBufferMRT3); + public static readonly GlobalKeyword DecalNormalBlendLow = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendLow); + public static readonly GlobalKeyword DecalNormalBlendMedium = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendMedium); + public static readonly GlobalKeyword DecalNormalBlendHigh = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendHigh); + public static readonly GlobalKeyword DecalLayers = GlobalKeyword.Create(ShaderKeywordStrings.DecalLayers); + public static readonly GlobalKeyword WriteRenderingLayers = GlobalKeyword.Create(ShaderKeywordStrings.WriteRenderingLayers); + public static readonly GlobalKeyword WriteSmoothness = GlobalKeyword.Create(ShaderKeywordStrings.WriteSmoothness); + public static readonly GlobalKeyword ScreenSpaceOcclusion = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceOcclusion); + public static readonly GlobalKeyword ScreenSpaceIrradiance = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceIrradiance); + public static readonly GlobalKeyword _SPOT = GlobalKeyword.Create(ShaderKeywordStrings._SPOT); + public static readonly GlobalKeyword _DIRECTIONAL = GlobalKeyword.Create(ShaderKeywordStrings._DIRECTIONAL); + public static readonly GlobalKeyword _POINT = GlobalKeyword.Create(ShaderKeywordStrings._POINT); + public static readonly GlobalKeyword _DEFERRED_STENCIL = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_STENCIL); + public static readonly GlobalKeyword _DEFERRED_FIRST_LIGHT = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_FIRST_LIGHT); + public static readonly GlobalKeyword _DEFERRED_MAIN_LIGHT = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_MAIN_LIGHT); + public static readonly GlobalKeyword _GBUFFER_NORMALS_OCT = GlobalKeyword.Create(ShaderKeywordStrings._GBUFFER_NORMALS_OCT); + public static readonly GlobalKeyword _DEFERRED_MIXED_LIGHTING = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_MIXED_LIGHTING); + public static readonly GlobalKeyword LIGHTMAP_ON = GlobalKeyword.Create(ShaderKeywordStrings.LIGHTMAP_ON); + public static readonly GlobalKeyword DYNAMICLIGHTMAP_ON = GlobalKeyword.Create(ShaderKeywordStrings.DYNAMICLIGHTMAP_ON); + public static readonly GlobalKeyword _ALPHATEST_ON = GlobalKeyword.Create(ShaderKeywordStrings._ALPHATEST_ON); + public static readonly GlobalKeyword DIRLIGHTMAP_COMBINED = GlobalKeyword.Create(ShaderKeywordStrings.DIRLIGHTMAP_COMBINED); + public static readonly GlobalKeyword _DETAIL_MULX2 = GlobalKeyword.Create(ShaderKeywordStrings._DETAIL_MULX2); + public static readonly GlobalKeyword _DETAIL_SCALED = GlobalKeyword.Create(ShaderKeywordStrings._DETAIL_SCALED); + public static readonly GlobalKeyword _CLEARCOAT = GlobalKeyword.Create(ShaderKeywordStrings._CLEARCOAT); + public static readonly GlobalKeyword _CLEARCOATMAP = GlobalKeyword.Create(ShaderKeywordStrings._CLEARCOATMAP); + public static readonly GlobalKeyword DEBUG_DISPLAY = GlobalKeyword.Create(ShaderKeywordStrings.DEBUG_DISPLAY); + public static readonly GlobalKeyword LOD_FADE_CROSSFADE = GlobalKeyword.Create(ShaderKeywordStrings.LOD_FADE_CROSSFADE); + public static readonly GlobalKeyword USE_UNITY_CROSSFADE = GlobalKeyword.Create(ShaderKeywordStrings.USE_UNITY_CROSSFADE); + public static readonly GlobalKeyword _EMISSION = GlobalKeyword.Create(ShaderKeywordStrings._EMISSION); + public static readonly GlobalKeyword _RECEIVE_SHADOWS_OFF = GlobalKeyword.Create(ShaderKeywordStrings._RECEIVE_SHADOWS_OFF); + public static readonly GlobalKeyword _SURFACE_TYPE_TRANSPARENT = GlobalKeyword.Create(ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT); + public static readonly GlobalKeyword _ALPHAPREMULTIPLY_ON = GlobalKeyword.Create(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON); + public static readonly GlobalKeyword _ALPHAMODULATE_ON = GlobalKeyword.Create(ShaderKeywordStrings._ALPHAMODULATE_ON); + public static readonly GlobalKeyword _NORMALMAP = GlobalKeyword.Create(ShaderKeywordStrings._NORMALMAP); + public static readonly GlobalKeyword _ADD_PRECOMPUTED_VELOCITY = GlobalKeyword.Create(ShaderKeywordStrings._ADD_PRECOMPUTED_VELOCITY); + public static readonly GlobalKeyword EDITOR_VISUALIZATION = GlobalKeyword.Create(ShaderKeywordStrings.EDITOR_VISUALIZATION); + public static readonly GlobalKeyword FoveatedRenderingNonUniformRaster = GlobalKeyword.Create(ShaderKeywordStrings.FoveatedRenderingNonUniformRaster); + public static readonly GlobalKeyword DisableTexture2DXArray = GlobalKeyword.Create(ShaderKeywordStrings.DisableTexture2DXArray); + public static readonly GlobalKeyword BlitSingleSlice = GlobalKeyword.Create(ShaderKeywordStrings.BlitSingleSlice); + public static readonly GlobalKeyword XROcclusionMeshCombined = GlobalKeyword.Create(ShaderKeywordStrings.XROcclusionMeshCombined); + public static readonly GlobalKeyword SCREEN_COORD_OVERRIDE = GlobalKeyword.Create(ShaderKeywordStrings.SCREEN_COORD_OVERRIDE); + public static readonly GlobalKeyword DOWNSAMPLING_SIZE_2 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_2); + public static readonly GlobalKeyword DOWNSAMPLING_SIZE_4 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_4); + public static readonly GlobalKeyword DOWNSAMPLING_SIZE_8 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_8); + public static readonly GlobalKeyword DOWNSAMPLING_SIZE_16 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_16); + public static readonly GlobalKeyword EVALUATE_SH_MIXED = GlobalKeyword.Create(ShaderKeywordStrings.EVALUATE_SH_MIXED); + public static readonly GlobalKeyword EVALUATE_SH_VERTEX = GlobalKeyword.Create(ShaderKeywordStrings.EVALUATE_SH_VERTEX); + public static readonly GlobalKeyword ProbeVolumeL1 = GlobalKeyword.Create(ShaderKeywordStrings.ProbeVolumeL1); + public static readonly GlobalKeyword ProbeVolumeL2 = GlobalKeyword.Create(ShaderKeywordStrings.ProbeVolumeL2); + public static readonly GlobalKeyword LIGHTMAP_BICUBIC_SAMPLING = GlobalKeyword.Create(ShaderKeywordStrings.LIGHTMAP_BICUBIC_SAMPLING); + public static readonly GlobalKeyword _OUTPUT_DEPTH = GlobalKeyword.Create(ShaderKeywordStrings._OUTPUT_DEPTH); + public static readonly GlobalKeyword LinearToSRGBConversion = GlobalKeyword.Create(ShaderKeywordStrings.LinearToSRGBConversion); + public static readonly GlobalKeyword _ENABLE_ALPHA_OUTPUT = GlobalKeyword.Create(ShaderKeywordStrings._ENABLE_ALPHA_OUTPUT); + public static readonly GlobalKeyword ForwardPlus = GlobalKeyword.Create(ShaderKeywordStrings.ForwardPlus); // Backward compatibility. Deprecated in 6.1. #if (UNITY_META_QUEST) - public static GlobalKeyword META_QUEST_ORTHO_PROJ; - public static GlobalKeyword META_QUEST_LIGHTUNROLL; - public static GlobalKeyword META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP; + public static readonly GlobalKeyword META_QUEST_ORTHO_PROJ = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_ORTHO_PROJ); + public static readonly GlobalKeyword META_QUEST_LIGHTUNROLL = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_LIGHTUNROLL); + public static readonly GlobalKeyword META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP); #endif - public static GlobalKeyword APPLICATION_SPACE_WARP_MOTION_TRANSPARENT; - public static GlobalKeyword DEPTH_AS_INPUT_ATTACHMENT; - public static GlobalKeyword DEPTH_AS_INPUT_ATTACHMENT_MSAA; + public static readonly GlobalKeyword APPLICATION_SPACE_WARP_MOTION_TRANSPARENT = GlobalKeyword.Create(ShaderKeywordStrings.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT); + public static readonly GlobalKeyword DEPTH_AS_INPUT_ATTACHMENT = GlobalKeyword.Create(ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT); + public static readonly GlobalKeyword DEPTH_AS_INPUT_ATTACHMENT_MSAA = GlobalKeyword.Create(ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT_MSAA); // TODO: Move following keywords to Local keywords? // https://docs.unity3d.com/ScriptReference/Rendering.LocalKeyword.html - //public static GlobalKeyword TonemapACES; - //public static GlobalKeyword TonemapNeutral; - //public static GlobalKeyword UseFastSRGBLinearConversion; - //public static GlobalKeyword SmaaLow; - //public static GlobalKeyword SmaaMedium; - //public static GlobalKeyword SmaaHigh; - //public static GlobalKeyword PaniniGeneric; - //public static GlobalKeyword PaniniUnitDistance; - //public static GlobalKeyword HighQualitySampling; - //public static GlobalKeyword BloomLQ; - //public static GlobalKeyword BloomHQ; - //public static GlobalKeyword BloomLQDirt; - //public static GlobalKeyword BloomHQDirt; - //public static GlobalKeyword UseRGBM; - //public static GlobalKeyword Distortion; - //public static GlobalKeyword ChromaticAberration; - //public static GlobalKeyword HDRGrading; - //public static GlobalKeyword FilmGrain; - //public static GlobalKeyword Fxaa; - //public static GlobalKeyword Dithering; - //public static GlobalKeyword Rcas; - //public static GlobalKeyword EasuRcasAndHDRInput; - //public static GlobalKeyword Gamma20; - //public static GlobalKeyword Gamma20AndHDRInput; - //public static GlobalKeyword PointSampling; + //public static readonly GlobalKeyword TonemapACES; + //public static readonly GlobalKeyword TonemapNeutral; + //public static readonly GlobalKeyword UseFastSRGBLinearConversion; + //public static readonly GlobalKeyword SmaaLow; + //public static readonly GlobalKeyword SmaaMedium; + //public static readonly GlobalKeyword SmaaHigh; + //public static readonly GlobalKeyword PaniniGeneric; + //public static readonly GlobalKeyword PaniniUnitDistance; + //public static readonly GlobalKeyword HighQualitySampling; + //public static readonly GlobalKeyword BloomLQ; + //public static readonly GlobalKeyword BloomHQ; + //public static readonly GlobalKeyword BloomLQDirt; + //public static readonly GlobalKeyword BloomHQDirt; + //public static readonly GlobalKeyword UseRGBM; + //public static readonly GlobalKeyword Distortion; + //public static readonly GlobalKeyword ChromaticAberration; + //public static readonly GlobalKeyword HDRGrading; + //public static readonly GlobalKeyword FilmGrain; + //public static readonly GlobalKeyword Fxaa; + //public static readonly GlobalKeyword Dithering; + //public static readonly GlobalKeyword Rcas; + //public static readonly GlobalKeyword EasuRcasAndHDRInput; + //public static readonly GlobalKeyword Gamma20; + //public static readonly GlobalKeyword Gamma20AndHDRInput; + //public static readonly GlobalKeyword PointSampling; + + // Explicit class constructor required to ensure static field initializers when calling InitializeShaderGlobalKeywords + static ShaderGlobalKeywords() { } public static void InitializeShaderGlobalKeywords() { - // Init all keywords upfront - ShaderGlobalKeywords.MainLightShadows = GlobalKeyword.Create(ShaderKeywordStrings.MainLightShadows); - ShaderGlobalKeywords.MainLightShadowCascades = GlobalKeyword.Create(ShaderKeywordStrings.MainLightShadowCascades); - ShaderGlobalKeywords.MainLightShadowScreen = GlobalKeyword.Create(ShaderKeywordStrings.MainLightShadowScreen); - ShaderGlobalKeywords.CastingPunctualLightShadow = GlobalKeyword.Create(ShaderKeywordStrings.CastingPunctualLightShadow); - ShaderGlobalKeywords.AdditionalLightsVertex = GlobalKeyword.Create(ShaderKeywordStrings.AdditionalLightsVertex); - ShaderGlobalKeywords.AdditionalLightsPixel = GlobalKeyword.Create(ShaderKeywordStrings.AdditionalLightsPixel); - ShaderGlobalKeywords.ClusterLightLoop = GlobalKeyword.Create(ShaderKeywordStrings.ClusterLightLoop); - ShaderGlobalKeywords.AdditionalLightShadows = GlobalKeyword.Create(ShaderKeywordStrings.AdditionalLightShadows); - ShaderGlobalKeywords.ReflectionProbeBoxProjection = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeBoxProjection); - ShaderGlobalKeywords.ReflectionProbeBlending = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeBlending); - ShaderGlobalKeywords.ReflectionProbeAtlas = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeAtlas); - ShaderGlobalKeywords.ReflectionProbeRotation = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeRotation); - ShaderGlobalKeywords.ScreenSpaceReflection = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceReflection); - ShaderGlobalKeywords.SoftShadows = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadows); - ShaderGlobalKeywords.SoftShadowsLow = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsLow); - ShaderGlobalKeywords.SoftShadowsMedium = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsMedium); - ShaderGlobalKeywords.SoftShadowsHigh = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsHigh); - ShaderGlobalKeywords.MixedLightingSubtractive = GlobalKeyword.Create(ShaderKeywordStrings.MixedLightingSubtractive); - ShaderGlobalKeywords.LightmapShadowMixing = GlobalKeyword.Create(ShaderKeywordStrings.LightmapShadowMixing); - ShaderGlobalKeywords.ShadowsShadowMask = GlobalKeyword.Create(ShaderKeywordStrings.ShadowsShadowMask); - ShaderGlobalKeywords.LightLayers = GlobalKeyword.Create(ShaderKeywordStrings.LightLayers); - ShaderGlobalKeywords.RenderPassEnabled = GlobalKeyword.Create(ShaderKeywordStrings.RenderPassEnabled); - ShaderGlobalKeywords.BillboardFaceCameraPos = GlobalKeyword.Create(ShaderKeywordStrings.BillboardFaceCameraPos); - ShaderGlobalKeywords.LightCookies = GlobalKeyword.Create(ShaderKeywordStrings.LightCookies); - ShaderGlobalKeywords.DepthNoMsaa = GlobalKeyword.Create(ShaderKeywordStrings.DepthNoMsaa); - ShaderGlobalKeywords.DepthMsaa2 = GlobalKeyword.Create(ShaderKeywordStrings.DepthMsaa2); - ShaderGlobalKeywords.DepthMsaa4 = GlobalKeyword.Create(ShaderKeywordStrings.DepthMsaa4); - ShaderGlobalKeywords.DepthMsaa8 = GlobalKeyword.Create(ShaderKeywordStrings.DepthMsaa8); - ShaderGlobalKeywords.DBufferMRT1 = GlobalKeyword.Create(ShaderKeywordStrings.DBufferMRT1); - ShaderGlobalKeywords.DBufferMRT2 = GlobalKeyword.Create(ShaderKeywordStrings.DBufferMRT2); - ShaderGlobalKeywords.DBufferMRT3 = GlobalKeyword.Create(ShaderKeywordStrings.DBufferMRT3); - ShaderGlobalKeywords.DecalNormalBlendLow = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendLow); - ShaderGlobalKeywords.DecalNormalBlendMedium = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendMedium); - ShaderGlobalKeywords.DecalNormalBlendHigh = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendHigh); - ShaderGlobalKeywords.DecalLayers = GlobalKeyword.Create(ShaderKeywordStrings.DecalLayers); - ShaderGlobalKeywords.WriteRenderingLayers = GlobalKeyword.Create(ShaderKeywordStrings.WriteRenderingLayers); - ShaderGlobalKeywords.WriteSmoothness = GlobalKeyword.Create(ShaderKeywordStrings.WriteSmoothness); - ShaderGlobalKeywords.ScreenSpaceOcclusion = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceOcclusion); - ShaderGlobalKeywords.ScreenSpaceIrradiance = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceIrradiance); - ShaderGlobalKeywords._SPOT = GlobalKeyword.Create(ShaderKeywordStrings._SPOT); - ShaderGlobalKeywords._DIRECTIONAL = GlobalKeyword.Create(ShaderKeywordStrings._DIRECTIONAL); - ShaderGlobalKeywords._POINT = GlobalKeyword.Create(ShaderKeywordStrings._POINT); - ShaderGlobalKeywords._DEFERRED_STENCIL = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_STENCIL); - ShaderGlobalKeywords._DEFERRED_FIRST_LIGHT = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_FIRST_LIGHT); - ShaderGlobalKeywords._DEFERRED_MAIN_LIGHT = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_MAIN_LIGHT); - ShaderGlobalKeywords._GBUFFER_NORMALS_OCT = GlobalKeyword.Create(ShaderKeywordStrings._GBUFFER_NORMALS_OCT); - ShaderGlobalKeywords._DEFERRED_MIXED_LIGHTING = GlobalKeyword.Create(ShaderKeywordStrings._DEFERRED_MIXED_LIGHTING); - ShaderGlobalKeywords.LIGHTMAP_ON = GlobalKeyword.Create(ShaderKeywordStrings.LIGHTMAP_ON); - ShaderGlobalKeywords.DYNAMICLIGHTMAP_ON = GlobalKeyword.Create(ShaderKeywordStrings.DYNAMICLIGHTMAP_ON); - ShaderGlobalKeywords._ALPHATEST_ON = GlobalKeyword.Create(ShaderKeywordStrings._ALPHATEST_ON); - ShaderGlobalKeywords.DIRLIGHTMAP_COMBINED = GlobalKeyword.Create(ShaderKeywordStrings.DIRLIGHTMAP_COMBINED); - ShaderGlobalKeywords._DETAIL_MULX2 = GlobalKeyword.Create(ShaderKeywordStrings._DETAIL_MULX2); - ShaderGlobalKeywords._DETAIL_SCALED = GlobalKeyword.Create(ShaderKeywordStrings._DETAIL_SCALED); - ShaderGlobalKeywords._CLEARCOAT = GlobalKeyword.Create(ShaderKeywordStrings._CLEARCOAT); - ShaderGlobalKeywords._CLEARCOATMAP = GlobalKeyword.Create(ShaderKeywordStrings._CLEARCOATMAP); - ShaderGlobalKeywords.DEBUG_DISPLAY = GlobalKeyword.Create(ShaderKeywordStrings.DEBUG_DISPLAY); - ShaderGlobalKeywords.LOD_FADE_CROSSFADE = GlobalKeyword.Create(ShaderKeywordStrings.LOD_FADE_CROSSFADE); - ShaderGlobalKeywords.USE_UNITY_CROSSFADE = GlobalKeyword.Create(ShaderKeywordStrings.USE_UNITY_CROSSFADE); - ShaderGlobalKeywords._EMISSION = GlobalKeyword.Create(ShaderKeywordStrings._EMISSION); - ShaderGlobalKeywords._RECEIVE_SHADOWS_OFF = GlobalKeyword.Create(ShaderKeywordStrings._RECEIVE_SHADOWS_OFF); - ShaderGlobalKeywords._SURFACE_TYPE_TRANSPARENT = GlobalKeyword.Create(ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT); - ShaderGlobalKeywords._ALPHAPREMULTIPLY_ON = GlobalKeyword.Create(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON); - ShaderGlobalKeywords._ALPHAMODULATE_ON = GlobalKeyword.Create(ShaderKeywordStrings._ALPHAMODULATE_ON); - ShaderGlobalKeywords._NORMALMAP = GlobalKeyword.Create(ShaderKeywordStrings._NORMALMAP); - ShaderGlobalKeywords._ADD_PRECOMPUTED_VELOCITY = GlobalKeyword.Create(ShaderKeywordStrings._ADD_PRECOMPUTED_VELOCITY); - ShaderGlobalKeywords.EDITOR_VISUALIZATION = GlobalKeyword.Create(ShaderKeywordStrings.EDITOR_VISUALIZATION); - ShaderGlobalKeywords.FoveatedRenderingNonUniformRaster = GlobalKeyword.Create(ShaderKeywordStrings.FoveatedRenderingNonUniformRaster); - ShaderGlobalKeywords.DisableTexture2DXArray = GlobalKeyword.Create(ShaderKeywordStrings.DisableTexture2DXArray); - ShaderGlobalKeywords.BlitSingleSlice = GlobalKeyword.Create(ShaderKeywordStrings.BlitSingleSlice); - ShaderGlobalKeywords.XROcclusionMeshCombined = GlobalKeyword.Create(ShaderKeywordStrings.XROcclusionMeshCombined); - ShaderGlobalKeywords.SCREEN_COORD_OVERRIDE = GlobalKeyword.Create(ShaderKeywordStrings.SCREEN_COORD_OVERRIDE); - ShaderGlobalKeywords.DOWNSAMPLING_SIZE_2 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_2); - ShaderGlobalKeywords.DOWNSAMPLING_SIZE_4 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_4); - ShaderGlobalKeywords.DOWNSAMPLING_SIZE_8 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_8); - ShaderGlobalKeywords.DOWNSAMPLING_SIZE_16 = GlobalKeyword.Create(ShaderKeywordStrings.DOWNSAMPLING_SIZE_16); - ShaderGlobalKeywords.EVALUATE_SH_MIXED = GlobalKeyword.Create(ShaderKeywordStrings.EVALUATE_SH_MIXED); - ShaderGlobalKeywords.EVALUATE_SH_VERTEX = GlobalKeyword.Create(ShaderKeywordStrings.EVALUATE_SH_VERTEX); - ShaderGlobalKeywords.ProbeVolumeL1 = GlobalKeyword.Create(ShaderKeywordStrings.ProbeVolumeL1); - ShaderGlobalKeywords.ProbeVolumeL2 = GlobalKeyword.Create(ShaderKeywordStrings.ProbeVolumeL2); - ShaderGlobalKeywords.LIGHTMAP_BICUBIC_SAMPLING = GlobalKeyword.Create(ShaderKeywordStrings.LIGHTMAP_BICUBIC_SAMPLING); - ShaderGlobalKeywords._OUTPUT_DEPTH = GlobalKeyword.Create(ShaderKeywordStrings._OUTPUT_DEPTH); - ShaderGlobalKeywords.LinearToSRGBConversion = GlobalKeyword.Create(ShaderKeywordStrings.LinearToSRGBConversion); - ShaderGlobalKeywords._ENABLE_ALPHA_OUTPUT = GlobalKeyword.Create(ShaderKeywordStrings._ENABLE_ALPHA_OUTPUT); - ShaderGlobalKeywords.ForwardPlus = GlobalKeyword.Create(ShaderKeywordStrings.ForwardPlus); // Backward compatibility. Deprecated in 6.1. -#if (UNITY_META_QUEST) - ShaderGlobalKeywords.META_QUEST_ORTHO_PROJ = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_ORTHO_PROJ); - ShaderGlobalKeywords.META_QUEST_LIGHTUNROLL = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_LIGHTUNROLL); - ShaderGlobalKeywords.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP); -#endif - ShaderGlobalKeywords.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT = GlobalKeyword.Create(ShaderKeywordStrings.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT); - ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT = GlobalKeyword.Create(ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT); - ShaderGlobalKeywords.DEPTH_AS_INPUT_ATTACHMENT_MSAA = GlobalKeyword.Create(ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT_MSAA); + // Keeping and calling this empty static function from pipeline creation ensures the static fields are + // initialized at that point, instead of happening on the first frame, potentially causing a hitch. } } From 252da96a9ac265460709c710d9a9ccffcc0b7625 Mon Sep 17 00:00:00 2001 From: Justin Schwartz Date: Wed, 15 Apr 2026 20:41:36 +0000 Subject: [PATCH 87/88] Updated `NormalReconstruction` to work with CoreCLR --- .../Runtime/NormalReconstruction.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/NormalReconstruction.cs b/Packages/com.unity.render-pipelines.universal/Runtime/NormalReconstruction.cs index 2375ec30970..5fa959d3a97 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/NormalReconstruction.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/NormalReconstruction.cs @@ -8,7 +8,7 @@ namespace UnityEngine.Rendering.Universal.Internal public static class NormalReconstruction { private static readonly int s_NormalReconstructionMatrixID = Shader.PropertyToID("_NormalReconstructionMatrix"); - private static Matrix4x4[] s_NormalReconstructionMatrix = new Matrix4x4[2]; + private static readonly Matrix4x4[] s_NormalReconstructionMatrix = new Matrix4x4[2]; /// /// Setup properties needed for normal reconstruction from depth using shader functions in NormalReconstruction.hlsl @@ -57,7 +57,6 @@ public static void SetupProperties(RasterCommandBuffer cmd, in UniversalCameraDa { Matrix4x4 view = cameraData.GetViewMatrix(eyeIndex); Matrix4x4 proj = cameraData.GetProjectionMatrix(eyeIndex); - s_NormalReconstructionMatrix[eyeIndex] = proj * view; // camera view space without translation, used by SSAO.hlsl ReconstructViewPos() to calculate view vector. Matrix4x4 cview = view; From 44d490e9df603d603f601b3bceeeec46afd093e0 Mon Sep 17 00:00:00 2001 From: Rasmus Roenn Nielsen Date: Wed, 15 Apr 2026 20:41:58 +0000 Subject: [PATCH 88/88] Use current Defrag Count in Surface Cache --- .../Lighting/SurfaceCache/SurfaceCache.cs | 35 +++++++++++-------- .../SurfaceCacheGIRendererFeature.cs | 12 +++---- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs index 47a4f6d7d4f..df9147b5d7c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCache.cs @@ -194,11 +194,11 @@ internal class SurfaceCacheResourceSet internal int TemporalFilteringKernel; internal uint3 TemporalFilteringKernelGroupSize; - internal readonly uint SubGroupSize; + internal readonly uint ComputeSubGroupSize; - internal SurfaceCacheResourceSet(uint subGroupSize) + internal SurfaceCacheResourceSet(uint computeSubGroupSize) { - SubGroupSize = subGroupSize; + ComputeSubGroupSize = computeSubGroupSize; } internal bool LoadFromRenderPipelineResources(RayTracingContext rtContext) @@ -223,9 +223,9 @@ internal bool LoadFromRenderPipelineResources(RayTracingContext rtContext) TemporalFilteringKernel = TemporalFilteringShader.FindKernel("FilterTemporally"); TemporalFilteringShader.GetKernelThreadGroupSizes(TemporalFilteringKernel, out TemporalFilteringKernelGroupSize.x, out TemporalFilteringKernelGroupSize.y, out TemporalFilteringKernelGroupSize.z); - Debug.Assert(SubGroupSize == 8 || SubGroupSize == 16 || SubGroupSize == 32 || SubGroupSize == 48 || SubGroupSize == 64); + Debug.Assert(ComputeSubGroupSize == 8 || ComputeSubGroupSize == 16 || ComputeSubGroupSize == 32 || ComputeSubGroupSize == 48 || ComputeSubGroupSize == 64); DefragShader = rpResources.defragShader; - var defragKeyword = "SUB_GROUP_SIZE_" + SubGroupSize; + var defragKeyword = "SUB_GROUP_SIZE_" + ComputeSubGroupSize; DefragShader.EnableKeyword(defragKeyword); DefragKernel = DefragShader.FindKernel("Defrag"); DefragShader.GetKernelThreadGroupSizes(DefragKernel, out DefragKernelGroupSize.x, out DefragKernelGroupSize.y, out DefragKernelGroupSize.z); @@ -256,6 +256,7 @@ internal bool LoadFromRenderPipelineResources(RayTracingContext rtContext) internal class SurfaceCache : IDisposable { public const uint CascadeMax = 8; + private readonly GraphicsBuffer _punctualLightSamples; private readonly SurfaceCachePatchList _patches; private readonly SurfaceCacheVolume _volume; @@ -267,7 +268,8 @@ internal class SurfaceCache : IDisposable private SurfaceCachePatchFilteringParameterSet _patchFilteringParams; private float _shortHysteresis; - readonly private uint _defragCount; + private uint _defragCount = 1; + private uint _defragOffset = 0; readonly private float _albedoBoost = 1.0f; public GraphicsBuffer PunctualLightSamples => _punctualLightSamples; @@ -323,7 +325,7 @@ private class DefragPassData internal GraphicsBuffer PatchStatistics; internal GraphicsBuffer CellPatchIndices; internal uint RingConfigStartFlipflop; - internal uint EvenIterationPatchOffset; + internal uint ComputeSubGroupSize; internal uint OddIterationPatchOffset; } @@ -442,7 +444,6 @@ internal static class ShaderIDs public SurfaceCache( SurfaceCacheResourceSet resources, - uint defragCount, SurfaceCacheVolumeParameterSet volParams) { Debug.Assert(volParams.CascadeCount != 0); @@ -457,8 +458,6 @@ public SurfaceCache( _ringConfig = new SurfaceCacheRingConfig(); _patches = new SurfaceCachePatchList(patchCapacity); _punctualLightSamples = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)punctualLightSampleCount, sizeof(float) * 17); - - _defragCount = defragCount; } public void SetEstimationParams(SurfaceCacheEstimationParameterSet estimationParams) @@ -466,6 +465,11 @@ public void SetEstimationParams(SurfaceCacheEstimationParameterSet estimationPar _estimationParams = estimationParams; } + public void SetDefragCount(uint count) + { + _defragCount = count; + } + public void SetPatchFilteringParams(SurfaceCachePatchFilteringParameterSet patchFilteringParams) { Debug.Assert(0.0f <= patchFilteringParams.TemporalSmoothing && patchFilteringParams.TemporalSmoothing <= 1.0f); @@ -473,7 +477,7 @@ public void SetPatchFilteringParams(SurfaceCachePatchFilteringParameterSet patch _shortHysteresis = Mathf.Lerp(0.75f, 0.95f, patchFilteringParams.TemporalSmoothing); } - public void UpdateVolumeSize(float size) + public void SetVolumeSize(float size) { _volume.VoxelMinSize = size / (_volume.SpatialResolution * (float)(1u << (int)(_volume.CascadeCount - 1u))); } @@ -495,7 +499,7 @@ private void RecordDefragmentation(RenderGraph renderGraph, uint frameIdx) { using (var builder = renderGraph.AddComputePass("Surface Cache Defrag", out DefragPassData passData)) { - passData.IterationOffset = frameIdx * _defragCount; + passData.IterationOffset = _defragOffset; passData.IterationCount = _defragCount; passData.Shader = _resources.DefragShader; passData.Keyword = _resources.DefragKeyword; @@ -510,8 +514,7 @@ private void RecordDefragmentation(RenderGraph renderGraph, uint frameIdx) passData.PatchGeometries = Patches.Geometries; passData.PatchStatistics = Patches.Statistics; passData.CellPatchIndices = Volume.CellPatchIndices; - passData.EvenIterationPatchOffset = 0; - passData.OddIterationPatchOffset = _resources.SubGroupSize / 2; + passData.ComputeSubGroupSize = _resources.ComputeSubGroupSize; builder.AllowGlobalStateModification(true); // Set to ensure ordering. builder.SetRenderFunc((DefragPassData data, ComputeGraphContext cgContext) => Defrag(data, cgContext)); @@ -519,6 +522,8 @@ private void RecordDefragmentation(RenderGraph renderGraph, uint frameIdx) if (_defragCount % 2 == 1) RingConfig.Flip(); } + + _defragOffset += _defragCount; } private void RecordEviction(RenderGraph renderGraph, uint frameIdx) @@ -770,7 +775,7 @@ static void Defrag(DefragPassData data, ComputeGraphContext cgContext) { uint readOffset = SurfaceCacheRingConfig.GetOffsetA(flipflop); uint writeOffset = SurfaceCacheRingConfig.GetOffsetB(flipflop); - uint patchOffset = iterationIndex % 2 == 0 ? data.EvenIterationPatchOffset : data.OddIterationPatchOffset; + uint patchOffset = iterationIndex % 2 * (data.ComputeSubGroupSize / 2); cmd.SetComputeIntParam(shader, ShaderIDs._RingConfigReadOffset, (int)readOffset); cmd.SetComputeIntParam(shader, ShaderIDs._RingConfigWriteOffset, (int)writeOffset); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs index a451c9dcd43..068a2dad0a7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs @@ -356,7 +356,6 @@ private class ScreenIrradianceUpsamplingPassData // Stored for runtime cache recreation when resolution or cascade count changes private readonly Rendering.SurfaceCacheResourceSet _coreResources; - private uint _defragCount; public SurfaceCachePass( RayTracingContext rtContext, @@ -371,7 +370,6 @@ public SurfaceCachePass( bool debugEnabled, DebugViewMode_ debugViewMode, bool debugShowSamplePosition, - uint defragCount, SurfaceCacheVolumeParameterSet volParams) { Debug.Assert(volParams.CascadeCount != 0); @@ -403,9 +401,8 @@ public SurfaceCachePass( _debugShowSamplePosition = debugShowSamplePosition; _coreResources = resourceSet; - _defragCount = defragCount; - _cache = new SurfaceCache(resourceSet, defragCount, volParams); + _cache = new SurfaceCache(resourceSet, volParams); _sceneTracker = new SceneUpdatesTracker(); _world = new SurfaceCacheWorld(); @@ -521,7 +518,6 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer var stack = VolumeManager.instance.stack; var volume = stack.GetComponent(); var volumeParams = GetVolumeParametersOrDefaults(volume); - _defragCount = volumeParams.DefragCount; // Detect structural changes that require buffer reallocation. if (volumeParams.VolumeResolution != _cache.Volume.SpatialResolution || volumeParams.VolumeCascadeCount != _cache.Volume.CascadeCount) @@ -537,13 +533,14 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer Size = volumeParams.VolumeSize, CascadeCount = newCascadeCount }; - _cache = new SurfaceCache(_coreResources, _defragCount, newVolParams); + _cache = new SurfaceCache(_coreResources, newVolParams); _frameIdx = 0; } _cache.SetEstimationParams(volumeParams.EstimationParams); _cache.SetPatchFilteringParams(volumeParams.PatchFilteringParams); - _cache.UpdateVolumeSize(volumeParams.VolumeSize); + _cache.SetVolumeSize(volumeParams.VolumeSize); + _cache.SetDefragCount(volumeParams.DefragCount); bool useMotionVectorPatchSeeding = UseMotionVectorPatchSeeding(cameraData.cameraType); @@ -1037,7 +1034,6 @@ public override void Create() _parameterSet.DebugEnabled, _parameterSet.DebugViewMode, _parameterSet.DebugShowSamplePosition, - defragCount: DEFAULT_DEFRAG_COUNT, volParams); _pass.renderPassEvent = RenderPassEvent.AfterRenderingPrePasses + 1;