diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs index ab94e7d8..bb204530 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs @@ -361,6 +361,7 @@ namespace UnityEngine.Rendering activeSet = newSet; ProbeReferenceVolume.instance.Clear(); + ProbeReferenceVolume.instance.SetActiveBakingSet(newSet); } if (activeSet != null) diff --git a/Packages/com.unity.render-pipelines.core/Editor/LookDev/DisplayWindow.EnvironmentLibrarySidePanel.cs b/Packages/com.unity.render-pipelines.core/Editor/LookDev/DisplayWindow.EnvironmentLibrarySidePanel.cs index 20902c6f..aa7b4fab 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/LookDev/DisplayWindow.EnvironmentLibrarySidePanel.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/LookDev/DisplayWindow.EnvironmentLibrarySidePanel.cs @@ -451,7 +451,7 @@ namespace UnityEditor.Rendering.LookDev void OnFocus() { //OnFocus is called before OnEnable that open backend if not already opened, so only sync if backend is open - if (LookDev.open) + if (LookDev.open && LookDev.currentContext != null) { //If EnvironmentLibrary asset as been edited by the user (deletion), //update all view to use null environment if it was not temporary ones diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs index 5154a6de..6913fe88 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs @@ -13,6 +13,7 @@ namespace UnityEngine.Rendering /// [ExecuteAlways] [AddComponentMenu("Rendering/Lens Flare (SRP)")] + [CurrentPipelineHelpURL("shared/lens-flare/lens-flare-component")] public sealed class LensFlareComponentSRP : MonoBehaviour { [SerializeField] 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 0357f870..90c5918a 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 @@ -1076,7 +1076,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler foreach (ref readonly var nativePass in contextData.NativePasses) { // Loop over all created resources by this nrp - var graphPasses = nativePass.GraphPasses(contextData); + var graphPasses = nativePass.GraphPasses(contextData, out var actualPasses); foreach (ref readonly var subPass in graphPasses) { foreach (ref readonly var createdRes in subPass.FirstUsedResources(contextData)) @@ -1118,6 +1118,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } } + if (actualPasses.IsCreated) + actualPasses.Dispose(); } } } @@ -1168,7 +1170,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler if (pass.mergeState == PassMergeState.Begin || pass.mergeState == PassMergeState.None) { ref var nativePass = ref contextData.nativePassData.ElementAt(pass.nativePassIndex); - foreach (ref readonly var subPass in nativePass.GraphPasses(contextData)) + var graphPasses = nativePass.GraphPasses(contextData, out var actualPasses); + foreach (ref readonly var subPass in graphPasses) { foreach (ref readonly var res in subPass.FirstUsedResources(contextData)) { @@ -1204,6 +1207,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } } + if (actualPasses.IsCreated) + actualPasses.Dispose(); } } // Other passes just create them at the beginning of the individual pass @@ -1826,7 +1831,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler if (pass.mergeState == PassMergeState.End || pass.mergeState == PassMergeState.None) { ref var nativePass = ref contextData.nativePassData.ElementAt(pass.nativePassIndex); - foreach (ref readonly var subPass in nativePass.GraphPasses(contextData)) + var graphPasses = nativePass.GraphPasses(contextData, out var actualPasses); + foreach (ref readonly var subPass in graphPasses) { foreach (ref readonly var res in subPass.LastUsedResources(contextData)) { @@ -1837,6 +1843,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } } + if (actualPasses.IsCreated) + actualPasses.Dispose(); } } else 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 cdb8b770..2dad1fa9 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 @@ -781,15 +781,16 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly ReadOnlySpan GraphPasses(CompilerContextData ctx) + public readonly ReadOnlySpan GraphPasses(CompilerContextData ctx, out NativeArray actualPasses) { // When there's no pass being culled, we can directly return a Span of the Native List if (lastGraphPass - firstGraphPass + 1 == numGraphPasses) { + actualPasses = default; return ctx.passData.MakeReadOnlySpan(firstGraphPass, numGraphPasses); } - var actualPasses = + actualPasses = new NativeArray(numGraphPasses, Allocator.Temp, NativeArrayOptions.UninitializedMemory); @@ -808,10 +809,14 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly void GetGraphPassNames(CompilerContextData ctx, DynamicArray dest) { - foreach (ref readonly var pass in GraphPasses(ctx)) + var span = GraphPasses(ctx, out var actualPasses); + foreach (ref readonly var pass in span) { dest.Add(pass.GetName(ctx)); } + + if (actualPasses.IsCreated) + actualPasses.Dispose(); } static bool CanMergeMSAASamples(ref NativePassData nativePass, ref PassData passToMerge) @@ -953,7 +958,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler // Temporary cache of sampled textures in current Native Render Pass for conflict detection against fragments using (HashSetPool.Get(out var tempSampledTextures)) { - var graphPasses = nativePass.GraphPasses(contextData); + var graphPasses = nativePass.GraphPasses(contextData, out var actualPasses); foreach (ref readonly var graphPass in graphPasses) { if (graphPass.numSampledOnlyRaster > 0) // Skip passes with no sampled textures @@ -965,6 +970,9 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } + if (actualPasses.IsCreated) + actualPasses.Dispose(); + foreach (ref readonly var fragment in passToMerge.Fragments(contextData)) { bool alreadyAttached = false; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs index 0b297487..3e9a8f92 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs @@ -5,6 +5,11 @@ using UnityEditor; namespace UnityEngine.Rendering.UnifiedRayTracing { + [Scripting.APIUpdating.MovedFrom( + autoUpdateAPI: true, + sourceNamespace: "UnityEngine.Rendering.UnifiedRayTracing", + sourceAssembly: "Unity.Rendering.LightTransport.Runtime" + )] [Serializable] [SupportedOnRenderPipeline()] [Categorization.CategoryInfo(Name = "R: Unified Ray Tracing", Order = 1000), HideInInspector] 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 b91c8634..d1a9f9aa 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs @@ -1951,6 +1951,37 @@ namespace UnityEngine.Rendering #endif } + /// + /// Indicates whether the combined camera viewports fully cover the screen area. + /// + /// List of cameras to render. + /// True if the combined camera viewports fully cover the screen area. + public static bool IsScreenFullyCoveredByCameras(List cameras) + { + if (cameras == null || cameras.Count == 0) + return false; + + bool isScreenFullyCovered = false; + using (ListPool.Get(out var cameraRects)) + { + // We don't need to exclude stacked cameras for the input camera list because the overlay camera have the same viewport with its base camera. + foreach (var camera in cameras) + { + if (camera.targetTexture != null || camera.cameraType != CameraType.Game) + continue; + + // Skip test if any viewport is full-screen + if (Mathf.Approximately(camera.rect.xMin, 0f) && Mathf.Approximately(camera.rect.yMin, 0f) && camera.rect.width >= Screen.width && camera.rect.height >= Screen.height) + return true; + + cameraRects.Add(camera.rect); + } + isScreenFullyCovered = Mathf.Approximately(SweepLineRectUtils.CalculateRectUnionArea(cameraRects), 1f); + } + + return isScreenFullyCovered; + } + #if UNITY_EDITOR /// /// Populates null fields or collection elements in a target object from a source object of the same type. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs new file mode 100644 index 00000000..2f1d9189 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs @@ -0,0 +1,173 @@ +using System.Buffers; +using System.Collections.Generic; +using Unity.Collections; + +namespace UnityEngine.Rendering +{ + /// + /// Utility class that computes the total rect area via a sweep-line. + /// + public static class SweepLineRectUtils + { + struct EventComparer : IComparer + { + public int Compare(Vector4 a, Vector4 b) + { + int cx = a.x.CompareTo(b.x); + if (cx != 0) return cx; + // tie on x: larger y first (+1 before -1) + return b.y.CompareTo(a.y); + } + } + struct ActiveComparer : IComparer + { + public int Compare(Vector2 a, Vector2 b) + { + return a.x.CompareTo(b.x); + } + } + + /// + /// Computes the total covered area (union) of a set of axis-aligned rectangles, counting overlaps only once. + /// + /// List of rects to compute. + /// The normalized union area in [0,1], with overlaps counted once. + public static float CalculateRectUnionArea(List rects) + { + int rectsCount = rects.Count; + var eventsBuffer = ArrayPool.Shared.Rent(rectsCount * 2); + var activeBuffer = ArrayPool.Shared.Rent(rectsCount); + + int eventCount = 0; + foreach (var rect in rects) + InsertEvents(rect, eventsBuffer, ref eventCount); + + float area = CalculateRectUnionArea(eventsBuffer, activeBuffer, eventCount); + ArrayPool.Shared.Return(eventsBuffer); + ArrayPool.Shared.Return(activeBuffer); + + return area; + } + + // Merge overlapping intervals and return total covered Y length + static float MergeLengthY(Vector2[] activeBuffer, int count) + { + if (count <= 0) + return 0f; + + // ActiveBuffer stores (yMin, yMax) + float total = 0f; + float cy0 = activeBuffer[0].x; + float cy1 = activeBuffer[0].y; + + for (int i = 1; i < count; i++) + { + float y0 = activeBuffer[i].x; + float y1 = activeBuffer[i].y; + if (y0 <= cy1) + { + if (y1 > cy1) cy1 = y1; + } + else + { + total += (cy1 - cy0); + cy0 = y0; cy1 = y1; + } + } + total += (cy1 - cy0); + return Mathf.Clamp01(total); + } + + /// + /// Computes the total covered area (union) of a set of axis-aligned rectangles using a sweep-line. + /// + static unsafe float CalculateRectUnionArea(Vector4[] eventsBuffer, Vector2[] activeBuffer, int eventCount) + { + if (eventCount == 0) + return 0f; + + // Sort events by (x asc, enter first) + fixed (Vector4* ptr = eventsBuffer) + { + NativeSortExtension.Sort(ptr, eventCount, new EventComparer()); + } + + int activeCount = 0; + float area = 0f; + float lastX = eventsBuffer[0].x; + bool needLastXUpdate = false; + int i = 0; + + while (i < eventCount) + { + float x = eventsBuffer[i].x; + + if (needLastXUpdate) + { + lastX = x; + needLastXUpdate = false; + } + + // Accumulate area over [lastX, x) + float dx = x - lastX; + if (dx > 0f && activeCount > 0) + { + fixed (Vector2* ptr = activeBuffer) + { + NativeSortExtension.Sort(ptr, activeCount, new ActiveComparer()); + } + area += MergeLengthY(activeBuffer, activeCount) * dx; + lastX = x; + } + + // Consume all events at this x (group approx-equal x's) + do + { + Vector4 ev = eventsBuffer[i]; + float y0 = ev.z; + float y1 = ev.w; + + if (ev.y > 0f) // Enter + { + activeBuffer[activeCount++] = new Vector2(y0, y1); + } + else // Leave + { + // Remove once (swap with last) + for (int k = 0; k < activeCount; k++) + { + Vector2 v = activeBuffer[k]; + if (Mathf.Approximately(v.x, y0) && Mathf.Approximately(v.y, y1)) + { + int last = activeCount - 1; + activeBuffer[k] = activeBuffer[last]; + activeCount = last; + break; + } + } + + if (activeCount == 0) + needLastXUpdate = true; + } + + i++; + } + while (i < eventCount && Mathf.Approximately(eventsBuffer[i].x, x)); + } + + return area; + } + + // Insert events with clamped rects + static void InsertEvents(in Rect rect, Vector4[] eventsBuffer, ref int eventCount) + { + if (rect.width > 0f && rect.height > 0f) + { + var y0 = Mathf.Clamp01(rect.yMin); + var y1 = Mathf.Clamp01(rect.yMax); + eventsBuffer[eventCount++] = new Vector4(Mathf.Clamp01(rect.xMin), +1f, y0, y1); // enter + eventsBuffer[eventCount++] = new Vector4(Mathf.Clamp01(rect.xMax), -1f, y0, y1); // leave + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs.meta new file mode 100644 index 00000000..d841b2be --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/SweepLineRectUtils.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ff1aad7bfc102a847b1979aebf787494 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs index b8ff9672..a06a82f9 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs @@ -1569,7 +1569,9 @@ namespace UnityEngine.Rendering.Tests ValidateNoGCAllocs(() => { - passes[0].GraphPasses(result.contextData); + var graphPasses = passes[0].GraphPasses(result.contextData, out var actualPasses); + if (actualPasses.IsCreated) + actualPasses.Dispose(); }); // From RenderPassCullingTests.cs diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs new file mode 100644 index 00000000..6638e9ec --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs @@ -0,0 +1,184 @@ +using NUnit.Framework; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; + +namespace UnityEditor.Rendering.Tests +{ + class SweepLineRectUtilsTests + { + const float Epsilon = 1e-5f; + + static object[][] s_Empty = new object[][] + { + new object[] { new List() } + }; + + [Test] + [TestCaseSource("s_Empty")] + public void TestEmpty(List rects) + { + var area = SweepLineRectUtils.CalculateRectUnionArea(rects); + Assert.That(area, Is.EqualTo(0f).Within(Epsilon)); + } + + static object[][] s_SingleRect = new object[][] + { + new object[] { new Rect(0.1f, 0.2f, 0.3f, 0.4f), 0.12f }, + new object[] { new Rect(0f, 0f, 1f, 1f), 1f }, + }; + + [Test] + [TestCaseSource("s_SingleRect")] + public void SingleRect(Rect r, float expected) + { + var area = SweepLineRectUtils.CalculateRectUnionArea(new List { r }); + Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); + } + + static object[][] s_NonOverlapping = new object[][] + { + new object[] + { + new List { new Rect(0f, 0f, 0.5f, 0.5f), new Rect(0.5f, 0.5f, 0.5f, 0.5f) }, 0.5f + }, + new object[] + { + new List + { + new Rect(0f, 0f, 0.2f, 0.2f), // 0.04 + new Rect(0.2f, 0f, 0.3f, 0.2f), // 0.06 + new Rect(0.5f, 0.5f, 0.25f, 0.25f) // 0.0625 + }, + 0.1625f + }, + new object[] + { + new List { new Rect(0f, 0f, 0.5f, 1f), new Rect(0.5f, 0f, 0.5f, 1f) }, 1f + }, + new object[] + { + new List { new Rect(0.2f, 0.2f, 0f, 0.5f), new Rect(0.2f, 0.2f, 0.5f, 0f) }, 0f + }, + new object[] + { + new List { new Rect(0f, 0f, 0f, 0f), new Rect(0.1f, 0.1f, 0.2f, 0.3f) }, 0.06f + }, + new object[] + { + new List + { + new Rect(0f, 0.3f, 0.3f, 0.3f), + new Rect(0.6f, 0.3f, 0.3f, 0.3f), + new Rect(0.3f, 0.3f, 0.3f, 0.3f), + new Rect(0f, 0.6f, 0.3f, 0.3f), + new Rect(0.7f, 0.7f, 0.3f, 0.3f), + }, + 0.45f + } + }; + + [Test] + [TestCaseSource("s_NonOverlapping")] + public void NonOverlappingRects(List rects, float expected) + { + var area = SweepLineRectUtils.CalculateRectUnionArea(rects); + Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); + } + + static object[][] s_Overlapping = new object[][] + { + new object[] + { + new List + { + new Rect(0.2f, 0.2f, 0.4f, 0.3f), + new Rect(0.2f, 0.2f, 0.4f, 0.3f) + }, + 0.4f * 0.3f + }, + new object[] + { + new List + { + new Rect(0f, 0f, 0.6f, 0.5f), + new Rect(0.3f, 0f, 0.6f, 0.5f) + }, + 0.9f * 0.5f + }, + new object[] + { + new List + { + new Rect(0f, 0.3f, 0.4f, 0.4f), + new Rect(0.6f, 0.3f, 0.4f, 0.4f), + new Rect(0.3f, 0f, 0.4f, 0.4f), + new Rect(0.3f, 0.6f, 0.4f, 0.4f) + }, + 0.64f - 0.04f + } + }; + + [Test] + [TestCaseSource("s_Overlapping")] + public void OverlappingRects(List rects, float expected) + { + var area = SweepLineRectUtils.CalculateRectUnionArea(rects); + Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); + } + + static object[][] s_ClampingOutside = new object[][] + { + new object[] + { + new List + { + new Rect(-0.2f, -0.2f, 0.3f, 0.3f), // clamps to [0,0,0.1,0.1] area 0.01 + new Rect(0.9f, 0.9f, 0.5f, 0.5f), // clamps to [0.9,0.9,0.1,0.1] area 0.01 + }, + 0.02f + }, + new object[] { new List { new Rect(-10f, -10f, 20f, 20f) }, 1f } + }; + + [Test] + [TestCaseSource("s_ClampingOutside")] + public void ClampingOutside(List rects, float expected) + { + var area = SweepLineRectUtils.CalculateRectUnionArea(rects); + Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); + } + + static object[][] s_IntervalsSorting = new object[][] + { + new object[] + { + new List + { + new Rect(0.0f, 0.2f, 0.2f, 0.2f), + new Rect(0.0f, 0.0f, 0.2f, 0.1f), + new Rect(0.0f, 0.3f, 0.2f, 0.2f), + }, + 0.2f * 0.4f + }, + new object[] + { + new List + { + new Rect(0.0f, 0.0f, 0.2f, 0.1f), + new Rect(0.3f, 0.0f, 0.3f, 0.1f), + new Rect(0.5f, 0.0f, 0.2f, 0.1f), + }, + 0.6f * 0.1f + } + }; + + [Test] + [TestCaseSource("s_IntervalsSorting")] + public void IntervalsSorting(List rects, float expected) + { + var area = SweepLineRectUtils.CalculateRectUnionArea(rects); + Assert.That(area, Is.EqualTo(expected).Within(Epsilon)); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs.meta new file mode 100644 index 00000000..092bccef --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/SweepLineRectUtilsTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bfba7561301ac2a44b010c12825cd189 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/package.json b/Packages/com.unity.render-pipelines.core/package.json index 708f3a33..7c8fe8cd 100644 --- a/Packages/com.unity.render-pipelines.core/package.json +++ b/Packages/com.unity.render-pipelines.core/package.json @@ -13,5 +13,5 @@ "com.unity.modules.terrain": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" }, - "_fingerprint": "33b0f6d355dd85889fe12b1205b211093eedf629" + "_fingerprint": "ce86d16dfe9d627973eff1e9329caf16c648363c" } 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 989ca554..c5ff8626 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 @@ -214,10 +214,9 @@ namespace UnityEditor.Rendering.HighDefinition } else { - // Strip all the area light shadow filtering variants when they are disabled in the shader config. - foreach (var areaShadowVariant in m_ShadowKeywords.AreaShadowVariants) - if (inputData.shaderKeywordSet.IsEnabled(areaShadowVariant.Value)) - return true; + // Strip only AREA_SHADOW_HIGH variant, because HDRP enables AREA_SHADOW_MEDIUM if area light is disabled in ShaderConfig + if (inputData.shaderKeywordSet.IsEnabled(m_AreaShadowHigh)) + return true; } if (!shadowInitParams.supportScreenSpaceShadows && shader == m_ShaderResources.screenSpaceShadowPS) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/ShaderStrippers/HDRPComputeShaderVariantStripper.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/ShaderStrippers/HDRPComputeShaderVariantStripper.cs index c07916db..af1a1da2 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/ShaderStrippers/HDRPComputeShaderVariantStripper.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/ShaderStrippers/HDRPComputeShaderVariantStripper.cs @@ -15,6 +15,7 @@ namespace UnityEditor.Rendering.HighDefinition protected ShaderKeyword m_ProbeVolumesL1 = new ShaderKeyword("PROBE_VOLUMES_L1"); protected ShaderKeyword m_ProbeVolumesL2 = new ShaderKeyword("PROBE_VOLUMES_L2"); protected ShaderKeyword m_WaterAbsorption = new ShaderKeyword("SUPPORT_WATER_ABSORPTION"); + protected ShaderKeyword m_AreaShadowHigh = new ShaderKeyword("AREA_SHADOW_HIGH"); protected HDRenderPipelineRuntimeShaders m_Shaders; @@ -123,10 +124,9 @@ namespace UnityEditor.Rendering.HighDefinition } else { - // Strip all the area light shadow filtering variants when they are disabled in the shader config. - foreach (var areaShadowVariant in m_ShadowKeywords.AreaShadowVariants) - if (inputData.shaderKeywordSet.IsEnabled(areaShadowVariant.Value)) - return true; + // Strip only AREA_SHADOW_HIGH variant, because HDRP enables AREA_SHADOW_MEDIUM if area light is disabled in ShaderConfig + if (inputData.shaderKeywordSet.IsEnabled(m_AreaShadowHigh)) + return true; } // Screen space shadow variant is exclusive, either we have a variant with dynamic if that support screen space shadow or not diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs index 77978a8b..8425f8bd 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs @@ -64,6 +64,7 @@ namespace UnityEditor.Rendering.HighDefinition // Common keyword list protected ShaderKeyword m_Transparent; protected ShaderKeyword m_AlphaTestOn; + protected ShaderKeyword m_AreaShadowHigh; protected ShaderKeyword m_DebugDisplay; protected ShaderKeyword m_TileLighting; protected ShaderKeyword m_ClusterLighting; @@ -115,6 +116,7 @@ namespace UnityEditor.Rendering.HighDefinition // INSTANCING_ON m_Transparent = new ShaderKeyword("_SURFACE_TYPE_TRANSPARENT"); m_AlphaTestOn = new ShaderKeyword("_ALPHATEST_ON"); + m_AreaShadowHigh = new ShaderKeyword("AREA_SHADOW_HIGH"); m_DebugDisplay = new ShaderKeyword("DEBUG_DISPLAY"); m_TileLighting = new ShaderKeyword("USE_FPTL_LIGHTLIST"); m_ClusterLighting = new ShaderKeyword("USE_CLUSTERED_LIGHTLIST"); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/PropertyDrawers/LookDevVolumeProfileSettingsPropertyDrawer.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/PropertyDrawers/LookDevVolumeProfileSettingsPropertyDrawer.cs index 99cc74a5..c34c90ca 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/PropertyDrawers/LookDevVolumeProfileSettingsPropertyDrawer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/PropertyDrawers/LookDevVolumeProfileSettingsPropertyDrawer.cs @@ -13,6 +13,7 @@ namespace UnityEditor.Rendering.HighDefinition { VisualElement m_Root; Editor m_LookDevVolumeProfileEditor; + int m_LookDevVolumeProfileHash = -1; SerializedObject m_SettingsSerializedObject; SerializedProperty m_VolumeProfileSerializedProperty; EditorPrefBool m_DefaultVolumeProfileFoldoutExpanded; @@ -51,6 +52,14 @@ namespace UnityEditor.Rendering.HighDefinition Editor GetLookDevDefaultVolumeProfileEditor(VolumeProfile lookDevAsset) { + int currentHash = (lookDevAsset != null) ? lookDevAsset.GetHashCode() : -1; + if (currentHash != m_LookDevVolumeProfileHash) + { + Editor.DestroyImmediate(m_LookDevVolumeProfileEditor); + m_LookDevVolumeProfileEditor = null; + m_LookDevVolumeProfileHash = currentHash; + } + Editor.CreateCachedEditor(lookDevAsset, typeof(VolumeProfileEditor), ref m_LookDevVolumeProfileEditor); return m_LookDevVolumeProfileEditor; } @@ -68,8 +77,12 @@ namespace UnityEditor.Rendering.HighDefinition { tooltip = k_LookDevVolumeProfileAssetLabel.tooltip, objectType = typeof(VolumeProfile), - value = m_VolumeProfileSerializedProperty.objectReferenceValue as VolumeProfile, + style = + { + flexShrink = 1, + } }; + field.BindProperty(m_VolumeProfileSerializedProperty); field.AddToClassList("unity-base-field__aligned"); //Align with other BaseField field.Q