From efd47ee465dcaa29fdacca1ab46b28965b46cdfa Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Fri, 11 Sep 2026 15:40:01 +0000 Subject: [PATCH 001/192] [Port] [6000.7] UUM-151892: Fix TypeInitializationException when opening the Surface Cache GI feature inspector --- .../Editor/RendererFeatures/SurfaceCacheGIEditor.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/SurfaceCacheGIEditor.cs b/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/SurfaceCacheGIEditor.cs index 41150463406..aadf26c27e6 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/SurfaceCacheGIEditor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/SurfaceCacheGIEditor.cs @@ -11,9 +11,12 @@ internal class SurfaceCacheGIEditor : Editor { private const string k_UnsupportedRayTracingBackendMessage = "Surface Cache GI will not run on this device because it does not support hardware ray tracing or compute shaders."; - private static readonly GUIContent s_StaticBatchingError = L10n.TextContentWithIcon(SurfaceCacheGIRendererFeature.k_StaticBatchingErrorMesssage, MessageType.Error, null); - private static readonly GUIContent s_StaticBatchingWarning = L10n.TextContentWithIcon(SurfaceCacheGIRendererFeature.k_StaticBatchingErrorMesssage, MessageType.Warning, null); - private static readonly GUIContent s_OpenButton = L10n.TextContent("Open", null, null, null); + static class Styles + { + public static readonly GUIContent staticBatchingError = L10n.TextContentWithIcon(SurfaceCacheGIRendererFeature.k_StaticBatchingErrorMesssage, MessageType.Error, null); + public static readonly GUIContent staticBatchingWarning = L10n.TextContentWithIcon(SurfaceCacheGIRendererFeature.k_StaticBatchingErrorMesssage, MessageType.Warning, null); + public static readonly GUIContent openButton = L10n.TextContent("Open", null, null, null); + } private static GUIStyle s_FixMeBoxStyle; @@ -62,7 +65,7 @@ public override void OnInspectorGUI() if (PlayerSettings.GetStaticBatchingForPlatform(activeBuildTarget)) { - DrawFixMeBox(surfaceCacheGIRendererFeature.isActive ? s_StaticBatchingError : s_StaticBatchingWarning, s_OpenButton, () => + DrawFixMeBox(surfaceCacheGIRendererFeature.isActive ? Styles.staticBatchingError : Styles.staticBatchingWarning, Styles.openButton, () => PlayerSettingsInspectorUtility.OpenAndScrollTo(PlayerSettingsInspectorUtility.Section.OtherSettings, "Static Batching")); } else if (EditorGraphicsSettings.defaultMeshBufferTarget != DefaultMeshBufferTarget.Raw) From 056f63f6930a511510527f4a0d64b8dbdff4dc65 Mon Sep 17 00:00:00 2001 From: Evergreen Date: Fri, 11 Sep 2026 15:40:02 +0000 Subject: [PATCH 002/192] [UUM-152475] Disable unstable SRP Foundation Playmode test --- .../Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs index c211f70479f..bbf467f831a 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs @@ -217,6 +217,11 @@ public IEnumerator DiffuseMatchesDielectricMaterialModel() } [UnityTest] + [UnityPlatform(exclude = new RuntimePlatform[] { + RuntimePlatform.IPhonePlayer, // Disabled for Instability https://jira.unity3d.com/browse/UUM-152475 + RuntimePlatform.OSXEditor, // Disabled for Instability https://jira.unity3d.com/browse/UUM-152475 + RuntimePlatform.PS4 // Disabled for Instability https://jira.unity3d.com/browse/UUM-152475 + })] public IEnumerator SpecularHighlightsAddToDiffuse() { UseLitQuad(smoothness: 0.5f, specularHighlights: false); From c429b3801a230828c15da802b1f8cf3d7655ded4 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Sat, 12 Sep 2026 20:16:19 +0000 Subject: [PATCH 003/192] [Port] [6000.7] Fix passes never merging once a native pass exceeds the tile storage limit --- .../Runtime/RenderGraph/Compiler/PassesData.cs | 4 ++++ 1 file changed, 4 insertions(+) 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 4bea22cb539..f14b4748143 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 @@ -1110,6 +1110,10 @@ static bool CanMergeBackBufferAndCustomRenderTargets(CompilerContextData context static bool TotalAttachmentsSizeExceedPixelStorageLimit(CompilerContextData contextData, ref NativePassData nativePass, ref FixedAttachmentArray attachmentsToTryAdding) { + // A merge that adds no attachment cannot grow the tile footprint, so it can never exceed the limit + if (attachmentsToTryAdding.size == 0) + return false; + // TODO: We are currently only checking for iOS GPU Family 1 to 3 since the storage size is much more restricted (16 bytes for Family 1 and 32 for Family 2 & 3). // This is temporary. Later on, we should check all iOS GPU Families but also Android (Vulkan) to avoid the same potential restrictions. if (Application.platform == RuntimePlatform.IPhonePlayer && SystemInfo.maxTiledPixelStorageSize <= 32) From 9928fb651c8b89a5417b6532477876d8389e272f Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Sat, 12 Sep 2026 20:16:19 +0000 Subject: [PATCH 004/192] [Port] [6000.7] Fix UUM-151055: serialization warnings are displayed when creating a project using the HDRP template. --- .../Meshes/Props/Nature/Model/Bamboo_A.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Bamboo_B.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Bamboo_C.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Bamboo_D.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Bush_01.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Fern_01.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/LeaveSet.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Plant_C_02.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Plant_C_03.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Rock_A_01.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Rock_A_02.fbx.meta | 4 ++-- .../Meshes/Props/Nature/Model/Rock_A_03.fbx.meta | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_A.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_A.fbx.meta index e1c3da23072..59e4248678c 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_A.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_A.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a93cfaabcbbd9821609b8c58155c00f5d3ad1d78883da6e3ac03ebbfd5cabe7 -size 3667 +oid sha256:9d71a47dc90a6a4fe48fb2a0ef0b8325d81f87b9909c7e44ac8abd7b3733ab95 +size 5168 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_B.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_B.fbx.meta index db265e0e832..b8f7c3222c8 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_B.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_B.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2eca25f078a7bf4d185a8cc2529523d2601fa27e8131fae0c3a55bf98baed578 -size 3462 +oid sha256:eae6d9f8d0fae261e5dec491ac2b3c123081a03038b81579ced701fb618ccebc +size 4935 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_C.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_C.fbx.meta index 91dfa8086a1..6ec2e395208 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_C.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_C.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77135387a8098a38ba7a16f0221e0d890d65bb22624fa5af1e3ac1685ac7fb0f -size 3462 +oid sha256:27e94dd584d7d0d2879be38ef487d41b27fe983f2cc9be9e1987c6c40d7dbe14 +size 4935 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_D.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_D.fbx.meta index 555f596da54..6b093934601 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_D.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bamboo_D.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:853bc8bc84afd9dfd4f1443454479981bfd4a9078add9b22909af0a07fa9e5d6 -size 3462 +oid sha256:31c36b66cce6824a9b9dc72e8d8bf443ccdd94df585ed9ffe9c9d892706cb6e7 +size 4935 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bush_01.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bush_01.fbx.meta index a1f869a8d49..2b0a797d168 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bush_01.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Bush_01.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31c7fc2c64c5bb55c8089e4503fc647cf278da0170dd5c65292fd06f227c0ca9 -size 3110 +oid sha256:6a3dc9956752a17b28223a0f387643939667621fc5f0149dedf87f155ba5f4fe +size 3640 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Fern_01.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Fern_01.fbx.meta index cd33f9769f1..0758ead5809 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Fern_01.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Fern_01.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eee0cf85a25fc40a8c2410248dc2ebffb374e1919bb6867cef04e28ba4181ad8 -size 3114 +oid sha256:cba34fe9614df63dfd1ff83f52f61a916c1a5df6ea0c70695ff27cbfa53bed1a +size 3644 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/LeaveSet.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/LeaveSet.fbx.meta index faa30e2cc9b..674eebc57d3 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/LeaveSet.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/LeaveSet.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea753fbf14c8c6dcd9dd36205e67b48a56fd307c3cbfa92ed32dd76babfb4277 -size 3764 +oid sha256:a5cefec990c3e397b6e54801ac447363c5ce83d470b7d9e1e3377ba6d1c7772b +size 4170 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_02.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_02.fbx.meta index 751cf62b49b..ee2b70cd963 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_02.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_02.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc7524dc9338146279ab09e362fb2db2569a2f4a3751cf459c36283590028a79 -size 3173 +oid sha256:720acc8dbca6b95756190b86346928635c096da60b5868337a74c07949c35256 +size 4505 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_03.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_03.fbx.meta index 95f01aaf64e..01782c338e6 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_03.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Plant_C_03.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44f2a29131726f0705723e49f7e8cadeef38a5a9f2f1a28525a91d6a906c5551 -size 3173 +oid sha256:c5b364aac62643dd44b425e31fbc876df3f3a3961dd8e76120cd9ea51ba61c9d +size 4505 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_01.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_01.fbx.meta index 3016fe9d4a6..92274a7bae8 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_01.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_01.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6120454fead8c690e04ac7dd91bdfdc515bfe6441ef3bf44afaaae706a4fac7d -size 3234 +oid sha256:eaa1625f4d40a3968f79f2f4ba22d26cdbf7aa505e0ca82d5d8d6ac3135f2605 +size 4763 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_02.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_02.fbx.meta index 20e98a9394e..aa6db202725 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_02.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_02.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f39ea9d04f31c95a1085fda003771f2f06c7034f83730ea4f5c6805bd0b82d58 -size 3391 +oid sha256:cd0de091bfcdc1f05513a9ca98faf77768d1471e655efa176946109bba3f6bdf +size 5058 diff --git a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_03.fbx.meta b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_03.fbx.meta index fd6e1ab15dd..b9e622127d0 100644 --- a/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_03.fbx.meta +++ b/Templates/com.unity.template-hd/Assets/SampleSceneAssets/Meshes/Props/Nature/Model/Rock_A_03.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8924a48c62b30f8d5f11755b6cc165588eeea6ce33579534dfb5fd351e0ed846 -size 3270 +oid sha256:7aced54122ab4ef330ba57c7a73fec36d7240e761f0b41b3d0447888483e3f86 +size 4833 From 3f639171693cedcce8ee934644621213a5c7e8a1 Mon Sep 17 00:00:00 2001 From: Evergreen Date: Sat, 12 Sep 2026 20:16:19 +0000 Subject: [PATCH 005/192] [UUM-152664] Disable unstable Materials Playmode test --- .../HDRP_Tests/Assets/GraphicTests/Tests/Materials.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/Materials.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/Materials.cs index 9af9846216e..ca6a6959ff5 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/Materials.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/Materials.cs @@ -6,6 +6,7 @@ using UnityEngine.TestTools.Graphics; using UnityEngine.TestTools.Graphics.Contexts; using UnityEngine.TestTools.Graphics.Platforms; +using UnityEngine.Rendering; namespace UnityEngine.Rendering.HighDefinition.Tests { @@ -82,6 +83,12 @@ public MaterialsTests(GpuResidentDrawerContext grdContext) : base(grdContext) { Architecture.X64 )] [IgnoreGraphicsTest("1806_BatchCount$", "Fails everywhere (seems to be missing CPU markers).")] + [IgnoreGraphicsTest( + "1219_Lit_Light_on_Tesselation", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152664", + RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Vulkan + )] [TestNotSupportedOn( "1227|1805", "Not XR compatible", From 89f1386b6a037787b74a3b9eab8f550c6aeb0652 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 14 Sep 2026 17:05:07 +0000 Subject: [PATCH 006/192] [Port] [6000.7] Graphics XR: Temporal Pixel Synthesis integration --- .../Runtime/XR/XRPass.cs | 34 +++++ .../Runtime/XR/XRSystem.cs | 132 ++++++++++++++++++ ...enderPipelineCameraUI.Rendering.Drawers.cs | 7 + ...alRenderPipelineCameraUI.Rendering.Skin.cs | 2 + .../UniversalRenderPipelineAssetUI.Drawers.cs | 64 ++++++++- .../UniversalRenderPipelineAssetUI.Skin.cs | 2 + .../Runtime/FrameData/UniversalCameraData.cs | 21 ++- .../Runtime/Passes/XRDepthMotionPass.cs | 50 ++++++- .../Runtime/UniversalRenderPipeline.cs | 58 +++++++- 9 files changed, 363 insertions(+), 7 deletions(-) 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 6b4de44c7d3..a491fd28265 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs @@ -24,6 +24,10 @@ public struct XRPassCreateInfo internal bool copyDepth; internal bool hasMotionVectorPass; internal bool spaceWarpRightHandedNDC; + internal bool hasMotionVectorStencil; + internal uint motionVectorStencilValue; + internal uint motionVectorStencilMask; + internal bool isTemporalPixelSynthesisActive; internal bool skipFDMForFinalPasses; internal XRLayoutType xrLayoutType; internal Vector4 uvScales; @@ -131,6 +135,32 @@ public bool supportsFoveatedRendering /// public bool spaceWarpRightHandedNDC { get; private set; } + /// + /// If true, the runtime requests a stencil aspect on the motion-vector target, to be written by the + /// render pipeline and consumed by Temporal Pixel Synthesis. + /// + public bool hasMotionVectorStencil { get; private set; } + + /// + /// Reference stencil value for the Temporal Pixel Synthesis exclusion test. + /// Pixels where (stencilBuffer & motionVectorStencilMask) == motionVectorStencilValue + /// are excluded from temporal pixel synthesis. Constraint: (value & mask) == value. + /// + public uint motionVectorStencilValue { get; private set; } + + /// + /// Bitmask of stencil bits tested by Temporal Pixel Synthesis. Must be non-zero when + /// is true, and must not overlap pipeline-private stencil bits. + /// + public uint motionVectorStencilMask { get; private set; } + + /// + /// True when Temporal Pixel Synthesis is active for this pass. The render pipeline uses this to + /// suppress its own temporal resolve (TAA/STP), jitter, and upscaling, because the compositor + /// becomes the resolver. + /// + public bool isTemporalPixelSynthesisActive { get; private set; } + /// /// When true, the Fragment Density Map (FDM) is not attached to the FinalBlit and UberPost passes. /// Set by platform-specific XR features (e.g., Meta Quest) to allow the GPU driver to use Direct @@ -623,6 +653,10 @@ public void InitBase(XRPassCreateInfo createInfo) motionVectorRenderTargetDesc = createInfo.motionVectorRenderTargetDesc; hasMotionVectorPass = createInfo.hasMotionVectorPass; spaceWarpRightHandedNDC = createInfo.spaceWarpRightHandedNDC; + hasMotionVectorStencil = createInfo.hasMotionVectorStencil; + motionVectorStencilValue = createInfo.motionVectorStencilValue; + motionVectorStencilMask = createInfo.motionVectorStencilMask; + isTemporalPixelSynthesisActive = createInfo.isTemporalPixelSynthesisActive; skipFDMForFinalPasses = createInfo.skipFDMForFinalPasses; m_OcclusionMesh.SetMaterial(createInfo.occlusionMeshMaterial); occlusionMeshScale = createInfo.occlusionMeshScale; 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 13947364f34..acd2b402854 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs @@ -129,6 +129,29 @@ static public XRDisplaySubsystem GetActiveDisplay() [AutoStaticsCleanup] static Action s_LayoutOverride = null; + /// Per-frame Temporal Pixel Synthesis configuration override. + public struct TemporalPixelSynthesisConfig + { + /// TPS active this frame (gates URP TAA/STP/upscaler). + public bool active; + /// Runtime requests a stencil aspect on the motion-vector target. + public bool requestStencil; + /// Stencil reference value: (stencil & mask) == value ⇒ excluded from TPS. + public uint stencilValue; + /// Stencil bitmask tested by TPS (non-zero; must not overlap pipeline-private bits). + public uint stencilMask; + /// Compositor performs upscaling (eye target may be rendered below display res). + public bool upscalingEnabled; + } + + /// + /// Overrides the Temporal Pixel Synthesis contract reported by , for exercising + /// the feature without an XR provider that implements XR_META_temporal_pixel_synthesis. + /// Takes precedence over provider-supplied values while is true. + /// + [AutoStaticsCleanup] + public static TemporalPixelSynthesisConfig temporalPixelSynthesisConfig { get; set; } + /// /// Returns true if a XR device is connected and running. /// @@ -770,8 +793,48 @@ private static RenderTextureDescriptor XrRenderTextureDescToUnityRenderTextureDe return rtDesc; } + // Frame-keyed rather than a bool reset on "TPS inactive": in multi-pass the provider may describe + // pass 0 but not pass 1, and a per-pass reset would put the message back to once per frame. + [AutoStaticsCleanup] + static int s_LastTemporalPixelSynthesisStencilFormatErrorFrame = -1; + static XRPassCreateInfo BuildPass(XRDisplaySubsystem.XRRenderPass xrRenderPass, ScriptableCullingParameters cullingParameters, XRLayout layout, XRLayoutType layoutType, Vector4 uvScales, Vector4 uvOffsets) { + bool temporalPixelSynthesisActive; + uint temporalPixelSynthesisStencilValue; + uint temporalPixelSynthesisStencilMask; + bool temporalPixelSynthesisStencilRequested; + + if (temporalPixelSynthesisConfig.active) + { + temporalPixelSynthesisActive = true; + temporalPixelSynthesisStencilValue = temporalPixelSynthesisConfig.stencilValue; + temporalPixelSynthesisStencilMask = temporalPixelSynthesisConfig.stencilMask; + temporalPixelSynthesisStencilRequested = temporalPixelSynthesisConfig.requestStencil; + } + else + { + temporalPixelSynthesisActive = xrRenderPass.isTemporalPixelSynthesisActive; + temporalPixelSynthesisStencilValue = (uint)xrRenderPass.motionVectorStencilValue; + temporalPixelSynthesisStencilMask = (uint)xrRenderPass.motionVectorStencilMask; + temporalPixelSynthesisStencilRequested = temporalPixelSynthesisActive; + } + + // The 0xFF bound matters because the mask reaches StencilState.writeMask as a byte downstream, + // so e.g. 0x100 would truncate to 0 and silently write no stencil at all. + bool hasMotionVectorStencil = temporalPixelSynthesisActive + && temporalPixelSynthesisStencilRequested + && xrRenderPass.hasMotionVectorPass + && temporalPixelSynthesisStencilMask != 0 + && temporalPixelSynthesisStencilMask <= 0xFF; + + // Don't publish a contract that isn't in force. + if (!hasMotionVectorStencil) + { + temporalPixelSynthesisStencilValue = 0; + temporalPixelSynthesisStencilMask = 0; + } + XRPassCreateInfo passInfo = new XRPassCreateInfo { renderTarget = xrRenderPass.renderTarget, @@ -789,6 +852,10 @@ static XRPassCreateInfo BuildPass(XRDisplaySubsystem.XRRenderPass xrRenderPass, cullingPassId = xrRenderPass.cullingPassIndex, copyDepth = xrRenderPass.shouldFillOutDepth, spaceWarpRightHandedNDC = xrRenderPass.spaceWarpRightHandedNDC, + hasMotionVectorStencil = hasMotionVectorStencil, + motionVectorStencilValue = temporalPixelSynthesisStencilValue, + motionVectorStencilMask = temporalPixelSynthesisStencilMask, + isTemporalPixelSynthesisActive = temporalPixelSynthesisActive, skipFDMForFinalPasses = xrRenderPass.skipFDMForFinalPasses, xrSdkRenderPass = xrRenderPass, xrLayoutType = layoutType, @@ -796,9 +863,74 @@ static XRPassCreateInfo BuildPass(XRDisplaySubsystem.XRRenderPass xrRenderPass, uvOffsets = uvOffsets }; + // The pipeline-private bit-reservation check lives in URP (XRDepthMotionPass) instead, since + // which stencil bits the producer reserves is a URP shader convention. + if (passInfo.hasMotionVectorStencil) + { + Debug.Assert((passInfo.motionVectorStencilValue & passInfo.motionVectorStencilMask) == passInfo.motionVectorStencilValue, + "TPS: motionVectorStencilValue must be a subset of motionVectorStencilMask."); + + if (!GraphicsFormatUtility.IsStencilFormat(passInfo.motionVectorRenderTargetDesc.depthStencilFormat) + && s_LastTemporalPixelSynthesisStencilFormatErrorFrame != Time.frameCount) + { + s_LastTemporalPixelSynthesisStencilFormatErrorFrame = Time.frameCount; + Debug.LogError($"Temporal Pixel Synthesis requested a motion-vector stencil aspect, but the motion-vector depth target format ({passInfo.motionVectorRenderTargetDesc.depthStencilFormat}) has no stencil bits. A stencil-capable format such as D24_UNorm_S8_UInt or D32_SFloat_S8_UInt is required; TPS pixel exclusion will not work."); + } + } + + DebugTraceTemporalPixelSynthesis(in passInfo, xrRenderPass); + return passInfo; } + // Traces what the provider delivers at the boundary where TPS data crosses into SRP. + const bool k_DebugTemporalPixelSynthesis = false; + + // Indexed by multipassId, so the steady-state cost is a struct compare rather than a string per + // pass per frame. + [NoAutoStaticsCleanup] + static readonly (bool active, bool stencil, uint value, uint mask, bool hasMVPass, GraphicsFormat mvDepthFmt)[] s_LastTemporalPixelSynthesisTrace + = new (bool, bool, uint, uint, bool, GraphicsFormat)[kMaxTracedPasses]; + [NoAutoStaticsCleanup] + static readonly bool[] s_TemporalPixelSynthesisTraceLogged = new bool[kMaxTracedPasses]; + const int kMaxTracedPasses = 8; + + static void DebugTraceTemporalPixelSynthesis(in XRPassCreateInfo passInfo, XRDisplaySubsystem.XRRenderPass xrRenderPass) + { +#pragma warning disable 162 // unreachable code when the flag is false + if (!k_DebugTemporalPixelSynthesis) + return; + + int passIndex = passInfo.multipassId; + if (passIndex < 0 || passIndex >= kMaxTracedPasses) + return; + + var state = (passInfo.isTemporalPixelSynthesisActive, + passInfo.hasMotionVectorStencil, + passInfo.motionVectorStencilValue, + passInfo.motionVectorStencilMask, + passInfo.hasMotionVectorPass, + passInfo.motionVectorRenderTargetDesc.depthStencilFormat); + + if (s_TemporalPixelSynthesisTraceLogged[passIndex] && s_LastTemporalPixelSynthesisTrace[passIndex].Equals(state)) + return; + + s_TemporalPixelSynthesisTraceLogged[passIndex] = true; + s_LastTemporalPixelSynthesisTrace[passIndex] = state; + + // raw(...) is pre-override, pre-validation: populated raw with an empty resolved value means + // the contract was dropped here rather than never delivered. + Debug.Log($"[TPS] pass={passIndex} active={passInfo.isTemporalPixelSynthesisActive} " + + $"stencilRequested={passInfo.hasMotionVectorStencil} " + + $"value=0x{passInfo.motionVectorStencilValue:X} mask=0x{passInfo.motionVectorStencilMask:X} " + + $"| hasMVPass={passInfo.hasMotionVectorPass} " + + $"mvDepthFmt={passInfo.motionVectorRenderTargetDesc.depthStencilFormat} " + + $"stencilCapable={GraphicsFormatUtility.IsStencilFormat(passInfo.motionVectorRenderTargetDesc.depthStencilFormat)} " + + $"| raw(active={xrRenderPass.isTemporalPixelSynthesisActive} value={xrRenderPass.motionVectorStencilValue} mask={xrRenderPass.motionVectorStencilMask}) " + + $"configOverride={temporalPixelSynthesisConfig.active}"); +#pragma warning restore 162 + } + #endif } } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs index 01a20705521..2740c3c6471 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs @@ -41,6 +41,12 @@ public partial class Rendering (serialized, owner) => !serialized.renderPostProcessing.boolValue && (AntialiasingMode)serialized.antialiasing.intValue != AntialiasingMode.None, (serialized, owner) => EditorGUILayout.HelpBox(Styles.disabledPostprocessingAntiAliasWarning, MessageType.Warning)); + private static readonly CED.IDrawer XRAntialiasingInfoDrawer = CED.Conditional( + (serialized, owner) => UniversalRenderPipelineAssetUI.IsAndroidXRTargetted() + && (AntialiasingMode)serialized.antialiasing.intValue != AntialiasingMode.None, + (serialized, owner) => UniversalRenderPipelineAssetUI.DrawXRProjectValidationInfoBox( + Styles.xrAntialiasingInfo, Styles.xrAntialiasingInfoButton)); + private static readonly CED.IDrawer MSAAWarningDrawer = CED.Conditional( (serialized, owner) => (GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset asset && asset.msaaSampleCount > 1) && serialized.baseCameraSettings.allowMSAA.boolValue == true && (AntialiasingMode)serialized.antialiasing.intValue == AntialiasingMode.TemporalAntiAliasing, (serialized, owner) => EditorGUILayout.HelpBox(Styles.MSAAWarning, MessageType.Warning)); @@ -73,6 +79,7 @@ public partial class Rendering PostProcessingAAWarningDrawer, DisabledPostProcessingAAWarningDrawer, MSAAWarningDrawer, + XRAntialiasingInfoDrawer, CED.Conditional( (serialized, owner) => !serialized.antialiasing.hasMultipleDifferentValues, CED.Group( diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs index bb21f3b4852..eb2c6673ccb 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Skin.cs @@ -10,6 +10,8 @@ public class Styles { public static GUIContent rendererType = L10n.TextContent("Renderer", "The series of operations that translates code into visuals. These have different capabilities and performance characteristics.", null, null); + public static readonly string xrAntialiasingInfo = L10n.Tr("When targeting an XR device, the XR runtime or compositor may provide anti-aliasing. In that case this camera's anti-aliasing can be redundant or ignored - review your XR provider settings to configure anti-aliasing.", null); + public static readonly string xrAntialiasingInfoButton = L10n.Tr("Open Project Validation", null); public static GUIContent renderPostProcessing = L10n.TextContent("Post Processing", "Enable this to make this camera render post-processing effects.", null, null); public static GUIContent antialiasing = L10n.TextContent("Anti-aliasing", "The method the camera uses to smooth jagged edges.", null, null); public static GUIContent antialiasingQuality = L10n.TextContent("Quality", "The quality level to use for the selected anti-aliasing method.", null, null); 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 9365364b206..aeb238e22d9 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 @@ -277,7 +277,50 @@ static void DrawRenderingAdditional(SerializedUniversalRenderPipelineAsset seria EditorGUILayout.PropertyField(serialized.storeActionsOptimizationProperty, Styles.storeActionsOptimizationText); } - static bool IsAndroidXRTargetted() //Include Quest platform + internal const string k_XRProjectValidationSettingsPath = "Project/XR Plug-in Management/Project Validation"; + + // Built lazily: EditorStyles is not available during static initialization. + static GUIStyle s_XRInfoLabelStyle; + + // Hand-laid-out because CoreEditorUtils.DrawFixMeBox places the button inline and overlaps the text + // once it wraps. + internal static void DrawXRProjectValidationInfoBox(string message, string buttonLabel) + { + s_XRInfoLabelStyle ??= new GUIStyle(EditorStyles.label) { wordWrap = true }; + + using (new EditorGUILayout.HorizontalScope()) + { + // Reserved outside the box so it aligns with other help boxes, then zeroed so the contents + // position relative to the box rather than the inspector. + float indent = EditorGUI.indentLevel * 15f - EditorStyles.helpBox.margin.left; + if (indent > 0f) + GUILayoutUtility.GetRect(indent, EditorGUIUtility.singleLineHeight, GUILayout.ExpandWidth(false)); + + int oldIndent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) + { + using (new EditorGUILayout.HorizontalScope()) + { + GUILayout.Label(EditorGUIUtility.IconContent("console.infoicon"), + GUILayout.Width(32f), GUILayout.Height(32f)); + GUILayout.Label(message, s_XRInfoLabelStyle); + } + + using (new EditorGUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + if (GUILayout.Button(buttonLabel, EditorStyles.miniButton)) + SettingsService.OpenProjectSettings(k_XRProjectValidationSettingsPath); + } + } + + EditorGUI.indentLevel = oldIndent; + } + } + + internal static bool IsAndroidXRTargetted() //Include Quest platform { #if XR_MANAGEMENT_4_0_1_OR_NEWER var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); @@ -389,6 +432,25 @@ static void DrawQuality(SerializedUniversalRenderPipelineAsset serialized, Edito { EditorGUILayout.HelpBox("Camera depth isn't supported when Upscaling is turned on in the game view. We will automatically fall back to not doing depth-testing for this pass when upscaling is applied.", MessageType.Warning, true); } + + if (IsAndroidXRTargetted() && upscalingSelected) + { + DrawXRProjectValidationInfoBox(Styles.xrUpscalingInfo, Styles.xrUpscalingInfoButton); + } + + EditorGUILayout.PropertyField(serialized.enableLODCrossFadeProp, Styles.enableLODCrossFadeText); + EditorGUI.BeginDisabledGroup(!serialized.enableLODCrossFadeProp.boolValue); + EditorGUILayout.PropertyField(serialized.lodCrossFadeDitheringTypeProp, Styles.lodCrossFadeDitheringTypeText); + if (serialized.asset.enableLODCrossFade && serialized.asset.lodCrossFadeDitheringType == LODCrossFadeDitheringType.Stencil) + { + var rendererData = serialized.asset.m_RendererDataList[serialized.asset.m_DefaultRendererIndex]; + if (rendererData is UniversalRendererData && ((UniversalRendererData)rendererData).defaultStencilState.overrideStencilState) + { + EditorGUILayout.HelpBox(Styles.stencilLodCrossFadeWarningMessage.text, MessageType.Warning, true); + } + } + + EditorGUI.EndDisabledGroup(); } static void DrawUpscalerListAndOptions(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs index 96820ff581e..570672ab2c4 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs @@ -41,6 +41,8 @@ internal static class Styles public static GUIContent enableLODCrossFadeText = L10n.TextContent("LOD Cross Fade", "Controls whether LOD Cross Fade enabled or disabled.", null, null); public static GUIContent lodCrossFadeDitheringTypeText = L10n.TextContent("LOD Cross Fade Dithering Type", "Controls the LOD Cross Fade Dithering Type that will be used to draw Renderer LOD when LODGroup has CrossFade Fade Mode selected.", null, null); public static GUIContent shEvalModeText = L10n.TextContent("SH Evaluation Mode", "Defines the Spherical Harmonic (SH) lighting evaluation type (per vertex, per pixel, or mixed).", null, null); + public static readonly string xrUpscalingInfo = L10n.Tr("When targeting an XR device, the XR runtime or compositor may provide anti-aliasing and upscaling. In that case this URP upscaler can be redundant or ignored - review your XR provider settings to configure anti-aliasing and upscaling.", null); + public static readonly string xrUpscalingInfoButton = L10n.Tr("Open Project Validation", null); public static GUIContent lightFalloffModeText = L10n.TextContent("Light Falloff Mode", "How light intensity falls off with distance. Use Linear to match the Built-in Render Pipeline.", null, null); public static readonly string stpMobilePlatformWarning = L10n.Tr("STP is selected for use on a mobile platform. STP is only supported on modern compute-capable hardware and its performance overhead may make it impractical on lower-end devices.", null); #if ENABLE_UPSCALER_FRAMEWORK diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs index 48f6eed9f91..2f279aaa797 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs @@ -418,7 +418,10 @@ public bool IsHandleYFlipped(RTHandle handle) bool isBackbuffer = handleID == BuiltinRenderTextureType.CameraTarget || handleID == BuiltinRenderTextureType.Depth; #if ENABLE_VR && ENABLE_XR_MODULE if (xr.enabled) + { isBackbuffer |= handleID == new RenderTargetIdentifier(xr.renderTarget, 0, CubemapFace.Unknown, 0); + isBackbuffer |= handleID == new RenderTargetIdentifier(xr.motionVectorRenderTarget, 0, CubemapFace.Unknown, 0); + } #endif return !isBackbuffer; } @@ -450,6 +453,21 @@ internal bool IsTemporalAARequested() return antialiasing == AntialiasingMode.TemporalAntiAliasing; } + /// + /// Returns true when Meta Temporal Pixel Synthesis is the active resolver for this camera. + /// When true, the compositor performs the temporal resolve and any upscaling, so URP must suppress + /// its own TAA/STP resolve, its jitter, and its spatial upscalers. + /// + /// True if Temporal Pixel Synthesis is active + internal bool IsTemporalPixelSynthesisActive() + { +#if ENABLE_VR && ENABLE_XR_MODULE + return xr.enabled && xr.isTemporalPixelSynthesisActive; +#else + return false; +#endif + } + /// /// Returns true if the pipeline and the given camera are configured to render with temporal anti-aliasing post processing enabled /// @@ -467,7 +485,8 @@ internal bool IsTemporalAAEnabled() && (cameraTargetDescriptor.msaaSamples == 1) // No MSAA && !(additionalCameraData?.renderType == CameraRenderType.Overlay || additionalCameraData?.cameraStack.Count > 0) // No Camera stack && !camera.allowDynamicResolution // No Dynamic Resolution - && renderer.SupportsMotionVectors(); // Motion Vectors implemented + && renderer.SupportsMotionVectors() // Motion Vectors implemented + && !IsTemporalPixelSynthesisActive(); // XR compositor is the resolver (also disables jitter via CalculateJitterMatrix) } /// diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs index 85ee2bfe4f2..5e5772472e9 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs @@ -15,6 +15,9 @@ public class XRDepthMotionPass : ScriptableRenderPass private LocalKeyword m_SubsampleDepthKeyword; private static readonly ShaderTagId k_MotionOnlyShaderTagId = new ShaderTagId(k_MotionOnlyShaderTagIdName); private static readonly int k_SpaceWarpNDCModifier = Shader.PropertyToID("_SpaceWarpNDCModifier"); + // Stencil bit the object-motion passes use as the "has object motion" marker. Kept in sync with + // ObjectMotionVectorFallback and the material XRMotionVectors passes (WriteMask 1, Ref 1). + private const uint k_ObjectMotionMarkerMask = 0x1; private static readonly int k_XRDepthTextureUVScale = Shader.PropertyToID("_XRDepthTextureUVScale"); private RTHandle m_XRMotionVectorColor; private TextureHandle xrMotionVectorColor; @@ -94,14 +97,36 @@ private void InitObjectMotionRendererLists(ref PassData passData, ref CullingRes RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, objectMotionDrawingSettings, filteringSettings, renderStateBlock, ref passData.objMotionRendererList); } - private void InitTransparentObjectMotionRendererLists(ref PassData passData, ref CullingResults cullResults, RenderGraph renderGraph, Camera camera) + + private void InitTransparentObjectMotionRendererLists(ref PassData passData, ref CullingResults cullResults, RenderGraph renderGraph, UniversalCameraData cameraData) { + var camera = cameraData.camera; var objectMotionDrawingSettings = GetObjectMotionDrawingSettings(camera, true); var filteringSettings = new FilteringSettings(RenderQueueRange.transparent, m_transparentlayerMask); filteringSettings.forceAllMotionVectorObjects = true; // this is required because generally, transparent objects/ui don't usually write depth var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing); + // Stamp the runtime-supplied exclude pattern on transparent draws so the compositor skips + // temporal reuse on them, which is what prevents transparency and particle ghosting. + if (cameraData.xr.hasMotionVectorStencil && cameraData.xr.motionVectorStencilMask != 0) + { + uint excludeMask = cameraData.xr.motionVectorStencilMask; + uint excludeValue = cameraData.xr.motionVectorStencilValue; + renderStateBlock = new RenderStateBlock(RenderStateMask.Stencil) + { + stencilReference = (int)excludeValue, + stencilState = new StencilState( + enabled: true, + readMask: 0xFF, + writeMask: (byte)excludeMask, + compareFunction: CompareFunction.Always, + passOperation: StencilOp.Replace, + failOperation: StencilOp.Keep, + zFailOperation: StencilOp.Keep) + }; + } + RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, objectMotionDrawingSettings, filteringSettings, renderStateBlock, ref passData.objTransparentMotionRendererList); } @@ -179,11 +204,13 @@ private void ImportXRMotionColorAndDepth(RenderGraph renderGraph, UniversalCamer importMotionColorParams.clearOnFirstUse = true; importMotionColorParams.clearColor = Color.black; importMotionColorParams.discardOnLastUse = false; + importMotionColorParams.textureUVOrigin = TextureUVOrigin.TopLeft; ImportResourceParams importMotionDepthParams = new ImportResourceParams(); importMotionDepthParams.clearOnFirstUse = true; importMotionDepthParams.clearColor = Color.black; importMotionDepthParams.discardOnLastUse = false; + importMotionDepthParams.textureUVOrigin = TextureUVOrigin.TopLeft; xrMotionVectorColor = renderGraph.ImportTexture(m_XRMotionVectorColor, importInfo, importMotionColorParams); xrMotionVectorDepth = renderGraph.ImportTexture(m_XRMotionVectorDepth, importInfoDepth, importMotionDepthParams); @@ -212,6 +239,18 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) return; } + // The runtime owns the exclude mask but cannot know which bits URP's shaders reserve, so the + // overlap check has to happen on this side. + if (cameraData.xr.hasMotionVectorStencil) + { + Debug.Assert((cameraData.xr.motionVectorStencilMask & k_ObjectMotionMarkerMask) == 0, + $"TPS exclude mask 0x{cameraData.xr.motionVectorStencilMask:X} overlaps URP's object-motion " + + "marker bit (bit 0); moving opaque geometry would be wrongly excluded from temporal reuse."); + + Debug.Assert(cameraData.xr.motionVectorStencilMask <= 0xFF, + $"TPS exclude mask 0x{cameraData.xr.motionVectorStencilMask:X} does not fit in an 8-bit stencil buffer."); + } + // First, import XR motion color and depth targets into the RenderGraph ImportXRMotionColorAndDepth(renderGraph, cameraData); @@ -233,8 +272,11 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) builder.SetRenderAttachment(xrMotionVectorColor, 0, AccessFlags.Write); builder.SetRenderAttachmentDepth(xrMotionVectorDepth, AccessFlags.ReadWrite); - // Logic to detect if we already has valid XR depth data in the eye texture depth attachment - bool hasValidXRDepth = cameraData.xr.copyDepth; + // TEMP WORKAROUND - forced false under TPS to avoid the UseTexture(backBufferDepth, Read) + // below, which forces textureUVOrigin = BottomLeft under Tile-Only Mode and flips the frame. + // Costs a full object draw instead of moving objects only, so TPS profiling numbers taken + // here are not representative. Drop the condition once UV-origin ownership is resolved. + bool hasValidXRDepth = cameraData.xr.copyDepth && !cameraData.xr.isTemporalPixelSynthesisActive; // In case we don't have valid depth, setup the renderer list to draw both static objects and moving objects to populate color+depth at the same time. bool forceAllMotionVectorObjects = !hasValidXRDepth; @@ -242,7 +284,7 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) // Setup RendererList InitObjectMotionRendererLists(ref passData, ref renderingData.cullResults, renderGraph, cameraData.camera, forceAllMotionVectorObjects); builder.UseRendererList(passData.objMotionRendererList); - InitTransparentObjectMotionRendererLists(ref passData, ref renderingData.cullResults, renderGraph, cameraData.camera); + InitTransparentObjectMotionRendererLists(ref passData, ref renderingData.cullResults, renderGraph, cameraData); builder.UseRendererList(passData.objTransparentMotionRendererList); // Allow setting up global matrix array diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 8c8e199f559..f4e490c8891 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -1559,6 +1559,60 @@ static void UpdateCameraData(UniversalCameraData baseCameraData, in XRPass xr) // If upscaling is active, set the scaled width and height baseCameraData.scaledWidth = Mathf.Max(1, (int)(baseCameraData.pixelWidth * baseCameraData.renderScale)); baseCameraData.scaledHeight = Mathf.Max(1, (int)(baseCameraData.pixelHeight * baseCameraData.renderScale)); + + ApplyTemporalPixelSynthesisOverrides(baseCameraData); + } + + // Frame-keyed rather than bools: this runs once per XR pass and once per stacked overlay camera, and + // any one of those can see TPS inactive, so a bool reset on "inactive" would spam every frame. + [AutoStaticsCleanup] static int s_LastTemporalPixelSynthesisSuppressedTAAFrame = -1; + [AutoStaticsCleanup] static int s_LastTemporalPixelSynthesisSuppressedUpscalerFrame = -1; + + /// + /// Reports what Temporal Pixel Synthesis suppressed, and neutralises the legacy upscaling filter. + /// TAA and STP are suppressed in , and the + /// upscaler framework in CreatePostProcessingData. + /// + static void ApplyTemporalPixelSynthesisOverrides(UniversalCameraData cameraData) + { + if (!cameraData.IsTemporalPixelSynthesisActive()) + return; + + if (cameraData.IsTemporalAARequested() + && !cameraData.IsSTPRequested() + && s_LastTemporalPixelSynthesisSuppressedTAAFrame != Time.frameCount) + { + s_LastTemporalPixelSynthesisSuppressedTAAFrame = Time.frameCount; + Debug.LogWarning("URP Temporal Anti-aliasing is disabled: Meta Temporal Pixel Synthesis is the active resolver on this XR device. " + + "The compositor performs the temporal resolve, and URP must not apply its own jitter. Set Anti-aliasing to None on the camera to silence this message."); + } + +#if ENABLE_UPSCALER_FRAMEWORK + bool spatialUpscalerActive = cameraData.resolvedUpscalerHash != k_UpscalerHash_Linear + && cameraData.resolvedUpscalerHash != k_UpscalerHash_Point + && cameraData.imageScalingMode == ImageScalingMode.Upscaling; + + if (spatialUpscalerActive && s_LastTemporalPixelSynthesisSuppressedUpscalerFrame != Time.frameCount) + { + s_LastTemporalPixelSynthesisSuppressedUpscalerFrame = Time.frameCount; + Debug.LogWarning($"URP upscaler '{upscaling?.activeUpscaler?.name ?? string.Empty}' is disabled: Meta Temporal Pixel Synthesis is the active resolver on this XR device and the compositor performs anti-aliasing and upscaling. " + + "URP has fallen back to a bilinear resolve for the render scale. Set the URP Asset's upscaling filter to Automatic to silence this message."); + } +#else + // upscalingFilter is the single per-camera source of truth here, so it is safe to neutralise. + if (cameraData.upscalingFilter == ImageUpscalingFilter.FSR || cameraData.upscalingFilter == ImageUpscalingFilter.STP) + { + var suppressed = cameraData.upscalingFilter; + cameraData.upscalingFilter = ImageUpscalingFilter.Linear; + + if (s_LastTemporalPixelSynthesisSuppressedUpscalerFrame != Time.frameCount) + { + s_LastTemporalPixelSynthesisSuppressedUpscalerFrame = Time.frameCount; + Debug.LogWarning($"URP upscaling filter '{suppressed}' is disabled: Meta Temporal Pixel Synthesis is the active resolver on this XR device and the compositor performs anti-aliasing and upscaling. " + + "URP has fallen back to bilinear filtering for the render-scale resolve. Set the URP Asset's upscaling filter to Automatic to silence this message."); + } + } +#endif } static void UpdateOffscreenUIRendering(UniversalCameraData cameraData, bool finalOutputHDR) @@ -2020,6 +2074,7 @@ static void InitializeStackedCameraData(Camera baseCamera, UniversalAdditionalCa cameraData.xr = XRSystem.emptyPass; var renderScaleXR = cameraData.renderScale; + XRSystem.SetRenderScale(renderScaleXR); var commonOpaqueFlags = SortingCriteria.CommonOpaque; @@ -2404,7 +2459,8 @@ static UniversalPostProcessingData CreatePostProcessingData(ContextContainer fra postProcessingData.supportDataDrivenLensFlare = settings.supportDataDrivenLensFlare; #if ENABLE_UPSCALER_FRAMEWORK - postProcessingData.activeUpscaler = upscaling.activeUpscaler; + // Disable upscaler when TPS is active + postProcessingData.activeUpscaler = cameraData.IsTemporalPixelSynthesisActive() ? null : upscaling.activeUpscaler; postProcessingData.activeUpscalerIsEmbedded = upscaling.activeUpscalerIsEmbedded; #endif From 32054e6590edfa00240505a03e42370da92d85a2 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 14 Sep 2026 17:05:07 +0000 Subject: [PATCH 007/192] [Port] [6000.7] [URP] [SRP-919] Dynamic keyword refactor --- .../Lighting/ProbeVolume/ProbeVolume.hlsl | 8 +- .../ShaderLibrary/Macros.hlsl | 9 +- .../ShaderLibrary/UnityInstancing.hlsl | 6 +- .../Editor/Decal/DecalPass.template | 5 +- .../Includes/DepthNormalsOnlyPass.hlsl | 6 +- .../ShaderGraph/Includes/DepthOnlyPass.hlsl | 6 +- .../Includes/MotionVectorPass.hlsl | 4 +- .../ShaderGraph/Includes/PBRForwardPass.hlsl | 74 +-- .../ShaderGraph/Includes/PBRGBufferPass.hlsl | 59 +- .../ShaderGraph/Includes/ShaderPassDecal.hlsl | 22 +- .../Includes/ShadowCasterPass.hlsl | 6 +- .../Includes/SixWayForwardPass.hlsl | 26 +- .../Includes/Terrain/PBRForwardPass.hlsl | 40 +- .../Includes/Terrain/PBRGBufferPass.hlsl | 40 +- .../Includes/UnlitGBufferPass.hlsl | 17 +- .../ShaderGraph/Includes/UnlitPass.hlsl | 23 +- .../Editor/ShaderGraph/Includes/Varyings.hlsl | 8 +- .../Includes/VolumetricFogBlendMode.hlsl | 42 ++ .../Includes/VolumetricFogBlendMode.hlsl.meta | 5 +- .../Targets/UniversalDecalSubTarget.cs | 1 - .../ShaderGraph/Targets/UniversalTarget.cs | 25 +- .../Targets/UniversalTerrainLitSubTarget.cs | 1 - .../Targets/UniversalUnlitSubTarget.cs | 5 +- .../ShaderGraph/UniversalStructFields.cs | 8 +- .../VFXAbstractParticleURPLitOutput.cs | 4 +- ...niversalRenderPipelineAssetPrefiltering.cs | 3 +- .../Shaders/VFXCommon.deprecated.hlsl | 33 + .../Shaders/VFXCommon.deprecated.hlsl.meta | 5 +- .../Runtime/VFXGraph/Shaders/VFXCommon.hlsl | 27 +- .../Runtime/VFXGraph/Shaders/VFXDefines.hlsl | 7 +- .../Runtime/VFXGraph/Shaders/VFXLit.hlsl | 11 +- .../VFXGraph/Shaders/VFXLitPixelOutput.hlsl | 12 +- .../AmbientOcclusion.deprecated.hlsl | 53 ++ .../AmbientOcclusion.deprecated.hlsl.meta | 7 + .../ShaderLibrary/AmbientOcclusion.hlsl | 47 +- .../ShaderLibrary/AmbientOcclusionFactor.hlsl | 10 + .../AmbientOcclusionFactor.hlsl.meta | 7 + .../ShaderLibrary/BRDF.deprecated.hlsl | 139 +++++ .../ShaderLibrary/BRDF.deprecated.hlsl.meta | 7 + .../ShaderLibrary/BRDF.hlsl | 147 ++--- .../ShaderLibrary/BRDFData.hlsl | 21 + .../ShaderLibrary/BRDFData.hlsl.meta | 7 + .../ShaderLibrary/Core.hlsl | 2 + .../ShaderLibrary/DBuffer.deprecated.hlsl | 70 +++ .../DBuffer.deprecated.hlsl.meta | 7 + .../ShaderLibrary/DBuffer.hlsl | 104 ++-- .../Debug/Debugging3D.deprecated.hlsl | 40 ++ .../Debug/Debugging3D.deprecated.hlsl.meta | 7 + .../ShaderLibrary/Debug/Debugging3D.hlsl | 55 +- .../ShaderLibrary/DistanceFog.hlsl | 13 +- .../ShaderLibrary/GBufferCommon.hlsl | 7 +- .../ShaderLibrary/GBufferFragOutput.hlsl | 33 + .../ShaderLibrary/GBufferFragOutput.hlsl.meta | 7 + .../ShaderLibrary/GBufferInput.hlsl | 7 +- .../GBufferOutput.deprecated.hlsl | 74 +++ .../GBufferOutput.deprecated.hlsl.meta | 7 + .../ShaderLibrary/GBufferOutput.hlsl | 93 ++- .../GlobalIllumination.deprecated.hlsl | 136 +++++ .../GlobalIllumination.deprecated.hlsl.meta | 7 + .../ShaderLibrary/GlobalIllumination.hlsl | 578 ++++++++++-------- .../ShaderLibrary/LODCrossFade.hlsl | 21 +- .../ShaderLibrary/Light.hlsl | 14 + .../ShaderLibrary/Light.hlsl.meta | 7 + .../LightCookie/LightCookie.hlsl | 22 +- .../ShaderLibrary/Lighting.deprecated.hlsl | 309 ++++++++++ .../Lighting.deprecated.hlsl.meta | 7 + .../ShaderLibrary/Lighting.hlsl | 292 +++------ .../ShaderLibrary/Lightmaps.hlsl | 219 +++++++ .../ShaderLibrary/Lightmaps.hlsl.meta | 7 + .../ObjectMotionVectors.deprecated.hlsl | 119 ++++ .../ObjectMotionVectors.deprecated.hlsl.meta | 7 + .../ShaderLibrary/ObjectMotionVectors.hlsl | 120 +--- .../ObjectMotionVectors.hlsl.meta | 2 +- .../ShaderLibrary/PackNormalsTexture.hlsl | 32 +- .../ShaderLibrary/Particles.deprecated.hlsl | 89 +++ .../Particles.deprecated.hlsl.meta | 7 + .../ShaderLibrary/Particles.hlsl | 174 +----- .../ParticlesInstancing.deprecated.hlsl | 1 + .../ParticlesInstancing.deprecated.hlsl.meta | 7 + .../ShaderLibrary/ParticlesInstancing.hlsl | 98 +-- .../RealtimeLights.deprecated.hlsl | 79 +++ .../RealtimeLights.deprecated.hlsl.meta | 7 + .../ShaderLibrary/RealtimeLights.hlsl | 90 ++- .../ShaderLibrary/ShaderGraphFunctions.hlsl | 27 +- .../ShaderVariablesFunctions.deprecated.hlsl | 80 +++ .../ShaderVariablesFunctions.hlsl | 53 +- .../ShaderLibrary/ShadowSamplingData.hlsl | 12 + .../ShadowSamplingData.hlsl.meta | 7 + .../ShaderLibrary/Shadows.deprecated.hlsl | 164 +++++ .../ShaderLibrary/Shadows.hlsl | 537 +++++++++++----- .../ShaderLibrary/SixWayLighting.hlsl | 69 +-- .../SurfaceInput.deprecated.hlsl | 19 + .../SurfaceInput.deprecated.hlsl.meta | 7 + .../ShaderLibrary/SurfaceInput.hlsl | 63 +- .../SurfaceInputFunctions.deprecated.hlsl | 115 ++++ ...SurfaceInputFunctions.deprecated.hlsl.meta | 7 + .../ShaderLibrary/VolumetricFog.hlsl | 25 +- .../Shaders/2D/Include/Lit2DCommon.hlsl | 3 +- .../Shaders/BakedLit.shader | 4 +- .../Shaders/BakedLitDepthNormalsPass.hlsl | 41 +- .../Shaders/BakedLitFeatures.hlsl | 9 + .../Shaders/BakedLitFeatures.hlsl.meta | 7 + .../Shaders/BakedLitForwardPass.hlsl | 105 ++-- .../Shaders/BakedLitGBufferPass.hlsl | 129 ++-- .../Shaders/BakedLitInput.hlsl | 16 +- .../Shaders/ComplexLit.shader | 18 +- .../Shaders/DepthNormalsPass.hlsl | 19 +- .../Shaders/DepthOnlyPass.hlsl | 24 +- .../Shaders/Lit.shader | 15 +- .../Shaders/LitDepthNormalsPass.hlsl | 90 +-- .../Shaders/LitFeatures.hlsl | 16 + .../Shaders/LitFeatures.hlsl.meta | 7 + .../Shaders/LitForwardPass.hlsl | 169 +++-- .../Shaders/LitGBufferPass.hlsl | 150 +++-- .../Shaders/LitInput.deprecated.hlsl | 14 + .../Shaders/LitInput.deprecated.hlsl.meta | 7 + .../Shaders/LitInput.hlsl | 233 +++---- .../Shaders/LitMetaPass.hlsl | 4 +- .../Shaders/Nature/SpeedTree7.shader | 5 +- .../Shaders/Nature/SpeedTree7Billboard.shader | 5 +- .../Nature/SpeedTree7BillboardPasses.hlsl | 55 +- .../Shaders/Nature/SpeedTree7CommonInput.hlsl | 13 +- .../Nature/SpeedTree7CommonPasses.hlsl | 122 ++-- .../Shaders/Nature/SpeedTree7Passes.hlsl | 27 +- .../Shaders/Nature/SpeedTree8.shader | 7 +- .../Shaders/Nature/SpeedTree8Input.hlsl | 13 +- .../Shaders/Nature/SpeedTree8Passes.hlsl | 146 ++--- .../Shaders/ObjectMotionVectorFallback.shader | 4 +- .../Shaders/Particles/ParticleParams.hlsl | 14 + .../Particles/ParticleParams.hlsl.meta | 7 + .../Shaders/Particles/Particles.hlsl | 175 ++++++ .../Shaders/Particles/Particles.hlsl.meta | 7 + .../Particles/ParticlesDepthNormalsPass.hlsl | 37 +- .../Particles/ParticlesEditorPass.hlsl | 2 +- .../Shaders/Particles/ParticlesInput.hlsl | 11 +- .../Particles/ParticlesInstancing.hlsl | 97 +++ .../Particles/ParticlesInstancing.hlsl.meta | 7 + .../Shaders/Particles/ParticlesLit.shader | 9 +- .../Particles/ParticlesLitFeatures.hlsl | 14 + .../Particles/ParticlesLitFeatures.hlsl.meta | 7 + .../Particles/ParticlesLitForwardPass.hlsl | 53 +- .../Particles/ParticlesLitGbufferPass.hlsl | 73 ++- .../ParticlesLitInput.deprecated.hlsl | 118 ++++ .../ParticlesLitInput.deprecated.hlsl.meta | 7 + .../Shaders/Particles/ParticlesLitInput.hlsl | 87 +-- .../Particles/ParticlesSimpleLit.shader | 7 +- .../Particles/ParticlesSimpleLitFeatures.hlsl | 12 + .../ParticlesSimpleLitFeatures.hlsl.meta | 7 + .../ParticlesSimpleLitForwardPass.hlsl | 70 ++- .../ParticlesSimpleLitGBufferPass.hlsl | 68 ++- .../ParticlesSimpleLitInput.deprecated.hlsl | 104 ++++ ...rticlesSimpleLitInput.deprecated.hlsl.meta | 7 + .../Particles/ParticlesSimpleLitInput.hlsl | 62 +- .../Particles/ParticlesUnlitFeatures.hlsl | 9 + .../ParticlesUnlitFeatures.hlsl.meta | 7 + .../Particles/ParticlesUnlitForwardPass.hlsl | 46 +- .../ParticlesUnlitInput.deprecated.hlsl | 58 ++ .../ParticlesUnlitInput.deprecated.hlsl.meta | 7 + .../Particles/ParticlesUnlitInput.hlsl | 39 +- .../Shaders/ShadowCasterPass.hlsl | 13 +- .../Shaders/SimpleLit.shader | 18 +- .../Shaders/SimpleLitDepthNormalsPass.hlsl | 34 +- .../Shaders/SimpleLitFeatures.hlsl | 12 + .../Shaders/SimpleLitFeatures.hlsl.meta | 7 + .../Shaders/SimpleLitForwardPass.hlsl | 143 +++-- .../Shaders/SimpleLitGBufferPass.hlsl | 135 ++-- .../Shaders/SimpleLitInput.deprecated.hlsl | 130 ++++ .../SimpleLitInput.deprecated.hlsl.meta | 7 + .../Shaders/SimpleLitInput.hlsl | 52 +- .../Shaders/SimpleLitMetaPass.hlsl | 5 +- .../Shaders/Terrain/TerrainDetailLit.shader | 87 ++- .../Terrain/TerrainDetailLitPasses.hlsl | 85 ++- .../Shaders/Terrain/TerrainLit.shader | 7 +- .../Shaders/Terrain/TerrainLitAdd.shader | 7 +- .../Shaders/Terrain/TerrainLitBase.shader | 7 +- .../Terrain/TerrainLitDepthNormalsPass.hlsl | 44 +- .../Shaders/Terrain/TerrainLitFeatures.hlsl | 15 + .../Terrain/TerrainLitFeatures.hlsl.meta | 7 + .../Shaders/Terrain/TerrainLitInput.hlsl | 18 +- .../Shaders/Terrain/TerrainLitPasses.hlsl | 146 ++--- .../Shaders/Terrain/WavingGrass.shader | 5 +- .../Terrain/WavingGrassBillboard.shader | 5 +- .../Terrain/WavingGrassDepthNormalsPass.hlsl | 9 +- .../Shaders/Terrain/WavingGrassFeatures.hlsl | 13 + .../Terrain/WavingGrassFeatures.hlsl.meta | 7 + .../Shaders/Terrain/WavingGrassInput.hlsl | 5 +- .../Shaders/Terrain/WavingGrassPasses.hlsl | 100 +-- .../Shaders/Unlit.shader | 4 +- .../Shaders/UnlitDepthNormalsPass.hlsl | 15 +- .../Shaders/UnlitFeatures.hlsl | 11 + .../Shaders/UnlitFeatures.hlsl.meta | 7 + .../Shaders/UnlitForwardPass.hlsl | 32 +- .../Shaders/UnlitGBufferPass.hlsl | 28 +- .../Shaders/UnlitInput.hlsl | 10 +- .../Shaders/UnlitMetaPass.hlsl | 2 +- .../Shaders/Utils/AlphaBlend.hlsl | 62 ++ .../Shaders/Utils/AlphaBlend.hlsl.meta | 7 + .../Shaders/Utils/ClearCoat.hlsl | 81 +++ .../Shaders/Utils/ClearCoat.hlsl.meta | 7 + .../Shaders/Utils/ClusterDeferred.hlsl | 38 +- .../Shaders/Utils/ClusterDeferred.shader | 10 +- .../Shaders/Utils/DetailMap.hlsl | 137 +++++ .../Shaders/Utils/DetailMap.hlsl.meta | 3 + .../Shaders/Utils/Emission.hlsl | 52 ++ .../Shaders/Utils/Emission.hlsl.meta | 7 + .../Shaders/Utils/EnvironmentReflections.hlsl | 37 ++ .../Utils/EnvironmentReflections.hlsl.meta | 7 + .../Shaders/Utils/MetallicSpecGloss.hlsl | 118 ++++ .../Shaders/Utils/MetallicSpecGloss.hlsl.meta | 7 + .../Shaders/Utils/NormalMap.hlsl | 61 ++ .../Shaders/Utils/NormalMap.hlsl.meta | 7 + .../Shaders/Utils/ObjectMotionVectors.hlsl | 116 ++++ .../Utils/ObjectMotionVectors.hlsl.meta | 7 + .../Shaders/Utils/OcclusionMap.hlsl | 48 ++ .../Shaders/Utils/OcclusionMap.hlsl.meta | 7 + .../Shaders/Utils/ParallaxMap.hlsl | 49 ++ .../Shaders/Utils/ParallaxMap.hlsl.meta | 7 + .../Shaders/Utils/ReceiveShadows.hlsl | 45 ++ .../Shaders/Utils/ReceiveShadows.hlsl.meta | 7 + .../Shaders/Utils/ScreenSpaceShadows.shader | 4 +- .../Shaders/Utils/SpecGloss.hlsl | 89 +++ .../Shaders/Utils/SpecGloss.hlsl.meta | 7 + .../Shaders/Utils/SpecularHighlights.hlsl | 40 ++ .../Utils/SpecularHighlights.hlsl.meta | 7 + .../Shaders/Utils/StencilDeferred.hlsl | 80 ++- .../Shaders/Utils/StencilDeferred.shader | 22 +- .../Shaders/Utils/SurfaceType.hlsl | 63 +- .../Shaders/Utils/Universal2D.hlsl | 8 +- .../Editor/DeprecatedSurfaceIsolationTests.cs | 263 ++++++++ .../DeprecatedSurfaceIsolationTests.cs.meta | 2 + .../Tests/Editor/DynamicKeywordGuardTests.cs | 391 ++++++++++++ .../Editor/DynamicKeywordGuardTests.cs.meta | 2 + .../Editor/ShaderLibraryLayeringTests.cs | 75 +++ .../Editor/ShaderLibraryLayeringTests.cs.meta | 2 + .../Assets/Scenes/000_ForwardPlus_Many.unity | 4 +- .../Scenes/055_SoftShadowQuality_High.unity | 4 +- .../Assets/Scenes/350_VRS/VRS_Unlit.shader | 4 +- .../AnalyticDirectLightingTests.cs | 297 --------- .../AnalyticDirectLightingTests.cs.meta | 2 - .../LightingOverloadConsistency.shader | 67 -- .../LightingOverloadConsistency.shader.meta | 9 - 241 files changed, 7953 insertions(+), 3508 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl rename Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting.meta => Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl.meta (57%) create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl rename Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources.meta => Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl.meta (57%) create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl create mode 100644 Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs.meta delete mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs delete mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs.meta delete mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader delete mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl index e82cead81f1..96c6b36d79b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl @@ -89,8 +89,12 @@ struct APVResourcesRW #ifndef USE_APV_PROBE_OCCLUSION // If we are rendering a probe lit renderer, and we have APV enabled, and we are using subtractive or shadowmask mode, we sample occlusion from APV. -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && (defined(LIGHTMAP_SHADOW_MIXING) || defined(SHADOWS_SHADOWMASK)) -#define USE_APV_PROBE_OCCLUSION 1 +#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) + #if (LIGHTMAP_SHADOW_MIXING_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) || (SHADOWS_SHADOWMASK_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #define USE_APV_PROBE_OCCLUSION 1 + #elif defined(LIGHTMAP_SHADOW_MIXING) || defined(SHADOWS_SHADOWMASK) + #define USE_APV_PROBE_OCCLUSION 1 + #endif #endif #endif diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl index ebd5bb45dd7..5d4068e4cc0 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl @@ -6,9 +6,12 @@ #define MERGE_NAME(X, Y) X##Y #define CALL_MERGE_NAME(X, Y) MERGE_NAME(X, Y) -// True when X is defined to a non-zero (or empty) value; false when undefined or defined as literal 0. -// undefined -> false, '#define X' -> true, '#define X 0' -> false, '#define X N' -> true (N non-zero). -#define DEFINED_NONZERO(X) (defined(X) && ((1 - X - 1) != 0)) +// Whether X is defined to a non-zero (or empty) value, for use in #if/#elif expressions. +// undefined == false +// '#define X' == true +// '#define X 0' == false +// '#define X N' == true, where N is non-zero +#define DEFINED_NONZERO(X) ((1 - X - 1) != 0) // These define are use to abstract the way we sample into a cubemap array. // Some platform don't support cubemap array so we fallback on 2D latlong diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl index 014bcfdaa65..ec70ed956d2 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl @@ -346,8 +346,12 @@ #if !defined(DYNAMICLIGHTMAP_ON) #define UNITY_USE_SHCOEFFS_ARRAYS #endif - #if defined(SHADOWS_SHADOWMASK) + #if (SHADOWS_SHADOWMASK_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) #define UNITY_USE_PROBESOCCLUSION_ARRAY + #elif !defined(SHADOWS_SHADOWMASK_KEYWORD_DECLARED) || (SHADOWS_SHADOWMASK_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(SHADOWS_SHADOWMASK) + #define UNITY_USE_PROBESOCCLUSION_ARRAY + #endif #endif #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template b/Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template index 07d56e16781..f77e1f3e8f1 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template +++ b/Packages/com.unity.render-pipelines.universal/Editor/Decal/DecalPass.template @@ -27,6 +27,7 @@ Pass #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" // Defines $Attributes.normalOS: #define ATTRIBUTES_NEED_NORMAL @@ -142,9 +143,7 @@ Pass $Varyings.normalWS: input.normalWS.xyz = normalWS; $Varyings.tangentWS: input.tangentWS.xyzw = half4(tangentWS, sign); #else - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(positionCS); - #endif + LODFadeCrossFade(positionCS); half fadeFactor = half(1.0); #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl index 7dd80fc1be8..223205d3bac 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl @@ -1,6 +1,8 @@ #ifndef SG_DEPTH_NORMALS_PASS_INCLUDED #define SG_DEPTH_NORMALS_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" PackedVaryings vert(Attributes input) @@ -29,9 +31,7 @@ void frag( clip(surfaceDescription.Alpha - surfaceDescription.AlphaClipThreshold); #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); // Retrieve the normal from the bump map or mesh normal #if defined(_NORMALMAP) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthOnlyPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthOnlyPass.hlsl index 6626022717f..5406b4750c6 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthOnlyPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthOnlyPass.hlsl @@ -1,6 +1,8 @@ #ifndef SG_DEPTH_ONLY_PASS_INCLUDED #define SG_DEPTH_ONLY_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + PackedVaryings vert(Attributes input) { Varyings output = (Varyings)0; @@ -21,9 +23,7 @@ half4 frag(PackedVaryings packedInput) : SV_TARGET clip(surfaceDescription.Alpha - surfaceDescription.AlphaClipThreshold); #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); return packedInput.positionCS.z; } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl index 4b41f12c190..70d3a473f52 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl @@ -1,6 +1,8 @@ #ifndef SG_MOTION_VECTORS_PASS_INCLUDED #define SG_MOTION_VECTORS_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MotionVectorsCommon.hlsl" #if defined(ATTRIBUTES_NEED_TEXCOORD4) @@ -192,9 +194,7 @@ float4 frag( clip(surfaceDescription.Alpha - surfaceDescription.AlphaClipThreshold); #endif -#if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif #if defined(APPLICATION_SPACE_WARP_MOTION) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl index 0021d4861d0..818ba314b28 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl @@ -1,5 +1,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl" void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, out InputData inputData) { @@ -26,12 +28,10 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); inputData.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; @@ -39,12 +39,13 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.sh; #endif @@ -58,25 +59,30 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, inputData.preExposureMultiplier = GetPreExposureMultiplier(); } -void InitializeBakedGIData(Varyings input, inout InputData inputData) +void InitializeBakedGIData(Varyings input, inout InputData inputData, bool isSurfaceTypeTransparent) { -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, input.sh, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.sh, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - input.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.sh, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.sh; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV.xy; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = input.positionCS.xy; + giParams.isSurfaceTypeTransparent = isSurfaceTypeTransparent; + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } PackedVaryings vert(Attributes input) @@ -102,9 +108,9 @@ void frag( SurfaceDescription surfaceDescription = BuildSurfaceDescription(unpacked); #if defined(_SURFACE_TYPE_TRANSPARENT) - bool isTransparent = true; + bool isSurfaceTypeTransparent = true; #else - bool isTransparent = false; + bool isSurfaceTypeTransparent = false; #endif #if defined(_ALPHATEST_ON) @@ -115,9 +121,7 @@ void frag( half alpha = half(1.0); #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); InputData inputData; InitializeInputData(unpacked, surfaceDescription, inputData); @@ -159,19 +163,19 @@ void frag( surface.albedo = AlphaModulate(surface.albedo, surface.alpha); -#if defined(_DBUFFER) +#if defined(_DBUFFER) && !defined(_SURFACE_TYPE_TRANSPARENT) ApplyDecalToSurfaceData(unpacked.positionCS, surface, inputData); #endif - InitializeBakedGIData(unpacked, inputData); + InitializeBakedGIData(unpacked, inputData, isSurfaceTypeTransparent); URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surface); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, unpacked.positionCS)); #if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - color.rgb = MixVolumetricFog(color.rgb, color.a, VolumetricFogBlendModeFromDefines(), unpacked.positionCS); + color.rgb = MixVolumetricFog(color.rgb, color.a, VolumetricFogBlendModeFromDefines(), false, unpacked.positionCS); #endif - color.a = OutputAlpha(color.a, isTransparent); + color.a = OutputAlpha(color.a, isSurfaceTypeTransparent); outColor = color; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl index a5c0186aa82..6cf786b428f 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl @@ -1,4 +1,6 @@ +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, out InputData inputData) { inputData = (InputData)0; @@ -25,23 +27,20 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); inputData.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS); -#if defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); -#else - inputData.shadowCoord = float4(0, 0, 0, 0); -#endif + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS) : float4(0, 0, 0, 0); inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.sh; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -54,23 +53,27 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, void InitializeBakedGIData(Varyings input, inout InputData inputData) { -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, input.sh, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.sh, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.sh, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.sh; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV.xy; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } PackedVaryings vert(Attributes input) @@ -98,9 +101,7 @@ GBufferFragOutput frag(PackedVaryings packedInput) half alpha = 1; #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); InputData inputData; InitializeInputData(unpacked, surfaceDescription, inputData); @@ -136,7 +137,7 @@ GBufferFragOutput frag(PackedVaryings packedInput) InitializeBRDFData(surfaceDescription.BaseColor, metallic, specular, surfaceDescription.Smoothness, alpha, brdfData); Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); URP_LIGHT_ACCUM3 color = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl index 706242ca490..056342340ac 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl @@ -76,12 +76,10 @@ void InitializeInputData(Varyings input, float3 positionWS, half3 normalWS, half inputData.viewDirectionWS = viewDirectionWS; inputData.preExposureMultiplier = GetPreExposureMultiplier(); -#if defined(VARYINGS_NEED_SHADOW_COORD) && defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(positionWS); +#if defined(VARYINGS_NEED_SHADOW_COORD) && USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(positionWS); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(positionWS) : float4(0, 0, 0, 0); #endif #ifdef VARYINGS_NEED_FOG_AND_VERTEX_LIGHT @@ -90,13 +88,13 @@ void InitializeInputData(Varyings input, float3 positionWS, half3 normalWS, half #if defined(_SCREEN_SPACE_IRRADIANCE) inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, normalWS, GetInvPreExposureMultiplier()); -#elif defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON) +#elif defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, half3(input.sh), normalWS); #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV) inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); #endif #elif defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV) -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if !USE_LIGHTMAP_UV_INTERPOLATOR && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) inputData.bakedGI = SAMPLE_GI(input.sh, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -113,10 +111,10 @@ void InitializeInputData(Varyings input, float3 positionWS, half3 normalWS, half #endif #if defined(DEBUG_DISPLAY) - #if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON) + #if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif - #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV) && defined(LIGHTMAP_ON) + #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV) && USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; #elif defined(VARYINGS_NEED_SH) inputData.vertexSH = input.sh; @@ -166,11 +164,11 @@ PackedVaryings Vert(Attributes inputMesh) OUTPUT_LIGHTMAP_UV(inputMesh.uv1, unity_LightmapST, output.staticLightmapUV); #endif -#if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON) +#if defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR output.dynamicLightmapUV.xy = inputMesh.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif -#if defined(VARYINGS_NEED_SH) && !defined(LIGHTMAP_ON) +#if defined(VARYINGS_NEED_SH) && USE_VERTEX_SH_INTERPOLATOR output.sh = float3(SampleSHVertex(half3(output.normalWS))); #endif @@ -368,7 +366,7 @@ void Frag(PackedVaryings packedInput, // Skip GI if there is no abledo #ifdef _MATERIAL_AFFECTS_ALBEDO Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, surfaceData.normalWS.xyz, inputData.bakedGI, inputData.shadowMask); + MixRealtimeAndBakedGI(mainLight, surfaceData.normalWS.xyz, inputData.bakedGI); URP_LIGHT_ACCUM3 color = GlobalIllumination(brdfData, inputData.bakedGI, surface.occlusion, surfaceData.normalWS.xyz, inputData.viewDirectionWS); #else URP_LIGHT_ACCUM3 color = 0; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShadowCasterPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShadowCasterPass.hlsl index 4644b5fa6ed..10fb026810e 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShadowCasterPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShadowCasterPass.hlsl @@ -1,6 +1,8 @@ #ifndef SG_SHADOW_PASS_INCLUDED #define SG_SHADOW_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + PackedVaryings vert(Attributes input) { Varyings output = (Varyings)0; @@ -20,9 +22,7 @@ half4 frag(PackedVaryings packedInput) : SV_TARGET clip(surfaceDescription.Alpha - surfaceDescription.AlphaClipThreshold); #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); return 0; } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SixWayForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SixWayForwardPass.hlsl index 7a4c1f04dc8..925462b7705 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SixWayForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SixWayForwardPass.hlsl @@ -1,4 +1,6 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl" void InitializeInputData(Varyings input, bool frontFace, out InputData inputData) { @@ -16,12 +18,10 @@ void InitializeInputData(Varyings input, bool frontFace, out InputData inputData inputData.viewDirectionWS = GetWorldSpaceNormalizeViewDir(input.positionWS); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; @@ -29,10 +29,10 @@ void InitializeInputData(Varyings input, bool frontFace, out InputData inputData inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; #else inputData.vertexSH = input.sh; @@ -71,9 +71,9 @@ void frag( SurfaceDescription surfaceDescription = BuildSurfaceDescription(unpacked); #if defined(_SURFACE_TYPE_TRANSPARENT) - bool isTransparent = true; + bool isSurfaceTypeTransparent = true; #else - bool isTransparent = false; + bool isSurfaceTypeTransparent = false; #endif #if defined(_ALPHATEST_ON) @@ -84,9 +84,7 @@ void frag( half alpha = half(1.0); #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); InputData inputData; InitializeInputData(unpacked, frontFace, inputData); @@ -116,10 +114,10 @@ void frag( URP_LIGHT_ACCUM4 color = UniversalFragmentSixWay(inputData, surfaceData); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, unpacked.positionCS)); #if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - color.rgb = MixVolumetricFog(color.rgb, color.a, VolumetricFogBlendModeFromDefines(), unpacked.positionCS); + color.rgb = MixVolumetricFog(color.rgb, color.a, VolumetricFogBlendModeFromDefines(), false, unpacked.positionCS); #endif - color.a = OutputAlpha(color.a, isTransparent); + color.a = OutputAlpha(color.a, isSurfaceTypeTransparent); outColor = color; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl index fb28febf751..f92382f2e83 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl @@ -10,32 +10,42 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, inputData.positionWS = input.positionWS; inputData.preExposureMultiplier = GetPreExposureMultiplier(); - half3 SH = 0.0h; CalculateTerrainNormalWS(input, surfaceDescription, inputData); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; -#if defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, SH, inputData.normalWS); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, SH, inputData.normalWS); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.sh; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV.xy; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = input.positionCS.xy; + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); + inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; #else inputData.vertexSH = input.sh; @@ -97,7 +107,7 @@ void frag(PackedVaryings packedInput, surface.albedo = AlphaModulate(surface.albedo, surface.alpha); -#ifdef _DBUFFER +#if defined(_DBUFFER) && !defined(_SURFACE_TYPE_TRANSPARENT) ApplyDecalToSurfaceData(unpacked.positionCS, surface, inputData); #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl index 641ed280464..3297c68bfb5 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl @@ -12,32 +12,42 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, inputData.preExposureMultiplier = GetPreExposureMultiplier(); - half3 SH = 0.0h; CalculateTerrainNormalWS(input, surfaceDescription, inputData); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; -#if defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, SH, inputData.normalWS); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, SH, inputData.normalWS); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.sh; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV.xy; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = input.positionCS.xy; + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); + inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; #else inputData.vertexSH = input.sh; @@ -108,7 +118,7 @@ GBufferFragOutput frag(PackedVaryings packedInput) // Baked lighting. URP_LIGHT_ACCUM4 color; Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); color.rgb = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitGBufferPass.hlsl index a3c4e08e3d2..775bf791509 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitGBufferPass.hlsl @@ -1,5 +1,6 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl" @@ -41,15 +42,9 @@ GBufferFragOutput frag(PackedVaryings packedInput) surfaceData.alpha = AlphaDiscard(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold); #endif -#if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE LODFadeCrossFade(unpacked.positionCS); -#endif -#if defined(_ALPHAMODULATE_ON) surfaceData.albedo = AlphaModulate(surfaceDescription.BaseColor, surfaceData.alpha); -#else - surfaceData.albedo = surfaceDescription.BaseColor; -#endif #if defined(_DBUFFER) && defined(UNLIT_DEFAULT_DECAL_BLENDING) ApplyDecalToBaseColor(unpacked.positionCS, surfaceData.albedo); @@ -57,14 +52,16 @@ GBufferFragOutput frag(PackedVaryings packedInput) InputData inputData; InitializeInputData(unpacked, inputData); - surfaceData.occlusion = 1; - #if defined(_SCREEN_SPACE_OCCLUSION) && defined(UNLIT_DEFAULT_SSAO) // GBuffer never has transparents - float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(unpacked.positionCS); +#if defined(UNLIT_DEFAULT_SSAO) + if (ScreenSpaceOcclusionAvailable()) // No transparent-surface check needed: the GBuffer pass only renders opaque geometry + { + float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(inputData.positionCS); AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); surfaceData.occlusion = aoFactor.directAmbientOcclusion; - #endif + } +#endif return PackGBuffersSurfaceData(surfaceData, inputData, float3(0,0,0)); } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl index c3fba4ddb63..73a2ba0ef42 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl @@ -1,5 +1,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl" void InitializeInputData(Varyings input, out InputData inputData) { @@ -45,9 +47,9 @@ void frag( SurfaceDescription surfaceDescription = BuildSurfaceDescription(unpacked); #if defined(_SURFACE_TYPE_TRANSPARENT) - bool isTransparent = true; + bool isSurfaceTypeTransparent = true; #else - bool isTransparent = false; + bool isSurfaceTypeTransparent = false; #endif #if defined(_ALPHATEST_ON) @@ -58,15 +60,11 @@ void frag( half alpha = half(1.0); #endif - #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE - LODFadeCrossFade(unpacked.positionCS); - #endif + LODFadeCrossFade(unpacked.positionCS); -#if defined(_ALPHAMODULATE_ON) surfaceDescription.BaseColor = AlphaModulate(surfaceDescription.BaseColor, alpha); -#endif -#if defined(_DBUFFER) && defined(UNLIT_DEFAULT_DECAL_BLENDING) +#if defined(_DBUFFER) && defined(UNLIT_DEFAULT_DECAL_BLENDING) && !defined(_SURFACE_TYPE_TRANSPARENT) ApplyDecalToBaseColor(unpacked.positionCS, surfaceDescription.BaseColor); #endif @@ -79,16 +77,19 @@ void frag( #endif half4 finalColor = UniversalFragmentUnlit(inputData, surfaceDescription.BaseColor, alpha); - finalColor.a = OutputAlpha(finalColor.a, isTransparent); + finalColor.a = OutputAlpha(finalColor.a, isSurfaceTypeTransparent); - #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) && defined(UNLIT_DEFAULT_SSAO) + #if !defined(_SURFACE_TYPE_TRANSPARENT) && defined(UNLIT_DEFAULT_SSAO) + if (ScreenSpaceOcclusionAvailable()) + { float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(unpacked.positionCS); AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); finalColor.rgb *= aoFactor.directAmbientOcclusion; + } #endif #if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, VolumetricFogBlendModeFromDefines(), unpacked.positionCS); + finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, VolumetricFogBlendModeFromDefines(), false, unpacked.positionCS); #endif outColor = finalColor; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl index fa00d0d4ffa..6a36c775b23 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl @@ -267,7 +267,7 @@ Varyings BuildVaryings(Attributes input #ifdef UNIVERSAL_TERRAIN_ENABLED #if (SHADERPASS == SHADERPASS_FORWARD) || (SHADERPASS == SHADERPASS_GBUFFER) OUTPUT_LIGHTMAP_UV(input.uv0, unity_LightmapST, output.staticLightmapUV); - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR output.dynamicLightmapUV.xy = input.uv0.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif OUTPUT_SH4(vertexInput.positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.sh, output.probeOcclusion); @@ -275,7 +275,7 @@ Varyings BuildVaryings(Attributes input #else #if (SHADERPASS == SHADERPASS_FORWARD) || (SHADERPASS == SHADERPASS_GBUFFER) OUTPUT_LIGHTMAP_UV(input.uv1, unity_LightmapST, output.staticLightmapUV); - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR output.dynamicLightmapUV.xy = input.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif OUTPUT_SH4(vertexInput.positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.sh, output.probeOcclusion); @@ -288,8 +288,8 @@ Varyings BuildVaryings(Attributes input output.fogFactorAndVertexLight = URP_LIGHT_ACCUM4(fogFactor, vertexLight); #endif - #if defined(VARYINGS_NEED_SHADOW_COORD) && defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if defined(VARYINGS_NEED_SHADOW_COORD) && USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput) : float4(0, 0, 0, 0); #endif #if defined(VARYINGS_NEED_SIX_WAY_DIFFUSE_GI_DATA) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl new file mode 100644 index 00000000000..c5dafe09ecb --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl @@ -0,0 +1,42 @@ +#ifndef UNIVERSAL_VOLUMETRIC_FOG_BLEND_MODE_INCLUDED +#define UNIVERSAL_VOLUMETRIC_FOG_BLEND_MODE_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// Resolves the MixVolumetricFog blend mode for shaders that carry it as compile-time +// defines (ShaderGraph targets) rather than as the _Blend material float. Graphs whose +// blending is material-overridable expose only Multiply as a keyword, so their Premultiply +// and Additive materials fall back to the Alpha formula. + +#if !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAMODULATE_ON) + #define _ALPHAMODULATE_ON 0 + #define _ALPHAMODULATE_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef _ALPHAMODULATE_ON + #define _ALPHAMODULATE_ON 1 + #endif +#endif + +half VolumetricFogBlendModeFromDefines() +{ +#if defined(_BLENDMODE_ADDITIVE) + return 2.0; +#else + if (_ALPHAMODULATE_ON) + return 3.0; + #if defined(_BLENDMODE_PREMULTIPLY) + return 1.0; + #else + return 0.0; + #endif +#endif +} + +// Prevents leaking the fallback keyword definition to shaders that include this file. +#if defined(_ALPHAMODULATE_ON_DEFINED_LOCALLY) + #undef _ALPHAMODULATE_ON_DEFINED_LOCALLY + #undef _ALPHAMODULATE_ON +#endif + +#endif diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting.meta b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl.meta similarity index 57% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting.meta rename to Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl.meta index 22f3a2bf074..7d46a21d162 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting.meta +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/VolumetricFogBlendMode.hlsl.meta @@ -1,7 +1,6 @@ fileFormatVersion: 2 -guid: 70d489c0964c84aab9ae3fc7bb7715ee -folderAsset: yes -DefaultImporter: +guid: 61ed89d5f896c4be4b689627074a6424 +ShaderIncludeImporter: externalObjects: {} userData: assetBundleName: 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 39e865cfb42..a7f93dea10b 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 @@ -951,7 +951,6 @@ private static class Descriptors { Descriptors.AffectsNormal, 1, new FieldCondition(AffectsNormal, true) }, { Descriptors.AffectsNormalBlend, 1, new FieldCondition(AffectsNormalBlend, true) }, { Descriptors.AffectsMAOS, 1, new FieldCondition(AffectsMAOS, true) }, - { CoreKeywordDescriptors.UseUnityCrossFade, 1, new FieldCondition(Fields.LodCrossFade, true) } }; public static DefineCollection MeshEmission = new DefineCollection 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 936962860c4..f5d51e986b1 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 @@ -1369,9 +1369,7 @@ internal static void AddLODCrossFadeControlToPass(ref PassDescriptor pass, Unive { if (target.supportsLodCrossFade) { - pass.includes.Add(CoreIncludes.LODCrossFade); pass.keywords.Add(CoreKeywordDescriptors.LODFadeCrossFade); - pass.defines.Add(CoreKeywordDescriptors.UseUnityCrossFade, 1); } } @@ -2340,6 +2338,7 @@ static class CoreIncludes const string kFoveatedRenderingKeywords = "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"; const string kFoveatedRendering = "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"; const string kMipmapDebugMacros = "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl"; + const string kPackNormalsTexture = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl"; // Files that are included with #include_with_pragmas const string kDOTS = "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"; @@ -2358,7 +2357,8 @@ static class CoreIncludes { kLighting, IncludeLocation.Pregraph }, { kInput, IncludeLocation.Pregraph }, { kTextureStack, IncludeLocation.Pregraph }, // TODO: put this on a conditional - { kMipmapDebugMacros, IncludeLocation.Pregraph} + { kMipmapDebugMacros, IncludeLocation.Pregraph }, + { kLODCrossFade, IncludeLocation.Pregraph } }; public static readonly IncludeCollection DOTSPregraph = new IncludeCollection @@ -2411,6 +2411,7 @@ static class CoreIncludes { WriteRenderLayersPregraph }, { CorePregraph }, { ShaderGraphPregraph }, + { kPackNormalsTexture, IncludeLocation.Pregraph }, // Post-graph { CorePostgraph }, @@ -2483,11 +2484,6 @@ static class CoreIncludes { kSelectionPickingPass, IncludeLocation.Postgraph }, }; - public static readonly IncludeCollection LODCrossFade = new IncludeCollection - { - { kLODCrossFade, IncludeLocation.Pregraph } - }; - public static readonly IncludeCollection GBufferOutputFormat = new IncludeCollection { { kGbufferOutputFormat, IncludeLocation.Postgraph, true } @@ -2971,6 +2967,7 @@ static class CoreKeywordDescriptors type = KeywordType.Boolean, definition = KeywordDefinition.MultiCompile, scope = KeywordScope.Global, + stages = KeywordShaderStage.Fragment }; public static readonly KeywordDescriptor EditorVisualization = new KeywordDescriptor() @@ -2999,16 +2996,6 @@ static class CoreKeywordDescriptors scope = KeywordScope.Global }; - public static readonly KeywordDescriptor UseUnityCrossFade = new KeywordDescriptor() - { - displayName = ShaderKeywordStrings.USE_UNITY_CROSSFADE, - referenceName = ShaderKeywordStrings.USE_UNITY_CROSSFADE, - type = KeywordType.Boolean, - definition = KeywordDefinition.MultiCompile, - scope = KeywordScope.Global, - stages = KeywordShaderStage.Fragment, - }; - public static readonly KeywordDescriptor ScreenSpaceAmbientOcclusion = new KeywordDescriptor() { displayName = "Screen Space Ambient Occlusion", @@ -3054,7 +3041,7 @@ static class CoreKeywordDescriptors referenceName = ShaderKeywordStrings.USE_LEGACY_LIGHTMAPS, type = KeywordType.Boolean, definition = KeywordDefinition.MultiCompile, - scope = KeywordScope.Global + scope = KeywordScope.Global, }; public static readonly KeywordDescriptor XRMotionVectors = new KeywordDescriptor() 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 ae681a210f1..441e276f170 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 @@ -1552,7 +1552,6 @@ static class TerrainLitKeywords { CoreKeywordDescriptors.ShadowsShadowmask }, { CoreKeywordDescriptors.DBuffer }, { CoreKeywordDescriptors.GBufferNormalsOct }, - { CoreKeywordDescriptors.LightLayers }, { CoreKeywordDescriptors.RenderPassEnabled }, { CoreKeywordDescriptors.ScreenSpaceReflection }, { CoreKeywordDescriptors.DebugDisplay }, 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 14d512443db..b635f2edeb2 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 @@ -556,7 +556,7 @@ public static PassDescriptor DepthNormalOnly(UniversalTarget target) customInterpolators = CoreCustomInterpDescriptors.Common }; - CorePasses.AddTargetSurfaceControlsToPass(ref result, target); + CorePasses.AddAlphaClipControlToPass(ref result, target); CorePasses.AddLODCrossFadeControlToPass(ref result, target); CorePasses.AddStencilStateControlToPass(ref result, target, useDefaults: !target.depthStencilPassMask.Has(DepthStencilPassMask.Prepass)); @@ -600,10 +600,9 @@ public static PassDescriptor GBuffer(UniversalTarget target) customInterpolators = CoreCustomInterpDescriptors.Common }; - CorePasses.AddTargetSurfaceControlsToPass(ref result, target); + CorePasses.AddAlphaClipControlToPass(ref result, target); CorePasses.AddLODCrossFadeControlToPass(ref result, target); CorePasses.AddDepthStateControlToPass(ref result, target, useDefaults: !target.depthStencilPassMask.Has(DepthStencilPassMask.ColorPass)); - if (target.activeSubTarget is UniversalUnlitSubTarget unlitSubTarget) { UnlitPasses.AddDefaultDecalBlendingControlToPass(ref result, unlitSubTarget); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalStructFields.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalStructFields.cs index 1a557103d3e..97ddd6ef81f 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalStructFields.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalStructFields.cs @@ -8,15 +8,15 @@ public struct Varyings { public static string name = "Varyings"; public static FieldDescriptor staticLightmapUV = new FieldDescriptor(Varyings.name, "staticLightmapUV", "", ShaderValueType.Float2, - preprocessor: "defined(LIGHTMAP_ON)", subscriptOptions: StructFieldOptions.Optional); + preprocessor: "USE_LIGHTMAP_UV_INTERPOLATOR", subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor dynamicLightmapUV = new FieldDescriptor(Varyings.name, "dynamicLightmapUV", "", ShaderValueType.Float2, - preprocessor: "defined(DYNAMICLIGHTMAP_ON)", subscriptOptions: StructFieldOptions.Optional); + preprocessor: "USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR", subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor sh = new FieldDescriptor(Varyings.name, "sh", "", ShaderValueType.Float3, - preprocessor: "!defined(LIGHTMAP_ON)", subscriptOptions: StructFieldOptions.Optional); + preprocessor: "USE_VERTEX_SH_INTERPOLATOR", subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor fogFactorAndVertexLight = new FieldDescriptor(Varyings.name, "fogFactorAndVertexLight", "VARYINGS_NEED_FOG_AND_VERTEX_LIGHT", ShaderValueType.Float4, subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor shadowCoord = new FieldDescriptor(Varyings.name, "shadowCoord", "VARYINGS_NEED_SHADOWCOORD", ShaderValueType.Float4, - subscriptOptions: StructFieldOptions.Optional, preprocessor: "defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)"); + subscriptOptions: StructFieldOptions.Optional, preprocessor: "USE_VERTEX_SHADOW_COORD_INTERPOLATOR"); public static FieldDescriptor probeOcclusion = new FieldDescriptor(Varyings.name, "probeOcclusion", "", ShaderValueType.Float4, preprocessor: "defined(USE_APV_PROBE_OCCLUSION)", subscriptOptions: StructFieldOptions.Optional); public static FieldDescriptor stereoTargetEyeIndexAsRTArrayIdx = new FieldDescriptor(Varyings.name, "stereoTargetEyeIndexAsRTArrayIdx", "", ShaderValueType.Uint, diff --git a/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/VFXAbstractParticleURPLitOutput.cs b/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/VFXAbstractParticleURPLitOutput.cs index 9de0e5b6b10..8f976511d13 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/VFXAbstractParticleURPLitOutput.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/VFXAbstractParticleURPLitOutput.cs @@ -766,13 +766,13 @@ public override IEnumerable> additionalRep // URP Forward specific defines var forwardDefines = new VFXShaderWriter(); if (workflowMode == WorkflowMode.Specular) - forwardDefines.Write("#define _SPECULAR_SETUP"); + forwardDefines.Write("#define _SPECULAR_SETUP 1"); yield return new KeyValuePair("${VFXURPForwardDefines}", forwardDefines); // URP GBuffer specific defines var gbufferDefines = new VFXShaderWriter(); if (workflowMode == WorkflowMode.Specular) - gbufferDefines.Write("#define _SPECULAR_SETUP"); + gbufferDefines.Write("#define _SPECULAR_SETUP 1"); yield return new KeyValuePair("${VFXURPGBufferDefines}", gbufferDefines); var forwardPassLightMode = new VFXShaderWriter(); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs index 72e074640f9..d1f813b5b0a 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs @@ -74,7 +74,8 @@ internal enum PrefilteringModeAdditionalLights // Additional Lights // clustered renderer can override PerVertex/PerPixel to be disabled // NOTE: off variants are atm always kept when additional lights are enabled due to XR perf reasons - // multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + // multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + // multi_compile_fragment _ _ADDITIONAL_LIGHTS [ShaderKeywordFilter.RemoveIf(PrefilteringModeAdditionalLights.Remove, keywordNames: new string[] {ShaderKeywordStrings.AdditionalLightsVertex, ShaderKeywordStrings.AdditionalLightsPixel})] [ShaderKeywordFilter.SelectIf(PrefilteringModeAdditionalLights.SelectVertex, keywordNames: ShaderKeywordStrings.AdditionalLightsVertex)] [ShaderKeywordFilter.SelectIf(PrefilteringModeAdditionalLights.SelectVertexAndOff,keywordNames: new string[] {"", ShaderKeywordStrings.AdditionalLightsVertex})] diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl new file mode 100644 index 00000000000..5b339cd6429 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl @@ -0,0 +1,33 @@ +#ifndef UNIVERSAL_VFX_COMMON_DEPRECATED_INCLUDED +#define UNIVERSAL_VFX_COMMON_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (VFXCommon.hlsl). + +float4 VFXApplyAO(float4 color, float4 posCS, bool surfaceTypeTransparent); + +#if !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef _SURFACE_TYPE_TRANSPARENT + #define _SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif + +// Deprecated. Use VFXApplyAO(color, posCS, surfaceTypeTransparent). +float4 VFXApplyAO(float4 color, float4 posCS) +{ + return VFXApplyAO(color, posCS, _SURFACE_TYPE_TRANSPARENT); +} + +// Prevents leaking the fallback keyword definition to shaders that include this file. +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT +#endif + +#endif // UNIVERSAL_VFX_COMMON_DEPRECATED_INCLUDED diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources.meta b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl.meta similarity index 57% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources.meta rename to Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl.meta index 31a7a6634de..a25671e4942 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources.meta +++ b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl.meta @@ -1,7 +1,6 @@ fileFormatVersion: 2 -guid: d3eef07d42a344cc7b0fc095e96a3630 -folderAsset: yes -DefaultImporter: +guid: 5997942a9f03d4776a85853b284fc884 +ShaderIncludeImporter: externalObjects: {} userData: assetBundleName: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl index 459ca653577..bbeb70a688d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.hlsl @@ -1,3 +1,4 @@ +#pragma once #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" @@ -11,6 +12,8 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DecalInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXCommon.deprecated.hlsl" float3 _LightDirection; @@ -170,13 +173,14 @@ void VFXApplyShadowBias(inout float4 posCS, inout float3 posWS) posCS = VFXTransformPositionWorldToClip(posWS); } -float4 VFXApplyAO(float4 color, float4 posCS) +float4 VFXApplyAO(float4 color, float4 posCS, bool isSurfaceTypeTransparent) { -#if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) - float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(posCS); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); - color.rgb *= aoFactor.directAmbientOcclusion; -#endif + if (!isSurfaceTypeTransparent && ScreenSpaceOcclusionAvailable()) + { + float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(posCS); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, isSurfaceTypeTransparent); + color.rgb *= aoFactor.directAmbientOcclusion; + } return color; } @@ -189,7 +193,7 @@ float4 VFXTransformFinalColor(float4 color, float4 posCS) color = VFXApplyAO(color, posCS); } -#ifdef _DBUFFER +#if defined(_DBUFFER) && !defined(_SURFACE_TYPE_TRANSPARENT) float3 decalColor = color.rgb; ApplyDecalToBaseColor(posCS, decalColor); color.rgb = decalColor; @@ -208,14 +212,14 @@ float4 VFXApplyVolumetricFog(float4 color, float4 posCS) #else const half fogBlendMode = 0.0; #endif - color.rgb = MixVolumetricFog(color.rgb, color.a, fogBlendMode, posCS); + color.rgb = MixVolumetricFog(color.rgb, color.a, fogBlendMode, false, posCS); #endif return color; } float4 VFXApplyFog(float4 color,float4 posCS,float3 posWS) { - if (FOG_LINEAR || FOG_EXP || FOG_EXP2) + if (DistanceFogAvailable()) { float4 fog = (float4)0; fog.rgb = ClampExposed(GetPreExposureMultiplier() * unity_FogColor.rgb); @@ -237,7 +241,4 @@ float3 VFXGetCameraWorldDirection() return unity_CameraToWorld._m02_m12_m22; } -#define VFXComputePixelOutputToNormalBuffer(i,normalWS,uvData,outNormalBuffer) \ -{ \ - outNormalBuffer = float4(PackNormalWSToTexture(normalWS), 0.0); \ -} +#define VFXComputePixelOutputToNormalBuffer(i,normalWS,uvData,outNormalBuffer) { outNormalBuffer = float4(PackNormalWSToTexture(normalWS), 0.0); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXDefines.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXDefines.hlsl index 60b7afb7d8b..23125b1dd3b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXDefines.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXDefines.hlsl @@ -1,3 +1,4 @@ +#pragma once #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" @@ -14,16 +15,16 @@ #endif #if IS_TRANSPARENT_PARTICLE -#define _SURFACE_TYPE_TRANSPARENT +#define _SURFACE_TYPE_TRANSPARENT 1 #endif #if VFX_SIX_WAY_COLOR_ABSORPTION - #define _SIX_WAY_COLOR_ABSORPTION +#define _SIX_WAY_COLOR_ABSORPTION 1 #endif //URP currently does not allow to know the blend mode in the shader in general, but we have this information in VFX generated shaders. #if VFX_BLENDMODE_PREMULTIPLY -#define _BLENDMODE_PREMULTIPLY +#define _BLENDMODE_PREMULTIPLY 1 #endif // this is only necessary for the old VFXTarget pathway // it defines the macro used to access hybrid instanced properties diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLit.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLit.hlsl index 725352b7335..7815ac2f6ce 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLit.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLit.hlsl @@ -37,13 +37,12 @@ InputData VFXGetInputData(const VFX_VARYING_PS_INPUTS i, const PositionInputs po #endif //When there is only one cascaded, this shadowCoord can be computed at vertex stage -//#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) +//#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR // inputData.shadowCoord = inputData.shadowCoord; -#if defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); -#else - inputData.shadowCoord = float4(0, 0, 0, 0); -#endif + if (MainLightShadowsAvailable()) + inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + else + inputData.shadowCoord = float4(0, 0, 0, 0); inputData.preExposureMultiplier = GetPreExposureMultiplier(); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl index ec176860889..19e094fed90 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl @@ -14,7 +14,7 @@ float4 VFXCalcPixelOutputForward(const VFX_VARYING_PS_INPUTS i, SurfaceData surf #if VFX_MATERIAL_TYPE_SIX_WAY_SMOKE URP_LIGHT_ACCUM4 color = UniversalFragmentSixWay(inputData, surfaceData); #else - #if defined(_DBUFFER) + #if defined(_DBUFFER) && !defined(_SURFACE_TYPE_TRANSPARENT) ApplyDecalToSurfaceData(i.VFX_VARYING_POSCS, surfaceData, inputData); #endif URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData); @@ -24,11 +24,11 @@ float4 VFXCalcPixelOutputForward(const VFX_VARYING_PS_INPUTS i, SurfaceData surf color = VFXApplyVolumetricFog(color, i.VFX_VARYING_POSCS); #if IS_OPAQUE_PARTICLE - bool isTransparent = false; + bool isSurfaceTypeTransparent = false; #else - bool isTransparent = true; + bool isSurfaceTypeTransparent = true; #endif - color.a = OutputAlpha(color.a, isTransparent); + color.a = OutputAlpha(color.a, isSurfaceTypeTransparent); return color; } @@ -78,7 +78,7 @@ void VFXComputePixelOutputToGBuffer(const VFX_VARYING_PS_INPUTS i, const float3 inputData.bakedGI, surfaceData.occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); -#if defined(_DBUFFER) +#if defined(_DBUFFER) && !defined(_SURFACE_TYPE_TRANSPARENT) ApplyDecalToBaseColor(i.VFX_VARYING_POSCS, surfaceData.albedo); #endif @@ -102,7 +102,7 @@ void VFXComputePixelOutputToGBufferShaderGraph(const VFX_VARYING_PS_INPUTS i, Su inputData.bakedGI, surfaceData.occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); -#if defined(_DBUFFER) +#if defined(_DBUFFER) && !defined(_SURFACE_TYPE_TRANSPARENT) ApplyDecalToBaseColor(i.VFX_VARYING_POSCS, surfaceData.albedo); #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl new file mode 100644 index 00000000000..ec27bd116f6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl @@ -0,0 +1,53 @@ +#ifndef AMBIENT_OCCLUSION_DEPRECATED_INCLUDED +#define AMBIENT_OCCLUSION_DEPRECATED_INCLUDED + +// 2023.3 Deprecated. This is for backwards compatibility. Remove in the future. +#define sampler_ScreenSpaceOcclusionTexture sampler_LinearClamp + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (AmbientOcclusion.hlsl). + +AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV, bool surfaceTypeTransparent); +AmbientOcclusionFactor CreateAmbientOcclusionFactor(float2 normalizedScreenSpaceUV, half occlusion, bool surfaceTypeTransparent); +AmbientOcclusionFactor CreateAmbientOcclusionFactor(InputData inputData, SurfaceData surfaceData, bool surfaceTypeTransparent); + +#if !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef _SURFACE_TYPE_TRANSPARENT + #define _SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif + +// Deprecated. Use GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, surfaceTypeTransparent). +AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV) +{ + return GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use CreateAmbientOcclusionFactor(normalizedScreenSpaceUV, occlusion, surfaceTypeTransparent). +AmbientOcclusionFactor CreateAmbientOcclusionFactor(float2 normalizedScreenSpaceUV, half occlusion) +{ + return CreateAmbientOcclusionFactor(normalizedScreenSpaceUV, occlusion, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use CreateAmbientOcclusionFactor(inputData, surfaceData, surfaceTypeTransparent). +AmbientOcclusionFactor CreateAmbientOcclusionFactor(InputData inputData, SurfaceData surfaceData) +{ + return CreateAmbientOcclusionFactor(inputData, surfaceData, _SURFACE_TYPE_TRANSPARENT); +} + +// Prevents leaking the fallback keyword definition to shaders that include this file. +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT +#endif + +#endif // AMBIENT_OCCLUSION_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl.meta new file mode 100644 index 00000000000..8ba66aa2e97 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 97c1979a98776434bb806547985ae69a +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl index cacbfeb90a9..6a5d8b25a71 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl @@ -3,18 +3,26 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.deprecated.hlsl" -// Ambient occlusion -TEXTURE2D_X(_ScreenSpaceOcclusionTexture); - -// 2023.3 Deprecated. This is for backwards compatibility. Remove in the future. -#define sampler_ScreenSpaceOcclusionTexture sampler_LinearClamp +#if !defined(_SCREEN_SPACE_OCCLUSION_KEYWORD_DECLARED) + #if !defined(_SCREEN_SPACE_OCCLUSION) + static const bool _SCREEN_SPACE_OCCLUSION = 0; + #elif DEFINED_NONZERO(_SCREEN_SPACE_OCCLUSION) + #undef _SCREEN_SPACE_OCCLUSION + #define _SCREEN_SPACE_OCCLUSION 1 + #endif +#endif -struct AmbientOcclusionFactor +bool ScreenSpaceOcclusionAvailable() { - half indirectAmbientOcclusion; - half directAmbientOcclusion; -}; + return _SCREEN_SPACE_OCCLUSION; +} + +// Ambient occlusion +TEXTURE2D_X(_ScreenSpaceOcclusionTexture); half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV) { @@ -25,17 +33,18 @@ half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV) return half(SAMPLE_TEXTURE2D_X(_ScreenSpaceOcclusionTexture, sampler_LinearClamp, uv).x); } -AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV) +AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV, bool isSurfaceTypeTransparent) { AmbientOcclusionFactor aoFactor; - #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) + aoFactor.directAmbientOcclusion = half(1.0); + aoFactor.indirectAmbientOcclusion = half(1.0); + + if (!isSurfaceTypeTransparent && _SCREEN_SPACE_OCCLUSION) + { float ssao = saturate(SampleAmbientOcclusion(normalizedScreenSpaceUV) + (1.0 - _AmbientOcclusionParam.x)); aoFactor.indirectAmbientOcclusion = ssao; aoFactor.directAmbientOcclusion = lerp(half(1.0), ssao, _AmbientOcclusionParam.w); - #else - aoFactor.directAmbientOcclusion = half(1.0); - aoFactor.indirectAmbientOcclusion = half(1.0); - #endif + } #if defined(DEBUG_DISPLAY) switch(_DebugLightingMode) @@ -55,17 +64,17 @@ AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpa return aoFactor; } -AmbientOcclusionFactor CreateAmbientOcclusionFactor(float2 normalizedScreenSpaceUV, half occlusion) +AmbientOcclusionFactor CreateAmbientOcclusionFactor(float2 normalizedScreenSpaceUV, half occlusion, bool isSurfaceTypeTransparent) { - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, isSurfaceTypeTransparent); aoFactor.indirectAmbientOcclusion = min(aoFactor.indirectAmbientOcclusion, occlusion); return aoFactor; } -AmbientOcclusionFactor CreateAmbientOcclusionFactor(InputData inputData, SurfaceData surfaceData) +AmbientOcclusionFactor CreateAmbientOcclusionFactor(InputData inputData, SurfaceData surfaceData, bool isSurfaceTypeTransparent) { - return CreateAmbientOcclusionFactor(inputData.normalizedScreenSpaceUV, surfaceData.occlusion); + return CreateAmbientOcclusionFactor(inputData.normalizedScreenSpaceUV, surfaceData.occlusion, isSurfaceTypeTransparent); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl new file mode 100644 index 00000000000..da5d49c50f0 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl @@ -0,0 +1,10 @@ +#ifndef AMBIENT_OCCLUSION_FACTOR_INCLUDED +#define AMBIENT_OCCLUSION_FACTOR_INCLUDED + +struct AmbientOcclusionFactor +{ + half indirectAmbientOcclusion; + half directAmbientOcclusion; +}; + +#endif // AMBIENT_OCCLUSION_FACTOR_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl.meta new file mode 100644 index 00000000000..b714c23d078 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 58b126bf10912422d908126df415969f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl new file mode 100644 index 00000000000..14ce0bd0d71 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl @@ -0,0 +1,139 @@ +#ifndef UNIVERSAL_BRDF_DEPRECATED_INCLUDED +#define UNIVERSAL_BRDF_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (BRDF.hlsl). + +BRDFData InitializeBRDFDataDirect(half3 albedo, half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, half alpha, bool alphaPremultiplyEnabled); +BRDFData InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, bool specularSetup, bool alphaPremultiplyEnabled); +BRDFData InitializeBRDFData(SurfaceData surfaceData, bool specularSetup, bool alphaPremultiplyEnabled); +BRDFData CreateEmptyBRDFData(); +BRDFData InitializeBRDFDataClearCoat(half clearCoatMask, half clearCoatSmoothness, inout BRDFData baseBRDFData); +half3 DirectBRDF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS, bool specularHighlights); + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +#if !defined(_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED) + #if !defined(_SPECULARHIGHLIGHTS_OFF) + #define _SPECULARHIGHLIGHTS_OFF 0 + #define _SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULARHIGHLIGHTS_OFF) + #undef _SPECULARHIGHLIGHTS_OFF + #define _SPECULARHIGHLIGHTS_OFF 1 + #endif +#endif + +#if !defined(_CLEARCOAT_KEYWORD_DECLARED) + #if !defined(_CLEARCOAT) + #define _CLEARCOAT 0 + #define _CLEARCOAT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_CLEARCOAT) + #undef _CLEARCOAT + #define _CLEARCOAT 1 + #endif +#endif + +#if !defined(_CLEARCOATMAP_KEYWORD_DECLARED) + #if !defined(_CLEARCOATMAP) + #define _CLEARCOATMAP 0 + #define _CLEARCOATMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_CLEARCOATMAP) + #undef _CLEARCOATMAP + #define _CLEARCOATMAP 1 + #endif +#endif + +#if !defined(_SPECULAR_SETUP_KEYWORD_DECLARED) + #if !defined(_SPECULAR_SETUP) + #define _SPECULAR_SETUP 0 + #define _SPECULAR_SETUP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_SETUP) + #undef _SPECULAR_SETUP + #define _SPECULAR_SETUP 1 + #endif +#endif + +// Deprecated. Use the BRDFData-returning InitializeBRDFDataDirect(..., alphaPremultiplyEnabled). +inline void InitializeBRDFDataDirect(half3 albedo, half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, inout half alpha, out BRDFData outBRDFData) +{ + outBRDFData = InitializeBRDFDataDirect(albedo, diffuse, specular, reflectivity, oneMinusReflectivity, smoothness, alpha, _ALPHAPREMULTIPLY_ON); +} + +// Legacy: do not call, will not correctly initialize albedo property. +inline void InitializeBRDFDataDirect(half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, inout half alpha, out BRDFData outBRDFData) +{ + outBRDFData = InitializeBRDFDataDirect(half3(0.0, 0.0, 0.0), diffuse, specular, reflectivity, oneMinusReflectivity, smoothness, alpha, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use the BRDFData-returning InitializeBRDFData(..., specularSetup, alphaPremultiplyEnabled). +inline void InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, inout half alpha, out BRDFData outBRDFData) +{ + outBRDFData = InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, _SPECULAR_SETUP, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use the BRDFData-returning InitializeBRDFData(..., specularSetup, alphaPremultiplyEnabled). +inline void InitializeBRDFData(inout SurfaceData surfaceData, out BRDFData brdfData) +{ + brdfData = InitializeBRDFData(surfaceData, _SPECULAR_SETUP, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use the BRDFData-returning InitializeBRDFDataClearCoat(clearCoatMask, clearCoatSmoothness, baseBRDFData). +inline void InitializeBRDFDataClearCoat(half clearCoatMask, half clearCoatSmoothness, inout BRDFData baseBRDFData, out BRDFData outBRDFData) +{ + outBRDFData = InitializeBRDFDataClearCoat(clearCoatMask, clearCoatSmoothness, baseBRDFData); +} + +// Deprecated. Gate InitializeBRDFDataClearCoat at the call site instead. +BRDFData CreateClearCoatBRDFData(SurfaceData surfaceData, inout BRDFData brdfData) +{ + BRDFData brdfDataClearCoat = CreateEmptyBRDFData(); + if (_CLEARCOAT || _CLEARCOATMAP) + brdfDataClearCoat = InitializeBRDFDataClearCoat(surfaceData.clearCoatMask, surfaceData.clearCoatSmoothness, brdfData); + return brdfDataClearCoat; +} + +// Deprecated. Use DirectBRDF(..., specularHighlights). +half3 DirectBRDF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS) +{ + return DirectBRDF(brdfData, normalWS, lightDirectionWS, viewDirectionWS, !_SPECULARHIGHLIGHTS_OFF); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#if defined(_SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY) + #undef _SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY + #undef _SPECULARHIGHLIGHTS_OFF +#endif + +#if defined(_CLEARCOAT_DEFINED_LOCALLY) + #undef _CLEARCOAT_DEFINED_LOCALLY + #undef _CLEARCOAT +#endif + +#if defined(_CLEARCOATMAP_DEFINED_LOCALLY) + #undef _CLEARCOATMAP_DEFINED_LOCALLY + #undef _CLEARCOATMAP +#endif + +#if defined(_SPECULAR_SETUP_DEFINED_LOCALLY) + #undef _SPECULAR_SETUP_DEFINED_LOCALLY + #undef _SPECULAR_SETUP +#endif + +#endif // UNIVERSAL_BRDF_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl.meta new file mode 100644 index 00000000000..8973d7cf0f9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a225464041fa14d28b8f609d547ddf40 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl index 07e5e7af0c4..29395cb71ec 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl @@ -6,26 +6,12 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Deprecated.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ExposureFunctions.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.deprecated.hlsl" #define kDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) // standard dielectric reflectivity coef at incident angle (= 4%) -struct BRDFData -{ - half3 albedo; - half3 diffuse; - half3 specular; - half reflectivity; - half perceptualRoughness; - half roughness; - half roughness2; - half grazingTerm; - - // We save some light invariant BRDF terms so we don't have to recompute - // them in the light loop. Take a look at DirectBRDF function for detailed explaination. - half normalizationTerm; // roughness * 4.0 + 2.0 - half roughness2MinusOne; // roughness^2 - 1.0 -}; - half ReflectivitySpecular(half3 specular) { return Max3(specular.r, specular.g, specular.b); @@ -48,58 +34,59 @@ half MetallicFromReflectivity(half reflectivity) return (reflectivity - kDielectricSpec.r) / oneMinusDielectricSpec; } -inline void InitializeBRDFDataDirect(half3 albedo, half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, inout half alpha, out BRDFData outBRDFData) +inline BRDFData InitializeBRDFDataDirect(half3 albedo, half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, half alpha, bool useAlphaPremultiply) { - outBRDFData = (BRDFData)0; - outBRDFData.albedo = albedo; - outBRDFData.diffuse = diffuse; - outBRDFData.specular = specular; - outBRDFData.reflectivity = reflectivity; - - outBRDFData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness); - outBRDFData.roughness = max(PerceptualRoughnessToRoughness(outBRDFData.perceptualRoughness), HALF_MIN_SQRT); - outBRDFData.roughness2 = max(outBRDFData.roughness * outBRDFData.roughness, HALF_MIN); - outBRDFData.grazingTerm = saturate(smoothness + reflectivity); - outBRDFData.normalizationTerm = outBRDFData.roughness * half(4.0) + half(2.0); - outBRDFData.roughness2MinusOne = outBRDFData.roughness2 - half(1.0); + BRDFData brdfData = (BRDFData)0; + brdfData.albedo = albedo; + brdfData.diffuse = diffuse; + brdfData.specular = specular; + brdfData.reflectivity = reflectivity; + + brdfData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness); + brdfData.roughness = max(PerceptualRoughnessToRoughness(brdfData.perceptualRoughness), HALF_MIN_SQRT); + brdfData.roughness2 = max(brdfData.roughness * brdfData.roughness, HALF_MIN); + brdfData.grazingTerm = saturate(smoothness + reflectivity); + brdfData.normalizationTerm = brdfData.roughness * half(4.0) + half(2.0); + brdfData.roughness2MinusOne = brdfData.roughness2 - half(1.0); // Input is expected to be non-alpha-premultiplied while ROP is set to pre-multiplied blend. // We use input color for specular, but (pre-)multiply the diffuse with alpha to complete the standard alpha blend equation. // In shader: Cs' = Cs * As, in ROP: Cs' + Cd(1-As); // i.e. we only alpha blend the diffuse part to background (transmittance). - #if defined(_ALPHAPREMULTIPLY_ON) - // TODO: would be clearer to multiply this once to accumulated diffuse lighting at end instead of the surface property. - outBRDFData.diffuse *= alpha; - #endif -} + if (useAlphaPremultiply) + brdfData.diffuse *= alpha; // TODO: would be clearer to multiply this once to accumulated diffuse lighting at end instead of the surface property. -// Legacy: do not call, will not correctly initialize albedo property. -inline void InitializeBRDFDataDirect(half3 diffuse, half3 specular, half reflectivity, half oneMinusReflectivity, half smoothness, inout half alpha, out BRDFData outBRDFData) -{ - InitializeBRDFDataDirect(half3(0.0, 0.0, 0.0), diffuse, specular, reflectivity, oneMinusReflectivity, smoothness, alpha, outBRDFData); + return brdfData; } -// Initialize BRDFData for material, managing both specular and metallic setup using shader keyword _SPECULAR_SETUP. -inline void InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, inout half alpha, out BRDFData outBRDFData) +// Initialize BRDFData for material, managing both specular and metallic setup using the isSpecularSetup flag (shader keyword _SPECULAR_SETUP). +inline BRDFData InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, bool isSpecularSetup, bool useAlphaPremultiply) { -#ifdef _SPECULAR_SETUP - half reflectivity = ReflectivitySpecular(specular); - half oneMinusReflectivity = half(1.0) - reflectivity; - half3 brdfDiffuse = albedo * oneMinusReflectivity; - half3 brdfSpecular = specular; -#else - half oneMinusReflectivity = OneMinusReflectivityMetallic(metallic); - half reflectivity = half(1.0) - oneMinusReflectivity; - half3 brdfDiffuse = albedo * oneMinusReflectivity; - half3 brdfSpecular = lerp(kDielectricSpec.rgb, albedo, metallic); -#endif + half reflectivity; + half oneMinusReflectivity; + half3 brdfDiffuse; + half3 brdfSpecular; + if (isSpecularSetup) + { + reflectivity = ReflectivitySpecular(specular); + oneMinusReflectivity = half(1.0) - reflectivity; + brdfDiffuse = albedo * oneMinusReflectivity; + brdfSpecular = specular; + } + else + { + oneMinusReflectivity = OneMinusReflectivityMetallic(metallic); + reflectivity = half(1.0) - oneMinusReflectivity; + brdfDiffuse = albedo * oneMinusReflectivity; + brdfSpecular = lerp(kDielectricSpec.rgb, albedo, metallic); + } - InitializeBRDFDataDirect(albedo, brdfDiffuse, brdfSpecular, reflectivity, oneMinusReflectivity, smoothness, alpha, outBRDFData); + return InitializeBRDFDataDirect(albedo, brdfDiffuse, brdfSpecular, reflectivity, oneMinusReflectivity, smoothness, alpha, useAlphaPremultiply); } -inline void InitializeBRDFData(inout SurfaceData surfaceData, out BRDFData brdfData) +inline BRDFData InitializeBRDFData(SurfaceData surfaceData, bool isSpecularSetup, bool useAlphaPremultiply) { - InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); + return InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, isSpecularSetup, useAlphaPremultiply); } half3 ConvertF0ForClearCoat15(half3 f0) @@ -107,22 +94,22 @@ half3 ConvertF0ForClearCoat15(half3 f0) return ConvertF0ForAirInterfaceToF0ForClearCoat15Fast(f0); } -inline void InitializeBRDFDataClearCoat(half clearCoatMask, half clearCoatSmoothness, inout BRDFData baseBRDFData, out BRDFData outBRDFData) +inline BRDFData InitializeBRDFDataClearCoat(half clearCoatMask, half clearCoatSmoothness, inout BRDFData baseBRDFData) { - outBRDFData = (BRDFData)0; - outBRDFData.albedo = half(1.0); + BRDFData coatBRDFData = (BRDFData)0; + coatBRDFData.albedo = half(1.0); // Calculate Roughness of Clear Coat layer - outBRDFData.diffuse = kDielectricSpec.aaa; // 1 - kDielectricSpec - outBRDFData.specular = kDielectricSpec.rgb; - outBRDFData.reflectivity = kDielectricSpec.r; + coatBRDFData.diffuse = kDielectricSpec.aaa; // 1 - kDielectricSpec + coatBRDFData.specular = kDielectricSpec.rgb; + coatBRDFData.reflectivity = kDielectricSpec.r; - outBRDFData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(clearCoatSmoothness); - outBRDFData.roughness = max(PerceptualRoughnessToRoughness(outBRDFData.perceptualRoughness), HALF_MIN_SQRT); - outBRDFData.roughness2 = max(outBRDFData.roughness * outBRDFData.roughness, HALF_MIN); - outBRDFData.normalizationTerm = outBRDFData.roughness * half(4.0) + half(2.0); - outBRDFData.roughness2MinusOne = outBRDFData.roughness2 - half(1.0); - outBRDFData.grazingTerm = saturate(clearCoatSmoothness + kDielectricSpec.x); + coatBRDFData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(clearCoatSmoothness); + coatBRDFData.roughness = max(PerceptualRoughnessToRoughness(coatBRDFData.perceptualRoughness), HALF_MIN_SQRT); + coatBRDFData.roughness2 = max(coatBRDFData.roughness * coatBRDFData.roughness, HALF_MIN); + coatBRDFData.normalizationTerm = coatBRDFData.roughness * half(4.0) + half(2.0); + coatBRDFData.roughness2MinusOne = coatBRDFData.roughness2 - half(1.0); + coatBRDFData.grazingTerm = saturate(clearCoatSmoothness + kDielectricSpec.x); // Modify Roughness of base layer using coat IOR half ieta = lerp(1.0h, CLEAR_COAT_IETA, clearCoatMask); @@ -140,18 +127,18 @@ inline void InitializeBRDFDataClearCoat(half clearCoatMask, half clearCoatSmooth // Darken/saturate base layer using coat to surface reflectance (vs. air to surface) baseBRDFData.specular = lerp(baseBRDFData.specular, ConvertF0ForClearCoat15(baseBRDFData.specular), clearCoatMask); // TODO: what about diffuse? at least in specular workflow diffuse should be recalculated as it directly depends on it. + + return coatBRDFData; } -BRDFData CreateClearCoatBRDFData(SurfaceData surfaceData, inout BRDFData brdfData) +// Placeholder for BRDFData that a disabled feature path leaves unused. The normalization term +// is the roughness-0 value (4 * roughness + 2) so a constant-folded disabled path cannot divide +// by zero in DirectBRDFSpecular, which the compiler reports as a warning. +BRDFData CreateEmptyBRDFData() { - BRDFData brdfDataClearCoat = (BRDFData)0; - - #if defined(_CLEARCOAT) || defined(_CLEARCOATMAP) - // base brdfData is modified here, rely on the compiler to eliminate dead computation by InitializeBRDFData() - InitializeBRDFDataClearCoat(surfaceData.clearCoatMask, surfaceData.clearCoatSmoothness, brdfData, brdfDataClearCoat); - #endif - - return brdfDataClearCoat; + BRDFData brdfData = (BRDFData)0; + brdfData.normalizationTerm = half(2.0); + return brdfData; } // Computes the specular term for EnvironmentBRDF @@ -280,13 +267,11 @@ half3 DirectBDRF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half // * NDF [Modified] GGX // * Modified Kelemen and Szirmay-Kalos for Visibility term // * Fresnel approximated with 1/LdotH -half3 DirectBRDF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS) +half3 DirectBRDF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS, bool useSpecularHighlights) { -#ifndef _SPECULARHIGHLIGHTS_OFF - return brdfData.diffuse + DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS) * brdfData.specular; -#else + if (useSpecularHighlights) + return brdfData.diffuse + DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS) * brdfData.specular; return brdfData.diffuse; -#endif } #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl new file mode 100644 index 00000000000..4a6d79b0cae --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl @@ -0,0 +1,21 @@ +#ifndef UNIVERSAL_BRDF_DATA_INCLUDED +#define UNIVERSAL_BRDF_DATA_INCLUDED + +struct BRDFData +{ + half3 albedo; + half3 diffuse; + half3 specular; + half reflectivity; + half perceptualRoughness; + half roughness; + half roughness2; + half grazingTerm; + + // We save some light invariant BRDF terms so we don't have to recompute + // them in the light loop. Take a look at DirectBRDF function for detailed explaination. + half normalizationTerm; // roughness * 4.0 + 2.0 + half roughness2MinusOne; // roughness^2 - 1.0 +}; + +#endif // UNIVERSAL_BRDF_DATA_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl.meta new file mode 100644 index 00000000000..022b1ee2ffd --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0e1d479cb8c88456695afb7a615f238c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl index 15adf9e5f51..2c9065121a9 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl @@ -21,6 +21,8 @@ #undef _ADDITIONAL_LIGHTS_VERTEX #endif +#define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR 1 + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl new file mode 100644 index 00000000000..07a32ab68a4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl @@ -0,0 +1,70 @@ +#ifndef UNIVERSAL_DBUFFER_DEPRECATED_INCLUDED +#define UNIVERSAL_DBUFFER_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (DBuffer.hlsl). + +void ApplyDecalSpecular(float4 positionCS, inout half3 baseColor, inout half3 specularColor, inout half3 normalWS, inout half occlusion, inout half smoothness); +void ApplyDecalMetallic(float4 positionCS, inout half3 baseColor, inout half3 normalWS, inout half metallic, inout half occlusion, inout half smoothness); +void ApplyDecalToSurfaceData(float4 positionCS, inout SurfaceData surfaceData, inout InputData inputData, bool specularSetup); + +#if !defined(_SPECULAR_SETUP_KEYWORD_DECLARED) + #if !defined(_SPECULAR_SETUP) + #define _SPECULAR_SETUP 0 + #define _SPECULAR_SETUP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_SETUP) + #undef _SPECULAR_SETUP + #define _SPECULAR_SETUP 1 + #endif +#endif + +#if !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef _SURFACE_TYPE_TRANSPARENT + #define _SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif + +// Deprecated. Use ApplyDecalSpecular or ApplyDecalMetallic. +void ApplyDecal(float4 positionCS, + inout half3 baseColor, + inout half3 specularColor, + inout half3 normalWS, + inout half metallic, + inout half occlusion, + inout half smoothness) +{ + if (_SURFACE_TYPE_TRANSPARENT) + return; + + if (_SPECULAR_SETUP) + ApplyDecalSpecular(positionCS, baseColor, specularColor, normalWS, occlusion, smoothness); + else + ApplyDecalMetallic(positionCS, baseColor, normalWS, metallic, occlusion, smoothness); +} + +// Deprecated. Use ApplyDecalToSurfaceData(positionCS, surfaceData, inputData, specularSetup). +void ApplyDecalToSurfaceData(float4 positionCS, inout SurfaceData surfaceData, inout InputData inputData) +{ + if (!_SURFACE_TYPE_TRANSPARENT) + ApplyDecalToSurfaceData(positionCS, surfaceData, inputData, _SPECULAR_SETUP); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_SPECULAR_SETUP_DEFINED_LOCALLY) + #undef _SPECULAR_SETUP_DEFINED_LOCALLY + #undef _SPECULAR_SETUP +#endif +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT +#endif + +#endif // UNIVERSAL_DBUFFER_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl.meta new file mode 100644 index 00000000000..6c424cc8bea --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b4ffe31a36bbc4031a037408800d72fb +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl index 18617146701..1a85550547c 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl @@ -4,11 +4,14 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DecalInput.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.deprecated.hlsl" -#if (defined(_DBUFFER_MRT1) || defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)) && !defined(_SURFACE_TYPE_TRANSPARENT) -#define _DBUFFER +#if (defined(_DBUFFER_MRT1) || defined(_DBUFFER_MRT2) || defined(_DBUFFER_MRT3)) +#define _DBUFFER 1 #endif #define DBufferType0 half4 @@ -117,17 +120,11 @@ void DecodeFromDBuffer( DECLARE_DBUFFER_TEXTURE(_DBufferTexture); -void ApplyDecal(float4 positionCS, - inout half3 baseColor, - inout half3 specularColor, - inout half3 normalWS, - inout half metallic, - inout half occlusion, - inout half smoothness) +// Blends the decal base color and normal into the surface; shared by the workflow-specific entry points below. +void ApplyDecalToBaseColorAndNormal(float4 positionCS, inout half3 baseColor, inout half3 normalWS, out DecalSurfaceData decalSurfaceData) { FETCH_DBUFFER(DBuffer, _DBufferTexture, int2(positionCS.xy)); - DecalSurfaceData decalSurfaceData; DECODE_FROM_DBUFFER(DBuffer, decalSurfaceData); // using alpha compositing https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html, mean weight of 1 is neutral @@ -142,17 +139,45 @@ void ApplyDecal(float4 positionCS, normalWS.xyz = SafeNormalize(normalWS.xyz * decalSurfaceData.normalWS.w + decalSurfaceData.normalWS.xyz); } #endif +} + +// Applies the decal to a specular-workflow surface (_SPECULAR_SETUP). +void ApplyDecalSpecular(float4 positionCS, + inout half3 baseColor, + inout half3 specularColor, + inout half3 normalWS, + inout half occlusion, + inout half smoothness) +{ + DecalSurfaceData decalSurfaceData; + ApplyDecalToBaseColorAndNormal(positionCS, baseColor, normalWS, decalSurfaceData); #if defined(_DBUFFER_MRT3) -#ifdef _SPECULAR_SETUP if (decalSurfaceData.MAOSAlpha.x < 1.0) { half3 decalSpecularColor = ComputeFresnel0((decalSurfaceData.baseColor.w < 1.0) ? decalSurfaceData.baseColor.xyz : half3(1.0, 1.0, 1.0), decalSurfaceData.metallic, DEFAULT_SPECULAR_VALUE); specularColor = specularColor * decalSurfaceData.MAOSAlpha + decalSpecularColor * (1.0f - decalSurfaceData.MAOSAlpha); } -#else - metallic = metallic * decalSurfaceData.MAOSAlpha + decalSurfaceData.metallic; + + occlusion = occlusion * decalSurfaceData.MAOSAlpha + decalSurfaceData.occlusion; + + smoothness = smoothness * decalSurfaceData.MAOSAlpha + decalSurfaceData.smoothness; #endif +} + +// Applies the decal to a metallic-workflow surface. +void ApplyDecalMetallic(float4 positionCS, + inout half3 baseColor, + inout half3 normalWS, + inout half metallic, + inout half occlusion, + inout half smoothness) +{ + DecalSurfaceData decalSurfaceData; + ApplyDecalToBaseColorAndNormal(positionCS, baseColor, normalWS, decalSurfaceData); + +#if defined(_DBUFFER_MRT3) + metallic = metallic * decalSurfaceData.MAOSAlpha + decalSurfaceData.metallic; occlusion = occlusion * decalSurfaceData.MAOSAlpha + decalSurfaceData.occlusion; @@ -175,39 +200,30 @@ void ApplyDecalToBaseColor(float4 positionCS, inout half3 baseColor) void ApplyDecalToBaseColorAndNormal(float4 positionCS, inout half3 baseColor, inout half3 normalWS) { - half3 specular = 0; - half metallic = 0; - half occlusion = 0; - half smoothness = 0; - ApplyDecal(positionCS, - baseColor, - specular, - normalWS, - metallic, - occlusion, - smoothness); + DecalSurfaceData decalSurfaceData; + ApplyDecalToBaseColorAndNormal(positionCS, baseColor, normalWS, decalSurfaceData); } -void ApplyDecalToSurfaceData(float4 positionCS, inout SurfaceData surfaceData, inout InputData inputData) +void ApplyDecalToSurfaceData(float4 positionCS, inout SurfaceData surfaceData, inout InputData inputData, bool isSpecularSetup) { -#ifdef _SPECULAR_SETUP - half metallic = 0; - ApplyDecal(positionCS, - surfaceData.albedo, - surfaceData.specular, - inputData.normalWS, - metallic, - surfaceData.occlusion, - surfaceData.smoothness); -#else - half3 specular = 0; - ApplyDecal(positionCS, - surfaceData.albedo, - specular, - inputData.normalWS, - surfaceData.metallic, - surfaceData.occlusion, - surfaceData.smoothness); -#endif + if (isSpecularSetup) + { + ApplyDecalSpecular(positionCS, + surfaceData.albedo, + surfaceData.specular, + inputData.normalWS, + surfaceData.occlusion, + surfaceData.smoothness); + } + else + { + ApplyDecalMetallic(positionCS, + surfaceData.albedo, + inputData.normalWS, + surfaceData.metallic, + surfaceData.occlusion, + surfaceData.smoothness); + } } + #endif // UNIVERSAL_DBUFFER_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl new file mode 100644 index 00000000000..8823291608d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl @@ -0,0 +1,40 @@ +#ifndef UNIVERSAL_DEBUGGING3D_DEPRECATED_INCLUDED +#define UNIVERSAL_DEBUGGING3D_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +#if defined(DEBUG_DISPLAY) + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (Debugging3D.hlsl). + +bool UpdateSurfaceAndInputDataForDebug(inout SurfaceData surfaceData, inout InputData inputData, bool normalMap); + +#if !defined(_NORMALMAP_KEYWORD_DECLARED) + #if !defined(_NORMALMAP) + #define _NORMALMAP 0 + #define _NORMALMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_NORMALMAP) + #undef _NORMALMAP + #define _NORMALMAP 1 + #endif +#endif + +// Deprecated. Use UpdateSurfaceAndInputDataForDebug(surfaceData, inputData, normalMap). +bool UpdateSurfaceAndInputDataForDebug(inout SurfaceData surfaceData, inout InputData inputData) +{ + return UpdateSurfaceAndInputDataForDebug(surfaceData, inputData, _NORMALMAP); +} + +// Prevents leaking the fallback keyword definition to shaders that include this file. +#if defined(_NORMALMAP_DEFINED_LOCALLY) + #undef _NORMALMAP_DEFINED_LOCALLY + #undef _NORMALMAP +#endif + +#endif // defined(DEBUG_DISPLAY) + +#endif // UNIVERSAL_DEBUGGING3D_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl.meta new file mode 100644 index 00000000000..96adb99820b --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bb15f599527f5401bbc966539376993c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl index 0ec82181be5..c4b50df28fb 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl @@ -4,6 +4,8 @@ // Ensure that we always include "DebuggingCommon.hlsl" even if we don't use it - saves extraneous includes elsewhere... #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/DebuggingCommon.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.deprecated.hlsl" #if defined(DEBUG_DISPLAY) @@ -48,7 +50,7 @@ void SetupDebugDataTerrain(inout InputData inputData) inputData.streamInfo = TERRAIN_STREAM_INFO; } -bool UpdateSurfaceAndInputDataForDebug(inout SurfaceData surfaceData, inout InputData inputData) +bool UpdateSurfaceAndInputDataForDebug(inout SurfaceData surfaceData, inout InputData inputData, bool useNormalMap) { bool changed = false; @@ -83,11 +85,10 @@ bool UpdateSurfaceAndInputDataForDebug(inout SurfaceData surfaceData, inout Inpu if (_DebugLightingMode == DEBUGLIGHTINGMODE_LIGHTING_WITHOUT_NORMAL_MAPS || _DebugLightingMode == DEBUGLIGHTINGMODE_REFLECTIONS) { const half3 normalTS = half3(0, 0, 1); - #if defined(_NORMALMAP) - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); - #else - inputData.normalWS = inputData.normalWS; - #endif + if (useNormalMap) + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + else + inputData.normalWS = inputData.normalWS; surfaceData.normalTS = normalTS; changed = true; } @@ -321,18 +322,17 @@ bool CanDebugOverrideOutputColor(inout InputData inputData, inout SurfaceData su #if defined(_SCREEN_SPACE_IRRADIANCE) // In screen space irradiance mode the final pixel values have already been resolved so we cannot reevaluate here. - #elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.dynamicLightmapUV.xy, inputData.vertexSH, inputData.normalWS); - #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(inputData.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - inputData.probeOcclusion, - inputData.shadowMask); #else - inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.vertexSH, inputData.normalWS); + GIParams giParams = (GIParams)0; + giParams.staticLightmapUV = inputData.staticLightmapUV; + giParams.dynamicLightmapUV = inputData.dynamicLightmapUV; + giParams.vertexSH = inputData.vertexSH; + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + giParams.vertexProbeOcclusion = inputData.probeOcclusion; + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); #endif } } @@ -373,18 +373,17 @@ bool CanDebugOverrideOutputColor(inout InputData inputData, inout SurfaceData su #if defined(_SCREEN_SPACE_IRRADIANCE) // In screen space irradiance mode the final pixel values have already been resolved so we cannot reevaluate here. - #elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.dynamicLightmapUV.xy, inputData.vertexSH, inputData.normalWS); - #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(inputData.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - inputData.probeOcclusion, - inputData.shadowMask); #else - inputData.bakedGI = SAMPLE_GI(inputData.staticLightmapUV, inputData.vertexSH, inputData.normalWS); + GIParams giParams = (GIParams)0; + giParams.staticLightmapUV = inputData.staticLightmapUV; + giParams.dynamicLightmapUV = inputData.dynamicLightmapUV; + giParams.vertexSH = inputData.vertexSH; + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + giParams.vertexProbeOcclusion = inputData.probeOcclusion; + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); #endif } } diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl index 84791188b03..dd7557eedaa 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl @@ -36,6 +36,11 @@ #endif #endif +bool DistanceFogAvailable() +{ + return FOG_LINEAR || FOG_EXP || FOG_EXP2; +} + // Calculate a normalized fog blend factor in [0,1] range. // Returns 1 when 'nearToFarZ' = 0, decreasing towards 0 as 'nearToFarZ' // approaches the distance between the near and far-plane (far-near). @@ -96,7 +101,7 @@ float DistanceFogNearToFarZ(float4 positionCS) // Blending parameters are derived from fragment coordinates (SV_Position). half3 BlendDistanceFogColor(half3 color, float4 positionCS, half3 fogColor) { - if ((FOG_LINEAR || FOG_EXP || FOG_EXP2) && IsFogEnabled()) + if (DistanceFogAvailable() && IsFogEnabled()) { half t = DistanceFogOcclusionFactor(DistanceFogNearToFarZ(positionCS)); // UUM-61728: manual lerp avoids Vulkan artifacts on some GPUs @@ -108,7 +113,7 @@ half3 BlendDistanceFogColor(half3 color, float4 positionCS, half3 fogColor) float3 BlendDistanceFogColor(float3 color, float4 positionCS, float3 fogColor) { - if ((FOG_LINEAR || FOG_EXP || FOG_EXP2) && IsFogEnabled()) + if (DistanceFogAvailable() && IsFogEnabled()) { float t = DistanceFogOcclusionFactor(DistanceFogNearToFarZ(positionCS)); color = lerp(fogColor, color, t); @@ -121,7 +126,7 @@ float3 BlendDistanceFogColor(float3 color, float4 positionCS, float3 fogColor) // Blending parameters are derived from explicit eye depth ('linearEyeDepth' is view-space z). half3 BlendDistanceFogColorFromEyeDepth(half3 color, float linearEyeDepth, half3 fogColor) { - if ((FOG_LINEAR || FOG_EXP || FOG_EXP2) && IsFogEnabled()) + if (DistanceFogAvailable() && IsFogEnabled()) { half t = DistanceFogOcclusionFactor(linearEyeDepth - _ProjectionParams.y); // UUM-61728: manual lerp avoids Vulkan artifacts on some GPUs @@ -133,7 +138,7 @@ half3 BlendDistanceFogColorFromEyeDepth(half3 color, float linearEyeDepth, half3 float3 BlendDistanceFogColorFromEyeDepth(float3 color, float linearEyeDepth, float3 fogColor) { - if ((FOG_LINEAR || FOG_EXP || FOG_EXP2) && IsFogEnabled()) + if (DistanceFogAvailable() && IsFogEnabled()) { float t = DistanceFogOcclusionFactor(linearEyeDepth - _ProjectionParams.y); color = lerp(fogColor, color, t); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl index de75030e2ca..15f5fbc7f0a 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl @@ -5,7 +5,6 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" // Material flags: @@ -24,11 +23,7 @@ #define GBUFFER_FEATURE_DEPTH 1 #endif -#if defined(SHADOWS_SHADOWMASK) - #define GBUFFER_FEATURE_SHADOWMASK 1 -#elif !defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) - #define GBUFFER_FEATURE_SHADOWMASK 1 -#elif defined(_DEFERRED_MIXED_LIGHTING) +#if defined(SHADOWS_SHADOWMASK) || defined(LIGHTMAP_SHADOW_MIXING) || defined(_DEFERRED_MIXED_LIGHTING) #define GBUFFER_FEATURE_SHADOWMASK 1 #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl new file mode 100644 index 00000000000..0c997b76632 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl @@ -0,0 +1,33 @@ +#ifndef UNIVERSAL_GBUFFER_FRAG_OUTPUT_INCLUDED +#define UNIVERSAL_GBUFFER_FRAG_OUTPUT_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl" + +#define DECL_SV_TARGET(idx) SV_Target##idx +#define DECL_OPT_GBUFFER_TARGET(type, name, idx) type name : DECL_SV_TARGET(GBUFFER_IDX_AFTER(idx)) + +// URP GBuffer pass fragment shader output struct. +struct GBufferFragOutput +{ + half4 gBuffer0 : SV_Target0; + half4 gBuffer1 : SV_Target1; + half4 gBuffer2 : SV_Target2; + half4 color : SV_Target3; // Camera color attachment, used for GI during GBuffer laydown + + #if defined(GBUFFER_FEATURE_DEPTH) + DECL_OPT_GBUFFER_TARGET(float, depth, GBUFFER_IDX_R_DEPTH); + #endif + + #if defined(GBUFFER_FEATURE_SHADOWMASK) + DECL_OPT_GBUFFER_TARGET(half4, shadowMask, GBUFFER_IDX_RGBA_SHADOWMASK); + #endif + + #if defined(GBUFFER_FEATURE_RENDERING_LAYERS) + DECL_OPT_GBUFFER_TARGET(uint, meshRenderingLayers, GBUFFER_IDX_R_RENDERING_LAYERS); + #endif +}; + +#undef DECL_SV_TARGET +#undef DECL_OPT_GBUFFER_TARGET + +#endif // UNIVERSAL_GBUFFER_FRAG_OUTPUT_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl.meta new file mode 100644 index 00000000000..e3b74325898 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 69637d96f9c7b45e5babfb6b87a72835 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferInput.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferInput.hlsl index 295bcc5a9eb..3322b020805 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferInput.hlsl @@ -153,9 +153,6 @@ BRDFData GBufferDataToBRDFData(GBufferData gBufferData) uint materialFlags = gBufferData.materialFlags; half smoothness = gBufferData.smoothness; - BRDFData brdfData = (BRDFData)0; - half alpha = half(1.0); // NOTE: alpha can get modfied, forward writes it out (_ALPHAPREMULTIPLY_ON). - half3 brdfDiffuse; half3 brdfSpecular; half reflectivity; @@ -179,9 +176,7 @@ BRDFData GBufferDataToBRDFData(GBufferData gBufferData) brdfSpecular = lerp(kDielectricSpec.rgb, albedo, metallic); } - InitializeBRDFDataDirect(albedo, brdfDiffuse, brdfSpecular, reflectivity, oneMinusReflectivity, smoothness, alpha, brdfData); - - return brdfData; + return InitializeBRDFDataDirect(albedo, brdfDiffuse, brdfSpecular, reflectivity, oneMinusReflectivity, smoothness, half(1.0), false); } #ifdef GBUFFER_TEX2D_NAME diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl new file mode 100644 index 00000000000..e0ee03ba150 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl @@ -0,0 +1,74 @@ +#ifndef UNIVERSAL_GBUFFEROUTPUT_DEPRECATED_INCLUDED +#define UNIVERSAL_GBUFFEROUTPUT_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (GBufferOutput.hlsl). + +GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inputData, half3 globalIllumination, bool receiveShadows); +GBufferFragOutput PackGBuffersBRDFData(BRDFData brdfData, InputData inputData, half smoothness, half3 globalIllumination, half occlusion, bool receiveShadows, bool specularSetup, bool specularHighlights); + +#if !defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) + #if !defined(_RECEIVE_SHADOWS_OFF) + #define _RECEIVE_SHADOWS_OFF 0 + #define _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + #undef _RECEIVE_SHADOWS_OFF + #define _RECEIVE_SHADOWS_OFF 1 + #endif +#endif + +#if !defined(_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED) + #if !defined(_SPECULARHIGHLIGHTS_OFF) + #define _SPECULARHIGHLIGHTS_OFF 0 + #define _SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULARHIGHLIGHTS_OFF) + #undef _SPECULARHIGHLIGHTS_OFF + #define _SPECULARHIGHLIGHTS_OFF 1 + #endif +#endif + +#if !defined(_SPECULAR_SETUP_KEYWORD_DECLARED) + #if !defined(_SPECULAR_SETUP) + #define _SPECULAR_SETUP 0 + #define _SPECULAR_SETUP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_SETUP) + #undef _SPECULAR_SETUP + #define _SPECULAR_SETUP 1 + #endif +#endif + +// Deprecated. Use PackGBuffersSurfaceData(surfaceData, inputData, globalIllumination, receiveShadows). +GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inputData, half3 globalIllumination) +{ + return PackGBuffersSurfaceData(surfaceData, inputData, globalIllumination, !_RECEIVE_SHADOWS_OFF); +} + +// Deprecated. Use PackGBuffersBRDFData(brdfData, inputData, smoothness, globalIllumination, occlusion, receiveShadows, specularSetup, specularHighlights). +GBufferFragOutput PackGBuffersBRDFData(BRDFData brdfData, InputData inputData, half smoothness, half3 globalIllumination, half occlusion = 1.0) +{ + return PackGBuffersBRDFData(brdfData, inputData, smoothness, globalIllumination, occlusion, !_RECEIVE_SHADOWS_OFF, _SPECULAR_SETUP, !_SPECULARHIGHLIGHTS_OFF); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY) + #undef _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY + #undef _RECEIVE_SHADOWS_OFF +#endif + +#if defined(_SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY) + #undef _SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY + #undef _SPECULARHIGHLIGHTS_OFF +#endif + +#if defined(_SPECULAR_SETUP_DEFINED_LOCALLY) + #undef _SPECULAR_SETUP_DEFINED_LOCALLY + #undef _SPECULAR_SETUP +#endif + +#endif // UNIVERSAL_GBUFFEROUTPUT_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl.meta new file mode 100644 index 00000000000..2f4acca2c25 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 883b44297912e43b188616a1ee0b1417 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl index bf343962d59..31d07dedb95 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl @@ -6,36 +6,13 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" - -#define DECL_SV_TARGET(idx) SV_Target##idx -#define DECL_OPT_GBUFFER_TARGET(type, name, idx) type name : DECL_SV_TARGET(GBUFFER_IDX_AFTER(idx)) - -// URP GBuffer pass fragment shader output struct. -struct GBufferFragOutput -{ - half4 gBuffer0 : SV_Target0; - half4 gBuffer1 : SV_Target1; - half4 gBuffer2 : SV_Target2; - half4 color : SV_Target3; // Camera color attachment, used for GI during GBuffer laydown - - #if defined(GBUFFER_FEATURE_DEPTH) - DECL_OPT_GBUFFER_TARGET(float, depth, GBUFFER_IDX_R_DEPTH); - #endif - - #if defined(GBUFFER_FEATURE_SHADOWMASK) - DECL_OPT_GBUFFER_TARGET(half4, shadowMask, GBUFFER_IDX_RGBA_SHADOWMASK); - #endif - - #if defined(GBUFFER_FEATURE_RENDERING_LAYERS) - DECL_OPT_GBUFFER_TARGET(uint, meshRenderingLayers, GBUFFER_IDX_R_RENDERING_LAYERS); - #endif -}; - -#undef DECL_SV_TARGET -#undef DECL_OPT_GBUFFER_TARGET +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferFragOutput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.deprecated.hlsl" // Pack SurfaceData into GBuffers. -GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inputData, half3 globalIllumination) +GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inputData, half3 globalIllumination, bool receiveShadows) { half3 packedNormalWS = PackGBufferNormal(inputData.normalWS); @@ -43,13 +20,11 @@ GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inp // SimpleLit does not use _SPECULARHIGHLIGHTS_OFF to disable specular highlights. - #ifdef _RECEIVE_SHADOWS_OFF - materialFlags |= kMaterialFlagReceiveShadowsOff; - #endif + if (!receiveShadows) + materialFlags |= kMaterialFlagReceiveShadowsOff; - #if defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) - materialFlags |= kMaterialFlagSubtractiveMixedLighting; - #endif + if (LightmapAvailable() && MixedLightingSubtractive()) + materialFlags |= kMaterialFlagSubtractiveMixedLighting; GBufferFragOutput output; output.gBuffer0 = half4(surfaceData.albedo.rgb, PackGBufferMaterialFlags(materialFlags)); // albedo albedo albedo materialFlags (sRGB rendertarget) @@ -73,37 +48,41 @@ GBufferFragOutput PackGBuffersSurfaceData(SurfaceData surfaceData, InputData inp } // Pack BRDFData into GBuffers. -GBufferFragOutput PackGBuffersBRDFData(BRDFData brdfData, InputData inputData, half smoothness, half3 globalIllumination, half occlusion = 1.0) +// isSpecularSetup: packs the specular color instead of reflectivity (specular vs metallic workflow). +// useSpecularHighlights: when false, silences packed specular and flags the surface so the deferred shading pass skips specular. +GBufferFragOutput PackGBuffersBRDFData(BRDFData brdfData, InputData inputData, half smoothness, half3 globalIllumination, half occlusion, bool receiveShadows, bool isSpecularSetup, bool useSpecularHighlights) { half3 packedNormalWS = PackGBufferNormal(inputData.normalWS); uint materialFlags = 0; - #ifdef _RECEIVE_SHADOWS_OFF - materialFlags |= kMaterialFlagReceiveShadowsOff; - #endif + if (!receiveShadows) + materialFlags |= kMaterialFlagReceiveShadowsOff; half3 packedSpecular; - #ifdef _SPECULAR_SETUP - materialFlags |= kMaterialFlagSpecularSetup; - packedSpecular = brdfData.specular.rgb; - #else - packedSpecular.r = brdfData.reflectivity; - packedSpecular.gb = 0.0; - #endif - - #ifdef _SPECULARHIGHLIGHTS_OFF - // During the next deferred shading pass, we don't use a shader variant to disable specular calculations. - // Instead, we can either silence specular contribution when writing the gbuffer, and/or reserve a bit in the gbuffer - // and use this during shading to skip computations via dynamic branching. Fastest option depends on platforms. - materialFlags |= kMaterialFlagSpecularHighlightsOff; - packedSpecular = 0.0.xxx; - #endif - - #if defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) - materialFlags |= kMaterialFlagSubtractiveMixedLighting; - #endif + if (isSpecularSetup) + { + materialFlags |= kMaterialFlagSpecularSetup; + packedSpecular = brdfData.specular.rgb; + } + else + { + packedSpecular.r = brdfData.reflectivity; + packedSpecular.gb = 0.0; + } + + if (!useSpecularHighlights) + { + // During the next deferred shading pass, we don't use a shader variant to disable specular calculations. + // Instead, we can either silence specular contribution when writing the gbuffer, and/or reserve a bit in the gbuffer + // and use this during shading to skip computations via dynamic branching. Fastest option depends on platforms. + materialFlags |= kMaterialFlagSpecularHighlightsOff; + packedSpecular = half3(0.0, 0.0, 0.0); + } + + if (LightmapAvailable() && MixedLightingSubtractive()) + materialFlags |= kMaterialFlagSubtractiveMixedLighting; GBufferFragOutput output; output.gBuffer0 = half4(brdfData.albedo.rgb, PackGBufferMaterialFlags(materialFlags)); // diffuse diffuse diffuse materialFlags (sRGB rendertarget) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl new file mode 100644 index 00000000000..b6f666cdf6a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl @@ -0,0 +1,136 @@ +#ifndef UNIVERSAL_GLOBAL_ILLUMINATION_DEPRECATED_INCLUDED +#define UNIVERSAL_GLOBAL_ILLUMINATION_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ExposureFunctions.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (GlobalIllumination.hlsl). + +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, + URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, + half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV, bool clearCoatEnabled, bool environmentReflections); +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, + URP_LIGHT_ACCUM3 bakedGI, half occlusion, + half3 normalWS, half3 viewDirectionWS, bool clearCoatEnabled, bool environmentReflections); +half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV, bool environmentReflections); +half3 GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion, bool environmentReflections); + +#if !defined(_CLEARCOAT_KEYWORD_DECLARED) + #if !defined(_CLEARCOAT) + #define _CLEARCOAT 0 + #define _CLEARCOAT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_CLEARCOAT) + #undef _CLEARCOAT + #define _CLEARCOAT 1 + #endif +#endif + +#if !defined(_CLEARCOATMAP_KEYWORD_DECLARED) + #if !defined(_CLEARCOATMAP) + #define _CLEARCOATMAP 0 + #define _CLEARCOATMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_CLEARCOATMAP) + #undef _CLEARCOATMAP + #define _CLEARCOATMAP 1 + #endif +#endif + +#if !defined(_ENVIRONMENTREFLECTIONS_OFF_KEYWORD_DECLARED) + #if !defined(_ENVIRONMENTREFLECTIONS_OFF) + #define _ENVIRONMENTREFLECTIONS_OFF 0 + #define _ENVIRONMENTREFLECTIONS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ENVIRONMENTREFLECTIONS_OFF) + #undef _ENVIRONMENTREFLECTIONS_OFF + #define _ENVIRONMENTREFLECTIONS_OFF 1 + #endif +#endif + +// Deprecated. Use GlobalIllumination(..., normalizedScreenSpaceUV, clearCoatEnabled, environmentReflections). +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, + URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, + half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV) +{ + return GlobalIllumination(brdfData, brdfDataClearCoat, clearCoatMask, bakedGI, occlusion, positionWS, normalWS, viewDirectionWS, normalizedScreenSpaceUV, _CLEARCOAT || _CLEARCOATMAP, !_ENVIRONMENTREFLECTIONS_OFF); +} + +#if !USE_CLUSTER_LIGHT_LOOP +// Deprecated. Use GlobalIllumination(..., normalizedScreenSpaceUV, clearCoatEnabled, environmentReflections). +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, + URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, + half3 normalWS, half3 viewDirectionWS) +{ + return GlobalIllumination(brdfData, brdfDataClearCoat, clearCoatMask, bakedGI, occlusion, positionWS, normalWS, viewDirectionWS, float2(0.0f, 0.0f), _CLEARCOAT || _CLEARCOATMAP, !_ENVIRONMENTREFLECTIONS_OFF); +} +#endif + +// Deprecated. Use GlobalIllumination(..., clearCoatEnabled, environmentReflections). +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, + URP_LIGHT_ACCUM3 bakedGI, half occlusion, + half3 normalWS, half3 viewDirectionWS) +{ + return GlobalIllumination(brdfData, brdfDataClearCoat, clearCoatMask, bakedGI, occlusion, normalWS, viewDirectionWS, _CLEARCOAT || _CLEARCOATMAP, !_ENVIRONMENTREFLECTIONS_OFF); +} + +// Deprecated. Use GlobalIllumination(..., normalizedScreenSpaceUV, clearCoatEnabled, environmentReflections). +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, half3 normalWS, half3 viewDirectionWS) +{ + const BRDFData noClearCoat = (BRDFData)0; + return GlobalIllumination(brdfData, noClearCoat, 0.0, bakedGI, occlusion, positionWS, normalWS, viewDirectionWS, float2(0.0f, 0.0f), false, !_ENVIRONMENTREFLECTIONS_OFF); +} + +// Deprecated. Use GlobalIllumination(..., clearCoatEnabled, environmentReflections). +URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, URP_LIGHT_ACCUM3 bakedGI, half occlusion, half3 normalWS, half3 viewDirectionWS) +{ + const BRDFData noClearCoat = (BRDFData)0; + return GlobalIllumination(brdfData, noClearCoat, 0.0, bakedGI, occlusion, normalWS, viewDirectionWS, false, !_ENVIRONMENTREFLECTIONS_OFF); +} + +// Deprecated. Use GlossyEnvironmentReflection(..., environmentReflections). +half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV) +{ + return GlossyEnvironmentReflection(reflectVector, positionWS, perceptualRoughness, occlusion, normalizedScreenSpaceUV, !_ENVIRONMENTREFLECTIONS_OFF); +} + +#if !USE_CLUSTER_LIGHT_LOOP +// Deprecated. Use GlossyEnvironmentReflection(..., environmentReflections). +half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion) +{ + return GlossyEnvironmentReflection(reflectVector, positionWS, perceptualRoughness, occlusion, float2(0.0f, 0.0f), !_ENVIRONMENTREFLECTIONS_OFF); +} +#endif + +// Deprecated. Use GlossyEnvironmentReflection(..., environmentReflections). +half3 GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion) +{ + return GlossyEnvironmentReflection(reflectVector, perceptualRoughness, occlusion, !_ENVIRONMENTREFLECTIONS_OFF); +} + +void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout URP_LIGHT_ACCUM3 bakedGI); + +// Deprecated. Use MixRealtimeAndBakedGI(light, normalWS, bakedGI); the shadowMask argument was never used. +void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout URP_LIGHT_ACCUM3 bakedGI, half4 shadowMask) +{ + MixRealtimeAndBakedGI(light, normalWS, bakedGI); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_CLEARCOAT_DEFINED_LOCALLY) + #undef _CLEARCOAT_DEFINED_LOCALLY + #undef _CLEARCOAT +#endif + +#if defined(_CLEARCOATMAP_DEFINED_LOCALLY) + #undef _CLEARCOATMAP_DEFINED_LOCALLY + #undef _CLEARCOATMAP +#endif + +#if defined(_ENVIRONMENTREFLECTIONS_OFF_DEFINED_LOCALLY) + #undef _ENVIRONMENTREFLECTIONS_OFF_DEFINED_LOCALLY + #undef _ENVIRONMENTREFLECTIONS_OFF +#endif + +#endif // UNIVERSAL_GLOBAL_ILLUMINATION_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl.meta new file mode 100644 index 00000000000..02ac4958255 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cea1afa18f4a3489f912c595040a8e97 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl index 17a6c164952..c0944eff02f 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl @@ -4,18 +4,19 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareExposureTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.deprecated.hlsl" -#define AMBIENT_PROBE_BUFFER 0 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/AmbientProbe.hlsl" #if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl" #endif -#if USE_CLUSTER_LIGHT_LOOP #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" #if defined(_SCREEN_SPACE_IRRADIANCE) TEXTURE2D_X(_ScreenSpaceIrradiance); @@ -34,19 +35,56 @@ URP_LIGHT_ACCUM3 SampleScreenSpaceGI(float2 pos, float invPreExposureMultiplier) // If lightmap is not defined than we evaluate GI (ambient + probes) from SH // Legacy: _MIXED_LIGHTING_SUBTRACTIVE was an alias for (LIGHTMAP_SHADOW_MIXING && !SHADOWS_SHADOWMASK). -// Derived both ways so shaders that still read or declare it keep working; nothing else should reference it. -#if !defined(_MIXED_LIGHTING_SUBTRACTIVE) && defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) - #define _MIXED_LIGHTING_SUBTRACTIVE -#elif defined(_MIXED_LIGHTING_SUBTRACTIVE) && !defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) - #define LIGHTMAP_SHADOW_MIXING 1 +// Derived here so shaders that still read it keep working; the reverse derive lives in Shadows.hlsl. +#if !defined(LIGHTMAP_SHADOW_MIXING_KEYWORD_DECLARED) && !defined(SHADOWS_SHADOWMASK_KEYWORD_DECLARED) + #if !defined(_MIXED_LIGHTING_SUBTRACTIVE) && !defined(SHADOWS_SHADOWMASK) && DEFINED_NONZERO(LIGHTMAP_SHADOW_MIXING) + #define _MIXED_LIGHTING_SUBTRACTIVE 1 + #endif #endif -#if !defined(_REFLECTION_PROBE_BLENDING_KEYWORD_DECLARED) && !defined(_REFLECTION_PROBE_BLENDING) - #define _REFLECTION_PROBE_BLENDING 0 +#if !defined(_REFLECTION_PROBE_BLENDING_KEYWORD_DECLARED) + #if !defined(_REFLECTION_PROBE_BLENDING) + static const bool _REFLECTION_PROBE_BLENDING = 0; + #elif DEFINED_NONZERO(_REFLECTION_PROBE_BLENDING) + #undef _REFLECTION_PROBE_BLENDING + #define _REFLECTION_PROBE_BLENDING 1 + #endif #endif -#if !defined(_REFLECTION_PROBE_BOX_PROJECTION_KEYWORD_DECLARED) && !defined(_REFLECTION_PROBE_BOX_PROJECTION) - #define _REFLECTION_PROBE_BOX_PROJECTION 0 +#if !defined(_REFLECTION_PROBE_BOX_PROJECTION_KEYWORD_DECLARED) + #if !defined(_REFLECTION_PROBE_BOX_PROJECTION) + static const bool _REFLECTION_PROBE_BOX_PROJECTION = 0; + #elif DEFINED_NONZERO(_REFLECTION_PROBE_BOX_PROJECTION) + #undef _REFLECTION_PROBE_BOX_PROJECTION + #define _REFLECTION_PROBE_BOX_PROJECTION 1 + #endif +#endif + +#if !defined(EVALUATE_SH_VERTEX_KEYWORD_DECLARED) + #if !defined(EVALUATE_SH_VERTEX) + static const bool EVALUATE_SH_VERTEX = 0; + #elif DEFINED_NONZERO(EVALUATE_SH_VERTEX) + #undef EVALUATE_SH_VERTEX + #define EVALUATE_SH_VERTEX 1 + #endif +#endif + +#if !defined(EVALUATE_SH_MIXED_KEYWORD_DECLARED) + #if !defined(EVALUATE_SH_MIXED) + static const bool EVALUATE_SH_MIXED = 0; + #elif DEFINED_NONZERO(EVALUATE_SH_MIXED) + #undef EVALUATE_SH_MIXED + #define EVALUATE_SH_MIXED 1 + #endif +#endif + +#if !defined(REFLECTION_PROBE_ROTATION_KEYWORD_DECLARED) + #if !defined(REFLECTION_PROBE_ROTATION) + static const bool REFLECTION_PROBE_ROTATION = 0; + #elif DEFINED_NONZERO(REFLECTION_PROBE_ROTATION) + #undef REFLECTION_PROBE_ROTATION + #define REFLECTION_PROBE_ROTATION 1 + #endif #endif // SH Vertex Evaluation. Depending on target SH sampling might be @@ -54,75 +92,101 @@ URP_LIGHT_ACCUM3 SampleScreenSpaceGI(float2 pos, float invPreExposureMultiplier) // per pixel. See SampleSHPixel half3 SampleSHVertex(half3 normalWS) { -#if defined(EVALUATE_SH_VERTEX) - return EvaluateAmbientProbeSRGB(normalWS); -#elif defined(EVALUATE_SH_MIXED) - // no max since this is only L2 contribution - return SHEvalLinearL2(normalWS, unity_SHBr, unity_SHBg, unity_SHBb, unity_SHC); -#endif + // Fully per-pixel: nothing to compute. + half3 result = half3(0.0, 0.0, 0.0); - // Fully per-pixel. Nothing to compute. - return half3(0.0, 0.0, 0.0); + if (EVALUATE_SH_VERTEX) + result = EvaluateAmbientProbeSRGB(normalWS); + else if (EVALUATE_SH_MIXED) // no max since this is only L2 contribution + result = SHEvalLinearL2(normalWS, unity_SHBr, unity_SHBg, unity_SHBb, unity_SHC); + + return result; } // SH Pixel Evaluation. Depending on target SH sampling might be done // mixed or fully in pixel. See SampleSHVertex half3 SampleSHPixel(half3 L2Term, half3 normalWS) { -#if defined(EVALUATE_SH_VERTEX) - return L2Term; -#elif defined(EVALUATE_SH_MIXED) - half3 res = L2Term + SHEvalLinearL0L1(normalWS, unity_SHAr, unity_SHAg, unity_SHAb); -#ifdef UNITY_COLORSPACE_GAMMA - res = LinearToSRGB(res); -#endif - return max(half3(0, 0, 0), res); -#endif - - // Default: Evaluate SH fully per-pixel - return EvaluateAmbientProbeSRGB(normalWS); + half3 result = half3(0.0, 0.0, 0.0); + if (EVALUATE_SH_VERTEX) + { + result = L2Term; + } + else if (EVALUATE_SH_MIXED) + { + half3 res = L2Term + SHEvalLinearL0L1(normalWS, unity_SHAr, unity_SHAg, unity_SHAb); + #ifdef UNITY_COLORSPACE_GAMMA + res = LinearToSRGB(res); + #endif + result = max(half3(0, 0, 0), res); + } + else + { + // Default: Evaluate SH fully per-pixel + result = EvaluateAmbientProbeSRGB(normalWS); + } + return result; } // APV Prove volume // Vertex and Mixed both use Vertex sampling -#if (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) -// APV reads its data from StructuredBuffers (SSBOs). On GLES, vertex-stage SSBO support is -// device-dependent (GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS may be 0), so referencing APV data in -// the vertex shader can fail to link. On GLES3, APV is evaluated per-pixel instead. +// APV reads its data from StructuredBuffers (SSBOs). On GLES, vertex-stage SSBO support is device-dependent +// (GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS may be 0), so sampling APV in the vertex shader can fail to link. +// Where unsupported, APV is evaluated per-pixel instead (see SampleProbeVolumePixel). +#if defined(SHADER_API_GLES3) + #define APV_VERTEX_SAMPLING_SUPPORTED 0 +#else + #define APV_VERTEX_SAMPLING_SUPPORTED 1 +#endif + half3 SampleProbeVolumeVertex(in float3 absolutePositionWS, in float3 normalWS, in float3 viewDir, out float4 probeOcclusion) { probeOcclusion = 1.0; + half3 result = half3(0, 0, 0); -#if (defined(EVALUATE_SH_VERTEX) || defined(EVALUATE_SH_MIXED)) && !defined(SHADER_API_GLES3) - half3 bakedGI; - // APV per-renderer. When MeshRenderer.lightProbeUsage == Off, fall back to the ambient sky probe (matches LightProbeGroup behavior). - if (_EnableProbeVolumes && IsLightProbeSamplingEnabled()) - { - EvaluateAdaptiveProbeVolume(absolutePositionWS, normalWS, viewDir, GetMeshRenderingLayer(), bakedGI, probeOcclusion); - } - else +#if (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && APV_VERTEX_SAMPLING_SUPPORTED + + if (EVALUATE_SH_VERTEX || EVALUATE_SH_MIXED) { - bakedGI = EvaluateAmbientProbe(normalWS); + half3 bakedGI; + + if (_EnableProbeVolumes && IsLightProbeSamplingEnabled()) + { + EvaluateAdaptiveProbeVolume(absolutePositionWS, normalWS, viewDir, GetMeshRenderingLayer(), bakedGI, probeOcclusion); + } + else + { + bakedGI = EvaluateAmbientProbe(normalWS); + } + + #ifdef UNITY_COLORSPACE_GAMMA + bakedGI = LinearToSRGB(bakedGI); + #endif + + result = bakedGI; } -#ifdef UNITY_COLORSPACE_GAMMA - bakedGI = LinearToSRGB(bakedGI); -#endif - return bakedGI; -#else - return half3(0, 0, 0); + #endif + + return result; } half3 SampleProbeVolumePixel(in half3 vertexValue, in float3 absolutePositionWS, in float3 normalWS, in float3 viewDir, in float2 positionSS, in float4 vertexProbeOcclusion, out float4 probeOcclusion) { probeOcclusion = 1.0; -#if (defined(EVALUATE_SH_VERTEX) || defined(EVALUATE_SH_MIXED)) && !defined(SHADER_API_GLES3) - probeOcclusion = vertexProbeOcclusion; - return vertexValue; -#elif defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) +#if APV_VERTEX_SAMPLING_SUPPORTED + if (EVALUATE_SH_VERTEX || EVALUATE_SH_MIXED) + { + probeOcclusion = vertexProbeOcclusion; + return vertexValue; + } +#endif + +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) half3 bakedGI; + // APV per-renderer. When MeshRenderer.lightProbeUsage == Off, fall back to the ambient sky probe (matches LightProbeGroup behavior). if (_EnableProbeVolumes && IsLightProbeSamplingEnabled()) { EvaluateAdaptiveProbeVolume(absolutePositionWS, normalWS, viewDir, positionSS, GetMeshRenderingLayer(), bakedGI, probeOcclusion); @@ -132,7 +196,7 @@ half3 SampleProbeVolumePixel(in half3 vertexValue, in float3 absolutePositionWS, bakedGI = EvaluateAmbientProbe(normalWS); } #ifdef UNITY_COLORSPACE_GAMMA - bakedGI = LinearToSRGB(bakedGI); + bakedGI = LinearToSRGB(bakedGI); #endif return bakedGI; #else @@ -145,7 +209,6 @@ half3 SampleProbeVolumePixel(in half3 vertexValue, in float3 absolutePositionWS, float4 unusedProbeOcclusion = 0; return SampleProbeVolumePixel(vertexValue, absolutePositionWS, normalWS, viewDir, positionSS, unusedProbeOcclusion, unusedProbeOcclusion); } -#endif half3 SampleProbeSHVertex(in float3 absolutePositionWS, in float3 normalWS, in float3 viewDir, out float4 probeOcclusion) { @@ -164,74 +227,40 @@ half3 SampleProbeSHVertex(in float3 absolutePositionWS, in float3 normalWS, in f return SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir, unusedProbeOcclusion); } -#if defined(UNITY_DOTS_INSTANCING_ENABLED) && !defined(USE_LEGACY_LIGHTMAPS) -// ^ GPU-driven rendering is enabled, and we haven't opted-out from lightmap -// texture arrays. This minimizes batch breakages, but texture arrays aren't -// supported in a performant way on all GPUs. -#define LIGHTMAP_NAME unity_Lightmaps -#define LIGHTMAP_INDIRECTION_NAME unity_LightmapsInd -#define LIGHTMAP_SAMPLER_NAME samplerunity_Lightmaps -#define LIGHTMAP_SAMPLE_EXTRA_ARGS staticLightmapUV, unity_LightmapIndex.x -#else -// ^ Lightmaps are not bound as texture arrays, but as individual textures. The -// batch is broken every time lightmaps are changed, but this is well-supported -// on all GPUs. -#define LIGHTMAP_NAME unity_Lightmap -#define LIGHTMAP_INDIRECTION_NAME unity_LightmapInd -#define LIGHTMAP_SAMPLER_NAME samplerunity_Lightmap -#define LIGHTMAP_SAMPLE_EXTRA_ARGS staticLightmapUV -#endif - -// Sample baked and/or realtime lightmap. Non-Direction and Directional if available. -half3 SampleLightmap(float2 staticLightmapUV, float2 dynamicLightmapUV, half3 normalWS) -{ - // The shader library sample lightmap functions transform the lightmap uv coords to apply bias and scale. - // However, universal pipeline already transformed those coords in vertex. We pass half4(1, 1, 0, 0) and - // the compiler will optimize the transform away. - half4 transformCoords = half4(1, 1, 0, 0); - - float3 diffuseLighting = 0; - -#if defined(LIGHTMAP_ON) && defined(DIRLIGHTMAP_COMBINED) - diffuseLighting = SampleDirectionalLightmap(TEXTURE2D_LIGHTMAP_ARGS(LIGHTMAP_NAME, LIGHTMAP_SAMPLER_NAME), - TEXTURE2D_LIGHTMAP_ARGS(LIGHTMAP_INDIRECTION_NAME, LIGHTMAP_SAMPLER_NAME), - LIGHTMAP_SAMPLE_EXTRA_ARGS, transformCoords, normalWS, true); -#elif defined(LIGHTMAP_ON) - diffuseLighting = SampleSingleLightmap(TEXTURE2D_LIGHTMAP_ARGS(LIGHTMAP_NAME, LIGHTMAP_SAMPLER_NAME), LIGHTMAP_SAMPLE_EXTRA_ARGS, transformCoords, true); -#endif - -#if defined(DYNAMICLIGHTMAP_ON) && defined(DIRLIGHTMAP_COMBINED) - diffuseLighting += SampleDirectionalLightmap(TEXTURE2D_ARGS(unity_DynamicLightmap, samplerunity_DynamicLightmap), - TEXTURE2D_ARGS(unity_DynamicDirectionality, samplerunity_DynamicLightmap), - dynamicLightmapUV, transformCoords, normalWS, false); -#elif defined(DYNAMICLIGHTMAP_ON) - diffuseLighting += SampleSingleLightmap(TEXTURE2D_ARGS(unity_DynamicLightmap, samplerunity_DynamicLightmap), - dynamicLightmapUV, transformCoords, false); -#endif - - return diffuseLighting; -} - -// Legacy version of SampleLightmap where Realtime GI is not supported. -half3 SampleLightmap(float2 staticLightmapUV, half3 normalWS) +half3 SampleLightmapOrSH(float2 staticLightmapUV, float2 dynamicLightmapUV, half3 vertexSH, half3 normalWS) { - float2 dummyDynamicLightmapUV = float2(0,0); - half3 result = SampleLightmap(staticLightmapUV, dummyDynamicLightmapUV, normalWS); - return result; + if (LightmapAvailable() || DynamicLightmapAvailable()) + return SampleLightmap(staticLightmapUV, dynamicLightmapUV, normalWS); + return SampleSHPixel(vertexSH, normalWS); } +// SAMPLE_GI exists for backward compatibility with custom shaders and ShaderGraph; +// pipeline passes call InitializeBakedGI instead. +// The shName argument may reference a struct field that only exists when the SH interpolator is +// live, so the lightmap arms may only expand it under USE_VERTEX_SH_INTERPOLATOR. That is exactly +// the runtime-branching case, where the SH fallback is needed because lightmap availability is a +// runtime property; specialized variants keep the direct SampleLightmap expansion. #if defined(_SCREEN_SPACE_IRRADIANCE) - #if !defined(_SURFACE_TYPE_TRANSPARENT) - #define SAMPLE_GI(irradianceTex, pos, normal, invPreExposureMultiplier) SampleScreenSpaceGI(pos, invPreExposureMultiplier) + // Transparent surfaces are not in the surface cache; they fall back to the ambient probe. + #define SAMPLE_GI(irradianceTex, pos, normal, invPreExposureMultiplier) (IsSurfaceTypeTransparent() ? URP_LIGHT_ACCUM3(EvaluateAmbientProbe(normal)) : SampleScreenSpaceGI(pos, invPreExposureMultiplier)) +#elif USE_LIGHTMAP_UV_INTERPOLATOR && USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + #if USE_VERTEX_SH_INTERPOLATOR + #define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmapOrSH(staticLmName, dynamicLmName, shName, normalWSName) + #else + #define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmap(staticLmName, dynamicLmName, normalWSName) + #endif +#elif USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + #if USE_VERTEX_SH_INTERPOLATOR + #define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmapOrSH(0, dynamicLmName, shName, normalWSName) + #else + #define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmap(0, dynamicLmName, normalWSName) + #endif +#elif USE_LIGHTMAP_UV_INTERPOLATOR + #if USE_VERTEX_SH_INTERPOLATOR + #define SAMPLE_GI(staticLmName, shName, normalWSName) SampleLightmapOrSH(staticLmName, 0, shName, normalWSName) #else - #define SAMPLE_GI(irradianceTex, pos, normal, invPreExposureMultiplier) EvaluateAmbientProbe(normal) + #define SAMPLE_GI(staticLmName, shName, normalWSName) SampleLightmap(staticLmName, 0, normalWSName) #endif -#elif defined(LIGHTMAP_ON) && defined(DYNAMICLIGHTMAP_ON) -#define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmap(staticLmName, dynamicLmName, normalWSName) -#elif defined(DYNAMICLIGHTMAP_ON) -#define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmap(0, dynamicLmName, normalWSName) -#elif defined(LIGHTMAP_ON) -#define SAMPLE_GI(staticLmName, shName, normalWSName) SampleLightmap(staticLmName, 0, normalWSName) #elif defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) #ifdef USE_APV_PROBE_OCCLUSION #define SAMPLE_GI(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) SampleProbeVolumePixel(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) @@ -242,6 +271,62 @@ half3 SampleLightmap(float2 staticLightmapUV, half3 normalWS) #define SAMPLE_GI(staticLmName, shName, normalWSName) SampleSHPixel(shName, normalWSName) #endif +// Inputs for InitializeBakedGI. Zero-initialize with (GIParams)0 and fill the fields the pass +// has data for; fields left zero select the corresponding neutral behavior. +struct GIParams +{ + float2 staticLightmapUV; + float2 dynamicLightmapUV; + half3 vertexSH; + float3 positionWS; + half3 normalWS; + float3 viewDirWS; + float2 positionSS; + float4 vertexProbeOcclusion; + bool isSurfaceTypeTransparent; +}; + +// Samples baked GI (lightmaps, probe volumes, SH, or screen-space irradiance, depending on the +// active configuration) and the shadow mask for a surface point. +void InitializeBakedGI(GIParams giParams, out URP_LIGHT_ACCUM3 bakedGI, out half4 shadowMask) +{ + bakedGI = 0.0; + shadowMask = half4(1, 1, 1, 1); + +#if defined(_SCREEN_SPACE_IRRADIANCE) + if (!giParams.isSurfaceTypeTransparent) + { + bakedGI = SampleScreenSpaceGI(giParams.positionSS, GetInvPreExposureMultiplier()); + } + else + { + bakedGI = EvaluateAmbientProbe(giParams.normalWS); + } +#else + if (LightmapAvailable() || DynamicLightmapAvailable()) + { + bakedGI = SampleLightmap(giParams.staticLightmapUV, giParams.dynamicLightmapUV, giParams.normalWS); + shadowMask = SampleShadowMask(giParams.staticLightmapUV); + } + #if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) + else + { + #ifdef USE_APV_PROBE_OCCLUSION + bakedGI = SampleProbeVolumePixel(giParams.vertexSH, GetAbsolutePositionWS(giParams.positionWS), giParams.normalWS, giParams.viewDirWS, giParams.positionSS, giParams.vertexProbeOcclusion, shadowMask); + #else + bakedGI = SampleProbeVolumePixel(giParams.vertexSH, GetAbsolutePositionWS(giParams.positionWS), giParams.normalWS, giParams.viewDirWS, giParams.positionSS); + #endif + } + #else + else + { + bakedGI = SampleSHPixel(giParams.vertexSH, giParams.normalWS); + shadowMask = SampleShadowMask(giParams.staticLightmapUV); + } + #endif +#endif +} + float3 GetReflectionProbeCenter(float4 boxMin, float4 boxMax) { return boxMin.xyz + (boxMax.xyz - boxMin.xyz) / 2; @@ -304,36 +389,43 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi { half3 irradiance = half3(0.0h, 0.0h, 0.0h); half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + #if USE_CLUSTER_LIGHT_LOOP && CLUSTER_HAS_REFLECTION_PROBES + float totalWeight = 0.0f; uint probeIndex; + float3 rotPosWS = positionWS; ClusterIterator it = ClusterInit(normalizedScreenSpaceUV, positionWS, 1); [loop] while (ClusterNext(it, probeIndex) && totalWeight < 0.99f) { probeIndex -= URP_FP_PROBES_BEGIN; -#if defined(REFLECTION_PROBE_ROTATION) - // We need to rotated positionWS such that we can assume the influence volumes to be axis aligned - // when calculating the weight and box projection. - float3 probeCenterPosWS = GetReflectionProbeCenter(urp_ReflProbes_BoxMin[probeIndex], urp_ReflProbes_BoxMax[probeIndex]); - float3 rotPosWS = GetRotatedPoint(probeCenterPosWS, urp_ReflProbes_Rotation[probeIndex], positionWS); -#else - float3 rotPosWS = positionWS; -#endif - float weight = CalculateProbeWeight(rotPosWS, urp_ReflProbes_BoxMin[probeIndex], urp_ReflProbes_BoxMax[probeIndex]); + float4 probeRotation = urp_ReflProbes_Rotation[probeIndex]; + float4 probePosition = urp_ReflProbes_ProbePosition[probeIndex]; + float4 probeBoxMin = urp_ReflProbes_BoxMin[probeIndex]; + float4 probeBoxMax = urp_ReflProbes_BoxMax[probeIndex]; + + if (REFLECTION_PROBE_ROTATION) + { + // We need to rotate positionWS such that we can assume the influence volumes to be axis aligned + // when calculating the weight and box projection. + float3 probeCenterPosWS = GetReflectionProbeCenter(probeBoxMin, probeBoxMax); + rotPosWS = GetRotatedPoint(probeCenterPosWS, probeRotation, positionWS); + } + + float weight = CalculateProbeWeight(rotPosWS, probeBoxMin, probeBoxMax); weight = min(weight, 1.0f - totalWeight); half3 sampleVector = reflectVector; if (_REFLECTION_PROBE_BOX_PROJECTION) { - #if defined(REFLECTION_PROBE_ROTATION) - sampleVector = BoxProjectedCubemapDirection(urp_ReflProbes_Rotation[probeIndex], reflectVector, rotPosWS, urp_ReflProbes_ProbePosition[probeIndex], urp_ReflProbes_BoxMin[probeIndex], urp_ReflProbes_BoxMax[probeIndex]); - #else - sampleVector = BoxProjectedCubemapDirection(reflectVector, rotPosWS, urp_ReflProbes_ProbePosition[probeIndex], urp_ReflProbes_BoxMin[probeIndex], urp_ReflProbes_BoxMax[probeIndex]); - #endif + if (REFLECTION_PROBE_ROTATION) + sampleVector = BoxProjectedCubemapDirection(probeRotation, reflectVector, rotPosWS, probePosition, probeBoxMin, probeBoxMax); + else + sampleVector = BoxProjectedCubemapDirection(reflectVector, rotPosWS, probePosition, probeBoxMin, probeBoxMax); } - uint maxMip = (uint)abs(urp_ReflProbes_ProbePosition[probeIndex].w) - 1; + uint maxMip = (uint)abs(probePosition.w) - 1; half probeMip = min(mip, maxMip); float2 uv = saturate(PackNormalOctQuadEncode(sampleVector) * 0.5 + 0.5); @@ -349,32 +441,40 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi irradiance += preExposure * weight * lerp(irradiance0, irradiance1, mipBlend); totalWeight += weight; } + #else -#if defined(REFLECTION_PROBE_ROTATION) - // We need to rotated positionWS such that we can assume the influence volumes to be axis aligned - // when calculating the weight and box projection. - float3 probeCenterPosWS0 = GetReflectionProbeCenter(unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - float3 rotPosWS0 = GetRotatedPoint(probeCenterPosWS0, unity_SpecCube0_Rotation, positionWS); - float3 probeCenterPosWS1 = GetReflectionProbeCenter(unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax); - float3 rotPosWS1 = GetRotatedPoint(probeCenterPosWS1, unity_SpecCube1_Rotation, positionWS); -#else + + float4 boxMin0 = unity_SpecCube0_BoxMin; + float4 boxMax0 = unity_SpecCube0_BoxMax; + float4 boxMin1 = unity_SpecCube1_BoxMin; + float4 boxMax1 = unity_SpecCube1_BoxMax; + float3 rotPosWS0 = positionWS; float3 rotPosWS1 = positionWS; -#endif - half probe0Volume = CalculateProbeVolumeSqrMagnitude(unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - half probe1Volume = CalculateProbeVolumeSqrMagnitude(unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax); + if (REFLECTION_PROBE_ROTATION) + { + // We need to rotate positionWS such that we can assume the influence volumes to be axis aligned + // when calculating the weight and box projection. + float3 probeCenterPosWS0 = GetReflectionProbeCenter(boxMin0, boxMax0); + rotPosWS0 = GetRotatedPoint(probeCenterPosWS0, unity_SpecCube0_Rotation, positionWS); + float3 probeCenterPosWS1 = GetReflectionProbeCenter(boxMin1, boxMax1); + rotPosWS1 = GetRotatedPoint(probeCenterPosWS1, unity_SpecCube1_Rotation, positionWS); + } + + half probe0Volume = CalculateProbeVolumeSqrMagnitude(boxMin0, boxMax0); + half probe1Volume = CalculateProbeVolumeSqrMagnitude(boxMin1, boxMax1); half volumeDiff = probe0Volume - probe1Volume; - float importanceSign = unity_SpecCube1_BoxMin.w; + float importanceSign = boxMin1.w; // A probe is dominant if its importance is higher // Or have equal importance but smaller volume bool probe0Dominant = importanceSign > 0.0f || (importanceSign == 0.0f && volumeDiff < -0.0001h); bool probe1Dominant = importanceSign < 0.0f || (importanceSign == 0.0f && volumeDiff > 0.0001h); - float desiredWeightProbe0 = CalculateProbeWeight(rotPosWS0, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - float desiredWeightProbe1 = CalculateProbeWeight(rotPosWS1, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax); + float desiredWeightProbe0 = CalculateProbeWeight(rotPosWS0, boxMin0, boxMax0); + float desiredWeightProbe1 = CalculateProbeWeight(rotPosWS1, boxMin1, boxMax1); // Subject the probes weight if the other probe is dominant float weightProbe0 = probe1Dominant ? min(desiredWeightProbe0, 1.0f - desiredWeightProbe1) : desiredWeightProbe0; @@ -393,12 +493,11 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi half3 reflectVector0 = reflectVector; if (_REFLECTION_PROBE_BOX_PROJECTION) { - #if defined(REFLECTION_PROBE_ROTATION) - reflectVector0 = BoxProjectedCubemapDirection(unity_SpecCube0_Rotation, reflectVector, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - #else - reflectVector0 = BoxProjectedCubemapDirection(reflectVector, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - #endif - } + if (REFLECTION_PROBE_ROTATION) + reflectVector0 = BoxProjectedCubemapDirection(unity_SpecCube0_Rotation, reflectVector, rotPosWS0, unity_SpecCube0_ProbePosition, boxMin0, boxMax0); + else + reflectVector0 = BoxProjectedCubemapDirection(reflectVector, rotPosWS0, unity_SpecCube0_ProbePosition, boxMin0, boxMax0); + } half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector0, mip)); @@ -411,11 +510,10 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi half3 reflectVector1 = reflectVector; if (_REFLECTION_PROBE_BOX_PROJECTION) { - #if defined(REFLECTION_PROBE_ROTATION) - reflectVector1 = BoxProjectedCubemapDirection(unity_SpecCube1_Rotation, reflectVector, rotPosWS1, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax); - #else - reflectVector1 = BoxProjectedCubemapDirection(reflectVector, rotPosWS1, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax); - #endif + if (REFLECTION_PROBE_ROTATION) + reflectVector1 = BoxProjectedCubemapDirection(unity_SpecCube1_Rotation, reflectVector, rotPosWS1, unity_SpecCube1_ProbePosition, boxMin1, boxMax1); + else + reflectVector1 = BoxProjectedCubemapDirection(reflectVector, rotPosWS1, unity_SpecCube1_ProbePosition, boxMin1, boxMax1); } half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube1, samplerunity_SpecCube1, reflectVector1, mip)); @@ -434,9 +532,10 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi return irradiance; } -half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV) +half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV, bool useEnvironmentReflections) { - half3 irradiance = 0; + half3 irradiance = half3(0, 0, 0); + #if defined(_SCREENSPACEREFLECTIONS_OFF) half4 ssrColor = 0; #else @@ -445,15 +544,16 @@ half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half p ssrColor.rgb *= GetInvPreExposureMultiplier(); #endif - // We skip sampling reflection probes if they would be overwritten by SSR anyways. - // This optimization causes a miscompilation when using FXC, and the rendering path - // is single pass stereo instancing, so disable it in that path. - #if !defined(STEREO_INSTANCING_ON) || defined(UNITY_COMPILER_DXC) +// Skip the reflection-probe work when SSR fully covers the pixel (the lerp below discards it). +#if !defined(STEREO_INSTANCING_ON) || defined(UNITY_COMPILER_DXC) if (ssrColor.a < 1.0) - #endif +#endif { - #if !defined(_ENVIRONMENTREFLECTIONS_OFF) - if (_REFLECTION_PROBE_BLENDING) + if (!useEnvironmentReflections) + { + irradiance = _GlossyEnvironmentColor.rgb; + } + else if (_REFLECTION_PROBE_BLENDING) { irradiance = CalculateIrradianceFromReflectionProbes(reflectVector, positionWS, perceptualRoughness, normalizedScreenSpaceUV); } @@ -461,26 +561,27 @@ half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half p { if (_REFLECTION_PROBE_BOX_PROJECTION) { - #if defined(REFLECTION_PROBE_ROTATION) - float3 probeCenterPosWS0 = unity_SpecCube0_BoxMin.xyz + (unity_SpecCube0_BoxMax.xyz - unity_SpecCube0_BoxMin.xyz) / 2; - float3 rotPosWS0 = RotateVectorByQuat(unity_SpecCube0_Rotation, positionWS - probeCenterPosWS0) + probeCenterPosWS0; - half3 rotReflectVector0 = RotateVectorByQuat(unity_SpecCube0_Rotation, reflectVector); - float4 inverseRotation0 = -unity_SpecCube0_Rotation; - inverseRotation0.w = -inverseRotation0.w; - reflectVector = BoxProjectedCubemapDirection(rotReflectVector0, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - reflectVector = RotateVectorByQuat(inverseRotation0, reflectVector); - #else - reflectVector = BoxProjectedCubemapDirection(reflectVector, positionWS, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - #endif + if (REFLECTION_PROBE_ROTATION) + { + float3 probeCenterPosWS0 = unity_SpecCube0_BoxMin.xyz + (unity_SpecCube0_BoxMax.xyz - unity_SpecCube0_BoxMin.xyz) / 2; + float3 rotPosWS0 = RotateVectorByQuat(unity_SpecCube0_Rotation, positionWS - probeCenterPosWS0) + probeCenterPosWS0; + half3 rotReflectVector0 = RotateVectorByQuat(unity_SpecCube0_Rotation, reflectVector); + float4 inverseRotation0 = -unity_SpecCube0_Rotation; + inverseRotation0.w = -inverseRotation0.w; + reflectVector = BoxProjectedCubemapDirection(rotReflectVector0, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); + reflectVector = RotateVectorByQuat(inverseRotation0, reflectVector); + } + else + { + reflectVector = BoxProjectedCubemapDirection(reflectVector, positionWS, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); + } } + half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness); half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip)); irradiance = SelectProbeExposureMultiplier(unity_SpecCube0_Exposure.x) * DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR); } - #else // _ENVIRONMENTREFLECTIONS_OFF - irradiance = _GlossyEnvironmentColor.rgb; - #endif // !_ENVIRONMENTREFLECTIONS_OFF } irradiance = lerp(irradiance.rgb, ssrColor.rgb, ssrColor.a); @@ -489,26 +590,25 @@ half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half p } #if !USE_CLUSTER_LIGHT_LOOP -half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion) +half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, bool useEnvironmentReflections) { - return GlossyEnvironmentReflection(reflectVector, positionWS, perceptualRoughness, occlusion, float2(0.0f, 0.0f)); + return GlossyEnvironmentReflection(reflectVector, positionWS, perceptualRoughness, occlusion, float2(0.0f, 0.0f), useEnvironmentReflections); } #endif -half3 GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion) +half3 GlossyEnvironmentReflection(half3 reflectVector, half perceptualRoughness, half occlusion, bool useEnvironmentReflections) { -#if !defined(_ENVIRONMENTREFLECTIONS_OFF) - half3 irradiance; - half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness); - half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip)); + half3 irradiance = _GlossyEnvironmentColor.rgb; - irradiance = SelectProbeExposureMultiplier(unity_SpecCube0_Exposure.x) * DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR); + if (useEnvironmentReflections) + { + half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip)); - return irradiance * occlusion; -#else + irradiance = SelectProbeExposureMultiplier(unity_SpecCube0_Exposure.x) * DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR); + } - return _GlossyEnvironmentColor.rgb * occlusion; -#endif // _ENVIRONMENTREFLECTIONS_OFF + return irradiance * occlusion; } URP_LIGHT_ACCUM3 SubtractDirectMainLightFromLightmap(Light mainLight, half3 normalWS, URP_LIGHT_ACCUM3 bakedGI) @@ -541,7 +641,7 @@ URP_LIGHT_ACCUM3 SubtractDirectMainLightFromLightmap(Light mainLight, half3 norm URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, - half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV) + half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV, bool useClearCoat, bool useEnvironmentReflections) { // Prevent calling 'reflect' from causing NdotV to be computed twice on Adreno GPUs #if (UNITY_PLATFORM_META_QUEST) // This is platform specific change targeting performance only @@ -559,7 +659,7 @@ URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoa half fresnelTerm = Pow4(1.0 - NoV); URP_LIGHT_ACCUM3 indirectDiffuse = bakedGI; - half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfData.perceptualRoughness, 1.0h, normalizedScreenSpaceUV); + half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfData.perceptualRoughness, 1.0h, normalizedScreenSpaceUV, useEnvironmentReflections); URP_LIGHT_ACCUM3 color = EnvironmentBRDF(brdfData, indirectDiffuse, indirectSpecular, fresnelTerm); @@ -568,40 +668,24 @@ URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoa color = half3(1,1,1); // "Base white" for AO debug lighting mode } -#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP) - half3 coatIndirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfDataClearCoat.perceptualRoughness, 1.0h, normalizedScreenSpaceUV); - // TODO: "grazing term" causes problems on full roughness - half3 coatColor = EnvironmentBRDFClearCoat(brdfDataClearCoat, clearCoatMask, coatIndirectSpecular, fresnelTerm); - - // Blend with base layer using khronos glTF recommended way using NoV - // Smooth surface & "ambiguous" lighting - // NOTE: fresnelTerm (above) is pow4 instead of pow5, but should be ok as blend weight. - half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * fresnelTerm; - return (color * (1.0 - coatFresnel * clearCoatMask) + coatColor) * occlusion; -#else + if (useClearCoat) + { + half3 coatIndirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfDataClearCoat.perceptualRoughness, 1.0h, normalizedScreenSpaceUV, useEnvironmentReflections); + // TODO: "grazing term" causes problems on full roughness + half3 coatColor = EnvironmentBRDFClearCoat(brdfDataClearCoat, clearCoatMask, coatIndirectSpecular, fresnelTerm); + + // Blend with base layer using khronos glTF recommended way using NoV + // Smooth surface & "ambiguous" lighting + // NOTE: fresnelTerm (above) is pow4 instead of pow5, but should be ok as blend weight. + half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * fresnelTerm; + color = color * (1.0 - coatFresnel * clearCoatMask) + coatColor; + } return color * occlusion; -#endif -} - -#if !USE_CLUSTER_LIGHT_LOOP -URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, - URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, - half3 normalWS, half3 viewDirectionWS) -{ - return GlobalIllumination(brdfData, brdfDataClearCoat, clearCoatMask, bakedGI, occlusion, positionWS, normalWS, viewDirectionWS, float2(0.0f, 0.0f)); -} -#endif - -// Backwards compatiblity -URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, URP_LIGHT_ACCUM3 bakedGI, half occlusion, float3 positionWS, half3 normalWS, half3 viewDirectionWS) -{ - const BRDFData noClearCoat = (BRDFData)0; - return GlobalIllumination(brdfData, noClearCoat, 0.0, bakedGI, occlusion, positionWS, normalWS, viewDirectionWS, 0); } URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoat, float clearCoatMask, URP_LIGHT_ACCUM3 bakedGI, half occlusion, - half3 normalWS, half3 viewDirectionWS) + half3 normalWS, half3 viewDirectionWS, bool useClearCoat, bool useEnvironmentReflections) { // Prevent calling 'reflect' from causing NdotV to be computed twice on Adreno GPUs #if (UNITY_PLATFORM_META_QUEST) // This is platform specific change targeting performance only @@ -619,43 +703,29 @@ URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, BRDFData brdfDataClearCoa half fresnelTerm = Pow4(1.0 - NoV); URP_LIGHT_ACCUM3 indirectDiffuse = bakedGI; - half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, brdfData.perceptualRoughness, half(1.0)); + half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, brdfData.perceptualRoughness, half(1.0), useEnvironmentReflections); URP_LIGHT_ACCUM3 color = EnvironmentBRDF(brdfData, indirectDiffuse, indirectSpecular, fresnelTerm); -#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP) - half3 coatIndirectSpecular = GlossyEnvironmentReflection(reflectVector, brdfDataClearCoat.perceptualRoughness, half(1.0)); - // TODO: "grazing term" causes problems on full roughness - half3 coatColor = EnvironmentBRDFClearCoat(brdfDataClearCoat, clearCoatMask, coatIndirectSpecular, fresnelTerm); - - // Blend with base layer using khronos glTF recommended way using NoV - // Smooth surface & "ambiguous" lighting - // NOTE: fresnelTerm (above) is pow4 instead of pow5, but should be ok as blend weight. - half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * fresnelTerm; - return (color * (1.0 - coatFresnel * clearCoatMask) + coatColor) * occlusion; -#else + if (useClearCoat) + { + half3 coatIndirectSpecular = GlossyEnvironmentReflection(reflectVector, brdfDataClearCoat.perceptualRoughness, half(1.0), useEnvironmentReflections); + // TODO: "grazing term" causes problems on full roughness + half3 coatColor = EnvironmentBRDFClearCoat(brdfDataClearCoat, clearCoatMask, coatIndirectSpecular, fresnelTerm); + + // Blend with base layer using khronos glTF recommended way using NoV + // Smooth surface & "ambiguous" lighting + // NOTE: fresnelTerm (above) is pow4 instead of pow5, but should be ok as blend weight. + half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * fresnelTerm; + color = color * (1.0 - coatFresnel * clearCoatMask) + coatColor; + } return color * occlusion; -#endif -} - - -URP_LIGHT_ACCUM3 GlobalIllumination(BRDFData brdfData, URP_LIGHT_ACCUM3 bakedGI, half occlusion, half3 normalWS, half3 viewDirectionWS) -{ - const BRDFData noClearCoat = (BRDFData)0; - return GlobalIllumination(brdfData, noClearCoat, 0.0, bakedGI, occlusion, normalWS, viewDirectionWS); } void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout URP_LIGHT_ACCUM3 bakedGI) { -#if defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) - bakedGI = SubtractDirectMainLightFromLightmap(light, normalWS, bakedGI); -#endif -} - -// Backwards compatibility -void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout URP_LIGHT_ACCUM3 bakedGI, half4 shadowMask) -{ - MixRealtimeAndBakedGI(light, normalWS, bakedGI); + if (LightmapAvailable() && MixedLightingSubtractive()) + bakedGI = SubtractDirectMainLightFromLightmap(light, normalWS, bakedGI); } void MixRealtimeAndBakedGI(inout Light light, half3 normalWS, inout URP_LIGHT_ACCUM3 bakedGI, AmbientOcclusionFactor aoFactor) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl index 27574c8d525..1c102d1cd49 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl @@ -2,8 +2,18 @@ #define UNIVERSAL_PIPELINE_LODCROSSFADE_INCLUDED #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GlobalSamplers.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalShaderVariables.hlsl" +#if !defined(LOD_FADE_CROSSFADE_KEYWORD_DECLARED) + #if !defined(LOD_FADE_CROSSFADE) + static const bool LOD_FADE_CROSSFADE = 0; + #elif DEFINED_NONZERO(LOD_FADE_CROSSFADE) + #undef LOD_FADE_CROSSFADE + #define LOD_FADE_CROSSFADE 1 + #endif +#endif + TEXTURE2D(_DitheringTexture); half CopySign(half x, half s) @@ -13,13 +23,16 @@ half CopySign(half x, half s) void LODFadeCrossFade(float4 positionCS) { - half2 uv = positionCS.xy * _DitheringTextureInvSize; + if (LOD_FADE_CROSSFADE) + { + half2 uv = positionCS.xy * _DitheringTextureInvSize; - half d = SAMPLE_TEXTURE2D(_DitheringTexture, sampler_PointRepeat, uv).a; + half d = SAMPLE_TEXTURE2D(_DitheringTexture, sampler_PointRepeat, uv).a; - d = unity_LODFade.x - CopySign(d, unity_LODFade.x); + d = unity_LODFade.x - CopySign(d, unity_LODFade.x); - clip(d); + clip(d); + } } #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl new file mode 100644 index 00000000000..238581d6eee --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl @@ -0,0 +1,14 @@ +#ifndef UNIVERSAL_LIGHT_INCLUDED +#define UNIVERSAL_LIGHT_INCLUDED + +// Abstraction over Light shading data. +struct Light +{ + half3 direction; + half3 color; + float distanceAttenuation; // full-float precision required on some platforms + half shadowAttenuation; + uint layerMask; +}; + +#endif // UNIVERSAL_LIGHT_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl.meta new file mode 100644 index 00000000000..2eff26ed11f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fb13dafa5ff594b01925b72dd86f0ee9 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookie.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookie.hlsl index 94daadbade8..941f9d308d4 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookie.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookie.hlsl @@ -5,13 +5,21 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookieInput.hlsl" - -#if defined(_LIGHT_COOKIES) - #ifndef REQUIRES_WORLD_SPACE_POS_INTERPOLATOR - #define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR 1 +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +#if !defined(_LIGHT_COOKIES_KEYWORD_DECLARED) + #if !defined(_LIGHT_COOKIES) + static const bool _LIGHT_COOKIES = 0; + #elif DEFINED_NONZERO(_LIGHT_COOKIES) + #undef _LIGHT_COOKIES + #define _LIGHT_COOKIES 1 #endif #endif +bool LightCookiesAvailable() +{ + return _LIGHT_COOKIES; +} float2 ComputeLightCookieUVDirectional(float4x4 worldToLight, float3 samplePositionWS, float4 atlasUVRect, uint2 uvWrap) { @@ -66,13 +74,11 @@ float2 ComputeLightCookieUVPoint(float4x4 worldToLight, float3 samplePositionWS, return positionAtlasUV; } - - real3 SampleMainLightCookie(float3 samplePositionWS) { real3 cookie = real3(1, 1, 1); - if(IsMainLightCookieEnabled()) + if ((_LIGHT_COOKIES) && IsMainLightCookieEnabled()) { float2 uv = ComputeLightCookieUVDirectional(_MainLightWorldToLight, samplePositionWS, float4(1, 1, 0, 0), URP_TEXTURE_WRAP_MODE_NONE); real4 color = SampleMainLightCookieTexture(uv); @@ -89,7 +95,7 @@ real3 SampleAdditionalLightCookie(int perObjectLightIndex, float3 samplePosition { real3 cookie = real3(1, 1, 1); - if (IsLightCookieEnabled(perObjectLightIndex)) + if ((_LIGHT_COOKIES) && IsLightCookieEnabled(perObjectLightIndex)) { int lightType = GetLightCookieLightType(perObjectLightIndex); int isSpot = lightType == URP_LIGHT_TYPE_SPOT; diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl new file mode 100644 index 00000000000..932a38103f3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl @@ -0,0 +1,309 @@ +#ifndef UNIVERSAL_LIGHTING_DEPRECATED_INCLUDED +#define UNIVERSAL_LIGHTING_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDFData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ExposureFunctions.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (Lighting.hlsl). + +half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, + half3 lightColor, half3 lightDirectionWS, float lightAttenuation, + half3 normalWS, half3 viewDirectionWS, + half clearCoatMask, bool specularHighlights, bool clearCoatEnabled); +half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlights, bool clearCoatEnabled); +half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlights, bool clearCoatEnabled); +half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData, bool specularEnabled, bool alphaPremultiplyEnabled); +URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, bool specularSetup, bool specularHighlights, bool alphaPremultiplyEnabled, bool clearCoatEnabled, bool receiveShadows, bool surfaceTypeTransparent, bool environmentReflections); +URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData, bool specularEnabled, bool alphaPremultiplyEnabled, bool receiveShadows, bool surfaceTypeTransparent); +URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData, bool surfaceTypeTransparent); + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +#if !defined(_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED) + #if !defined(_SPECULARHIGHLIGHTS_OFF) + #define _SPECULARHIGHLIGHTS_OFF 0 + #define _SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULARHIGHLIGHTS_OFF) + #undef _SPECULARHIGHLIGHTS_OFF + #define _SPECULARHIGHLIGHTS_OFF 1 + #endif +#endif + +#if !defined(_ENVIRONMENTREFLECTIONS_OFF_KEYWORD_DECLARED) + #if !defined(_ENVIRONMENTREFLECTIONS_OFF) + #define _ENVIRONMENTREFLECTIONS_OFF 0 + #define _ENVIRONMENTREFLECTIONS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ENVIRONMENTREFLECTIONS_OFF) + #undef _ENVIRONMENTREFLECTIONS_OFF + #define _ENVIRONMENTREFLECTIONS_OFF 1 + #endif +#endif + +#if !defined(_SPECGLOSSMAP_KEYWORD_DECLARED) + #if !defined(_SPECGLOSSMAP) + #define _SPECGLOSSMAP 0 + #define _SPECGLOSSMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECGLOSSMAP) + #undef _SPECGLOSSMAP + #define _SPECGLOSSMAP 1 + #endif +#endif + +#if !defined(_SPECULAR_COLOR_KEYWORD_DECLARED) + #if !defined(_SPECULAR_COLOR) + #define _SPECULAR_COLOR 0 + #define _SPECULAR_COLOR_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_COLOR) + #undef _SPECULAR_COLOR + #define _SPECULAR_COLOR 1 + #endif +#endif + +#if !defined(_CLEARCOAT_KEYWORD_DECLARED) + #if !defined(_CLEARCOAT) + #define _CLEARCOAT 0 + #define _CLEARCOAT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_CLEARCOAT) + #undef _CLEARCOAT + #define _CLEARCOAT 1 + #endif +#endif + +#if !defined(_CLEARCOATMAP_KEYWORD_DECLARED) + #if !defined(_CLEARCOATMAP) + #define _CLEARCOATMAP 0 + #define _CLEARCOATMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_CLEARCOATMAP) + #undef _CLEARCOATMAP + #define _CLEARCOATMAP 1 + #endif +#endif + +#if !defined(_SPECULAR_SETUP_KEYWORD_DECLARED) + #if !defined(_SPECULAR_SETUP) + #define _SPECULAR_SETUP 0 + #define _SPECULAR_SETUP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_SETUP) + #undef _SPECULAR_SETUP + #define _SPECULAR_SETUP 1 + #endif +#endif + +#if !defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) + #if !defined(_RECEIVE_SHADOWS_OFF) + #define _RECEIVE_SHADOWS_OFF 0 + #define _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + #undef _RECEIVE_SHADOWS_OFF + #define _RECEIVE_SHADOWS_OFF 1 + #endif +#endif + +#if !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef _SURFACE_TYPE_TRANSPARENT + #define _SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif + +// Deprecated. Use LightingPhysicallyBased(..., specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, + half3 lightColor, half3 lightDirectionWS, float lightAttenuation, + half3 normalWS, half3 viewDirectionWS, + half clearCoatMask, bool specularHighlightsOff) +{ + return LightingPhysicallyBased(brdfData, brdfDataClearCoat, lightColor, lightDirectionWS, lightAttenuation, normalWS, viewDirectionWS, clearCoatMask, !specularHighlightsOff, _CLEARCOAT || _CLEARCOATMAP); +} + +// Deprecated. Use LightingPhysicallyBased(..., specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff) +{ + return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light, normalWS, viewDirectionWS, clearCoatMask, !specularHighlightsOff, _CLEARCOAT || _CLEARCOATMAP); +} + +// Deprecated. Construct a Light and use LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlights, bool clearCoatEnabled) +{ + Light light; + light.color = lightColor; + light.direction = lightDirectionWS; + light.distanceAttenuation = lightAttenuation; + light.shadowAttenuation = 1; + return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, specularHighlights, clearCoatEnabled); +} + +// Deprecated. Use LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS) +{ + return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, !_SPECULARHIGHLIGHTS_OFF, _CLEARCOAT || _CLEARCOATMAP); +} + +// Deprecated. Use LightingPhysicallyBased(..., specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS) +{ + return LightingPhysicallyBased(brdfData, lightColor, lightDirectionWS, lightAttenuation, normalWS, viewDirectionWS, !_SPECULARHIGHLIGHTS_OFF, _CLEARCOAT || _CLEARCOATMAP); +} + +// Deprecated. Use LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff) +{ + return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, !specularHighlightsOff, _CLEARCOAT || _CLEARCOATMAP); +} + +// Deprecated. Use LightingPhysicallyBased(..., specularHighlights, clearCoatEnabled). +half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff) +{ + return LightingPhysicallyBased(brdfData, lightColor, lightDirectionWS, lightAttenuation, normalWS, viewDirectionWS, !specularHighlightsOff, _CLEARCOAT || _CLEARCOATMAP); +} + +// Deprecated. Use CalculateBlinnPhong(light, inputData, surfaceData, specularEnabled, alphaPremultiplyEnabled). +half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData) +{ + return CalculateBlinnPhong(light, inputData, surfaceData, _SPECGLOSSMAP || _SPECULAR_COLOR, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use UniversalFragmentPBR(inputData, surfaceData, specularSetup, specularHighlights, alphaPremultiplyEnabled, clearCoatEnabled, receiveShadows, surfaceTypeTransparent, environmentReflections). +URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData) +{ + return UniversalFragmentPBR(inputData, surfaceData, _SPECULAR_SETUP, !_SPECULARHIGHLIGHTS_OFF, _ALPHAPREMULTIPLY_ON, _CLEARCOAT || _CLEARCOATMAP, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT, !_ENVIRONMENTREFLECTIONS_OFF); +} + +// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments... +URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular, + half smoothness, half occlusion, half3 emission, half alpha) +{ + SurfaceData surfaceData; + + surfaceData.albedo = albedo; + surfaceData.specular = specular; + surfaceData.metallic = metallic; + surfaceData.smoothness = smoothness; + surfaceData.normalTS = half3(0, 0, 1); + surfaceData.emission = emission; + surfaceData.occlusion = occlusion; + surfaceData.alpha = alpha; + surfaceData.clearCoatMask = 0; + surfaceData.clearCoatSmoothness = 1; + + return UniversalFragmentPBR(inputData, surfaceData, _SPECULAR_SETUP, !_SPECULARHIGHLIGHTS_OFF, _ALPHAPREMULTIPLY_ON, _CLEARCOAT || _CLEARCOATMAP, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT, !_ENVIRONMENTREFLECTIONS_OFF); +} + +// Deprecated. Use UniversalFragmentBlinnPhong(inputData, surfaceData, specularEnabled, alphaPremultiplyEnabled, receiveShadows, surfaceTypeTransparent). +URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData) +{ + return UniversalFragmentBlinnPhong(inputData, surfaceData, _SPECGLOSSMAP || _SPECULAR_COLOR, _ALPHAPREMULTIPLY_ON, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments... +URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS) +{ + SurfaceData surfaceData; + + surfaceData.albedo = diffuse; + surfaceData.alpha = alpha; + surfaceData.emission = emission; + surfaceData.metallic = 0; + surfaceData.occlusion = 1; + surfaceData.smoothness = smoothness; + surfaceData.specular = specularGloss.rgb; + surfaceData.clearCoatMask = 0; + surfaceData.clearCoatSmoothness = 1; + surfaceData.normalTS = normalTS; + + return UniversalFragmentBlinnPhong(inputData, surfaceData, _SPECGLOSSMAP || _SPECULAR_COLOR, _ALPHAPREMULTIPLY_ON, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use UniversalFragmentBakedLit(inputData, surfaceData, surfaceTypeTransparent). +URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData) +{ + return UniversalFragmentBakedLit(inputData, surfaceData, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments... +URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS) +{ + SurfaceData surfaceData; + + surfaceData.albedo = color; + surfaceData.alpha = alpha; + surfaceData.emission = half3(0, 0, 0); + surfaceData.metallic = 0; + surfaceData.occlusion = 1; + surfaceData.smoothness = 1; + surfaceData.specular = half3(0, 0, 0); + surfaceData.clearCoatMask = 0; + surfaceData.clearCoatSmoothness = 1; + surfaceData.normalTS = normalTS; + + return UniversalFragmentBakedLit(inputData, surfaceData, _SURFACE_TYPE_TRANSPARENT); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#if defined(_SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY) + #undef _SPECULARHIGHLIGHTS_OFF_DEFINED_LOCALLY + #undef _SPECULARHIGHLIGHTS_OFF +#endif + +#if defined(_SPECGLOSSMAP_DEFINED_LOCALLY) + #undef _SPECGLOSSMAP_DEFINED_LOCALLY + #undef _SPECGLOSSMAP +#endif + +#if defined(_SPECULAR_COLOR_DEFINED_LOCALLY) + #undef _SPECULAR_COLOR_DEFINED_LOCALLY + #undef _SPECULAR_COLOR +#endif + +#if defined(_CLEARCOAT_DEFINED_LOCALLY) + #undef _CLEARCOAT_DEFINED_LOCALLY + #undef _CLEARCOAT +#endif + +#if defined(_CLEARCOATMAP_DEFINED_LOCALLY) + #undef _CLEARCOATMAP_DEFINED_LOCALLY + #undef _CLEARCOATMAP +#endif + +#if defined(_SPECULAR_SETUP_DEFINED_LOCALLY) + #undef _SPECULAR_SETUP_DEFINED_LOCALLY + #undef _SPECULAR_SETUP +#endif + +#if defined(_RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY) + #undef _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY + #undef _RECEIVE_SHADOWS_OFF +#endif + +#if defined(_ENVIRONMENTREFLECTIONS_OFF_DEFINED_LOCALLY) + #undef _ENVIRONMENTREFLECTIONS_OFF_DEFINED_LOCALLY + #undef _ENVIRONMENTREFLECTIONS_OFF +#endif + +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT +#endif + +#endif // UNIVERSAL_LIGHTING_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl.meta new file mode 100644 index 00000000000..2f1d9335932 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5af35a738600346669f40fadce0630df +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl index 63bc5186b04..4f009b714ab 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl @@ -8,25 +8,31 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" - -#if defined(LIGHTMAP_ON) - #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) float2 lmName : TEXCOORD##index - #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = lightmapUV.xy * lightmapScaleOffset.xy + lightmapScaleOffset.zw; - #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) - #define OUTPUT_SH(normalWS, OUT) -#else - #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, index) half3 shName : TEXCOORD##index - #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) - #ifdef USE_APV_PROBE_OCCLUSION - #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir, OUT_OCCLUSION) - #else - #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir) +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.deprecated.hlsl" + +#if !defined(_LIGHT_LAYERS_KEYWORD_DECLARED) + #if !defined(_LIGHT_LAYERS) + static const bool _LIGHT_LAYERS = 0; + #elif DEFINED_NONZERO(_LIGHT_LAYERS) + #undef _LIGHT_LAYERS + #define _LIGHT_LAYERS 1 #endif - // Note: This is the legacy function, which does not support APV. - // Kept to avoid breaking shaders still calling it (UUM-37723) - #define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS) #endif +bool LightLayersAvailable() +{ + return _LIGHT_LAYERS; +} + +bool IsMatchingLightLayer(Light light, uint renderingLayers) +{ + bool isMatching = true; + if (_LIGHT_LAYERS) + isMatching = IsMatchingLightLayer(light.layerMask, renderingLayers); + return isMatching; +} + /////////////////////////////////////////////////////////////////////////////// // Lighting Functions // /////////////////////////////////////////////////////////////////////////////// @@ -49,7 +55,7 @@ half3 LightingSpecular(half3 lightColor, half3 lightDir, half3 normal, half3 vie half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS, - half clearCoatMask, bool specularHighlightsOff) + half clearCoatMask, bool useSpecularHighlights, bool useClearCoat) { #if (UNITY_PLATFORM_META_QUEST) half NdotL = dot(normalWS, lightDirectionWS); @@ -60,35 +66,34 @@ half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, #if (UNITY_PLATFORM_META_QUEST) [branch] if (NdotL > 0.0) - { + { half3 radiance = lightColor * (lightAttenuation * saturate(NdotL)); #else half3 radiance = lightColor * (lightAttenuation * NdotL); #endif half3 brdf = brdfData.diffuse; -#ifndef _SPECULARHIGHLIGHTS_OFF [branch] - if (!specularHighlightsOff) + if (useSpecularHighlights) { brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS); -#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP) - // Clear coat evaluates the specular a second time and has some common terms with the base specular. - // We rely on the compiler to merge these and compute them only once. - half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS); - - // Mix clear coat and base layer using khronos glTF recommended formula - // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md - // Use NoV for direct too instead of LoH as an optimization (NoV is light invariant). - half NoV = saturate(dot(normalWS, viewDirectionWS)); - // Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization. - // It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct) - half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV); - - brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask; -#endif // _CLEARCOAT + if (useClearCoat) + { + // Clear coat evaluates the specular a second time and has some common terms with the base specular. + // We rely on the compiler to merge these and compute them only once. + half brdfCoat = kDielectricSpec.r * DirectBRDFSpecular(brdfDataClearCoat, normalWS, lightDirectionWS, viewDirectionWS); + + // Mix clear coat and base layer using khronos glTF recommended formula + // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md + // Use NoV for direct too instead of LoH as an optimization (NoV is light invariant). + half NoV = saturate(dot(normalWS, viewDirectionWS)); + // Use slightly simpler fresnelTerm (Pow4 vs Pow5) as a small optimization. + // It is matching fresnel used in the GI/Env, so should produce a consistent clear coat blend (env vs. direct) + half coatFresnel = kDielectricSpec.x + kDielectricSpec.a * Pow4(1.0 - NoV); + + brdf = brdf * (1.0 - clearCoatMask * coatFresnel) + brdfCoat * clearCoatMask; + } } -#endif // _SPECULARHIGHLIGHTS_OFF return brdf * radiance; #if (UNITY_PLATFORM_META_QUEST) } @@ -96,54 +101,15 @@ half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, return 0.0; } -half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool specularHighlightsOff) +half3 LightingPhysicallyBased(BRDFData brdfData, BRDFData brdfDataClearCoat, Light light, half3 normalWS, half3 viewDirectionWS, half clearCoatMask, bool useSpecularHighlights, bool useClearCoat) { - return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, specularHighlightsOff); + return LightingPhysicallyBased(brdfData, brdfDataClearCoat, light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, clearCoatMask, useSpecularHighlights, useClearCoat); } -// Backwards compatibility -// Pre-exposure is fixed to 1 -half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS) +half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool useSpecularHighlights, bool useClearCoat) { - #ifdef _SPECULARHIGHLIGHTS_OFF - bool specularHighlightsOff = true; -#else - bool specularHighlightsOff = false; -#endif - const BRDFData noClearCoat = (BRDFData)0; - return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff); -} - -// Backwards compatibility -// Pre-exposure is fixed to 1 -half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS) -{ - Light light; - light.color = lightColor; - light.direction = lightDirectionWS; - light.distanceAttenuation = lightAttenuation; - light.shadowAttenuation = 1; - return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS); -} - -// Backwards compatibility -// Pre-exposure is fixed to 1 -half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff) -{ - const BRDFData noClearCoat = (BRDFData)0; - return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, specularHighlightsOff); -} - -// Backwards compatibility -// Pre-exposure is fixed to 1 -half3 LightingPhysicallyBased(BRDFData brdfData, half3 lightColor, half3 lightDirectionWS, float lightAttenuation, half3 normalWS, half3 viewDirectionWS, bool specularHighlightsOff) -{ - Light light; - light.color = lightColor; - light.direction = lightDirectionWS; - light.distanceAttenuation = lightAttenuation; - light.shadowAttenuation = 1; - return LightingPhysicallyBased(brdfData, light, normalWS, viewDirectionWS, specularHighlightsOff); + const BRDFData noClearCoat = CreateEmptyBRDFData(); + return LightingPhysicallyBased(brdfData, noClearCoat, light, normalWS, viewDirectionWS, 0.0, useSpecularHighlights, useClearCoat); } URP_LIGHT_ACCUM3 VertexLighting(float3 positionWS, half3 normalWS) @@ -157,9 +123,7 @@ URP_LIGHT_ACCUM3 VertexLighting(float3 positionWS, half3 normalWS) LIGHT_LOOP_BEGIN(lightsCount) Light light = GetAdditionalLight(lightIndex, positionWS); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) -#endif + if (IsMatchingLightLayer(light, meshRenderingLayers)) { #if defined(UNITY_PLATFORM_META_QUEST) if(light.distanceAttenuation > 0.0) @@ -255,23 +219,23 @@ LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData) return lightingData; } -half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData) +// useSpecularHighlights: the material provides a specular color (_SPECGLOSSMAP or _SPECULAR_COLOR). +half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceData, bool useSpecularHighlights, bool useAlphaPremultiply) { half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation); half3 lightDiffuseColor = LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS); half3 lightSpecularColor = half3(0,0,0); - #if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR) - half smoothness = exp2(10 * surfaceData.smoothness + 1); + if (useSpecularHighlights) + { + half smoothness = exp2(10 * surfaceData.smoothness + 1); + lightSpecularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness); + } - lightSpecularColor += LightingSpecular(attenuatedLightColor, light.direction, inputData.normalWS, inputData.viewDirectionWS, half4(surfaceData.specular, 1), smoothness); - #endif + if (useAlphaPremultiply) + lightDiffuseColor *= surfaceData.alpha; -#if _ALPHAPREMULTIPLY_ON - return lightDiffuseColor * surfaceData.albedo * surfaceData.alpha + lightSpecularColor; -#else return lightDiffuseColor * surfaceData.albedo + lightSpecularColor; -#endif } /////////////////////////////////////////////////////////////////////////////// @@ -282,17 +246,9 @@ half3 CalculateBlinnPhong(Light light, InputData inputData, SurfaceData surfaceD //////////////////////////////////////////////////////////////////////////////// /// PBR lighting... //////////////////////////////////////////////////////////////////////////////// -URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData) +URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, bool isSpecularSetup, bool useSpecularHighlights, bool useAlphaPremultiply, bool useClearCoat, bool receiveShadows, bool isSurfaceTypeTransparent, bool useEnvironmentReflections) { - #if defined(_SPECULARHIGHLIGHTS_OFF) - bool specularHighlightsOff = true; - #else - bool specularHighlightsOff = false; - #endif - BRDFData brdfData; - - // NOTE: can modify "surfaceData"... - InitializeBRDFData(surfaceData, brdfData); + BRDFData brdfData = InitializeBRDFData(surfaceData, isSpecularSetup, useAlphaPremultiply); #if defined(DEBUG_DISPLAY) float4 debugColor; @@ -303,10 +259,14 @@ URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceDa } #endif - // Clear-coat calculation... - BRDFData brdfDataClearCoat = CreateClearCoatBRDFData(surfaceData, brdfData); + BRDFData brdfDataClearCoat = CreateEmptyBRDFData(); + if (useClearCoat) + { + // base brdfData is modified here, rely on the compiler to eliminate dead computation by InitializeBRDFData() + brdfDataClearCoat = InitializeBRDFDataClearCoat(surfaceData.clearCoatMask, surfaceData.clearCoatSmoothness, brdfData); + } half4 shadowMask = CalculateShadowMask(inputData); - AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData); + AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData, isSurfaceTypeTransparent); uint meshRenderingLayers = GetMeshRenderingLayer(); #if (UNITY_PLATFORM_META_QUEST) @@ -315,8 +275,8 @@ URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceDa inputData.shadowCoord.z = -1; // Force outside of shadowmap } #endif - - Light mainLight = GetMainLight(inputData, shadowMask, aoFactor); + + Light mainLight = GetMainLight(inputData, shadowMask, aoFactor, receiveShadows, isSurfaceTypeTransparent); // NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below... MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); @@ -325,15 +285,14 @@ URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceDa lightingData.giColor = GlobalIllumination(brdfData, brdfDataClearCoat, surfaceData.clearCoatMask, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS, - inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers)) -#endif + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV, useClearCoat, useEnvironmentReflections); + + if (IsMatchingLightLayer(mainLight, meshRenderingLayers)) { lightingData.mainLightColor = LightingPhysicallyBased(brdfData, brdfDataClearCoat, mainLight, inputData.normalWS, inputData.viewDirectionWS, - surfaceData.clearCoatMask, specularHighlightsOff); + surfaceData.clearCoatMask, useSpecularHighlights, useClearCoat); } #if defined(_ADDITIONAL_LIGHTS) @@ -344,32 +303,28 @@ URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceDa { CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK - Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor); + Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor, receiveShadows, isSurfaceTypeTransparent); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) -#endif + if (IsMatchingLightLayer(light, meshRenderingLayers)) { lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light, inputData.normalWS, inputData.viewDirectionWS, - surfaceData.clearCoatMask, specularHighlightsOff); + surfaceData.clearCoatMask, useSpecularHighlights, useClearCoat); } } #endif LIGHT_LOOP_BEGIN(pixelLightCount) - Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor); + Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor, receiveShadows, isSurfaceTypeTransparent); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) -#endif + if (IsMatchingLightLayer(light, meshRenderingLayers)) { #if defined(UNITY_PLATFORM_META_QUEST) if(light.distanceAttenuation > 0.0) #endif lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, brdfDataClearCoat, light, inputData.normalWS, inputData.viewDirectionWS, - surfaceData.clearCoatMask, specularHighlightsOff); + surfaceData.clearCoatMask, useSpecularHighlights, useClearCoat); } LIGHT_LOOP_END #endif @@ -386,30 +341,10 @@ URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceDa #endif } -// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments... -URP_LIGHT_ACCUM4 UniversalFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular, - half smoothness, half occlusion, half3 emission, half alpha) -{ - SurfaceData surfaceData; - - surfaceData.albedo = albedo; - surfaceData.specular = specular; - surfaceData.metallic = metallic; - surfaceData.smoothness = smoothness; - surfaceData.normalTS = half3(0, 0, 1); - surfaceData.emission = emission; - surfaceData.occlusion = occlusion; - surfaceData.alpha = alpha; - surfaceData.clearCoatMask = 0; - surfaceData.clearCoatSmoothness = 1; - - return UniversalFragmentPBR(inputData, surfaceData); -} - //////////////////////////////////////////////////////////////////////////////// /// Phong lighting... //////////////////////////////////////////////////////////////////////////////// -URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData) +URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData surfaceData, bool useSpecularHighlights, bool useAlphaPremultiply, bool receiveShadows, bool isSurfaceTypeTransparent) { #if defined(DEBUG_DISPLAY) float4 debugColor; @@ -422,19 +357,18 @@ URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData su uint meshRenderingLayers = GetMeshRenderingLayer(); half4 shadowMask = CalculateShadowMask(inputData); - AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData); - Light mainLight = GetMainLight(inputData, shadowMask, aoFactor); + AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData, isSurfaceTypeTransparent); + Light mainLight = GetMainLight(inputData, shadowMask, aoFactor, receiveShadows, isSurfaceTypeTransparent); MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, aoFactor); inputData.bakedGI *= surfaceData.albedo; LightingData lightingData = CreateLightingData(inputData, surfaceData); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers)) -#endif + + if (IsMatchingLightLayer(mainLight, meshRenderingLayers)) { - lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData); + lightingData.mainLightColor += CalculateBlinnPhong(mainLight, inputData, surfaceData, useSpecularHighlights, useAlphaPremultiply); } #if defined(_ADDITIONAL_LIGHTS) @@ -445,26 +379,24 @@ URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData su { CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK - Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) -#endif + Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor, receiveShadows, isSurfaceTypeTransparent); + + if (IsMatchingLightLayer(light, meshRenderingLayers)) { - lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData); + lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, useSpecularHighlights, useAlphaPremultiply); } } #endif LIGHT_LOOP_BEGIN(pixelLightCount) - Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor); -#ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) -#endif + Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor, receiveShadows, isSurfaceTypeTransparent); + + if (IsMatchingLightLayer(light, meshRenderingLayers)) { #if defined(UNITY_PLATFORM_META_QUEST) if(light.distanceAttenuation > 0.0) #endif - lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData); + lightingData.additionalLightsColor += CalculateBlinnPhong(light, inputData, surfaceData, useSpecularHighlights, useAlphaPremultiply); } LIGHT_LOOP_END #endif @@ -476,29 +408,10 @@ URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, SurfaceData su return CalculateFinalColor(lightingData, surfaceData.alpha); } -// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments... -URP_LIGHT_ACCUM4 UniversalFragmentBlinnPhong(InputData inputData, half3 diffuse, half4 specularGloss, half smoothness, half3 emission, half alpha, half3 normalTS) -{ - SurfaceData surfaceData; - - surfaceData.albedo = diffuse; - surfaceData.alpha = alpha; - surfaceData.emission = emission; - surfaceData.metallic = 0; - surfaceData.occlusion = 1; - surfaceData.smoothness = smoothness; - surfaceData.specular = specularGloss.rgb; - surfaceData.clearCoatMask = 0; - surfaceData.clearCoatSmoothness = 1; - surfaceData.normalTS = normalTS; - - return UniversalFragmentBlinnPhong(inputData, surfaceData); -} - //////////////////////////////////////////////////////////////////////////////// /// Unlit //////////////////////////////////////////////////////////////////////////////// -URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData) +URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surfaceData, bool isSurfaceTypeTransparent) { #if defined(DEBUG_DISPLAY) float4 debugColor; @@ -509,7 +422,7 @@ URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surf } #endif - AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData); + AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData, isSurfaceTypeTransparent); LightingData lightingData = CreateLightingData(inputData, surfaceData); if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION)) @@ -521,23 +434,4 @@ URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, SurfaceData surf return half4(CalculateLightingColor(lightingData, surfaceData.albedo), surfaceData.alpha); } -// Deprecated: Use the version which takes "SurfaceData" instead of passing all of these arguments... -URP_LIGHT_ACCUM4 UniversalFragmentBakedLit(InputData inputData, half3 color, half alpha, half3 normalTS) -{ - SurfaceData surfaceData; - - surfaceData.albedo = color; - surfaceData.alpha = alpha; - surfaceData.emission = half3(0, 0, 0); - surfaceData.metallic = 0; - surfaceData.occlusion = 1; - surfaceData.smoothness = 1; - surfaceData.specular = half3(0, 0, 0); - surfaceData.clearCoatMask = 0; - surfaceData.clearCoatSmoothness = 1; - surfaceData.normalTS = normalTS; - - return UniversalFragmentBakedLit(inputData, surfaceData); -} - #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl new file mode 100644 index 00000000000..74ca212f038 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl @@ -0,0 +1,219 @@ +#ifndef UNIVERSAL_LIGHTMAPS_INCLUDED +#define UNIVERSAL_LIGHTMAPS_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// Fallbacks so the lightmap keywords always evaluate as values (if (LIGHTMAP_ON)) +// even in passes that don't declare them. + +#if !defined(LIGHTMAP_ON_KEYWORD_DECLARED) + #if !defined(LIGHTMAP_ON) + static const bool LIGHTMAP_ON = 0; + #elif DEFINED_NONZERO(LIGHTMAP_ON) + #undef LIGHTMAP_ON + #define LIGHTMAP_ON 1 + #endif +#endif + +#if !defined(DYNAMICLIGHTMAP_ON_KEYWORD_DECLARED) + #if !defined(DYNAMICLIGHTMAP_ON) + static const bool DYNAMICLIGHTMAP_ON = 0; + #elif DEFINED_NONZERO(DYNAMICLIGHTMAP_ON) + #undef DYNAMICLIGHTMAP_ON + #define DYNAMICLIGHTMAP_ON 1 + #endif +#endif + +#if !defined(DIRLIGHTMAP_COMBINED_KEYWORD_DECLARED) + #if !defined(DIRLIGHTMAP_COMBINED) + static const bool DIRLIGHTMAP_COMBINED = 0; + #elif DEFINED_NONZERO(DIRLIGHTMAP_COMBINED) + #undef DIRLIGHTMAP_COMBINED + #define DIRLIGHTMAP_COMBINED 1 + #endif +#endif + +// Interpolator allocation flags, always defined as 0 or 1: whether the Varyings carry the +// lightmap UV / vertex SH / dynamic lightmap UV field. Pre-defining a deprecated REQUIRES_* +// alias still forces the field on for existing callers. +#if defined(LIGHTMAP_ON_KEYWORD_DECLARED) && (LIGHTMAP_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #define USE_LIGHTMAP_UV_INTERPOLATOR 1 + #define USE_VERTEX_SH_INTERPOLATOR 1 +#elif !defined(LIGHTMAP_ON_KEYWORD_DECLARED) || (LIGHTMAP_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(LIGHTMAP_ON) + #define USE_LIGHTMAP_UV_INTERPOLATOR 1 + #else + #define USE_VERTEX_SH_INTERPOLATOR 1 + #endif +#endif + +#if defined(DYNAMICLIGHTMAP_ON_KEYWORD_DECLARED) && (DYNAMICLIGHTMAP_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #define USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR 1 +#elif !defined(DYNAMICLIGHTMAP_ON_KEYWORD_DECLARED) || (DYNAMICLIGHTMAP_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(DYNAMICLIGHTMAP_ON) + #define USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR 1 + #endif +#endif + +#if !defined(USE_LIGHTMAP_UV_INTERPOLATOR) + #if defined(REQUIRES_LIGHTMAP_UV_INTERPOLATOR) + #define USE_LIGHTMAP_UV_INTERPOLATOR 1 + #else + #define USE_LIGHTMAP_UV_INTERPOLATOR 0 + #endif +#endif +#if !defined(USE_VERTEX_SH_INTERPOLATOR) + #if defined(REQUIRES_VERTEX_SH_INTERPOLATOR) + #define USE_VERTEX_SH_INTERPOLATOR 1 + #else + #define USE_VERTEX_SH_INTERPOLATOR 0 + #endif +#endif +#if !defined(USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR) + #if defined(REQUIRES_DYNAMICLIGHTMAP_UV_INTERPOLATOR) + #define USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR 1 + #else + #define USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR 0 + #endif +#endif + +// Deprecated aliases for existing callers; new code reads the USE_* flags. +#if USE_LIGHTMAP_UV_INTERPOLATOR && !defined(REQUIRES_LIGHTMAP_UV_INTERPOLATOR) + #define REQUIRES_LIGHTMAP_UV_INTERPOLATOR 1 +#endif +#if USE_VERTEX_SH_INTERPOLATOR && !defined(REQUIRES_VERTEX_SH_INTERPOLATOR) + #define REQUIRES_VERTEX_SH_INTERPOLATOR 1 +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR && !defined(REQUIRES_DYNAMICLIGHTMAP_UV_INTERPOLATOR) + #define REQUIRES_DYNAMICLIGHTMAP_UV_INTERPOLATOR 1 +#endif + +// Runtime query functions — work with both specialized variants and dynamic branching. + +bool LightmapAvailable() +{ + return LIGHTMAP_ON; +} + +bool DynamicLightmapAvailable() +{ + return DYNAMICLIGHTMAP_ON; +} + +bool DirectionalLightmapAvailable() +{ + return DIRLIGHTMAP_COMBINED; +} + +float2 TransformLightmapUV(float2 lightmapUV, float4 lightmapScaleOffset) +{ + return lightmapUV * lightmapScaleOffset.xy + lightmapScaleOffset.zw; +} + +// Lightmap texture binding macros — resolve DOTS instancing texture arrays vs individual textures. +#if defined(UNITY_DOTS_INSTANCING_ENABLED) && !defined(USE_LEGACY_LIGHTMAPS) +#define LIGHTMAP_NAME unity_Lightmaps +#define LIGHTMAP_INDIRECTION_NAME unity_LightmapsInd +#define LIGHTMAP_SAMPLER_NAME samplerunity_Lightmaps +#define LIGHTMAP_SAMPLE_EXTRA_ARGS staticLightmapUV, unity_LightmapIndex.x +#else +#define LIGHTMAP_NAME unity_Lightmap +#define LIGHTMAP_INDIRECTION_NAME unity_LightmapInd +#define LIGHTMAP_SAMPLER_NAME samplerunity_Lightmap +#define LIGHTMAP_SAMPLE_EXTRA_ARGS staticLightmapUV +#endif + +// Sample baked and/or realtime lightmap. Non-Direction and Directional if available. +half3 SampleLightmap(float2 staticLightmapUV, float2 dynamicLightmapUV, half3 normalWS) +{ + // The shader library sample lightmap functions transform the lightmap uv coords to apply bias and scale. + // However, universal pipeline already transformed those coords in vertex. We pass half4(1, 1, 0, 0) and + // the compiler will optimize the transform away. + half4 transformCoords = half4(1, 1, 0, 0); + + float3 diffuseLighting = 0; + + if (LightmapAvailable()) + { + if (DirectionalLightmapAvailable()) + { + diffuseLighting = SampleDirectionalLightmap(TEXTURE2D_LIGHTMAP_ARGS(LIGHTMAP_NAME, LIGHTMAP_SAMPLER_NAME), + TEXTURE2D_LIGHTMAP_ARGS(LIGHTMAP_INDIRECTION_NAME, LIGHTMAP_SAMPLER_NAME), + LIGHTMAP_SAMPLE_EXTRA_ARGS, transformCoords, normalWS, true); + } + else + { + diffuseLighting = SampleSingleLightmap(TEXTURE2D_LIGHTMAP_ARGS(LIGHTMAP_NAME, LIGHTMAP_SAMPLER_NAME), + LIGHTMAP_SAMPLE_EXTRA_ARGS, transformCoords, true); + } + } + + // unity_DynamicLightmap is always a Texture2D, but in the DOTS texture-array path + // SampleDirectional/SingleLightmap are Texture2DArray-typed. Dynamic lightmaps are not + // supported with GPU-driven rendering, so skip them when the array path is active. +#if !defined(UNITY_DOTS_INSTANCING_ENABLED) || defined(USE_LEGACY_LIGHTMAPS) + if (DynamicLightmapAvailable()) + { + if (DirectionalLightmapAvailable()) + { + diffuseLighting += SampleDirectionalLightmap(TEXTURE2D_ARGS(unity_DynamicLightmap, samplerunity_DynamicLightmap), + TEXTURE2D_ARGS(unity_DynamicDirectionality, samplerunity_DynamicLightmap), + dynamicLightmapUV, transformCoords, normalWS, false); + } + else + { + diffuseLighting += SampleSingleLightmap(TEXTURE2D_ARGS(unity_DynamicLightmap, samplerunity_DynamicLightmap), + dynamicLightmapUV, transformCoords, false); + } + } +#endif + + return diffuseLighting; +} + +// Legacy version of SampleLightmap where Realtime GI is not supported. +half3 SampleLightmap(float2 staticLightmapUV, half3 normalWS) +{ + float2 dummyDynamicLightmapUV = float2(0,0); + return SampleLightmap(staticLightmapUV, dummyDynamicLightmapUV, normalWS); +} + +// Deprecated macros, kept for shaders that still use them: use the USE_* interpolator flags +// for struct layout, TransformLightmapUV()/SampleProbeSHVertex() for vertex output, and +// InitializeBakedGI() for fragment input. +#if USE_LIGHTMAP_UV_INTERPOLATOR && USE_VERTEX_SH_INTERPOLATOR + // Deprecated: use the USE_* interpolator flags instead. + #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, _unused) float2 lmName : LIGHTMAPUV; half3 shName : VERTEXSH + // Deprecated: use TransformLightmapUV() instead. + #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = LightmapAvailable() ? TransformLightmapUV(lightmapUV.xy, lightmapScaleOffset) : float2(0, 0); + // Deprecated: use SampleProbeSHVertex() instead. + #ifdef USE_APV_PROBE_OCCLUSION + #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) if (!LightmapAvailable()) { OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir, OUT_OCCLUSION); } else { OUT.xyz = half3(0, 0, 0); } + #else + #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) if (!LightmapAvailable()) { OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir); } else { OUT.xyz = half3(0, 0, 0); } + #endif + // Deprecated: use SampleSHVertex() instead. + #define OUTPUT_SH(normalWS, OUT) OUT.xyz = !LightmapAvailable() ? SampleSHVertex(normalWS) : half3(0, 0, 0) +#elif REQUIRES_LIGHTMAP_UV_INTERPOLATOR + // Deprecated: use REQUIRES_LIGHTMAP_UV_INTERPOLATOR instead. + #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, _unused) float2 lmName : LIGHTMAPUV + // Deprecated: use TransformLightmapUV() instead. + #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) OUT.xy = TransformLightmapUV(lightmapUV.xy, lightmapScaleOffset); + #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) + #define OUTPUT_SH(normalWS, OUT) +#else + // Deprecated: use REQUIRES_VERTEX_SH_INTERPOLATOR instead. + #define DECLARE_LIGHTMAP_OR_SH(lmName, shName, _unused) half3 shName : VERTEXSH + #define OUTPUT_LIGHTMAP_UV(lightmapUV, lightmapScaleOffset, OUT) + // Deprecated: use SampleProbeSHVertex() instead. + #ifdef USE_APV_PROBE_OCCLUSION + #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir, OUT_OCCLUSION) + #else + #define OUTPUT_SH4(absolutePositionWS, normalWS, viewDir, OUT, OUT_OCCLUSION) OUT.xyz = SampleProbeSHVertex(absolutePositionWS, normalWS, viewDir) + #endif + // Deprecated: use SampleSHVertex() instead. + #define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS) +#endif + +#endif // UNIVERSAL_LIGHTMAPS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl.meta new file mode 100644 index 00000000000..a18e3e00732 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6885af6b524c84448a97a181cf0e2188 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl new file mode 100644 index 00000000000..c12fbbc27e5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl @@ -0,0 +1,119 @@ +#ifndef UNIVERSAL_OBJECT_MOTION_VECTORS_DEPRECATED_INCLUDED +#define UNIVERSAL_OBJECT_MOTION_VECTORS_DEPRECATED_INCLUDED + +#pragma target 3.5 + +#pragma vertex vert +#pragma fragment frag + +//-------------------------------------- +// GPU Instancing +#pragma multi_compile_instancing +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl" + +//------------------------------------- +// Other pragmas +#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + +// ------------------------------------- +// Includes +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" + +#if defined(LOD_FADE_CROSSFADE) + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#endif + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MotionVectorsCommon.hlsl" + +// ------------------------------------- +// Structs +struct Attributes +{ + float4 position : POSITION; +#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + float2 uv : TEXCOORD0; +#endif + float3 positionOld : TEXCOORD4; +#if _ADD_PRECOMPUTED_VELOCITY + float3 alembicMotionVector : TEXCOORD5; +#endif + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct Varyings +{ + float4 positionCS : SV_POSITION; + float4 positionCSNoJitter : POSITION_CS_NO_JITTER; + float4 previousPositionCSNoJitter : PREV_POSITION_CS_NO_JITTER; +#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + float2 uv : TEXCOORD0; +#endif + UNITY_VERTEX_INPUT_INSTANCE_ID + UNITY_VERTEX_OUTPUT_STEREO +}; + +// ------------------------------------- +// Vertex +Varyings vert(Attributes input) +{ + Varyings output = (Varyings)0; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_TRANSFER_INSTANCE_ID(input, output); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + const VertexPositionInputs vertexInput = GetVertexPositionInputs(input.position.xyz); + + #if defined(_ALPHATEST_ON) || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + output.uv = TRANSFORM_TEX(input.uv, _BaseMap); + #endif + +#if defined(APPLICATION_SPACE_WARP_MOTION) + // We do not need jittered position in ASW + output.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, mul(UNITY_MATRIX_M, input.position));; + output.positionCS = output.positionCSNoJitter; +#else + // Jittered. Match the frame. + output.positionCS = vertexInput.positionCS; + output.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, mul(UNITY_MATRIX_M, input.position)); +#endif + + float4 prevPos = (unity_MotionVectorsParams.x == 1) ? float4(input.positionOld, 1) : input.position; + +#if _ADD_PRECOMPUTED_VELOCITY + prevPos = prevPos - float4(input.alembicMotionVector, 0); +#endif + + output.previousPositionCSNoJitter = mul(_PrevViewProjMatrix, mul(UNITY_PREV_MATRIX_M, prevPos)); + + return output; +} + +// ------------------------------------- +// Fragment +float4 frag(Varyings input) : SV_Target +{ + UNITY_SETUP_INSTANCE_ID(input); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + #if defined(_ALPHATEST_ON) + Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + #endif + + #if defined(LOD_FADE_CROSSFADE) + LODFadeCrossFade(input.positionCS); + #endif + + #if defined(APPLICATION_SPACE_WARP_MOTION) + #if APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + clip((SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a * _BaseColor.a) - 0.001); + #endif + return float4(CalcAswNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 1); + #else + return float4(CalcNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 0, 0); + #endif +} + + +#endif // UNIVERSAL_OBJECT_MOTION_VECTORS_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl.meta new file mode 100644 index 00000000000..70b845a34f5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 828119ddb2d9449169220134df2fae00 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl index 2963ba74749..7ac15eebb11 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl @@ -1,119 +1,3 @@ -#ifndef UNIVERSAL_OBJECT_MOTION_VECTORS_INCLUDED -#define UNIVERSAL_OBJECT_MOTION_VECTORS_INCLUDED +#warning "ShaderLibrary/ObjectMotionVectors.hlsl" is deprecated. New code should include "Shaders/Utils/ObjectMotionVectors.hlsl", whose passes sample the base map through the material input file getters. -#pragma target 3.5 - -#pragma vertex vert -#pragma fragment frag - -//-------------------------------------- -// GPU Instancing -#pragma multi_compile_instancing -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl" - -//------------------------------------- -// Other pragmas -#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" - -// ------------------------------------- -// Includes -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" - -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif - -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MotionVectorsCommon.hlsl" - -// ------------------------------------- -// Structs -struct Attributes -{ - float4 position : POSITION; -#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT - float2 uv : TEXCOORD0; -#endif - float3 positionOld : TEXCOORD4; -#if _ADD_PRECOMPUTED_VELOCITY - float3 alembicMotionVector : TEXCOORD5; -#endif - UNITY_VERTEX_INPUT_INSTANCE_ID -}; - -struct Varyings -{ - float4 positionCS : SV_POSITION; - float4 positionCSNoJitter : POSITION_CS_NO_JITTER; - float4 previousPositionCSNoJitter : PREV_POSITION_CS_NO_JITTER; -#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT - float2 uv : TEXCOORD0; -#endif - UNITY_VERTEX_INPUT_INSTANCE_ID - UNITY_VERTEX_OUTPUT_STEREO -}; - -// ------------------------------------- -// Vertex -Varyings vert(Attributes input) -{ - Varyings output = (Varyings)0; - - UNITY_SETUP_INSTANCE_ID(input); - UNITY_TRANSFER_INSTANCE_ID(input, output); - UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); - - const VertexPositionInputs vertexInput = GetVertexPositionInputs(input.position.xyz); - - #if defined(_ALPHATEST_ON) || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT - output.uv = TRANSFORM_TEX(input.uv, _BaseMap); - #endif - -#if defined(APPLICATION_SPACE_WARP_MOTION) - // We do not need jittered position in ASW - output.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, mul(UNITY_MATRIX_M, input.position));; - output.positionCS = output.positionCSNoJitter; -#else - // Jittered. Match the frame. - output.positionCS = vertexInput.positionCS; - output.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, mul(UNITY_MATRIX_M, input.position)); -#endif - - float4 prevPos = (unity_MotionVectorsParams.x == 1) ? float4(input.positionOld, 1) : input.position; - -#if _ADD_PRECOMPUTED_VELOCITY - prevPos = prevPos - float4(input.alembicMotionVector, 0); -#endif - - output.previousPositionCSNoJitter = mul(_PrevViewProjMatrix, mul(UNITY_PREV_MATRIX_M, prevPos)); - - return output; -} - -// ------------------------------------- -// Fragment -float4 frag(Varyings input) : SV_Target -{ - UNITY_SETUP_INSTANCE_ID(input); - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - - #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); - #endif - - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif - - #if defined(APPLICATION_SPACE_WARP_MOTION) - #if APPLICATION_SPACE_WARP_MOTION_TRANSPARENT - clip((SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a * _BaseColor.a) - 0.001); - #endif - return float4(CalcAswNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 1); - #else - return float4(CalcNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 0, 0); - #endif -} - - -#endif // UNIVERSAL_OBJECT_MOTION_VECTORS_INCLUDED +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.deprecated.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl.meta index 9801850efb7..18d44f6152a 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl.meta +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6d239a0044031854a817ab72a66ce766 +guid: 615de22272327434ea7f0505fd1e945f ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl index 177ae181e6a..7ac7a5bd0f0 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl @@ -2,6 +2,16 @@ #define UNIVERSAL_PACK_NORMALS_TEXTURE_INCLUDED #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +#if !defined(_GBUFFER_NORMALS_OCT_KEYWORD_DECLARED) + #if !defined(_GBUFFER_NORMALS_OCT) + #define _GBUFFER_NORMALS_OCT 0 + #elif DEFINED_NONZERO(_GBUFFER_NORMALS_OCT) + #undef _GBUFFER_NORMALS_OCT + #define _GBUFFER_NORMALS_OCT 1 + #endif +#endif // Converts a world-space normal to a packed output format suited for a URP normals texture. // Note that this function does not normalize normalWS, manually normalizing before packing is required. @@ -9,11 +19,12 @@ half3 PackNormalWSToTexture(half3 normalWS) { half3 result = normalWS; // values between [-1, +1] -#if defined(_GBUFFER_NORMALS_OCT) - float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms. - float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, +1] - result = half3(PackFloat2To888(remappedOctNormalWS)); // values between [ 0, +1] -#endif + if (_GBUFFER_NORMALS_OCT) + { + float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms. + float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, +1] + result = half3(PackFloat2To888(remappedOctNormalWS)); // values between [ 0, +1] + } return result; } @@ -23,11 +34,12 @@ half3 UnpackNormalWSFromTexture(half3 packedNormal) { half3 result = packedNormal; // values between [-1, +1] -#if defined(_GBUFFER_NORMALS_OCT) - float2 remappedOctNormalWS = Unpack888ToFloat2(packedNormal); // values between [ 0, +1], must use fp32 to preserve the 12-bit payload. - float2 octNormalWS = remappedOctNormalWS * 2.0 - 1.0; // values between [-1, +1] - result = half3(UnpackNormalOctQuadEncode(octNormalWS)); // values between [-1, +1] -#endif + if (_GBUFFER_NORMALS_OCT) + { + float2 remappedOctNormalWS = Unpack888ToFloat2(packedNormal); // values between [ 0, +1], must use fp32 to preserve the 12-bit payload. + float2 octNormalWS = remappedOctNormalWS * 2.0 - 1.0; // values between [-1, +1] + result = half3(UnpackNormalOctQuadEncode(octNormalWS)); // values between [-1, +1] + } return result; // values between [-1, +1] } diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl new file mode 100644 index 00000000000..a39df2a2c89 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl @@ -0,0 +1,89 @@ +#ifndef UNIVERSAL_PARTICLES_DEPRECATED_INCLUDED +#define UNIVERSAL_PARTICLES_DEPRECATED_INCLUDED + +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" + +// Deprecated pre-multiplied alpha helper macros; must precede the local keyword fallbacks +// below so defined() sees the raw keyword state. New code uses the function forms. +#if defined(_ALPHAPREMULTIPLY_ON) + #define ALBEDO_MUL albedo +#else + #define ALBEDO_MUL albedo.a +#endif + +#if defined(_ALPHAPREMULTIPLY_ON) + #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) albedo * val +#elif defined(_ALPHAMODULATE_ON) + #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) half4(lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a * val), albedo.a * val) +#else + #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) albedo * half4(1.0, 1.0, 1.0, val) +#endif + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (Shaders/Particles/Particles.hlsl). + +#if !defined(_NORMALMAP_KEYWORD_DECLARED) + #if !defined(_NORMALMAP) + #define _NORMALMAP 0 + #define _NORMALMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_NORMALMAP) + #undef _NORMALMAP + #define _NORMALMAP 1 + #endif +#endif + +#if !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAMODULATE_ON) + #define _ALPHAMODULATE_ON 0 + #define _ALPHAMODULATE_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef _ALPHAMODULATE_ON + #define _ALPHAMODULATE_ON 1 + #endif +#endif + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +// Deprecated. Use AlphaModulateAndPremultiply(albedo, alpha, alphaModulateEnabled) gated on either blend mode being enabled. +half3 AlphaModulateAndPremultiply(half3 albedo, half alpha) +{ + half3 result = albedo; + if (_ALPHAMODULATE_ON || _ALPHAPREMULTIPLY_ON) + result = AlphaModulateAndPremultiply(albedo, alpha, _ALPHAMODULATE_ON); + return result; +} + +// Deprecated. Gate SampleParticleNormalTS at the call site instead. +half3 SampleNormalTS(float2 uv, float3 blendUv, UnityTexture2D bumpMap, half scale = half(1.0)) +{ + return _NORMALMAP ? SampleParticleNormalTS(uv, blendUv, bumpMap, scale) : half3(0.0, 0.0, 1.0); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_NORMALMAP_DEFINED_LOCALLY) + #undef _NORMALMAP_DEFINED_LOCALLY + #undef _NORMALMAP +#endif + +#if defined(_ALPHAMODULATE_ON_DEFINED_LOCALLY) + #undef _ALPHAMODULATE_ON_DEFINED_LOCALLY + #undef _ALPHAMODULATE_ON +#endif + +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#endif // UNIVERSAL_PARTICLES_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl.meta new file mode 100644 index 00000000000..80a897153cb --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2e90baa3e13824bbfa3517389f68743d +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl index f9cb8892568..8d75e630e70 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl @@ -1,173 +1,3 @@ -#ifndef UNIVERSAL_PARTICLES_INCLUDED -#define UNIVERSAL_PARTICLES_INCLUDED -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl" -#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/Particles.hlsl" +#warning "ShaderLibrary/Particles.hlsl" is deprecated. Please update your include path to "Shaders/Particles/Particles.hlsl". -struct ParticleParams -{ - float4 positionWS; - float4 vertexColor; - float4 projectedPosition; - half4 baseColor; - float3 blendUv; - float2 uv; -}; - -void InitParticleParams(VaryingsParticle input, out ParticleParams output) -{ - output = (ParticleParams) 0; - output.uv = input.texcoord; - output.vertexColor = input.color; - - #if defined(_FLIPBOOKBLENDING_ON) - output.blendUv = input.texcoord2AndBlend; - #else - output.blendUv = float3(0,0,0); - #endif - - #if !defined(PARTICLES_EDITOR_META_PASS) - output.positionWS = input.positionWS; - output.baseColor = _BaseColor; - - #if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON) - output.projectedPosition = input.projectedPosition; - #else - output.projectedPosition = float4(0,0,0,0); - #endif - #endif -} - -// Pre-multiplied alpha helper -#if defined(_ALPHAPREMULTIPLY_ON) - #define ALBEDO_MUL albedo -#else - #define ALBEDO_MUL albedo.a -#endif - -#if defined(_ALPHAPREMULTIPLY_ON) - #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) albedo * val -#elif defined(_ALPHAMODULATE_ON) - #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) half4(lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a * val), albedo.a * val) -#else - #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) albedo * half4(1.0, 1.0, 1.0, val) -#endif - -// Color blending fragment function -half4 MixParticleColor(half4 baseColor, half4 particleColor, half4 colorAddSubDiff) -{ -#if defined(_COLOROVERLAY_ON) // Overlay blend - half4 output = baseColor; - output.rgb = lerp(1 - 2 * (1 - baseColor.rgb) * (1 - particleColor.rgb), 2 * baseColor.rgb * particleColor.rgb, step(baseColor.rgb, 0.5)); - output.a *= particleColor.a; - return output; -#elif defined(_COLORCOLOR_ON) // Color blend - half3 aHSL = RgbToHsv(baseColor.rgb); - half3 bHSL = RgbToHsv(particleColor.rgb); - half3 rHSL = half3(bHSL.x, bHSL.y, aHSL.z); - return half4(HsvToRgb(rHSL), baseColor.a * particleColor.a); -#elif defined(_COLORADDSUBDIFF_ON) // Additive, Subtractive and Difference blends based on 'colorAddSubDiff' - half4 output = baseColor; - output.rgb = baseColor.rgb + particleColor.rgb * colorAddSubDiff.x; - output.rgb = lerp(output.rgb, abs(output.rgb), colorAddSubDiff.y); - output.a *= particleColor.a; - return output; -#else // Default to Multiply blend - return baseColor * particleColor; -#endif -} - -// Soft particles - returns alpha value for fading particles based on the depth to the background pixel -float SoftParticles(float near, float far, float4 projection) -{ - float fade = 1; - if (near > 0.0 || far > 0.0) - { - float2 uv = UnityStereoTransformScreenSpaceTex(projection.xy / projection.w); -#if defined(UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION) - uv = RemovePretransformRotation(uv); -#endif - uv = FoveatedRemapLinearToNonUniform(uv); - - float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r; - float sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(rawDepth, _ZBufferParams) : LinearDepthToEyeDepth(rawDepth); - float thisZ = LinearEyeDepth(projection.z / projection.w, _ZBufferParams); - fade = saturate(far * ((sceneZ - near) - thisZ)); - } - return fade; -} - -// Soft particles - returns alpha value for fading particles based on the depth to the background pixel -float SoftParticles(float near, float far, ParticleParams params) -{ - float fade = 1; - if (near > 0.0 || far > 0.0) - { - float2 uv = UnityStereoTransformScreenSpaceTex(params.projectedPosition.xy / params.projectedPosition.w); -#if defined(UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION) - uv = RemovePretransformRotation(uv); -#endif - uv = FoveatedRemapLinearToNonUniform(uv); - float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r; - float sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(rawDepth, _ZBufferParams) : LinearDepthToEyeDepth(rawDepth); - float thisZ = LinearEyeDepth(params.positionWS.xyz, GetWorldToViewMatrix()); - fade = saturate(far * ((sceneZ - near) - thisZ)); - } - return fade; -} - -// Camera fade - returns alpha value for fading particles based on camera distance -half CameraFade(float near, float far, float4 projection) -{ - float thisZ = LinearEyeDepth(projection.z / projection.w, _ZBufferParams); - return half(saturate((thisZ - near) * far)); -} - -half3 AlphaModulateAndPremultiply(half3 albedo, half alpha) -{ -#if defined(_ALPHAMODULATE_ON) - return AlphaModulate(albedo, alpha); -#elif defined(_ALPHAPREMULTIPLY_ON) - return AlphaPremultiply(albedo, alpha); -#endif - return albedo; -} - -half3 Distortion(float4 baseColor, float3 normal, half strength, half blend, float4 projection) -{ - float2 screenUV = (projection.xy / projection.w) + normal.xy * strength * baseColor.a; - screenUV = UnityStereoTransformScreenSpaceTex(screenUV); - float3 distortion = SampleSceneColor(screenUV); - return half3(lerp(distortion, baseColor.rgb, saturate(baseColor.a - blend))); -} - -// Sample a texture and do blending for texture sheet animation if needed -half4 BlendTexture(UnityTexture2D _Texture, float2 uv, float3 blendUv) -{ - half4 color = half4(SAMPLE_TEXTURE2D(_Texture.tex, _Texture.samplerstate, uv)); -#ifdef _FLIPBOOKBLENDING_ON - half4 color2 = half4(SAMPLE_TEXTURE2D(_Texture.tex, _Texture.samplerstate, blendUv.xy)); - color = lerp(color, color2, half(blendUv.z)); -#endif - return color; -} - -// Sample a normal map in tangent space -half3 SampleNormalTS(float2 uv, float3 blendUv, UnityTexture2D bumpMap, half scale = half(1.0)) -{ -#if defined(_NORMALMAP) - half4 n = BlendTexture(bumpMap, uv, blendUv); - #if BUMP_SCALE_NOT_SUPPORTED - return UnpackNormal(n); - #else - return UnpackNormalScale(n, scale); - #endif -#else - return half3(0.0, 0.0, 1.0); -#endif -} - -#endif // UNIVERSAL_PARTICLES_INCLUDED +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.deprecated.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl new file mode 100644 index 00000000000..64d057abc07 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl @@ -0,0 +1 @@ +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl.meta new file mode 100644 index 00000000000..b6eb04e1eeb --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9d99a600587424fc5b9b68920172dc48 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl index 4e1ecf3ee4f..257910ffecc 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl @@ -1,97 +1,3 @@ -#ifndef UNIVERSAL_PARTICLESINSTANCING_INCLUDED -#define UNIVERSAL_PARTICLESINSTANCING_INCLUDED +#warning "ShaderLibrary/ParticlesInstancing.hlsl" has moved. Please update your include path to "Shaders/Particles/ParticlesInstancing.hlsl". -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParticlesInstancing.hlsl" - -#if defined(UNITY_PARTICLE_INSTANCING_ENABLED) - -// Kept for backward compatibility with custom shaders that call it directly. -void ParticleInstancingMatrices(out float4x4 objectToWorld, out float4x4 worldToObject) -{ - UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID]; - - // transform matrix - objectToWorld._11_21_31_41 = float4(data.transform._11_21_31, 0.0f); - objectToWorld._12_22_32_42 = float4(data.transform._12_22_32, 0.0f); - objectToWorld._13_23_33_43 = float4(data.transform._13_23_33, 0.0f); - objectToWorld._14_24_34_44 = float4(data.transform._14_24_34, 1.0f); - - // inverse transform matrix - float3x3 worldToObject3x3; - worldToObject3x3[0] = objectToWorld[1].yzx * objectToWorld[2].zxy - objectToWorld[1].zxy * objectToWorld[2].yzx; - worldToObject3x3[1] = objectToWorld[0].zxy * objectToWorld[2].yzx - objectToWorld[0].yzx * objectToWorld[2].zxy; - worldToObject3x3[2] = objectToWorld[0].yzx * objectToWorld[1].zxy - objectToWorld[0].zxy * objectToWorld[1].yzx; - - float det = dot(objectToWorld[0].xyz, worldToObject3x3[0]); - - worldToObject3x3 = transpose(worldToObject3x3); - - worldToObject3x3 *= rcp(det); - - float3 worldToObjectPosition = mul(worldToObject3x3, -objectToWorld._14_24_34); - - worldToObject._11_21_31_41 = float4(worldToObject3x3._11_21_31, 0.0f); - worldToObject._12_22_32_42 = float4(worldToObject3x3._12_22_32, 0.0f); - worldToObject._13_23_33_43 = float4(worldToObject3x3._13_23_33, 0.0f); - worldToObject._14_24_34_44 = float4(worldToObjectPosition, 1.0f); -} - -// Builds VertexPositionInputs from the particle instance transform directly, -// bypassing GetVertexPositionInputs() which reads UNITY_MATRIX_M. -VertexPositionInputs ParticleInstancingGetVertexPositionInputs(float3x4 transform, float3 positionOS) -{ - VertexPositionInputs vertexInput; - vertexInput.positionWS = ParticleInstancingTransformPosition(transform, positionOS); - vertexInput.positionVS = TransformWorldToView(vertexInput.positionWS); - vertexInput.positionCS = TransformWorldToHClip(vertexInput.positionWS); - float4 ndc = vertexInput.positionCS * 0.5f; - vertexInput.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w; - vertexInput.positionNDC.zw = vertexInput.positionCS.zw; - return vertexInput; -} - -// Builds VertexNormalInputs from the particle instance transform directly, -// bypassing GetVertexNormalInputs() which reads UNITY_MATRIX_I_M. -// Tangents transform with the forward 3x3 (covariant, like directions). -// Normals require the inverse-transpose: cofactor(m) equals det(m)*m^{-T}; -// after SafeNormalize this gives the correct world normal under non-uniform scale. -// Matches TransformParticleMesh in the ShaderGraph package (Particles.hlsl). -VertexNormalInputs ParticleInstancingGetVertexNormalInputs(float3x4 transform, float3 normalOS, float4 tangentOS) -{ - ParticleInstancingTransformNormalTangent(transform, normalOS, tangentOS.xyz); - - VertexNormalInputs tbn; - tbn.normalWS = SafeNormalize(normalOS); - tbn.tangentWS = real3(SafeNormalize(tangentOS.xyz)); - - real sign = real(tangentOS.w) * GetOddNegativeScale(); - tbn.bitangentWS = real3(cross(tbn.normalWS, float3(tbn.tangentWS))) * sign; - return tbn; -} - -#endif - -VertexPositionInputs GetParticleVertexPositionInputs(float3 positionOS) -{ -#if defined(UNITY_PARTICLE_INSTANCING_ENABLED) - return ParticleInstancingGetVertexPositionInputs(unity_ParticleInstanceData[unity_InstanceID].transform, positionOS); -#else - return GetVertexPositionInputs(positionOS); -#endif -} - -VertexNormalInputs GetParticleVertexNormalInputs(float3 normalOS, float4 tangentOS) -{ -#if defined(UNITY_PARTICLE_INSTANCING_ENABLED) - return ParticleInstancingGetVertexNormalInputs(unity_ParticleInstanceData[unity_InstanceID].transform, normalOS, tangentOS); -#else - return GetVertexNormalInputs(normalOS, tangentOS); -#endif -} - -VertexNormalInputs GetParticleVertexNormalInputs(float3 normalOS) -{ - return GetParticleVertexNormalInputs(normalOS, float4(0, 0, 0, 1)); -} - -#endif // UNIVERSAL_PARTICLESINSTANCING_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.deprecated.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl new file mode 100644 index 00000000000..2e1d381885a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl @@ -0,0 +1,79 @@ +#ifndef UNIVERSAL_REALTIME_LIGHTS_DEPRECATED_INCLUDED +#define UNIVERSAL_REALTIME_LIGHTS_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusionFactor.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (RealtimeLights.hlsl). + +Light GetMainLight(float4 shadowCoord, bool receiveShadows, bool surfaceTypeTransparent); +Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask, bool receiveShadows, bool surfaceTypeTransparent); +Light GetMainLight(InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor, bool receiveShadows, bool surfaceTypeTransparent); +Light GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask, bool receiveShadows); +Light GetAdditionalLight(uint i, InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor, bool receiveShadows, bool surfaceTypeTransparent); + +#if !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef _SURFACE_TYPE_TRANSPARENT + #define _SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif + +#if !defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) + #if !defined(_RECEIVE_SHADOWS_OFF) + #define _RECEIVE_SHADOWS_OFF 0 + #define _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + #undef _RECEIVE_SHADOWS_OFF + #define _RECEIVE_SHADOWS_OFF 1 + #endif +#endif + +// Deprecated. Use GetMainLight(shadowCoord, receiveShadows, surfaceTypeTransparent). +Light GetMainLight(float4 shadowCoord) +{ + return GetMainLight(shadowCoord, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use GetMainLight(shadowCoord, positionWS, shadowMask, receiveShadows, surfaceTypeTransparent). +Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask) +{ + return GetMainLight(shadowCoord, positionWS, shadowMask, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use GetMainLight(inputData, shadowMask, aoFactor, receiveShadows, surfaceTypeTransparent). +Light GetMainLight(InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor) +{ + return GetMainLight(inputData, shadowMask, aoFactor, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use GetAdditionalLight(i, positionWS, shadowMask, receiveShadows). +Light GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask) +{ + return GetAdditionalLight(i, positionWS, shadowMask, !_RECEIVE_SHADOWS_OFF); +} + +// Deprecated. Use GetAdditionalLight(i, inputData, shadowMask, aoFactor, receiveShadows, surfaceTypeTransparent). +Light GetAdditionalLight(uint i, InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor) +{ + return GetAdditionalLight(i, inputData, shadowMask, aoFactor, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT +#endif + +#if defined(_RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY) + #undef _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY + #undef _RECEIVE_SHADOWS_OFF +#endif + +#endif // UNIVERSAL_REALTIME_LIGHTS_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl.meta new file mode 100644 index 00000000000..139fd98dfcc --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f8e1f59ca40dc4716a73b2127c719edf +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl index 0808411a978..87e8359076f 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl @@ -5,29 +5,21 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookie.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Clustering.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareExposureTexture.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/VolumetricFog.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Light.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.deprecated.hlsl" - -// Abstraction over Light shading data. -struct Light -{ - half3 direction; - half3 color; - float distanceAttenuation; // full-float precision required on some platforms - half shadowAttenuation; - uint layerMask; -}; - -#if USE_CLUSTER_LIGHT_LOOP && defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) -#define CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK if (_AdditionalLightsColor[lightIndex].a > 0.0h) continue; +#if USE_CLUSTER_LIGHT_LOOP + #define CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK if (LightmapAvailable() && LightmapShadowMixingAvailable() && _AdditionalLightsColor[lightIndex].a > 0.0h) continue; #else -#define CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK + #define CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK #endif - #if defined(UNITY_PLATFORM_META_QUEST) && META_QUEST_LIGHTUNROLL #define UNROLL_ONELIGHT [unroll(1)] #else @@ -112,11 +104,7 @@ Light GetMainLight() Light light; light.direction = half3(_MainLightPosition.xyz); #if USE_CLUSTER_LIGHT_LOOP -#if defined(LIGHTMAP_ON) && defined(LIGHTMAP_SHADOW_MIXING) - light.distanceAttenuation = _MainLightColor.a; -#else - light.distanceAttenuation = 1.0; -#endif + light.distanceAttenuation = (LightmapAvailable() && LightmapShadowMixingAvailable()) ? _MainLightColor.a : 1.0; #else light.distanceAttenuation = unity_LightData.z; // unity_LightData.z is 1 when not culled by the culling mask, otherwise 0. #endif @@ -128,22 +116,20 @@ Light GetMainLight() return light; } -Light GetMainLight(float4 shadowCoord) +Light GetMainLight(float4 shadowCoord, bool receiveShadows, bool isSurfaceTypeTransparent) { Light light = GetMainLight(); - light.shadowAttenuation = MainLightRealtimeShadow(shadowCoord); + light.shadowAttenuation = receiveShadows ? SampleMainLightRealtimeShadow(shadowCoord, isSurfaceTypeTransparent) : half(1.0); return light; } -Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask) +Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask, bool receiveShadows, bool isSurfaceTypeTransparent) { Light light = GetMainLight(); - light.shadowAttenuation = MainLightShadow(shadowCoord, positionWS, shadowMask, _MainLightOcclusionProbes); + light.shadowAttenuation = MainLightShadow(shadowCoord, positionWS, shadowMask, _MainLightOcclusionProbes, receiveShadows, isSurfaceTypeTransparent); - #if defined(_LIGHT_COOKIES) - real3 cookieColor = SampleMainLightCookie(positionWS); - light.color *= cookieColor; - #endif + real3 cookieColor = SampleMainLightCookie(positionWS); + light.color *= cookieColor; // Dim the main light by how much height-fog its rays pass through to reach this fragment. // Returns 1 (no change) when no Fog volume override is active. @@ -152,16 +138,14 @@ Light GetMainLight(float4 shadowCoord, float3 positionWS, half4 shadowMask) return light; } -Light GetMainLight(InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor) +Light GetMainLight(InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor, bool receiveShadows, bool isSurfaceTypeTransparent) { - Light light = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask); + Light light = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask, receiveShadows, isSurfaceTypeTransparent); - #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) - if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION)) + if (!isSurfaceTypeTransparent && ScreenSpaceOcclusionAvailable() && IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION)) { light.color *= aoFactor.directAmbientOcclusion; } - #endif return light; } @@ -242,7 +226,7 @@ Light GetAdditionalLight(uint i, float3 positionWS) return GetAdditionalPerObjectLight(lightIndex, positionWS); } -Light GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask) +Light GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask, bool receiveShadows) { #if USE_CLUSTER_LIGHT_LOOP int lightIndex = i; @@ -252,25 +236,22 @@ Light GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask) Light light = GetAdditionalPerObjectLight(lightIndex, positionWS); half4 occlusionProbeChannels = _AdditionalLightsOcclusionProbes[lightIndex]; - light.shadowAttenuation = AdditionalLightShadow(lightIndex, positionWS, light.direction, shadowMask, occlusionProbeChannels); -#if defined(_LIGHT_COOKIES) + light.shadowAttenuation = AdditionalLightShadow(lightIndex, positionWS, light.direction, shadowMask, occlusionProbeChannels, receiveShadows); + real3 cookieColor = SampleAdditionalLightCookie(lightIndex, positionWS); light.color *= cookieColor; -#endif return light; } -Light GetAdditionalLight(uint i, InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor) +Light GetAdditionalLight(uint i, InputData inputData, half4 shadowMask, AmbientOcclusionFactor aoFactor, bool receiveShadows, bool isSurfaceTypeTransparent) { - Light light = GetAdditionalLight(i, inputData.positionWS, shadowMask); + Light light = GetAdditionalLight(i, inputData.positionWS, shadowMask, receiveShadows); - #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) - if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION)) + if (!isSurfaceTypeTransparent && ScreenSpaceOcclusionAvailable() && IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_AMBIENT_OCCLUSION)) { light.color *= aoFactor.directAmbientOcclusion; } - #endif return light; } @@ -291,17 +272,24 @@ int GetAdditionalLightsCount() half4 CalculateShadowMask(InputData inputData) { // To ensure backward compatibility we have to avoid using shadowMask input, as it is not present in older shaders - #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON) - half4 shadowMask = inputData.shadowMask; // Shadowmask was sampled from lightmap - #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - half4 shadowMask = inputData.shadowMask; // Shadowmask (probe occlusion) was sampled from APV - #elif !defined (LIGHTMAP_ON) - half4 shadowMask = unity_ProbesOcclusion; // Sample shadowmask (probe occlusion) from legacy probes + if (LightmapAvailable()) + { + if (ShadowMaskAvailable()) + return inputData.shadowMask; // Shadowmask was sampled from lightmap + else + return half4(1, 1, 1, 1); // Fallback shadowmask, fully unoccluded + } + #if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) + else + { + return inputData.shadowMask; // Shadowmask (probe occlusion) was sampled from APV + } #else - half4 shadowMask = half4(1, 1, 1, 1); // Fallback shadowmask, fully unoccluded + else + { + return unity_ProbesOcclusion; // Sample shadowmask (probe occlusion) from legacy probes + } #endif - - return shadowMask; } #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl index 0eda99ba1c6..1f690917deb 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl @@ -77,18 +77,16 @@ float3 shadergraph_LWSampleSceneNormals(float2 uv) float3 shadergraph_LWBakedGI(float3 positionWS, float3 normalWS, uint2 positionSS, float2 uvStaticLightmap, float2 uvDynamicLightmap, bool applyScaling) { -#ifdef LIGHTMAP_ON - if (applyScaling) + if (LightmapAvailable() || DynamicLightmapAvailable()) { - uvStaticLightmap = uvStaticLightmap * unity_LightmapST.xy + unity_LightmapST.zw; - uvDynamicLightmap = uvDynamicLightmap * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; + if (applyScaling) + { + uvStaticLightmap = TransformLightmapUV(uvStaticLightmap, unity_LightmapST); + uvDynamicLightmap = TransformLightmapUV(uvDynamicLightmap, unity_DynamicLightmapST); + } + return SampleLightmap(uvStaticLightmap, uvDynamicLightmap, normalWS); } -#if defined(DYNAMICLIGHTMAP_ON) - return SampleLightmap(uvStaticLightmap, uvDynamicLightmap, normalWS); -#else - return SampleLightmap(uvStaticLightmap, normalWS); -#endif -#else + #if (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) if (_EnableProbeVolumes && IsLightProbeSamplingEnabled()) { @@ -96,12 +94,9 @@ float3 shadergraph_LWBakedGI(float3 positionWS, float3 normalWS, uint2 positionS EvaluateAdaptiveProbeVolume(positionWS, normalWS, GetWorldSpaceNormalizeViewDir(positionWS), positionSS, bakeDiffuseLighting); return bakeDiffuseLighting; } - else - return SampleSH(normalWS); - #else - return SampleSH(normalWS); #endif -#endif + + return SampleSH(normalWS); } float3 shadergraph_LWReflectionProbe(float3 viewDir, float3 normalOS, float lod) @@ -118,7 +113,7 @@ void shadergraph_LWFog(float3 positionOS, out float4 color, out float density) { color = unity_FogColor; density = 0.0f; - if (FOG_LINEAR || FOG_EXP || FOG_EXP2) + if (DistanceFogAvailable()) { float viewZ = -TransformWorldToView(TransformObjectToWorld(positionOS)).z; float nearZ0ToFarZ = max(viewZ - _ProjectionParams.y, 0); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.deprecated.hlsl index 586abd0fe9c..9c7a5c2a801 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.deprecated.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.deprecated.hlsl @@ -17,4 +17,84 @@ float4 ComputeScreenPos(float4 positionCS) // Deprecated: Call 'firstbitlow' directly instead. #define FIRST_BIT_LOW firstbitlow +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (ShaderVariablesFunctions.hlsl). + +half3 ApplyAlphaModulate(half3 albedo, half alpha); +half3 ApplyAlphaPremultiply(half3 albedo, half alpha); +half3 NormalizeNormalPerPixel(half3 normalWS, bool normalMap); +float3 NormalizeNormalPerPixel(float3 normalWS, bool normalMap); + +#if !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAMODULATE_ON) + #define _ALPHAMODULATE_ON 0 + #define _ALPHAMODULATE_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef _ALPHAMODULATE_ON + #define _ALPHAMODULATE_ON 1 + #endif +#endif + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +#if !defined(_NORMALMAP_KEYWORD_DECLARED) + #if !defined(_NORMALMAP) + #define _NORMALMAP 0 + #define _NORMALMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_NORMALMAP) + #undef _NORMALMAP + #define _NORMALMAP 1 + #endif +#endif + +// Deprecated. Gate ApplyAlphaModulate at the call site instead. +half3 AlphaModulate(half3 albedo, half alpha) +{ + return _ALPHAMODULATE_ON ? ApplyAlphaModulate(albedo, alpha) : albedo; +} + +// Deprecated. Gate ApplyAlphaPremultiply at the call site instead. +half3 AlphaPremultiply(half3 albedo, half alpha) +{ + return _ALPHAPREMULTIPLY_ON ? ApplyAlphaPremultiply(albedo, alpha) : albedo; +} + +// Deprecated. Use NormalizeNormalPerPixel(normalWS, normalMap). +half3 NormalizeNormalPerPixel(half3 normalWS) +{ + return NormalizeNormalPerPixel(normalWS, _NORMALMAP); +} + +// Deprecated. Use NormalizeNormalPerPixel(normalWS, normalMap). +float3 NormalizeNormalPerPixel(float3 normalWS) +{ + return NormalizeNormalPerPixel(normalWS, _NORMALMAP); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_ALPHAMODULATE_ON_DEFINED_LOCALLY) + #undef _ALPHAMODULATE_ON_DEFINED_LOCALLY + #undef _ALPHAMODULATE_ON +#endif + +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#if defined(_NORMALMAP_DEFINED_LOCALLY) + #undef _NORMALMAP_DEFINED_LOCALLY + #undef _NORMALMAP +#endif + #endif // UNITY_SHADER_VARIABLES_FUNCTIONS_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl index bcdb18b98e1..8278d5ca702 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl @@ -4,6 +4,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.deprecated.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/DebuggingCommon.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareExposureTexture.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" VertexPositionInputs GetVertexPositionInputs(float3 positionOS) { @@ -247,9 +248,9 @@ real AlphaDiscard(real alpha, real cutoff, real offset = real(0.0)) return alpha; } -half OutputAlpha(half alpha, bool isTransparent) +half OutputAlpha(half alpha, bool isSurfaceTypeTransparent) { - if (isTransparent) + if (isSurfaceTypeTransparent) { return alpha; } @@ -264,29 +265,22 @@ half OutputAlpha(half alpha, bool isTransparent) } } -half3 AlphaModulate(half3 albedo, half alpha) +half3 ApplyAlphaModulate(half3 albedo, half alpha) { // Fake alpha for multiply blend by lerping albedo towards 1 (white) using alpha. // Manual adjustment for "lighter" multiply effect (similar to "premultiplied alpha") // would be painting whiter pixels in the texture. // This emulates that procedure in shader, so it should be applied to the base/source color. -#if defined(_ALPHAMODULATE_ON) return lerp(half3(1.0, 1.0, 1.0), albedo, alpha); -#else - return albedo; -#endif } -half3 AlphaPremultiply(half3 albedo, half alpha) +half3 ApplyAlphaPremultiply(half3 albedo, half alpha) { // Multiply alpha into albedo only for Preserve Specular material diffuse part. // Preserve Specular material (glass like) has different alpha for diffuse and specular lighting. // Logically this is "variable" Alpha blending. // (HW blend mode is premultiply, but with alpha multiply in shader.) -#if defined(_ALPHAPREMULTIPLY_ON) return albedo * alpha; -#endif - return albedo; } // Normalization used to depend on SHADER_QUALITY @@ -302,39 +296,38 @@ float3 NormalizeNormalPerVertex(float3 normalWS) return normalize(normalWS); } -half3 NormalizeNormalPerPixel(half3 normalWS) +half3 NormalizeNormalPerPixel(half3 normalWS, bool useNormalMap) { + half3 result; // With XYZ normal map encoding we sporadically sample normals with near-zero-length causing Inf/NaN -#if defined(UNITY_NO_DXT5nm) && defined(_NORMALMAP) - return SafeNormalize(normalWS); +#if defined(UNITY_NO_DXT5nm) + if (useNormalMap) + result = SafeNormalize(normalWS); + else + result = normalize(normalWS); #else - return normalize(normalWS); + result = normalize(normalWS); #endif + return result; } -float3 NormalizeNormalPerPixel(float3 normalWS) +float3 NormalizeNormalPerPixel(float3 normalWS, bool useNormalMap) { -#if defined(UNITY_NO_DXT5nm) && defined(_NORMALMAP) - return SafeNormalize(normalWS); + float3 result; +#if defined(UNITY_NO_DXT5nm) + if (useNormalMap) + result = SafeNormalize(normalWS); + else + result = normalize(normalWS); #else - return normalize(normalWS); + result = normalize(normalWS); #endif + return result; } - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Fog.deprecated.hlsl" -half3 MixFogExposed(half3 fragColor, half fogFactor, float preExposureMultiplier) -{ - return MixFogColor(fragColor, preExposureMultiplier * half3(unity_FogColor.rgb), fogFactor); -} - -float3 MixFogExposed(float3 fragColor, float fogFactor, float preExposureMultiplier) -{ - return MixFogColor(fragColor, preExposureMultiplier * float3(unity_FogColor.rgb), fogFactor); -} - // Linear depth buffer value between [0, 1] or [1, 0] to eye depth value between [near, far] half LinearDepthToEyeDepth(half rawDepth) { diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl new file mode 100644 index 00000000000..b28e2ef89ba --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl @@ -0,0 +1,12 @@ +#ifndef UNIVERSAL_SHADOW_SAMPLING_DATA_INCLUDED +#define UNIVERSAL_SHADOW_SAMPLING_DATA_INCLUDED + +struct ShadowSamplingData +{ + half4 shadowOffset0; + half4 shadowOffset1; + float4 shadowmapSize; + half softShadowQuality; +}; + +#endif // UNIVERSAL_SHADOW_SAMPLING_DATA_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl.meta new file mode 100644 index 00000000000..6d5ca7cb164 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a21a1dcd41bf54759a2b2b853558f392 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.deprecated.hlsl index 92aba0181ed..17b5132ac14 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.deprecated.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.deprecated.hlsl @@ -1,10 +1,174 @@ #ifndef UNIVERSAL_SHADOWS_DEPRECATED_INCLUDED #define UNIVERSAL_SHADOWS_DEPRECATED_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl" + // Deprecated: Reduce the number of unique samplers by using inline samplers instead. // Some graphics APIs support only a low number of unique active samplers. #define sampler_ScreenSpaceShadowmapTexture sampler_PointClamp #define sampler_MainLightShadowmapTexture sampler_LinearClampCompare #define sampler_AdditionalLightsShadowmapTexture sampler_LinearClampCompare +// Legacy: _MIXED_LIGHTING_SUBTRACTIVE was an alias for (LIGHTMAP_SHADOW_MIXING && !SHADOWS_SHADOWMASK). +// This runs before the Shadows.hlsl keyword fallbacks, so shaders that still declare it keep working. +#if !defined(LIGHTMAP_SHADOW_MIXING_KEYWORD_DECLARED) && !defined(SHADOWS_SHADOWMASK_KEYWORD_DECLARED) + #if defined(_MIXED_LIGHTING_SUBTRACTIVE) && !defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) + #define LIGHTMAP_SHADOW_MIXING 1 + #endif +#endif + +// Deprecated, callers should use MainLightShadowsAvailable(). The compile-time keyword tests +// stay inside their own keyword's _KEYWORD_DECLARED arms so they never restrict conversion. +#if (_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS) + #define MAIN_LIGHT_CALCULATE_SHADOWS 1 + #endif +#elif !defined(_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED) || (_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(_MAIN_LIGHT_SHADOWS) && !defined(MAIN_LIGHT_CALCULATE_SHADOWS) + #define MAIN_LIGHT_CALCULATE_SHADOWS 1 + #endif +#endif + +#if (_MAIN_LIGHT_SHADOWS_CASCADE_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS) + #define MAIN_LIGHT_CALCULATE_SHADOWS 1 + #endif +#elif !defined(_MAIN_LIGHT_SHADOWS_CASCADE_KEYWORD_DECLARED) || (_MAIN_LIGHT_SHADOWS_CASCADE_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(_MAIN_LIGHT_SHADOWS_CASCADE) && !defined(MAIN_LIGHT_CALCULATE_SHADOWS) + #define MAIN_LIGHT_CALCULATE_SHADOWS 1 + #endif +#endif + +#if (_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS) + #define MAIN_LIGHT_CALCULATE_SHADOWS 1 + #endif +#elif !defined(_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED) || (_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(MAIN_LIGHT_CALCULATE_SHADOWS) + #define MAIN_LIGHT_CALCULATE_SHADOWS 1 + #endif +#endif + +// Deprecated, callers should use AdditionalLightShadowsAvailable(). +#if (_ADDITIONAL_LIGHT_SHADOWS_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #define ADDITIONAL_LIGHT_CALCULATE_SHADOWS 1 +#elif !defined(_ADDITIONAL_LIGHT_SHADOWS_KEYWORD_DECLARED) || (_ADDITIONAL_LIGHT_SHADOWS_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(_ADDITIONAL_LIGHT_SHADOWS) + #define ADDITIONAL_LIGHT_CALCULATE_SHADOWS 1 + #endif +#endif + +// Deprecated. Baked shadow evaluation is always available; keywords have fallbacks. +#define CALCULATE_BAKED_SHADOWS 1 + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (Shadows.hlsl). + +float4 TransformWorldToShadowCoord(float3 positionWS, bool surfaceTypeTransparent); +half SampleMainLightRealtimeShadow(float4 shadowCoord, half4 shadowParams, ShadowSamplingData shadowSamplingData, bool surfaceTypeTransparent); +half SampleMainLightRealtimeShadow(float4 shadowCoord, bool surfaceTypeTransparent); +half SampleAdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowParams, ShadowSamplingData shadowSamplingData); +half SampleAdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection); +half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels, bool receiveShadows, bool surfaceTypeTransparent); +half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels, bool receiveShadows); +float4 GetShadowCoord(VertexPositionInputs vertexInput, bool surfaceTypeTransparent); +bool AdditionalLightShadowsAvailable(); +half4 GetAdditionalLightShadowParams(int lightIndex); + +#if !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef _SURFACE_TYPE_TRANSPARENT + #define _SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif + +#if !defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) + #if !defined(_RECEIVE_SHADOWS_OFF) + #define _RECEIVE_SHADOWS_OFF 0 + #define _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + #undef _RECEIVE_SHADOWS_OFF + #define _RECEIVE_SHADOWS_OFF 1 + #endif #endif + +// Deprecated. Use TransformWorldToShadowCoord(positionWS, surfaceTypeTransparent). +float4 TransformWorldToShadowCoord(float3 positionWS) +{ + return TransformWorldToShadowCoord(positionWS, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Gate SampleMainLightRealtimeShadow(shadowCoord, shadowParams, shadowSamplingData, surfaceTypeTransparent) at the call site instead. +half MainLightRealtimeShadow(float4 shadowCoord, half4 shadowParams, ShadowSamplingData shadowSamplingData) +{ + return _RECEIVE_SHADOWS_OFF ? half(1.0) : SampleMainLightRealtimeShadow(shadowCoord, shadowParams, shadowSamplingData, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Gate SampleMainLightRealtimeShadow(shadowCoord, surfaceTypeTransparent) at the call site instead. +half MainLightRealtimeShadow(float4 shadowCoord) +{ + return _RECEIVE_SHADOWS_OFF ? half(1.0) : SampleMainLightRealtimeShadow(shadowCoord, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Gate SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection, shadowParams, shadowSamplingData) at the call site instead. +half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowParams, ShadowSamplingData shadowSamplingData) +{ + return _RECEIVE_SHADOWS_OFF ? half(1.0) : SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection, shadowParams, shadowSamplingData); +} + +// Deprecated. Gate SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection) at the call site instead. +half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) +{ + return _RECEIVE_SHADOWS_OFF ? half(1.0) : SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection); +} + +// Deprecated: Use AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) in Shadows.hlsl instead, as it supports Point Light shadows +half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS) +{ + return _RECEIVE_SHADOWS_OFF ? half(1.0) : SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, half3(1, 0, 0)); +} + +// Deprecated. Use MainLightShadow(shadowCoord, positionWS, shadowMask, occlusionProbeChannels, receiveShadows, surfaceTypeTransparent). +half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels) +{ + return MainLightShadow(shadowCoord, positionWS, shadowMask, occlusionProbeChannels, !_RECEIVE_SHADOWS_OFF, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated. Use AdditionalLightShadow(lightIndex, positionWS, lightDirection, shadowMask, occlusionProbeChannels, receiveShadows). +half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels) +{ + return AdditionalLightShadow(lightIndex, positionWS, lightDirection, shadowMask, occlusionProbeChannels, !_RECEIVE_SHADOWS_OFF); +} + +// Deprecated. Use GetShadowCoord(vertexInput, surfaceTypeTransparent). +float4 GetShadowCoord(VertexPositionInputs vertexInput) +{ + return GetShadowCoord(vertexInput, _SURFACE_TYPE_TRANSPARENT); +} + +// Deprecated: Use GetAdditionalLightShadowParams instead. +half GetAdditionalLightShadowStrenth(int lightIndex) +{ + if (!AdditionalLightShadowsAvailable() || _RECEIVE_SHADOWS_OFF) + return half(1.0); + + return GetAdditionalLightShadowParams(lightIndex).x; +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT +#endif + +#if defined(_RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY) + #undef _RECEIVE_SHADOWS_OFF_DEFINED_LOCALLY + #undef _RECEIVE_SHADOWS_OFF +#endif + +#endif // UNIVERSAL_SHADOWS_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl index 7439e7f5b7d..777c27a0c4d 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl @@ -1,27 +1,167 @@ #ifndef UNIVERSAL_SHADOWS_INCLUDED #define UNIVERSAL_SHADOWS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GlobalSamplers.hlsl" -#include "Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" -#include "Shadows.deprecated.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lightmaps.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShadowSamplingData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.deprecated.hlsl" + +#if !defined(_ADDITIONAL_LIGHT_SHADOWS_KEYWORD_DECLARED) + #if !defined(_ADDITIONAL_LIGHT_SHADOWS) + static const bool _ADDITIONAL_LIGHT_SHADOWS = 0; + #elif DEFINED_NONZERO(_ADDITIONAL_LIGHT_SHADOWS) + #undef _ADDITIONAL_LIGHT_SHADOWS + #define _ADDITIONAL_LIGHT_SHADOWS 1 + #endif +#endif -#if !defined(_RECEIVE_SHADOWS_OFF) - #if defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN) - #define MAIN_LIGHT_CALCULATE_SHADOWS +#if !defined(_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED) + #if !defined(_MAIN_LIGHT_SHADOWS) + static const bool _MAIN_LIGHT_SHADOWS = 0; + #elif DEFINED_NONZERO(_MAIN_LIGHT_SHADOWS) + #undef _MAIN_LIGHT_SHADOWS + #define _MAIN_LIGHT_SHADOWS 1 + #endif +#endif - #if defined(_MAIN_LIGHT_SHADOWS) || (defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)) - #define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR - #endif +#if !defined(_MAIN_LIGHT_SHADOWS_CASCADE_KEYWORD_DECLARED) + #if !defined(_MAIN_LIGHT_SHADOWS_CASCADE) + static const bool _MAIN_LIGHT_SHADOWS_CASCADE = 0; + #elif DEFINED_NONZERO(_MAIN_LIGHT_SHADOWS_CASCADE) + #undef _MAIN_LIGHT_SHADOWS_CASCADE + #define _MAIN_LIGHT_SHADOWS_CASCADE 1 + #endif +#endif + +#if !defined(_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED) + #if !defined(_MAIN_LIGHT_SHADOWS_SCREEN) + static const bool _MAIN_LIGHT_SHADOWS_SCREEN = 0; + #elif DEFINED_NONZERO(_MAIN_LIGHT_SHADOWS_SCREEN) + #undef _MAIN_LIGHT_SHADOWS_SCREEN + #define _MAIN_LIGHT_SHADOWS_SCREEN 1 + #endif +#endif + +#if !defined(_SHADOWS_SOFT_LOW_KEYWORD_DECLARED) + #if !defined(_SHADOWS_SOFT_LOW) + static const bool _SHADOWS_SOFT_LOW = 0; + #elif DEFINED_NONZERO(_SHADOWS_SOFT_LOW) + #undef _SHADOWS_SOFT_LOW + #define _SHADOWS_SOFT_LOW 1 + #endif +#endif + +#if !defined(_SHADOWS_SOFT_MEDIUM_KEYWORD_DECLARED) + #if !defined(_SHADOWS_SOFT_MEDIUM) + static const bool _SHADOWS_SOFT_MEDIUM = 0; + #elif DEFINED_NONZERO(_SHADOWS_SOFT_MEDIUM) + #undef _SHADOWS_SOFT_MEDIUM + #define _SHADOWS_SOFT_MEDIUM 1 #endif +#endif - #if defined(_ADDITIONAL_LIGHT_SHADOWS) - #define ADDITIONAL_LIGHT_CALCULATE_SHADOWS +#if !defined(_SHADOWS_SOFT_HIGH_KEYWORD_DECLARED) + #if !defined(_SHADOWS_SOFT_HIGH) + static const bool _SHADOWS_SOFT_HIGH = 0; + #elif DEFINED_NONZERO(_SHADOWS_SOFT_HIGH) + #undef _SHADOWS_SOFT_HIGH + #define _SHADOWS_SOFT_HIGH 1 #endif #endif +#if !defined(_SHADOWS_SOFT_KEYWORD_DECLARED) + #if !defined(_SHADOWS_SOFT) + static const bool _SHADOWS_SOFT = 0; + #elif DEFINED_NONZERO(_SHADOWS_SOFT) + #undef _SHADOWS_SOFT + #define _SHADOWS_SOFT 1 + #endif +#endif + +// 1 when the soft-shadow quality keywords are runtime-branching: all qualities then share one +// variant, so filtering must use the single-body filter instead of the per-quality unrolled ones. +#if defined(_SHADOWS_SOFT_LOW_KEYWORD_DECLARED) && (_SHADOWS_SOFT_LOW_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #define SHADOWS_SOFT_DYNAMIC_BRANCH 1 +#else + #define SHADOWS_SOFT_DYNAMIC_BRANCH 0 +#endif + +#if !defined(SHADOWS_SHADOWMASK_KEYWORD_DECLARED) + #if !defined(SHADOWS_SHADOWMASK) + static const bool SHADOWS_SHADOWMASK = 0; + #elif DEFINED_NONZERO(SHADOWS_SHADOWMASK) + #undef SHADOWS_SHADOWMASK + #define SHADOWS_SHADOWMASK 1 + #endif +#endif + +#if !defined(LIGHTMAP_SHADOW_MIXING_KEYWORD_DECLARED) + #if !defined(LIGHTMAP_SHADOW_MIXING) + static const bool LIGHTMAP_SHADOW_MIXING = 0; + #elif DEFINED_NONZERO(LIGHTMAP_SHADOW_MIXING) + #undef LIGHTMAP_SHADOW_MIXING + #define LIGHTMAP_SHADOW_MIXING 1 + #endif +#endif + +#if !defined(_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED) || (_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(_MAIN_LIGHT_SHADOWS) && !defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR 1 + #endif +#endif + +#if !defined(_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED) || (_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR 1 + #endif +#endif + +#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) || (_MAIN_LIGHT_SHADOWS_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) || (_MAIN_LIGHT_SHADOWS_SCREEN_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 1 +#else + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif + +bool ShadowCoordInterpolatorAvailable() +{ + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + return _MAIN_LIGHT_SHADOWS || _MAIN_LIGHT_SHADOWS_SCREEN; + #else + return false; + #endif +} + +bool MainLightShadowsAvailable() +{ + return _MAIN_LIGHT_SHADOWS || _MAIN_LIGHT_SHADOWS_CASCADE || _MAIN_LIGHT_SHADOWS_SCREEN; +} + +bool MainLightScreenShadowsAvailable() +{ + return _MAIN_LIGHT_SHADOWS_SCREEN; +} + +bool AdditionalLightShadowsAvailable() +{ + return _ADDITIONAL_LIGHT_SHADOWS; +} + +bool SoftShadowsAvailable() +{ + return _SHADOWS_SOFT || _SHADOWS_SOFT_LOW || _SHADOWS_SOFT_MEDIUM || _SHADOWS_SOFT_HIGH; +} + +// Should match: UnityEngine.Rendering.Universal + 1 +#define SOFT_SHADOW_QUALITY_OFF half(0) +#define SOFT_SHADOW_QUALITY_LOW half(1) +#define SOFT_SHADOW_QUALITY_MEDIUM half(2) +#define SOFT_SHADOW_QUALITY_HIGH half(3) + #if defined(UNITY_DOTS_INSTANCING_ENABLED) && !defined(USE_LEGACY_LIGHTMAPS) // ^ GPU-driven rendering is enabled, and we haven't opted-out from lightmap // texture arrays. This minimizes batch breakages, but texture arrays aren't @@ -38,22 +178,54 @@ #define SHADOWMASK_SAMPLE_EXTRA_ARGS #endif -#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON) - #if defined(LIGHTMAP_BICUBIC_SAMPLING) - #define SAMPLE_SHADOWMASK(uv) SampleLightmapBicubic(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, uv SHADOWMASK_SAMPLE_EXTRA_ARGS); - #else - #define SAMPLE_SHADOWMASK(uv) SAMPLE_TEXTURE2D_LIGHTMAP(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, uv SHADOWMASK_SAMPLE_EXTRA_ARGS); - #endif -#elif !defined (LIGHTMAP_ON) - #define SAMPLE_SHADOWMASK(uv) unity_ProbesOcclusion; -#else - #define SAMPLE_SHADOWMASK(uv) half4(1, 1, 1, 1); -#endif +bool ShadowMaskAvailable() +{ + return SHADOWS_SHADOWMASK; +} -#define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR +bool LightmapShadowMixingAvailable() +{ + return LIGHTMAP_SHADOW_MIXING; +} + +bool BakedShadowsAvailable() +{ + return LightmapAvailable() || LightmapShadowMixingAvailable() || ShadowMaskAvailable(); +} + +bool MixedLightingSubtractive() +{ + return LightmapShadowMixingAvailable() && !ShadowMaskAvailable(); +} + +half4 SampleShadowMask(float2 lightmapUV) +{ + if (LightmapAvailable()) + { + if (ShadowMaskAvailable()) + { + #if defined(LIGHTMAP_BICUBIC_SAMPLING) + return SampleLightmapBicubic(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, lightmapUV SHADOWMASK_SAMPLE_EXTRA_ARGS); + #else + return SAMPLE_TEXTURE2D_LIGHTMAP(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, lightmapUV SHADOWMASK_SAMPLE_EXTRA_ARGS); + #endif + } + else + { + return half4(1, 1, 1, 1); + } + } + else + { + return unity_ProbesOcclusion; + } +} -#if defined(LIGHTMAP_ON) || defined(LIGHTMAP_SHADOW_MIXING) || defined(SHADOWS_SHADOWMASK) -#define CALCULATE_BAKED_SHADOWS +// Back-compat macro; without a lightmap UV interpolator the uv argument may not exist, so it is discarded. +#if USE_LIGHTMAP_UV_INTERPOLATOR + #define SAMPLE_SHADOWMASK(uv) SampleShadowMask(uv) +#else + #define SAMPLE_SHADOWMASK(uv) unity_ProbesOcclusion; #endif #if !(defined(_SPOT) || defined(_POINT) || defined(_DIRECTIONAL)) @@ -70,7 +242,6 @@ float4 _MainLightShadowParams; // (x: shadowStrength, y: >= 1.0 if soft s float4 _AdditionalShadowFadeParams; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0) -#if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) // Point lights can use 6 shadow slices. Some mobile GPUs performance decrease drastically with uniform // blocks bigger than 8kb while others have a 64kb max uniform block size. This number ensures size of buffer // AdditionalLightShadows stays reasonable. It also avoids shader compilation errors on SHADER_API_GLES30 @@ -85,7 +256,6 @@ float4 _AdditionalShadowParams[MAX_VISIBLE_LIGHTS]; // Per-light da #ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_END #endif -#endif // x: depth bias, // y: normal bias, @@ -110,20 +280,6 @@ half IsPointLight() #define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z <= 0.0 || shadowCoord.z >= 1.0 -// Should match: UnityEngine.Rendering.Universal + 1 -#define SOFT_SHADOW_QUALITY_OFF half(0.0) -#define SOFT_SHADOW_QUALITY_LOW half(1.0) -#define SOFT_SHADOW_QUALITY_MEDIUM half(2.0) -#define SOFT_SHADOW_QUALITY_HIGH half(3.0) - -struct ShadowSamplingData -{ - half4 shadowOffset0; - half4 shadowOffset1; - float4 shadowmapSize; - half softShadowQuality; -}; - ShadowSamplingData GetMainLightShadowSamplingData() { ShadowSamplingData shadowSamplingData; @@ -143,7 +299,8 @@ ShadowSamplingData GetAdditionalLightShadowSamplingData(int index) { ShadowSamplingData shadowSamplingData = (ShadowSamplingData)0; - #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) + if (AdditionalLightShadowsAvailable()) + { // shadowOffsets are used in SampleShadowmapFiltered for low quality soft shadows. shadowSamplingData.shadowOffset0 = _AdditionalShadowOffset0; shadowSamplingData.shadowOffset1 = _AdditionalShadowOffset1; @@ -151,7 +308,7 @@ ShadowSamplingData GetAdditionalLightShadowSamplingData(int index) // shadowmapSize is used in SampleShadowmapFiltered otherwise. shadowSamplingData.shadowmapSize = _AdditionalShadowmapSize; shadowSamplingData.softShadowQuality = _AdditionalShadowParams[index].y; - #endif + } return shadowSamplingData; } @@ -164,7 +321,6 @@ half4 GetMainLightShadowParams() return half4(_MainLightShadowParams); } - // ShadowParams // x: ShadowStrength // y: >= 1.0 if shadow is soft, 0.0 otherwise. Higher value for higher quality. (1.0 == low, 2.0 == medium, 3.0 == high) @@ -172,17 +328,17 @@ half4 GetMainLightShadowParams() // w: first shadow slice index for this light, there can be 6 in case of point lights. (-1 for non-shadow-casting-lights) half4 GetAdditionalLightShadowParams(int lightIndex) { - half4 results; - #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) + // Same defaults as set in AdditionalLightsShadowCasterPass.cs + half4 results = half4(0, 0, 0, -1); + + if (AdditionalLightShadowsAvailable()) + { results = _AdditionalShadowParams[lightIndex]; // workaround: Avoid failing the graphics test using Terrain Shader on Android Vulkan when using dynamic branching for fog keywords. #if !SKIP_SHADOWS_LIGHT_INDEX_CHECK results.w = lightIndex < 0 ? -1 : results.w; #endif - #else - // Same defaults as set in AdditionalLightsShadowCasterPass.cs - return half4(0, 0, 0, -1); - #endif + } return results; } @@ -259,26 +415,63 @@ real SampleShadowmapFilteredHighQuality(TEXTURE2D_SHADOW_PARAM(ShadowMap, sample + fetchesWeights[15] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[15].xy, shadowCoord.z)); } -real SampleShadowmapFiltered(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) +// Single-body soft filter for runtime-selected quality (per-light, and dynamic-keyword builds). +half SampleShadowmapFilteredUnified(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData, half quality) { - real attenuation = real(1.0); + // Up to 16 taps for the active quality, accumulated in fixed 4-tap chunks gated by quality. + // All indexing is compile-time constant for better codegen. + float fetchesWeights[16]; + float2 fetchesUV[16]; + + // Zero-init so unused taps contribute nothing even if the hardware flattens the quality gates below. + UNITY_UNROLL for (int z = 0; z < 16; z++) { fetchesWeights[z] = 0.0; fetchesUV[z] = shadowCoord.xy; } - if (samplingData.softShadowQuality == SOFT_SHADOW_QUALITY_LOW) + if (quality >= SOFT_SHADOW_QUALITY_HIGH) { - attenuation = SampleShadowmapFilteredLowQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); + SampleShadow_ComputeSamples_Tent_Filter_7x7(float, samplingData.shadowmapSize, shadowCoord, fetchesWeights, fetchesUV); } - else if(samplingData.softShadowQuality == SOFT_SHADOW_QUALITY_MEDIUM) + else if (quality >= SOFT_SHADOW_QUALITY_MEDIUM) { - attenuation = SampleShadowmapFilteredMediumQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); + SampleShadow_ComputeSamples_Tent_Filter_5x5(float, samplingData.shadowmapSize, shadowCoord, fetchesWeights, fetchesUV); } - else // SOFT_SHADOW_QUALITY_HIGH + else { - attenuation = SampleShadowmapFilteredHighQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); + fetchesWeights[0] = 0.25; fetchesUV[0] = shadowCoord.xy + samplingData.shadowOffset0.xy; + fetchesWeights[1] = 0.25; fetchesUV[1] = shadowCoord.xy + samplingData.shadowOffset0.zw; + fetchesWeights[2] = 0.25; fetchesUV[2] = shadowCoord.xy + samplingData.shadowOffset1.xy; + fetchesWeights[3] = 0.25; fetchesUV[3] = shadowCoord.xy + samplingData.shadowOffset1.zw; } + #define SHADOW_TAP(i) half(fetchesWeights[i]) * half(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[i].xy, shadowCoord.z))) + + // chunk 0: 4 taps (LOW and up) + half attenuation = SHADOW_TAP(0) + SHADOW_TAP(1) + SHADOW_TAP(2) + SHADOW_TAP(3); + + UNITY_BRANCH + if (quality >= SOFT_SHADOW_QUALITY_MEDIUM) + { + // chunk 1: taps 4..8 (MEDIUM is 9 taps; pad with the zeroed 9th) + attenuation += SHADOW_TAP(4) + SHADOW_TAP(5) + SHADOW_TAP(6) + SHADOW_TAP(7) + SHADOW_TAP(8); + + UNITY_BRANCH + if (quality >= SOFT_SHADOW_QUALITY_HIGH) + { + // chunk 2: taps 9..15 (HIGH is 16 taps) + attenuation += SHADOW_TAP(9) + SHADOW_TAP(10) + SHADOW_TAP(11) + SHADOW_TAP(12) + + SHADOW_TAP(13) + SHADOW_TAP(14) + SHADOW_TAP(15); + } + } + + #undef SHADOW_TAP return attenuation; } +half SampleShadowmapFiltered(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData) +{ + // Per-light soft-shadow quality is a runtime value, so always use the single-body filter. + return SampleShadowmapFilteredUnified(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData, samplingData.softShadowQuality); +} + real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData, half4 shadowParams, bool isPerspectiveProjection = true) { // Compiler will optimize this branch away as long as isPerspectiveProjection is known at compile time @@ -288,15 +481,37 @@ real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float real attenuation; real shadowStrength = shadowParams.x; - // Quality levels are only for platforms requiring strict static branches - #if defined(_SHADOWS_SOFT_LOW) +#if SHADOWS_SOFT_DYNAMIC_BRANCH + half quality = _SHADOWS_SOFT_HIGH ? SOFT_SHADOW_QUALITY_HIGH + : _SHADOWS_SOFT_MEDIUM ? SOFT_SHADOW_QUALITY_MEDIUM + : _SHADOWS_SOFT_LOW ? SOFT_SHADOW_QUALITY_LOW + : _SHADOWS_SOFT ? shadowParams.y + : SOFT_SHADOW_QUALITY_OFF; + + if (quality > SOFT_SHADOW_QUALITY_OFF) + { + attenuation = SampleShadowmapFilteredUnified(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData, quality); + } + else + { + attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz)); + } +#else + if (_SHADOWS_SOFT_LOW) + { attenuation = SampleShadowmapFilteredLowQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); - #elif defined(_SHADOWS_SOFT_MEDIUM) + } + else if (_SHADOWS_SOFT_MEDIUM) + { attenuation = SampleShadowmapFilteredMediumQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); - #elif defined(_SHADOWS_SOFT_HIGH) + } + else if (_SHADOWS_SOFT_HIGH) + { attenuation = SampleShadowmapFilteredHighQuality(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); - #elif defined(_SHADOWS_SOFT) - if (shadowParams.y > SOFT_SHADOW_QUALITY_OFF) + } + else if (_SHADOWS_SOFT) + { + if (shadowParams.y > (half)SOFT_SHADOW_QUALITY_OFF) { attenuation = SampleShadowmapFiltered(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData); } @@ -304,9 +519,13 @@ real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float { attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz)); } - #else + } + else + { attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz)); - #endif + } +#endif + attenuation = LerpWhiteTo(attenuation, shadowStrength); @@ -329,56 +548,61 @@ half ComputeCascadeIndex(float3 positionWS) return half(4.0) - dot(weights, half4(4, 3, 2, 1)); } -float4 TransformWorldToShadowCoord(float3 positionWS) +float4 TransformWorldToShadowCoord(float3 positionWS, bool isSurfaceTypeTransparent) { -#if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) - float4 shadowCoord = float4(ComputeNormalizedDeviceCoordinatesWithZ(positionWS, GetWorldToHClipMatrix()), 1.0); -#else - #ifdef _MAIN_LIGHT_SHADOWS_CASCADE - half cascadeIndex = ComputeCascadeIndex(positionWS); - #else - half cascadeIndex = half(0.0); - #endif + float4 shadowCoord = (float4)0; + + if (_MAIN_LIGHT_SHADOWS_SCREEN && !isSurfaceTypeTransparent) + { + shadowCoord = float4(ComputeNormalizedDeviceCoordinatesWithZ(positionWS, GetWorldToHClipMatrix()), 1.0); + } + else + { + half cascadeIndex = _MAIN_LIGHT_SHADOWS_CASCADE ? ComputeCascadeIndex(positionWS) : 0; + shadowCoord = float4(mul(_MainLightWorldToShadow[cascadeIndex], float4(positionWS, 1.0)).xyz, 1.0); + } - float4 shadowCoord = float4(mul(_MainLightWorldToShadow[cascadeIndex], float4(positionWS, 1.0)).xyz, 1.0); -#endif return shadowCoord; } -half MainLightRealtimeShadow(float4 shadowCoord, half4 shadowParams, ShadowSamplingData shadowSamplingData) +half SampleMainLightRealtimeShadow(float4 shadowCoord, half4 shadowParams, ShadowSamplingData shadowSamplingData, bool isSurfaceTypeTransparent) { - #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS) - return half(1.0); - #endif + half result = 1; #if (UNITY_PLATFORM_META_QUEST) // Avoid shadowmap lookup if coordinates are outside of the shadowmap. - if (shadowCoord.z < 0.0 || any(saturate(shadowCoord.xy) != shadowCoord.xy)) - return half(1.0); + bool shadowCoordsValid = !(shadowCoord.z < 0.0 || any(saturate(shadowCoord.xy) != shadowCoord.xy)); +#else + bool shadowCoordsValid = true; #endif - #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) - return SampleScreenSpaceShadowmap(shadowCoord); - #else - return SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, false); - #endif + if (MainLightShadowsAvailable() && shadowCoordsValid) + { + if (_MAIN_LIGHT_SHADOWS_SCREEN && !isSurfaceTypeTransparent) + { + result = SampleScreenSpaceShadowmap(shadowCoord); + } + else + { + result = SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, false); + } + } + + return result; } -half MainLightRealtimeShadow(float4 shadowCoord) +half SampleMainLightRealtimeShadow(float4 shadowCoord, bool isSurfaceTypeTransparent) { - #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS) - return half(1.0); - #endif - - return MainLightRealtimeShadow(shadowCoord, GetMainLightShadowParams(), GetMainLightShadowSamplingData()); + return SampleMainLightRealtimeShadow(shadowCoord, GetMainLightShadowParams(), GetMainLightShadowSamplingData(), isSurfaceTypeTransparent); } // returns 0.0 if position is in light's shadow // returns 1.0 if position is in light -half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowParams, ShadowSamplingData shadowSamplingData) +half SampleAdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowParams, ShadowSamplingData shadowSamplingData) { - half shadow = half(1.0); + half result = 1.0; - #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) + if (AdditionalLightShadowsAvailable()) + { int shadowSliceIndex = shadowParams.w; if (shadowSliceIndex >= 0) { @@ -397,20 +621,19 @@ half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 ligh float4 shadowCoord = mul(_AdditionalLightsWorldToShadow[shadowSliceIndex], float4(positionWS, 1.0)); - shadow = SampleShadowmap(TEXTURE2D_ARGS(_AdditionalLightsShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, true); + result = SampleShadowmap(TEXTURE2D_ARGS(_AdditionalLightsShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, true); } - #endif + } - return shadow; + return result; } -half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) +half SampleAdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) { - #if !defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) - return half(1.0); - #endif - - return AdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection, GetAdditionalLightShadowParams(lightIndex), GetAdditionalLightShadowSamplingData(lightIndex)); + half result = half(1.0); + if (AdditionalLightShadowsAvailable()) + result = SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection, GetAdditionalLightShadowParams(lightIndex), GetAdditionalLightShadowSamplingData(lightIndex)); + return result; } half GetMainLightShadowFade(float3 positionWS) @@ -424,24 +647,25 @@ half GetMainLightShadowFade(float3 positionWS) half GetAdditionalLightShadowFade(float3 positionWS) { - #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) + half shadowFade = half(1.0); + if (AdditionalLightShadowsAvailable()) + { float3 camToPixel = positionWS - _WorldSpaceCameraPos; float distanceCamToPixel2 = dot(camToPixel, camToPixel); float fade = saturate(distanceCamToPixel2 * float(_AdditionalShadowFadeParams.x) + float(_AdditionalShadowFadeParams.y)); - return half(fade); - #else - return half(1.0); - #endif + shadowFade = half(fade); + } + + return shadowFade; } half MixRealtimeAndBakedShadows(half realtimeShadow, half bakedShadow, half shadowFade) { -#if defined(LIGHTMAP_SHADOW_MIXING) - return min(lerp(realtimeShadow, 1, shadowFade), bakedShadow); -#else - return lerp(realtimeShadow, bakedShadow, shadowFade); -#endif + if (LightmapShadowMixingAvailable()) + return min(lerp(realtimeShadow, 1, shadowFade), bakedShadow); + else + return lerp(realtimeShadow, bakedShadow, shadowFade); } half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels, half4 shadowParams) @@ -456,60 +680,59 @@ half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels, half4 shadowPar return bakedShadow; } -half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels) +half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels, bool receiveShadows, bool isSurfaceTypeTransparent) { half4 shadowParams = GetMainLightShadowParams(); - half realtimeShadow = MainLightRealtimeShadow(shadowCoord, shadowParams, GetMainLightShadowSamplingData()); + // receiveShadows only disables the realtime contribution; the baked shadowmask below still + // applies (the material Receive Shadows toggle never affected baked shadows). + half realtimeShadow = receiveShadows ? SampleMainLightRealtimeShadow(shadowCoord, shadowParams, GetMainLightShadowSamplingData(), isSurfaceTypeTransparent) : half(1.0); - #ifdef CALCULATE_BAKED_SHADOWS - half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels, shadowParams); - #else - half bakedShadow = half(1.0); - #endif + half bakedShadow = BakedShadowsAvailable() ? BakedShadow(shadowMask, occlusionProbeChannels, shadowParams) : half(1.0); - #ifdef MAIN_LIGHT_CALCULATE_SHADOWS - half shadowFade = GetMainLightShadowFade(positionWS); - #else - half shadowFade = half(1.0); - #endif + half shadowFade = (MainLightShadowsAvailable() && receiveShadows) ? GetMainLightShadowFade(positionWS) : half(1.0); return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade); } -half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels) +half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels, bool receiveShadows) { half4 shadowParams = GetAdditionalLightShadowParams(lightIndex); ShadowSamplingData samplingData = GetAdditionalLightShadowSamplingData(lightIndex); - half realtimeShadow = AdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection, shadowParams, samplingData); + // receiveShadows only disables the realtime contribution; the baked shadowmask below still + // applies (the material Receive Shadows toggle never affected baked shadows). + half realtimeShadow = receiveShadows ? SampleAdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection, shadowParams, samplingData) : half(1.0); - #ifdef CALCULATE_BAKED_SHADOWS + half bakedShadow = half(1.0); + if (BakedShadowsAvailable()) + { // This fading of the baked shadow using the light's shadow strength parameter needs // to be guarded against the Real-Time Shadow keyword as _AdditionalShadowParams is // only included in URP Shaders and updated when real time additional shadows are enabled. - #ifndef ADDITIONAL_LIGHT_CALCULATE_SHADOWS + if (!(AdditionalLightShadowsAvailable() && receiveShadows)) shadowParams.x = half(1.0); - #endif - half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels, shadowParams); - #else - half bakedShadow = half(1.0); - #endif - #ifdef ADDITIONAL_LIGHT_CALCULATE_SHADOWS - half shadowFade = GetAdditionalLightShadowFade(positionWS); - #else - half shadowFade = half(1.0); - #endif + bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels, shadowParams); + } + + half shadowFade = (AdditionalLightShadowsAvailable() && receiveShadows) ? GetAdditionalLightShadowFade(positionWS) : half(1.0); return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade); } -float4 GetShadowCoord(VertexPositionInputs vertexInput) +float4 GetShadowCoord(VertexPositionInputs vertexInput, bool isSurfaceTypeTransparent) { -#if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) - return ComputeScreenPos(vertexInput.positionCS); -#else - return TransformWorldToShadowCoord(vertexInput.positionWS); -#endif + float4 result = (float4)0; + + if (_MAIN_LIGHT_SHADOWS_SCREEN && !isSurfaceTypeTransparent) + { + result = vertexInput.positionNDC; + } + else + { + result = TransformWorldToShadowCoord(vertexInput.positionWS, isSurfaceTypeTransparent); + } + + return result; } float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection) @@ -571,16 +794,6 @@ half GetMainLightShadowStrength() return half(_MainLightShadowData.x); } -// Deprecated: Use GetAdditionalLightShadowParams instead. -half GetAdditionalLightShadowStrenth(int lightIndex) -{ - #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) - return half(_AdditionalShadowParams[lightIndex].x); - #else - return half(1.0); - #endif -} - // Deprecated: Use SampleShadowmap that takes shadowParams instead of strength. real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), ShadowSamplingData samplingData, half shadowStrength, bool isPerspectiveProjection = true) { @@ -588,19 +801,9 @@ real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_PARAM(ShadowMap, sampl return SampleShadowmap(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData, shadowParams, isPerspectiveProjection); } -// Deprecated: Use AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) in Shadows.hlsl instead, as it supports Point Light shadows -half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS) -{ - return AdditionalLightRealtimeShadow(lightIndex, positionWS, half3(1, 0, 0)); -} - // Deprecated: Use BakedShadow(half4 shadowMask, half4 occlusionProbeChannels, half4 shadowParams) as it supports shadowStrength from the light half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels) { - #ifndef CALCULATE_BAKED_SHADOWS - return half(1.0); - #endif - return BakedShadow(shadowMask, occlusionProbeChannels, half4(1,0,0,0)); } diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SixWayLighting.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SixWayLighting.hlsl index 56b38f5bb19..9812efedf6d 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SixWayLighting.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SixWayLighting.hlsl @@ -48,34 +48,33 @@ void SampleAPVSixWay(APVSample apvSample, half3x3 tbn, out half4 diffuseGIData[3 void GatherDiffuseGIData(float3 positionWS, float3 normalWS, float4 tangentWS, inout half4 diffuseGIData0, inout half4 diffuseGIData1, inout half4 diffuseGIData2) { - #if defined(LIGHTMAP_ON) - //Do nothing + if (LightmapAvailable()) + return; + + half4 diffuseGIData[] = {diffuseGIData0, diffuseGIData1, diffuseGIData2}; + float crossSign = (tangentWS.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale(); + float3 bitangentWS = crossSign * cross(normalWS, tangentWS.xyz); + float3x3 tbn = float3x3(tangentWS.xyz, bitangentWS, -normalWS); + + #if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) + APVSample apvSample = SampleAPV(positionWS, normalWS, 0xFFFFFFFF, 0); + if (apvSample.status != APV_SAMPLE_STATUS_INVALID) + { + apvSample.Decode(); + SampleAPVSixWay(apvSample, tbn, diffuseGIData); + } #else - half4 diffuseGIData[] = {diffuseGIData0, diffuseGIData1, diffuseGIData2}; - float crossSign = (tangentWS.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale(); - float3 bitangentWS = crossSign * cross(normalWS, tangentWS.xyz); - float3x3 tbn = float3x3(tangentWS.xyz, bitangentWS, -normalWS); - - #if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) - APVSample apvSample = SampleAPV(positionWS, normalWS, 0xFFFFFFFF, 0); - if (apvSample.status != APV_SAMPLE_STATUS_INVALID) - { - apvSample.Decode(); - SampleAPVSixWay(apvSample, tbn, diffuseGIData); - } - #else - half3 L0 = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); - - for (int i = 0; i<3; i++) - { - diffuseGIData[i].xyz = SHEvalLinearL1(tbn[i] * kInvClampedCosine1, unity_SHAr.xyz, unity_SHAg.xyz, unity_SHAb.xyz); - diffuseGIData[i].w = L0[i]; - } - #endif - diffuseGIData0 = diffuseGIData[0]; - diffuseGIData1 = diffuseGIData[1]; - diffuseGIData2 = diffuseGIData[2]; + half3 L0 = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); + + for (int i = 0; i<3; i++) + { + diffuseGIData[i].xyz = SHEvalLinearL1(tbn[i] * kInvClampedCosine1, unity_SHAr.xyz, unity_SHAg.xyz, unity_SHAb.xyz); + diffuseGIData[i].w = L0[i]; + } #endif + diffuseGIData0 = diffuseGIData[0]; + diffuseGIData1 = diffuseGIData[1]; + diffuseGIData2 = diffuseGIData[2]; } half3 ComputeGIColor(SixWaySurfaceData surfaceData) @@ -134,9 +133,7 @@ URP_LIGHT_ACCUM4 UniversalFragmentSixWay(InputData inputData, SixWaySurfaceData lightingData.giColor = ComputeGIColor(surfaceData); - #ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers)) - #endif + if (IsMatchingLightLayer(mainLight, meshRenderingLayers)) { lightingData.mainLightColor = SixWayLightBlend(surfaceData, mainLight, inputData.tangentToWorld); } @@ -151,9 +148,7 @@ URP_LIGHT_ACCUM4 UniversalFragmentSixWay(InputData inputData, SixWaySurfaceData Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor); - #ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) - #endif + if (IsMatchingLightLayer(light, meshRenderingLayers)) { lightingData.additionalLightsColor += SixWayLightBlend(surfaceData, light, inputData.tangentToWorld); } @@ -163,12 +158,10 @@ URP_LIGHT_ACCUM4 UniversalFragmentSixWay(InputData inputData, SixWaySurfaceData LIGHT_LOOP_BEGIN(pixelLightCount) Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor); - #ifdef _LIGHT_LAYERS - if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers)) - #endif - { - lightingData.additionalLightsColor += SixWayLightBlend(surfaceData, light, inputData.tangentToWorld); - } + if (IsMatchingLightLayer(light, meshRenderingLayers)) + { + lightingData.additionalLightsColor += SixWayLightBlend(surfaceData, light, inputData.tangentToWorld); + } LIGHT_LOOP_END #endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl new file mode 100644 index 00000000000..339a354a580 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl @@ -0,0 +1,19 @@ + +#ifndef UNIVERSAL_INPUT_SURFACE_DEPRECATED_INCLUDED +#define UNIVERSAL_INPUT_SURFACE_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" + +TEXTURE2D(_BaseMap); +SAMPLER(sampler_BaseMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); +TEXTURE2D(_EmissionMap); +SAMPLER(sampler_EmissionMap); + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl" + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl.meta new file mode 100644 index 00000000000..e06e83522dd --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 501294f78a9e249538247b7e4af97d97 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl index effb2fdd04a..eb7b04a5f74 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl @@ -1,62 +1,3 @@ -#ifndef UNIVERSAL_INPUT_SURFACE_INCLUDED -#define UNIVERSAL_INPUT_SURFACE_INCLUDED +#warning "ShaderLibrary/SurfaceInput.hlsl" is deprecated. Materials own their texture bindings; declare them in the shader's input file (see Shaders/LitInput.hlsl). -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" - -TEXTURE2D(_BaseMap); -SAMPLER(sampler_BaseMap); -UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); -TEXTURE2D(_BumpMap); -SAMPLER(sampler_BumpMap); -TEXTURE2D(_EmissionMap); -SAMPLER(sampler_EmissionMap); - -/////////////////////////////////////////////////////////////////////////////// -// Material Property Helpers // -/////////////////////////////////////////////////////////////////////////////// -half Alpha(half albedoAlpha, half4 color, half cutoff) -{ -#if !defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) && !defined(_GLOSSINESS_FROM_BASE_ALPHA) - half alpha = albedoAlpha * color.a; -#else - half alpha = color.a; -#endif - - alpha = AlphaDiscard(alpha, cutoff); - - return alpha; -} - -half4 SampleAlbedoAlpha(float2 uv, TEXTURE2D_PARAM(albedoAlphaMap, sampler_albedoAlphaMap)) -{ - return half4(SAMPLE_TEXTURE2D(albedoAlphaMap, sampler_albedoAlphaMap, uv)); -} - -half3 SampleNormal(float2 uv, TEXTURE2D_PARAM(bumpMap, sampler_bumpMap), half scale = half(1.0)) -{ -#ifdef _NORMALMAP - half4 n = SAMPLE_TEXTURE2D(bumpMap, sampler_bumpMap, uv); - #if BUMP_SCALE_NOT_SUPPORTED - return UnpackNormal(n); - #else - return UnpackNormalScale(n, scale); - #endif -#else - return half3(0.0h, 0.0h, 1.0h); -#endif -} - -half3 SampleEmission(float2 uv, half3 emissionColor, TEXTURE2D_PARAM(emissionMap, sampler_emissionMap)) -{ -#ifndef _EMISSION - return 0; -#else - return SAMPLE_TEXTURE2D(emissionMap, sampler_emissionMap, uv).rgb * emissionColor; -#endif -} - -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.deprecated.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl new file mode 100644 index 00000000000..f6dd0afedaf --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl @@ -0,0 +1,115 @@ +#ifndef UNIVERSAL_INPUT_SURFACE_FUNCTIONS_DEPRECATED_INCLUDED +#define UNIVERSAL_INPUT_SURFACE_FUNCTIONS_DEPRECATED_INCLUDED + +// Deprecated keyword-reading material helpers, kept for external back-compat. +// They are fully parameterized (no texture bindings), so the material input files can expose +// them through their own .deprecated counterparts without duplicating resource declarations. +// New code samples through the material getters and the Shaders/Utils feature helpers. + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +#if !defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_KEYWORD_DECLARED) + #if !defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) + #define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 0 + #define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) + #undef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #define _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1 + #endif +#endif + +#if !defined(_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED) + #if !defined(_GLOSSINESS_FROM_BASE_ALPHA) + #define _GLOSSINESS_FROM_BASE_ALPHA 0 + #define _GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_GLOSSINESS_FROM_BASE_ALPHA) + #undef _GLOSSINESS_FROM_BASE_ALPHA + #define _GLOSSINESS_FROM_BASE_ALPHA 1 + #endif +#endif + +#if !defined(_NORMALMAP_KEYWORD_DECLARED) + #if !defined(_NORMALMAP) + #define _NORMALMAP 0 + #define _NORMALMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_NORMALMAP) + #undef _NORMALMAP + #define _NORMALMAP 1 + #endif +#endif + +#if !defined(_EMISSION_KEYWORD_DECLARED) + #if !defined(_EMISSION) + #define _EMISSION 0 + #define _EMISSION_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_EMISSION) + #undef _EMISSION + #define _EMISSION 1 + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Material Property Helpers // +/////////////////////////////////////////////////////////////////////////////// +half Alpha(half albedoAlpha, half4 color, half cutoff) +{ + half alpha = (_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A || _GLOSSINESS_FROM_BASE_ALPHA) ? color.a : albedoAlpha * color.a; + + alpha = AlphaDiscard(alpha, cutoff); + + return alpha; +} + +half4 SampleAlbedoAlpha(float2 uv, TEXTURE2D_PARAM(albedoAlphaMap, sampler_albedoAlphaMap)) +{ + return half4(SAMPLE_TEXTURE2D(albedoAlphaMap, sampler_albedoAlphaMap, uv)); +} + +half3 SampleNormal(float2 uv, TEXTURE2D_PARAM(bumpMap, sampler_bumpMap), half scale = half(1.0)) +{ + half3 normalTS = half3(0.0h, 0.0h, 1.0h); + if (_NORMALMAP) + { + half4 n = SAMPLE_TEXTURE2D(bumpMap, sampler_bumpMap, uv); + #if BUMP_SCALE_NOT_SUPPORTED + normalTS = UnpackNormal(n); + #else + normalTS = UnpackNormalScale(n, scale); + #endif + } + return normalTS; +} + +half3 SampleEmission(float2 uv, half3 emissionColor, TEXTURE2D_PARAM(emissionMap, sampler_emissionMap)) +{ + half3 emission = half3(0.0h, 0.0h, 0.0h); + if (_EMISSION) + emission = SAMPLE_TEXTURE2D(emissionMap, sampler_emissionMap, uv).rgb * emissionColor; + return emission; +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_DEFINED_LOCALLY) + #undef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_DEFINED_LOCALLY + #undef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A +#endif + +#if defined(_GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY) + #undef _GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY + #undef _GLOSSINESS_FROM_BASE_ALPHA +#endif + +#if defined(_NORMALMAP_DEFINED_LOCALLY) + #undef _NORMALMAP_DEFINED_LOCALLY + #undef _NORMALMAP +#endif + +#if defined(_EMISSION_DEFINED_LOCALLY) + #undef _EMISSION_DEFINED_LOCALLY + #undef _EMISSION +#endif + +#endif // UNIVERSAL_INPUT_SURFACE_FUNCTIONS_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl.meta new file mode 100644 index 00000000000..d28e5ea8968 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ac0577e0f34b94a23a1625b3af6bd551 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/VolumetricFog.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/VolumetricFog.hlsl index bf869c896f0..c4ab07f2e23 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/VolumetricFog.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/VolumetricFog.hlsl @@ -2,6 +2,7 @@ #define UNIVERSAL_VOLUMETRIC_FOG_INCLUDED #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/VolumeRendering.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" // The height-fog band used to attenuate the main directional light on surfaces and in the // v-buffer lighting. Set from C# before opaque rendering; the fog type driving these values @@ -92,30 +93,13 @@ void ApplyAnalyticFog(float cosZenith, float cameraHeight, float startDist, floa } } -// Resolves the MixVolumetricFog blend mode for shaders that carry it as compile-time -// defines (ShaderGraph targets) rather than as the _Blend material float. Graphs whose -// blending is material-overridable expose only Multiply as a keyword, so their Premultiply -// and Additive materials fall back to the Alpha formula. -half VolumetricFogBlendModeFromDefines() -{ -#if defined(_BLENDMODE_ADDITIVE) - return 2.0; -#elif defined(_ALPHAMODULATE_ON) - return 3.0; -#elif defined(_BLENDMODE_PREMULTIPLY) - return 1.0; -#else - return 0.0; -#endif -} - // Applies the volume-driven fog to a transparent surface's shaded color, before hardware // blending. Sampling a transparent fragment's own depth is safe with respect to the zeroed // slices past the MaxZ early-out because the fragment is always nearer than the opaque depth // that built the mask, and VolumetricFogSliceCoord biases the lookup toward the camera. // 'blendMode' follows BaseShaderGUI.BlendMode: 0 = Alpha, 1 = Premultiply, 2 = Additive, // 3 = Multiply. 'positionCS' is the fragment's SV_Position. -half3 MixVolumetricFog(half3 color, half alpha, half blendMode, float4 positionCS) +half3 MixVolumetricFog(half3 color, half alpha, half blendMode, bool useAlphaPremultiply, float4 positionCS) { #if defined(_FOG_ANALYTIC) || defined(_FOG_VOLUMETRIC) float2 uv = GetNormalizedScreenSpaceUV(positionCS); @@ -143,10 +127,7 @@ half3 MixVolumetricFog(half3 color, half alpha, half blendMode, float4 positionC // pre-exposed shaded color, so the in-scattering must be exposed here to match. fogRadiance *= GetPreExposureMultiplier(); - bool premultipliedBlend = blendMode == 1.0; -#if defined(_ALPHAPREMULTIPLY_ON) - premultipliedBlend = true; -#endif + bool premultipliedBlend = blendMode == 1.0 || useAlphaPremultiply; if (blendMode == 2.0) { diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Lit2DCommon.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Lit2DCommon.hlsl index 7caee681621..bd0aca5a337 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Lit2DCommon.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Lit2DCommon.hlsl @@ -25,7 +25,8 @@ Varyings CommonLitVertex(Attributes input) o.normalWS = TransformObjectToWorldDir(input.normal); #endif o.uv = input.uv; - o.lightingUV = half2(ComputeScreenPos(o.positionCS / o.positionCS.w).xy); + float4 ndc = o.positionCS * 0.5; + o.lightingUV = half2((float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w) / o.positionCS.w); return o; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader index d6c43ae653e..ac8f9a27933 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader @@ -378,7 +378,7 @@ Shader "Universal Render Pipeline/Baked Lit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -405,7 +405,7 @@ Shader "Universal Render Pipeline/Baked Lit" #define APPLICATION_SPACE_WARP_MOTION 1 #include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitDepthNormalsPass.hlsl index e82265ad7b0..679d88078f4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitDepthNormalsPass.hlsl @@ -1,12 +1,15 @@ #ifndef UNIVERSAL_BAKEDLIT_DEPTH_NORMALS_PASS_INCLUDED #define UNIVERSAL_BAKEDLIT_DEPTH_NORMALS_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 +#endif + struct Attributes { float4 positionOS : POSITION; @@ -23,7 +26,7 @@ struct Varyings float2 uv : TEXCOORD0; half3 normalWS : TEXCOORD1; - #if defined(_NORMALMAP) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 tangentWS : TEXCOORD3; #endif @@ -47,7 +50,7 @@ Varyings DepthNormalsVertex(Attributes input) // also required for per-vertex SH evaluation VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); output.normalWS = half3(normalInput.normalWS); - #if defined(_NORMALMAP) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) real sign = input.tangentOS.w * GetOddNegativeScale(); output.tangentWS = half4(normalInput.tangentWS.xyz, sign); #endif @@ -66,24 +69,30 @@ void DepthNormalsFragment( UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - half4 texColor = (half4) SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv); + half4 texColor = (half4) SampleBaseMap(input.uv); half alpha = texColor.a * _BaseColor.a; AlphaDiscard(alpha, _Cutoff); - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.positionCS); - #endif - - #if defined(_NORMALMAP) - half3 normalTS = SampleNormal(input.uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)).xyz; - half sgn = input.tangentWS.w; // should be either +1 or -1 - half3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); - half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent, input.normalWS)); + LODFadeCrossFade(input.positionCS); + + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + half3 normalTS = SampleNormal(input.uv); + half3 normalWS; + if (UseNormalMap()) + { + half sgn = input.tangentWS.w; // should be either +1 or -1 + half3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent, input.normalWS)); + } + else + { + normalWS = input.normalWS; + } #else half3 normalWS = input.normalWS; #endif - outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS)), 0.0); + outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), 0.0); #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl new file mode 100644 index 00000000000..7b591913359 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl @@ -0,0 +1,9 @@ +#ifndef UNIVERSAL_BAKED_LIT_FEATURES_INCLUDED +#define UNIVERSAL_BAKED_LIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the BakedLit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" + +#endif // UNIVERSAL_BAKED_LIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl.meta new file mode 100644 index 00000000000..73cc0d4481b --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 25a662d7c30914a9b896e1d4a1c649d5 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl index f898260dd13..39451c2279f 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl @@ -4,8 +4,11 @@ #include "BakedLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl" + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif struct Attributes @@ -23,10 +26,15 @@ struct Varyings { float4 positionCS : SV_POSITION; float3 uv0AndFogCoord : TEXCOORD0; // xy: uv0, z: fogCoord - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 1); +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; +#endif +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif half3 normalWS : TEXCOORD2; - #if defined(_NORMALMAP) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 tangentWS : TEXCOORD3; #endif @@ -56,14 +64,15 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.viewDirectionWS = half3(0, 0, 1); #endif - #if defined(_NORMALMAP) - float sgn = input.tangentWS.w; // should be either +1 or -1 - float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); - - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); - #else inputData.normalWS = input.normalWS; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + float sgn = input.tangentWS.w; // should be either +1 or -1 + float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } #endif inputData.shadowCoord = float4(0, 0, 0, 0); @@ -72,9 +81,10 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.shadowMask = half4(1, 1, 1, 1); #if defined(DEBUG_DISPLAY) - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.vertexSH; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -87,17 +97,29 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(input.positionWS), - inputData.normalWS, - input.viewDirWS, - input.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.viewDirWS = float3(0, 0, 1); + #if defined(DEBUG_DISPLAY) || defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) + giParams.positionWS = input.positionWS; + giParams.viewDirWS = input.viewDirWS; + #endif + + giParams.normalWS = inputData.normalWS; + giParams.positionSS = input.positionCS.xy; + giParams.isSurfaceTypeTransparent = IsSurfaceTypeTransparent(); + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } Varyings BakedLitForwardPassVertex(Attributes input) @@ -117,12 +139,20 @@ Varyings BakedLitForwardPassVertex(Attributes input) // also required for per-vertex SH evaluation VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); output.normalWS = normalInput.normalWS; - #if defined(_NORMALMAP) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) real sign = input.tangentOS.w * GetOddNegativeScale(); output.tangentWS = half4(normalInput.tangentWS.xyz, sign); #endif - OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV); - OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); +#if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = TransformLightmapUV(input.staticLightmapUV.xy, unity_LightmapST); +#endif +#if USE_VERTEX_SH_INTERPOLATOR + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif +#endif #if defined(DEBUG_DISPLAY) || (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) output.positionWS = vertexInput.positionWS; @@ -144,28 +174,24 @@ void BakedLitForwardPassFragment( UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uv0AndFogCoord.xy; - #if defined(_NORMALMAP) - half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)).xyz; - #else - half3 normalTS = half3(0, 0, 1); - #endif + half3 normalTS = SampleNormal(uv); InputData inputData; InitializeInputData(input, normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv0AndFogCoord.xy, _BaseMap)); - half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); + half4 texColor = SampleBaseMap(uv); half3 color = texColor.rgb * _BaseColor.rgb; half alpha = texColor.a * _BaseColor.a; alpha = AlphaDiscard(alpha, _Cutoff); - color = AlphaModulate(color, alpha); + if (UseAlphaModulate()) + color = ApplyAlphaModulate(color, alpha); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif #if defined(_DBUFFER) - ApplyDecalToBaseColorAndNormal(input.positionCS, color, inputData.normalWS); + if (!IsSurfaceTypeTransparent()) + ApplyDecalToBaseColorAndNormal(input.positionCS, color, inputData.normalWS); #endif InitializeBakedGIData(input, inputData); @@ -174,8 +200,9 @@ void BakedLitForwardPassFragment( finalColor.rgb = BlendDistanceFog(finalColor.rgb, input.positionCS); finalColor.rgb = ClampExposed(inputData.preExposureMultiplier * finalColor.rgb); -#if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, _Blend, input.positionCS); +#if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, _Blend, UseAlphaPremultiply(), input.positionCS); #endif finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent()); outColor = finalColor; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitGBufferPass.hlsl index 3e83d19c587..74e3a5b2bd8 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitGBufferPass.hlsl @@ -1,10 +1,14 @@ #ifndef UNIVERSAL_BAKEDLIT_GBUFFER_PASS_INCLUDED #define UNIVERSAL_BAKEDLIT_GBUFFER_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/BakedLitFeatures.hlsl" + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif struct Attributes @@ -22,10 +26,15 @@ struct Varyings { float4 positionCS : SV_POSITION; float3 uv0AndFogCoord : TEXCOORD0; // xy: uv0, z: fogCoord - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 1); +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; +#endif +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif half3 normalWS : TEXCOORD2; -#if defined(_NORMALMAP) +#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 tangentWS : TEXCOORD3; #endif @@ -50,14 +59,15 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.positionWS = float3(0, 0, 0); inputData.viewDirectionWS = half3(0, 0, 1); -#if defined(_NORMALMAP) - float sgn = input.tangentWS.w; // should be either +1 or -1 - float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); - - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); -#else inputData.normalWS = input.normalWS; +#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + float sgn = input.tangentWS.w; // should be either +1 or -1 + float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } #endif inputData.shadowCoord = float4(0, 0, 0, 0); @@ -66,9 +76,10 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.shadowMask = half4(1, 1, 1, 1); #if defined(DEBUG_DISPLAY) -#if defined(LIGHTMAP_ON) +#if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; -#else +#endif +#if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.vertexSH; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -79,17 +90,29 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(input.positionWS), - inputData.normalWS, - input.viewDirWS, - input.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.viewDirWS = float3(0, 0, 1); + #if defined(DEBUG_DISPLAY) || defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) + giParams.positionWS = input.positionWS; + giParams.viewDirWS = input.viewDirWS; + #endif + + giParams.normalWS = inputData.normalWS; + giParams.positionSS = input.positionCS.xy; + giParams.isSurfaceTypeTransparent = IsSurfaceTypeTransparent(); + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } Varyings BakedLitGBufferPassVertex(Attributes input) @@ -109,12 +132,20 @@ Varyings BakedLitGBufferPassVertex(Attributes input) // also required for per-vertex SH evaluation VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); output.normalWS = normalInput.normalWS; -#if defined(_NORMALMAP) +#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) real sign = input.tangentOS.w * GetOddNegativeScale(); output.tangentWS = half4(normalInput.tangentWS.xyz, sign); #endif - OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV); - OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); +#if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = TransformLightmapUV(input.staticLightmapUV.xy, unity_LightmapST); +#endif +#if USE_VERTEX_SH_INTERPOLATOR + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif +#endif #if defined(DEBUG_DISPLAY) || (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) output.positionWS = vertexInput.positionWS; @@ -128,43 +159,39 @@ GBufferFragOutput BakedLitGBufferPassFragment(Varyings input) { UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - -#if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE + LODFadeCrossFade(input.positionCS); -#endif - + half2 uv = input.uv0AndFogCoord.xy; -#if defined(_NORMALMAP) - half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)).xyz; -#else - half3 normalTS = half3(0, 0, 1); -#endif - half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); + half3 normalTS = SampleNormal(uv); + half4 texColor = SampleBaseMap(uv); half alpha = AlphaDiscard(texColor.a * _BaseColor.a, _Cutoff); - half3 color = AlphaModulate(texColor.rgb * _BaseColor.rgb, alpha); - + half3 color = texColor.rgb * _BaseColor.rgb; + if (UseAlphaModulate()) + color = ApplyAlphaModulate(color, alpha); + InputData inputData; InitializeInputData(input, normalTS, inputData); - + #if defined(_DBUFFER) ApplyDecalToBaseColorAndNormal(input.positionCS, color, inputData.normalWS); #endif - + InitializeBakedGIData(input, inputData); - + SurfaceData surfaceData = (SurfaceData) 0; surfaceData.albedo = color; surfaceData.alpha = alpha; - -#if defined(_SCREEN_SPACE_OCCLUSION) // GBuffer never has transparents - float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); - surfaceData.occlusion = aoFactor.directAmbientOcclusion; -#else surfaceData.occlusion = 1; -#endif - return PackGBuffersSurfaceData(surfaceData, inputData, float3(0, 0, 0)); + if (ScreenSpaceOcclusionAvailable()) // No transparent-surface check needed: the GBuffer pass only renders opaque geometry + { + float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, IsSurfaceTypeTransparent()); + surfaceData.occlusion = aoFactor.directAmbientOcclusion; + } + + return PackGBuffersSurfaceData(surfaceData, inputData, float3(0, 0, 0), ReceiveShadows()); } -#endif \ No newline at end of file +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl index 0005877e0ca..2095d2f14ce 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl @@ -1,10 +1,19 @@ #ifndef UNIVERSAL_BAKEDLIT_INPUT_INCLUDED #define UNIVERSAL_BAKEDLIT_INPUT_INCLUDED -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +TEXTURE2D(_BaseMap); +SAMPLER(sampler_BaseMap); +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); + CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _BaseMap_TexelSize; @@ -52,4 +61,9 @@ void SetupDOTSBakedLitMaterialPropertyCaches() #endif +half GetBumpScale() { return half(1.0); } + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } +half4 SampleBumpMap(float2 uv) { return SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv); } + #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader index 1874a5e1a35..77f29ba4f63 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader @@ -143,11 +143,12 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma multi_compile _ META_QUEST_LIGHTUNROLL #endif #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #if defined(UNITY_PLATFORM_META_QUEST) #pragma multi_compile _ META_QUEST_ORTHO_PROJ #pragma multi_compile _ META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP @@ -157,8 +158,7 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION - #pragma multi_compile_fragment _ _SHADOWS_SOFT - #pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH + #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _SCREEN_SPACE_IRRADIANCE #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 @@ -303,10 +303,10 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION - #pragma multi_compile_fragment _ _SHADOWS_SOFT + #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile_fragment _ _SCREEN_SPACE_IRRADIANCE #pragma multi_compile _ _EXPOSURE @@ -506,7 +506,7 @@ Shader "Universal Render Pipeline/Complex Lit" // ------------------------------------- // Material Keywords #pragma shader_feature_local_fragment _ALPHATEST_ON - #pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON + #pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON // ------------------------------------- // Includes @@ -527,7 +527,7 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -554,7 +554,7 @@ Shader "Universal Render Pipeline/Complex Lit" #define APPLICATION_SPACE_WARP_MOTION 1 #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl index 0394d94d773..e4f6098c4d4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/DepthNormalsPass.hlsl @@ -2,11 +2,10 @@ #define UNIVERSAL_DEPTH_NORMALS_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" struct Attributes { @@ -59,14 +58,16 @@ void DepthNormalsFragment( UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + half alpha = albedoAlpha * _BaseColor.a; + if (UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) + alpha = _BaseColor.a; + AlphaDiscard(alpha, _Cutoff); #endif - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif + LODFadeCrossFade(input.positionCS); - outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(input.normalWS)), 0.0); + outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(input.normalWS, UseNormalMap())), 0.0); #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl index 79ec6725110..3eeb3d7e5d8 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl @@ -2,11 +2,11 @@ #define UNIVERSAL_DEPTH_ONLY_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" -#if defined(_PARALLAXMAP) && defined(_ALPHATEST_ON) +#if FEATURES_PARALLAXMAP && defined(_ALPHATEST_ON) #define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR #endif @@ -64,17 +64,19 @@ half DepthOnlyFragment(Varyings input) : SV_TARGET UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - #if defined(_PARALLAXMAP) && defined(_ALPHATEST_ON) - ApplyPerPixelDisplacement(input.viewDirTS, input.uv); - #endif +#if FEATURES_PARALLAXMAP && defined(_ALPHATEST_ON) + ApplyPerPixelDisplacement(input.viewDirTS, input.uv); +#endif #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + half alpha = albedoAlpha * _BaseColor.a; + if (UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) + alpha = _BaseColor.a; + AlphaDiscard(alpha, _Cutoff); #endif - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif + LODFadeCrossFade(input.positionCS); return input.positionCS.z; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader index 4d0536e8f23..ab76c0139c2 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader @@ -143,7 +143,8 @@ Shader "Universal Render Pipeline/Lit" #pragma multi_compile _ META_QUEST_LIGHTUNROLL #endif #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS @@ -160,7 +161,7 @@ Shader "Universal Render Pipeline/Lit" #pragma multi_compile_fragment _FOG_ANALYTIC _FOG_VOLUMETRIC #pragma shader_feature_local_fragment _TRANSPARENT_RECEIVE_FOG #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) #pragma multi_compile _ META_QUEST_ORTHO_PROJ @@ -176,9 +177,9 @@ Shader "Universal Render Pipeline/Lit" #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile_fragment _ REFLECTION_PROBE_ROTATION - #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS #pragma multi_compile _ LOD_FADE_CROSSFADE #pragma multi_compile_fragment _ DEBUG_DISPLAY @@ -303,7 +304,7 @@ Shader "Universal Render Pipeline/Lit" #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" @@ -504,7 +505,7 @@ Shader "Universal Render Pipeline/Lit" // ------------------------------------- // Material Keywords #pragma shader_feature_local_fragment _ALPHATEST_ON - #pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON + #pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl" @@ -527,7 +528,7 @@ Shader "Universal Render Pipeline/Lit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -554,7 +555,7 @@ Shader "Universal Render Pipeline/Lit" #define APPLICATION_SPACE_WARP_MOTION 1 #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl index d2d159f63f7..88e0e65d839 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl @@ -1,25 +1,23 @@ #ifndef UNIVERSAL_FORWARD_LIT_DEPTH_NORMALS_PASS_INCLUDED #define UNIVERSAL_FORWARD_LIT_DEPTH_NORMALS_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" -#if defined(_DETAIL_MULX2) || defined(_DETAIL_SCALED) -#define _DETAIL -#endif - -#if defined(_PARALLAXMAP) -#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR +#if FEATURES_PARALLAXMAP +#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR 1 #endif -#if (defined(_NORMALMAP) || (defined(_PARALLAXMAP) && !defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR))) || defined(_DETAIL) -#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR +#if (FEATURES_NORMALMAP || FEATURES_DETAILMAP) +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif -#if defined(_ALPHATEST_ON) || defined(_PARALLAXMAP) || defined(_NORMALMAP) || defined(_DETAIL) || defined(_WRITE_SMOOTHNESS) +#if defined(_ALPHATEST_ON) || FEATURES_PARALLAXMAP || FEATURES_NORMALMAP || FEATURES_DETAILMAP || defined(_WRITE_SMOOTHNESS) #define REQUIRES_UV_INTERPOLATOR #endif @@ -35,17 +33,17 @@ struct Attributes struct Varyings { float4 positionCS : SV_POSITION; + #if defined(REQUIRES_UV_INTERPOLATOR) float2 uv : TEXCOORD1; #endif + half3 normalWS : TEXCOORD2; #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 tangentWS : TEXCOORD4; // xyz: tangent, w: sign #endif - half3 viewDirWS : TEXCOORD5; - #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) half3 viewDirTS : TEXCOORD8; #endif @@ -100,47 +98,59 @@ void DepthNormalsFragment( UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - #if defined(_PARALLAXMAP) - #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) - half3 viewDirTS = input.viewDirTS; - #else - half3 viewDirTS = GetViewDirectionTangentSpace(input.tangentWS, input.normalWS, input.viewDirWS); - #endif + #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) + half3 viewDirTS = input.viewDirTS; ApplyPerPixelDisplacement(viewDirTS, input.uv); #endif #if defined(_ALPHATEST_ON) || defined(_WRITE_SMOOTHNESS) - float alpha = SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a; + float alpha = SampleBaseMap(input.uv).a; #endif #if defined(_ALPHATEST_ON) - Alpha(alpha, _BaseColor, _Cutoff); + half discardAlpha = half(alpha) * GetBaseColor().a; + if (UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) + discardAlpha = GetBaseColor().a; + AlphaDiscard(discardAlpha, GetCutoff()); #endif - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif + LODFadeCrossFade(input.positionCS); - #if defined(_NORMALMAP) || defined(_DETAIL) - float sgn = input.tangentWS.w; // should be either +1 or -1 - float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); - float3 normalTS = SampleNormal(input.uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale); + half3 normalWS = input.normalWS; - #if defined(_DETAIL) - half detailMask = SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, input.uv).a; - float2 detailUv = input.uv * _DetailAlbedoMap_ST.xy + _DetailAlbedoMap_ST.zw; - normalTS = ApplyDetailNormal(detailUv, normalTS, detailMask); - #endif - - float3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz)); - #else - float3 normalWS = input.normalWS; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap() || UseDetailMap()) + { + float sgn = input.tangentWS.w; // should be either +1 or -1 + float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + half3 normalTS = SampleNormal(input.uv); + + if (UseDetailMap()) + { + half detailMask = SampleDetailMask(input.uv).a; + float2 detailUv = input.uv * GetDetailAlbedoMapST().xy + GetDetailAlbedoMapST().zw; + normalTS = ApplyDetailNormal(detailUv, normalTS, detailMask); + } + + normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz)); + } #endif - outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS)), 0.0); + outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), 0.0); #if defined(_WRITE_SMOOTHNESS) && !defined(_SCREENSPACEREFLECTIONS_OFF) - outNormalWS.a = SampleMetallicSpecGloss(input.uv, alpha).a; + half4 specGloss; + if (UseMetallicSpecGlossMap()) + { + specGloss = IsSpecularSetup() ? SampleSpecGlossMap(input.uv) : SampleMetallicGlossMap(input.uv); + specGloss.a = UseSmoothnessTextureAlbedoChannelA() ? alpha * _Smoothness : specGloss.a * _Smoothness; + } + else + { + specGloss.rgb = IsSpecularSetup() ? _SpecColor.rgb : _Metallic.rrr; + specGloss.a = UseSmoothnessTextureAlbedoChannelA() ? alpha * _Smoothness : _Smoothness; + } + outNormalWS.a = specGloss.a; #endif #ifdef _WRITE_RENDERING_LAYERS diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl new file mode 100644 index 00000000000..af4cd15f49c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl @@ -0,0 +1,16 @@ +#ifndef UNIVERSAL_LIT_FEATURES_INCLUDED +#define UNIVERSAL_LIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the Lit and ComplexLit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" + +#endif // UNIVERSAL_LIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl.meta new file mode 100644 index 00000000000..2b4c2d7e766 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 81ca33344f5d247ae818e0e26fa4086f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl index aab1ab7ef29..1abe124534b 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl @@ -2,19 +2,24 @@ #define UNIVERSAL_FORWARD_LIT_PASS_INCLUDED #include "LitInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 #endif -#if defined(_PARALLAXMAP) -#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR +#if FEATURES_PARALLAXMAP +#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR 1 #endif -#if (defined(_NORMALMAP) || (defined(_PARALLAXMAP) && !defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR))) || defined(_DETAIL) -#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR +#if (FEATURES_NORMALMAP || FEATURES_DETAILMAP) +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif // keep this file in sync with LitGBufferPass.hlsl @@ -34,12 +39,13 @@ struct Varyings { float2 uv : TEXCOORD0; -#if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR) +#if REQUIRES_WORLD_SPACE_POS_INTERPOLATOR float3 positionWS : TEXCOORD1; #endif float3 normalWS : TEXCOORD2; -#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + +#if REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR half4 tangentWS : TEXCOORD3; // xyz: tangent, w: sign #endif @@ -49,21 +55,28 @@ struct Varyings half fogFactor : TEXCOORD5; #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD6; #endif -#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) +#if REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR half3 viewDirTS : TEXCOORD7; #endif - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 8); -#ifdef DYNAMICLIGHTMAP_ON - float2 dynamicLightmapUV : TEXCOORD9; // Dynamic lightmap UVs +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; +#endif + +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif + +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + float2 dynamicLightmapUV : DYNLIGHTMAPUV; #endif #ifdef USE_APV_PROBE_OCCLUSION - float4 probeOcclusion : TEXCOORD10; + float4 probeOcclusion : PROBEOCCLUSION; #endif float4 positionCS : SV_POSITION; @@ -85,28 +98,28 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData #endif half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); -#if defined(_NORMALMAP) || defined(_DETAIL) - float sgn = input.tangentWS.w; // should be either +1 or -1 - float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); - half3x3 tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz); - - #if defined(_NORMALMAP) - inputData.tangentToWorld = tangentToWorld; - #endif - inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld); + inputData.normalWS = input.normalWS; +#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap() || UseDetailMap()) + { + float sgn = input.tangentWS.w; // should be either +1 or -1 + float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + half3x3 tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz); + if (UseNormalMap()) + inputData.tangentToWorld = tangentToWorld; + inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld); + } #else inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); inputData.viewDirectionWS = viewDirWS; -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif #ifdef _ADDITIONAL_LIGHTS_VERTEX inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; @@ -115,12 +128,13 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.vertexSH; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -133,23 +147,28 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { - #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); - #elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); - #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - input.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); - #else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV; #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = input.positionCS.xy; + giParams.isSurfaceTypeTransparent = IsSurfaceTypeTransparent(); + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } /////////////////////////////////////////////////////////////////////////////// @@ -180,25 +199,46 @@ Varyings LitPassVertex(Attributes input) // already normalized from normal transform to WS. output.normalWS = normalInput.normalWS; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) || defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) real sign = input.tangentOS.w * GetOddNegativeScale(); half4 tangentWS = half4(normalInput.tangentWS.xyz, sign); #endif + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.tangentWS = tangentWS; #endif +half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); + #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); half3 viewDirTS = GetViewDirectionTangentSpace(tangentWS, output.normalWS, viewDirWS); output.viewDirTS = viewDirTS; #endif - OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV); -#ifdef DYNAMICLIGHTMAP_ON - output.dynamicLightmapUV = input.dynamicLightmapUV.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; +#if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = LightmapAvailable() ? TransformLightmapUV(input.staticLightmapUV.xy, unity_LightmapST) : float2(0, 0); +#endif + +#if USE_VERTEX_SH_INTERPOLATOR + if (!LightmapAvailable()) + { + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, viewDirWS, output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, viewDirWS); + #endif + } + else + { + output.vertexSH = half3(0, 0, 0); + } #endif - OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); + +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + output.dynamicLightmapUV = DynamicLightmapAvailable() ? TransformLightmapUV(input.dynamicLightmapUV.xy, unity_DynamicLightmapST) : float2(0, 0); +#endif + #ifdef _ADDITIONAL_LIGHTS_VERTEX output.fogFactorAndVertexLight = URP_LIGHT_ACCUM4(fogFactor, vertexLight); #else @@ -209,8 +249,8 @@ Varyings LitPassVertex(Attributes input) output.positionWS = vertexInput.positionWS; #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif output.positionCS = vertexInput.positionCS; @@ -230,37 +270,34 @@ void LitPassFragment( UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); -#if defined(_PARALLAXMAP) #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) half3 viewDirTS = input.viewDirTS; -#else - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); - half3 viewDirTS = GetViewDirectionTangentSpace(input.tangentWS, input.normalWS, viewDirWS); -#endif ApplyPerPixelDisplacement(viewDirTS, input.uv); #endif SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv, _BaseMap)); #if defined(_DBUFFER) - ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData); + if (!IsSurfaceTypeTransparent()) + ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData, IsSpecularSetup()); #endif InitializeBakedGIData(input, inputData); - URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData); + URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData, + IsSpecularSetup(), UseSpecularHighlights(), UseAlphaPremultiply(), + UseClearCoat() || UseClearCoatMap(), ReceiveShadows(), IsSurfaceTypeTransparent(), UseEnvironmentReflections()); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.positionCS)); -#if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, input.positionCS); +#if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, UseAlphaPremultiply(), input.positionCS); #endif color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl index e501550876e..6038e535cca 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl @@ -1,22 +1,27 @@ #ifndef UNIVERSAL_LIT_GBUFFER_PASS_INCLUDED #define UNIVERSAL_LIT_GBUFFER_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 #endif -// TODO: Currently we support viewDirTS caclulated in vertex shader and in fragments shader. -// As both solutions have their advantages and disadvantages (etc. shader target 2.0 has only 8 interpolators). -// We need to find out if we can stick to one solution, which we needs testing. -// So keeping this until I get manaul QA pass. -#if defined(_PARALLAXMAP) && (SHADER_TARGET >= 30) -#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR +#if FEATURES_PARALLAXMAP +#define REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR 1 #endif -#if (defined(_NORMALMAP) || (defined(_PARALLAXMAP) && !defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR))) || defined(_DETAIL) -#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR +#if (FEATURES_NORMALMAP || FEATURES_DETAILMAP) +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif // keep this file in sync with LitForwardPass.hlsl @@ -48,7 +53,7 @@ struct Varyings URP_LIGHT_ACCUM3 vertexLighting : TEXCOORD4; // xyz: vertex lighting #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD5; #endif @@ -56,13 +61,18 @@ struct Varyings half3 viewDirTS : TEXCOORD6; #endif - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 7); -#ifdef DYNAMICLIGHTMAP_ON - float2 dynamicLightmapUV : TEXCOORD8; // Dynamic lightmap UVs +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; +#endif +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + float2 dynamicLightmapUV : DYNLIGHTMAPUV; #endif #ifdef USE_APV_PROBE_OCCLUSION - float4 probeOcclusion : TEXCOORD9; + float4 probeOcclusion : PROBEOCCLUSION; #endif float4 positionCS : SV_POSITION; @@ -79,24 +89,24 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData #endif inputData.positionCS = input.positionCS; - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); - #if defined(_NORMALMAP) || defined(_DETAIL) - float sgn = input.tangentWS.w; // should be either +1 or -1 - float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz)); - #else - inputData.normalWS = input.normalWS; + inputData.normalWS = input.normalWS; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap() || UseDetailMap()) + { + float sgn = input.tangentWS.w; // should be either +1 or -1 + float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz)); + } #endif + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); inputData.viewDirectionWS = viewDirWS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.fogCoord = 0.0; // we don't apply fog in the guffer pass @@ -114,23 +124,28 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + giParams.isSurfaceTypeTransparent = IsSurfaceTypeTransparent(); + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } /////////////////////////////////////////////////////////////////////////////// @@ -173,11 +188,19 @@ Varyings LitGBufferPassVertex(Attributes input) output.viewDirTS = viewDirTS; #endif - OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV); -#ifdef DYNAMICLIGHTMAP_ON - output.dynamicLightmapUV = input.dynamicLightmapUV.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; +#if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = TransformLightmapUV(input.staticLightmapUV.xy, unity_LightmapST); +#endif +#if USE_VERTEX_SH_INTERPOLATOR + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + output.dynamicLightmapUV = TransformLightmapUV(input.dynamicLightmapUV.xy, unity_DynamicLightmapST); #endif - OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); #ifdef _ADDITIONAL_LIGHTS_VERTEX URP_LIGHT_ACCUM3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS); @@ -188,8 +211,8 @@ Varyings LitGBufferPassVertex(Attributes input) output.positionWS = vertexInput.positionWS; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif output.positionCS = vertexInput.positionCS; @@ -203,29 +226,22 @@ GBufferFragOutput LitGBufferPassFragment(Varyings input) UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); -#if defined(_PARALLAXMAP) - #if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) - half3 viewDirTS = input.viewDirTS; - #else - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS); - half3 viewDirTS = GetViewDirectionTangentSpace(input.tangentWS, input.normalWS, viewDirWS); - #endif +#if defined(REQUIRES_TANGENT_SPACE_VIEW_DIR_INTERPOLATOR) + half3 viewDirTS = input.viewDirTS; ApplyPerPixelDisplacement(viewDirTS, input.uv); #endif SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv, _BaseMap)); #if defined(_DBUFFER) - ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData); + ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData, IsSpecularSetup()); #endif InitializeBakedGIData(input, inputData); @@ -234,18 +250,18 @@ GBufferFragOutput LitGBufferPassFragment(Varyings input) // in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR // in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer - BRDFData brdfData; - InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); + BRDFData brdfData = InitializeBRDFData(surfaceData, IsSpecularSetup(), UseAlphaPremultiply()); - Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask, ReceiveShadows(), IsSurfaceTypeTransparent()); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); URP_LIGHT_ACCUM3 color = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, surfaceData.occlusion, inputData.positionWS, - inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV, + UseClearCoat() || UseClearCoatMap(), UseEnvironmentReflections()); half3 gbufferLighting = ClampExposed(inputData.preExposureMultiplier * (surfaceData.emission + color)); - return PackGBuffersBRDFData(brdfData, inputData, surfaceData.smoothness, gbufferLighting, surfaceData.occlusion); + return PackGBuffersBRDFData(brdfData, inputData, surfaceData.smoothness, gbufferLighting, surfaceData.occlusion, ReceiveShadows(), IsSpecularSetup(), UseSpecularHighlights()); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl new file mode 100644 index 00000000000..77df6a92245 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl @@ -0,0 +1,14 @@ +#ifndef UNIVERSAL_LIT_INPUT_DEPRECATED_INCLUDED +#define UNIVERSAL_LIT_INPUT_DEPRECATED_INCLUDED + +// Deprecated helpers, kept for external back-compat. + +// Trunk's LitInput.hlsl transitively provided the SurfaceInput helpers (Alpha, +// SampleAlbedoAlpha, SampleNormal, SampleEmission); custom shaders built on copies of +// LitInput rely on them. +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl" + +// Deprecated. Sample the metallic/specular gloss map through SampleMetallicSpecGloss instead. +#define SAMPLE_METALLICSPECULAR(uv) (IsSpecularSetup() ? SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv) : SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv)) + +#endif // UNIVERSAL_LIT_INPUT_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl.meta new file mode 100644 index 00000000000..b1b0c99ee88 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c25355049b83f4351be6cfc4052d8dd6 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl index 8717626ff1e..b980c10e1bb 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl @@ -3,15 +3,21 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" - -#if defined(_DETAIL_MULX2) || defined(_DETAIL_SCALED) -#define _DETAIL -#endif +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.deprecated.hlsl" // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -120,6 +126,9 @@ void SetupDOTSLitMaterialPropertyCaches() #endif +TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); +TEXTURE2D(_BumpMap); SAMPLER(sampler_BumpMap); +TEXTURE2D(_EmissionMap); SAMPLER(sampler_EmissionMap); TEXTURE2D(_ParallaxMap); SAMPLER(sampler_ParallaxMap); TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap); TEXTURE2D(_DetailMask); SAMPLER(sampler_DetailMask); @@ -128,165 +137,77 @@ TEXTURE2D(_DetailNormalMap); SAMPLER(sampler_DetailNormalMap); TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap); TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); TEXTURE2D(_ClearCoatMap); SAMPLER(sampler_ClearCoatMap); - -#ifdef _SPECULAR_SETUP - #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv) -#else - #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv) -#endif - -half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) -{ - half4 specGloss; - -#ifdef _METALLICSPECGLOSSMAP - specGloss = half4(SAMPLE_METALLICSPECULAR(uv)); - #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A - specGloss.a = albedoAlpha * _Smoothness; - #else - specGloss.a *= _Smoothness; - #endif -#else // _METALLICSPECGLOSSMAP - #if _SPECULAR_SETUP - specGloss.rgb = _SpecColor.rgb; - #else - specGloss.rgb = _Metallic.rrr; - #endif - - #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A - specGloss.a = albedoAlpha * _Smoothness; - #else - specGloss.a = _Smoothness; - #endif -#endif - - return specGloss; -} - -half SampleOcclusion(float2 uv) -{ - #ifdef _OCCLUSIONMAP - half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; - return LerpWhiteTo(occ, _OcclusionStrength); - #else - return half(1.0); - #endif -} - - -// Returns clear coat parameters -// .x/.r == mask -// .y/.g == smoothness -half2 SampleClearCoat(float2 uv) -{ -#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP) - half2 clearCoatMaskSmoothness = half2(_ClearCoatMask, _ClearCoatSmoothness); - -#if defined(_CLEARCOATMAP) - clearCoatMaskSmoothness *= SAMPLE_TEXTURE2D(_ClearCoatMap, sampler_ClearCoatMap, uv).rg; -#endif - - return clearCoatMaskSmoothness; -#else - return half2(0.0, 1.0); -#endif // _CLEARCOAT -} - -void ApplyPerPixelDisplacement(half3 viewDirTS, inout float2 uv) -{ -#if defined(_PARALLAXMAP) - uv += ParallaxMapping(TEXTURE2D_ARGS(_ParallaxMap, sampler_ParallaxMap), viewDirTS, _Parallax, uv); -#endif -} - -// Used for scaling detail albedo. Main features: -// - Depending if detailAlbedo brightens or darkens, scale magnifies effect. -// - No effect is applied if detailAlbedo is 0.5. -half3 ScaleDetailAlbedo(half3 detailAlbedo, half scale) -{ - // detailAlbedo = detailAlbedo * 2.0h - 1.0h; - // detailAlbedo *= _DetailAlbedoMapScale; - // detailAlbedo = detailAlbedo * 0.5h + 0.5h; - // return detailAlbedo * 2.0f; - - // A bit more optimized - return half(2.0) * detailAlbedo * scale - scale + half(1.0); -} - -half3 ApplyDetailAlbedo(float2 detailUv, half3 albedo, half detailMask) -{ -#if defined(_DETAIL) - half3 detailAlbedo = SAMPLE_TEXTURE2D(_DetailAlbedoMap, sampler_DetailAlbedoMap, detailUv).rgb; - - // In order to have same performance as builtin, we do scaling only if scale is not 1.0 (Scaled version has 6 additional instructions) -#if defined(_DETAIL_SCALED) - detailAlbedo = ScaleDetailAlbedo(detailAlbedo, _DetailAlbedoMapScale); -#else - detailAlbedo = half(2.0) * detailAlbedo; -#endif - - return albedo * LerpWhiteTo(detailAlbedo, detailMask); -#else - return albedo; -#endif -} - -half3 ApplyDetailNormal(float2 detailUv, half3 normalTS, half detailMask) -{ -#if defined(_DETAIL) -#if BUMP_SCALE_NOT_SUPPORTED - half3 detailNormalTS = UnpackNormal(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv)); -#else - half3 detailNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv), _DetailNormalMapScale); -#endif - - // With UNITY_NO_DXT5nm unpacked vector is not normalized for BlendNormalRNM - // For visual consistancy we going to do in all cases - detailNormalTS = normalize(detailNormalTS); - - return lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask); // todo: detailMask should lerp the angle of the quaternion rotation, not the normals -#else - return normalTS; -#endif -} +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); + +// Simple getters for the material properties above. All raw material input (constant buffer +// values, texture samples) is accessed through these; the feature helpers build on them. +half4 GetBaseColor() { return _BaseColor; } +half4 GetSpecColor() { return _SpecColor; } +half4 GetEmissionColor() { return _EmissionColor; } +half GetCutoff() { return _Cutoff; } +half GetSmoothness() { return _Smoothness; } +half GetMetallic() { return _Metallic; } +half GetBumpScale() { return _BumpScale; } +half GetParallax() { return _Parallax; } +half GetOcclusionStrength() { return _OcclusionStrength; } +half GetClearCoatMask() { return _ClearCoatMask; } +half GetClearCoatSmoothness() { return _ClearCoatSmoothness; } +half GetDetailAlbedoMapScale() { return _DetailAlbedoMapScale; } +half GetDetailNormalMapScale() { return _DetailNormalMapScale; } +float4 GetBaseMapST() { return _BaseMap_ST; } +float4 GetBaseMapTexelSize() { return _BaseMap_TexelSize; } +float4 GetDetailAlbedoMapST() { return _DetailAlbedoMap_ST; } + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } +half4 SampleBumpMap(float2 uv) { return SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv); } +half4 SampleEmissionMap(float2 uv) { return SAMPLE_TEXTURE2D(_EmissionMap, sampler_EmissionMap, uv); } +half4 SampleParallaxMap(float2 uv) { return SAMPLE_TEXTURE2D(_ParallaxMap, sampler_ParallaxMap, uv); } +half4 SampleOcclusionMap(float2 uv) { return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv); } +half4 SampleDetailMask(float2 uv) { return SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, uv); } +half4 SampleDetailAlbedoMap(float2 uv) { return SAMPLE_TEXTURE2D(_DetailAlbedoMap, sampler_DetailAlbedoMap, uv); } +half4 SampleDetailNormalMap(float2 uv) { return SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, uv); } +half4 SampleMetallicGlossMap(float2 uv) { return SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv); } +half4 SampleSpecGlossMap(float2 uv) { return SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv); } +half4 SampleClearCoatMap(float2 uv) { return SAMPLE_TEXTURE2D(_ClearCoatMap, sampler_ClearCoatMap, uv); } inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData) { - half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); - outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff); + half4 albedoAlpha = SampleBaseMap(uv); + outSurfaceData.alpha = AlphaDiscard(UseSmoothnessTextureAlbedoChannelA() ? GetBaseColor().a : albedoAlpha.a * GetBaseColor().a, GetCutoff()); half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a); - outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb; - outSurfaceData.albedo = AlphaModulate(outSurfaceData.albedo, outSurfaceData.alpha); -#if _SPECULAR_SETUP - outSurfaceData.metallic = half(1.0); - outSurfaceData.specular = specGloss.rgb; -#else - outSurfaceData.metallic = specGloss.r; - outSurfaceData.specular = half3(0.0, 0.0, 0.0); -#endif + outSurfaceData.albedo = albedoAlpha.rgb * GetBaseColor().rgb; + if (UseAlphaModulate()) + outSurfaceData.albedo = ApplyAlphaModulate(outSurfaceData.albedo, outSurfaceData.alpha); + + if (IsSpecularSetup()) + { + outSurfaceData.metallic = half(1.0); + outSurfaceData.specular = specGloss.rgb; + } + else + { + outSurfaceData.metallic = specGloss.r; + outSurfaceData.specular = half3(0.0, 0.0, 0.0); + } outSurfaceData.smoothness = specGloss.a; - outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale); + outSurfaceData.normalTS = SampleNormal(uv); outSurfaceData.occlusion = SampleOcclusion(uv); - outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); - -#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP) - half2 clearCoat = SampleClearCoat(uv); - outSurfaceData.clearCoatMask = clearCoat.r; - outSurfaceData.clearCoatSmoothness = clearCoat.g; -#else - outSurfaceData.clearCoatMask = half(0.0); - outSurfaceData.clearCoatSmoothness = half(0.0); -#endif - -#if defined(_DETAIL) - half detailMask = SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, uv).a; - float2 detailUv = uv * _DetailAlbedoMap_ST.xy + _DetailAlbedoMap_ST.zw; - outSurfaceData.albedo = ApplyDetailAlbedo(detailUv, outSurfaceData.albedo, detailMask); - outSurfaceData.normalTS = ApplyDetailNormal(detailUv, outSurfaceData.normalTS, detailMask); -#endif + outSurfaceData.emission = SampleEmission(uv); + + half2 clearCoatMaskSmoothness = SampleClearCoat(uv); + outSurfaceData.clearCoatMask = clearCoatMaskSmoothness.r; + outSurfaceData.clearCoatSmoothness = clearCoatMaskSmoothness.g; + + if (UseDetailMap()) + { + half detailMask = SampleDetailMask(uv).a; + float2 detailUv = uv * GetDetailAlbedoMapST().xy + GetDetailAlbedoMapST().zw; + outSurfaceData.albedo = ApplyDetailAlbedo(detailUv, outSurfaceData.albedo, detailMask); + outSurfaceData.normalTS = ApplyDetailNormal(detailUv, outSurfaceData.normalTS, detailMask); + } } #endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl index 589d2c36b88..9af16c0c7c9 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_LIT_META_PASS_INCLUDED #define UNIVERSAL_LIT_META_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/LitFeatures.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UniversalMetaPass.hlsl" half4 UniversalFragmentMetaLit(Varyings input) : SV_Target @@ -8,8 +9,7 @@ half4 UniversalFragmentMetaLit(Varyings input) : SV_Target SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); - BRDFData brdfData; - InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); + BRDFData brdfData = InitializeBRDFData(surfaceData, IsSpecularSetup(), UseAlphaPremultiply()); MetaInput metaInput; metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5; 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 9c4dc241fb9..abf756ecc48 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader @@ -39,7 +39,8 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7" #pragma fragment SpeedTree7Frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH @@ -49,7 +50,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7" #pragma multi_compile_fragment _ _LIGHT_COOKIES #pragma multi_compile_fragment _ _VOLUMETRIC_FOG #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" 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 0c51093fbe3..a6caed611fa 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader @@ -34,11 +34,12 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7 Billboard" #pragma fragment SpeedTree7Frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Fog.hlsl" #pragma multi_compile __ BILLBOARD_FACE_CAMERA_POS diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7BillboardPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7BillboardPasses.hlsl index 5a00c3879d0..d5fe8a41771 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7BillboardPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7BillboardPasses.hlsl @@ -1,7 +1,8 @@ #ifndef UNIVERSAL_SPEEDTREE7BILLBOARD_PASSES_INCLUDED #define UNIVERSAL_SPEEDTREE7BILLBOARD_PASSES_INCLUDED -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" + #include "SpeedTree7CommonPasses.hlsl" void InitializeData(inout SpeedTreeVertexInput input, out half2 outUV, out half outHueVariation) @@ -83,11 +84,14 @@ SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input) output.fogFactorAndVertexLight = URP_LIGHT_ACCUM4(fogFactor, vertexLight); half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); - #ifdef EFFECT_BUMP - real sign = input.tangent.w * GetOddNegativeScale(); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.normalWS.xyz = TransformObjectToWorldNormal(input.normal); - output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); - output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + if (UseNormalMap()) + { + real sign = input.tangent.w * GetOddNegativeScale(); + output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); + output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + } // View dir packed in w. output.normalWS.w = viewDirWS.x; @@ -102,8 +106,8 @@ SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input) output.clipPos = vertexInput.positionCS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -150,11 +154,14 @@ SpeedTreeVertexDepthNormalOutput SpeedTree7VertDepthNormalBillboard(SpeedTreeVer half3 normalWS = TransformObjectToWorldNormal(input.normal); half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); - #ifdef EFFECT_BUMP - real sign = input.tangent.w * GetOddNegativeScale(); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.normalWS.xyz = normalWS; - output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); - output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + if (UseNormalMap()) + { + real sign = input.tangent.w * GetOddNegativeScale(); + output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); + output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + } // View dir packed in w. output.normalWS.w = viewDirWS.x; @@ -175,31 +182,25 @@ half4 SpeedTree7FragDepthNormalBillboard(SpeedTreeVertexDepthNormalOutput input) UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uvHueVariation.xy; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)); + half4 diffuse = SampleBaseMap(uv); diffuse.a *= _Color.a; #ifdef SPEEDTREE_ALPHATEST AlphaDiscard(diffuse.a, _Cutoff); #endif - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.clipPos); - #endif + LODFadeCrossFade(input.clipPos); - #if defined(EFFECT_BUMP) - half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)).xyz; - #else - half3 normalWS = input.normalWS.xyz; + half3 normalWS = input.normalWS.xyz; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + half3 normalTS = SampleNormal(uv); + normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)).xyz; + } #endif - #if defined(_GBUFFER_NORMALS_OCT) - float2 octNormalWS = PackNormalOctQuadEncode(normalize(float3(normalWS))); // values between [-1, +1], must use fp32 on some platforms. - float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1] - return half4(PackFloat2To888(remappedOctNormalWS), 0.0); // values between [ 0, 1] - #else - return half4(NormalizeNormalPerPixel(normalWS), 0.0); - #endif + return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), 0.0); } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonInput.hlsl index aff1a90c736..b0453c3b2a5 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonInput.hlsl @@ -6,12 +6,14 @@ #endif #ifdef EFFECT_BUMP - #define _NORMALMAP + #define _NORMALMAP 1 #endif #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #ifdef ENABLE_WIND #define WIND_QUALITY_NONE 0 @@ -30,6 +32,13 @@ TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize; +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); + +half GetBumpScale() { return half(1.0); } + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv); } +half4 SampleBumpMap(float2 uv) { return SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv); } #ifdef EFFECT_HUE_VARIATION half4 _HueVariation; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonPasses.hlsl index 2efeea96342..b28ae458e95 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7CommonPasses.hlsl @@ -4,10 +4,18 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "SpeedTreeUtility.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif struct SpeedTreeVertexInput @@ -38,7 +46,7 @@ struct SpeedTreeVertexOutput URP_LIGHT_ACCUM4 fogFactorAndVertexLight : TEXCOORD2; // x: fogFactor, yzw: vertex light - #ifdef EFFECT_BUMP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z @@ -47,7 +55,7 @@ struct SpeedTreeVertexOutput half3 viewDirWS : TEXCOORD4; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD6; #endif @@ -76,7 +84,7 @@ struct SpeedTreeVertexDepthNormalOutput half3 detail : TEXCOORD1; #endif - #ifdef EFFECT_BUMP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z @@ -97,28 +105,29 @@ void InitializeInputData(SpeedTreeVertexOutput input, half3 normalTS, out InputD inputData.positionWS = input.positionWS.xyz; inputData.positionCS = input.clipPos; - #ifdef EFFECT_BUMP - inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = input.normalWS; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) inputData.viewDirectionWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); + if (UseNormalMap()) + { + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } #else - inputData.normalWS = NormalizeNormalPerPixel(input.normalWS); inputData.viewDirectionWS = input.viewDirWS; #endif - + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); inputData.viewDirectionWS = SafeNormalize(inputData.viewDirectionWS); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; // Billboards cannot use lightmaps. -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) inputData.bakedGI = SAMPLE_GI(input.vertexSH, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -133,13 +142,9 @@ void InitializeInputData(SpeedTreeVertexOutput input, half3 normalTS, out InputD inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos); inputData.shadowMask = half4(1, 1, 1, 1); // No GI currently. - #if defined(DEBUG_DISPLAY) && !defined(LIGHTMAP_ON) + #if defined(DEBUG_DISPLAY) inputData.vertexSH = input.vertexSH; #endif - - #if defined(_NORMALMAP) - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); - #endif } #ifdef GBUFFER @@ -152,16 +157,14 @@ half4 SpeedTree7Frag(SpeedTreeVertexOutput input) : SV_Target UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uvHueVariation.xy; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)); + half4 diffuse = SampleBaseMap(uv); diffuse.a *= _Color.a; #ifdef SPEEDTREE_ALPHATEST diffuse.a = AlphaDiscard(diffuse.a, _Cutoff); #endif - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.clipPos); - #endif + LODFadeCrossFade(input.clipPos); half3 diffuseColor = diffuse.rgb; @@ -181,14 +184,16 @@ half4 SpeedTree7Frag(SpeedTreeVertexOutput input) : SV_Target diffuseColor.rgb = saturate(shiftedColor); #endif - #ifdef EFFECT_BUMP - half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - #ifdef GEOM_TYPE_BRANCH_DETAIL - half3 detailNormal = SampleNormal(input.detail.xy, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - normalTs = lerp(normalTs, detailNormal, input.detail.z < 2.0f ? saturate(input.detail.z) : detailColor.a); - #endif - #else - half3 normalTs = half3(0, 0, 1); + half3 normalTs = half3(0, 0, 1); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + normalTs = SampleNormal(uv); + #ifdef GEOM_TYPE_BRANCH_DETAIL + half3 detailNormal = SampleNormal(input.detail.xy); + normalTs = lerp(normalTs, detailNormal, input.detail.z < 2.0f ? saturate(input.detail.z) : detailColor.a); + #endif + } #endif InputData inputData; @@ -217,9 +222,11 @@ half4 SpeedTree7Frag(SpeedTreeVertexOutput input) : SV_Target #ifdef GBUFFER URP_LIGHT_ACCUM4 color = URP_LIGHT_ACCUM4(inputData.bakedGI * diffuseColor.rgb, diffuse.a); surfaceData.occlusion = 1.0; - return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb)); + return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb), ReceiveShadows()); #else - URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, surfaceData); + URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, surfaceData, + UseSpecGlossMap() || UseSpecularColor(), UseAlphaPremultiply(), + ReceiveShadows(), IsSurfaceTypeTransparent()); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.clipPos)); color.a = OutputAlpha(color.a, _Surface); return color; @@ -232,16 +239,14 @@ half4 SpeedTree7FragDepth(SpeedTreeVertexDepthOutput input) : SV_Target UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uvHueVariation.xy; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)); + half4 diffuse = SampleBaseMap(uv); diffuse.a *= _Color.a; #ifdef SPEEDTREE_ALPHATEST AlphaDiscard(diffuse.a, _Cutoff); #endif - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.clipPos); - #endif + LODFadeCrossFade(input.clipPos); #if defined(SCENESELECTIONPASS) // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly @@ -257,37 +262,30 @@ half4 SpeedTree7FragDepthNormal(SpeedTreeVertexDepthNormalOutput input) : SV_Tar UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uvHueVariation.xy; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)); + half4 diffuse = SampleBaseMap(uv); diffuse.a *= _Color.a; #ifdef SPEEDTREE_ALPHATEST AlphaDiscard(diffuse.a, _Cutoff); #endif - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.clipPos); + LODFadeCrossFade(input.clipPos); + + half3 normalWS = input.normalWS.xyz; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + half3 normalTS = SampleNormal(uv); + #ifdef GEOM_TYPE_BRANCH_DETAIL + half4 detailColor = tex2D(_DetailTex, input.detail.xy); + half3 detailNormal = SampleNormal(input.detail.xy); + normalTS = lerp(normalTS, detailNormal, input.detail.z < 2.0f ? saturate(input.detail.z) : detailColor.a); + #endif + normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)).xyz; + } #endif - #if defined(EFFECT_BUMP) - half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - #ifdef GEOM_TYPE_BRANCH_DETAIL - half4 detailColor = tex2D(_DetailTex, input.detail.xy); - half3 detailNormal = SampleNormal(input.detail.xy, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - normalTS = lerp(normalTS, detailNormal, input.detail.z < 2.0f ? saturate(input.detail.z) : detailColor.a); - #endif - - half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)).xyz; - #else - half3 normalWS = input.normalWS.xyz; - #endif - - #if defined(_GBUFFER_NORMALS_OCT) - float2 octNormalWS = PackNormalOctQuadEncode(normalize(float3(normalWS))); // values between [-1, +1], must use fp32 on some platforms. - float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1] - return half4(PackFloat2To888(remappedOctNormalWS), 0.0); // values between [ 0, 1] - #else - return half4(NormalizeNormalPerPixel(normalWS), 0.0); - #endif + return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), 0.0); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Passes.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Passes.hlsl index 9de8e5d4c50..5141fa2d30b 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Passes.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Passes.hlsl @@ -4,7 +4,6 @@ // Legacy keyword, behavior is determined dynamically #define LOD_FADE_PERCENTAGE 1 -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "SpeedTree7CommonPasses.hlsl" void InitializeData(inout SpeedTreeVertexInput input, float lodValue) @@ -140,11 +139,14 @@ SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); - #ifdef EFFECT_BUMP - real sign = input.tangent.w * GetOddNegativeScale(); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.normalWS.xyz = normalWS; - output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); - output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + if (UseNormalMap()) + { + real sign = input.tangent.w * GetOddNegativeScale(); + output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); + output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + } // View dir packed in w. output.normalWS.w = viewDirWS.x; @@ -155,8 +157,8 @@ SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input) output.viewDirWS = viewDirWS; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif output.positionWS = vertexInput.positionWS; @@ -217,11 +219,14 @@ SpeedTreeVertexDepthNormalOutput SpeedTree7VertDepthNormal(SpeedTreeVertexInput output.detail.z = input.color.a == 0 ? input.texcoord2.z : 2.5; // stay out of Blend's .z range #endif - #ifdef EFFECT_BUMP - real sign = input.tangent.w * GetOddNegativeScale(); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.normalWS.xyz = normalWS; - output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); - output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + if (UseNormalMap()) + { + real sign = input.tangent.w * GetOddNegativeScale(); + output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); + output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + } // View dir packed in w. output.normalWS.w = viewDirWS.x; 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 db282a7714d..61c92e4e3bf 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader @@ -54,10 +54,11 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #pragma fragment SpeedTree8Frag #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION @@ -150,7 +151,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #pragma multi_compile _ LOD_FADE_CROSSFADE #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ProbeVolumeVariants.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Input.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Input.hlsl index 5c7af778f1a..cf5703a0f01 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Input.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Input.hlsl @@ -2,14 +2,16 @@ #define UNIVERSAL_SPEEDTREE8_INPUT_INCLUDED #ifdef EFFECT_BUMP - #define _NORMALMAP + #define _NORMALMAP 1 #endif #define _ALPHATEST_ON #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #if defined(ENABLE_WIND) && !defined(_WINDQUALITY_NONE) #define SPEEDTREE_Y_UP @@ -31,6 +33,13 @@ int _TwoSided; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize; +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); + +half GetBumpScale() { return half(1.0); } + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv); } +half4 SampleBumpMap(float2 uv) { return SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv); } #ifdef EFFECT_EXTRA_TEX sampler2D _ExtraTex; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl index 8b39d8223f4..d6b01fa1d32 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl @@ -7,10 +7,21 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTreeCommon.hlsl" #include "SpeedTreeUtility.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif struct SpeedTreeVertexInput @@ -34,7 +45,7 @@ struct SpeedTreeVertexOutput URP_LIGHT_ACCUM4 fogFactorAndVertexLight : TEXCOORD2; // x: fogFactor, yzw: vertex light - #ifdef EFFECT_BUMP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z @@ -43,7 +54,7 @@ struct SpeedTreeVertexOutput half3 viewDirWS : TEXCOORD4; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD6; #endif @@ -69,7 +80,7 @@ struct SpeedTreeVertexDepthNormalOutput half2 uv : TEXCOORD0; half4 color : TEXCOORD1; - #ifdef EFFECT_BUMP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z @@ -258,11 +269,14 @@ SpeedTreeVertexOutput SpeedTree8Vert(SpeedTreeVertexInput input) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); - #ifdef EFFECT_BUMP - real sign = input.tangent.w * GetOddNegativeScale(); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.normalWS.xyz = normalWS; - output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); - output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + if (UseNormalMap()) + { + real sign = input.tangent.w * GetOddNegativeScale(); + output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); + output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + } // View dir packed in w. output.normalWS.w = viewDirWS.x; @@ -275,8 +289,8 @@ SpeedTreeVertexOutput SpeedTree8Vert(SpeedTreeVertexInput input) output.positionWS = vertexInput.positionWS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif output.clipPos = vertexInput.positionCS; @@ -328,27 +342,28 @@ void InitializeInputData(SpeedTreeFragmentInput input, half3 normalTS, out Input inputData.positionWS = input.interpolated.positionWS.xyz; inputData.positionCS = input.interpolated.clipPos; -#ifdef EFFECT_BUMP - inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz)); - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = input.interpolated.normalWS; +#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) inputData.viewDirectionWS = half3(input.interpolated.normalWS.w, input.interpolated.tangentWS.w, input.interpolated.bitangentWS.w); + if (UseNormalMap()) + { + inputData.tangentToWorld = half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } #else - inputData.normalWS = NormalizeNormalPerPixel(input.interpolated.normalWS); inputData.viewDirectionWS = input.interpolated.viewDirWS; #endif - + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); inputData.viewDirectionWS = SafeNormalize(inputData.viewDirectionWS); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.interpolated.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.interpolated.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.interpolated.fogFactorAndVertexLight.yzw; -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) inputData.bakedGI = SAMPLE_GI(input.interpolated.vertexSH, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -363,13 +378,9 @@ void InitializeInputData(SpeedTreeFragmentInput input, half3 normalTS, out Input inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.interpolated.clipPos); inputData.shadowMask = half4(1, 1, 1, 1); // No GI currently. - #if defined(DEBUG_DISPLAY) && !defined(LIGHTMAP_ON) + #if defined(DEBUG_DISPLAY) inputData.vertexSH = input.interpolated.vertexSH; #endif - - #if defined(_NORMALMAP) - inputData.tangentToWorld = half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz); - #endif } #ifdef GBUFFER @@ -382,14 +393,12 @@ half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated); half2 uv = input.interpolated.uv; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color; + half4 diffuse = SampleBaseMap(uv) * _Color; half alpha = diffuse.a * input.interpolated.color.a; alpha = AlphaDiscard(alpha, 0.3333); - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.interpolated.clipPos); - #endif + LODFadeCrossFade(input.interpolated.clipPos); half3 albedo = diffuse.rgb; half3 emission = 0; @@ -413,10 +422,10 @@ half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target #endif // normal - #ifdef EFFECT_BUMP - half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - #else - half3 normalTs = half3(0, 0, 1); + half3 normalTs = half3(0, 0, 1); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + normalTs = SampleNormal(uv); #endif // flip normal on backsides @@ -447,7 +456,7 @@ half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target SETUP_DEBUG_TEXTURE_DATA(inputData, input.interpolated.uv); #if defined(GBUFFER) || defined(EFFECT_SUBSURFACE) - Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); + Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask, ReceiveShadows(), IsSurfaceTypeTransparent()); #endif // subsurface (hijack emissive) @@ -455,8 +464,8 @@ half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target half fSubsurfaceRough = 0.7 - smoothness * 0.5; half fSubsurface = D_GGX(clamp(-dot(mainLight.direction.xyz, inputData.viewDirectionWS.xyz), 0, 1), fSubsurfaceRough); - float4 shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); - half realtimeShadow = MainLightRealtimeShadow(shadowCoord); + float4 shadowCoord = TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); + half realtimeShadow = ReceiveShadows() ? SampleMainLightRealtimeShadow(shadowCoord, IsSurfaceTypeTransparent()) : half(1.0); float3 tintedSubsurface = tex2D(_SubsurfaceTex, uv).rgb * _SubsurfaceColor.rgb; float3 directSubsurface = tintedSubsurface.rgb * mainLight.color.rgb * fSubsurface * realtimeShadow; float3 indirectSubsurface = tintedSubsurface.rgb * inputData.bakedGI.rgb * _SubsurfaceIndirect; @@ -466,14 +475,14 @@ half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target #ifdef GBUFFER // in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR // in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer - BRDFData brdfData; - InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData); + BRDFData brdfData = InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, IsSpecularSetup(), UseAlphaPremultiply()); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); URP_LIGHT_ACCUM3 color = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, occlusion, inputData.positionWS, - inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV, + UseClearCoat() || UseClearCoatMap(), UseEnvironmentReflections()); - return PackGBuffersBRDFData(brdfData, inputData, smoothness, ClampExposed(inputData.preExposureMultiplier * (emission + color)), occlusion); + return PackGBuffersBRDFData(brdfData, inputData, smoothness, ClampExposed(inputData.preExposureMultiplier * (emission + color)), occlusion, ReceiveShadows(), IsSpecularSetup(), UseSpecularHighlights()); #else SurfaceData surfaceData; @@ -493,7 +502,9 @@ half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target inputData.uv = uv; #endif - URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData); + URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData, + IsSpecularSetup(), UseSpecularHighlights(), UseAlphaPremultiply(), + UseClearCoat() || UseClearCoatMap(), ReceiveShadows(), IsSurfaceTypeTransparent(), UseEnvironmentReflections()); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.interpolated.clipPos)); color.a = OutputAlpha(color.a, _Surface); @@ -509,14 +520,12 @@ half4 SpeedTree8FragDepth(SpeedTreeVertexDepthOutput input) : SV_Target UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uv; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color; + half4 diffuse = SampleBaseMap(uv) * _Color; half alpha = diffuse.a * input.color.a; AlphaDiscard(alpha, 0.3333); - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.clipPos); - #endif + LODFadeCrossFade(input.clipPos); #if defined(SCENESELECTIONPASS) // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly @@ -541,11 +550,14 @@ SpeedTreeVertexDepthNormalOutput SpeedTree8VertDepthNormal(SpeedTreeVertexInput VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz); half3 normalWS = TransformObjectToWorldNormal(input.normal); half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); - #ifdef EFFECT_BUMP - real sign = input.tangent.w * GetOddNegativeScale(); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) output.normalWS.xyz = normalWS; - output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); - output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + if (UseNormalMap()) + { + real sign = input.tangent.w * GetOddNegativeScale(); + output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz); + output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign; + } // View dir packed in w. output.normalWS.w = viewDirWS.x; @@ -566,20 +578,18 @@ half4 SpeedTree8FragDepthNormal(SpeedTreeDepthNormalFragmentInput input) : SV_Ta UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated); half2 uv = input.interpolated.uv; - half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color; + half4 diffuse = SampleBaseMap(uv) * _Color; half alpha = diffuse.a * input.interpolated.color.a; AlphaDiscard(alpha, 0.3333); - #ifdef LOD_FADE_CROSSFADE - LODFadeCrossFade(input.interpolated.clipPos); - #endif + LODFadeCrossFade(input.interpolated.clipPos); // normal - #if defined(EFFECT_BUMP) - half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - #else - half3 normalTs = half3(0, 0, 1); + half3 normalTs = half3(0, 0, 1); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + normalTs = SampleNormal(uv); #endif // flip normal on backsides @@ -606,19 +616,13 @@ half4 SpeedTree8FragDepthNormal(SpeedTreeDepthNormalFragmentInput input) : SV_Ta #endif #endif - #if defined(EFFECT_BUMP) - float3 normalWS = TransformTangentToWorld(normalTs, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz)); - #else - float3 normalWS = input.interpolated.normalWS; + half3 normalWS = input.interpolated.normalWS.xyz; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + normalWS = TransformTangentToWorld(normalTs, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz)); #endif - #if defined(_GBUFFER_NORMALS_OCT) - float2 octNormalWS = PackNormalOctQuadEncode(normalize(normalWS)); // values between [-1, +1], must use fp32 on some platforms. - float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1] - return half4(PackFloat2To888(remappedOctNormalWS), outputAlpha); // values between [ 0, 1] - #else - return half4(NormalizeNormalPerPixel(normalWS), outputAlpha); - #endif + return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), outputAlpha); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader index 43816444345..febc5431d3d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader @@ -10,7 +10,7 @@ Shader "Hidden/Universal Render Pipeline/ObjectMotionVectorFallback" ColorMask RG HLSLPROGRAM - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -32,7 +32,7 @@ Shader "Hidden/Universal Render Pipeline/ObjectMotionVectorFallback" HLSLPROGRAM #define APPLICATION_SPACE_WARP_MOTION 1 #define APPLICATION_SPACE_WARP_MOTION_TRANSPARENT 0 - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl new file mode 100644 index 00000000000..3c49807d3f8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl @@ -0,0 +1,14 @@ +#ifndef UNIVERSAL_PARTICLE_PARAMS_INCLUDED +#define UNIVERSAL_PARTICLE_PARAMS_INCLUDED + +struct ParticleParams +{ + float4 positionWS; + float4 vertexColor; + float4 projectedPosition; + half4 baseColor; + float3 blendUv; + float2 uv; +}; + +#endif // UNIVERSAL_PARTICLE_PARAMS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl.meta new file mode 100644 index 00000000000..2a855e68b4e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 53d01bda3a3e14df1a84ed0360daaa45 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl new file mode 100644 index 00000000000..f9ae39cee0e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl @@ -0,0 +1,175 @@ +#ifndef UNIVERSAL_PARTICLES_INCLUDED +#define UNIVERSAL_PARTICLES_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl" + +void InitParticleParams(VaryingsParticle input, out ParticleParams output) +{ + output = (ParticleParams) 0; + output.uv = input.texcoord; + output.vertexColor = input.color; + + #if defined(_FLIPBOOKBLENDING_ON) + output.blendUv = input.texcoord2AndBlend; + #else + output.blendUv = float3(0,0,0); + #endif + + #if !defined(PARTICLES_EDITOR_META_PASS) + output.positionWS = input.positionWS; + output.baseColor = _BaseColor; + + #if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON) + output.projectedPosition = input.projectedPosition; + #else + output.projectedPosition = float4(0,0,0,0); + #endif + #endif +} + +void MulAlbedo(inout half4 albedo, half val, bool useAlphaPremultiply = false) +{ + if (useAlphaPremultiply) + { + albedo *= val; + } + else + { + albedo.a *= val; + } +} + +void SoftParticleMulAlbedo(inout half4 albedo, half val, bool useAlphaPremultiply = false, bool useAlphaModulate = false) +{ + if (useAlphaPremultiply) + { + albedo *= val; + } + else if (useAlphaModulate) + { + albedo = half4(lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a * val), albedo.a * val); + } + else + { + albedo *= half4(1.0, 1.0, 1.0, val); + } +} + +// Color blending fragment function +half4 MixParticleColor(half4 baseColor, half4 particleColor, half4 colorAddSubDiff) +{ +#if defined(_COLOROVERLAY_ON) // Overlay blend + half4 output = baseColor; + output.rgb = lerp(1 - 2 * (1 - baseColor.rgb) * (1 - particleColor.rgb), 2 * baseColor.rgb * particleColor.rgb, step(baseColor.rgb, 0.5)); + output.a *= particleColor.a; + return output; +#elif defined(_COLORCOLOR_ON) // Color blend + half3 aHSL = RgbToHsv(baseColor.rgb); + half3 bHSL = RgbToHsv(particleColor.rgb); + half3 rHSL = half3(bHSL.x, bHSL.y, aHSL.z); + return half4(HsvToRgb(rHSL), baseColor.a * particleColor.a); +#elif defined(_COLORADDSUBDIFF_ON) // Additive, Subtractive and Difference blends based on 'colorAddSubDiff' + half4 output = baseColor; + output.rgb = baseColor.rgb + particleColor.rgb * colorAddSubDiff.x; + output.rgb = lerp(output.rgb, abs(output.rgb), colorAddSubDiff.y); + output.a *= particleColor.a; + return output; +#else // Default to Multiply blend + return baseColor * particleColor; +#endif +} + +// Soft particles - returns alpha value for fading particles based on the depth to the background pixel +float SoftParticles(float near, float far, float4 projection) +{ + float fade = 1; + if (near > 0.0 || far > 0.0) + { + float2 uv = UnityStereoTransformScreenSpaceTex(projection.xy / projection.w); +#if defined(UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION) + uv = RemovePretransformRotation(uv); +#endif + uv = FoveatedRemapLinearToNonUniform(uv); + + float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r; + float sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(rawDepth, _ZBufferParams) : LinearDepthToEyeDepth(rawDepth); + float thisZ = LinearEyeDepth(projection.z / projection.w, _ZBufferParams); + fade = saturate(far * ((sceneZ - near) - thisZ)); + } + return fade; +} + +// Soft particles - returns alpha value for fading particles based on the depth to the background pixel +float SoftParticles(float near, float far, ParticleParams params) +{ + float fade = 1; + if (near > 0.0 || far > 0.0) + { + float2 uv = UnityStereoTransformScreenSpaceTex(params.projectedPosition.xy / params.projectedPosition.w); +#if defined(UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION) + uv = RemovePretransformRotation(uv); +#endif + uv = FoveatedRemapLinearToNonUniform(uv); + float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r; + float sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(rawDepth, _ZBufferParams) : LinearDepthToEyeDepth(rawDepth); + float thisZ = LinearEyeDepth(params.positionWS.xyz, GetWorldToViewMatrix()); + fade = saturate(far * ((sceneZ - near) - thisZ)); + } + return fade; +} + +// Camera fade - returns alpha value for fading particles based on camera distance +half CameraFade(float near, float far, float4 projection) +{ + float thisZ = LinearEyeDepth(projection.z / projection.w, _ZBufferParams); + return half(saturate((thisZ - near) * far)); +} + +// Only call when alpha modulate or alpha premultiply is enabled; the two are mutually exclusive. +half3 AlphaModulateAndPremultiply(half3 albedo, half alpha, bool useAlphaModulate) +{ + half3 result; + if (useAlphaModulate) + result = ApplyAlphaModulate(albedo, alpha); + else + result = ApplyAlphaPremultiply(albedo, alpha); + + return result; +} + +half3 Distortion(float4 baseColor, float3 normal, half strength, half blend, float4 projection) +{ + float2 screenUV = (projection.xy / projection.w) + normal.xy * strength * baseColor.a; + screenUV = UnityStereoTransformScreenSpaceTex(screenUV); + float3 distortion = SampleSceneColor(screenUV); + return half3(lerp(distortion, baseColor.rgb, saturate(baseColor.a - blend))); +} + +// Sample a texture and do blending for texture sheet animation if needed +half4 BlendTexture(UnityTexture2D _Texture, float2 uv, float3 blendUv) +{ + half4 color = half4(SAMPLE_TEXTURE2D(_Texture.tex, _Texture.samplerstate, uv)); +#ifdef _FLIPBOOKBLENDING_ON + half4 color2 = half4(SAMPLE_TEXTURE2D(_Texture.tex, _Texture.samplerstate, blendUv.xy)); + color = lerp(color, color2, half(blendUv.z)); +#endif + return color; +} + +// Samples and unpacks the flipbook-blended normal map. Only call when the material has a normal map. +half3 SampleParticleNormalTS(float2 uv, float3 blendUv, UnityTexture2D bumpMap, half scale) +{ + half4 n = BlendTexture(bumpMap, uv, blendUv); + #if BUMP_SCALE_NOT_SUPPORTED + return UnpackNormal(n); + #else + return UnpackNormalScale(n, scale); + #endif +} + +#endif // UNIVERSAL_PARTICLES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl.meta new file mode 100644 index 00000000000..ce9108b4f97 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 27c3e50780000403caa6d5cbadda9f08 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl index 74194b10060..2ea2f5eac85 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl @@ -3,6 +3,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" VaryingsDepthNormalsParticle DepthNormalsVertex(AttributesDepthNormalsParticle input) { @@ -16,7 +17,7 @@ VaryingsDepthNormalsParticle DepthNormalsVertex(AttributesDepthNormalsParticle i half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); - #if defined(_NORMALMAP) + #if FEATURES_NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); @@ -31,7 +32,7 @@ VaryingsDepthNormalsParticle DepthNormalsVertex(AttributesDepthNormalsParticle i output.color = GetParticleColor(input.color); #endif - #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) + #if defined(_ALPHATEST_ON) || FEATURES_NORMALMAP #if defined(_FLIPBOOKBLENDING_ON) #if defined(UNITY_PARTICLE_INSTANCING_ENABLED) GetParticleTexcoords(output.texcoord, output.texcoord2AndBlend, input.texcoords.xyxy, 0.0); @@ -52,7 +53,7 @@ half4 DepthNormalsFragment(VaryingsDepthNormalsParticle input) : SV_TARGET UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); // Inputs... - #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) || defined(_WRITE_SMOOTHNESS) + #if defined(_ALPHATEST_ON) || FEATURES_NORMALMAP || defined(_WRITE_SMOOTHNESS) float2 uv = input.texcoord; #if defined(_FLIPBOOKBLENDING_ON) @@ -78,24 +79,28 @@ half4 DepthNormalsFragment(VaryingsDepthNormalsParticle input) : SV_TARGET #endif // Normals... - #ifdef _NORMALMAP - half3 normalTS = SampleNormalTS(uv, blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), _BumpScale); - float3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); - #else - float3 normalWS = input.normalWS; + half3 normalWS = input.normalWS.xyz; + + #if FEATURES_NORMALMAP + if (UseNormalMap()) + { + half3 normalTS = half3(0.0, 0.0, 1.0); + if (UseNormalMap()) + normalTS = SampleParticleNormalTS(uv, blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), _BumpScale); + normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + } #endif half outputAlpha = 0; + #if defined(_WRITE_SMOOTHNESS) - #if defined(_METALLICSPECGLOSSMAP) - outputAlpha = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_MetallicGlossMap), uv, blendUv).a * _Smoothness; - #else - outputAlpha = _Smoothness; - #endif + half glossMapAlpha = UseMetallicSpecGlossMap() + ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_MetallicGlossMap), uv, blendUv).a + : half(1.0); + outputAlpha = glossMapAlpha * _Smoothness; #endif - - // Output... - return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS)), outputAlpha); + + return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), outputAlpha); } #endif // UNIVERSAL_PARTICLES_LIT_DEPTH_NORMALS_PASS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl index d2853bc4c23..b1d37f82a1f 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesEditorPass.hlsl @@ -2,7 +2,7 @@ #define UNIVERSAL_PARTICLES_EDITOR_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl" float _ObjectId; float _PassValue; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl index 2afcc388f6f..1bc8739d424 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl @@ -2,6 +2,7 @@ #define UNIVERSAL_PARTICLES_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" struct AttributesParticle { @@ -35,7 +36,7 @@ struct VaryingsParticle #if !defined(PARTICLES_EDITOR_META_PASS) float4 positionWS : TEXCOORD1; - #ifdef _NORMALMAP + #if FEATURES_NORMALMAP half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z @@ -48,7 +49,7 @@ struct VaryingsParticle float4 projectedPosition: TEXCOORD6; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD7; #endif @@ -140,7 +141,7 @@ struct AttributesDepthNormalsParticle half4 color : COLOR; #endif - #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) + #if defined(_ALPHATEST_ON) || FEATURES_NORMALMAP #if defined(_FLIPBOOKBLENDING_ON) && !defined(UNITY_PARTICLE_INSTANCING_ENABLED) float4 texcoords : TEXCOORD0; float texcoordBlend : TEXCOORD1; @@ -164,7 +165,7 @@ struct VaryingsDepthNormalsParticle half4 color : COLOR; #endif - #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) || defined(_WRITE_SMOOTHNESS) + #if defined(_ALPHATEST_ON) || FEATURES_NORMALMAP || defined(_WRITE_SMOOTHNESS) float2 texcoord : TEXCOORD0; #if defined(_FLIPBOOKBLENDING_ON) @@ -172,7 +173,7 @@ struct VaryingsDepthNormalsParticle #endif #endif - #if defined(_NORMALMAP) + #if FEATURES_NORMALMAP float4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x float4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y float4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl new file mode 100644 index 00000000000..4e1ecf3ee4f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl @@ -0,0 +1,97 @@ +#ifndef UNIVERSAL_PARTICLESINSTANCING_INCLUDED +#define UNIVERSAL_PARTICLESINSTANCING_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParticlesInstancing.hlsl" + +#if defined(UNITY_PARTICLE_INSTANCING_ENABLED) + +// Kept for backward compatibility with custom shaders that call it directly. +void ParticleInstancingMatrices(out float4x4 objectToWorld, out float4x4 worldToObject) +{ + UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID]; + + // transform matrix + objectToWorld._11_21_31_41 = float4(data.transform._11_21_31, 0.0f); + objectToWorld._12_22_32_42 = float4(data.transform._12_22_32, 0.0f); + objectToWorld._13_23_33_43 = float4(data.transform._13_23_33, 0.0f); + objectToWorld._14_24_34_44 = float4(data.transform._14_24_34, 1.0f); + + // inverse transform matrix + float3x3 worldToObject3x3; + worldToObject3x3[0] = objectToWorld[1].yzx * objectToWorld[2].zxy - objectToWorld[1].zxy * objectToWorld[2].yzx; + worldToObject3x3[1] = objectToWorld[0].zxy * objectToWorld[2].yzx - objectToWorld[0].yzx * objectToWorld[2].zxy; + worldToObject3x3[2] = objectToWorld[0].yzx * objectToWorld[1].zxy - objectToWorld[0].zxy * objectToWorld[1].yzx; + + float det = dot(objectToWorld[0].xyz, worldToObject3x3[0]); + + worldToObject3x3 = transpose(worldToObject3x3); + + worldToObject3x3 *= rcp(det); + + float3 worldToObjectPosition = mul(worldToObject3x3, -objectToWorld._14_24_34); + + worldToObject._11_21_31_41 = float4(worldToObject3x3._11_21_31, 0.0f); + worldToObject._12_22_32_42 = float4(worldToObject3x3._12_22_32, 0.0f); + worldToObject._13_23_33_43 = float4(worldToObject3x3._13_23_33, 0.0f); + worldToObject._14_24_34_44 = float4(worldToObjectPosition, 1.0f); +} + +// Builds VertexPositionInputs from the particle instance transform directly, +// bypassing GetVertexPositionInputs() which reads UNITY_MATRIX_M. +VertexPositionInputs ParticleInstancingGetVertexPositionInputs(float3x4 transform, float3 positionOS) +{ + VertexPositionInputs vertexInput; + vertexInput.positionWS = ParticleInstancingTransformPosition(transform, positionOS); + vertexInput.positionVS = TransformWorldToView(vertexInput.positionWS); + vertexInput.positionCS = TransformWorldToHClip(vertexInput.positionWS); + float4 ndc = vertexInput.positionCS * 0.5f; + vertexInput.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w; + vertexInput.positionNDC.zw = vertexInput.positionCS.zw; + return vertexInput; +} + +// Builds VertexNormalInputs from the particle instance transform directly, +// bypassing GetVertexNormalInputs() which reads UNITY_MATRIX_I_M. +// Tangents transform with the forward 3x3 (covariant, like directions). +// Normals require the inverse-transpose: cofactor(m) equals det(m)*m^{-T}; +// after SafeNormalize this gives the correct world normal under non-uniform scale. +// Matches TransformParticleMesh in the ShaderGraph package (Particles.hlsl). +VertexNormalInputs ParticleInstancingGetVertexNormalInputs(float3x4 transform, float3 normalOS, float4 tangentOS) +{ + ParticleInstancingTransformNormalTangent(transform, normalOS, tangentOS.xyz); + + VertexNormalInputs tbn; + tbn.normalWS = SafeNormalize(normalOS); + tbn.tangentWS = real3(SafeNormalize(tangentOS.xyz)); + + real sign = real(tangentOS.w) * GetOddNegativeScale(); + tbn.bitangentWS = real3(cross(tbn.normalWS, float3(tbn.tangentWS))) * sign; + return tbn; +} + +#endif + +VertexPositionInputs GetParticleVertexPositionInputs(float3 positionOS) +{ +#if defined(UNITY_PARTICLE_INSTANCING_ENABLED) + return ParticleInstancingGetVertexPositionInputs(unity_ParticleInstanceData[unity_InstanceID].transform, positionOS); +#else + return GetVertexPositionInputs(positionOS); +#endif +} + +VertexNormalInputs GetParticleVertexNormalInputs(float3 normalOS, float4 tangentOS) +{ +#if defined(UNITY_PARTICLE_INSTANCING_ENABLED) + return ParticleInstancingGetVertexNormalInputs(unity_ParticleInstanceData[unity_InstanceID].transform, normalOS, tangentOS); +#else + return GetVertexNormalInputs(normalOS, tangentOS); +#endif +} + +VertexNormalInputs GetParticleVertexNormalInputs(float3 normalOS) +{ + return GetParticleVertexNormalInputs(normalOS, float4(0, 0, 0, 1)); +} + +#endif // UNIVERSAL_PARTICLESINSTANCING_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl.meta new file mode 100644 index 00000000000..dc034496913 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInstancing.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e23b52cb754364b2fae1e12fe3867d4d +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: 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 af615b98926..bdf98ade0fb 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader @@ -130,7 +130,8 @@ Shader "Universal Render Pipeline/Particles/Lit" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING @@ -143,8 +144,8 @@ Shader "Universal Render Pipeline/Particles/Lit" #pragma multi_compile_fragment _ _VOLUMETRIC_FOG #pragma multi_compile_fragment _FOG_ANALYTIC _FOG_VOLUMETRIC #pragma shader_feature_local_fragment _TRANSPARENT_RECEIVE_FOG + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) @@ -228,7 +229,7 @@ Shader "Universal Render Pipeline/Particles/Lit" #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" @@ -499,7 +500,7 @@ Shader "Universal Render Pipeline/Particles/Lit" // ------------------------------------- // Material Keywords #pragma shader_feature_local_fragment _ALPHATEST_ON - #pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON + #pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON // ------------------------------------- // Includes diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl new file mode 100644 index 00000000000..9488988fe5d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl @@ -0,0 +1,14 @@ +#ifndef UNIVERSAL_PARTICLES_LIT_FEATURES_INCLUDED +#define UNIVERSAL_PARTICLES_LIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the ParticlesLit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" + +#endif // UNIVERSAL_PARTICLES_LIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl.meta new file mode 100644 index 00000000000..a16857fd30c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 95043838ca165485a9bcffdbc727e063 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl index 71d95bb9511..0fbd37863a1 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl @@ -4,7 +4,14 @@ #include "ParticlesLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData inputData) { @@ -13,31 +20,36 @@ void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData i inputData.positionWS = input.positionWS.xyz; -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + if (UseNormalMap()) + { + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } + else + { + inputData.normalWS = input.normalWS.xyz; + } #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = half3(0.0h, 0.0h, 0.0h); -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) inputData.bakedGI = SAMPLE_GI(input.vertexSH, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -80,7 +92,7 @@ VaryingsParticle ParticlesLitVertex(AttributesParticle input) URP_LIGHT_ACCUM3 vertexLight = VertexLighting(vertexInput.positionWS, half3(normalInput.normalWS)); half fogFactor = 0.0; -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); @@ -110,8 +122,8 @@ VaryingsParticle ParticlesLitVertex(AttributesParticle input) output.projectedPosition = vertexInput.positionNDC; #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -126,16 +138,21 @@ half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target InitParticleParams(input, particleParams); SurfaceData surfaceData; - InitializeParticleLitSurfaceData(particleParams, surfaceData); + InitializeParticleLitSurfaceData(particleParams, surfaceData, + UseAlphaPremultiply(), UseMetallicSpecGlossMap(), UseEmission(), + UseNormalMap(), UseAlphaModulate()); InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA_FOR_TEX(inputData, input.texcoord, _BaseMap); - URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData); + URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, surfaceData, + IsSpecularSetup(), UseSpecularHighlights(), UseAlphaPremultiply(), + UseClearCoat() || UseClearCoatMap(), ReceiveShadows(), IsSurfaceTypeTransparent(), UseEnvironmentReflections()); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.clipPos)); -#if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, input.clipPos); +#if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, UseAlphaPremultiply(), input.clipPos); #endif color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl index 85bb4017b83..c5f3ce12300 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl @@ -3,6 +3,14 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitFeatures.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData inputData) { @@ -12,42 +20,47 @@ void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData i inputData.positionWS = input.positionWS.xyz; inputData.positionCS = input.clipPos; -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); - inputData.normalWS = TransformTangentToWorld(normalTS, - half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + if (UseNormalMap()) + { + inputData.normalWS = TransformTangentToWorld(normalTS, + half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + } + else + { + inputData.normalWS = input.normalWS.xyz; + } #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.fogCoord = 0.0; // not used for deferred shading inputData.vertexLighting = half3(0.0h, 0.0h, 0.0h); -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SampleSHPixel(input.vertexSH, inputData.normalWS); + GIParams giParams = (GIParams)0; +#ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; #endif + giParams.vertexSH = input.vertexSH; + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + half4 unusedShadowMask; + InitializeBakedGI(giParams, inputData.bakedGI, unusedShadowMask); inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos); inputData.shadowMask = half4(1, 1, 1, 1); @@ -78,7 +91,7 @@ VaryingsParticle ParticlesGBufferVertex(AttributesParticle input) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); URP_LIGHT_ACCUM3 vertexLight = VertexLighting(vertexInput.positionWS, half3(normalInput.normalWS)); -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); @@ -103,8 +116,8 @@ VaryingsParticle ParticlesGBufferVertex(AttributesParticle input) GetParticleTexcoords(output.texcoord, input.texcoords.xy); #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -126,7 +139,9 @@ GBufferFragOutput ParticlesGBufferFragment(VaryingsParticle input) #endif SurfaceData surfaceData; - InitializeParticleLitSurfaceData(input.texcoord, blendUv, input.color, projectedPosition, surfaceData); + InitializeParticleLitSurfaceData(input.texcoord, blendUv, input.color, projectedPosition, surfaceData, + UseAlphaPremultiply(), UseMetallicSpecGlossMap(), UseEmission(), + UseNormalMap(), UseAlphaModulate()); InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); @@ -136,15 +151,15 @@ GBufferFragOutput ParticlesGBufferFragment(VaryingsParticle input) // in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR // in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer - BRDFData brdfData; - InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); + BRDFData brdfData = InitializeBRDFData(surfaceData, IsSpecularSetup(), UseAlphaPremultiply()); - Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask, ReceiveShadows(), IsSurfaceTypeTransparent()); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); URP_LIGHT_ACCUM3 color = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, surfaceData.occlusion, inputData.positionWS, - inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV, + UseClearCoat() || UseClearCoatMap(), UseEnvironmentReflections()); - return PackGBuffersBRDFData(brdfData, inputData, surfaceData.smoothness, ClampExposed(inputData.preExposureMultiplier * (surfaceData.emission + color)), surfaceData.occlusion); + return PackGBuffersBRDFData(brdfData, inputData, surfaceData.smoothness, ClampExposed(inputData.preExposureMultiplier * (surfaceData.emission + color)), surfaceData.occlusion, ReceiveShadows(), IsSpecularSetup(), UseSpecularHighlights()); } #endif // UNIVERSAL_PARTICLES_GBUFFER_LIT_PASS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl new file mode 100644 index 00000000000..d11728d29f9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl @@ -0,0 +1,118 @@ +#ifndef UNIVERSAL_PARTICLES_LIT_INPUT_DEPRECATED_INCLUDED +#define UNIVERSAL_PARTICLES_LIT_INPUT_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (ParticlesLitInput.hlsl). + +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap, bool alphaPremultiplyEnabled); +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params, bool alphaPremultiplyEnabled); +void InitializeParticleLitSurfaceData(float2 uv, float3 blendUv, float4 particleColor, float4 projectedPosition, out SurfaceData outSurfaceData, bool alphaPremultiplyEnabled, bool metallicSpecGlossMap, bool emission, bool normalMap, bool alphaModulateEnabled); +void InitializeParticleLitSurfaceData(ParticleParams params, out SurfaceData outSurfaceData, bool alphaPremultiplyEnabled, bool metallicSpecGlossMap, bool emission, bool normalMap, bool alphaModulateEnabled); + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +#if !defined(_EMISSION_KEYWORD_DECLARED) + #if !defined(_EMISSION) + #define _EMISSION 0 + #define _EMISSION_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_EMISSION) + #undef _EMISSION + #define _EMISSION 1 + #endif +#endif + +#if !defined(_METALLICSPECGLOSSMAP_KEYWORD_DECLARED) + #if !defined(_METALLICSPECGLOSSMAP) + #define _METALLICSPECGLOSSMAP 0 + #define _METALLICSPECGLOSSMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_METALLICSPECGLOSSMAP) + #undef _METALLICSPECGLOSSMAP + #define _METALLICSPECGLOSSMAP 1 + #endif +#endif + +#if !defined(_NORMALMAP_KEYWORD_DECLARED) + #if !defined(_NORMALMAP) + #define _NORMALMAP 0 + #define _NORMALMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_NORMALMAP) + #undef _NORMALMAP + #define _NORMALMAP 1 + #endif +#endif + +#if !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAMODULATE_ON) + #define _ALPHAMODULATE_ON 0 + #define _ALPHAMODULATE_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef _ALPHAMODULATE_ON + #define _ALPHAMODULATE_ON 1 + #endif +#endif + +// Deprecated. Use SampleAlbedo(..., alphaPremultiplyEnabled). +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap) +{ + return SampleAlbedo(uv, blendUv, color, particleColor, projectedPosition, albedoMap, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use SampleAlbedo(albedoMap, params, alphaPremultiplyEnabled). +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) +{ + return SampleAlbedo(albedoMap, params, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use InitializeParticleLitSurfaceData(..., alphaPremultiplyEnabled, metallicSpecGlossMap, emission, normalMap, alphaModulateEnabled). +inline void InitializeParticleLitSurfaceData(float2 uv, float3 blendUv, float4 particleColor, float4 projectedPosition, out SurfaceData outSurfaceData) +{ + InitializeParticleLitSurfaceData(uv, blendUv, particleColor, projectedPosition, outSurfaceData, _ALPHAPREMULTIPLY_ON, _METALLICSPECGLOSSMAP, _EMISSION, _NORMALMAP, _ALPHAMODULATE_ON); +} + +// Deprecated. Use InitializeParticleLitSurfaceData(params, outSurfaceData, alphaPremultiplyEnabled, metallicSpecGlossMap, emission, normalMap, alphaModulateEnabled). +inline void InitializeParticleLitSurfaceData(ParticleParams params, out SurfaceData outSurfaceData) +{ + InitializeParticleLitSurfaceData(params, outSurfaceData, _ALPHAPREMULTIPLY_ON, _METALLICSPECGLOSSMAP, _EMISSION, _NORMALMAP, _ALPHAMODULATE_ON); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#if defined(_EMISSION_DEFINED_LOCALLY) + #undef _EMISSION_DEFINED_LOCALLY + #undef _EMISSION +#endif + +#if defined(_METALLICSPECGLOSSMAP_DEFINED_LOCALLY) + #undef _METALLICSPECGLOSSMAP_DEFINED_LOCALLY + #undef _METALLICSPECGLOSSMAP +#endif + +#if defined(_NORMALMAP_DEFINED_LOCALLY) + #undef _NORMALMAP_DEFINED_LOCALLY + #undef _NORMALMAP +#endif + +#if defined(_ALPHAMODULATE_ON_DEFINED_LOCALLY) + #undef _ALPHAMODULATE_ON_DEFINED_LOCALLY + #undef _ALPHAMODULATE_ON +#endif + +#endif // UNIVERSAL_PARTICLES_LIT_INPUT_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl.meta new file mode 100644 index 00000000000..a3ca4f41d2d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8e8119f247d6b453a907fc670f84e70b +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl index a65e53ee822..88291d8ec15 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl @@ -2,8 +2,22 @@ #define UNIVERSAL_PARTICLES_LIT_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.deprecated.hlsl" + +TEXTURE2D(_BaseMap); +SAMPLER(sampler_BaseMap); +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); +TEXTURE2D(_EmissionMap); +SAMPLER(sampler_EmissionMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -23,7 +37,8 @@ half _DistortionBlend; half _Blend; CBUFFER_END -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap); @@ -33,7 +48,7 @@ TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap); #define CAMERA_NEAR_FADE _CameraFadeParams.x #define CAMERA_INV_FADE_DISTANCE _CameraFadeParams.y -half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap) +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap, bool useAlphaPremultiply) { half4 albedo = BlendTexture(albedoMap, uv, blendUv) * color; @@ -47,17 +62,17 @@ half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, albedo.a = AlphaDiscard(albedo.a, _Cutoff); #if defined(_SOFTPARTICLES_ON) - ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition); + MulAlbedo(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition)), useAlphaPremultiply); #endif - #if defined(_FADING_ON) - ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition); - #endif +#if defined(_FADING_ON) + MulAlbedo(albedo, CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition), useAlphaPremultiply); +#endif return albedo; } -half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params, bool useAlphaPremultiply) { half4 albedo = BlendTexture(albedoMap, params.uv, params.blendUv) * params.baseColor; @@ -71,33 +86,27 @@ half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) albedo.a = AlphaDiscard(albedo.a, _Cutoff); #if defined(_SOFTPARTICLES_ON) - ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params); + MulAlbedo(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params)), useAlphaPremultiply); #endif - #if defined(_FADING_ON) - ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition); - #endif +#if defined(_FADING_ON) + MulAlbedo(albedo, CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition), useAlphaPremultiply); +#endif return albedo; } -inline void InitializeParticleLitSurfaceData(float2 uv, float3 blendUv, float4 particleColor, float4 projectedPosition, out SurfaceData outSurfaceData) +inline void InitializeParticleLitSurfaceData(float2 uv, float3 blendUv, float4 particleColor, float4 projectedPosition, out SurfaceData outSurfaceData, bool useAlphaPremultiply, bool useMetallicSpecGlossMap, bool useEmission, bool useNormalMap, bool useAlphaModulate) { - half4 albedo = SampleAlbedo(uv, blendUv, _BaseColor, particleColor, projectedPosition, UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap)); + half4 albedo = SampleAlbedo(uv, blendUv, _BaseColor, particleColor, projectedPosition, UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), useAlphaPremultiply); -#if defined(_METALLICSPECGLOSSMAP) - half2 metallicGloss = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_MetallicGlossMap), uv, blendUv).ra * half2(1.0, _Smoothness); -#else - half2 metallicGloss = half2(_Metallic, _Smoothness); -#endif + half2 metallicGloss = useMetallicSpecGlossMap ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_MetallicGlossMap), uv, blendUv).ra * half2(1.0, _Smoothness) : half2(_Metallic, _Smoothness); - half3 normalTS = SampleNormalTS(uv, blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), _BumpScale); + half3 normalTS = half3(0.0, 0.0, 1.0); + if (useNormalMap) + normalTS = SampleParticleNormalTS(uv, blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), _BumpScale); -#if defined(_EMISSION) - half3 emission = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), uv, blendUv).rgb * _EmissionColor.rgb; -#else - half3 emission = half3(0, 0, 0); -#endif + half3 emissionColor = useEmission ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), uv, blendUv).rgb * _EmissionColor.rgb : half3(0, 0, 0); #if defined(_DISTORTION_ON) albedo.rgb = Distortion(albedo, normalTS, _DistortionStrengthScaled, _DistortionBlend, projectedPosition); @@ -107,35 +116,30 @@ inline void InitializeParticleLitSurfaceData(float2 uv, float3 blendUv, float4 p outSurfaceData.albedo = albedo.rgb; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); outSurfaceData.normalTS = normalTS; - outSurfaceData.emission = emission; + outSurfaceData.emission = emissionColor; outSurfaceData.metallic = metallicGloss.r; outSurfaceData.smoothness = metallicGloss.g; outSurfaceData.occlusion = 1.0; - outSurfaceData.albedo = AlphaModulate(outSurfaceData.albedo, albedo.a); // Premultiply in UniversalPBR, BRDF init. + if (useAlphaModulate) + outSurfaceData.albedo = ApplyAlphaModulate(outSurfaceData.albedo, albedo.a); // Premultiply in UniversalPBR, BRDF init. outSurfaceData.alpha = albedo.a; outSurfaceData.clearCoatMask = half(0.0); outSurfaceData.clearCoatSmoothness = half(1.0); } -inline void InitializeParticleLitSurfaceData(ParticleParams params, out SurfaceData outSurfaceData) +inline void InitializeParticleLitSurfaceData(ParticleParams params, out SurfaceData outSurfaceData, bool useAlphaPremultiply, bool useMetallicSpecGlossMap, bool useEmission, bool useNormalMap, bool useAlphaModulate) { - half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), params); + half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), params, useAlphaPremultiply); - #if defined(_METALLICSPECGLOSSMAP) - half2 metallicGloss = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_MetallicGlossMap), params.uv, params.blendUv).ra * half2(1.0, _Smoothness); - #else - half2 metallicGloss = half2(_Metallic, _Smoothness); - #endif + half2 metallicGloss = useMetallicSpecGlossMap ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_MetallicGlossMap), params.uv, params.blendUv).ra * half2(1.0, _Smoothness) : half2(_Metallic, _Smoothness); - half3 normalTS = SampleNormalTS(params.uv, params.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), _BumpScale); + half3 normalTS = half3(0.0, 0.0, 1.0); + if (useNormalMap) + normalTS = SampleParticleNormalTS(params.uv, params.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), _BumpScale); - #if defined(_EMISSION) - half3 emission = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), params.uv, params.blendUv).rgb * _EmissionColor.rgb; - #else - half3 emission = half3(0, 0, 0); - #endif + half3 emissionColor = useEmission ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), params.uv, params.blendUv).rgb * _EmissionColor.rgb : half3(0, 0, 0); #if defined(_DISTORTION_ON) albedo.rgb = Distortion(albedo, normalTS, _DistortionStrengthScaled, _DistortionBlend, params.projectedPosition); @@ -145,12 +149,13 @@ inline void InitializeParticleLitSurfaceData(ParticleParams params, out SurfaceD outSurfaceData.albedo = albedo.rgb; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); outSurfaceData.normalTS = normalTS; - outSurfaceData.emission = emission; + outSurfaceData.emission = emissionColor; outSurfaceData.metallic = metallicGloss.r; outSurfaceData.smoothness = metallicGloss.g; outSurfaceData.occlusion = 1.0; - outSurfaceData.albedo = AlphaModulate(outSurfaceData.albedo, albedo.a); + if (useAlphaModulate) + outSurfaceData.albedo = ApplyAlphaModulate(outSurfaceData.albedo, albedo.a); outSurfaceData.alpha = albedo.a; outSurfaceData.clearCoatMask = half(0.0); 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 9129019f4d2..e7e70605763 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader @@ -135,7 +135,8 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH @@ -144,8 +145,8 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" #pragma multi_compile_fragment _ _VOLUMETRIC_FOG #pragma multi_compile_fragment _FOG_ANALYTIC _FOG_VOLUMETRIC #pragma shader_feature_local_fragment _TRANSPARENT_RECEIVE_FOG + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) @@ -504,7 +505,7 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" // ------------------------------------- // Material Keywords #pragma shader_feature_local_fragment _ALPHATEST_ON - #pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON + #pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON // ------------------------------------- // Includes diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl new file mode 100644 index 00000000000..4222b074fec --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl @@ -0,0 +1,12 @@ +#ifndef UNIVERSAL_PARTICLES_SIMPLE_LIT_FEATURES_INCLUDED +#define UNIVERSAL_PARTICLES_SIMPLE_LIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the ParticlesSimpleLit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" + +#endif // UNIVERSAL_PARTICLES_SIMPLE_LIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl.meta new file mode 100644 index 00000000000..378cbd0f6e8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a4c08e32368cc44208037cce70ba8f4e +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl index a1ac0bb9d53..66ac623dec8 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl @@ -4,7 +4,15 @@ #include "ParticlesSimpleLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData inputData) { @@ -13,31 +21,36 @@ void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData i inputData.positionWS = input.positionWS.xyz; -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + if (UseNormalMap()) + { + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } + else + { + inputData.normalWS = input.normalWS.xyz; + } #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = half3(0.0h, 0.0h, 0.0h); -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) inputData.bakedGI = SAMPLE_GI(input.vertexSH, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -76,7 +89,7 @@ VaryingsParticle ParticlesLitVertex(AttributesParticle input) VertexNormalInputs normalInput = GetParticleVertexNormalInputs(input.normalOS, input.tangentOS); half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); @@ -108,8 +121,8 @@ VaryingsParticle ParticlesLitVertex(AttributesParticle input) output.projectedPosition = vertexInput.positionNDC; #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -123,16 +136,22 @@ half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target ParticleParams particleParams; InitParticleParams(input, particleParams); - half3 normalTS = SampleNormalTS(particleParams.uv, particleParams.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap)); - half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), particleParams); - half3 diffuse = AlphaModulate(albedo.rgb, albedo.a); + half3 normalTS = half3(0.0, 0.0, 1.0); + if (UseNormalMap()) + normalTS = SampleParticleNormalTS(particleParams.uv, particleParams.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), half(1.0)); + half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), particleParams, UseAlphaPremultiply()); + half3 diffuse = albedo.rgb; + if (UseAlphaModulate()) + diffuse = ApplyAlphaModulate(albedo.rgb, albedo.a); half alpha = albedo.a; -#if defined(_EMISSION) - half3 emission = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb; -#else - half3 emission = half3(0, 0, 0); -#endif - half4 specularGloss = SampleSpecularSmoothness(particleParams.uv, particleParams.blendUv, albedo.a, _SpecColor, UnityBuildTexture2DStructNoScaleNoTexelSize(_SpecGlossMap)); + half3 emission = UseEmission() ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb : half3(0, 0, 0); + half4 specularGloss = half4(0, 0, 0, 1); + if (UseSpecGlossMap()) + specularGloss = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_SpecGlossMap), particleParams.uv, particleParams.blendUv); + else if (UseSpecularColor()) + specularGloss = _SpecColor; + if (UseGlossinessFromBaseAlpha()) + specularGloss.a = albedo.a; #if defined(_DISTORTION_ON) diffuse = Distortion(half4(diffuse, alpha), normalTS, _DistortionStrengthScaled, _DistortionBlend, particleParams.projectedPosition); @@ -144,8 +163,9 @@ half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, diffuse, specularGloss, specularGloss.a, emission, alpha, normalTS); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.clipPos)); -#if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, input.clipPos); +#if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, UseAlphaPremultiply(), input.clipPos); #endif color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl index 2ed0ac23d04..b6749ca5b7a 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl @@ -3,7 +3,16 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitFeatures.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData inputData) { @@ -13,32 +22,37 @@ void InitializeInputData(VaryingsParticle input, half3 normalTS, out InputData i inputData.positionWS = input.positionWS.xyz; inputData.positionCS = input.clipPos; -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); - inputData.normalWS = TransformTangentToWorld(normalTS, - half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + if (UseNormalMap()) + { + inputData.normalWS = TransformTangentToWorld(normalTS, + half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + } + else + { + inputData.normalWS = input.normalWS.xyz; + } #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.fogCoord = 0; // not used for deferred shading inputData.vertexLighting = half3(0.0h, 0.0h, 0.0h); -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) inputData.bakedGI = SAMPLE_GI(input.vertexSH, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -68,16 +82,22 @@ inline void InitializeParticleSimpleLitSurfaceData(VaryingsParticle input, out S ParticleParams particleParams; InitParticleParams(input, particleParams); - outSurfaceData.normalTS = SampleNormalTS(particleParams.uv, particleParams.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap)); - half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), particleParams); - outSurfaceData.albedo = AlphaModulate(albedo.rgb, albedo.a); + outSurfaceData.normalTS = half3(0.0, 0.0, 1.0); + if (UseNormalMap()) + outSurfaceData.normalTS = SampleParticleNormalTS(particleParams.uv, particleParams.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), half(1.0)); + half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), particleParams, UseAlphaPremultiply()); + outSurfaceData.albedo = albedo.rgb; + if (UseAlphaModulate()) + outSurfaceData.albedo = ApplyAlphaModulate(albedo.rgb, albedo.a); outSurfaceData.alpha = albedo.a; -#if defined(_EMISSION) - outSurfaceData.emission = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb; -#else - outSurfaceData.emission = half3(0, 0, 0); -#endif - half4 specularGloss = SampleSpecularSmoothness(particleParams.uv, particleParams.blendUv, albedo.a, _SpecColor, UnityBuildTexture2DStructNoScaleNoTexelSize(_SpecGlossMap)); + outSurfaceData.emission = UseEmission() ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb : half3(0, 0, 0); + half4 specularGloss = half4(0, 0, 0, 1); + if (UseSpecGlossMap()) + specularGloss = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_SpecGlossMap), particleParams.uv, particleParams.blendUv); + else if (UseSpecularColor()) + specularGloss = _SpecColor; + if (UseGlossinessFromBaseAlpha()) + specularGloss.a = albedo.a; outSurfaceData.specular = specularGloss.rgb; outSurfaceData.smoothness = specularGloss.a; @@ -105,7 +125,7 @@ VaryingsParticle ParticlesLitGBufferVertex(AttributesParticle input) VertexNormalInputs normalInput = GetParticleVertexNormalInputs(input.normalOS, input.tangentOS); half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); @@ -135,8 +155,8 @@ VaryingsParticle ParticlesLitGBufferVertex(AttributesParticle input) output.projectedPosition = vertexInput.positionNDC; #endif -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -157,7 +177,7 @@ GBufferFragOutput ParticlesLitGBufferFragment(VaryingsParticle input) URP_LIGHT_ACCUM4 color = URP_LIGHT_ACCUM4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha); - return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb)); + return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb), ReceiveShadows()); } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl new file mode 100644 index 00000000000..e3071013908 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl @@ -0,0 +1,104 @@ +#ifndef UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_DEPRECATED_INCLUDED +#define UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl" + +// Deprecated keyword-reading helpers, kept for external back-compat. +// New code passes the keyword state as parameters (ParticlesSimpleLitInput.hlsl). + +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap, bool alphaPremultiplyEnabled); +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params, bool alphaPremultiplyEnabled); +half4 BlendTexture(UnityTexture2D _Texture, float2 uv, float3 blendUv); + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +#if !defined(_SPECGLOSSMAP_KEYWORD_DECLARED) + #if !defined(_SPECGLOSSMAP) + #define _SPECGLOSSMAP 0 + #define _SPECGLOSSMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECGLOSSMAP) + #undef _SPECGLOSSMAP + #define _SPECGLOSSMAP 1 + #endif +#endif + +#if !defined(_SPECULAR_COLOR_KEYWORD_DECLARED) + #if !defined(_SPECULAR_COLOR) + #define _SPECULAR_COLOR 0 + #define _SPECULAR_COLOR_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_COLOR) + #undef _SPECULAR_COLOR + #define _SPECULAR_COLOR 1 + #endif +#endif + +#if !defined(_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED) + #if !defined(_GLOSSINESS_FROM_BASE_ALPHA) + #define _GLOSSINESS_FROM_BASE_ALPHA 0 + #define _GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_GLOSSINESS_FROM_BASE_ALPHA) + #undef _GLOSSINESS_FROM_BASE_ALPHA + #define _GLOSSINESS_FROM_BASE_ALPHA 1 + #endif +#endif + +// Deprecated. Use SampleAlbedo(..., alphaPremultiplyEnabled). +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap) +{ + return SampleAlbedo(uv, blendUv, color, particleColor, projectedPosition, albedoMap, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Use SampleAlbedo(albedoMap, params, alphaPremultiplyEnabled). +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) +{ + return SampleAlbedo(albedoMap, params, _ALPHAPREMULTIPLY_ON); +} + +// Deprecated. Sample the specular gloss data at the call site; the caller knows the keyword state. +half4 SampleSpecularSmoothness(float2 uv, float3 blendUv, half alpha, half4 specColor, UnityTexture2D specGlossMap) +{ + half4 specularGloss = half4(0, 0, 0, 1); + if (_SPECGLOSSMAP) + specularGloss = BlendTexture(specGlossMap, uv, blendUv); + else if (_SPECULAR_COLOR) + specularGloss = specColor; + + if (_GLOSSINESS_FROM_BASE_ALPHA) + specularGloss.a = alpha; + + return specularGloss; +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#if defined(_SPECGLOSSMAP_DEFINED_LOCALLY) + #undef _SPECGLOSSMAP_DEFINED_LOCALLY + #undef _SPECGLOSSMAP +#endif + +#if defined(_SPECULAR_COLOR_DEFINED_LOCALLY) + #undef _SPECULAR_COLOR_DEFINED_LOCALLY + #undef _SPECULAR_COLOR +#endif + +#if defined(_GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY) + #undef _GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY + #undef _GLOSSINESS_FROM_BASE_ALPHA +#endif + +#endif // UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl.meta new file mode 100644 index 00000000000..840ab47f871 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1db191e79910a47018911b339d7f4dd0 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl index 99394d5409c..fc958a64398 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl @@ -2,8 +2,22 @@ #define UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.deprecated.hlsl" + +TEXTURE2D(_BaseMap); +SAMPLER(sampler_BaseMap); +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); +TEXTURE2D(_EmissionMap); +SAMPLER(sampler_EmissionMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -22,7 +36,9 @@ CBUFFER_START(UnityPerMaterial) half _Blend; CBUFFER_END -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +// TODO: This include hierarchy is a mess, includes should go at the top of a file +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); @@ -34,7 +50,7 @@ TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); #define _BumpScale 1.0 -half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap) +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap, bool useAlphaPremultiply) { half4 albedo = BlendTexture(albedoMap, uv, blendUv) * color; @@ -46,18 +62,18 @@ half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, albedo.a = AlphaDiscard(albedo.a, _Cutoff); - #if defined(_SOFTPARTICLES_ON) - ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition); - #endif +#if defined(_SOFTPARTICLES_ON) + MulAlbedo(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition)), useAlphaPremultiply); +#endif - #if defined(_FADING_ON) - ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition); - #endif +#if defined(_FADING_ON) + MulAlbedo(albedo, CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition), useAlphaPremultiply); +#endif return albedo; } -half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params, bool useAlphaPremultiply) { half4 albedo = BlendTexture(albedoMap, params.uv, params.blendUv) * params.baseColor; @@ -69,31 +85,15 @@ half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) albedo.a = AlphaDiscard(albedo.a, _Cutoff); - #if defined(_SOFTPARTICLES_ON) - ALBEDO_MUL *= SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params); - #endif + #if defined(_SOFTPARTICLES_ON) + MulAlbedo(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params)), useAlphaPremultiply); + #endif - #if defined(_FADING_ON) - ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition); - #endif + #if defined(_FADING_ON) + MulAlbedo(albedo, CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition), useAlphaPremultiply); + #endif return albedo; } -half4 SampleSpecularSmoothness(float2 uv, float3 blendUv, half alpha, half4 specColor, UnityTexture2D specGlossMap) -{ - half4 specularGloss = half4(0, 0, 0, 1); -#ifdef _SPECGLOSSMAP - specularGloss = BlendTexture(specGlossMap, uv, blendUv); -#elif defined(_SPECULAR_COLOR) - specularGloss = specColor; -#endif - -#ifdef _GLOSSINESS_FROM_BASE_ALPHA - specularGloss.a = alpha; -#endif - - return specularGloss; -} - #endif // UNIVERSAL_PARTICLES_SIMPLE_LIT_INPUT_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl new file mode 100644 index 00000000000..be0bf2fa392 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl @@ -0,0 +1,9 @@ +#ifndef UNIVERSAL_PARTICLES_UNLIT_FEATURES_INCLUDED +#define UNIVERSAL_PARTICLES_UNLIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the ParticlesUnlit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" + +#endif // UNIVERSAL_PARTICLES_UNLIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl.meta new file mode 100644 index 00000000000..d5d59304b94 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bfad3a442eb7e4745afe870d51c9cc90 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl index a5f4e05f618..5b30622da61 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl @@ -5,7 +5,8 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/VolumetricFog.hlsl" -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitFeatures.hlsl" void InitializeInputData(VaryingsParticle input, SurfaceData surfaceData, out InputData inputData) { @@ -14,23 +15,30 @@ void InitializeInputData(VaryingsParticle input, SurfaceData surfaceData, out In inputData.positionWS = input.positionWS.xyz; -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); - inputData.normalWS = TransformTangentToWorld(surfaceData.normalTS, inputData.tangentToWorld); + if (UseNormalMap()) + { + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(surfaceData.normalTS, inputData.tangentToWorld); + } + else + { + inputData.normalWS = input.normalWS.xyz; + } #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; inputData.vertexLighting = 0; -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) +#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) inputData.bakedGI = SAMPLE_GI(input.vertexSH, GetAbsolutePositionWS(inputData.positionWS), inputData.normalWS, @@ -57,18 +65,16 @@ void InitializeInputData(VaryingsParticle input, SurfaceData surfaceData, out In void InitializeSurfaceData(ParticleParams particleParams, out SurfaceData surfaceData) { surfaceData = (SurfaceData)0; - half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), particleParams); - half3 normalTS = SampleNormalTS(particleParams.uv, particleParams.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap)); + half4 albedo = SampleAlbedo(UnityBuildTexture2DStructNoScaleNoTexelSize(_BaseMap), particleParams, UseAlphaPremultiply(), UseAlphaModulate()); + half3 normalTS = half3(0.0, 0.0, 1.0); + if (UseNormalMap()) + normalTS = SampleParticleNormalTS(particleParams.uv, particleParams.blendUv, UnityBuildTexture2DStructNoScaleNoTexelSize(_BumpMap), half(1.0)); #if defined (_DISTORTION_ON) albedo.rgb = Distortion(albedo, normalTS, _DistortionStrengthScaled, _DistortionBlend, particleParams.projectedPosition); #endif - #if defined(_EMISSION) - half3 emission = BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb; - #else - const half3 emission = 0; - #endif + half3 emission = UseEmission() ? BlendTexture(UnityBuildTexture2DStructNoScaleNoTexelSize(_EmissionMap), particleParams.uv, particleParams.blendUv).rgb * _EmissionColor.rgb : half3(0, 0, 0); surfaceData.albedo = albedo.rgb; surfaceData.specular = 0; @@ -109,7 +115,7 @@ VaryingsParticle vertParticleUnlit(AttributesParticle input) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); -#ifdef _NORMALMAP +#if FEATURES_NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); @@ -151,15 +157,17 @@ half4 fragParticleUnlit(VaryingsParticle input) : SV_Target half4 finalColor = UniversalFragmentUnlit(inputData, surfaceData); - #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) + if (ScreenSpaceOcclusionAvailable() && !IsSurfaceTypeTransparent()) + { float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, IsSurfaceTypeTransparent()); finalColor.rgb *= aoFactor.directAmbientOcclusion; - #endif + } finalColor.rgb = ClampExposed(BlendDistanceFogExposed(finalColor.rgb, input.clipPos, inputData.preExposureMultiplier)); - #if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, _Blend, input.clipPos); + #if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, _Blend, UseAlphaPremultiply(), input.clipPos); #endif finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent()); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl new file mode 100644 index 00000000000..93dd559844c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl @@ -0,0 +1,58 @@ +#ifndef UNIVERSAL_PARTICLES_UNLIT_INPUT_DEPRECATED_INCLUDED +#define UNIVERSAL_PARTICLES_UNLIT_INPUT_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticleParams.hlsl" + +// Deprecated keyword-reading wrappers, kept for external back-compat. +// New code passes the keyword state as parameters (ParticlesUnlitInput.hlsl). + +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap, bool alphaPremultiplyEnabled, bool alphaModulateEnabled); +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params, bool alphaPremultiplyEnabled, bool alphaModulateEnabled); + +#if !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAPREMULTIPLY_ON) + #define _ALPHAPREMULTIPLY_ON 0 + #define _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef _ALPHAPREMULTIPLY_ON + #define _ALPHAPREMULTIPLY_ON 1 + #endif +#endif + +#if !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAMODULATE_ON) + #define _ALPHAMODULATE_ON 0 + #define _ALPHAMODULATE_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef _ALPHAMODULATE_ON + #define _ALPHAMODULATE_ON 1 + #endif +#endif + +// Deprecated. Use SampleAlbedo(..., alphaPremultiplyEnabled, alphaModulateEnabled). +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap) +{ + return SampleAlbedo(uv, blendUv, color, particleColor, projectedPosition, albedoMap, _ALPHAPREMULTIPLY_ON, _ALPHAMODULATE_ON); +} + +// Deprecated. Use SampleAlbedo(albedoMap, params, alphaPremultiplyEnabled, alphaModulateEnabled). +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) +{ + return SampleAlbedo(albedoMap, params, _ALPHAPREMULTIPLY_ON, _ALPHAMODULATE_ON); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY) + #undef _ALPHAPREMULTIPLY_ON_DEFINED_LOCALLY + #undef _ALPHAPREMULTIPLY_ON +#endif + +#if defined(_ALPHAMODULATE_ON_DEFINED_LOCALLY) + #undef _ALPHAMODULATE_ON_DEFINED_LOCALLY + #undef _ALPHAMODULATE_ON +#endif + +#endif // UNIVERSAL_PARTICLES_UNLIT_INPUT_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl.meta new file mode 100644 index 00000000000..54c953fd8b1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3d5b7fc5c64494acdba8e4d879b515d2 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl index 8b3744c3da7..93303a82411 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl @@ -2,8 +2,23 @@ #define UNIVERSAL_PARTICLES_UNLIT_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.deprecated.hlsl" + +TEXTURE2D(_BaseMap); +SAMPLER(sampler_BaseMap); +TEXTURE2D(_BumpMap); +SAMPLER(sampler_BumpMap); +TEXTURE2D(_EmissionMap); +SAMPLER(sampler_EmissionMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); + +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -20,7 +35,7 @@ CBUFFER_START(UnityPerMaterial) half _Blend; CBUFFER_END -#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/Particles.hlsl" #define SOFT_PARTICLE_NEAR_FADE _SoftParticleFadeParams.x #define SOFT_PARTICLE_INV_FADE_DISTANCE _SoftParticleFadeParams.y @@ -30,7 +45,7 @@ CBUFFER_END #define _BumpScale 1.0 -half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap) +half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, float4 projectedPosition, UnityTexture2D albedoMap, bool useAlphaPremultiply, bool useAlphaModulate) { half4 albedo = BlendTexture(albedoMap, uv, blendUv) * color; @@ -43,20 +58,21 @@ half4 SampleAlbedo(float2 uv, float3 blendUv, half4 color, float4 particleColor, albedo.a = AlphaDiscard(albedo.a, _Cutoff); - albedo.rgb = AlphaModulateAndPremultiply(albedo.rgb, albedo.a); + if (useAlphaModulate || useAlphaPremultiply) + albedo.rgb = AlphaModulateAndPremultiply(albedo.rgb, albedo.a, useAlphaModulate); #if defined(_SOFTPARTICLES_ON) - albedo = SOFT_PARTICLE_MUL_ALBEDO(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition))); + SoftParticleMulAlbedo(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, projectedPosition)), useAlphaPremultiply, useAlphaModulate); #endif - #if defined(_FADING_ON) - ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition); - #endif +#if defined(_FADING_ON) + MulAlbedo(albedo, CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, projectedPosition), useAlphaPremultiply); +#endif return albedo; } -half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) +half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params, bool useAlphaPremultiply, bool useAlphaModulate) { half4 albedo = BlendTexture(albedoMap, params.uv, params.blendUv) * params.baseColor; @@ -69,14 +85,15 @@ half4 SampleAlbedo(UnityTexture2D albedoMap, ParticleParams params) albedo = MixParticleColor(albedo, half4(params.vertexColor), colorAddSubDiff); albedo.a = AlphaDiscard(albedo.a, _Cutoff); - albedo.rgb = AlphaModulateAndPremultiply(albedo.rgb, albedo.a); + if (useAlphaModulate || useAlphaPremultiply) + albedo.rgb = AlphaModulateAndPremultiply(albedo.rgb, albedo.a, useAlphaModulate); #if defined(_SOFTPARTICLES_ON) - albedo = SOFT_PARTICLE_MUL_ALBEDO(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params))); + SoftParticleMulAlbedo(albedo, half(SoftParticles(SOFT_PARTICLE_NEAR_FADE, SOFT_PARTICLE_INV_FADE_DISTANCE, params)), useAlphaPremultiply, useAlphaModulate); #endif #if defined(_FADING_ON) - ALBEDO_MUL *= CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition); + MulAlbedo(albedo, CameraFade(CAMERA_NEAR_FADE, CAMERA_INV_FADE_DISTANCE, params.projectedPosition), useAlphaPremultiply); #endif return albedo; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl index 1414b0febf1..1030710b711 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl @@ -3,9 +3,9 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" // Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs // For Directional lights, _LightDirection is used when applying shadow Normal Bias. @@ -65,12 +65,11 @@ half4 ShadowPassFragment(Varyings input) : SV_TARGET UNITY_SETUP_INSTANCE_ID(input); #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + AlphaDiscard((UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) ? _BaseColor.a : albedoAlpha * _BaseColor.a, _Cutoff); #endif - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif + LODFadeCrossFade(input.positionCS); return 0; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader index b0fb55d3821..f5ebe599356 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader @@ -107,21 +107,21 @@ Shader "Universal Render Pipeline/Simple Lit" #pragma multi_compile _ META_QUEST_LIGHTUNROLL #endif #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) #pragma multi_compile _ META_QUEST_ORTHO_PROJ #pragma multi_compile _ META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP #endif #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS - #pragma multi_compile_fragment _ _SHADOWS_SOFT - #pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH + #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _SCREEN_SPACE_IRRADIANCE #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 @@ -250,8 +250,7 @@ Shader "Universal Render Pipeline/Simple Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN //#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS //#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS - #pragma multi_compile_fragment _ _SHADOWS_SOFT - #pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH + #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE @@ -405,7 +404,6 @@ Shader "Universal Render Pipeline/Simple Lit" // ------------------------------------- // Material Keywords - #pragma shader_feature_local_fragment _SPECGLOSSMAP #pragma shader_feature EDITOR_VISUALIZATION // Required for SampleEmission to sample the emission; GI extraction gates emission @@ -441,7 +439,7 @@ Shader "Universal Render Pipeline/Simple Lit" // ------------------------------------- // Material Keywords #pragma shader_feature_local_fragment _ALPHATEST_ON - #pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON + #pragma shader_feature_local_fragment _ _ALPHAPREMULTIPLY_ON // ------------------------------------- // Includes @@ -462,7 +460,7 @@ Shader "Universal Render Pipeline/Simple Lit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -489,7 +487,7 @@ Shader "Universal Render Pipeline/Simple Lit" #define APPLICATION_SPACE_WARP_MOTION 1 #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitDepthNormalsPass.hlsl index ccf6ee50910..5f4fe5a7c5c 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitDepthNormalsPass.hlsl @@ -1,13 +1,17 @@ #ifndef UNIVERSAL_SIMPLE_LIT_DEPTH_NORMALS_PASS_INCLUDED #define UNIVERSAL_SIMPLE_LIT_DEPTH_NORMALS_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl" + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 +#endif -#if defined(_ALPHATEST_ON) || defined(_NORMALMAP) +#if defined(_ALPHATEST_ON) || FEATURES_NORMALMAP #define REQUIRES_UV_INTERPOLATOR #endif @@ -28,7 +32,7 @@ struct Varyings float2 uv : TEXCOORD1; #endif - #ifdef _NORMALMAP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z @@ -57,7 +61,7 @@ Varyings DepthNormalsVertex(Attributes input) VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); VertexNormalInputs normalInput = GetVertexNormalInputs(input.normal, input.tangentOS); - #if defined(_NORMALMAP) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); @@ -81,21 +85,23 @@ void DepthNormalsFragment( UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + AlphaDiscard((UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) ? _BaseColor.a : albedoAlpha * _BaseColor.a, _Cutoff); #endif - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif + LODFadeCrossFade(input.positionCS); - #if defined(_NORMALMAP) - half3 normalTS = SampleNormal(input.uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); - half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + half3 normalWS; + if (UseNormalMap()) + normalWS = TransformTangentToWorld(SampleNormal(input.uv), half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); + else + normalWS = input.normalWS.xyz; #else half3 normalWS = input.normalWS; #endif - outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS)), 0.0); + outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS, UseNormalMap())), 0.0); #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl new file mode 100644 index 00000000000..99af4d6c683 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl @@ -0,0 +1,12 @@ +#ifndef UNIVERSAL_SIMPLE_LIT_FEATURES_INCLUDED +#define UNIVERSAL_SIMPLE_LIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the SimpleLit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" + +#endif // UNIVERSAL_SIMPLE_LIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl.meta new file mode 100644 index 00000000000..2855f698d88 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 63c4acc2c1f394906834d84aac11a344 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl index 11b01f52d6a..5007fec05a0 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl @@ -4,8 +4,18 @@ #include "SimpleLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif struct Attributes @@ -25,7 +35,7 @@ struct Varyings float3 positionWS : TEXCOORD1; // xyz: posWS - #ifdef _NORMALMAP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z @@ -39,18 +49,22 @@ struct Varyings half fogFactor : TEXCOORD5; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD6; #endif - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 7); - -#ifdef DYNAMICLIGHTMAP_ON - float2 dynamicLightmapUV : TEXCOORD8; // Dynamic lightmap UVs +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; +#endif +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + float2 dynamicLightmapUV : DYNLIGHTMAPUV; #endif #ifdef USE_APV_PROBE_OCCLUSION - float4 probeOcclusion : TEXCOORD9; + float4 probeOcclusion : PROBEOCCLUSION; #endif float4 positionCS : SV_POSITION; @@ -67,26 +81,31 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.positionCS = input.positionCS; #endif - #ifdef _NORMALMAP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); - inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + if (UseNormalMap()) + { + inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); + } + else + { + inputData.normalWS = input.normalWS.xyz; + } #else half3 viewDirWS = GetWorldSpaceNormalizeViewDir(inputData.positionWS); inputData.normalWS = input.normalWS; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif #ifdef _ADDITIONAL_LIGHTS_VERTEX @@ -98,12 +117,13 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) - inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy; + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + inputData.dynamicLightmapUV = input.dynamicLightmapUV; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.vertexSH; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -116,23 +136,28 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - input.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = input.positionCS.xy; + giParams.isSurfaceTypeTransparent = IsSurfaceTypeTransparent(); + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } /////////////////////////////////////////////////////////////////////////////// @@ -157,7 +182,7 @@ Varyings LitPassVertexSimple(Attributes input) output.positionWS.xyz = vertexInput.positionWS; output.positionCS = vertexInput.positionCS; -#ifdef _NORMALMAP +#if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half3 viewDirWS = GetWorldSpaceViewDir(vertexInput.positionWS); output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); @@ -166,11 +191,19 @@ Varyings LitPassVertexSimple(Attributes input) output.normalWS = NormalizeNormalPerVertex(normalInput.normalWS); #endif - OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV); -#ifdef DYNAMICLIGHTMAP_ON - output.dynamicLightmapUV = input.dynamicLightmapUV.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; +#if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = TransformLightmapUV(input.staticLightmapUV.xy, unity_LightmapST); +#endif +#if USE_VERTEX_SH_INTERPOLATOR + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + output.dynamicLightmapUV = TransformLightmapUV(input.dynamicLightmapUV.xy, unity_DynamicLightmapST); #endif - OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); #ifdef _ADDITIONAL_LIGHTS_VERTEX URP_LIGHT_ACCUM3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS); @@ -179,8 +212,8 @@ Varyings LitPassVertexSimple(Attributes input) output.fogFactor = fogFactor; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -199,26 +232,30 @@ void LitPassFragmentSimple( UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); SurfaceData surfaceData; - InitializeSimpleLitSurfaceData(input.uv, surfaceData); + InitializeSimpleLitSurfaceData(input.uv, surfaceData, + UseSpecGlossMap(), UseSpecularColor(), UseGlossinessFromBaseAlpha(), + UseAlphaModulate(), UseNormalMap(), UseEmission()); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv, _BaseMap)); #if defined(_DBUFFER) - ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData); + if (!IsSurfaceTypeTransparent()) + ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData, IsSpecularSetup()); #endif InitializeBakedGIData(input, inputData); - URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, surfaceData); + URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, surfaceData, + UseSpecGlossMap() || UseSpecularColor(), UseAlphaPremultiply(), + ReceiveShadows(), IsSurfaceTypeTransparent()); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.positionCS)); -#if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, input.positionCS); +#if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + color.rgb = MixVolumetricFog(color.rgb, color.a, _Blend, UseAlphaPremultiply(), input.positionCS); #endif color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl index 980b1784e76..1a32db51031 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl @@ -1,10 +1,21 @@ #ifndef UNIVERSAL_SIMPLELIT_GBUFFER_PASS_INCLUDED #define UNIVERSAL_SIMPLELIT_GBUFFER_PASS_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl" + +// Realtime shadows are never sampled when Receive Shadows is off at compile time; +// drop the vertex shadow-coord interpolator. +#if _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #undef USE_VERTEX_SHADOW_COORD_INTERPOLATOR + #define USE_VERTEX_SHADOW_COORD_INTERPOLATOR 0 +#endif + +#if FEATURES_NORMALMAP +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 #endif // keep this file in sync with LitForwardPass.hlsl @@ -26,7 +37,7 @@ struct Varyings float3 posWS : TEXCOORD1; // xyz: posWS - #ifdef _NORMALMAP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normal : TEXCOORD2; // xyz: normal, w: viewDir.x half4 tangent : TEXCOORD3; // xyz: tangent, w: viewDir.y half4 bitangent : TEXCOORD4; // xyz: bitangent, w: viewDir.z @@ -38,17 +49,22 @@ struct Varyings URP_LIGHT_ACCUM3 vertexLighting : TEXCOORD5; // xyz: vertex light #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD6; #endif - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 7); -#ifdef DYNAMICLIGHTMAP_ON - float2 dynamicLightmapUV : TEXCOORD8; // Dynamic lightmap UVs +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; +#endif +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + float2 dynamicLightmapUV : DYNLIGHTMAPUV; #endif #ifdef USE_APV_PROBE_OCCLUSION - float4 probeOcclusion : TEXCOORD9; + float4 probeOcclusion : PROBEOCCLUSION; #endif float4 positionCS : SV_POSITION; @@ -63,25 +79,30 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.positionWS = input.posWS; inputData.positionCS = input.positionCS; - #ifdef _NORMALMAP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half3 viewDirWS = half3(input.normal.w, input.tangent.w, input.bitangent.w); - inputData.normalWS = TransformTangentToWorld(normalTS,half3x3(input.tangent.xyz, input.bitangent.xyz, input.normal.xyz)); + if (UseNormalMap()) + { + inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangent.xyz, input.bitangent.xyz, input.normal.xyz)); + } + else + { + inputData.normalWS = input.normal.xyz; + } #else half3 viewDirWS = GetWorldSpaceNormalizeViewDir(inputData.positionWS); inputData.normalWS = input.normal; #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif #ifdef _ADDITIONAL_LIGHTS_VERTEX @@ -94,12 +115,13 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = input.dynamicLightmapUV; #endif - #if defined(LIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.staticLightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.vertexSH; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -112,23 +134,28 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#endif + GIParams giParams = (GIParams)0; + + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = input.dynamicLightmapUV; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + giParams.isSurfaceTypeTransparent = IsSurfaceTypeTransparent(); + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } /////////////////////////////////////////////////////////////////////////////// @@ -151,7 +178,7 @@ Varyings LitPassVertexSimple(Attributes input) output.posWS.xyz = vertexInput.positionWS; output.positionCS = vertexInput.positionCS; - #ifdef _NORMALMAP + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS); output.normal = half4(normalInput.normalWS, viewDirWS.x); output.tangent = half4(normalInput.tangentWS, viewDirWS.y); @@ -160,19 +187,27 @@ Varyings LitPassVertexSimple(Attributes input) output.normal = NormalizeNormalPerVertex(normalInput.normalWS); #endif - OUTPUT_LIGHTMAP_UV(input.staticLightmapUV, unity_LightmapST, output.staticLightmapUV); -#ifdef DYNAMICLIGHTMAP_ON - output.dynamicLightmapUV = input.dynamicLightmapUV.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; +#if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = TransformLightmapUV(input.staticLightmapUV.xy, unity_LightmapST); +#endif +#if USE_VERTEX_SH_INTERPOLATOR + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif +#endif +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + output.dynamicLightmapUV = TransformLightmapUV(input.dynamicLightmapUV.xy, unity_DynamicLightmapST); #endif - OUTPUT_SH4(vertexInput.positionWS, output.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); #ifdef _ADDITIONAL_LIGHTS_VERTEX URP_LIGHT_ACCUM3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS); output.vertexLighting = vertexLight; #endif - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.shadowCoord = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return output; @@ -185,27 +220,27 @@ GBufferFragOutput LitPassFragmentSimple(Varyings input) UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); SurfaceData surfaceData; - InitializeSimpleLitSurfaceData(input.uv, surfaceData); + InitializeSimpleLitSurfaceData(input.uv, surfaceData, + UseSpecGlossMap(), UseSpecularColor(), UseGlossinessFromBaseAlpha(), + UseAlphaModulate(), UseNormalMap(), UseEmission()); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv, _BaseMap)); #if defined(_DBUFFER) - ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData); + ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData, IsSpecularSetup()); #endif InitializeBakedGIData(input, inputData); - Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask, ReceiveShadows(), IsSurfaceTypeTransparent()); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); URP_LIGHT_ACCUM4 color = URP_LIGHT_ACCUM4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha); - return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb)); + return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb), ReceiveShadows()); }; #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl new file mode 100644 index 00000000000..01b9e370a9c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl @@ -0,0 +1,130 @@ +#ifndef UNIVERSAL_SIMPLE_LIT_INPUT_DEPRECATED_INCLUDED +#define UNIVERSAL_SIMPLE_LIT_INPUT_DEPRECATED_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" + +// Deprecated keyword-reading helpers, kept for external back-compat. +// New code passes the keyword state to InitializeSimpleLitSurfaceData as parameters (SimpleLitInput.hlsl). + +// Trunk's SimpleLitInput.hlsl transitively provided the SurfaceInput helpers (Alpha, +// SampleAlbedoAlpha, SampleNormal, SampleEmission); custom shaders built on copies of +// SimpleLitInput rely on them. +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInputFunctions.deprecated.hlsl" + +void InitializeSimpleLitSurfaceData(float2 uv, out SurfaceData outSurfaceData, bool specGlossMap, bool specularColor, bool glossinessFromBaseAlpha, bool alphaModulateEnabled, bool normalMap, bool emission); + +#if !defined(_SPECGLOSSMAP_KEYWORD_DECLARED) + #if !defined(_SPECGLOSSMAP) + #define _SPECGLOSSMAP 0 + #define _SPECGLOSSMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECGLOSSMAP) + #undef _SPECGLOSSMAP + #define _SPECGLOSSMAP 1 + #endif +#endif + +#if !defined(_SPECULAR_COLOR_KEYWORD_DECLARED) + #if !defined(_SPECULAR_COLOR) + #define _SPECULAR_COLOR 0 + #define _SPECULAR_COLOR_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_SPECULAR_COLOR) + #undef _SPECULAR_COLOR + #define _SPECULAR_COLOR 1 + #endif +#endif + +#if !defined(_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED) + #if !defined(_GLOSSINESS_FROM_BASE_ALPHA) + #define _GLOSSINESS_FROM_BASE_ALPHA 0 + #define _GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_GLOSSINESS_FROM_BASE_ALPHA) + #undef _GLOSSINESS_FROM_BASE_ALPHA + #define _GLOSSINESS_FROM_BASE_ALPHA 1 + #endif +#endif + +#if !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + #if !defined(_ALPHAMODULATE_ON) + #define _ALPHAMODULATE_ON 0 + #define _ALPHAMODULATE_ON_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef _ALPHAMODULATE_ON + #define _ALPHAMODULATE_ON 1 + #endif +#endif + +#if !defined(_NORMALMAP_KEYWORD_DECLARED) + #if !defined(_NORMALMAP) + #define _NORMALMAP 0 + #define _NORMALMAP_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_NORMALMAP) + #undef _NORMALMAP + #define _NORMALMAP 1 + #endif +#endif + +#if !defined(_EMISSION_KEYWORD_DECLARED) + #if !defined(_EMISSION) + #define _EMISSION 0 + #define _EMISSION_DEFINED_LOCALLY 1 + #elif DEFINED_NONZERO(_EMISSION) + #undef _EMISSION + #define _EMISSION 1 + #endif +#endif + +// Deprecated. Sample the specular map and apply the smoothness source at the call site instead. +half4 SampleSpecularSmoothness(float2 uv, half alpha, half4 specColor, TEXTURE2D_PARAM(specMap, sampler_specMap)) +{ + half4 specularSmoothness = half4(0, 0, 0, 1); + if (_SPECGLOSSMAP) + specularSmoothness = SAMPLE_TEXTURE2D(specMap, sampler_specMap, uv) * specColor; + else if (_SPECULAR_COLOR) + specularSmoothness = specColor; + + if (_GLOSSINESS_FROM_BASE_ALPHA) + specularSmoothness.a = alpha; + + return specularSmoothness; +} + +// Deprecated. Use InitializeSimpleLitSurfaceData(..., specGlossMap, specularColor, glossinessFromBaseAlpha, alphaModulateEnabled, normalMap, emission). +inline void InitializeSimpleLitSurfaceData(float2 uv, out SurfaceData outSurfaceData) +{ + InitializeSimpleLitSurfaceData(uv, outSurfaceData, _SPECGLOSSMAP, _SPECULAR_COLOR, _GLOSSINESS_FROM_BASE_ALPHA, _ALPHAMODULATE_ON, _NORMALMAP, _EMISSION); +} + +// Prevents leaking the fallback keyword definitions to shaders that include this file. +#if defined(_SPECGLOSSMAP_DEFINED_LOCALLY) + #undef _SPECGLOSSMAP_DEFINED_LOCALLY + #undef _SPECGLOSSMAP +#endif + +#if defined(_SPECULAR_COLOR_DEFINED_LOCALLY) + #undef _SPECULAR_COLOR_DEFINED_LOCALLY + #undef _SPECULAR_COLOR +#endif + +#if defined(_GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY) + #undef _GLOSSINESS_FROM_BASE_ALPHA_DEFINED_LOCALLY + #undef _GLOSSINESS_FROM_BASE_ALPHA +#endif + +#if defined(_ALPHAMODULATE_ON_DEFINED_LOCALLY) + #undef _ALPHAMODULATE_ON_DEFINED_LOCALLY + #undef _ALPHAMODULATE_ON +#endif + +#if defined(_NORMALMAP_DEFINED_LOCALLY) + #undef _NORMALMAP_DEFINED_LOCALLY + #undef _NORMALMAP +#endif + +#if defined(_EMISSION_DEFINED_LOCALLY) + #undef _EMISSION_DEFINED_LOCALLY + #undef _EMISSION +#endif + +#endif // UNIVERSAL_SIMPLE_LIT_INPUT_DEPRECATED_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl.meta new file mode 100644 index 00000000000..f297541ec40 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c322299d0b4794980b8770f03f282c5c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl index cd86e6d6a87..2a50aaa8133 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl @@ -2,9 +2,14 @@ #define UNIVERSAL_SIMPLE_LIT_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.deprecated.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; @@ -52,42 +57,47 @@ void SetupDOTSSimpleLitMaterialPropertyCaches() #endif +TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); +TEXTURE2D(_BumpMap); SAMPLER(sampler_BumpMap); +TEXTURE2D(_EmissionMap); SAMPLER(sampler_EmissionMap); TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); -half4 SampleSpecularSmoothness(float2 uv, half alpha, half4 specColor, TEXTURE2D_PARAM(specMap, sampler_specMap)) -{ - half4 specularSmoothness = half4(0, 0, 0, 1); -#ifdef _SPECGLOSSMAP - specularSmoothness = SAMPLE_TEXTURE2D(specMap, sampler_specMap, uv) * specColor; -#elif defined(_SPECULAR_COLOR) - specularSmoothness = specColor; -#endif +half4 GetEmissionColor() { return _EmissionColor; } +half GetBumpScale() { return half(1.0); } -#ifdef _GLOSSINESS_FROM_BASE_ALPHA - specularSmoothness.a = alpha; -#endif +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } +half4 SampleBumpMap(float2 uv) { return SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv); } +half4 SampleEmissionMap(float2 uv) { return SAMPLE_TEXTURE2D(_EmissionMap, sampler_EmissionMap, uv); } +half4 SampleSpecGlossMap(float2 uv) { return SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv); } - return specularSmoothness; -} - -inline void InitializeSimpleLitSurfaceData(float2 uv, out SurfaceData outSurfaceData) +inline void InitializeSimpleLitSurfaceData(float2 uv, out SurfaceData outSurfaceData, bool useSpecGlossMap, bool useSpecularColor, bool useGlossinessFromBaseAlpha, bool useAlphaModulate, bool useNormalMap, bool useEmission) { outSurfaceData = (SurfaceData)0; - half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); + half4 albedoAlpha = SampleBaseMap(uv); outSurfaceData.alpha = albedoAlpha.a * _BaseColor.a; outSurfaceData.alpha = AlphaDiscard(outSurfaceData.alpha, _Cutoff); outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb; - outSurfaceData.albedo = AlphaModulate(outSurfaceData.albedo, outSurfaceData.alpha); + if (useAlphaModulate) + outSurfaceData.albedo = ApplyAlphaModulate(outSurfaceData.albedo, outSurfaceData.alpha); + + half4 specularSmoothness = half4(0, 0, 0, 1); + if (useSpecGlossMap) + specularSmoothness = SampleSpecGlossMap(uv) * _SpecColor; + else if (useSpecularColor) + specularSmoothness = _SpecColor; + + if (useGlossinessFromBaseAlpha) + specularSmoothness.a = outSurfaceData.alpha; - half4 specularSmoothness = SampleSpecularSmoothness(uv, outSurfaceData.alpha, _SpecColor, TEXTURE2D_ARGS(_SpecGlossMap, sampler_SpecGlossMap)); outSurfaceData.metallic = 0.0; // unused outSurfaceData.specular = specularSmoothness.rgb; outSurfaceData.smoothness = specularSmoothness.a; - outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); + outSurfaceData.normalTS = SampleNormal(uv, useNormalMap); outSurfaceData.occlusion = 1.0; - outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); + outSurfaceData.emission = SampleEmission(uv, useEmission); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl index f2c41d9f86c..9d23a713151 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitMetaPass.hlsl @@ -2,13 +2,14 @@ #define UNIVERSAL_SIMPLE_LIT_META_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UniversalMetaPass.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitFeatures.hlsl" half4 UniversalFragmentMetaSimple(Varyings input) : SV_Target { float2 uv = input.uv; MetaInput metaInput; - metaInput.Albedo = _BaseColor.rgb * SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv).rgb; - metaInput.Emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); + metaInput.Albedo = _BaseColor.rgb * SampleBaseMap(uv).rgb; + metaInput.Emission = SampleEmission(uv); return UniversalFragmentMeta(input, metaInput); } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader index e93ba43a8fc..5ea604b0e5c 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader @@ -21,7 +21,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile_vertex _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING @@ -30,7 +30,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" #pragma multi_compile_fragment _ _SCREEN_SPACE_IRRADIANCE #pragma multi_compile_fragment _ _LIGHT_COOKIES #pragma multi_compile_fragment _ _VOLUMETRIC_FOG - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_vertex _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Fog.hlsl" @@ -88,6 +88,8 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" + #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" + #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_ST; @@ -104,14 +106,22 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" struct Varyings { - float2 UV01 : TEXCOORD0; // UV0 - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 1); - half4 Color : TEXCOORD2; // Vertex Color - URP_LIGHT_ACCUM3 VertexLighting : TEXCOORD3; // Vertex Lighting - float4 ShadowCoords : TEXCOORD4; // Shadow UVs - half3 NormalWS : TEXCOORD5; // World Space Normal - float3 PositionWS : TEXCOORD6; - float4 PositionCS : SV_POSITION; // Clip Position + float2 UV01 : TEXCOORD0; // UV0 + #if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; + #endif + half4 Color : TEXCOORD2; // Vertex Color + URP_LIGHT_ACCUM3 VertexLighting : TEXCOORD3; // Vertex Lighting + float4 ShadowCoords : TEXCOORD4; // Shadow UVs + half3 NormalWS : TEXCOORD5; // World Space Normal + float3 PositionWS : TEXCOORD6; + #ifdef USE_APV_PROBE_OCCLUSION + float4 probeOcclusion : PROBEOCCLUSION; + #endif + float4 PositionCS : SV_POSITION; // Clip Position UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO @@ -127,18 +137,33 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" // Vertex attributes output.UV01 = TRANSFORM_TEX(input.UV0, _MainTex); - OUTPUT_LIGHTMAP_UV(input.UV1, unity_LightmapST, output.staticLightmapUV); + #if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = LightmapAvailable() ? TransformLightmapUV(input.UV1.xy, unity_LightmapST) : float2(0, 0); + #endif VertexPositionInputs vertexInput = GetVertexPositionInputs(input.PositionOS.xyz); output.Color = input.Color; output.PositionCS = vertexInput.positionCS; // Shadow Coords - output.ShadowCoords = GetShadowCoord(vertexInput); + output.ShadowCoords = GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()); // Vertex Lighting output.NormalWS = TransformObjectToWorldNormal(input.NormalOS).xyz; - OUTPUT_SH4(vertexInput.positionWS, output.NormalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, NOT_USED); + #if USE_VERTEX_SH_INTERPOLATOR + if (!LightmapAvailable()) + { + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.NormalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, output.NormalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif + } + else + { + output.vertexSH = half3(0, 0, 0); + } + #endif Light mainLight = GetMainLight(); half3 attenuatedLightColor = mainLight.color * mainLight.distanceAttenuation; @@ -165,19 +190,26 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); float preExposureMultiplier = GetPreExposureMultiplier(); -#if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - half3 bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(input.PositionWS), - input.NormalWS.xyz, - GetWorldSpaceNormalizeViewDir(input.PositionWS), - input.PositionCS.xy, - NOT_USED, - NOT_USED); -#else - half3 bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, input.NormalWS); -#endif - - URP_LIGHT_ACCUM3 lighting = input.VertexLighting * MainLightRealtimeShadow(input.ShadowCoords) + bakedGI; + GIParams giParams = (GIParams)0; + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + giParams.positionWS = input.PositionWS; + giParams.normalWS = input.NormalWS.xyz; + giParams.viewDirWS = GetWorldSpaceNormalizeViewDir(input.PositionWS); + giParams.positionSS = input.PositionCS.xy; + URP_LIGHT_ACCUM3 bakedGI; + half4 shadowMask; + InitializeBakedGI(giParams, bakedGI, shadowMask); + + half realtimeShadow = ReceiveShadows() ? SampleMainLightRealtimeShadow(input.ShadowCoords, IsSurfaceTypeTransparent()) : half(1.0); + URP_LIGHT_ACCUM3 lighting = input.VertexLighting * realtimeShadow + bakedGI; half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.UV01); URP_LIGHT_ACCUM4 color = 1.0; @@ -191,8 +223,9 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" inputData.preExposureMultiplier = preExposureMultiplier; inputData.normalWS = input.NormalWS; inputData.positionCS = input.PositionCS; + inputData.shadowMask = shadowMask; - return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb)); + return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb), ReceiveShadows()); } ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl index 90f7401332f..ea0fd9efa1b 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl @@ -4,6 +4,8 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" struct Attributes { @@ -18,10 +20,15 @@ struct Attributes struct Varyings { float2 UV01 : TEXCOORD0; // UV0 - DECLARE_LIGHTMAP_OR_SH(staticLightmapUV, vertexSH, 1); + #if USE_LIGHTMAP_UV_INTERPOLATOR + float2 staticLightmapUV : LIGHTMAPUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; + #endif half4 Color : TEXCOORD2; // Vertex Color URP_LIGHT_ACCUM3 VertexLighting : TEXCOORD3; // Vertex Lighting - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 ShadowCoords : TEXCOORD4; // Shadow UVs #endif half4 NormalWS : TEXCOORD5; @@ -44,32 +51,33 @@ void InitializeInputData(Varyings input, out InputData inputData) inputData.normalWS = half3(0, 1, 0); inputData.viewDirectionWS = half3(0, 0, 1); - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.ShadowCoords; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(input.PositionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.ShadowCoords : TransformWorldToShadowCoord(input.PositionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(input.PositionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.VertexLighting; inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.PositionCS); inputData.positionWS = input.PositionWS; -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy, input.NormalWS.xyz, GetInvPreExposureMultiplier()); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - input.NormalWS.xyz, - GetWorldSpaceNormalizeViewDir(inputData.positionWS), - inputData.positionCS.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, input.NormalWS.xyz); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); -#endif + { + GIParams giParams = (GIParams)0; + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.staticLightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + giParams.positionWS = inputData.positionWS; + giParams.normalWS = input.NormalWS.xyz; + giParams.viewDirWS = GetWorldSpaceNormalizeViewDir(inputData.positionWS); + giParams.positionSS = inputData.positionCS.xy; + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); + } #if defined(DEBUG_DISPLAY) inputData.uv = input.UV01; @@ -106,11 +114,7 @@ URP_LIGHT_ACCUM4 UniversalTerrainLit(InputData inputData, SurfaceData surfaceDat } #endif - #if defined(MAIN_LIGHT_CALCULATE_SHADOWS) - URP_LIGHT_ACCUM3 lighting = inputData.vertexLighting * MainLightRealtimeShadow(inputData.shadowCoord); - #else - URP_LIGHT_ACCUM3 lighting = inputData.vertexLighting; - #endif + URP_LIGHT_ACCUM3 lighting = ReceiveShadows() ? inputData.vertexLighting * SampleMainLightRealtimeShadow(inputData.shadowCoord, IsSurfaceTypeTransparent()) : inputData.vertexLighting; URP_LIGHT_ACCUM4 color = half4(surfaceData.albedo, surfaceData.alpha); if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION)) @@ -140,19 +144,34 @@ Varyings TerrainLitVertex(Attributes input) // Vertex attributes output.UV01 = TRANSFORM_TEX(input.UV0, _MainTex); - OUTPUT_LIGHTMAP_UV(input.UV1, unity_LightmapST, output.staticLightmapUV); + #if USE_LIGHTMAP_UV_INTERPOLATOR + output.staticLightmapUV = LightmapAvailable() ? TransformLightmapUV(input.UV1.xy, unity_LightmapST) : float2(0, 0); + #endif VertexPositionInputs vertexInput = GetVertexPositionInputs(input.PositionOS.xyz); output.Color = input.Color; output.PositionCS = vertexInput.positionCS; // Shadow Coords - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - output.ShadowCoords = GetShadowCoord(vertexInput); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + output.ShadowCoords = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif // Vertex Lighting half3 NormalWS = input.NormalOS; - OUTPUT_SH4(vertexInput.positionWS, NormalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion); + #if USE_VERTEX_SH_INTERPOLATOR + if (!LightmapAvailable()) + { + #ifdef USE_APV_PROBE_OCCLUSION + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, NormalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.probeOcclusion); + #else + output.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, NormalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif + } + else + { + output.vertexSH = half3(0, 0, 0); + } + #endif Light mainLight = GetMainLight(); half3 attenuatedLightColor = mainLight.color * mainLight.distanceAttenuation; URP_LIGHT_ACCUM3 diffuseColor = half3(0, 0, 0); @@ -198,6 +217,8 @@ half4 TerrainLitForwardFragment(Varyings input) : SV_Target return color; } +#ifdef TERRAIN_GBUFFER + GBufferFragOutput TerrainLitGBufferFragment(Varyings input) { UNITY_SETUP_INSTANCE_ID(input); @@ -211,5 +232,7 @@ GBufferFragOutput TerrainLitGBufferFragment(Varyings input) InitializeSurfaceData(tex.rgb, tex.a, surfaceData); URP_LIGHT_ACCUM4 color = UniversalTerrainLit(inputData, tex.rgb, tex.a); - return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb)); + return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb), ReceiveShadows()); } + +#endif 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 eabc8fee6d6..5cc55fc6c89 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader @@ -66,12 +66,13 @@ Shader "Universal Render Pipeline/Terrain/Lit" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) @@ -175,7 +176,7 @@ Shader "Universal Render Pipeline/Terrain/Lit" #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" 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 52412f65fc8..72ce52a0590 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader @@ -61,12 +61,13 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) #pragma multi_compile _ META_QUEST_ORTHO_PROJ @@ -146,7 +147,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" 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 8fe6faec5e7..427208e7ff9 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader @@ -39,12 +39,13 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) #pragma multi_compile _ META_QUEST_ORTHO_PROJ @@ -138,7 +139,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" //#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl index 2ba0622aa83..87f991a4784 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl @@ -2,7 +2,6 @@ #define UNIVERSAL_FORWARD_LIT_DEPTH_NORMALS_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" // DepthNormal pass struct AttributesDepthNormal @@ -21,7 +20,7 @@ struct VaryingsDepthNormal float4 uvSplat23 : TEXCOORD2; // xy: splat2, zw: splat3 #endif - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z @@ -52,16 +51,18 @@ VaryingsDepthNormal DepthNormalOnlyVertex(AttributesDepthNormal v) o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3); #endif - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(attributes.positionWS); - float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0); - VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, vertexTangent); - - o.normal = half4(normalInput.normalWS, viewDirWS.x); - o.tangent = half4(normalInput.tangentWS, viewDirWS.y); - o.bitangent = half4(normalInput.bitangentWS, viewDirWS.z); - #else - o.normal = TransformObjectToWorldNormal(v.normalOS); + o.normal.xyz = TransformObjectToWorldNormal(v.normalOS); + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + half3 viewDirWS = GetWorldSpaceNormalizeViewDir(attributes.positionWS); + float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0); + VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, vertexTangent); + + o.normal = half4(normalInput.normalWS, viewDirWS.x); + o.tangent = half4(normalInput.tangentWS, viewDirWS.y); + o.bitangent = half4(normalInput.bitangentWS, viewDirWS.z); + } #endif o.clipPos = attributes.positionCS; @@ -86,19 +87,20 @@ void DepthNormalOnlyFragment( half3 normalTS = half3(0.0h, 0.0h, 1.0h); NormalMapMix(IN.uvSplat01, IN.uvSplat23, splatControl, normalTS); - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) - half3 normalWS = TransformTangentToWorld(normalTS, half3x3(-IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz)); + half3 normalWS = IN.normal.xyz; + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + normalWS = TransformTangentToWorld(normalTS, half3x3(-IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz)); #elif defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) - half3 viewDirWS = IN.viewDir; float2 sampleCoords = (IN.uvMainAndLM.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy; - half3 normalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1)); - half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS); - half3 normalWS = TransformTangentToWorld(normalTS, half3x3(-tangentWS, cross(normalWS, tangentWS), normalWS)); - #else - half3 normalWS = IN.normal; + half3 perpixelNormalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1)); + half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, perpixelNormalWS); + normalWS = TransformTangentToWorld(normalTS, half3x3(-tangentWS, cross(perpixelNormalWS, tangentWS), perpixelNormalWS)); #endif - outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(normalWS)), 0.0); + normalWS = NormalizeNormalPerPixel(normalWS, UseNormalMap()); + + outNormalWS = half4(PackNormalWSToTexture(normalWS), 0.0); #if defined(_WRITE_SMOOTHNESS) half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl new file mode 100644 index 00000000000..6ffba24eccf --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl @@ -0,0 +1,15 @@ +#ifndef UNIVERSAL_TERRAIN_LIT_FEATURES_INCLUDED +#define UNIVERSAL_TERRAIN_LIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the terrain shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" + +#endif // UNIVERSAL_TERRAIN_LIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl.meta new file mode 100644 index 00000000000..7f8caa8ef29 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8c5d8cda2ad8b48e8bc63e22dbd13088 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl index c02c6a44bed..5a4d4a630e4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl @@ -3,8 +3,9 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" CBUFFER_START(UnityPerMaterial) float4 _MainTex_ST; @@ -66,9 +67,14 @@ TEXTURE2D(_Mask2); SAMPLER(sampler_Mask2); TEXTURE2D(_Mask3); SAMPLER(sampler_Mask3); TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); +TEXTURE2D(_BumpMap); SAMPLER(sampler_BumpMap); TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); TEXTURE2D(_MetallicTex); SAMPLER(sampler_MetallicTex); +half GetBumpScale() { return half(1.0); } + +half4 SampleBumpMap(float2 uv) { return SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv); } + #if defined(UNITY_INSTANCING_ENABLED) && defined(_TERRAIN_INSTANCED_PERPIXEL_NORMAL) #define ENABLE_TERRAIN_PERPIXEL_NORMAL #endif @@ -103,8 +109,8 @@ void ClipHoles(float2 uv) #define SampleLayerAlbedo(i) (SAMPLE_TEXTURE2D(_Splat##i, sampler_Splat0, splat##i##uv) * half4(_DiffuseRemapScale##i.rgb, 1.0h)) -#ifdef _NORMALMAP - #define SampleLayerNormal(i) UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal##i, sampler_Normal0, splat##i##uv), _NormalScale##i) +#if FEATURES_NORMALMAP + #define SampleLayerNormal(i) (UseNormalMap() ? UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal##i, sampler_Normal0, splat##i##uv), _NormalScale##i) : half3(0.0, 0.0, 1.0)) #else #define SampleLayerNormal(i) half3(0.0, 0.0, 1.0) #endif @@ -115,7 +121,7 @@ void ClipHoles(float2 uv) #define SampleLayerMasks(i) (_MaskMapRemapOffset##i + _MaskMapRemapScale##i * 0.5h); #endif -half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) +half4 SampleTerrainMetallic(float2 uv, half albedoAlpha) { half4 specGloss; specGloss = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, uv); @@ -129,14 +135,14 @@ inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfa half4 albedoSmoothness = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv); outSurfaceData.alpha = 1; - half4 specGloss = SampleMetallicSpecGloss(uv, albedoSmoothness.a); + half4 specGloss = SampleTerrainMetallic(uv, albedoSmoothness.a); outSurfaceData.albedo = albedoSmoothness.rgb; outSurfaceData.metallic = specGloss.r; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); outSurfaceData.smoothness = specGloss.a; - outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap)); + outSurfaceData.normalTS = SampleNormal(uv); outSurfaceData.occlusion = 1; outSurfaceData.emission = 0; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl index 92b805728d3..4cdaaeec477 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl @@ -1,4 +1,3 @@ - #ifndef UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED #define UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED @@ -6,6 +5,11 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitFeatures.hlsl" + +#if FEATURES_NORMALMAP && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) +#define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR 1 +#endif struct Attributes { @@ -23,7 +27,7 @@ struct Varyings float4 uvSplat23 : TEXCOORD2; // xy: splat2, zw: splat3 #endif - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z @@ -40,16 +44,16 @@ struct Varyings float3 positionWS : TEXCOORD7; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD8; #endif -#if defined(DYNAMICLIGHTMAP_ON) - float2 dynamicLightmapUV : TEXCOORD9; +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + float2 dynamicLightmapUV : DYNLIGHTMAPUV; #endif #ifdef USE_APV_PROBE_OCCLUSION - float4 probeOcclusion : TEXCOORD10; + float4 probeOcclusion : PROBEOCCLUSION; #endif float4 clipPos : SV_POSITION; @@ -64,33 +68,41 @@ void InitializeInputData(Varyings IN, half3 normalTS, out InputData inputData) inputData.positionWS = IN.positionWS; inputData.positionCS = IN.clipPos; - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) - half3 viewDirWS = half3(IN.normal.w, IN.tangent.w, IN.bitangent.w); - inputData.tangentToWorld = half3x3(-IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz); - inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld); - half3 SH = 0; - #elif defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(IN.positionWS); - float2 sampleCoords = (IN.uvMainAndLM.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy; - half3 normalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1)); - half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS); - inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(-tangentWS, cross(normalWS, tangentWS), normalWS)); - half3 SH = IN.vertexSH; + inputData.normalWS = IN.normal.xyz; + half3 viewDirWS = GetWorldSpaceNormalizeViewDir(IN.positionWS); + half3 SH = 0; + + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + if (UseNormalMap()) + { + viewDirWS = half3(IN.normal.w, IN.tangent.w, IN.bitangent.w); + half3x3 tangentToWorld = half3x3(-IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz); + inputData.tangentToWorld = tangentToWorld; + inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld); + } + else + { + // vertexSH interpolator doesn't exist in this path; evaluate the vertex SH portion + // per pixel so consumers composing with SampleSHPixel get the full result. + SH = SampleSHVertex(IN.normal.xyz); + } #else - half3 viewDirWS = GetWorldSpaceNormalizeViewDir(IN.positionWS); - inputData.normalWS = IN.normal; - half3 SH = IN.vertexSH; + SH = IN.vertexSH; + #if defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) + float2 sampleCoords = (IN.uvMainAndLM.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy; + half3 normalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1)); + half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS); + inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(-tangentWS, cross(normalWS, tangentWS), normalWS)); + #endif #endif - inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS, UseNormalMap()); inputData.viewDirectionWS = viewDirWS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = IN.shadowCoord; - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? IN.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif #ifdef _ADDITIONAL_LIGHTS_VERTEX @@ -100,14 +112,11 @@ void InitializeInputData(Varyings IN, half3 normalTS, out InputData inputData) inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.clipPos); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR inputData.dynamicLightmapUV = IN.dynamicLightmapUV; #endif - #if defined(LIGHTMAP_ON) inputData.staticLightmapUV = IN.uvMainAndLM.zw; - #else inputData.vertexSH = SH; - #endif #if defined(USE_APV_PROBE_OCCLUSION) inputData.probeOcclusion = IN.probeOcclusion; #endif @@ -116,36 +125,37 @@ void InitializeInputData(Varyings IN, half3 normalTS, out InputData inputData) void InitializeBakedGIData(Varyings IN, inout InputData inputData) { - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) - half3 SH = 0; + GIParams giParams = (GIParams)0; + + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) + // vertexSH interpolator doesn't exist in this path; evaluate the vertex SH portion per pixel + // instead so the later SampleSHPixel composes to the full result in all SH evaluation modes. + giParams.vertexSH = UseNormalMap() ? half3(0, 0, 0) : SampleSHVertex(inputData.normalWS); #else - half3 SH = IN.vertexSH; + giParams.vertexSH = IN.vertexSH; + #endif + #if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR + giParams.dynamicLightmapUV = IN.dynamicLightmapUV; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = IN.probeOcclusion; #endif -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, IN.dynamicLightmapUV, SH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(IN.uvMainAndLM.zw); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(SH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - inputData.positionCS.xy, - IN.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, SH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(IN.uvMainAndLM.zw); -#endif + giParams.staticLightmapUV = IN.uvMainAndLM.zw; + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = inputData.positionCS.xy; + + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); } #ifndef TERRAIN_SPLAT_BASEPASS void NormalMapMix(float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, inout half3 mixedNormal) { - #if defined(_NORMALMAP) + if (UseNormalMap()) + { half3 nrm = half(0.0); nrm += splatControl.r * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, uvSplat01.xy), _NormalScale0); nrm += splatControl.g * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, uvSplat01.zw), _NormalScale1); @@ -160,7 +170,7 @@ void NormalMapMix(float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, #endif mixedNormal = normalize(nrm.xyz); - #endif + } } void SplatmapMix(float4 uvMainAndLM, float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, out half weight, out half4 mixedDiffuse, out half4 defaultSmoothness, inout half3 mixedNormal) @@ -180,15 +190,15 @@ void SplatmapMix(float4 uvMainAndLM, float4 uvSplat01, float4 uvSplat23, inout h defaultSmoothness.r = (smoothnessSources.r < 0.5) ? diffuseAlpha.r * smoothnessConstants.r : // kConstantMultipliedByDiffuseAlpha (smoothnessSources.r < 1.5) ? diffuseAlpha.r : // kDiffuseAlphaChannel smoothnessConstants.r; // kConstant - + defaultSmoothness.g = (smoothnessSources.g < 0.5) ? diffuseAlpha.g * smoothnessConstants.g : (smoothnessSources.g < 1.5) ? diffuseAlpha.g : smoothnessConstants.g; - + defaultSmoothness.b = (smoothnessSources.b < 0.5) ? diffuseAlpha.b * smoothnessConstants.b : (smoothnessSources.b < 1.5) ? diffuseAlpha.b : smoothnessConstants.b; - + defaultSmoothness.a = (smoothnessSources.a < 0.5) ? diffuseAlpha.a * smoothnessConstants.a : (smoothnessSources.a < 1.5) ? diffuseAlpha.a : smoothnessConstants.a; @@ -331,11 +341,11 @@ Varyings SplatmapVert(Attributes v) o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3); #endif -#if defined(DYNAMICLIGHTMAP_ON) +#if USE_DYNAMICLIGHTMAP_UV_INTERPOLATOR o.dynamicLightmapUV = v.texcoord * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif - #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL) + #if defined(REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR) half3 viewDirWS = GetWorldSpaceNormalizeViewDir(Attributes.positionWS); float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0); VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, vertexTangent); @@ -360,8 +370,8 @@ Varyings SplatmapVert(Attributes v) o.positionWS = Attributes.positionWS; o.clipPos = Attributes.positionCS; - #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - o.shadowCoord = GetShadowCoord(Attributes); + #if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + o.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(Attributes, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif return o; @@ -460,10 +470,8 @@ void SplatmapFragment( SetupTerrainDebugTextureData(inputData, IN.uvMainAndLM.xy); #if defined(_DBUFFER) - half3 specular = half3(0.0h, 0.0h, 0.0h); - ApplyDecal(IN.clipPos, + ApplyDecalMetallic(IN.clipPos, albedo, - specular, inputData.normalWS, metallic, occlusion, @@ -474,15 +482,15 @@ void SplatmapFragment( #ifdef TERRAIN_GBUFFER - BRDFData brdfData; - InitializeBRDFData(albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, alpha, brdfData); + BRDFData brdfData = InitializeBRDFData(albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, alpha, IsSpecularSetup(), UseAlphaPremultiply()); // Baked lighting. URP_LIGHT_ACCUM4 color; - Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); - MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); + Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask, ReceiveShadows(), IsSurfaceTypeTransparent()); + MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI); color.rgb = GlobalIllumination(brdfData, (BRDFData)0, 0, inputData.bakedGI, occlusion, inputData.positionWS, - inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV, + UseClearCoat() || UseClearCoatMap(), UseEnvironmentReflections()); color.a = alpha; SplatmapFinalColor(color, IN.clipPos); @@ -496,7 +504,7 @@ void SplatmapFragment( inputData.normalWS = inputData.normalWS * alpha; smoothness *= alpha; - return PackGBuffersBRDFData(brdfData, inputData, smoothness, ClampExposed(inputData.preExposureMultiplier * color.rgb), occlusion); + return PackGBuffersBRDFData(brdfData, inputData, smoothness, ClampExposed(inputData.preExposureMultiplier * color.rgb), occlusion, ReceiveShadows(), IsSpecularSetup(), UseSpecularHighlights()); #else URP_LIGHT_ACCUM4 color = UniversalFragmentPBR(inputData, albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, occlusion, /* emission */ half3(0, 0, 0), alpha); 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 da01c1e4bdf..efe6af30e9d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader @@ -29,12 +29,13 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/WavingDoublePass" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) 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 5af4643d310..dce0a5f5247 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader @@ -29,13 +29,14 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/BillboardWavingDoublePass // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS + #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX + #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK - #pragma multi_compile _ _CLUSTER_LIGHT_LOOP + #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _EXPOSURE #if defined(UNITY_PLATFORM_META_QUEST) #pragma multi_compile _ META_QUEST_ORTHO_PROJ diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassDepthNormalsPass.hlsl index c4d7fb6e87e..76069930fde 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassDepthNormalsPass.hlsl @@ -2,6 +2,9 @@ #define UNIVERSAL_WAVING_GRASS_DEPTH_NORMAL_PASSE_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" struct GrassVertexDepthNormalInput { @@ -69,9 +72,11 @@ GrassVertexDepthNormalOutput DepthNormalOnlyBillboardVertex(GrassVertexDepthNorm half4 DepthNormalOnlyFragment(GrassVertexDepthNormalOutput input) : SV_TARGET { - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + AlphaDiscard((UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) ? input.color.a : albedoAlpha * input.color.a, _Cutoff); + + return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(input.normal, UseNormalMap())), 0.0); - return half4(PackNormalWSToTexture(NormalizeNormalPerPixel(input.normal)), 0.0); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl new file mode 100644 index 00000000000..6123a14a15d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl @@ -0,0 +1,13 @@ +#ifndef UNIVERSAL_WAVING_GRASS_FEATURES_INCLUDED +#define UNIVERSAL_WAVING_GRASS_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the waving-grass shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" + +#endif // UNIVERSAL_WAVING_GRASS_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl.meta new file mode 100644 index 00000000000..4ab6f092bc7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ea92bce7516354d66bcd09a572cb52d6 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl index defdd863c60..74c03cee09e 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl @@ -2,7 +2,8 @@ #define UNIVERSAL_WAVING_GRASS_INPUT_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" CBUFFER_START(UnityPerMaterial) @@ -29,6 +30,8 @@ SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize; UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_MainTex); +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv); } + // ---- Grass helpers // Calculate a 4 fast sine-cosine pairs diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl index 5d34c04c1b4..2485c71b126 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl @@ -5,6 +5,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassFeatures.hlsl" struct GrassVertexInput { @@ -20,7 +21,13 @@ struct GrassVertexInput struct GrassVertexOutput { float2 uv : TEXCOORD0; - DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1); + +#if USE_LIGHTMAP_UV_INTERPOLATOR + float2 lightmapUV : LIGHTMAPUV; +#endif +#if USE_VERTEX_SH_INTERPOLATOR + half3 vertexSH : VERTEXSH; +#endif float4 posWSShininess : TEXCOORD2; // xyz: posWS, w: Shininess * 128 @@ -29,7 +36,7 @@ struct GrassVertexOutput URP_LIGHT_ACCUM4 fogFactorAndVertexLight : TEXCOORD5; // x: fogFactor, yzw: vertex light -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR float4 shadowCoord : TEXCOORD6; #endif half4 color : TEXCOORD7; @@ -55,45 +62,42 @@ void InitializeInputData(GrassVertexOutput input, out InputData inputData) half3 viewDirWS = input.viewDir; viewDirWS = SafeNormalize(viewDirWS); - inputData.normalWS = NormalizeNormalPerPixel(input.normal); + inputData.normalWS = NormalizeNormalPerPixel(input.normal, UseNormalMap()); inputData.viewDirectionWS = viewDirWS; -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - inputData.shadowCoord = input.shadowCoord; -#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + inputData.shadowCoord = ShadowCoordInterpolatorAvailable() ? input.shadowCoord : TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()); #else - inputData.shadowCoord = float4(0, 0, 0, 0); + inputData.shadowCoord = MainLightShadowsAvailable() ? TransformWorldToShadowCoord(inputData.positionWS, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; -#if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy, inputData.normalWS, GetInvPreExposureMultiplier()); -#elif defined(DYNAMICLIGHTMAP_ON) - inputData.bakedGI = SAMPLE_GI(input.lightmapUV, NOT_USED, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV); -#elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) - inputData.bakedGI = SAMPLE_GI(input.vertexSH, - GetAbsolutePositionWS(inputData.positionWS), - inputData.normalWS, - inputData.viewDirectionWS, - input.clipPos.xy, - input.probeOcclusion, - inputData.shadowMask); -#else - inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS); - inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV); -#endif + { + GIParams giParams = (GIParams)0; + #if USE_LIGHTMAP_UV_INTERPOLATOR + giParams.staticLightmapUV = input.lightmapUV; + #endif + #if USE_VERTEX_SH_INTERPOLATOR + giParams.vertexSH = input.vertexSH; + #endif + #ifdef USE_APV_PROBE_OCCLUSION + giParams.vertexProbeOcclusion = input.probeOcclusion; + #endif + giParams.positionWS = inputData.positionWS; + giParams.normalWS = inputData.normalWS; + giParams.viewDirWS = inputData.viewDirectionWS; + giParams.positionSS = input.clipPos.xy; + InitializeBakedGI(giParams, inputData.bakedGI, inputData.shadowMask); + } inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.clipPos); #if defined(DEBUG_DISPLAY) - #if defined(DYNAMICLIGHTMAP_ON) + #if USE_LIGHTMAP_UV_INTERPOLATOR inputData.staticLightmapUV = input.lightmapUV; - #elif defined(LIGHTMAP_ON) - inputData.staticLightmapUV = input.lightmapUV; - #else + #endif + #if USE_VERTEX_SH_INTERPOLATOR inputData.vertexSH = input.vertexSH; #endif #if defined(USE_APV_PROBE_OCCLUSION) @@ -117,19 +121,30 @@ void InitializeVertData(GrassVertexInput input, inout GrassVertexOutput vertData vertData.normal = TransformObjectToWorldNormal(input.normal); - // We either sample GI from lightmap or SH. - // Lightmap UV and vertex SH coefficients use the same interpolator ("float2 lightmapUV" for lightmap or "half3 vertexSH" for SH) - // see DECLARE_LIGHTMAP_OR_SH macro. - // The following funcions initialize the correct variable with correct data - OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, vertData.lightmapUV); - OUTPUT_SH4(vertexInput.positionWS, vertData.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), vertData.vertexSH, vertData.probeOcclusion); +#if USE_LIGHTMAP_UV_INTERPOLATOR + vertData.lightmapUV = LightmapAvailable() ? TransformLightmapUV(input.lightmapUV, unity_LightmapST) : float2(0, 0); +#endif +#if USE_VERTEX_SH_INTERPOLATOR + if (!LightmapAvailable()) + { + #ifdef USE_APV_PROBE_OCCLUSION + vertData.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, vertData.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), vertData.probeOcclusion); + #else + vertData.vertexSH = SampleProbeSHVertex(vertexInput.positionWS, vertData.normal.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS)); + #endif + } + else + { + vertData.vertexSH = half3(0, 0, 0); + } +#endif URP_LIGHT_ACCUM3 vertexLight = VertexLighting(vertexInput.positionWS, vertData.normal.xyz); half fogFactor = 0; vertData.fogFactorAndVertexLight = URP_LIGHT_ACCUM4(fogFactor, vertexLight); -#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) - vertData.shadowCoord = GetShadowCoord(vertexInput); +#if USE_VERTEX_SHADOW_COORD_INTERPOLATOR + vertData.shadowCoord = ShadowCoordInterpolatorAvailable() ? GetShadowCoord(vertexInput, IsSurfaceTypeTransparent()) : float4(0, 0, 0, 0); #endif } @@ -180,7 +195,7 @@ GrassVertexOutput WavingGrassBillboardVert(GrassVertexInput v) inline void InitializeSimpleLitSurfaceData(GrassVertexOutput input, out SurfaceData outSurfaceData) { - half4 diffuseAlpha = SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)); + half4 diffuseAlpha = SampleBaseMap(input.uv); half3 diffuse = diffuseAlpha.rgb * input.color.rgb; half alpha = diffuseAlpha.a * input.color.a; @@ -216,9 +231,11 @@ half4 LitPassFragmentGrass(GrassVertexOutput input) : SV_Target #ifdef TERRAIN_GBUFFER URP_LIGHT_ACCUM4 color = URP_LIGHT_ACCUM4(inputData.bakedGI * surfaceData.albedo + surfaceData.emission, surfaceData.alpha); - return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb)); + return PackGBuffersSurfaceData(surfaceData, inputData, ClampExposed(inputData.preExposureMultiplier * color.rgb), ReceiveShadows()); #else - URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, surfaceData); + URP_LIGHT_ACCUM4 color = UniversalFragmentBlinnPhong(inputData, surfaceData, + UseSpecGlossMap() || UseSpecularColor(), UseAlphaPremultiply(), + ReceiveShadows(), IsSurfaceTypeTransparent()); color.rgb = ClampExposed(inputData.preExposureMultiplier * BlendDistanceFog(color.rgb, input.clipPos)); return half4(color.rgb, OutputAlpha(surfaceData.alpha, IsSurfaceTypeTransparent(_Surface))); #endif @@ -287,7 +304,8 @@ GrassVertexDepthOnlyOutput DepthOnlyBillboardVertex(GrassVertexDepthOnlyInput v) half4 DepthOnlyFragment(GrassVertexDepthOnlyOutput input) : SV_TARGET { - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)).a, input.color, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + AlphaDiscard((UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) ? input.color.a : albedoAlpha * input.color.a, _Cutoff); return input.clipPos.z; } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader index 95c52c716ae..c40ca6f4334 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader @@ -276,7 +276,7 @@ Shader "Universal Render Pipeline/Unlit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -303,7 +303,7 @@ Shader "Universal Render Pipeline/Unlit" #define APPLICATION_SPACE_WARP_MOTION 1 #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitDepthNormalsPass.hlsl index ae1bc01159b..6f84d46dded 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitDepthNormalsPass.hlsl @@ -2,10 +2,10 @@ #define UNIVERSAL_UNLIT_DEPTH_NORMALS_PASS_INCLUDED #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PackNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl" struct Attributes { @@ -58,15 +58,14 @@ void DepthNormalsFragment( UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + half albedoAlpha = SampleBaseMap(input.uv).a; + AlphaDiscard((UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) ? _BaseColor.a : albedoAlpha * _BaseColor.a, _Cutoff); #endif - #if defined(LOD_FADE_CROSSFADE) - LODFadeCrossFade(input.positionCS); - #endif + LODFadeCrossFade(input.positionCS); // Output... - outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(input.normalWS)), 0.0); + outNormalWS = half4(PackNormalWSToTexture(NormalizeNormalPerPixel(input.normalWS, UseNormalMap())), 0.0); #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl new file mode 100644 index 00000000000..f09987bb9a5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl @@ -0,0 +1,11 @@ +#ifndef UNIVERSAL_UNLIT_FEATURES_INCLUDED +#define UNIVERSAL_UNLIT_FEATURES_INCLUDED +// Feature-state queries (*Available()) for every shader_feature the Unlit shaders use. +// One include per feature axis; see the individual headers in Shaders/Utils/. + +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl" + +#endif // UNIVERSAL_UNLIT_FEATURES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl.meta new file mode 100644 index 00000000000..df4592b508c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7815a6d62b2b64020a7d1f56dcfebe98 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl index 5d9d6151cb7..505e489512d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl @@ -1,4 +1,3 @@ - #ifndef URP_UNLIT_FORWARD_PASS_INCLUDED #define URP_UNLIT_FORWARD_PASS_INCLUDED @@ -6,9 +5,8 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DistanceFog.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl" struct Attributes { @@ -103,36 +101,38 @@ void UnlitPassFragment( UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uv; - half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); + half4 texColor = SampleBaseMap(uv); half3 color = texColor.rgb * _BaseColor.rgb; half alpha = texColor.a * _BaseColor.a; alpha = AlphaDiscard(alpha, _Cutoff); - color = AlphaModulate(color, alpha); + if (UseAlphaModulate()) + color = ApplyAlphaModulate(color, alpha); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif InputData inputData; InitializeInputData(input, inputData); SETUP_DEBUG_TEXTURE_DATA(inputData, UNDO_TRANSFORM_TEX(input.uv, _BaseMap)); #ifdef _DBUFFER - ApplyDecalToBaseColor(input.positionCS, color); + if (!IsSurfaceTypeTransparent()) + ApplyDecalToBaseColor(input.positionCS, color); #endif half4 finalColor = UniversalFragmentUnlit(inputData, color, alpha); -#if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) - float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); - finalColor.rgb *= aoFactor.directAmbientOcclusion; -#endif + if (ScreenSpaceOcclusionAvailable() && !IsSurfaceTypeTransparent()) + { + float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, IsSurfaceTypeTransparent()); + finalColor.rgb *= aoFactor.directAmbientOcclusion; + } finalColor.rgb = ClampExposed(BlendDistanceFogExposed(finalColor.rgb, input.positionCS, inputData.preExposureMultiplier)); -#if defined(_SURFACE_TYPE_TRANSPARENT) && defined(_TRANSPARENT_RECEIVE_FOG) - finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, _Blend, input.positionCS); +#if defined(_TRANSPARENT_RECEIVE_FOG) + if (IsSurfaceTypeTransparent()) + finalColor.rgb = MixVolumetricFog(finalColor.rgb, finalColor.a, _Blend, UseAlphaPremultiply(), input.positionCS); #endif finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent()); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitGBufferPass.hlsl index eca73469837..87d5f91fb71 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitGBufferPass.hlsl @@ -3,9 +3,8 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutput.hlsl" -#if defined(LOD_FADE_CROSSFADE) - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" -#endif +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitFeatures.hlsl" struct Attributes { @@ -67,16 +66,15 @@ GBufferFragOutput UnlitPassFragment(Varyings input) UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); half2 uv = input.uv; - half4 texColor = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); + half4 texColor = SampleBaseMap(uv); half3 color = texColor.rgb * _BaseColor.rgb; half alpha = texColor.a * _BaseColor.a; alpha = AlphaDiscard(alpha, _Cutoff); - color = AlphaModulate(color, alpha); + if (UseAlphaModulate()) + color = ApplyAlphaModulate(color, alpha); -#ifdef LOD_FADE_CROSSFADE LODFadeCrossFade(input.positionCS); -#endif InputData inputData; InitializeInputData(input, inputData); @@ -88,16 +86,16 @@ GBufferFragOutput UnlitPassFragment(Varyings input) SurfaceData surfaceData = (SurfaceData)0; surfaceData.albedo = color; surfaceData.alpha = alpha; - -#if defined(_SCREEN_SPACE_OCCLUSION) // GBuffer never has transparents - float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV); - surfaceData.occlusion = aoFactor.directAmbientOcclusion; -#else surfaceData.occlusion = 1; -#endif - return PackGBuffersSurfaceData(surfaceData, inputData, float3(0,0,0)); + if (ScreenSpaceOcclusionAvailable()) // No transparent-surface check needed: the GBuffer pass only renders opaque geometry + { + float2 normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(normalizedScreenSpaceUV, IsSurfaceTypeTransparent()); + surfaceData.occlusion = aoFactor.directAmbientOcclusion; + } + + return PackGBuffersSurfaceData(surfaceData, inputData, float3(0,0,0), ReceiveShadows()); } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl index 5656349482a..3d9ab3c053d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl @@ -1,10 +1,16 @@ #ifndef UNIVERSAL_UNLIT_INPUT_INCLUDED #define UNIVERSAL_UNLIT_INPUT_INCLUDED -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" +TEXTURE2D(_BaseMap); +SAMPLER(sampler_BaseMap); +UNITY_TEXTURE_STREAMING_DEBUG_VARS_FOR_TEX(_BaseMap); + CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _BaseMap_TexelSize; @@ -41,4 +47,6 @@ void SetupDOTSUnlitMaterialPropertyCaches() #endif +half4 SampleBaseMap(float2 uv) { return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); } + #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl index fbbc6e9b988..3d12fe7d6f9 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl @@ -6,7 +6,7 @@ half4 UniversalFragmentMetaUnlit(Varyings input) : SV_Target { MetaInput metaInput = (MetaInput)0; - metaInput.Albedo = _BaseColor.rgb * SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).rgb; + metaInput.Albedo = _BaseColor.rgb * SampleBaseMap(input.uv).rgb; return UniversalFragmentMeta(input, metaInput); } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl new file mode 100644 index 00000000000..1b884438905 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl @@ -0,0 +1,62 @@ +#ifndef UNIVERSAL_ALPHA_BLEND_INCLUDED +#define UNIVERSAL_ALPHA_BLEND_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_ALPHAMODULATE_ON allows the preprocessor to know if the _ALPHAMODULATE_ON might be used. +// Dynamic branch mode: always true if _ALPHAMODULATE_ON feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _ALPHAMODULATE_ON is active. +#if (_ALPHAMODULATE_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_ALPHAMODULATE_ON + #define FEATURES_ALPHAMODULATE_ON 1 +#elif !defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) || (_ALPHAMODULATE_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_ALPHAMODULATE_ON) + #undef FEATURES_ALPHAMODULATE_ON + #define FEATURES_ALPHAMODULATE_ON 1 + #endif +#endif + +// FEATURES_ALPHAPREMULTIPLY_ON allows the preprocessor to know if the _ALPHAPREMULTIPLY_ON might be used. +// Dynamic branch mode: always true if _ALPHAPREMULTIPLY_ON feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _ALPHAPREMULTIPLY_ON is active. +#if (_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_ALPHAPREMULTIPLY_ON + #define FEATURES_ALPHAPREMULTIPLY_ON 1 +#elif !defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) || (_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + #undef FEATURES_ALPHAPREMULTIPLY_ON + #define FEATURES_ALPHAPREMULTIPLY_ON 1 + #endif +#endif + + +// Runtime queries for the _ALPHAPREMULTIPLY_ON / _ALPHAMODULATE_ON shader feature state, safe whether or not the +// keyword is declared in the current pass. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// Returns true if the _ALPHAPREMULTIPLY_ON variant is active. +bool UseAlphaPremultiply() +{ +#if defined(_ALPHAPREMULTIPLY_ON_KEYWORD_DECLARED) + return _ALPHAPREMULTIPLY_ON; +#elif DEFINED_NONZERO(_ALPHAPREMULTIPLY_ON) + return true; +#else + return false; +#endif +} + +// Returns true if the _ALPHAMODULATE_ON variant is active. +bool UseAlphaModulate() +{ +#if defined(_ALPHAMODULATE_ON_KEYWORD_DECLARED) + return _ALPHAMODULATE_ON; +#elif DEFINED_NONZERO(_ALPHAMODULATE_ON) + return true; +#else + return false; +#endif +} + +#endif // UNIVERSAL_ALPHA_BLEND_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl.meta new file mode 100644 index 00000000000..92fd3df24a9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bb23c2cc852944fddba48c9d83d6da07 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl new file mode 100644 index 00000000000..820015d254a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl @@ -0,0 +1,81 @@ +#ifndef UNIVERSAL_CLEAR_COAT_INCLUDED +#define UNIVERSAL_CLEAR_COAT_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_CLEARCOAT allows the preprocessor to know if the _CLEARCOAT might be used. +// Dynamic branch mode: always true if _CLEARCOAT feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _CLEARCOAT is active. +#if (_CLEARCOAT_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_CLEARCOAT + #define FEATURES_CLEARCOAT 1 +#elif !defined(_CLEARCOAT_KEYWORD_DECLARED) || (_CLEARCOAT_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_CLEARCOAT) + #undef FEATURES_CLEARCOAT + #define FEATURES_CLEARCOAT 1 + #endif +#endif + +// FEATURES_CLEARCOATMAP allows the preprocessor to know if the _CLEARCOATMAP might be used. +// Dynamic branch mode: always true if _CLEARCOATMAP feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _CLEARCOATMAP is active. +#if (_CLEARCOATMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_CLEARCOATMAP + #define FEATURES_CLEARCOATMAP 1 +#elif !defined(_CLEARCOATMAP_KEYWORD_DECLARED) || (_CLEARCOATMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_CLEARCOATMAP) + #undef FEATURES_CLEARCOATMAP + #define FEATURES_CLEARCOATMAP 1 + #endif +#endif + + +// Runtime queries for the _CLEARCOAT / _CLEARCOATMAP shader feature state, safe whether or not the +// keyword is declared in the current pass. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// Returns true if the _CLEARCOAT variant is active. +bool UseClearCoat() +{ +#if defined(_CLEARCOAT_KEYWORD_DECLARED) + return _CLEARCOAT; +#elif DEFINED_NONZERO(_CLEARCOAT) + return true; +#else + return false; +#endif +} + +// Returns true if the _CLEARCOATMAP variant is active. +bool UseClearCoatMap() +{ +#if defined(_CLEARCOATMAP_KEYWORD_DECLARED) + return _CLEARCOATMAP; +#elif DEFINED_NONZERO(_CLEARCOATMAP) + return true; +#else + return false; +#endif +} + +// Simple getters the including material's input file must define. +half4 SampleClearCoatMap(float2 uv); +half GetClearCoatMask(); +half GetClearCoatSmoothness(); + +// Returns the clear coat parameters: .r = mask, .g = smoothness. +half2 SampleClearCoat(float2 uv) +{ + half2 clearCoatMaskSmoothness = half2(0.0, 1.0); + if (UseClearCoat() || UseClearCoatMap()) + { + clearCoatMaskSmoothness = half2(GetClearCoatMask(), GetClearCoatSmoothness()); + + if (UseClearCoatMap()) + clearCoatMaskSmoothness *= SampleClearCoatMap(uv).rg; + } + return clearCoatMaskSmoothness; +} + +#endif // UNIVERSAL_CLEAR_COAT_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl.meta new file mode 100644 index 00000000000..ec65fe4739e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClearCoat.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bf4898bfebf044889812228a94e3224e +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.hlsl index 9583f7e972b..d12a4d85067 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.hlsl @@ -50,10 +50,8 @@ float4x4 _ScreenToWorld[2]; half3 DeferredLightContribution(Light light, InputData inputData, GBufferData gBufferData) { - #if defined(_LIGHT_LAYERS) - UNITY_BRANCH if (!IsMatchingLightLayer(light.layerMask, gBufferData.meshRenderingLayers)) + UNITY_BRANCH if (LightLayersAvailable() && !IsMatchingLightLayer(light.layerMask, gBufferData.meshRenderingLayers)) return half3(0.0, 0.0, 0.0); - #endif #if defined(_SIMPLELIT) { @@ -76,7 +74,7 @@ half3 DeferredLightContribution(Light light, InputData inputData, GBufferData gB #endif BRDFData brdfData = GBufferDataToBRDFData(gBufferData); - return half3(LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS, materialSpecularHighlightsOff)); + return half3(LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS, !materialSpecularHighlightsOff, false)); } #endif @@ -121,16 +119,17 @@ half4 DeferredShadingClustered(Varyings input) : SV_Target inputData.viewDirectionWS = GetWorldSpaceNormalizeViewDir(posWS.xyz); inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(screen_uv); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(screen_uv, false); - #if defined(_SCREEN_SPACE_OCCLUSION) + if (ScreenSpaceOcclusionAvailable()) + { // What we want is really to apply the minimum occlusion value between the baked occlusion from surfaceDataOcclusion and real-time occlusion from SSAO. // But we already applied the baked occlusion during gbuffer pass, so we have to cancel it out here. // We must also avoid divide-by-0 that the reciprocal can generate. half surfaceDataOcclusion = gBufferData.occlusion; half occlusion = aoFactor.indirectAmbientOcclusion < surfaceDataOcclusion ? aoFactor.indirectAmbientOcclusion * rcp(surfaceDataOcclusion) : 1.0; alpha = occlusion; - #endif + } // Main light Light mainLight = GetMainLight(); @@ -138,26 +137,19 @@ half4 DeferredShadingClustered(Varyings input) : SV_Target bool materialReceiveShadowsOff = (gBufferData.materialFlags & kMaterialFlagReceiveShadowsOff) != 0; UNITY_BRANCH if (!materialReceiveShadowsOff) { - #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) - float4 shadowCoord = float4(screen_uv, 0.0, 1.0); - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - float4 shadowCoord = TransformWorldToShadowCoord(posWS.xyz); - #else - float4 shadowCoord = float4(0, 0, 0, 0); - #endif - mainLight.shadowAttenuation = MainLightShadow(shadowCoord, posWS.xyz, gBufferData.shadowMask, _MainLightOcclusionProbes); + float4 shadowCoord = float4(0, 0, 0, 0); + if (MainLightShadowsAvailable()) + shadowCoord = MainLightScreenShadowsAvailable() ? float4(screen_uv, 0.0, 1.0) : TransformWorldToShadowCoord(posWS.xyz, false); + mainLight.shadowAttenuation = MainLightShadow(shadowCoord, posWS.xyz, gBufferData.shadowMask, _MainLightOcclusionProbes, !materialReceiveShadowsOff, false); } - #if defined(_LIGHT_COOKIES) - half3 cookieColor = SampleMainLightCookie(posWS.xyz); - mainLight.color *= half3(cookieColor); - #endif + real3 cookieColor = SampleMainLightCookie(posWS.xyz); + mainLight.color *= half3(cookieColor); mainLight.color *= ComputeMainLightFogAttenuation(posWS.xyz, mainLight.direction); - #if defined(_SCREEN_SPACE_OCCLUSION) + if (ScreenSpaceOcclusionAvailable()) mainLight.shadowAttenuation *= aoFactor.directAmbientOcclusion; - #endif color += DeferredLightContribution(mainLight, inputData, gBufferData); @@ -165,7 +157,7 @@ half4 DeferredShadingClustered(Varyings input) : SV_Target // We do additional directional lights last because otherwise FXC complains... uint pixelLightCount = GetAdditionalLightsCount(); LIGHT_LOOP_BEGIN(pixelLightCount) - Light light = GetAdditionalLight(lightIndex, inputData, gBufferData.shadowMask, aoFactor); + Light light = GetAdditionalLight(lightIndex, inputData, gBufferData.shadowMask, aoFactor, !materialReceiveShadowsOff, false); UNITY_BRANCH if (materialReceiveShadowsOff) { @@ -178,7 +170,7 @@ half4 DeferredShadingClustered(Varyings input) : SV_Target UNITY_LOOP for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++) { CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK - Light light = GetAdditionalLight(lightIndex, inputData, gBufferData.shadowMask, aoFactor); + Light light = GetAdditionalLight(lightIndex, inputData, gBufferData.shadowMask, aoFactor, !materialReceiveShadowsOff, false); UNITY_BRANCH if (materialReceiveShadowsOff) { diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader index 348cc4e1248..9a7f3698401 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader @@ -52,8 +52,8 @@ Shader "Hidden/Universal Render Pipeline/ClusterDeferred" // ------------------------------------- // Defines - #define _CLUSTER_LIGHT_LOOP - #define _LIT + #define _CLUSTER_LIGHT_LOOP 1 + #define _LIT 1 // ------------------------------------- // Universal Pipeline keywords @@ -118,8 +118,8 @@ Shader "Hidden/Universal Render Pipeline/ClusterDeferred" // ------------------------------------- // Defines - #define _CLUSTER_LIGHT_LOOP - #define _SIMPLELIT + #define _CLUSTER_LIGHT_LOOP 1 + #define _SIMPLELIT 1 // ------------------------------------- // Universal Pipeline keywords @@ -135,7 +135,7 @@ Shader "Hidden/Universal Render Pipeline/ClusterDeferred" #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED #pragma multi_compile_fragment _ _LIGHT_COOKIES #pragma multi_compile_fragment _ _VOLUMETRIC_FOG - #pragma multi_compile _ _LIGHT_LAYERS + #pragma multi_compile_fragment _ _LIGHT_LAYERS #pragma multi_compile_fragment _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl new file mode 100644 index 00000000000..3cce18eef27 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl @@ -0,0 +1,137 @@ +#ifndef UNIVERSAL_DETAILMAP_INCLUDED +#define UNIVERSAL_DETAILMAP_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +// Utility functionality for Universal RP materials that has the _DETAIL_MULX2 _DETAIL_SCALED shader feature. + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" + +// FEATURES_DETAIL_MULX2 allows the preprocessor to know if the _DETAIL_MULX2 might be used. +// Dynamic branch mode: always true if _DETAIL_MULX2 feature exists; use UseDetailMapMul2X() to query runtime usage. +// Specialized variants mode: only true when _DETAIL_MULX2 is active. +#if (_DETAIL_MULX2_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_DETAILMAP_MULX2 + #define FEATURES_DETAILMAP_MULX2 1 +#elif !defined(_DETAIL_MULX2_KEYWORD_DECLARED) || (_DETAIL_MULX2_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_DETAIL_MULX2) + #undef FEATURES_DETAILMAP_MULX2 + #define FEATURES_DETAILMAP_MULX2 1 + #endif +#endif + +// FEATURES_DETAIL_SCALED allows the preprocessor to know if the _DETAIL_SCALED might be used. +// Dynamic branch mode: always true if _DETAIL_SCALED feature exists; use UseDetailMapScaled() to query runtime usage. +// Specialized variants mode: only true when _DETAIL_SCALED is active. +#if (_DETAIL_SCALED_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_DETAILMAP_SCALED + #define FEATURES_DETAILMAP_SCALED 1 +#elif !defined(_DETAIL_SCALED_KEYWORD_DECLARED) || (_DETAIL_SCALED_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_DETAIL_SCALED) + #undef FEATURES_DETAILMAP_SCALED + #define FEATURES_DETAILMAP_SCALED 1 + #endif +#endif + +// FEATURES_DETAIL allows the preprocessor to know if FEATURES_DETAIL_MULX2 or _DETAIL_SCALED might be used. +// Dynamic branch mode: always true if _DETAIL_MULX2 or _DETAIL_SCALED feature exists; use UseDetailMap() to query runtime usage. +// Specialized variants mode: only true when _DETAIL_MULX2 or _DETAIL_SCALED is active. +#define FEATURES_DETAILMAP FEATURES_DETAILMAP_MULX2 || FEATURES_DETAILMAP_SCALED + +// Returns true if the _DETAIL_MULX2 shader feature is enabled, otherwise false. +bool UseDetailMapMul2X() +{ + #if defined(_DETAIL_MULX2_KEYWORD_DECLARED) + return _DETAIL_MULX2; + #else + #if defined(_DETAIL_MULX2) + return _DETAIL_MULX2; + #else + return false; + #endif + #endif +} + +// Returns true if the _DETAIL_SCALED shader feature is enabled, otherwise false. +bool UseDetailMapScaled() +{ + #if defined(_DETAIL_SCALED_KEYWORD_DECLARED) + return _DETAIL_SCALED; + #else + #if defined(_DETAIL_SCALED) + return _DETAIL_SCALED; + #else + return false; + #endif + #endif +} + +// Returns true if the _DETAIL_MULX2 or _DETAIL_SCALED shader features are enabled, otherwise false. +bool UseDetailMap() +{ + return UseDetailMapMul2X() || UseDetailMapScaled(); +} + +// Simple getters the including material's input file must define. +half4 SampleDetailAlbedoMap(float2 uv); +half4 SampleDetailNormalMap(float2 uv); +half GetDetailAlbedoMapScale(); +half GetDetailNormalMapScale(); + +// Used for scaling detail albedo. Main features: +// - Depending if detailAlbedo brightens or darkens, scale magnifies effect. +// - No effect is applied if detailAlbedo is 0.5. +half3 ScaleDetailAlbedo(half3 detailAlbedo, half scale) +{ + // detailAlbedo = detailAlbedo * 2.0h - 1.0h; + // detailAlbedo *= _DetailAlbedoMapScale; + // detailAlbedo = detailAlbedo * 0.5h + 0.5h; + // return detailAlbedo * 2.0f; + + // A bit more optimized + return half(2.0) * detailAlbedo * scale - scale + half(1.0); +} + +half3 ApplyDetailAlbedo(float2 detailUv, half3 albedo, half detailMask) +{ + half3 result = albedo; + + if (UseDetailMap()) + { + half3 detailAlbedo = SampleDetailAlbedoMap(detailUv).rgb; + + // In order to have same performance as builtin, we do scaling only if scale is not 1.0 (Scaled version has 6 additional instructions) + if (UseDetailMapScaled()) + detailAlbedo = ScaleDetailAlbedo(detailAlbedo, GetDetailAlbedoMapScale()); + else + detailAlbedo = half(2.0) * detailAlbedo; + + result *= LerpWhiteTo(detailAlbedo, detailMask); + } + + return result; +} + +half3 ApplyDetailNormal(float2 detailUv, half3 normalTS, half detailMask) +{ + half3 result = normalTS; + + if (UseDetailMap()) + { + #if BUMP_SCALE_NOT_SUPPORTED + half3 detailNormalTS = UnpackNormal(SampleDetailNormalMap(detailUv)); + #else + half3 detailNormalTS = UnpackNormalScale(SampleDetailNormalMap(detailUv), GetDetailNormalMapScale()); + #endif + + // With UNITY_NO_DXT5nm unpacked vector is not normalized for BlendNormalRNM + // For visual consistancy we going to do in all cases + detailNormalTS = normalize(detailNormalTS); + + result = lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask); // todo: detailMask should lerp the angle of the quaternion rotation, not the normals + } + + return result; +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl.meta new file mode 100644 index 00000000000..145c70ffaa8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/DetailMap.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4a704662ceb247ed919388fafff1508f +timeCreated: 1772555158 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl new file mode 100644 index 00000000000..5267f247745 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl @@ -0,0 +1,52 @@ +#ifndef UNIVERSAL_EMISSION_INCLUDED +#define UNIVERSAL_EMISSION_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_EMISSION allows the preprocessor to know if the _EMISSION might be used. +// Dynamic branch mode: always true if _EMISSION feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _EMISSION is active. +#if (_EMISSION_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_EMISSION + #define FEATURES_EMISSION 1 +#elif !defined(_EMISSION_KEYWORD_DECLARED) || (_EMISSION_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_EMISSION) + #undef FEATURES_EMISSION + #define FEATURES_EMISSION 1 + #endif +#endif + + +// Runtime queries for the _EMISSION shader feature state, safe whether or not the +// keyword is declared in the current pass. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// Returns true if the _EMISSION variant is active. +bool UseEmission() +{ +#if defined(_EMISSION_KEYWORD_DECLARED) + return _EMISSION; +#elif DEFINED_NONZERO(_EMISSION) + return true; +#else + return false; +#endif +} + +// Simple getters the including material's input file must define. +half4 SampleEmissionMap(float2 uv); +half4 GetEmissionColor(); + +// Returns the tinted emission color, or black when emission is disabled. +half3 SampleEmission(float2 uv, bool useEmission) +{ + return useEmission ? SampleEmissionMap(uv).rgb * GetEmissionColor().rgb : half3(0.0h, 0.0h, 0.0h); +} + +half3 SampleEmission(float2 uv) +{ + return SampleEmission(uv, UseEmission()); +} + +#endif // UNIVERSAL_EMISSION_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl.meta new file mode 100644 index 00000000000..e44089700ef --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Emission.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 730f05fae986e4dfbb406df569136a4f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl new file mode 100644 index 00000000000..421837af3d4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl @@ -0,0 +1,37 @@ +#ifndef UNIVERSAL_ENVIRONMENT_REFLECTIONS_INCLUDED +#define UNIVERSAL_ENVIRONMENT_REFLECTIONS_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_ENVIRONMENTREFLECTIONS_OFF allows the preprocessor to know if the _ENVIRONMENTREFLECTIONS_OFF might be used. +// Dynamic branch mode: always true if _ENVIRONMENTREFLECTIONS_OFF feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _ENVIRONMENTREFLECTIONS_OFF is active. +#if (_ENVIRONMENTREFLECTIONS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_ENVIRONMENTREFLECTIONS_OFF + #define FEATURES_ENVIRONMENTREFLECTIONS_OFF 1 +#elif !defined(_ENVIRONMENTREFLECTIONS_OFF_KEYWORD_DECLARED) || (_ENVIRONMENTREFLECTIONS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_ENVIRONMENTREFLECTIONS_OFF) + #undef FEATURES_ENVIRONMENTREFLECTIONS_OFF + #define FEATURES_ENVIRONMENTREFLECTIONS_OFF 1 + #endif +#endif + + +// Runtime query for the _ENVIRONMENTREFLECTIONS_OFF shader feature state, safe whether or not +// the keyword is declared in the current pass. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// True when environment reflections are enabled (inverts the _ENVIRONMENTREFLECTIONS_OFF keyword). +bool UseEnvironmentReflections() +{ +#if defined(_ENVIRONMENTREFLECTIONS_OFF_KEYWORD_DECLARED) + return !_ENVIRONMENTREFLECTIONS_OFF; +#elif DEFINED_NONZERO(_ENVIRONMENTREFLECTIONS_OFF) + return false; +#else + return true; +#endif +} + +#endif // UNIVERSAL_ENVIRONMENT_REFLECTIONS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl.meta new file mode 100644 index 00000000000..07d34bc251d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/EnvironmentReflections.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2b8761acd13644153b9f84fd27e2be86 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl new file mode 100644 index 00000000000..bd248b87c53 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl @@ -0,0 +1,118 @@ +#ifndef UNIVERSAL_METALLIC_SPEC_GLOSS_INCLUDED +#define UNIVERSAL_METALLIC_SPEC_GLOSS_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_METALLICSPECGLOSSMAP allows the preprocessor to know if the _METALLICSPECGLOSSMAP might be used. +// Dynamic branch mode: always true if _METALLICSPECGLOSSMAP feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _METALLICSPECGLOSSMAP is active. +#if (_METALLICSPECGLOSSMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_METALLICSPECGLOSSMAP + #define FEATURES_METALLICSPECGLOSSMAP 1 +#elif !defined(_METALLICSPECGLOSSMAP_KEYWORD_DECLARED) || (_METALLICSPECGLOSSMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_METALLICSPECGLOSSMAP) + #undef FEATURES_METALLICSPECGLOSSMAP + #define FEATURES_METALLICSPECGLOSSMAP 1 + #endif +#endif + +// FEATURES_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A allows the preprocessor to know if the _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A might be used. +// Dynamic branch mode: always true if _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A is active. +#if (_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #define FEATURES_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1 +#elif !defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_KEYWORD_DECLARED) || (_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) + #undef FEATURES_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #define FEATURES_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A 1 + #endif +#endif + +// FEATURES_SPECULAR_SETUP allows the preprocessor to know if the _SPECULAR_SETUP might be used. +// Dynamic branch mode: always true if _SPECULAR_SETUP feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _SPECULAR_SETUP is active. +#if (_SPECULAR_SETUP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_SPECULAR_SETUP + #define FEATURES_SPECULAR_SETUP 1 +#elif !defined(_SPECULAR_SETUP_KEYWORD_DECLARED) || (_SPECULAR_SETUP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_SPECULAR_SETUP) + #undef FEATURES_SPECULAR_SETUP + #define FEATURES_SPECULAR_SETUP 1 + #endif +#endif + + +// Runtime queries for the Lit-family metallic/specular gloss shader features, safe whether or +// not the keywords are declared in the current pass. These three act as one unit: +// _SPECULAR_SETUP selects the workflow, _METALLICSPECGLOSSMAP binds the workflow's mask +// texture, and _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A redirects that sample's smoothness source. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// Returns true if the _SPECULAR_SETUP variant is active. +bool IsSpecularSetup() +{ +#if defined(_SPECULAR_SETUP_KEYWORD_DECLARED) + return _SPECULAR_SETUP; +#elif DEFINED_NONZERO(_SPECULAR_SETUP) + return true; +#else + return false; +#endif +} + +// Returns true if the _METALLICSPECGLOSSMAP variant is active. +bool UseMetallicSpecGlossMap() +{ +#if defined(_METALLICSPECGLOSSMAP_KEYWORD_DECLARED) + return _METALLICSPECGLOSSMAP; +#elif DEFINED_NONZERO(_METALLICSPECGLOSSMAP) + return true; +#else + return false; +#endif +} + +// Returns true if the _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A variant is active. +bool UseSmoothnessTextureAlbedoChannelA() +{ +#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A_KEYWORD_DECLARED) + return _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A; +#elif DEFINED_NONZERO(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) + return true; +#else + return false; +#endif +} + +// Simple getters the including material's input file must define. +half4 SampleMetallicGlossMap(float2 uv); +half4 SampleSpecGlossMap(float2 uv); +half4 GetSpecColor(); +half GetMetallic(); +half GetSmoothness(); + +// Samples the active workflow's reflectivity/smoothness data: +// .rgb = specular color (specular workflow) or metallic in .r (metallic workflow), .a = smoothness. +half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) +{ + half smoothness = GetSmoothness(); + half4 specGloss; + + if (UseMetallicSpecGlossMap()) + { + specGloss = IsSpecularSetup() ? SampleSpecGlossMap(uv) : SampleMetallicGlossMap(uv); + specGloss.a = UseSmoothnessTextureAlbedoChannelA() ? albedoAlpha * smoothness : specGloss.a * smoothness; + } + else + { + half metallic = GetMetallic(); + specGloss.rgb = IsSpecularSetup() ? GetSpecColor().rgb : metallic.rrr; + specGloss.a = UseSmoothnessTextureAlbedoChannelA() ? albedoAlpha * smoothness : smoothness; + } + + return specGloss; +} + +#endif // UNIVERSAL_METALLIC_SPEC_GLOSS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl.meta new file mode 100644 index 00000000000..4a7b005e8b3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2f420cd155737423cb5d4b722de914b4 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl new file mode 100644 index 00000000000..4760b31e385 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl @@ -0,0 +1,61 @@ +#ifndef UNIVERSAL_NORMALMAP_INCLUDED +#define UNIVERSAL_NORMALMAP_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +// Utility functionality for Universal RP materials that has the _NORMALMAP shader feature. + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" + +// FEATURES_NORMALMAP allows the preprocessor to know if the _NORMALMAP might be used. +// Dynamic branch mode: always true if _NORMALMAP feature exists; use UseNormalMap() to query runtime usage. +// Specialized variants mode: only true when _NORMALMAP is active. +#if (_NORMALMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_NORMALMAP + #define FEATURES_NORMALMAP 1 +#elif !defined(_NORMALMAP_KEYWORD_DECLARED) || (_NORMALMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_NORMALMAP) + #undef FEATURES_NORMALMAP + #define FEATURES_NORMALMAP 1 + #endif +#endif + +// Returns true if the _NORMALMAP shader feature is enabled, otherwise false. +bool UseNormalMap() +{ + #if defined(_NORMALMAP_KEYWORD_DECLARED) + return _NORMALMAP; + #else + #if defined(_NORMALMAP) + return _NORMALMAP; + #else + return false; + #endif + #endif +} + +// Simple getters the including material's input file must define. +half4 SampleBumpMap(float2 uv); +half GetBumpScale(); + +// Returns the unpacked tangent-space normal, or the flat normal when the normal map is disabled. +half3 SampleNormal(float2 uv, bool useNormalMap) +{ + half3 normalTS = half3(0.0h, 0.0h, 1.0h); + if (useNormalMap) + { + half4 n = SampleBumpMap(uv); + #if BUMP_SCALE_NOT_SUPPORTED + normalTS = UnpackNormal(n); + #else + normalTS = UnpackNormalScale(n, GetBumpScale()); + #endif + } + return normalTS; +} + +half3 SampleNormal(float2 uv) +{ + return SampleNormal(uv, UseNormalMap()); +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl.meta new file mode 100644 index 00000000000..f0e4f47f584 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/NormalMap.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f433ebf47f61ed24b97c4a19aa5adaa9 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl new file mode 100644 index 00000000000..da5b0814bd9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl @@ -0,0 +1,116 @@ +#ifndef UNIVERSAL_OBJECT_MOTION_VECTORS_INCLUDED +#define UNIVERSAL_OBJECT_MOTION_VECTORS_INCLUDED + +#pragma target 3.5 + +#pragma vertex vert +#pragma fragment frag + +//-------------------------------------- +// GPU Instancing +#pragma multi_compile_instancing +#include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl" + +//------------------------------------- +// Other pragmas +#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + +// ------------------------------------- +// Includes +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MotionVectorsCommon.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/MetallicSpecGloss.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl" + +// ------------------------------------- +// Structs +struct Attributes +{ + float4 position : POSITION; +#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + float2 uv : TEXCOORD0; +#endif + float3 positionOld : TEXCOORD4; +#if _ADD_PRECOMPUTED_VELOCITY + float3 alembicMotionVector : TEXCOORD5; +#endif + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct Varyings +{ + float4 positionCS : SV_POSITION; + float4 positionCSNoJitter : POSITION_CS_NO_JITTER; + float4 previousPositionCSNoJitter : PREV_POSITION_CS_NO_JITTER; +#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + float2 uv : TEXCOORD0; +#endif + UNITY_VERTEX_INPUT_INSTANCE_ID + UNITY_VERTEX_OUTPUT_STEREO +}; + +// ------------------------------------- +// Vertex +Varyings vert(Attributes input) +{ + Varyings output = (Varyings)0; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_TRANSFER_INSTANCE_ID(input, output); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + const VertexPositionInputs vertexInput = GetVertexPositionInputs(input.position.xyz); + + #if defined(_ALPHATEST_ON) || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + output.uv = TRANSFORM_TEX(input.uv, _BaseMap); + #endif + +#if defined(APPLICATION_SPACE_WARP_MOTION) + // We do not need jittered position in ASW + output.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, mul(UNITY_MATRIX_M, input.position));; + output.positionCS = output.positionCSNoJitter; +#else + // Jittered. Match the frame. + output.positionCS = vertexInput.positionCS; + output.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, mul(UNITY_MATRIX_M, input.position)); +#endif + + float4 prevPos = (unity_MotionVectorsParams.x == 1) ? float4(input.positionOld, 1) : input.position; + +#if _ADD_PRECOMPUTED_VELOCITY + prevPos = prevPos - float4(input.alembicMotionVector, 0); +#endif + + output.previousPositionCSNoJitter = mul(_PrevViewProjMatrix, mul(UNITY_PREV_MATRIX_M, prevPos)); + + return output; +} + +// ------------------------------------- +// Fragment +float4 frag(Varyings input) : SV_Target +{ + UNITY_SETUP_INSTANCE_ID(input); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + #if defined(_ALPHATEST_ON) + half albedoAlpha = SampleBaseMap(input.uv).a; + AlphaDiscard((UseSmoothnessTextureAlbedoChannelA() || UseGlossinessFromBaseAlpha()) ? _BaseColor.a : albedoAlpha * _BaseColor.a, _Cutoff); + #endif + + LODFadeCrossFade(input.positionCS); + + #if defined(APPLICATION_SPACE_WARP_MOTION) + #if APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + clip((SampleBaseMap(input.uv).a * _BaseColor.a) - 0.001); + #endif + return float4(CalcAswNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 1); + #else + return float4(CalcNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 0, 0); + #endif +} + + +#endif // UNIVERSAL_OBJECT_MOTION_VECTORS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl.meta new file mode 100644 index 00000000000..9801850efb7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6d239a0044031854a817ab72a66ce766 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl new file mode 100644 index 00000000000..a2dc84c37dc --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl @@ -0,0 +1,48 @@ +#ifndef UNIVERSAL_OCCLUSION_MAP_INCLUDED +#define UNIVERSAL_OCCLUSION_MAP_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_OCCLUSIONMAP allows the preprocessor to know if the _OCCLUSIONMAP might be used. +// Dynamic branch mode: always true if _OCCLUSIONMAP feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _OCCLUSIONMAP is active. +#if (_OCCLUSIONMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_OCCLUSIONMAP + #define FEATURES_OCCLUSIONMAP 1 +#elif !defined(_OCCLUSIONMAP_KEYWORD_DECLARED) || (_OCCLUSIONMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_OCCLUSIONMAP) + #undef FEATURES_OCCLUSIONMAP + #define FEATURES_OCCLUSIONMAP 1 + #endif +#endif + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" + +// Runtime queries for the _OCCLUSIONMAP shader feature state, safe whether or not the +// keyword is declared in the current pass. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// Returns true if the _OCCLUSIONMAP variant is active. +bool UseOcclusionMap() +{ +#if defined(_OCCLUSIONMAP_KEYWORD_DECLARED) + return _OCCLUSIONMAP; +#elif DEFINED_NONZERO(_OCCLUSIONMAP) + return true; +#else + return false; +#endif +} + +// Simple getters the including material's input file must define. +half4 SampleOcclusionMap(float2 uv); +half GetOcclusionStrength(); + +// Returns the occlusion factor, or 1 when the material has no occlusion map. +half SampleOcclusion(float2 uv) +{ + return UseOcclusionMap() ? LerpWhiteTo(SampleOcclusionMap(uv).g, GetOcclusionStrength()) : half(1.0); +} + +#endif // UNIVERSAL_OCCLUSION_MAP_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl.meta new file mode 100644 index 00000000000..a9eeb55d2b4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/OcclusionMap.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4e57a300282c546f495e1adcf07225fc +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl new file mode 100644 index 00000000000..e5e3fb10212 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl @@ -0,0 +1,49 @@ +#ifndef UNIVERSAL_PARALLAXMAP_INCLUDED +#define UNIVERSAL_PARALLAXMAP_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +// Utility functionality for Universal RP materials that has the _PARALLAXMAP shader feature. + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl" + +// FEATURES_PARALLAXMAP allows the preprocessor to know if the _PARALLAXMAP might be used. +// Dynamic branch mode: always true if _PARALLAXMAP feature exists; use UseParallaxMap() to query runtime usage. +// Specialized variants mode: only true when _PARALLAXMAP is active. +#if (_PARALLAXMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_PARALLAXMAP + #define FEATURES_PARALLAXMAP 1 +#elif !defined(_PARALLAXMAP_KEYWORD_DECLARED) || (_PARALLAXMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_PARALLAXMAP) + #undef FEATURES_PARALLAXMAP + #define FEATURES_PARALLAXMAP 1 + #endif +#endif + +// Returns true if the _PARALLAXMAP shader feature is enabled, otherwise false. +bool UseParallaxMap() +{ + #if defined(_PARALLAXMAP_KEYWORD_DECLARED) + return _PARALLAXMAP; + #else + #if defined(_PARALLAXMAP) + return _PARALLAXMAP; + #else + return false; + #endif + #endif +} + +// Simple getters the including material's input file must define. +half4 SampleParallaxMap(float2 uv); +half GetParallax(); + +#ifndef BUILTIN_TARGET_API +// Offsets the uv by the parallax displacement when the material has a parallax (height) map. +void ApplyPerPixelDisplacement(half3 viewDirTS, inout float2 uv) +{ + if (UseParallaxMap()) + uv += ParallaxOffset1Step(SampleParallaxMap(uv).g, GetParallax(), viewDirTS); +} +#endif + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl.meta new file mode 100644 index 00000000000..ec2bf66a0de --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ParallaxMap.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b8f914155dd52604e9b81fd51fdd81e4 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl new file mode 100644 index 00000000000..7398fd45ab9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl @@ -0,0 +1,45 @@ +#ifndef UNIVERSAL_RECEIVE_SHADOWS_INCLUDED +#define UNIVERSAL_RECEIVE_SHADOWS_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_RECEIVE_SHADOWS_OFF allows the preprocessor to know if the _RECEIVE_SHADOWS_OFF might be used. +// Dynamic branch mode: always true if _RECEIVE_SHADOWS_OFF feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _RECEIVE_SHADOWS_OFF is active. +#if (_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_RECEIVE_SHADOWS_OFF + #define FEATURES_RECEIVE_SHADOWS_OFF 1 +#elif !defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) || (_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + #undef FEATURES_RECEIVE_SHADOWS_OFF + #define FEATURES_RECEIVE_SHADOWS_OFF 1 + #endif +#endif + +// True only when _RECEIVE_SHADOWS_OFF is enabled at compile time. +#if !defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) || (_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + #undef _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED + #define _RECEIVE_SHADOWS_OFF_STATICALLY_ENABLED 1 + #endif +#endif + + +// Runtime queries for the _RECEIVE_SHADOWS_OFF shader feature state, safe whether or not the +// keyword is declared in the current pass. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// True when the material receives shadows (inverts the _RECEIVE_SHADOWS_OFF keyword). +bool ReceiveShadows() +{ +#if defined(_RECEIVE_SHADOWS_OFF_KEYWORD_DECLARED) + return !_RECEIVE_SHADOWS_OFF; +#elif DEFINED_NONZERO(_RECEIVE_SHADOWS_OFF) + return false; +#else + return true; +#endif +} + +#endif // UNIVERSAL_RECEIVE_SHADOWS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl.meta new file mode 100644 index 00000000000..7e6e279154a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ReceiveShadows.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 59c538ee81a9a4222b0ca90ca50e6b99 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ScreenSpaceShadows.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ScreenSpaceShadows.shader index 2b84a80d86f..41513546437 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ScreenSpaceShadows.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ScreenSpaceShadows.shader @@ -27,10 +27,10 @@ Shader "Hidden/Universal Render Pipeline/ScreenSpaceShadows" //Fetch shadow coordinates for cascade. float3 wpos = ComputeWorldSpacePosition(input.texcoord.xy, deviceDepth, unity_MatrixInvVP); - float4 coords = TransformWorldToShadowCoord(wpos); + float4 coords = TransformWorldToShadowCoord(wpos, false); // Screenspace shadowmap is only used for directional lights which use orthogonal projection. - half realtimeShadow = MainLightRealtimeShadow(coords); + half realtimeShadow = SampleMainLightRealtimeShadow(coords, false); return realtimeShadow; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl new file mode 100644 index 00000000000..ec627b5f449 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl @@ -0,0 +1,89 @@ +#ifndef UNIVERSAL_SPEC_GLOSS_INCLUDED +#define UNIVERSAL_SPEC_GLOSS_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_GLOSSINESS_FROM_BASE_ALPHA allows the preprocessor to know if the _GLOSSINESS_FROM_BASE_ALPHA might be used. +// Dynamic branch mode: always true if _GLOSSINESS_FROM_BASE_ALPHA feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _GLOSSINESS_FROM_BASE_ALPHA is active. +#if (_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_GLOSSINESS_FROM_BASE_ALPHA + #define FEATURES_GLOSSINESS_FROM_BASE_ALPHA 1 +#elif !defined(_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED) || (_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_GLOSSINESS_FROM_BASE_ALPHA) + #undef FEATURES_GLOSSINESS_FROM_BASE_ALPHA + #define FEATURES_GLOSSINESS_FROM_BASE_ALPHA 1 + #endif +#endif + +// FEATURES_SPECGLOSSMAP allows the preprocessor to know if the _SPECGLOSSMAP might be used. +// Dynamic branch mode: always true if _SPECGLOSSMAP feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _SPECGLOSSMAP is active. +#if (_SPECGLOSSMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_SPECGLOSSMAP + #define FEATURES_SPECGLOSSMAP 1 +#elif !defined(_SPECGLOSSMAP_KEYWORD_DECLARED) || (_SPECGLOSSMAP_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_SPECGLOSSMAP) + #undef FEATURES_SPECGLOSSMAP + #define FEATURES_SPECGLOSSMAP 1 + #endif +#endif + +// FEATURES_SPECULAR_COLOR allows the preprocessor to know if the _SPECULAR_COLOR might be used. +// Dynamic branch mode: always true if _SPECULAR_COLOR feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _SPECULAR_COLOR is active. +#if (_SPECULAR_COLOR_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_SPECULAR_COLOR + #define FEATURES_SPECULAR_COLOR 1 +#elif !defined(_SPECULAR_COLOR_KEYWORD_DECLARED) || (_SPECULAR_COLOR_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_SPECULAR_COLOR) + #undef FEATURES_SPECULAR_COLOR + #define FEATURES_SPECULAR_COLOR 1 + #endif +#endif + + +// Runtime queries for the SimpleLit-family specular gloss shader features, safe whether or +// not the keywords are declared in the current pass. These act as one unit: the +// _SPECGLOSSMAP / _SPECULAR_COLOR axis selects the specular source (the empty state means +// no specular), and _GLOSSINESS_FROM_BASE_ALPHA redirects the source's smoothness channel. + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// Returns true if the _SPECGLOSSMAP variant is active. +bool UseSpecGlossMap() +{ +#if defined(_SPECGLOSSMAP_KEYWORD_DECLARED) + return _SPECGLOSSMAP; +#elif DEFINED_NONZERO(_SPECGLOSSMAP) + return true; +#else + return false; +#endif +} + +// Returns true if the _SPECULAR_COLOR variant is active. +bool UseSpecularColor() +{ +#if defined(_SPECULAR_COLOR_KEYWORD_DECLARED) + return _SPECULAR_COLOR; +#elif DEFINED_NONZERO(_SPECULAR_COLOR) + return true; +#else + return false; +#endif +} + +// Returns true if the _GLOSSINESS_FROM_BASE_ALPHA variant is active. +bool UseGlossinessFromBaseAlpha() +{ +#if defined(_GLOSSINESS_FROM_BASE_ALPHA_KEYWORD_DECLARED) + return _GLOSSINESS_FROM_BASE_ALPHA; +#elif DEFINED_NONZERO(_GLOSSINESS_FROM_BASE_ALPHA) + return true; +#else + return false; +#endif +} + +#endif // UNIVERSAL_SPEC_GLOSS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl.meta new file mode 100644 index 00000000000..a91f4a9d889 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecGloss.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0286235479e2f44a3bf80a368e17c896 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl new file mode 100644 index 00000000000..42a674d4886 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl @@ -0,0 +1,40 @@ +#ifndef UNIVERSAL_SPECULAR_HIGHLIGHTS_INCLUDED +#define UNIVERSAL_SPECULAR_HIGHLIGHTS_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_SPECULARHIGHLIGHTS_OFF allows the preprocessor to know if the _SPECULARHIGHLIGHTS_OFF might be used. +// Dynamic branch mode: always true if _SPECULARHIGHLIGHTS_OFF feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _SPECULARHIGHLIGHTS_OFF is active. +#if (_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_SPECULARHIGHLIGHTS_OFF + #define FEATURES_SPECULARHIGHLIGHTS_OFF 1 +#elif !defined(_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED) || (_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_SPECULARHIGHLIGHTS_OFF) + #undef FEATURES_SPECULARHIGHLIGHTS_OFF + #define FEATURES_SPECULARHIGHLIGHTS_OFF 1 + #endif +#endif + + +// Runtime query for the _SPECULARHIGHLIGHTS_OFF shader feature state, safe whether or not the +// keyword is declared in the current pass. + +// SimpleLit-family shaders have no _SPECULARHIGHLIGHTS_OFF; they express disabled highlights +// as the empty state of their specular source axis (SpecGloss.hlsl). + +// The DEFINED_NONZERO arm keeps a leaked `#define _KW 0` fallback from reading as enabled. + +// True when specular highlights are enabled (inverts the _SPECULARHIGHLIGHTS_OFF keyword). +bool UseSpecularHighlights() +{ +#if defined(_SPECULARHIGHLIGHTS_OFF_KEYWORD_DECLARED) + return !_SPECULARHIGHLIGHTS_OFF; +#elif DEFINED_NONZERO(_SPECULARHIGHLIGHTS_OFF) + return false; +#else + return true; +#endif +} + +#endif // UNIVERSAL_SPECULAR_HIGHLIGHTS_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl.meta new file mode 100644 index 00000000000..382ee6c308f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SpecularHighlights.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7382d37b510334a6c8dcc07ee74bd54c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.hlsl index a332c5cd39e..d37e3449dc2 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.hlsl @@ -53,14 +53,17 @@ Varyings Vertex(Attributes input) } #endif - #if defined(_DIRECTIONAL) || defined(_FOG) || defined(_CLEAR_STENCIL_PARTIAL) || (defined(_SSAO_ONLY) && defined(_SCREEN_SPACE_OCCLUSION)) + #if defined(_DIRECTIONAL) || defined(_FOG) || defined(_CLEAR_STENCIL_PARTIAL) // Full screen render using a large triangle. output.positionCS = float4(positionOS.xy, UNITY_RAW_FAR_CLIP_VALUE, 1.0); // Force triangle to be on zfar - #elif defined(_SSAO_ONLY) && !defined(_SCREEN_SPACE_OCCLUSION) + #elif defined(_SSAO_ONLY) // Deferred renderer does not know whether there is a SSAO feature or not at the C# scripting level. // However, this is known at the shader level because of the shader keyword SSAO feature enables. // If the keyword was not enabled, discard the SSAO_only pass by rendering the geometry outside the screen. - output.positionCS = float4(positionOS.xy, -2, 1.0); // Force triangle to be discarded + if (ScreenSpaceOcclusionAvailable()) + output.positionCS = float4(positionOS.xy, UNITY_RAW_FAR_CLIP_VALUE, 1.0); // Force triangle to be on zfar + else + output.positionCS = float4(positionOS.xy, -2, 1.0); // Force triangle to be discarded #else // Light shape geometry is projected as normal. VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS.xyz); @@ -145,7 +148,7 @@ Light UnityLightFromPunctualLightDataAndWorldSpacePosition(PunctualLightData pun light.shadowAttenuation = 1.0; else { - light.shadowAttenuation = AdditionalLightShadow(shadowLightIndex, positionWS, lightDirection, shadowMask, punctualLightData.occlusionProbeInfo); + light.shadowAttenuation = AdditionalLightShadow(shadowLightIndex, positionWS, lightDirection, shadowMask, punctualLightData.occlusionProbeInfo, !materialFlagReceiveShadowsOff); } light.layerMask = punctualLightData.layerMask; @@ -155,6 +158,9 @@ Light UnityLightFromPunctualLightDataAndWorldSpacePosition(PunctualLightData pun half4 SampleAdditionalLightCookieDeferred(int perObjectLightIndex, float3 samplePositionWS) { + if (!LightCookiesAvailable()) + return half4(1, 1, 1, 1); + float4 cookieUvRect = GetLightCookieAtlasUVRect(perObjectLightIndex); float4x4 worldToLight = GetLightCookieWorldToLightMatrix(perObjectLightIndex); float2 cookieUv = float2(0,0); @@ -172,8 +178,8 @@ half4 SampleAdditionalLightCookieDeferred(int perObjectLightIndex, float3 sample cookieColor = half4(IsAdditionalLightsCookieAtlasTextureRGBFormat() ? cookieColor.rgb : IsAdditionalLightsCookieAtlasTextureAlphaFormat() ? cookieColor.aaa : cookieColor.rrr, 1); - return cookieColor; + return cookieColor; } Light GetStencilLight(float3 posWS, float2 screen_uv, half4 shadowMask, uint materialFlags) @@ -192,20 +198,15 @@ Light GetStencilLight(float3 posWS, float2 screen_uv, half4 shadowMask, uint mat if (!materialReceiveShadowsOff) { - #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT) - float4 shadowCoord = float4(screen_uv, 0.0, 1.0); - #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS) - float4 shadowCoord = TransformWorldToShadowCoord(posWS.xyz); - #else - float4 shadowCoord = float4(0, 0, 0, 0); - #endif - unityLight.shadowAttenuation = MainLightShadow(shadowCoord, posWS.xyz, shadowMask, _MainLightOcclusionProbes); + float4 shadowCoord = float4(0, 0, 0, 0); + if (MainLightShadowsAvailable()) + shadowCoord = MainLightScreenShadowsAvailable() ? float4(screen_uv, 0.0, 1.0) : TransformWorldToShadowCoord(posWS.xyz, false); + + unityLight.shadowAttenuation = MainLightShadow(shadowCoord, posWS.xyz, shadowMask, _MainLightOcclusionProbes, !materialReceiveShadowsOff, false); } - #if defined(_LIGHT_COOKIES) - real3 cookieColor = SampleMainLightCookie(posWS); - unityLight.color *= half3(cookieColor); - #endif + real3 cookieColor = SampleMainLightCookie(posWS); + unityLight.color *= half3(cookieColor); unityLight.color *= ComputeMainLightFogAttenuation(posWS, unityLight.direction); #else @@ -217,19 +218,16 @@ Light GetStencilLight(float3 posWS, float2 screen_uv, half4 shadowMask, uint mat if (!materialReceiveShadowsOff) { - #if defined(_ADDITIONAL_LIGHT_SHADOWS) - unityLight.shadowAttenuation = AdditionalLightShadow(_ShadowLightIndex, posWS.xyz, _LightDirection, shadowMask, _LightOcclusionProbInfo); - #endif + unityLight.shadowAttenuation = AdditionalLightShadow(_ShadowLightIndex, posWS.xyz, _LightDirection, shadowMask, _LightOcclusionProbInfo, !materialReceiveShadowsOff); + } + + // Enable/disable is done toggling the keyword _LIGHT_COOKIES, but we could do a "static if" instead if required. + // if(_CookieLightIndex >= 0) + { + half3 cookieColor = SampleAdditionalLightCookieDeferred(_CookieLightIndex, posWS).xyz; + unityLight.color *= cookieColor; } - #ifdef _LIGHT_COOKIES - // Enable/disable is done toggling the keyword _LIGHT_COOKIES, but we could do a "static if" instead if required. - // if(_CookieLightIndex >= 0) - { - half3 cookieColor = SampleAdditionalLightCookieDeferred(_CookieLightIndex, posWS).xyz; - unityLight.color *= cookieColor; - } - #endif #endif #else PunctualLightData light; @@ -243,14 +241,13 @@ Light GetStencilLight(float3 posWS, float2 screen_uv, half4 shadowMask, uint mat light.layerMask = lightLayerMask; unityLight = UnityLightFromPunctualLightDataAndWorldSpacePosition(light, posWS.xyz, shadowMask, _ShadowLightIndex, materialReceiveShadowsOff); - #ifdef _LIGHT_COOKIES - // Enable/disable is done toggling the keyword _LIGHT_COOKIES, but we could do a "static if" instead if required. - // if(_CookieLightIndex >= 0) - { - half3 cookieColor = SampleAdditionalLightCookieDeferred(_CookieLightIndex, posWS).xyz; - unityLight.color *= cookieColor; - } - #endif + // Enable/disable is done toggling the keyword _LIGHT_COOKIES, but we could do a "static if" instead if required. + // if(_CookieLightIndex >= 0) + { + half3 cookieColor = SampleAdditionalLightCookieDeferred(_CookieLightIndex, posWS).xyz; + unityLight.color *= cookieColor; + } + #endif return unityLight; } @@ -303,8 +300,9 @@ half4 DeferredShading(Varyings input) : SV_Target return half4(color, alpha); // Cannot discard because stencil must be updated. #endif - #if defined(_SCREEN_SPACE_OCCLUSION) && !defined(_SURFACE_TYPE_TRANSPARENT) - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(screen_uv); + if (ScreenSpaceOcclusionAvailable()) + { + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(screen_uv, false); unityLight.color *= aoFactor.directAmbientOcclusion; #if defined(_DIRECTIONAL) && defined(_DEFERRED_FIRST_LIGHT) // What we want is really to apply the mininum occlusion value between the baked occlusion from surfaceDataOcclusion and real-time occlusion from SSAO. @@ -313,7 +311,7 @@ half4 DeferredShading(Varyings input) : SV_Target half occlusion = aoFactor.indirectAmbientOcclusion < gBufferData.occlusion ? aoFactor.indirectAmbientOcclusion * rcp(gBufferData.occlusion) : 1.0; alpha = occlusion; #endif - #endif + } InputData inputData = (InputData)0; inputData.preExposureMultiplier = GetPreExposureMultiplier(); @@ -330,7 +328,7 @@ half4 DeferredShading(Varyings input) : SV_Target bool materialSpecularHighlightsOff = (gBufferData.materialFlags & kMaterialFlagSpecularHighlightsOff); #endif BRDFData brdfData = GBufferDataToBRDFData(gBufferData); - color = LightingPhysicallyBased(brdfData, unityLight, inputData.normalWS, inputData.viewDirectionWS, materialSpecularHighlightsOff); + color = LightingPhysicallyBased(brdfData, unityLight, inputData.normalWS, inputData.viewDirectionWS, !materialSpecularHighlightsOff, false); #elif defined(_SIMPLELIT) SurfaceData surfaceData = GBufferDataToSurfaceData(gBufferData); half3 attenuatedLightColor = unityLight.color * (unityLight.distanceAttenuation * unityLight.shadowAttenuation); @@ -350,7 +348,7 @@ half4 FragSSAOOnly(Varyings input) : SV_Target UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); float2 screen_uv = (input.screenUV.xy / input.screenUV.z); - AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(screen_uv); + AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(screen_uv, false); half surfaceDataOcclusion = UnpackGBuffers(input.positionCS.xy).occlusion; // What we want is really to apply the mininum occlusion value between the baked occlusion from surfaceDataOcclusion and real-time occlusion from SSAO. // But we already applied the baked occlusion during gbuffer pass, so we have to cancel it out here. diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader index c74b2e4aa26..4a963d71d75 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader @@ -187,7 +187,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Defines - #define _SIMPLELIT + #define _SIMPLELIT 1 // ------------------------------------- // Universal Pipeline keywords @@ -202,7 +202,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED #pragma multi_compile_fragment _ _LIGHT_COOKIES - #pragma multi_compile _ _LIGHT_LAYERS + #pragma multi_compile_fragment _ _LIGHT_LAYERS #pragma multi_compile_fragment _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" @@ -252,15 +252,14 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Defines - #define _LIT - #define _DIRECTIONAL + #define _LIT 1 + #define _DIRECTIONAL 1 // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_fragment _ _DEFERRED_MAIN_LIGHT #pragma multi_compile_fragment _ _DEFERRED_FIRST_LIGHT - #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK @@ -270,7 +269,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED #pragma multi_compile_fragment _ _LIGHT_COOKIES #pragma multi_compile_fragment _ _VOLUMETRIC_FOG - #pragma multi_compile _ _LIGHT_LAYERS + #pragma multi_compile_fragment _ _LIGHT_LAYERS #pragma multi_compile_fragment _ _EXPOSURE #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" @@ -320,16 +319,14 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Universal Pipeline keywords - #define _SIMPLELIT - #define _DIRECTIONAL + #define _SIMPLELIT 1 + #define _DIRECTIONAL 1 // ------------------------------------- // Universal Pipeline keywords - #pragma multi_compile _ _LIGHT_LAYERS #pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_fragment _ _DEFERRED_MAIN_LIGHT #pragma multi_compile_fragment _ _DEFERRED_FIRST_LIGHT - #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK @@ -340,6 +337,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" #pragma multi_compile_fragment _ _LIGHT_COOKIES #pragma multi_compile_fragment _ _EXPOSURE #pragma multi_compile_fragment _ _VOLUMETRIC_FOG + #pragma multi_compile_fragment _ _LIGHT_LAYERS #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" // ------------------------------------- @@ -376,7 +374,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Defines - #define _FOG + #define _FOG 1 // ------------------------------------- // Universal Pipeline keywords @@ -422,7 +420,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Defines - #define _SSAO_ONLY + #define _SSAO_ONLY 1 // ------------------------------------- // Universal Pipeline keywords diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl index beee86c14f2..badae882568 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl @@ -1,33 +1,58 @@ #ifndef UNIVERSAL_SURFACE_TYPE_TRANSPARENT_INCLUDED #define UNIVERSAL_SURFACE_TYPE_TRANSPARENT_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" + +// FEATURES_SURFACE_TYPE_TRANSPARENT allows the preprocessor to know if the _SURFACE_TYPE_TRANSPARENT might be used. +// Dynamic branch mode: always true if _SURFACE_TYPE_TRANSPARENT feature exists; query the runtime state with the Available() helper. +// Specialized variants mode: only true when _SURFACE_TYPE_TRANSPARENT is active. +#if (_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_RUNTIME_BRANCHING) + #undef FEATURES_SURFACE_TYPE_TRANSPARENT + #define FEATURES_SURFACE_TYPE_TRANSPARENT 1 +#elif !defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) || (_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED & KEYWORD_TYPE_FLAG_SPECIALIZED_VARIANTS) + #if DEFINED_NONZERO(_SURFACE_TYPE_TRANSPARENT) + #undef FEATURES_SURFACE_TYPE_TRANSPARENT + #define FEATURES_SURFACE_TYPE_TRANSPARENT 1 + #endif +#endif // Utility functionality for Universal RP materials that has the _SURFACE_TYPE_TRANSPARENT shader feature. // The _Surface property has been removed, but we add this is a fallback. -#if defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) || defined(_SURFACE_TYPE_TRANSPARENT) -#if defined(_Surface) -#undef _Surface -#endif -// This property is deprecated. Use parameterless IsSurfaceTypeTransparent() instead. -#define _Surface _SURFACE_TYPE_TRANSPARENT +#if defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + #if defined(_Surface) + #undef _Surface + #endif + + // This property is deprecated. Use parameterless IsSurfaceTypeTransparent() instead. + static const half _Surface = (half)_SURFACE_TYPE_TRANSPARENT; #elif defined(_Surface) // Some shaders hardcode the _Surface property -// Use IsSurfaceTypeTransparent() instead of checking this keyword directly. -#define _SURFACE_TYPE_TRANSPARENT (_Surface > 0) -#define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #if !defined(_SURFACE_TYPE_TRANSPARENT) + // Use IsSurfaceTypeTransparent() instead of checking this keyword directly. + #define _SURFACE_TYPE_TRANSPARENT (_Surface > 0) + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #endif #else -// Use IsSurfaceTypeTransparent() instead of checking this keyword directly. -#define _SURFACE_TYPE_TRANSPARENT 0 -#define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 -// This property is deprecated. Use parameterless IsSurfaceTypeTransparent() instead. -static const half _Surface = 0; + #if !defined(_SURFACE_TYPE_TRANSPARENT) + // Use IsSurfaceTypeTransparent() instead of checking this keyword directly. + #define _SURFACE_TYPE_TRANSPARENT 0 + #define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 + #endif + + // This property is deprecated. Use parameterless IsSurfaceTypeTransparent() instead. + static const half _Surface = 0; #endif // Returns 'True' if the materials Surface Type is set to 'Transparent'. inline bool IsSurfaceTypeTransparent() { - #if defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) || defined(_SURFACE_TYPE_TRANSPARENT) - return _SURFACE_TYPE_TRANSPARENT; + #if defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) + return _SURFACE_TYPE_TRANSPARENT; #else - return false; + #if defined(_SURFACE_TYPE_TRANSPARENT) + return _SURFACE_TYPE_TRANSPARENT; + #else + return false; + #endif #endif } @@ -40,8 +65,8 @@ inline bool IsSurfaceTypeOpaque() // Prevents leaking _SURFACE_TYPE_TRANSPARENT fallback definition. // This makes sure #if defined(_SURFACE_TYPE_TRANSPARENT) doesn't suddenly return true for shaders that include this file. #if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) -#undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY -#undef _SURFACE_TYPE_TRANSPARENT + #undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY + #undef _SURFACE_TYPE_TRANSPARENT #endif #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl index bc495963628..4b3f6c6bdfd 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/Universal2D.hlsl @@ -1,5 +1,6 @@ #ifndef UNIVERSAL_FALLBACK_2D_INCLUDED #define UNIVERSAL_FALLBACK_2D_INCLUDED +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/AlphaBlend.hlsl" struct Attributes { @@ -33,14 +34,13 @@ half4 frag(Varyings input) : SV_Target { UNITY_SETUP_INSTANCE_ID(input); half2 uv = input.uv; - half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); + half4 texColor = SampleBaseMap(uv); half3 color = texColor.rgb * _BaseColor.rgb; half alpha = texColor.a * _BaseColor.a; AlphaDiscard(alpha, _Cutoff); + if (UseAlphaPremultiply()) + color = ApplyAlphaPremultiply(color, alpha); -#ifdef _ALPHAPREMULTIPLY_ON - color *= alpha; -#endif return half4(color, alpha); } diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs new file mode 100644 index 00000000000..f5530a3004d --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs @@ -0,0 +1,263 @@ +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; +using NUnit.Framework; + +namespace UnityEditor.Rendering.Universal.Tests +{ + // The .deprecated.hlsl files exist only for code outside this package; nothing live may + // depend on them, or removing the deprecated surface would break the package itself. + // Deprecated overloads of names that also have live definitions are invisible to this + // name-level scan; the back-compat suites cover those. + class DeprecatedSurfaceIsolationTests + { + const string k_PackageRoot = "Packages/com.unity.render-pipelines.universal"; + const string k_CorePackageRoot = "Packages/com.unity.render-pipelines.core"; + + static readonly string[] k_ScannedFolders = + { + "ShaderLibrary", + "Shaders", + "Runtime/VFXGraph/Shaders", + "Editor/ShaderGraph/Includes", + }; + + static readonly string[] k_CoreScannedFolders = + { + "ShaderLibrary", + "Runtime", + }; + + // Deliberate live includes of a .deprecated file that is not the including file's own + // counterpart. + static readonly (string includingFile, string includedFile)[] k_SanctionedCrossIncludes = + { + ("ShaderLibrary/Core.hlsl", "ShaderLibrary/ForwardPlusKeyword.deprecated.hlsl"), + ("ShaderLibrary/ShaderVariablesFunctions.hlsl", "ShaderLibrary/Fog.deprecated.hlsl"), + }; + + // Existing live references to deprecated-only symbols, pinned with exact counts so they + // cannot grow. Each entry is standing migration debt, not an endorsement. + static readonly (string path, string symbol, int count)[] k_SanctionedReferences = + { + // ShaderGraph includes stay on the deprecated wrappers until the cross-tree layering + // decision for keyword-state access in ShaderGraph passes is made. + ("Editor/ShaderGraph/Includes/PBRForwardPass.hlsl", "AlphaModulate", 1), + ("Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl", "ApplyDecal", 1), + ("Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl", "AlphaModulate", 1), + ("Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl", "AlphaModulate", 1), + ("Editor/ShaderGraph/Includes/UnlitGBufferPass.hlsl", "AlphaModulate", 1), + ("Editor/ShaderGraph/Includes/UnlitPass.hlsl", "AlphaModulate", 1), + }; + + // Deprecated contract macros: defined in live files for back-compat, but nothing live may + // read them outside their defining file (new code uses the USE_* flags). + static readonly (string symbol, string definingFile)[] k_DeprecatedContracts = + { + ("REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR", "ShaderLibrary/Shadows.hlsl"), + ("REQUIRES_LIGHTMAP_UV_INTERPOLATOR", "ShaderLibrary/Lightmaps.hlsl"), + ("REQUIRES_DYNAMICLIGHTMAP_UV_INTERPOLATOR", "ShaderLibrary/Lightmaps.hlsl"), + ("REQUIRES_VERTEX_SH_INTERPOLATOR", "ShaderLibrary/Lightmaps.hlsl"), + }; + + [Test] + public void LiveSourcesDoNotReferenceDeprecatedContractMacros() + { + var violations = new List(); + foreach (var (relativePath, file) in ScannedFiles(k_PackageRoot, k_ScannedFolders, includeDeprecated: false)) + { + string[] lines = StripComments(File.ReadAllText(file)).Split('\n'); + for (int i = 0; i < lines.Length; i++) + { + foreach (var (symbol, definingFile) in k_DeprecatedContracts) + { + if (relativePath == definingFile) + continue; + if (Regex.IsMatch(lines[i], $@"\b{symbol}\b")) + violations.Add($"{relativePath}:{i + 1}: {lines[i].Trim()}"); + } + } + } + Assert.IsEmpty(violations, + "Live source(s) reference deprecated contract macro(s):\n" + string.Join("\n", violations) + + "\nThese names keep their pre-conversion semantics for external code only; read the " + + "corresponding USE_* interpolator flag instead."); + } + + static readonly Regex k_Include = new Regex( + @"^\s*#\s*include(?:_with_pragmas)?\s+""([^""]+\.deprecated\.hlsl)""", + RegexOptions.Compiled); + // Return type = builtin scalar/vector/matrix, or a struct name (PascalCase with at least + // one lowercase letter, so all-caps macros like UNITY_BRANCH never parse as a type). + static readonly Regex k_FunctionDefinition = new Regex( + @"^\s*(?:inline\s+)?(?:(?:half|float|real|void|bool|int|uint|min16float)(?:[1-4](?:x[1-4])?)?|[A-Z]\w*[a-z]\w*)\s+(\w+)\s*\(", + RegexOptions.Compiled | RegexOptions.Multiline); + static readonly Regex k_MacroDefinition = new Regex( + @"^\s*#\s*define\s+(\w+)", RegexOptions.Compiled | RegexOptions.Multiline); + static readonly Regex k_MacroUndef = new Regex( + @"^\s*#\s*undef\s+(\w+)", RegexOptions.Compiled | RegexOptions.Multiline); + static readonly Regex k_StringLiteral = new Regex(@"""[^""]*""", RegexOptions.Compiled); + + [Test] + public void DeprecatedIncludesComeOnlyFromTheirLiveCounterparts() + { + var violations = new List(); + var seenSanctioned = new HashSet<(string, string)>(); + foreach (var (relativePath, file) in ScannedFiles(k_PackageRoot, k_ScannedFolders, includeDeprecated: true)) + { + bool includerIsDeprecated = relativePath.Contains(".deprecated."); + int lineNumber = 0; + foreach (string line in StripComments(File.ReadAllText(file)).Split('\n')) + { + lineNumber++; + var match = k_Include.Match(line); + if (!match.Success) + continue; + if (includerIsDeprecated) + continue; + + string included = match.Groups[1].Value.Replace('\\', '/'); + if (included.StartsWith(k_PackageRoot + "/")) + included = included.Substring(k_PackageRoot.Length + 1); + else if (!included.Contains("/")) + included = Path.GetDirectoryName(relativePath).Replace('\\', '/') + "/" + included; + + string ownCounterpart = relativePath.Substring(0, relativePath.Length - ".hlsl".Length) + ".deprecated.hlsl"; + if (relativePath.EndsWith(".hlsl") && included == ownCounterpart) + continue; + if (System.Array.IndexOf(k_SanctionedCrossIncludes, (relativePath, included)) >= 0) + { + seenSanctioned.Add((relativePath, included)); + continue; + } + violations.Add($"{relativePath}:{lineNumber}: #include \"{included}\""); + } + } + + Assert.IsEmpty(violations, + "Live source(s) include a .deprecated.hlsl file that is not their own counterpart:\n" + + string.Join("\n", violations) + "\n" + + "The deprecated surface exists only for old code outside this package. Use the live " + + "API instead, or add the pair to k_SanctionedCrossIncludes with a justification."); + Assert.AreEqual(k_SanctionedCrossIncludes.Length, seenSanctioned.Count, + "k_SanctionedCrossIncludes no longer matches the sources (include removed or moved) - " + + "update the table."); + } + + [Test] + public void LiveSourcesDoNotReferenceDeprecatedOnlySymbols() + { + GatherDefinitions(k_PackageRoot, k_ScannedFolders, deprecated: true, + out var deprecatedFunctions, out var deprecatedMacros, out var deprecatedUndefs); + GatherDefinitions(k_PackageRoot, k_ScannedFolders, deprecated: false, + out var liveFunctions, out var liveMacros, out _); + GatherDefinitions(k_CorePackageRoot, k_CoreScannedFolders, deprecated: false, + out var coreFunctions, out var coreMacros, out _); + + deprecatedFunctions.ExceptWith(liveFunctions); + deprecatedFunctions.ExceptWith(coreFunctions); + deprecatedMacros.ExceptWith(liveMacros); + deprecatedMacros.ExceptWith(coreMacros); + deprecatedMacros.ExceptWith(deprecatedUndefs); + deprecatedMacros.RemoveWhere(m => m.EndsWith("_INCLUDED") || m.EndsWith("_DEFINED_LOCALLY")); + Assert.NotZero(deprecatedFunctions.Count + deprecatedMacros.Count, + "Found no deprecated-only symbols; the extraction is broken or the deprecated files moved."); + + var functionReference = new Regex(@"\b(" + string.Join("|", deprecatedFunctions) + @")\s*\("); + var macroReference = new Regex(@"\b(" + string.Join("|", deprecatedMacros) + @")\b"); + + var found = new Dictionary<(string path, string symbol), List>(); + foreach (var (relativePath, file) in ScannedFiles(k_PackageRoot, k_ScannedFolders, includeDeprecated: false)) + { + string[] lines = StripComments(File.ReadAllText(file)).Split('\n'); + for (int i = 0; i < lines.Length; i++) + { + string line = k_StringLiteral.Replace(lines[i], "\"\""); + foreach (Match match in functionReference.Matches(line)) + AddSite(found, relativePath, match.Groups[1].Value, i + 1, lines[i]); + foreach (Match match in macroReference.Matches(line)) + AddSite(found, relativePath, match.Groups[1].Value, i + 1, lines[i]); + } + } + + var sanctioned = new Dictionary<(string path, string symbol), int>(); + foreach (var (path, symbol, count) in k_SanctionedReferences) + sanctioned.Add((path, symbol), count); + + var violations = new List(); + foreach (var (key, sites) in found) + { + sanctioned.TryGetValue(key, out int allowed); + if (sites.Count > allowed) + violations.AddRange(sites); + } + var stale = new List(); + foreach (var (key, count) in sanctioned) + { + if (!found.TryGetValue(key, out var sites) || sites.Count != count) + stale.Add($"{key.path} ({key.symbol}, expected {count})"); + } + + Assert.IsEmpty(violations, + "Live source(s) reference symbol(s) that are only defined in .deprecated.hlsl files:\n" + + string.Join("\n", violations) + "\n" + + "These definitions disappear when the deprecated surface is removed. Use the live " + + "replacement instead, or add the site to k_SanctionedReferences with a justification."); + Assert.IsEmpty(stale, + "k_SanctionedReferences no longer matches the sources (reference removed or moved) - " + + "update the table:\n" + string.Join("\n", stale)); + } + + static void AddSite(Dictionary<(string, string), List> found, string path, string symbol, + int lineNumber, string line) + { + if (!found.TryGetValue((path, symbol), out var sites)) + found[(path, symbol)] = sites = new List(); + sites.Add($"{path}:{lineNumber}: {line.Trim()}"); + } + + static IEnumerable<(string relativePath, string file)> ScannedFiles( + string packageRoot, string[] folders, bool includeDeprecated) + { + foreach (string folder in folders) + { + string root = Path.GetFullPath(packageRoot + "/" + folder); + if (!Directory.Exists(root)) + continue; + foreach (string file in Directory.EnumerateFiles(root, "*.*", SearchOption.AllDirectories)) + { + if (!file.EndsWith(".hlsl") && !file.EndsWith(".shader")) + continue; + if (!includeDeprecated && file.Contains(".deprecated.")) + continue; + yield return (folder + "/" + file.Substring(root.Length + 1).Replace('\\', '/'), file); + } + } + } + + static void GatherDefinitions(string packageRoot, string[] folders, bool deprecated, + out HashSet functions, out HashSet macros, out HashSet undefs) + { + functions = new HashSet(); + macros = new HashSet(); + undefs = new HashSet(); + foreach (var (relativePath, file) in ScannedFiles(packageRoot, folders, includeDeprecated: true)) + { + if (relativePath.Contains(".deprecated.") != deprecated) + continue; + string source = StripComments(File.ReadAllText(file)); + foreach (Match match in k_FunctionDefinition.Matches(source)) + functions.Add(match.Groups[1].Value); + foreach (Match match in k_MacroDefinition.Matches(source)) + macros.Add(match.Groups[1].Value); + foreach (Match match in k_MacroUndef.Matches(source)) + undefs.Add(match.Groups[1].Value); + } + } + + static string StripComments(string source) + { + return DynamicKeywordGuardTests.StripComments(source); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs.meta b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs.meta new file mode 100644 index 00000000000..3db5a65bd28 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DeprecatedSurfaceIsolationTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b0edc54c9f5c415388424b6ccf3a3a3a diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs new file mode 100644 index 00000000000..fc07939d264 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs @@ -0,0 +1,391 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; +using NUnit.Framework; +using UnityEditor.Shaders; +using UnityEngine; + +namespace UnityEditor.Rendering.Universal.Tests +{ + // A compile-time preprocessor check on a keyword declared with variantGenerationMode 3 + // (dynamic branching) makes the shader compiler silently fall back to specialized variants. + // These tests fail when a converted keyword regains such a check. + class DynamicKeywordGuardTests + { + static readonly string[] k_ConvertibleKeywords = + { + "DIRLIGHTMAP_COMBINED", + "DYNAMICLIGHTMAP_ON", + "EVALUATE_SH_MIXED", + "EVALUATE_SH_VERTEX", + "LIGHTMAP_ON", + "LIGHTMAP_SHADOW_MIXING", + "LOD_FADE_CROSSFADE", + "REFLECTION_PROBE_ROTATION", + "SHADOWS_SHADOWMASK", + "_ADDITIONAL_LIGHT_SHADOWS", + "_ALPHAMODULATE_ON", + "_ALPHAPREMULTIPLY_ON", + "_CLEARCOAT", + "_CLEARCOATMAP", + "_EMISSION", + "_ENVIRONMENTREFLECTIONS_OFF", + "_GBUFFER_NORMALS_OCT", + "_GLOSSINESS_FROM_BASE_ALPHA", + "_LIGHT_COOKIES", + "_LIGHT_LAYERS", + "_MAIN_LIGHT_SHADOWS", + "_MAIN_LIGHT_SHADOWS_CASCADE", + "_MAIN_LIGHT_SHADOWS_SCREEN", + "_METALLICSPECGLOSSMAP", + "_NORMALMAP", + "_OCCLUSIONMAP", + "_PARALLAXMAP", + "_RECEIVE_SHADOWS_OFF", + "_REFLECTION_PROBE_BLENDING", + "_SCREEN_SPACE_OCCLUSION", + "_SCREEN_SPACE_REFLECTION", + "_SHADOWS_SOFT", + "_SHADOWS_SOFT_HIGH", + "_SHADOWS_SOFT_LOW", + "_SHADOWS_SOFT_MEDIUM", + "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", + "_SPECGLOSSMAP", + "_SPECULARHIGHLIGHTS_OFF", + "_SPECULAR_COLOR", + "_SPECULAR_SETUP", + "_SURFACE_TYPE_TRANSPARENT", + }; + + static readonly HashSet k_ConvertibleKeywordSet = new HashSet(k_ConvertibleKeywords); + + // Deliberate compile-time references known not to break the dynamic declarations + static readonly (string path, string keyword, int count)[] k_SanctionedGuards = + { + ("ShaderLibrary/GBufferCommon.hlsl", "SHADOWS_SHADOWMASK", 1), + ("ShaderLibrary/GBufferCommon.hlsl", "LIGHTMAP_SHADOW_MIXING", 1), + ("ShaderLibrary/GBufferCommon.hlsl", "_LIGHT_LAYERS", 1), + ("Shaders/2D/Light2D.shader", "_LIGHT_LAYERS", 1), + + // ShaderGraph includes. _SURFACE_TYPE_TRANSPARENT is a per-material #define in + // generated code (not a declared keyword), so static tests on it are by design + // (includes the volumetric fog _TRANSPARENT_RECEIVE_FOG sites). + // The remaining feature-keyword guards are standing migration debt: conversion is + // blocked on the cross-tree layering decision for keyword-state access in + // ShaderGraph passes (same debt class as k_SanctionedReferences in + // DeprecatedSurfaceIsolationTests). + ("Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl", "_NORMALMAP", 1), + ("Editor/ShaderGraph/Includes/MotionVectorPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 1), + ("Editor/ShaderGraph/Includes/PBR2DPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 1), + ("Editor/ShaderGraph/Includes/PBRForwardPass.hlsl", "_NORMALMAP", 2), + ("Editor/ShaderGraph/Includes/PBRForwardPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 4), + ("Editor/ShaderGraph/Includes/PBRForwardPass.hlsl", "_SPECULAR_SETUP", 1), + ("Editor/ShaderGraph/Includes/PBRForwardPass.hlsl", "_CLEARCOAT", 1), + ("Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl", "_NORMALMAP", 1), + ("Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 1), + ("Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl", "_SPECULAR_SETUP", 1), + ("Editor/ShaderGraph/Includes/SixWayForwardPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 3), + ("Editor/ShaderGraph/Includes/UnlitPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 5), + ("Editor/ShaderGraph/Includes/Varyings.hlsl", "_NORMALMAP", 1), + ("Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl", "_NORMALMAP", 1), + ("Editor/ShaderGraph/Includes/Terrain/PBRForwardPass.hlsl", "_SURFACE_TYPE_TRANSPARENT", 1), + ("Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl", "_NORMALMAP", 1), + }; + + enum RestrictionScope + { + // Only where the compile-time consumer lives; the other declaring passes stay convertible + SomePasses, + + // The keyword only exists on restricted passes + AllPasses, + } + + // Expected: the shadowmask and rendering-layer keywords select the GBuffer render target + // layout (GBufferCommon.hlsl), so the GBuffer pass can never convert them to dynamic + // branches; passes without that dependency can, which is what a SomePasses scope pins. + static readonly (string shader, string keyword, RestrictionScope scope)[] k_ExpectedRestrictions = + { + ("Lit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.SomePasses), + ("Lit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.SomePasses), + ("SimpleLit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.SomePasses), + ("SimpleLit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.SomePasses), + ("Unlit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("BakedLit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/TerrainLit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/TerrainLit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Terrain/TerrainLit.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Particles/ParticlesLit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.SomePasses), + ("Particles/ParticlesSimpleLit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.SomePasses), + ("2D/Light2D.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("ComplexLit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.SomePasses), + ("ComplexLit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.SomePasses), + ("Nature/SpeedTree7.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Nature/SpeedTree8.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Terrain/TerrainDetailLit.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/TerrainDetailLit.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Terrain/TerrainLitAdd.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/TerrainLitAdd.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Terrain/TerrainLitAdd.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Terrain/TerrainLitBase.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/TerrainLitBase.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Terrain/TerrainLitBase.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Terrain/WavingGrass.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/WavingGrass.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Terrain/WavingGrass.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Terrain/WavingGrassBillboard.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Terrain/WavingGrassBillboard.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Utils/ClusterDeferred.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Utils/ClusterDeferred.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Utils/ClusterDeferred.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + ("Utils/StencilDeferred.shader", "SHADOWS_SHADOWMASK", RestrictionScope.AllPasses), + ("Utils/StencilDeferred.shader", "LIGHTMAP_SHADOW_MIXING", RestrictionScope.AllPasses), + ("Utils/StencilDeferred.shader", "_LIGHT_LAYERS", RestrictionScope.AllPasses), + }; + + const string k_PackageRoot = "Packages/com.unity.render-pipelines.universal"; + const string k_ShippedShaderFolder = "Shaders"; + static readonly string[] k_ScannedFolders = { "ShaderLibrary", "Shaders", "Editor/ShaderGraph/Includes" }; + + static readonly Regex k_Directive = new Regex(@"^\s*#\s*(if|elif|else|endif|ifdef|ifndef)\b(.*)$", RegexOptions.Compiled); + static readonly Regex k_AnyConvertibleKeyword = new Regex( + @"\b(" + string.Join("|", k_ConvertibleKeywords) + @")\b", RegexOptions.Compiled); + static readonly Regex k_DeclaredSymbol = new Regex(@"\b(\w+)_KEYWORD_DECLARED\b", RegexOptions.Compiled); + static readonly Regex k_DefinedNonZeroArm = new Regex(@"DEFINED_NONZERO\s*\(\s*$", RegexOptions.Compiled); + + static IEnumerable ShippedShaders() + { + string root = Path.GetFullPath(k_PackageRoot + "/" + k_ShippedShaderFolder); + var paths = new List(); + foreach (string file in Directory.EnumerateFiles(root, "*.shader", SearchOption.AllDirectories)) + paths.Add(file.Substring(root.Length + 1).Replace('\\', '/')); + paths.Sort(); + return paths; + } + + [Test] + public void ShaderKeywordsRemainDynamicBranchConvertible( + [ValueSource(nameof(ShippedShaders))] string shaderPath) + { + string assetPath = k_PackageRoot + "/" + k_ShippedShaderFolder + "/" + shaderPath; + var shader = AssetDatabase.LoadAssetAtPath(assetPath); + Assert.IsNotNull(shader, $"Failed to load shader at path '{assetPath}'"); + + var expected = new Dictionary(); + foreach (var (entryShader, keyword, scope) in k_ExpectedRestrictions) + { + if (entryShader == shaderPath) + expected.Add(keyword, scope); + } + + var unexpected = new List(); + var spread = new List(); + var narrowed = new List(); + var unusedExpected = new HashSet(expected.Keys); + foreach (var declaration in ShaderKeywordDeclarations.GatherFromShader(shader)) + { + bool restrictedAny = declaration.IsRestrictedInAnyInstance(ShaderKeywordOverrideRestriction.NoDynamicBranch); + if (!restrictedAny) + continue; + + bool restrictedEvery = declaration.IsRestrictedInEveryInstance(ShaderKeywordOverrideRestriction.NoDynamicBranch); + foreach (string keyword in declaration.keywords) + { + if (!k_ConvertibleKeywordSet.Contains(keyword)) + continue; + + if (!expected.TryGetValue(keyword, out var scope)) + unexpected.Add(keyword); + else if (scope == RestrictionScope.SomePasses && restrictedEvery) + spread.Add(keyword); + else if (scope == RestrictionScope.AllPasses && !restrictedEvery) + narrowed.Add(keyword); + unusedExpected.Remove(keyword); + } + } + + Assert.IsEmpty(unexpected, + $"Shader '{shader.name}' no longer supports dynamic branching (variantGenerationMode 3) for: " + + string.Join(", ", unexpected) + ". A compile-time preprocessor test on the keyword was " + + "introduced somewhere in the shader's include graph. Read the keyword at runtime " + + "(if (KW)) instead, or extend k_ExpectedRestrictions with a justification."); + Assert.IsEmpty(spread, + $"Shader '{shader.name}' is now restricted in EVERY pass declaring: " + + string.Join(", ", spread) + ". The sanctioned restriction covers only some passes; " + + "a compile-time preprocessor check on the keyword was introduced in a pass " + + "that must stay dynamic-branch convertible."); + Assert.IsEmpty(narrowed, + $"Shader '{shader.name}' is no longer restricted in every pass declaring: " + + string.Join(", ", narrowed) + ". Change the scope to SomePasses in " + + "k_ExpectedRestrictions so the improvement stays locked in."); + Assert.IsEmpty(unusedExpected, + $"Shader '{shader.name}' is dynamic-branch convertible again for: " + + string.Join(", ", unusedExpected) + ". Remove the pair(s) from k_ExpectedRestrictions " + + "so the improvement stays locked in."); + } + + [Test] + public void PackageSourcesHaveNoUnsanctionedStaticGuardsOnConvertibleKeywords() + { + var found = new Dictionary<(string path, string keyword), List>(); + int scannedFileCount = 0; + foreach (string folder in k_ScannedFolders) + { + string root = Path.GetFullPath(k_PackageRoot + "/" + folder); + foreach (string file in Directory.EnumerateFiles(root, "*.*", SearchOption.AllDirectories)) + { + if (!file.EndsWith(".hlsl") && !file.EndsWith(".shader")) + continue; + if (file.Contains(".deprecated.")) + continue; + + scannedFileCount++; + string relativePath = folder + "/" + + file.Substring(root.Length + 1).Replace('\\', '/'); + foreach (var (lineNumber, keyword, line) in FindStaticGuards(file)) + { + if (!found.TryGetValue((relativePath, keyword), out var sites)) + found[(relativePath, keyword)] = sites = new List(); + sites.Add($"{relativePath}:{lineNumber}: {line}"); + } + } + } + Assert.NotZero(scannedFileCount, "Scanned no shader source files; package layout changed?"); + + var sanctioned = new Dictionary<(string path, string keyword), int>(); + foreach (var (path, keyword, count) in k_SanctionedGuards) + sanctioned.Add((path, keyword), count); + + var violations = new List(); + foreach (var (key, sites) in found) + { + sanctioned.TryGetValue(key, out int allowed); + if (sites.Count > allowed) + violations.AddRange(sites); + } + var stale = new List(); + foreach (var (key, count) in sanctioned) + { + if (!found.TryGetValue(key, out var sites) || sites.Count != count) + stale.Add($"{key.path} ({key.keyword}, expected {count})"); + } + + Assert.IsEmpty(violations, + "Static preprocessor guard(s) found on dynamic-branch convertible keyword(s):\n" + + string.Join("\n", violations) + "\n" + + "These keywords are declared with variantGenerationMode 3 (dynamic branch) by URP " + + "test projects; a compile-time #if/#ifdef on them makes the compiler silently fall " + + "back to specialized variants. Read the keyword at runtime (if (KW)) instead, or " + + "add the site to k_SanctionedGuards with a justification."); + Assert.IsEmpty(stale, + "k_SanctionedGuards no longer matches the sources (guard removed or moved) - " + + "update the table:\n" + string.Join("\n", stale)); + } + + static IEnumerable<(int lineNumber, string keyword, string line)> FindStaticGuards(string file) + { + var reportedKeywords = new HashSet(); + string[] lines = StripComments(File.ReadAllText(file)).Split('\n'); + + // Conditional-block stack. Each entry holds the keywords whose _KEYWORD_DECLARED + // symbol the block's condition tests: inside such a block, compile-time tests on + // itself are the sanctioned declaration-aware normalization shape, not a restriction. + var declaredScopes = new List>(); + + for (int i = 0; i < lines.Length; i++) + { + int lineNumber = i + 1; + string line = lines[i]; + while (line.TrimEnd().EndsWith(@"\") && i + 1 < lines.Length) + line = line.TrimEnd().TrimEnd('\\') + " " + lines[++i]; + + var match = k_Directive.Match(line); + if (!match.Success) + continue; + + string directive = match.Groups[1].Value; + string expr = match.Groups[2].Value; + + if (directive == "endif") + { + if (declaredScopes.Count > 0) + declaredScopes.RemoveAt(declaredScopes.Count - 1); + continue; + } + if (directive == "else") + continue; + + var exprDeclared = new HashSet(); + foreach (Match declared in k_DeclaredSymbol.Matches(expr)) + exprDeclared.Add(declared.Groups[1].Value); + + bool Exempt(string keyword) + { + if (exprDeclared.Contains(keyword)) + return true; + foreach (var scope in declaredScopes) + { + if (scope.Contains(keyword)) + return true; + } + return false; + } + + if (directive == "elif") + { + // An #elif arm belongs to the enclosing #if block; fold its declared + // symbols into that block's exemption set. + if (declaredScopes.Count > 0) + declaredScopes[declaredScopes.Count - 1].UnionWith(exprDeclared); + } + + reportedKeywords.Clear(); + foreach (Match occurrence in k_AnyConvertibleKeyword.Matches(expr)) + { + // DEFINED_NONZERO(KW) is the sanctioned value-less normalization arm. + if (k_DefinedNonZeroArm.IsMatch(expr.Substring(0, occurrence.Index))) + continue; + if (!Exempt(occurrence.Value) && reportedKeywords.Add(occurrence.Value)) + yield return (lineNumber, occurrence.Value, line.Trim()); + } + + if (directive == "if" || directive == "ifdef" || directive == "ifndef") + declaredScopes.Add(exprDeclared); + } + } + + // Removes // and /* */ comments while preserving newlines, so reported line numbers + // match the source file. + internal static string StripComments(string source) + { + var result = new System.Text.StringBuilder(source.Length); + for (int i = 0; i < source.Length; i++) + { + if (source[i] == '/' && i + 1 < source.Length && source[i + 1] == '/') + { + while (i < source.Length && source[i] != '\n') + i++; + if (i < source.Length) + result.Append('\n'); + } + else if (source[i] == '/' && i + 1 < source.Length && source[i + 1] == '*') + { + i += 2; + while (i + 1 < source.Length && !(source[i] == '*' && source[i + 1] == '/')) + { + if (source[i] == '\n') + result.Append('\n'); + i++; + } + i++; + } + else + { + result.Append(source[i]); + } + } + return result.ToString(); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs.meta b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs.meta new file mode 100644 index 00000000000..0663feb313b --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/DynamicKeywordGuardTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 85188203a23ca4ec5a53be9a97c6eb5f \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs new file mode 100644 index 00000000000..511b4246145 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; +using NUnit.Framework; + +namespace UnityEditor.Rendering.Universal.Tests +{ + // ShaderLibrary/ must not depend on the material-level Shaders/ tree. + class ShaderLibraryLayeringTests + { + const string k_PackageRoot = "Packages/com.unity.render-pipelines.universal"; + + static readonly Regex k_ShadersInclude = new Regex( + @"^\s*#\s*include(_with_pragmas)?\s+""Packages/com\.unity\.render-pipelines\.universal/Shaders/", + RegexOptions.Compiled); + + static readonly (string path, int count)[] k_SanctionedIncludes = + { + // Pre-existing 2D debt: InputData2D/SurfaceData2D structs live in Shaders/2D/Include. + ("ShaderLibrary/Debug/Debugging2D.hlsl", 2), + }; + + [Test] + public void ShaderLibraryDoesNotIncludeShadersTree() + { + var found = new Dictionary>(); + int scannedFileCount = 0; + string root = Path.GetFullPath(k_PackageRoot + "/ShaderLibrary"); + foreach (string file in Directory.EnumerateFiles(root, "*.hlsl", SearchOption.AllDirectories)) + { + if (file.Contains(".deprecated.")) + continue; + + scannedFileCount++; + string relativePath = "ShaderLibrary/" + file.Substring(root.Length + 1).Replace('\\', '/'); + string[] lines = File.ReadAllLines(file); + for (int i = 0; i < lines.Length; i++) + { + if (!k_ShadersInclude.IsMatch(lines[i])) + continue; + if (!found.TryGetValue(relativePath, out var sites)) + found[relativePath] = sites = new List(); + sites.Add($"{relativePath}:{i + 1}: {lines[i].Trim()}"); + } + } + Assert.NotZero(scannedFileCount, "Scanned no ShaderLibrary files; package layout changed?"); + + var sanctioned = new Dictionary(); + foreach (var (path, count) in k_SanctionedIncludes) + sanctioned.Add(path, count); + + var violations = new List(); + foreach (var (path, sites) in found) + { + sanctioned.TryGetValue(path, out int allowed); + if (sites.Count > allowed) + violations.AddRange(sites); + } + var stale = new List(); + foreach (var (path, count) in sanctioned) + { + if (!found.TryGetValue(path, out var sites) || sites.Count != count) + stale.Add($"{path} (expected {count})"); + } + + Assert.IsEmpty(violations, + "ShaderLibrary file(s) include the Shaders/ tree:\n" + string.Join("\n", violations) + "\n" + + "ShaderLibrary must not depend on material-level modules; pass shader_feature " + + "state into library functions as parameters instead."); + Assert.IsEmpty(stale, + "k_SanctionedIncludes no longer matches the sources - update the table:\n" + + string.Join("\n", stale)); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs.meta b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs.meta new file mode 100644 index 00000000000..b71e1e8658b --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderLibraryLayeringTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f9126f4cb356346da9f3d803ea30b6d5 \ No newline at end of file diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/000_ForwardPlus_Many.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/000_ForwardPlus_Many.unity index 70bc9523a3c..62e95916696 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/000_ForwardPlus_Many.unity +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/000_ForwardPlus_Many.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dee5e792599b6786571375bcadea3bad3f53100c34cbf2ca534d17f6fc791bb -size 923624 +oid sha256:f64fe725770707a30a33e2c7c19e7c2bf5045b9edaa9fa1e06354100fd12f5ae +size 923622 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/055_SoftShadowQuality_High.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/055_SoftShadowQuality_High.unity index 7f96ecf3f9d..167decd9d11 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/055_SoftShadowQuality_High.unity +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/055_SoftShadowQuality_High.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac0660e29803a36e046d6d863883a700825bcec32e24bf06be39023678a5a557 -size 44801 +oid sha256:c03279e4f6b36a11e9cfe9afc586e87d9d2c6e8c6e5af6b96c6cc584b1d2ede7 +size 44802 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/350_VRS/VRS_Unlit.shader b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/350_VRS/VRS_Unlit.shader index 807fd07ef18..d86436eadad 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/350_VRS/VRS_Unlit.shader +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/350_VRS/VRS_Unlit.shader @@ -270,7 +270,7 @@ Shader "Universal Render Pipeline/VRS_Unlit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL } @@ -295,7 +295,7 @@ Shader "Universal Render Pipeline/VRS_Unlit" #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #define APLICATION_SPACE_WARP_MOTION 1 #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Utils/ObjectMotionVectors.hlsl" ENDHLSL }*/ } diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs deleted file mode 100644 index bbf467f831a..00000000000 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs +++ /dev/null @@ -1,297 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; -using UnityEngine.TestTools; -using Object = UnityEngine.Object; - -// Direct lighting rendered through the real pipeline and compared against values derived -// from the material model. -[UnityPlatform(exclude = new[] { RuntimePlatform.WebGLPlayer })] -class AnalyticDirectLightingTests -{ - const int k_Size = 64; - // min16float lets the two inlined evaluations round apart, so allow a few fp16 ULP of the ~0.5 output, well under the 0.12 a defect shows. - const float k_MaxOverloadDifference = 4e-3f; - - Camera m_Camera; - Light m_Light; - GameObject m_Quad; - RenderTexture m_RenderTexture; - readonly List m_Materials = new List(); - - AmbientMode m_SavedAmbientMode; - Color m_SavedAmbientLight; - Material m_SavedSkybox; - bool m_SavedFog; - float m_SavedReflectionIntensity; -#if UNITY_EDITOR - bool m_SavedAsyncCompilation; -#endif - - [SetUp] - public void SetUp() - { - if (GraphicsSettings.currentRenderPipeline is not UniversalRenderPipelineAsset) - Assert.Ignore("URP only test"); - if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat)) - Assert.Ignore("This device does not support ARGBFloat render targets."); - - var threadingMode = SystemInfo.renderingThreadingMode; - var nativeGraphicsJobs = threadingMode == RenderingThreadingMode.NativeGraphicsJobs - || threadingMode == RenderingThreadingMode.NativeGraphicsJobsWithoutRenderThread - || threadingMode == RenderingThreadingMode.NativeGraphicsJobsSplitThreading; - if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12 && nativeGraphicsJobs) - Assert.Ignore("The first render after a material change is lost on D3D12 with native or split graphics jobs. Tracking: UUM-147205"); - -#if UNITY_EDITOR - m_SavedAsyncCompilation = UnityEditor.ShaderUtil.allowAsyncCompilation; - UnityEditor.ShaderUtil.allowAsyncCompilation = false; -#endif - m_SavedAmbientMode = RenderSettings.ambientMode; - m_SavedAmbientLight = RenderSettings.ambientLight; - m_SavedSkybox = RenderSettings.skybox; - m_SavedFog = RenderSettings.fog; - m_SavedReflectionIntensity = RenderSettings.reflectionIntensity; - - RenderSettings.ambientMode = AmbientMode.Flat; - RenderSettings.ambientLight = Color.black; - RenderSettings.skybox = null; - RenderSettings.fog = false; - RenderSettings.reflectionIntensity = 0f; - - var cameraGo = new GameObject("TEST_AnalyticLightingCamera"); - m_Camera = cameraGo.AddComponent(); - m_Camera.enabled = false; - m_Camera.orthographic = true; - m_Camera.orthographicSize = 0.4f; - m_Camera.transform.position = new Vector3(0f, 0f, -3f); - m_Camera.clearFlags = CameraClearFlags.SolidColor; - m_Camera.backgroundColor = new Color(0f, 0f, 0f, 0f); - var cameraData = m_Camera.GetUniversalAdditionalCameraData(); - cameraData.renderPostProcessing = false; - cameraData.antialiasing = AntialiasingMode.None; - - var lightGo = new GameObject("TEST_AnalyticLightingLight"); - m_Light = lightGo.AddComponent(); - m_Light.type = LightType.Directional; - m_Light.color = Color.white; - m_Light.intensity = 1f; - m_Light.shadows = LightShadows.None; - - m_Quad = GameObject.CreatePrimitive(PrimitiveType.Quad); - m_Quad.name = "TEST_AnalyticLightingQuad"; - Object.DestroyImmediate(m_Quad.GetComponent()); - var renderer = m_Quad.GetComponent(); - renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; - renderer.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; - renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; - - m_RenderTexture = new RenderTexture(k_Size, k_Size, 24, RenderTextureFormat.ARGBFloat); - m_RenderTexture.Create(); - } - - [TearDown] - public void TearDown() - { - if (GraphicsSettings.currentRenderPipeline is not UniversalRenderPipelineAsset) - return; - - RenderSettings.ambientMode = m_SavedAmbientMode; - RenderSettings.ambientLight = m_SavedAmbientLight; - RenderSettings.skybox = m_SavedSkybox; - RenderSettings.fog = m_SavedFog; - RenderSettings.reflectionIntensity = m_SavedReflectionIntensity; -#if UNITY_EDITOR - UnityEditor.ShaderUtil.allowAsyncCompilation = m_SavedAsyncCompilation; -#endif - - foreach (var material in m_Materials) - Object.DestroyImmediate(material); - m_Materials.Clear(); - - if (m_Quad != null) - Object.DestroyImmediate(m_Quad); - if (m_Light != null) - Object.DestroyImmediate(m_Light.gameObject); - if (m_Camera != null) - Object.DestroyImmediate(m_Camera.gameObject); - if (m_RenderTexture != null) - { - m_RenderTexture.Release(); - Object.DestroyImmediate(m_RenderTexture); - } - } - - [UnityTest] - public IEnumerator DeprecatedLightingOverload_MatchesCanonicalOverload( - [Values(false, true)] bool specularKeywordOff, - [Values(false, true)] bool specularArgumentOff) - { - var material = CreateMaterial(Shader.Find("Hidden/Test/LightingOverloadConsistency")); - if (specularKeywordOff) - material.EnableKeyword("_SPECULARHIGHLIGHTS_OFF"); - material.SetFloat("_SpecularHighlightsOffArg", specularArgumentOff ? 1f : 0f); - m_Quad.GetComponent().sharedMaterial = material; - yield return null; - - var pixel = RenderCenterPixel(); - - Assert.That(pixel.a, Is.GreaterThan(0.1f), "positive control: the quad must draw a finite canonical value"); - Assert.That(pixel.r, Is.InRange(0f, k_MaxOverloadDifference), "red channel of |canonical - deprecated|"); - Assert.That(pixel.g, Is.InRange(0f, k_MaxOverloadDifference), "green channel of |canonical - deprecated|"); - Assert.That(pixel.b, Is.InRange(0f, k_MaxOverloadDifference), "blue channel of |canonical - deprecated|"); - } - - [UnityTest] - public IEnumerator DiffuseFollowsCosineFalloff() - { - UseLitQuad(smoothness: 0f, specularHighlights: false); - yield return null; - - var headOn = RenderCenterPixel().g; - SetLightAngle(30f); - var at30 = RenderCenterPixel().g; - SetLightAngle(60f); - var at60 = RenderCenterPixel().g; - - Assert.That(headOn, Is.GreaterThan(0.05f), "head-on diffuse should be clearly lit"); - Assert.That(at30 / headOn, Is.EqualTo(Mathf.Cos(30f * Mathf.Deg2Rad)).Within(3).Percent, "cos(30) falloff ratio"); - Assert.That(at60 / headOn, Is.EqualTo(Mathf.Cos(60f * Mathf.Deg2Rad)).Within(3).Percent, "cos(60) falloff ratio"); - } - - [UnityTest] - public IEnumerator DiffuseIsLinearInLightIntensity() - { - UseLitQuad(smoothness: 0f, specularHighlights: false); - yield return null; - - m_Light.intensity = 0.4f; - var dim = RenderCenterPixel().g; - m_Light.intensity = 0.8f; - var bright = RenderCenterPixel().g; - - Assert.That(dim, Is.GreaterThan(0.05f), "dim render should be clearly lit"); - Assert.That(bright / dim, Is.EqualTo(2f).Within(3).Percent, "doubling intensity should double the response"); - } - - [UnityTest] - public IEnumerator BackfacingLightContributesNothing() - { - var albedo = new Color(0.4f, 1f, 0.7f); - var lightColor = new Color(0.9f, 1f, 0.95f); - UseLitQuad(smoothness: 0f, specularHighlights: false, albedo, lightColor); - yield return null; - - var headOn = RenderCenterPixel(); - Assert.That(headOn.r, Is.GreaterThan(0.05f), "positive control red"); - Assert.That(headOn.g, Is.GreaterThan(0.05f), "positive control green"); - Assert.That(headOn.b, Is.GreaterThan(0.05f), "positive control blue"); - - SetLightAngle(120f); - var backface = RenderCenterPixel(); - Assert.That(backface.r, Is.InRange(0f, 0.01f), "backface red"); - Assert.That(backface.g, Is.InRange(0f, 0.01f), "backface green"); - Assert.That(backface.b, Is.InRange(0f, 0.01f), "backface blue"); - } - - [UnityTest] - public IEnumerator DiffuseMatchesDielectricMaterialModel() - { - var albedo = new Color(1f, 0.7f, 0.4f); - var lightColor = new Color(1f, 0.95f, 0.9f); - UseLitQuad(smoothness: 0f, specularHighlights: false, albedo, lightColor); - yield return null; - - var pixel = RenderCenterPixel(); - - // With _Metallic 0, linear-space diffuse per channel = albedo * (1 - 0.04) * lightColor (0.04 = kDielectricSpec.r, URP BRDF.hlsl) - // _BaseColor is an sRGB colour property, so the shader sees albedo.linear. - var linearAlbedo = albedo.linear; - var finalLight = FinalLightColor(lightColor, 1f); - Assert.That(pixel.r, Is.EqualTo(0.96f * linearAlbedo.r * finalLight.r).Within(0.02f), "red"); - Assert.That(pixel.g, Is.EqualTo(0.96f * linearAlbedo.g * finalLight.g).Within(0.02f), "green"); - Assert.That(pixel.b, Is.EqualTo(0.96f * linearAlbedo.b * finalLight.b).Within(0.02f), "blue"); - } - - [UnityTest] - [UnityPlatform(exclude = new RuntimePlatform[] { - RuntimePlatform.IPhonePlayer, // Disabled for Instability https://jira.unity3d.com/browse/UUM-152475 - RuntimePlatform.OSXEditor, // Disabled for Instability https://jira.unity3d.com/browse/UUM-152475 - RuntimePlatform.PS4 // Disabled for Instability https://jira.unity3d.com/browse/UUM-152475 - })] - public IEnumerator SpecularHighlightsAddToDiffuse() - { - UseLitQuad(smoothness: 0.5f, specularHighlights: false); - yield return null; - var withoutSpecular = RenderCenterPixel().g; - - UseLitQuad(smoothness: 0.5f, specularHighlights: true); - yield return null; - var withSpecular = RenderCenterPixel().g; - - Assert.That(withSpecular - withoutSpecular, Is.GreaterThan(0.01f), "mirror-aligned specular should add measurable light"); - } - - [UnityTest] - public IEnumerator SpecularPeakGrowsWithSmoothness() - { - UseLitQuad(smoothness: 0.25f, specularHighlights: true); - yield return null; - var rough = RenderCenterPixel().g; - - UseLitQuad(smoothness: 0.7f, specularHighlights: true); - yield return null; - var smooth = RenderCenterPixel().g; - - Assert.That(smooth, Is.GreaterThan(rough), "mirror-aligned specular peak should grow with smoothness"); - } - - void UseLitQuad(float smoothness, bool specularHighlights, Color? albedo = null, Color? lightColor = null) - { - var material = CreateMaterial(Shader.Find("Universal Render Pipeline/Lit")); - material.SetColor("_BaseColor", albedo ?? Color.white); - material.SetFloat("_Metallic", 0f); - material.SetFloat("_Smoothness", smoothness); - material.EnableKeyword("_ENVIRONMENTREFLECTIONS_OFF"); - if (!specularHighlights) - material.EnableKeyword("_SPECULARHIGHLIGHTS_OFF"); - m_Quad.GetComponent().sharedMaterial = material; - SetLightAngle(0f); - m_Light.color = lightColor ?? Color.white; - m_Light.intensity = 1f; - } - - Material CreateMaterial(Shader shader) - { - Assert.That(shader, Is.Not.Null, "test shader must be present in the build"); - var material = new Material(shader); - m_Materials.Add(material); - return material; - } - - void SetLightAngle(float degreesFromNormal) - { - m_Light.transform.rotation = Quaternion.Euler(degreesFromNormal, 0f, 0f); - } - - static Color FinalLightColor(Color color, float intensity) - { - return GraphicsSettings.lightsUseLinearIntensity ? color.linear * intensity : (color * intensity).linear; - } - - Color RenderCenterPixel() - { - var request = new UniversalRenderPipeline.SingleCameraRequest { destination = m_RenderTexture }; - RenderPipeline.SubmitRenderRequest(m_Camera, request); - - var readback = AsyncGPUReadback.Request(m_RenderTexture, 0, TextureFormat.RGBAFloat); - readback.WaitForCompletion(); - Assert.That(readback.hasError, Is.False, "GPU readback failed"); - - var pixel = readback.GetData()[(k_Size / 2) * k_Size + k_Size / 2]; - return new Color(pixel.x, pixel.y, pixel.z, pixel.w); - } -} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs.meta deleted file mode 100644 index ff5e29b8079..00000000000 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/AnalyticDirectLightingTests.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 3d92242dceb184a158d2d84a1d270346 \ No newline at end of file diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader deleted file mode 100644 index ac140d6600b..00000000000 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader +++ /dev/null @@ -1,67 +0,0 @@ -Shader "Hidden/Test/LightingOverloadConsistency" -{ - SubShader - { - Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } - - Pass - { - HLSLPROGRAM - #pragma vertex Vert - #pragma fragment Frag - #pragma multi_compile_fragment _ _SPECULARHIGHLIGHTS_OFF - - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" - #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" - - float _SpecularHighlightsOffArg; - - struct Attributes - { - float4 positionOS : POSITION; - }; - - struct Varyings - { - float4 positionCS : SV_POSITION; - }; - - Varyings Vert(Attributes input) - { - Varyings output; - output.positionCS = TransformObjectToHClip(input.positionOS.xyz); - return output; - } - - // RGB is |canonical - deprecated| for the same inputs; any non-zero value means the - // deprecated convenience overload no longer forwards correctly. Alpha carries the - // canonical green channel as a positive control that the quad actually drew. - half4 Frag(Varyings input) : SV_Target - { - half alpha = half(1.0); - BRDFData brdfData; - InitializeBRDFData(half3(1.0, 0.8, 0.6), half(0.0), half3(0.0, 0.0, 0.0), half(0.5), alpha, brdfData); - - // Normal deliberately differs from the view direction so argument swaps cannot cancel out. - half3 normalWS = half3(0.0, 0.38268343, 0.92387953); - half3 viewDirWS = half3(0.0, -0.31622776, 0.9486833); - half3 lightDir = half3(0.0, 0.70710678, 0.70710678); - half3 lightColor = half3(1.0, 0.95, 0.9); - - Light light = (Light)0; - light.color = lightColor; - light.direction = lightDir; - // Not 1.0, so a dropped or mis-forwarded attenuation cannot read as no difference. - light.distanceAttenuation = 0.5; - light.shadowAttenuation = half(1.0); - - bool specularHighlightsOff = _SpecularHighlightsOffArg != 0.0; - - half3 canonical = LightingPhysicallyBased(brdfData, light, normalWS, viewDirWS, specularHighlightsOff); - half3 deprecated = LightingPhysicallyBased(brdfData, lightColor, lightDir, 0.5, normalWS, viewDirWS, specularHighlightsOff); - return half4(abs(canonical - deprecated), canonical.g); - } - ENDHLSL - } - } -} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader.meta deleted file mode 100644 index 5d464e1301b..00000000000 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Test/Runtime/AnalyticLighting/Resources/LightingOverloadConsistency.shader.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 08b710d04ca024bccaa49ab121cba4e6 -ShaderImporter: - externalObjects: {} - defaultTextures: [] - nonModifiableTextures: [] - userData: - assetBundleName: - assetBundleVariant: From 214c43d292c467626e8655aa305b8f7f80ff2b7b Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 14 Sep 2026 17:05:07 +0000 Subject: [PATCH 008/192] [Port] [6000.7] [7000.0][UUM-150232] [2D] Respect Disable Depth and Stencil Buffers in URP 2D --- .../2D/Rendergraph/DrawNormal2DPass.cs | 2 +- .../2D/Rendergraph/DrawRenderer2DPass.cs | 2 +- .../2D/Rendergraph/Renderer2DRendergraph.cs | 38 ++-- .../Runtime/Passes/DrawScreenSpaceUIPass.cs | 4 +- .../Runtime/ScriptableRenderer.cs | 9 +- .../Shaders/2D/RenderingLayerMask.shader | 4 +- .../Runtime/Renderer2DBackbufferDepthTests.cs | 181 ++++++++++++++++++ .../Renderer2DBackbufferDepthTests.cs.meta | 11 ++ .../Test/Runtime/Renderer2DDepthUsageTests.cs | 120 ++++++++++++ .../Runtime/Renderer2DDepthUsageTests.cs.meta | 11 ++ 10 files changed, 364 insertions(+), 18 deletions(-) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs.meta diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawNormal2DPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawNormal2DPass.cs index 5152ddef3dc..5cf40956a59 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawNormal2DPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/DrawNormal2DPass.cs @@ -50,7 +50,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex builder.SetRenderAttachment(universal2DResourceData.normalsTexture[batchIndex], 0); // Depth needed for sprite mask stencil or z test for 3d meshes - if (Renderer2D.IsDepthUsageAllowed(frameData, rendererData)) + if (commonResourceData.activeDepthTexture.IsValid()) { var depth = universal2DResourceData.normalsDepth.IsValid() ? universal2DResourceData.normalsDepth : commonResourceData.activeDepthTexture; builder.SetRenderAttachmentDepth(depth); 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 74150fed2f5..a4ee9e4f701 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 @@ -164,7 +164,7 @@ public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex // Set color and depth attachments builder.SetRenderAttachment(commonResourceData.activeColorTexture, 0); - if (Renderer2D.IsDepthUsageAllowed(frameData, rendererData)) + if (commonResourceData.activeDepthTexture.IsValid()) builder.SetRenderAttachmentDepth(commonResourceData.activeDepthTexture); builder.AllowGlobalStateModification(true); 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 529d7bc3f5d..a7d3b0a95f4 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 @@ -232,12 +232,16 @@ internal static bool IsDepthUsageAllowed(ContextContainer frameData, Renderer2DD { UniversalCameraData cameraData = frameData.Get(); + // Renderer2DData.useDepthStencilBuffer bool allowDepth = rendererData.useDepthStencilBuffer; // 3D Render Textures with depth/stencil buffer are not supported if (cameraData.targetTexture != null) allowDepth &= cameraData.targetTexture.dimension != TextureDimension.Tex3D; + // The back buffer has none when PlayerSettings.disableDepthAndStencilBuffers is enabled on a graphics API that acts on it + allowDepth &= Graphics.backBufferHasDepthStencil; + return allowDepth; } @@ -529,6 +533,7 @@ void CreateResources(RenderGraph renderGraph) // RTHandles do not support combining color and depth in the same texture so we create them separately m_CreateDepthTexture |= m_CreateColorTexture; + m_CreateDepthTexture &= IsDepthUsageAllowed(frameData, m_Renderer2DData); // Camera Target Color if (m_CreateColorTexture) @@ -588,9 +593,12 @@ void CreateResources(RenderGraph renderGraph) if (m_CreateColorTexture) { importSummary.cameraColorParams.discardOnLastUse = lastCameraInTheStack; - importSummary.cameraDepthParams.discardOnLastUse = lastCameraInTheStack; - commonResourceData.cameraColor = renderGraph.ImportTexture(currentRenderGraphCameraColorHandle, importSummary.cameraColorParams); + } + + if (m_CreateDepthTexture) + { + importSummary.cameraDepthParams.discardOnLastUse = lastCameraInTheStack; commonResourceData.cameraDepth = renderGraph.ImportTexture(m_RenderGraphCameraDepthHandle, importSummary.cameraDepthParams); } @@ -614,17 +622,21 @@ void CreateResources(RenderGraph renderGraph) RTHandleStaticHelpers.SetRTHandleUserManagedWrapper(ref m_RenderGraphBackbufferColorHandle, targetColorId); } - if (m_RenderGraphBackbufferDepthHandle == null) - { - m_RenderGraphBackbufferDepthHandle = RTHandles.Alloc(targetDepthId, "Backbuffer depth"); - } - else if (m_RenderGraphBackbufferDepthHandle.nameID != targetDepthId) + commonResourceData.backBufferColor = renderGraph.ImportTexture(m_RenderGraphBackbufferColorHandle, importSummary.importInfo, importSummary.backBufferColorParams); + + if (IsDepthUsageAllowed(frameData, m_Renderer2DData)) { - RTHandleStaticHelpers.SetRTHandleUserManagedWrapper(ref m_RenderGraphBackbufferDepthHandle, targetDepthId); - } + if (m_RenderGraphBackbufferDepthHandle == null) + { + m_RenderGraphBackbufferDepthHandle = RTHandles.Alloc(targetDepthId, "Backbuffer depth"); + } + else if (m_RenderGraphBackbufferDepthHandle.nameID != targetDepthId) + { + RTHandleStaticHelpers.SetRTHandleUserManagedWrapper(ref m_RenderGraphBackbufferDepthHandle, targetDepthId); + } - commonResourceData.backBufferColor = renderGraph.ImportTexture(m_RenderGraphBackbufferColorHandle, importSummary.importInfo, importSummary.backBufferColorParams); - commonResourceData.backBufferDepth = renderGraph.ImportTexture(m_RenderGraphBackbufferDepthHandle, importSummary.importInfoDepth, importSummary.backBufferDepthParams); + commonResourceData.backBufferDepth = renderGraph.ImportTexture(m_RenderGraphBackbufferDepthHandle, importSummary.importInfoDepth, importSummary.backBufferDepthParams); + } if (RequiresDepthCopyPass()) CreateCameraDepthCopyTexture(renderGraph, cameraTargetDescriptor); @@ -642,9 +654,11 @@ void CreateCameraNormalsTextures(RenderGraph renderGraph, RenderTextureDescripto desc.graphicsFormat = RendererLighting.GetRenderTextureFormat(); desc.autoGenerateMips = false; desc.msaaSamples = descriptor.msaaSamples; + bool useNormals = false; for (int i = 0; i < resourceData.normalsTexture.Length; ++i) { + useNormals |= layerBatches[i].useNormals; if (layerBatches[i].useNormals) { resourceData.normalsTexture[i] = UniversalRenderer.CreateRenderGraphTexture(renderGraph, desc, "_NormalMap", true, RendererLighting.k_NormalClearColor); @@ -655,7 +669,7 @@ void CreateCameraNormalsTextures(RenderGraph renderGraph, RenderTextureDescripto } } - if (IsDepthUsageAllowed(frameData, m_Renderer2DData)) + if (useNormals && IsDepthUsageAllowed(frameData, m_Renderer2DData)) { // Normals pass can reuse active depth if same dimensions, if not create a new depth texture #if !(ENABLE_VR && ENABLE_XR_MODULE) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs index 8370d7ff145..b5080c5c2f7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs @@ -318,7 +318,9 @@ internal void RenderOverlayUIToolkitAndUGUI(RenderGraph renderGraph, ContextCont builder.UseAllGlobalTextures(true); builder.SetRenderAttachment(colorBuffer, 0); - builder.SetRenderAttachmentDepth(depthBuffer, AccessFlags.ReadWrite); + + if (depthBuffer.IsValid()) + builder.SetRenderAttachmentDepth(depthBuffer, AccessFlags.ReadWrite); passData.rendererList = renderGraph.CreateUIOverlayRendererList(cameraData.camera, UISubset.UIToolkit_UGUI); builder.UseRendererList(passData.rendererList); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index 8b9c97fe683..0f685b94549 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -815,7 +815,8 @@ internal void DrawRenderGraphGizmos(RenderGraph renderGraph, ContextContainer fr Profiling.drawGizmos)) { builder.UseTexture(color, AccessFlags.Write); - builder.UseTexture(depth, AccessFlags.ReadWrite); + if (depth.IsValid()) + builder.UseTexture(depth, AccessFlags.ReadWrite); passData.gizmoRenderList = renderGraph.CreateGizmoRendererList(cameraData.camera, gizmoSubset); passData.color = color; @@ -833,7 +834,11 @@ internal void DrawRenderGraphGizmos(RenderGraph renderGraph, ContextContainer fr { using (new ProfilingScope(rgContext.cmd, Profiling.drawGizmos)) { - rgContext.cmd.SetRenderTarget(data.color, data.depth); + if (data.depth.IsValid()) + rgContext.cmd.SetRenderTarget(data.color, data.depth); + else + rgContext.cmd.SetRenderTarget(data.color); + // SetRenderTarget resets the viewport to the full target; re-clamp to the camera rect // when rendering to the backbuffer. if (data.clampViewport) diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/2D/RenderingLayerMask.shader b/Packages/com.unity.render-pipelines.universal/Shaders/2D/RenderingLayerMask.shader index 0ae556942f7..4366531e0ad 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/2D/RenderingLayerMask.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/2D/RenderingLayerMask.shader @@ -13,8 +13,10 @@ Shader "Hidden/2D/RenderingLayerMask" SubShader { - ZTest Off + ZWrite [_ZWrite] + ZTest Off Blend Off + Cull Off Pass { diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs new file mode 100644 index 00000000000..5ae66800b2d --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs @@ -0,0 +1,181 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.Universal; +using UnityEngine.TestTools; + +// Verifies what the 2D renderer actually puts in the frame's resources when depth usage is disallowed: the +// back buffer depth must not be imported, and the rest of the frame must still record without errors (the +// overlay UI pass in particular reads UniversalResourceData.backBufferDepth and has to cope with it being +// invalid). +// +// A back buffer with no depth/stencil is not something a test can arrange - it is decided when the surface is +// created - so the disallowed case is driven here through the renderer's own "Depth/Stencil Buffer" setting, +// which reaches the exact same branch in Renderer2D.CreateRenderGraphCameraRenderTargets. The back buffer's own +// contribution to the decision is covered by Renderer2DDepthUsageTests. +[TestFixture] +class Renderer2DBackbufferDepthTests +{ + const int k_Renderer2DIndex = 2; // 2D Renderer. See the list of Renderers in CommonAssets/UniversalRPAsset. + + readonly List m_DisabledCameras = new List(); + readonly BackbufferDepthProbePass m_ProbePass = new BackbufferDepthProbePass(); + + GameObject m_CameraObj; + Camera m_Camera; + UniversalAdditionalCameraData m_CameraData; + Renderer2DData m_RendererData; + bool m_PreviousUseDepthStencilBuffer; + + [SetUp] + public void SetUp() + { + if (GraphicsSettings.currentRenderPipeline is not UniversalRenderPipelineAsset urpAsset) + { + Assert.Ignore("These tests only run when URP is the active render pipeline."); + return; + } + + // Under XR the renderer imports the XR-owned render target rather than the back buffer, so there is + // nothing to assert about the back buffer depth here. + if (XRGraphicsAutomatedTests.enabled) + { + Assert.Ignore("XR is active; the 2D renderer does not import the back buffer depth in that case."); + return; + } + + Assert.Greater(urpAsset.rendererDataList.Length, k_Renderer2DIndex, "The render pipeline asset no longer has a renderer at the 2D renderer index. Update this test to match."); + m_RendererData = urpAsset.rendererDataList[k_Renderer2DIndex] as Renderer2DData; + Assert.NotNull(m_RendererData, $"Renderer {k_Renderer2DIndex} of the render pipeline asset is not a 2D renderer. Update this test to match."); + m_PreviousUseDepthStencilBuffer = m_RendererData.useDepthStencilBuffer; + + // Frame isolation: only the test camera should render while the probe is installed. + foreach (var camera in Object.FindObjectsByType(FindObjectsInactive.Exclude)) + { + if (!camera.enabled) + continue; + + camera.enabled = false; + m_DisabledCameras.Add(camera); + } + + m_CameraObj = new GameObject("Backbuffer Depth Test Camera"); + m_Camera = m_CameraObj.AddComponent(); + m_CameraData = m_CameraObj.AddComponent(); + + // Render straight to the back buffer: no target texture, no stack and no post-processing, so the + // renderer does not create intermediate targets. + m_Camera.targetTexture = null; + m_Camera.allowHDR = false; + m_CameraData.SetRenderer(k_Renderer2DIndex); + m_CameraData.renderType = CameraRenderType.Base; + m_CameraData.renderPostProcessing = false; + + RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; + } + + [TearDown] + public void TearDown() + { + RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; + + if (m_RendererData != null) + Renderer2DDepthUsageTests.SetUseDepthStencilBuffer(m_RendererData, m_PreviousUseDepthStencilBuffer); + + if (m_CameraObj != null) + Object.DestroyImmediate(m_CameraObj); + + foreach (var camera in m_DisabledCameras) + { + if (camera != null) + camera.enabled = true; + } + m_DisabledCameras.Clear(); + } + + [UnityTest] + public IEnumerator BackbufferDepthIsImportedWhenDepthUsageIsAllowed() + { + Renderer2DDepthUsageTests.SetUseDepthStencilBuffer(m_RendererData, true); + + yield return RecordFrame(); + + // With the renderer setting on, the import follows the back buffer: there is nothing to import on a + // build where PlayerSettings.disableDepthAndStencilBuffers left it without a depth/stencil buffer. + Assert.AreEqual(Graphics.backBufferHasDepthStencil, m_ProbePass.backBufferDepthIsValid, + "The imported back buffer depth did not match whether the back buffer has a depth/stencil buffer."); + } + + [UnityTest] + public IEnumerator BackbufferDepthIsNotImportedWhenDepthUsageIsDisallowed() + { + Renderer2DDepthUsageTests.SetUseDepthStencilBuffer(m_RendererData, false); + + yield return RecordFrame(); + + Assert.IsFalse(m_ProbePass.backBufferDepthIsValid, "The 2D renderer imported the back buffer depth even though depth usage is disallowed."); + } + + [UnityTest] + public IEnumerator RenderingSucceedsWhenDepthUsageIsDisallowed() + { + Renderer2DDepthUsageTests.SetUseDepthStencilBuffer(m_RendererData, false); + + // Passes that read the back buffer depth - the overlay UI pass above all - must skip themselves rather + // than record against an invalid handle. Any error or exception they log fails this test. + yield return RecordFrame(); + yield return null; + } + + // Renders frames until the probe pass has recorded one with the current settings. + IEnumerator RecordFrame() + { + // The settings change lands on the next frame the renderer records, so drop the in-flight one first. + yield return null; + + m_ProbePass.Reset(); + yield return null; + + Assert.IsTrue(m_ProbePass.recorded, "The probe pass never recorded; the 2D renderer did not render the test camera."); + } + + void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) + { + if (camera != m_Camera) + return; + + m_CameraData.scriptableRenderer.EnqueuePass(m_ProbePass); + } + + // Reads the frame's back buffer depth handle at record time; it adds no render pass of its own. + class BackbufferDepthProbePass : ScriptableRenderPass + { + public bool recorded; + public bool backBufferDepthIsValid; + + public BackbufferDepthProbePass() + { + // The 2D renderer maps any event up to BeforeRenderingTransparents onto + // RenderPassEvent2D.BeforeRendering, which it records right after CreateResources - so the probe + // sees the back buffer depth as CreateResources left it. + renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + } + + public void Reset() + { + recorded = false; + backBufferDepthIsValid = false; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + var resourceData = frameData.Get(); + + recorded = true; + backBufferDepthIsValid = resourceData.backBufferDepth.IsValid(); + } + } +} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs.meta new file mode 100644 index 00000000000..1a278427739 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DBackbufferDepthTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd25264fd81a45d1b14927bef89166c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs new file mode 100644 index 00000000000..9473d9f1c5d --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs @@ -0,0 +1,120 @@ +using System.Reflection; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +// Covers Renderer2D.IsDepthUsageAllowed, which decides whether the 2D renderer uses a depth/stencil buffer at +// all. It combines three conditions: the renderer's own "Depth/Stencil Buffer" setting, a 3D render texture +// target (which cannot carry depth/stencil), and whether the back buffer has a depth/stencil buffer. +// +// The renderer setting is driven here by writing Renderer2DData's serialized field. The back buffer's state is +// not something the test can set - it is decided when the surface is created, from +// PlayerSettings.disableDepthAndStencilBuffers on the graphics APIs that act on it - so expectations are +// stated against Graphics.backBufferHasDepthStencil, which is what that condition contributes wherever the +// test happens to run. That keeps every case meaningful in the editor and in player builds alike. +[TestFixture] +class Renderer2DDepthUsageTests +{ + const string k_UseDepthStencilBufferField = "m_UseDepthStencilBuffer"; + + ContextContainer m_FrameData; + UniversalCameraData m_CameraData; + Renderer2DData m_RendererData; + RenderTexture m_TargetTexture; + + [SetUp] + public void SetUp() + { + m_FrameData = new ContextContainer(); + m_CameraData = m_FrameData.Create(); + m_RendererData = ScriptableObject.CreateInstance(); + } + + [TearDown] + public void TearDown() + { + m_CameraData.targetTexture = null; + + if (m_TargetTexture != null) + { + m_TargetTexture.Release(); + Object.DestroyImmediate(m_TargetTexture); + m_TargetTexture = null; + } + + if (m_RendererData != null) + Object.DestroyImmediate(m_RendererData); + + m_FrameData.Dispose(); + } + + [Test] + public void IsDepthUsageAllowed_FollowsTheRendererDepthStencilBufferSetting([Values(false, true)] bool useDepthStencilBuffer) + { + SetUseDepthStencilBuffer(m_RendererData, useDepthStencilBuffer); + + bool expected = useDepthStencilBuffer && Graphics.backBufferHasDepthStencil; + + Assert.AreEqual(expected, Renderer2D.IsDepthUsageAllowed(m_FrameData, m_RendererData)); + } + + [Test] + public void IsDepthUsageAllowed_FollowsTheBackBufferDepthStencil() + { + // With every other condition asking for depth, the back buffer decides. A build with + // PlayerSettings.disableDepthAndStencilBuffers enabled on a graphics API that acts on it lands here + // with no depth/stencil; everywhere else, including the editor, the back buffer keeps one. + SetUseDepthStencilBuffer(m_RendererData, true); + + Assert.AreEqual(Graphics.backBufferHasDepthStencil, Renderer2D.IsDepthUsageAllowed(m_FrameData, m_RendererData)); + } + + [Test] + public void IsDepthUsageAllowed_IsNotVetoedBy2DRenderTextureTargets() + { + // Only 3D render textures veto depth; a 2D one leaves the decision to the other conditions. + SetUseDepthStencilBuffer(m_RendererData, true); + m_CameraData.targetTexture = CreateTargetTexture(TextureDimension.Tex2D); + + Assert.AreEqual(Graphics.backBufferHasDepthStencil, Renderer2D.IsDepthUsageAllowed(m_FrameData, m_RendererData)); + } + + [Test] + public void IsDepthUsageAllowed_IsNotAllowedFor3DRenderTextureTargets() + { + // 3D render textures cannot have a depth/stencil buffer, so this vetoes the decision on its own even + // with everything else asking for depth. + SetUseDepthStencilBuffer(m_RendererData, true); + m_CameraData.targetTexture = CreateTargetTexture(TextureDimension.Tex3D); + + Assert.IsFalse(Renderer2D.IsDepthUsageAllowed(m_FrameData, m_RendererData)); + } + + RenderTexture CreateTargetTexture(TextureDimension dimension) + { + var descriptor = new RenderTextureDescriptor(4, 4) + { + dimension = dimension, + volumeDepth = dimension == TextureDimension.Tex3D ? 4 : 1, + graphicsFormat = GraphicsFormat.R8G8B8A8_UNorm, + depthStencilFormat = GraphicsFormat.None, + msaaSamples = 1 + }; + + m_TargetTexture = new RenderTexture(descriptor); + return m_TargetTexture; + } + + // Renderer2DData.useDepthStencilBuffer is a read-only view of a serialized field, so the test has to write + // the field. Kept in one place so a rename fails loudly instead of silently skipping the condition. + internal static void SetUseDepthStencilBuffer(Renderer2DData rendererData, bool value) + { + var field = typeof(Renderer2DData).GetField(k_UseDepthStencilBufferField, BindingFlags.Instance | BindingFlags.NonPublic); + Assert.NotNull(field, $"{nameof(Renderer2DData)}.{k_UseDepthStencilBufferField} no longer exists. Update this test to match."); + + field.SetValue(rendererData, value); + Assert.AreEqual(value, rendererData.useDepthStencilBuffer, $"{nameof(Renderer2DData)}.{k_UseDepthStencilBufferField} is no longer what useDepthStencilBuffer returns. Update this test to match."); + } +} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs.meta new file mode 100644 index 00000000000..676971cf07c --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Runtime/Renderer2DDepthUsageTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 28c6feeebd6a465fa9afb71cf4aa367d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 4b8dec8e45aac97a289c639cb40568e3a4ffd17e Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 14 Sep 2026 17:05:08 +0000 Subject: [PATCH 009/192] [Port] [6000.7] Make Surface Cache check the proper ray tracing capabilities --- .../SurfaceCacheGIRendererFeature.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 0d404f687b0..43849e00ed1 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 @@ -109,13 +109,13 @@ public class SurfaceCacheGIRendererFeature : ScriptableRendererFeature static bool TryGetSupportedRayTracingBackend(out RayTracingBackend backend) { - if (RayTracingContext.GetCapabilities(RayTracingBackend.Hardware).HasFlag(CapabilityMask.RayTracingShaders)) + if (RayTracingContext.GetCapabilities(RayTracingBackend.Hardware).HasFlag(CapabilityMask.InlineRayTracing)) { backend = RayTracingBackend.Hardware; return true; } - if (RayTracingContext.GetCapabilities(RayTracingBackend.Compute).HasFlag(CapabilityMask.RayTracingShaders)) + if (RayTracingContext.GetCapabilities(RayTracingBackend.Compute).HasFlag(CapabilityMask.InlineRayTracing)) { backend = RayTracingBackend.Compute; return true; From 897e759e85834e1c54c74bdc201cba10e7565018 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Tue, 15 Sep 2026 13:41:07 +0000 Subject: [PATCH 010/192] [Port] [6000.7] [URP] [ANT-3709] Prefilter unused volumetric fog shader keywords --- .../Editor/ShaderBuildPreprocessor.cs | 1 + .../Data/UniversalRenderPipelineAssetPrefiltering.cs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs index bbc7a043d26..e9eb8856d9a 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs @@ -1145,6 +1145,7 @@ ref List ssaoRendererFeatures spd.stripReflectionProbeAtlas = !IsFeatureEnabled(shaderFeatures, ShaderFeatures.ReflectionProbeAtlas); spd.stripScreenSpaceIrradiance = stripScreenSpaceIrradiance; spd.stripWriteSmoothness = !IsFeatureEnabled(shaderFeatures, ShaderFeatures.ScreenSpaceReflection); + spd.stripVolumetricFog = !IsFeatureEnabled(shaderFeatures, ShaderFeatures.VolumetricFog); // Rendering Modes // Check if only Deferred is being used diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs index d1f813b5b0a..a53f8690760 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs @@ -230,6 +230,12 @@ internal enum PrefilteringModeAdditionalLights [ShaderKeywordFilter.SelectOrRemove(false, keywordNames: ShaderKeywordStrings.Exposure)] [SerializeField] private bool m_PrefilterExposure = false; + // Volumetric fog (_VOLUMETRIC_FOG, _FOG_VOLUMETRIC) + // The fog mode pair has no off variant, so _FOG_ANALYTIC is selected as the survivor instead. + [ShaderKeywordFilter.RemoveIf(true, keywordNames: ShaderKeywordStrings.VolumetricFog)] + [ShaderKeywordFilter.SelectIf(true, keywordNames: ShaderKeywordStrings.FogAnalytic)] + [SerializeField] private bool m_PrefilterVolumetricFog = false; + // Hidden/Light2D variant prefiltering. The 6-keyword combo space (USE_NORMAL_MAP, // USE_SHADOW_MAP, USE_ADDITIVE_BLENDING, USE_VOLUMETRIC, USE_POINT_LIGHT_COOKIES, // LIGHT_QUALITY_FAST) is too dynamic to express with declarative ShaderKeywordFilter @@ -281,6 +287,8 @@ internal struct ShaderPrefilteringData public bool stripExposure; + public bool stripVolumetricFog; + public bool stripScreenSpaceIrradiance; // Keyword used by the DepthNormalOnly pass to write smoothness into alpha channel for screen space reflections. @@ -350,6 +358,8 @@ internal void UpdateShaderKeywordPrefiltering(ref ShaderPrefilteringData prefilt m_PrefilterExposure = prefilteringData.stripExposure; + m_PrefilterVolumetricFog = prefilteringData.stripVolumetricFog; + m_PrefilterScreenSpaceIrradiance = prefilteringData.stripScreenSpaceIrradiance; m_PrefilterWriteSmoothness = prefilteringData.stripWriteSmoothness; From 14c78d0945f2bde34647a4c3d7263b36434fc81c Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Tue, 15 Sep 2026 18:53:23 +0000 Subject: [PATCH 011/192] [Port] [6000.7] [INSTABILITY]: HDRP_Graphics_Tests.4111_DRS-DLSS-With-CustomPass --- .../4x_PostProcessing/4111_DRS-DLSS-With-CustomPass.unity | 4 ++-- .../HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4111_DRS-DLSS-With-CustomPass.unity b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4111_DRS-DLSS-With-CustomPass.unity index 2aae3adeaa1..2b46142f996 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4111_DRS-DLSS-With-CustomPass.unity +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4111_DRS-DLSS-With-CustomPass.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9382273716ea83dd43f472e9c2ff5feffd096974e25f2fa5026950893b181b25 -size 23636 +oid sha256:85f76ff7e7fea54dd92fe3bfab5f8fd9047f18c9e763f4b82289ef051b857c37 +size 23863 diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs index 5e9817db6cd..f711cdeda78 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs @@ -100,12 +100,13 @@ public PostProcessingTests(GpuResidentDrawerContext grdContext) : base(grdContex )] [TestOnlySupportedOn( "4111_DRS-DLSS-With-CustomPass", - "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only + "Platform not supported", // DLSS is DX12/DX11/Vulkan on PC-only, and needs an NVIDIA GPU. GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Direct3D11, GraphicsDeviceType.Vulkan, - RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer + RuntimePlatform.WindowsEditor, RuntimePlatform.WindowsPlayer, + GraphicsVendor.Nvidia )] [IgnoreGraphicsTest( - "4075_PhysicalCamera-gateFit|4111_DRS-DLSS-With-CustomPass", + "4075_PhysicalCamera-gateFit", "Disabled for Instability https://jira.unity3d.com/browse/UUM-134786", RuntimePlatform.WindowsEditor )] From 8347eae494ee4a3959ac8bdc44a179054223155c Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Tue, 15 Sep 2026 18:53:23 +0000 Subject: [PATCH 012/192] [Port] [6000.7] Filter out non-MeshRenderers in APV bake --- .../Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs | 2 +- .../Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs | 2 +- .../Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs index 57880c9e41f..4d4123d0ef5 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs @@ -119,7 +119,7 @@ static AccelStructAdapter BuildAccelerationStructure(out bool hasTerrains) if (mesh == null) continue; - if (renderer.component is SkinnedMeshRenderer) + if (renderer.component is not MeshRenderer) continue; int subMeshCount = mesh.subMeshCount; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs index fa7788e9630..97e4d823a94 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs @@ -214,7 +214,7 @@ static AccelStructAdapter BuildAccelerationStructure(out bool hasTerrains) if (!s_TracingContext.TryGetMeshForAccelerationStructure(renderer.component, out var mesh)) continue; - if (renderer.component is SkinnedMeshRenderer) + if (renderer.component is not MeshRenderer) continue; int subMeshCount = mesh.subMeshCount; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs index 0591c291a5b..b99673082a8 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs @@ -143,7 +143,7 @@ static AccelStructAdapter BuildAccelerationStructure(int mask, out bool hasTerra if (!s_TracingContext.TryGetMeshForAccelerationStructure(renderer.component, out var mesh)) continue; - if (renderer.component is SkinnedMeshRenderer) + if (renderer.component is not MeshRenderer) continue; int subMeshCount = mesh.subMeshCount; From 289a5ed6a30e56792cabc8bb65a69243c0b5bc27 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Wed, 16 Sep 2026 13:35:19 +0000 Subject: [PATCH 013/192] [Port] [6000.7] [GFXSKR-18] Rename Linear light falloff mode to Quadratic --- .../Editor/ShaderBuildPreprocessor.cs | 6 ++-- .../Targets/UniversalDecalSubTarget.cs | 4 +-- .../Targets/UniversalLitSubTarget.cs | 2 +- .../Targets/UniversalSixWaySubTarget.cs | 2 +- .../ShaderGraph/Targets/UniversalTarget.cs | 6 ++-- .../Targets/UniversalTerrainLitSubTarget.cs | 2 +- .../Targets/UniversalUnlitSubTarget.cs | 2 +- .../Editor/ShaderScriptableStripper.cs | 10 +++---- .../BuiltInToURP3DRenderSettingsConverter.cs | 2 +- .../UniversalRenderPipelineAssetUI.Skin.cs | 2 +- .../URPDecal/PassScreenSpace.template | 2 +- .../VFXGraph/Shaders/VFXPasses.template | 2 +- .../Data/UniversalRenderPipelineAsset.cs | 10 +++---- .../Runtime/ForwardLights.cs | 2 +- .../Fog/Passes/VolumetricLightingPass.cs | 16 +++++----- .../Fog/Shaders/VolumetricLighting.compute | 2 +- .../Runtime/UniversalRenderPipelineCore.cs | 10 +++---- .../ShaderLibrary/RealtimeLights.hlsl | 2 +- .../Shaders/ComplexLit.shader | 2 +- .../Shaders/Lit.shader | 2 +- .../Shaders/Nature/SpeedTree7.shader | 2 +- .../Shaders/Nature/SpeedTree7Billboard.shader | 2 +- .../Shaders/Nature/SpeedTree8.shader | 2 +- .../Shaders/Particles/ParticlesLit.shader | 2 +- .../Particles/ParticlesSimpleLit.shader | 2 +- .../Shaders/SimpleLit.shader | 2 +- .../Shaders/Terrain/TerrainDetailLit.shader | 2 +- .../Shaders/Terrain/TerrainLit.shader | 2 +- .../Shaders/Terrain/TerrainLitAdd.shader | 2 +- .../Shaders/Terrain/TerrainLitBase.shader | 2 +- .../Shaders/Terrain/WavingGrass.shader | 2 +- .../Terrain/WavingGrassBillboard.shader | 2 +- .../Shaders/Utils/ClusterDeferred.shader | 4 +-- .../Shaders/Utils/StencilDeferred.shader | 4 +-- .../Editor/ShaderBuildPreprocessorTests.cs | 6 ++-- .../Editor/ShaderScriptableStripperTests.cs | 28 +++++++++--------- ...near.asset => 056_Falloff_Quadratic.asset} | 2 +- ....meta => 056_Falloff_Quadratic.asset.meta} | 0 ...ta => 056_Lighting_Falloff_Quadratic.meta} | 0 ...y => 056_Lighting_Falloff_Quadratic.unity} | 0 ...056_Lighting_Falloff_Quadratic.unity.meta} | 0 ...ghting_Falloff_QuadraticSettings.lighting} | 2 +- ...g_Falloff_QuadraticSettings.lighting.meta} | 0 .../LightingData.asset | Bin .../LightingData.asset.meta | 0 .../Lightmap-0_comp_light.exr | 0 .../Lightmap-0_comp_light.exr.meta | 0 .../NeutralGray.mat | 0 .../NeutralGray.mat.meta | 0 .../SpotCookie.png | 0 .../SpotCookie.png.meta | 0 ..._Lighting_Falloff_Quadratic_deferred.meta} | 0 ...Lighting_Falloff_Quadratic_deferred.unity} | 0 ...ing_Falloff_Quadratic_deferred.unity.meta} | 0 .../LightingData.asset | Bin .../LightingData.asset.meta | 0 .../Lightmap-0_comp_light.exr | 0 .../Lightmap-0_comp_light.exr.meta | 0 .../ProjectSettings/EditorBuildSettings.asset | 4 +-- .../ProjectSettings/QualitySettings.asset | 2 +- 60 files changed, 82 insertions(+), 82 deletions(-) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/{056_Falloff_Linear.asset => 056_Falloff_Quadratic.asset} (99%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/{056_Falloff_Linear.asset.meta => 056_Falloff_Quadratic.asset.meta} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear.meta => 056_Lighting_Falloff_Quadratic.meta} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear.unity => 056_Lighting_Falloff_Quadratic.unity} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear.unity.meta => 056_Lighting_Falloff_Quadratic.unity.meta} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting => 056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting} (97%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting.meta => 056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting.meta} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/LightingData.asset (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/LightingData.asset.meta (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/Lightmap-0_comp_light.exr (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/Lightmap-0_comp_light.exr.meta (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/NeutralGray.mat (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/NeutralGray.mat.meta (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/SpotCookie.png (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear => 056_Lighting_Falloff_Quadratic}/SpotCookie.png.meta (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred.meta => 056_Lighting_Falloff_Quadratic_deferred.meta} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred.unity => 056_Lighting_Falloff_Quadratic_deferred.unity} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred.unity.meta => 056_Lighting_Falloff_Quadratic_deferred.unity.meta} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred => 056_Lighting_Falloff_Quadratic_deferred}/LightingData.asset (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred => 056_Lighting_Falloff_Quadratic_deferred}/LightingData.asset.meta (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred => 056_Lighting_Falloff_Quadratic_deferred}/Lightmap-0_comp_light.exr (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/{056_Lighting_Falloff_Linear_deferred => 056_Lighting_Falloff_Quadratic_deferred}/Lightmap-0_comp_light.exr.meta (100%) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs index e9eb8856d9a..a406735b833 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderBuildPreprocessor.cs @@ -78,7 +78,7 @@ enum ShaderFeatures : long ScreenSpaceReflection = (1L << 55), RenderObjectDepthInputAttachment = (1L << 56), VolumetricFog = (1L << 57), - LightFalloffLinear = (1L << 58), + LightFalloffQuadratic = (1L << 58), All = ~0 } @@ -674,8 +674,8 @@ internal static ShaderFeatures GetSupportedShaderFeaturesFromAsset( if (urpAsset.shEvalMode == ShEvalMode.Auto) urpAssetShaderFeatures |= ShaderFeatures.AutoSHMode; - if (urpAsset.lightFalloffMode == LightFalloffMode.Linear) - urpAssetShaderFeatures |= ShaderFeatures.LightFalloffLinear; + if (urpAsset.lightFalloffMode == LightFalloffMode.Quadratic) + urpAssetShaderFeatures |= ShaderFeatures.LightFalloffQuadratic; if (urpAsset.supportScreenSpaceLensFlare) urpAssetShaderFeatures |= ShaderFeatures.ScreenSpaceLensFlare; 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 a7f93dea10b..2368c803a53 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 @@ -1031,7 +1031,7 @@ static class Descriptors { CoreKeywordDescriptors.Exposure }, { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.AdditionalLights }, - { CoreKeywordDescriptors.LightFalloffLinear }, + { CoreKeywordDescriptors.LightFalloffQuadratic }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ShadowsSoft }, { CoreKeywordDescriptors.LightmapShadowMixing }, @@ -1055,7 +1055,7 @@ static class Descriptors { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.ScreenSpaceIrradiance }, { CoreKeywordDescriptors.AdditionalLights }, - { CoreKeywordDescriptors.LightFalloffLinear }, + { CoreKeywordDescriptors.LightFalloffQuadratic }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ShadowsSoft }, { CoreKeywordDescriptors.ClusterLightLoop }, 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 b544648ff55..279bbc6b260 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 @@ -1016,7 +1016,7 @@ static class LitKeywords { CoreKeywordDescriptors.ReflectionProbeRotation }, { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.AdditionalLights }, - { CoreKeywordDescriptors.LightFalloffLinear }, + { CoreKeywordDescriptors.LightFalloffQuadratic }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ReflectionProbeBlending }, { CoreKeywordDescriptors.ReflectionProbeBoxProjection }, diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalSixWaySubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalSixWaySubTarget.cs index d9d288363c4..1dd62d8420c 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalSixWaySubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalSixWaySubTarget.cs @@ -506,7 +506,7 @@ static class SixWayKeywords { CoreKeywordDescriptors.Exposure }, { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.AdditionalLights }, - { CoreKeywordDescriptors.LightFalloffLinear }, + { CoreKeywordDescriptors.LightFalloffQuadratic }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ShadowsSoft }, { CoreKeywordDescriptors.ShadowsShadowmask }, 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 f5d51e986b1..bd87681ecd8 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 @@ -2951,10 +2951,10 @@ static class CoreKeywordDescriptors } }; - public static readonly KeywordDescriptor LightFalloffLinear = new KeywordDescriptor() + public static readonly KeywordDescriptor LightFalloffQuadratic = new KeywordDescriptor() { - displayName = "Light Falloff Linear", - referenceName = "_LIGHT_FALLOFF_LINEAR", + displayName = "Light Falloff Quadratic", + referenceName = "_LIGHT_FALLOFF_QUADRATIC", type = KeywordType.Boolean, definition = KeywordDefinition.MultiCompile, scope = KeywordScope.Global, 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 441e276f170..86705a82dde 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 @@ -1525,7 +1525,7 @@ static class TerrainLitKeywords { CoreKeywordDescriptors.DirectionalLightmapCombined }, { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.AdditionalLights }, - { CoreKeywordDescriptors.LightFalloffLinear }, + { CoreKeywordDescriptors.LightFalloffQuadratic }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ReflectionProbeBlending }, { CoreKeywordDescriptors.ReflectionProbeBoxProjection }, 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 b635f2edeb2..0300ecccbd1 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 @@ -715,7 +715,7 @@ static class UnlitKeywords { { CoreKeywordDescriptors.MainLightShadows }, { CoreKeywordDescriptors.AdditionalLights }, - { CoreKeywordDescriptors.LightFalloffLinear }, + { CoreKeywordDescriptors.LightFalloffQuadratic }, { CoreKeywordDescriptors.AdditionalLightShadows }, { CoreKeywordDescriptors.ReflectionProbeBlending }, { CoreKeywordDescriptors.ReflectionProbeBoxProjection }, diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs index 3a3b9999456..5692a120f89 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs @@ -240,7 +240,7 @@ public bool IsKeywordDynamic(LocalKeyword keyword) LocalKeyword m_FogVolumetric; LocalKeyword m_TransparentReceiveFog; LocalKeyword m_SurfaceTypeTransparent; - LocalKeyword m_LightFalloffLinear; + LocalKeyword m_LightFalloffQuadratic; LocalKeyword m_LensDistortion; LocalKeyword m_ChromaticAberration; LocalKeyword m_BloomLQ; @@ -324,7 +324,7 @@ private void InitializeLocalShaderKeywords([DisallowNull] Shader shader) m_FogVolumetric = TryGetLocalKeyword(shader, ShaderKeywordStrings.FogVolumetric); m_TransparentReceiveFog = TryGetLocalKeyword(shader, ShaderKeywordStrings.TransparentReceiveFog); m_SurfaceTypeTransparent = TryGetLocalKeyword(shader, ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT); - m_LightFalloffLinear = TryGetLocalKeyword(shader, ShaderKeywordStrings.LightFalloffLinear); + m_LightFalloffQuadratic = TryGetLocalKeyword(shader, ShaderKeywordStrings.LightFalloffQuadratic); m_DepthAsInputAttachment = TryGetLocalKeyword(shader, ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT); m_DepthAsInputAttachmentMSAA = TryGetLocalKeyword(shader, ShaderKeywordStrings.DEPTH_AS_INPUT_ATTACHMENT_MSAA); @@ -896,9 +896,9 @@ internal bool StripUnusedFeatures_VolumetricFog(ref IShaderScriptableStrippingDa return false; } - internal bool StripUnusedFeatures_LightFalloffLinear(ref ShaderStripTool stripTool) + internal bool StripUnusedFeatures_LightFalloffQuadratic(ref ShaderStripTool stripTool) { - return stripTool.StripMultiCompileKeepOffVariant(m_LightFalloffLinear, ShaderFeatures.LightFalloffLinear); + return stripTool.StripMultiCompileKeepOffVariant(m_LightFalloffQuadratic, ShaderFeatures.LightFalloffQuadratic); } internal bool StripUnusedFeatures_ProbesVolumes(ref ShaderStripTool stripTool) @@ -1111,7 +1111,7 @@ internal bool StripUnusedFeatures(ref IShaderScriptableStrippingData strippingDa if (StripUnusedFeatures_VolumetricFog(ref strippingData, ref stripTool)) return true; - if (StripUnusedFeatures_LightFalloffLinear(ref stripTool)) + if (StripUnusedFeatures_LightFalloffQuadratic(ref stripTool)) return true; if (StripUnusedFeatures_ProbesVolumes(ref stripTool)) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DRenderSettingsConverter.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DRenderSettingsConverter.cs index 728bec94507..c3523963bb7 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DRenderSettingsConverter.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DRenderSettingsConverter.cs @@ -136,7 +136,7 @@ protected override void SetPipelineSettings(RenderPipelineAsset asset) GetEquivalentAdditionalLightAtlasShadowResolution((int)shadowResolution); // Light Falloff - urpAsset.lightFalloffMode = LightFalloffMode.Linear; + urpAsset.lightFalloffMode = LightFalloffMode.Quadratic; // Reflection Probes urpAsset.reflectionProbeBlending = reflectionProbeBlending; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs index 570672ab2c4..8bc9b0ca8e0 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs @@ -41,9 +41,9 @@ internal static class Styles public static GUIContent enableLODCrossFadeText = L10n.TextContent("LOD Cross Fade", "Controls whether LOD Cross Fade enabled or disabled.", null, null); public static GUIContent lodCrossFadeDitheringTypeText = L10n.TextContent("LOD Cross Fade Dithering Type", "Controls the LOD Cross Fade Dithering Type that will be used to draw Renderer LOD when LODGroup has CrossFade Fade Mode selected.", null, null); public static GUIContent shEvalModeText = L10n.TextContent("SH Evaluation Mode", "Defines the Spherical Harmonic (SH) lighting evaluation type (per vertex, per pixel, or mixed).", null, null); + public static GUIContent lightFalloffModeText = L10n.TextContent("Light Falloff Mode", "How light intensity falls off with distance. Use Quadratic to match the Built-in Render Pipeline.", null, null); public static readonly string xrUpscalingInfo = L10n.Tr("When targeting an XR device, the XR runtime or compositor may provide anti-aliasing and upscaling. In that case this URP upscaler can be redundant or ignored - review your XR provider settings to configure anti-aliasing and upscaling.", null); public static readonly string xrUpscalingInfoButton = L10n.Tr("Open Project Validation", null); - public static GUIContent lightFalloffModeText = L10n.TextContent("Light Falloff Mode", "How light intensity falls off with distance. Use Linear to match the Built-in Render Pipeline.", null, null); public static readonly string stpMobilePlatformWarning = L10n.Tr("STP is selected for use on a mobile platform. STP is only supported on modern compute-capable hardware and its performance overhead may make it impractical on lower-end devices.", null); #if ENABLE_UPSCALER_FRAMEWORK public static GUIContent scalingModeText = L10n.TextContent("Scaling Mode", "Whether the camera renders below, at, or above the display resolution. This sets the available Render Scale range.", null, null); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/Templates/URPDecal/PassScreenSpace.template b/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/Templates/URPDecal/PassScreenSpace.template index 1349ea307a3..ff05900c4fc 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/Templates/URPDecal/PassScreenSpace.template +++ b/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/Templates/URPDecal/PassScreenSpace.template @@ -21,7 +21,7 @@ Pass // Keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ _CLUSTER_LIGHT_LOOP diff --git a/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/VFXPasses.template b/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/VFXPasses.template index e8d3198b1ef..871e66cbd2d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/VFXPasses.template +++ b/Packages/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/VFXPasses.template @@ -30,7 +30,7 @@ ${VFXEnd} ${VFXBegin:VFXPassForwardLitAdditionalPragma} #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS -#pragma multi_compile _ _LIGHT_FALLOFF_LINEAR +#pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION 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 7d290f7187b..a34e7b762fb 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAsset.cs @@ -410,8 +410,8 @@ public enum LightFalloffMode [InspectorName("Inverse Squared")] InverseSquared = 0, /// Falloff matching the Built-in Render Pipeline. Use for Built-in to URP migration. - [InspectorName("Linear")] - Linear = 1, + [InspectorName("Quadratic")] + Quadratic = 1, } /// @@ -527,9 +527,9 @@ public UpscalerPriorityEntry(string upscalerId, string upscalerName) #endif [SerializeField] ShEvalMode m_ShEvalMode = ShEvalMode.Auto; -#if UNITY_EDITOR // multi_compile _ _LIGHT_FALLOFF_LINEAR - [ShaderKeywordFilter.RemoveIf(LightFalloffMode.InverseSquared, keywordNames: ShaderKeywordStrings.LightFalloffLinear)] - [ShaderKeywordFilter.SelectIf(LightFalloffMode.Linear, keywordNames: ShaderKeywordStrings.LightFalloffLinear)] +#if UNITY_EDITOR // multi_compile _ _LIGHT_FALLOFF_QUADRATIC + [ShaderKeywordFilter.RemoveIf(LightFalloffMode.InverseSquared, keywordNames: ShaderKeywordStrings.LightFalloffQuadratic)] + [ShaderKeywordFilter.SelectIf(LightFalloffMode.Quadratic, keywordNames: ShaderKeywordStrings.LightFalloffQuadratic)] #endif [SerializeField] LightFalloffMode m_LightFalloffMode = LightFalloffMode.InverseSquared; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs index 77795f89710..a8ab71c81ee 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs @@ -651,7 +651,7 @@ internal void SetupLights(UnsafeCommandBuffer cmd, UniversalRenderingData render cmd.SetKeyword(ShaderGlobalKeywords.EVALUATE_SH_MIXED, shMode == ShEvalMode.Mixed); cmd.SetKeyword(ShaderGlobalKeywords.EVALUATE_SH_VERTEX, shMode == ShEvalMode.PerVertex); - cmd.SetKeyword(ShaderGlobalKeywords.LightFalloffLinear, UniversalRenderPipeline.IsLinearFalloffEnabled()); + cmd.SetKeyword(ShaderGlobalKeywords.LightFalloffQuadratic, UniversalRenderPipeline.IsQuadraticFalloffEnabled()); var stack = VolumeManager.instance.stack; ProbeReferenceVolume.instance.UpdateShaderVariablesProbeVolumes( diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Passes/VolumetricLightingPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Passes/VolumetricLightingPass.cs index 6bb77bf72b3..327611b56a3 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Passes/VolumetricLightingPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Passes/VolumetricLightingPass.cs @@ -148,9 +148,9 @@ class VolumetricLightingPassData public TextureHandle additionalCookieAtlas; public float additionalCookieFormat; - // Linear (Built-in compatible) light falloff - public LocalKeyword lightFalloffLinearKeyword; - public bool useLinearFalloff; + // Quadratic (Built-in compatible) light falloff + public LocalKeyword lightFalloffQuadraticKeyword; + public bool useQuadraticFalloff; // Zero-filled stand-in public GraphicsBuffer zeroLightCB; @@ -338,10 +338,10 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.UseTexture(passData.additionalCookieAtlas, AccessFlags.Read); } - // Linear (Built-in compatible) light falloff + // Quadratic (Built-in compatible) light falloff { - passData.lightFalloffLinearKeyword = new LocalKeyword(m_Shader, ShaderKeywordStrings.LightFalloffLinear); - passData.useLinearFalloff = applyLocalLights && UniversalRenderPipeline.IsLinearFalloffEnabled(); + passData.lightFalloffQuadraticKeyword = new LocalKeyword(m_Shader, ShaderKeywordStrings.LightFalloffQuadratic); + passData.useQuadraticFalloff = applyLocalLights && UniversalRenderPipeline.IsQuadraticFalloffEnabled(); } passData.fogAnisotropy = fogData.fogAnisotropy; @@ -612,8 +612,8 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer cmd.SetComputeConstantBufferParam(cs, ShaderIDs.LightCookies, lightCookieCB, 0, lightCookieCBSizeBytes); } - // Linear (Built-in compatible) light falloff - cmd.SetKeyword(cs, data.lightFalloffLinearKeyword, data.useLinearFalloff); + // Quadratic (Built-in compatible) light falloff + cmd.SetKeyword(cs, data.lightFalloffQuadraticKeyword, data.useQuadraticFalloff); if (data.enableReprojection) { diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Shaders/VolumetricLighting.compute b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Shaders/VolumetricLighting.compute index f952db09af8..06b47cdafbf 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Shaders/VolumetricLighting.compute +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/Fog/Shaders/VolumetricLighting.compute @@ -24,7 +24,7 @@ #pragma multi_compile_local _ ENABLE_REPROJECTION #pragma multi_compile_local _ SUPPORT_LOCAL_LIGHTS SUPPORT_LOCAL_LIGHTS_SHADOWS #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE -#pragma multi_compile _ _LIGHT_FALLOFF_LINEAR +#pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ _LIGHT_COOKIES diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index d73caffd754..f26563a2444 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -1006,7 +1006,7 @@ internal static class ShaderGlobalKeywords 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); - public static readonly GlobalKeyword LightFalloffLinear = GlobalKeyword.Create(ShaderKeywordStrings.LightFalloffLinear); + public static readonly GlobalKeyword LightFalloffQuadratic = GlobalKeyword.Create(ShaderKeywordStrings.LightFalloffQuadratic); // TODO: Move following keywords to Local keywords? // https://docs.unity3d.com/ScriptReference/Rendering.LocalKeyword.html @@ -1427,7 +1427,7 @@ public static class ShaderKeywordStrings public const string DEPTH_AS_INPUT_ATTACHMENT_MSAA = "_DEPTH_AS_INPUT_ATTACHMENT_MSAA"; /// Keyword used to enable Built-in Render Pipeline compatible light falloff. - public const string LightFalloffLinear = "_LIGHT_FALLOFF_LINEAR"; + public const string LightFalloffQuadratic = "_LIGHT_FALLOFF_QUADRATIC"; } public sealed partial class UniversalRenderPipeline @@ -1658,7 +1658,7 @@ internal static RenderTextureDescriptor CreateRenderTextureDescriptor(Camera cam // This ensures that the baked punctual light intensity matches realtime intensity. (See GFXLIGHT-1755) const float piCorrection = Mathf.PI; - FalloffType punctualFalloff = IsLinearFalloffEnabled() ? FalloffType.Legacy : FalloffType.InverseSquared; + FalloffType punctualFalloff = IsQuadraticFalloffEnabled() ? FalloffType.Legacy : FalloffType.InverseSquared; #if UNITY_EDITOR // Always extract lights in the Editor. @@ -1883,9 +1883,9 @@ internal static void GetSpotDirection(ref Matrix4x4 lightLocalToWorldMatrix, out lightSpotDir = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f); } - internal static bool IsLinearFalloffEnabled() + internal static bool IsQuadraticFalloffEnabled() { - return asset != null && asset.lightFalloffMode == LightFalloffMode.Linear; + return asset != null && asset.lightFalloffMode == LightFalloffMode.Quadratic; } /// diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl index 87e8359076f..b70fb3a6776 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl @@ -53,7 +53,7 @@ float DistanceAttenuation(float distanceSqr, half2 distanceAttenuation, float di float DistanceAttenuation(float distanceSqr, half2 distanceAttenuation) #endif { -#if defined(_LIGHT_FALLOFF_LINEAR) +#if defined(_LIGHT_FALLOFF_QUADRATIC) half rangeRelDistSqr = half(distanceSqr * distanceAttenuation.x); half atten = half(1.0) / (half(1.0) + half(25.0) * rangeRelDistSqr); half fadeFactor = saturate((half(1.0) - rangeRelDistSqr) * distanceAttenuation.y); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader index 77f29ba4f63..9442c157409 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader @@ -145,7 +145,7 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ _LIGHT_LAYERS #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader index ab76c0139c2..b22ecdb190f 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader @@ -145,7 +145,7 @@ Shader "Universal Render Pipeline/Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING 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 abf756ecc48..890c555be35 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader @@ -41,7 +41,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ LOD_FADE_CROSSFADE 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 a6caed611fa..8f54b62a2dd 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader @@ -36,7 +36,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7 Billboard" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP 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 61c92e4e3bf..7c51746be13 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader @@ -56,7 +56,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ _LIGHT_LAYERS #pragma multi_compile_fragment _ _CLUSTER_LIGHT_LOOP #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS 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 bdf98ade0fb..38452479c40 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader @@ -132,7 +132,7 @@ Shader "Universal Render Pipeline/Particles/Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION 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 e7e70605763..af6579b3f92 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader @@ -137,7 +137,7 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader index f5ebe599356..ee955f8b7d3 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader @@ -109,7 +109,7 @@ Shader "Universal Render Pipeline/Simple Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader index 5ea604b0e5c..2c8a2b0dd9a 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLit.shader @@ -22,7 +22,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/Vertexlit" // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile_vertex _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK 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 5cc55fc6c89..fb4e0429c11 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader @@ -68,7 +68,7 @@ Shader "Universal Render Pipeline/Terrain/Lit" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS 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 72ce52a0590..09087bfe700 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader @@ -63,7 +63,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS 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 427208e7ff9..0c61453b218 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader @@ -41,7 +41,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS 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 efe6af30e9d..77db6096f79 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader @@ -31,7 +31,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/WavingDoublePass" #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING #pragma multi_compile _ SHADOWS_SHADOWMASK #pragma multi_compile _ _LIGHT_LAYERS 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 dce0a5f5247..720f73f3d09 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader @@ -31,7 +31,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/BillboardWavingDoublePass #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX #pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS - #pragma multi_compile _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader index 9a7f3698401..8fc3ddb164e 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ClusterDeferred.shader @@ -58,7 +58,7 @@ Shader "Hidden/Universal Render Pipeline/ClusterDeferred" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile_fragment _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile_fragment _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING @@ -124,7 +124,7 @@ Shader "Hidden/Universal Render Pipeline/ClusterDeferred" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN - #pragma multi_compile_fragment _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile_fragment _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader index 4a963d71d75..a2e90452845 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/StencilDeferred.shader @@ -126,7 +126,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _POINT _SPOT - #pragma multi_compile_fragment _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile_fragment _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING @@ -192,7 +192,7 @@ Shader "Hidden/Universal Render Pipeline/StencilDeferred" // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile _POINT _SPOT - #pragma multi_compile_fragment _ _LIGHT_FALLOFF_LINEAR + #pragma multi_compile_fragment _ _LIGHT_FALLOFF_QUADRATIC #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING 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 3b1ec47f851..eea41f7d36d 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs @@ -406,7 +406,7 @@ public void TestGetSupportedShaderFeaturesFromAsset_HighDynamicRange() m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); } - // ShaderFeatures.LightFalloffLinear - _LIGHT_FALLOFF_LINEAR + // ShaderFeatures.LightFalloffQuadratic - _LIGHT_FALLOFF_QUADRATIC [Test] public void TestGetSupportedShaderFeaturesFromAsset_LightFalloff() { @@ -415,9 +415,9 @@ public void TestGetSupportedShaderFeaturesFromAsset_LightFalloff() ShaderFeatures expected = m_TestHelper.defaultURPAssetFeatures; m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); - m_TestHelper.urpAsset.lightFalloffMode = LightFalloffMode.Linear; + m_TestHelper.urpAsset.lightFalloffMode = LightFalloffMode.Quadratic; actual = m_TestHelper.GetSupportedShaderFeaturesFromAsset(); - expected = m_TestHelper.defaultURPAssetFeatures | ShaderFeatures.LightFalloffLinear; + expected = m_TestHelper.defaultURPAssetFeatures | ShaderFeatures.LightFalloffQuadratic; m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); } diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs index 0ef4fe4acb5..730d9c021c7 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs @@ -840,7 +840,7 @@ public void TestStripUnusedFeatures(string shaderName) TestStripUnusedFeatures_AccurateGbufferNormals(shader); TestStripUnusedFeatures_LightCookies(shader); TestStripUnusedFeatures_VolumetricFog(shader); - TestStripUnusedFeatures_LightFalloffLinear(shader); + TestStripUnusedFeatures_LightFalloffQuadratic(shader); TestStripUnusedFeatures_ProbesVolumes(shader); TestStripUnusedFeatures_SHAuto(shader); TestStripUnusedFeatures_DataDrivenLensFlare(shader); @@ -2441,27 +2441,27 @@ public void TestStripUnusedFeatures_VolumetricFog(Shader shader) helper.IsFalse(helper.stripper.StripUnusedFeatures_VolumetricFog(ref helper.data, ref helper.featureStripTool)); } - public void TestStripUnusedFeatures_LightFalloffLinear(Shader shader) + public void TestStripUnusedFeatures_LightFalloffQuadratic(Shader shader) { TestHelper helper; helper = new TestHelper(shader, ShaderFeatures.None); - TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffLinear }; - helper.IsFalse(helper.stripper.StripUnusedFeatures_LightFalloffLinear(ref helper.featureStripTool)); + TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffQuadratic }; + helper.IsFalse(helper.stripper.StripUnusedFeatures_LightFalloffQuadratic(ref helper.featureStripTool)); helper = new TestHelper(shader, ShaderFeatures.None); - TestHelper.s_EnabledKeywords = new List() { ShaderKeywordStrings.LightFalloffLinear }; - TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffLinear }; - helper.AreEqual(shader != null, helper.stripper.StripUnusedFeatures_LightFalloffLinear(ref helper.featureStripTool)); + TestHelper.s_EnabledKeywords = new List() { ShaderKeywordStrings.LightFalloffQuadratic }; + TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffQuadratic }; + helper.AreEqual(shader != null, helper.stripper.StripUnusedFeatures_LightFalloffQuadratic(ref helper.featureStripTool)); - helper = new TestHelper(shader, ShaderFeatures.LightFalloffLinear); - TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffLinear }; - helper.IsFalse(helper.stripper.StripUnusedFeatures_LightFalloffLinear(ref helper.featureStripTool)); + helper = new TestHelper(shader, ShaderFeatures.LightFalloffQuadratic); + TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffQuadratic }; + helper.IsFalse(helper.stripper.StripUnusedFeatures_LightFalloffQuadratic(ref helper.featureStripTool)); - helper = new TestHelper(shader, ShaderFeatures.LightFalloffLinear); - TestHelper.s_EnabledKeywords = new List() { ShaderKeywordStrings.LightFalloffLinear }; - TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffLinear }; - helper.IsFalse(helper.stripper.StripUnusedFeatures_LightFalloffLinear(ref helper.featureStripTool)); + helper = new TestHelper(shader, ShaderFeatures.LightFalloffQuadratic); + TestHelper.s_EnabledKeywords = new List() { ShaderKeywordStrings.LightFalloffQuadratic }; + TestHelper.s_PassKeywords = new List() { ShaderKeywordStrings.LightFalloffQuadratic }; + helper.IsFalse(helper.stripper.StripUnusedFeatures_LightFalloffQuadratic(ref helper.featureStripTool)); } public void TestStripUnusedFeatures_ProbesVolumes(Shader shader) diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Linear.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Quadratic.asset similarity index 99% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Linear.asset rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Quadratic.asset index 971b5b96253..d96040fef35 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Linear.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Quadratic.asset @@ -10,7 +10,7 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3} - m_Name: 056_Falloff_Linear + m_Name: 056_Falloff_Quadratic m_EditorClassIdentifier: k_AssetVersion: 13 k_AssetPreviousVersion: 13 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Linear.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Quadratic.asset.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Linear.asset.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/URPAssets/056_Falloff_Quadratic.asset.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic.unity similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear.unity rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic.unity diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic.unity.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear.unity.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic.unity.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting similarity index 97% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting index dc9704bca69..7bc073fed81 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting @@ -6,7 +6,7 @@ LightingSettings: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: 056_Lighting_Falloff_LinearSettings + m_Name: 056_Lighting_Falloff_QuadraticSettings serializedVersion: 10 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 0 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/056_Lighting_Falloff_LinearSettings.lighting.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/056_Lighting_Falloff_QuadraticSettings.lighting.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/LightingData.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/LightingData.asset similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/LightingData.asset rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/LightingData.asset diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/LightingData.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/LightingData.asset.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/LightingData.asset.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/LightingData.asset.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/Lightmap-0_comp_light.exr b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/Lightmap-0_comp_light.exr similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/Lightmap-0_comp_light.exr rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/Lightmap-0_comp_light.exr diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/Lightmap-0_comp_light.exr.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/Lightmap-0_comp_light.exr.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/Lightmap-0_comp_light.exr.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/Lightmap-0_comp_light.exr.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/NeutralGray.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/NeutralGray.mat similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/NeutralGray.mat rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/NeutralGray.mat diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/NeutralGray.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/NeutralGray.mat.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/NeutralGray.mat.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/NeutralGray.mat.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/SpotCookie.png b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/SpotCookie.png similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/SpotCookie.png rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/SpotCookie.png diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/SpotCookie.png.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/SpotCookie.png.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear/SpotCookie.png.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic/SpotCookie.png.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.unity similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred.unity rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.unity diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.unity.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred.unity.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.unity.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/LightingData.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/LightingData.asset similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/LightingData.asset rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/LightingData.asset diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/LightingData.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/LightingData.asset.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/LightingData.asset.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/LightingData.asset.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/Lightmap-0_comp_light.exr b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/Lightmap-0_comp_light.exr similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/Lightmap-0_comp_light.exr rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/Lightmap-0_comp_light.exr diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/Lightmap-0_comp_light.exr.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/Lightmap-0_comp_light.exr.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Linear_deferred/Lightmap-0_comp_light.exr.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred/Lightmap-0_comp_light.exr.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/EditorBuildSettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/EditorBuildSettings.asset index 884d54597de..667c3d7d24a 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/EditorBuildSettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/EditorBuildSettings.asset @@ -57,10 +57,10 @@ EditorBuildSettings: path: Assets/Scenes/055_Lighting_Attenuation_Spot_Point.unity guid: 362b9a0c21a9b4e798504044c7604e80 - enabled: 1 - path: Assets/Scenes/056_Lighting_Falloff_Linear.unity + path: Assets/Scenes/056_Lighting_Falloff_Quadratic.unity guid: 12641eb34e1878947862d8b2400d8ed6 - enabled: 1 - path: Assets/Scenes/056_Lighting_Falloff_Linear_deferred.unity + path: Assets/Scenes/056_Lighting_Falloff_Quadratic_deferred.unity guid: 9729d2c1246947449b888799ef1a8725 - enabled: 1 path: Assets/Scenes/060_Deferred_GBuffer.unity diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/QualitySettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/QualitySettings.asset index cc79de09f7c..9bce1ef7ba8 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/QualitySettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/ProjectSettings/QualitySettings.asset @@ -908,7 +908,7 @@ QualitySettings: terrainMaxTrees: 50 excludedTargetPlatforms: [] - serializedVersion: 5 - name: 17-056_Falloff_Linear + name: 17-056_Falloff_Quadratic pixelLightCount: 4 shadows: 2 shadowResolution: 2 From aab930034647cb578513128b964db58e6f6e3b5a Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Wed, 16 Sep 2026 13:35:20 +0000 Subject: [PATCH 014/192] [Port] [6000.7] Fix rendering corruption caused by improperly synchronized pooled resource access in async compute (v2) --- .../Compiler/NativePassCompiler.cs | 143 ++++-- .../RenderGraph/Compiler/ResourcesData.cs | 15 + .../RenderGraph/RenderGraphResourceBuffer.cs | 8 +- .../RenderGraphResourceRegistry.cs | 10 +- .../RenderGraph/RenderGraphResourceTexture.cs | 8 +- .../RenderGraph/RenderGraphResources.cs | 23 +- .../Tests/Editor/RenderGraphTests.cs | 428 +++++++++++++++++- 7 files changed, 569 insertions(+), 66 deletions(-) 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 0df51ed12ac..d051a5c28d8 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 @@ -798,51 +798,63 @@ void CompactNonCulledPassesForRasterPasses() } } - bool FindFirstPassIdOnGraphicsQueueAwaitingFenceGoingForward(ref PassData startAsyncPass, out int firstPassIdAwaiting) + // Returns the first graphics pass that waits on a fence signalled by an async compute pass at or after + // lastAsyncComputeUsePassId. The async compute queue executes in order, so such a fence also covers the async + // compute usage at lastAsyncComputeUsePassId itself. Falls back to the last non-culled pass of the graph when + // the graphics queue never waits for that work. + // + // The waiting pass is included rather than the one before it, because a pass records its resource creation, + // which can clear the memory, before its own WaitOnAsyncGraphicsFence. Recycling into the waiting pass would + // let that clear race the async compute work still using the memory. + int FindPassIdWhereGraphicsWaitsForAsyncComputeFence(int lastAsyncComputeUsePassId) { var ctx = contextData; - Debug.Assert(startAsyncPass.asyncCompute && !startAsyncPass.culled); + Debug.Assert(ctx.passData.ElementAt(lastAsyncComputeUsePassId).asyncCompute + && !ctx.passData.ElementAt(lastAsyncComputeUsePassId).culled); - firstPassIdAwaiting = startAsyncPass.awaitingMyGraphicsFencePassId; - - // This async pass has no one waiting for it, try the next async passes - if (firstPassIdAwaiting == -1) + for (int passId = lastAsyncComputeUsePassId; passId < ctx.passData.Length; ++passId) { - var nextPassIndex = startAsyncPass.passId + 1; - var lastPassIndex = ctx.passData.Length - 1; + ref readonly var pass = ref ctx.passData.ElementAt(passId); - // Find the first async pass that is synchronized by the graphics queue - while (firstPassIdAwaiting == -1 && nextPassIndex <= lastPassIndex) - { - ref var nextPass = ref ctx.passData.ElementAt(nextPassIndex); + if (pass.asyncCompute && !pass.culled && pass.awaitingMyGraphicsFencePassId != -1) + return pass.awaitingMyGraphicsFencePassId; + } - if (nextPass.asyncCompute && !nextPass.culled) - firstPassIdAwaiting = nextPass.awaitingMyGraphicsFencePassId; + return FindFirstNonCulledPassIdGoingBackward(ctx.passData.Length - 1); + } - nextPassIndex++; - } + // Mirror of the above: the first async compute pass that waits on a fence signalled by the graphics queue at or + // after lastGraphicsUsePassId. Every async compute pass following it is ordered after that fence as well, + // because the async compute queue executes in order. Falls back to the last non-culled pass of the graph when + // the async compute queue never waits for that work. + // + // Including the waiting pass is not strictly required in this direction, as resource creation is always + // recorded on the graphics command buffer and is therefore ordered after the graphics work being protected, + // but it keeps both directions consistent. + int FindPassIdWhereAsyncComputeWaitsForGraphicsFence(int lastGraphicsUsePassId) + { + var ctx = contextData; - // We didn't find any fence, this should not happen? - if (nextPassIndex > lastPassIndex) - { - // For now we fallback to the last pass of the graph - firstPassIdAwaiting = lastPassIndex; - return false; - } + for (int passId = lastGraphicsUsePassId + 1; passId < ctx.passData.Length; ++passId) + { + ref readonly var pass = ref ctx.passData.ElementAt(passId); + + if (pass.asyncCompute && !pass.culled && pass.waitOnGraphicsFencePassId >= lastGraphicsUsePassId) + return passId; } - // Found a pass awaiting a fence - return true; + return FindFirstNonCulledPassIdGoingBackward(ctx.passData.Length - 1); } - int FindFirstNonCulledPassIdGoingBackward(int startPassId, bool startPassIsIncluded) + // Walks backward from startPassId, which is included, to the first pass that is not culled. + int FindFirstNonCulledPassIdGoingBackward(int startPassId) { var ctx = contextData; Debug.Assert(startPassId >= 0 && startPassId < ctx.passData.Length); - var currPassId = startPassIsIncluded ? startPassId : Math.Max(0, startPassId - 1); + var currPassId = startPassId; ref var currPass = ref ctx.passData.ElementAt(currPassId); @@ -855,12 +867,54 @@ int FindFirstNonCulledPassIdGoingBackward(int startPassId, bool startPassIsInclu return currPass.passId; } + // Works out whether the pass that last uses a resource can release it back to the pool right away, or whether + // that has to be delayed so that no queue is still working on the resource once another one reuses its memory. + // Returns false when the current pass can release the resource directly. + bool TryGetDelayedLastUsePassId(ref PassData pass, in ResourceUnversionedData pointTo, int lastAsyncComputePassId, out int delayedLastUsePassId) + { + delayedLastUsePassId = -1; + + // Imported resources never go through the pool, so no delay is required. + if (pointTo.isImported) + return false; + + // Because we pool graphics-queue-only resources separately, no special delay logic is required. + // See RenderGraphResource.CreatePooledGraphicsResource(). + if (pointTo.lastAsyncComputeUsePassID == -1) + return false; + + // Resource is used by both queues, but there are no async compute passes after this one so it can be safely returned to the pool. + if (pointTo.lastGraphicsUsePassID >= 0 && lastAsyncComputePassId <= pass.passId) + return false; + + var delayed = -1; + + // A later async compute pass could reuse this resource from the pool, and nothing makes it wait for the + // graphics work still running on it. Keep it out of the pool until the first async compute pass that does + // wait for the graphics queue. The async compute queue runs in order, so from that pass onwards the graphics + // work is done. If there is no such pass, hold on to it until the end of the graph (not ideal but safe). + if (pointTo.lastGraphicsUsePassID >= 0) + delayed = Math.Max(delayed, FindPassIdWhereAsyncComputeWaitsForGraphicsFence(pointTo.lastGraphicsUsePassID)); + + // The same thing the other way around: a later graphics pass could be handed this resource while the async + // compute work on it is still running, so wait for the first graphics pass that awaits a fence from it. + delayed = Math.Max(delayed, FindPassIdWhereGraphicsWaitsForAsyncComputeFence(pointTo.lastAsyncComputeUsePassID)); + + if (delayed <= pass.passId) + return false; + + delayedLastUsePassId = delayed; + return true; + } + void FindResourceUsageRangeAndSynchronization() { var ctx = contextData; using (k_FindResourceUsageRanges.Auto()) { + int lastAsyncComputePassId = -1; + // Algorithm is in two steps, traversing the list of passes twice // First forward traversal: @@ -874,6 +928,9 @@ void FindResourceUsageRangeAndSynchronization() if (pass.culled) continue; + if (pass.asyncCompute) + lastAsyncComputePassId = pass.passId; + // In case of an async pass, we need to extend the lifetime of the resource to the first pass on the graphics queue that waits for this async pass to be completed. // By doing so, we ensure that the resource will not be released back to the pool right after adding the async pass commands to the async queue, // as it could create a data race condition if a non async pass reuses the resource from the pool while the async pass is still processing it @@ -893,6 +950,16 @@ void FindResourceUsageRangeAndSynchronization() ref var pointToVer = ref ctx.VersionedResourceData(inputResource); pointTo.lastUsePassID = -1; + // Track where each queue last uses this resource: the pool uses this to keep async compute + // resources separate, and the second traversal uses it to work out where the resource can + // safely be released. Reads count, not just writes. A resource only read on the async queue + // but last used on the graphics queue can still have async work outstanding when that + // graphics pass is done with it. + if (pass.asyncCompute) + pointTo.lastAsyncComputeUsePassID = pass.passId; + else + pointTo.lastGraphicsUsePassID = pass.passId; + // If nobody else is using it yet, // mark this pass as the first using the resource. // It can happen that two passes use v0, e.g.: @@ -933,6 +1000,12 @@ void FindResourceUsageRangeAndSynchronization() ref var pointTo = ref ctx.UnversionedResourceData(outputResource); ref var pointToVer = ref ctx.VersionedResourceData(outputResource); + // Track where each queue last uses this resource (see comment above in the Inputs loop) + if (pass.asyncCompute) + pointTo.lastAsyncComputeUsePassID = pass.passId; + else + pointTo.lastGraphicsUsePassID = pass.passId; + // If nobody else is using it yet (no explicit read), // Mark this pass as the first using the resource. // It can happen that two passes use v0, e.g.: @@ -985,8 +1058,6 @@ void FindResourceUsageRangeAndSynchronization() if (pass.culled) continue; - bool isAsync = pass.asyncCompute; - foreach (ref readonly var input in pass.Inputs(ctx)) { var inputResource = input.resource; @@ -997,11 +1068,8 @@ void FindResourceUsageRangeAndSynchronization() var refC = pointTo.tag - 1; //Decrease refcount this pass is done using it if (refC == 0) // We're the last pass done using it, this pass should destroy it. { - if (isAsync) + if (TryGetDelayedLastUsePassId(ref pass, pointTo, lastAsyncComputePassId, out int delayLastUsedPassId)) { - // If no fence found, we fallback to the last non culled pass of the graph on graphics queue, not ideal but safe - bool foundFence = FindFirstPassIdOnGraphicsQueueAwaitingFenceGoingForward(ref pass, out int firstWaitingOrLastPassId); - var delayLastUsedPassId = FindFirstNonCulledPassIdGoingBackward(firstWaitingOrLastPassId, !foundFence); pointTo.lastUsePassID = delayLastUsedPassId; AddDelayedLastUseToPass(inputResource, delayLastUsedPassId); } @@ -1027,11 +1095,8 @@ void FindResourceUsageRangeAndSynchronization() var last = pointTo.latestVersionNumber; if (last == outputResource.version && pointToVer.numReaders == 0) { - if (isAsync) + if (TryGetDelayedLastUsePassId(ref pass, pointTo, lastAsyncComputePassId, out int delayLastUsedPassId)) { - // If no fence found, we fallback to the last non culled pass of the graph, not ideal but safe - bool foundFence = FindFirstPassIdOnGraphicsQueueAwaitingFenceGoingForward(ref pass, out int firstWaitingOrLastPassId); - var delayLastUsedPassId = FindFirstNonCulledPassIdGoingBackward(firstWaitingOrLastPassId, !foundFence); pointTo.lastUsePassID = delayLastUsedPassId; AddDelayedLastUseToPass(outputResource, delayLastUsedPassId); } @@ -1311,7 +1376,7 @@ private bool ExecuteInitializeResource(InternalRenderGraphContext rgContext, Ren // We create the resources from a pool // memoryless resources are also created but will not allocate in system memory - haveGfxCommandsBeenAddedToCmd |= resources.CreatePooledResource(rgContext, res.iType, res.index); + haveGfxCommandsBeenAddedToCmd |= resources.CreatePooledResource(rgContext, res.iType, res.index, resInfo.usedByAsyncComputePass); } else // Imported resource { @@ -1332,7 +1397,7 @@ private bool ExecuteInitializeResource(InternalRenderGraphContext rgContext, Ren ref readonly var pointTo = ref contextData.UnversionedResourceData(create); if (!pointTo.isImported) { - haveGfxCommandsBeenAddedToCmd |= resources.CreatePooledResource(rgContext, create.iType, create.index); + haveGfxCommandsBeenAddedToCmd |= resources.CreatePooledResource(rgContext, create.iType, create.index, pointTo.usedByAsyncComputePass); } else // Imported resource { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs index a2479ef219b..903bbfb72f1 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs @@ -36,8 +36,15 @@ internal struct ResourceUnversionedData public readonly bool isImported; // Imported graph resource public bool memoryLess; // Never create the texture on GPU if it is allocated/freed within a renderpass + public int lastGraphicsUsePassID; // Last non culled pass using this resource on the graphics queue, -1 if none + public int lastAsyncComputeUsePassID; // Last non culled pass using this resource on the async compute queue, -1 if none public int tag; + // True when at least one non-culled async compute pass touches this resource, whether or not graphics passes + // use it as well. These are pooled separately from resources only ever used on the graphics queue. + // See RenderGraphResource.CreatePooledGraphicsResource(). + public readonly bool usedByAsyncComputePass => lastAsyncComputeUsePassID >= 0; + public readonly int width; public readonly int height; public readonly int volumeDepth; @@ -61,6 +68,8 @@ public ResourceUnversionedData(TextureResource rll, ref RenderTargetInfo info, r firstUsePassID = -1; lastUsePassID = -1; lastWritePassID = -1; + lastGraphicsUsePassID = -1; + lastAsyncComputeUsePassID = -1; // Check if imported texture is memoryless memoryLess = desc.memoryless != RenderTextureMemoryless.None; @@ -95,6 +104,8 @@ public ResourceUnversionedData(IRenderGraphResource rll, ref BufferDesc _, bool lastUsePassID = -1; lastWritePassID = -1; memoryLess = false; + lastGraphicsUsePassID = -1; + lastAsyncComputeUsePassID = -1; width = -1; height = -1; @@ -126,6 +137,8 @@ public ResourceUnversionedData(IRenderGraphResource rll, ref RayTracingAccelerat lastUsePassID = -1; lastWritePassID = -1; memoryLess = false; + lastGraphicsUsePassID = -1; + lastAsyncComputeUsePassID = -1; width = -1; height = -1; @@ -152,6 +165,8 @@ public void InitializeNullResource() firstUsePassID = -1; lastUsePassID = -1; lastWritePassID = -1; + lastGraphicsUsePassID = -1; + lastAsyncComputeUsePassID = -1; textureUVOrigin = TextureUVOriginSelection.Unknown; } } 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 7fab19b20f6..b3521d1937a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceBuffer.cs @@ -91,14 +91,16 @@ public BufferDesc(int count, int stride, GraphicsBuffer.Target target) /// Hash function /// /// The texture descriptor hash. - public override int GetHashCode() + public override int GetHashCode() => ComputeDescHash().value; + + internal HashFNV1A32 ComputeDescHash() { var hashCode = HashFNV1A32.Create(); hashCode.Append(count); hashCode.Append(stride); hashCode.Append((int) target); hashCode.Append((int) usageFlags); - return hashCode.value; + return hashCode; } } @@ -114,7 +116,7 @@ public override string GetName() return desc.name; } - public override int GetDescHashCode() { return desc.GetHashCode(); } + public override HashFNV1A32 GetDescHash() { return desc.ComputeDescHash(); } public override void CreateGraphicsResource() { 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 d7bf7daff00..a0199363258 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs @@ -1079,7 +1079,7 @@ void ManageSharedRenderGraphResources() } } - internal bool CreatePooledResource(InternalRenderGraphContext rgContext, int type, int index) + internal bool CreatePooledResource(InternalRenderGraphContext rgContext, int type, int index, bool usedByAsyncComputePass) { Debug.Assert(index != 0, "Index 0 indicates the null object it can't be used here"); @@ -1087,19 +1087,13 @@ internal bool CreatePooledResource(InternalRenderGraphContext rgContext, int typ var resource = m_RenderGraphResources[type].resourceArray[index]; if (!resource.imported) { - resource.CreatePooledGraphicsResource(m_CurrentFrameIndex, m_ExecutionCount); + resource.CreatePooledGraphicsResource(m_CurrentFrameIndex, m_ExecutionCount, usedByAsyncComputePass); executedWork = m_RenderGraphResources[type].createResourceCallback?.Invoke(rgContext, resource); } return executedWork ?? false; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool CreatePooledResource(InternalRenderGraphContext rgContext, in ResourceHandle handle) - { - return CreatePooledResource(rgContext, handle.iType, handle.index); - } - // Only modified by native compiler when using native render pass internal bool forceManualClearOfResource = true; 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 0390f482d31..ccbd52902a8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs @@ -500,7 +500,9 @@ public TextureDesc(RenderTexture input) : this(input.descriptor) /// Hash function /// /// The texture descriptor hash. - public override int GetHashCode() + public override int GetHashCode() => ComputeDescHash().value; + + internal HashFNV1A32 ComputeDescHash() { var hashCode = HashFNV1A32.Create(); switch (sizeMode) @@ -536,7 +538,7 @@ public override int GetHashCode() hashCode.Append((int) msaaSamples); hashCode.Append(fastMemoryDesc.inFastMemory); hashCode.Append(enableShadingRate); - return hashCode.value; + return hashCode; } /// @@ -581,7 +583,7 @@ public override string GetName() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetDescHashCode() { return desc.GetHashCode(); } + public override HashFNV1A32 GetDescHash() { return desc.ComputeDescHash(); } public override void CreateGraphicsResource() { 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 4e06650ccd1..36fadc750f6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs @@ -186,7 +186,7 @@ public virtual void Reset(IRenderGraphResourcePool _ = null) requestFallBack = false; writeCount = 0; readCount = 0; - + #if UNITY_ENABLE_CHECKS debugScriptInfo = default; #endif @@ -224,13 +224,13 @@ public virtual bool NeedsFallBack() return requestFallBack && writeCount == 0; } - public virtual void CreatePooledGraphicsResource(int frameIndex, int executionCount) { } + public virtual void CreatePooledGraphicsResource(int frameIndex, int executionCount, bool usedByAsyncComputePass) { } public virtual void CreateGraphicsResource() { } public virtual void UpdateGraphicsResource() { } public virtual void ReleasePooledGraphicsResource(int frameIndex, int executionCount) { } public virtual void ReleaseGraphicsResource() { } public virtual int GetSortIndex() { return 0; } - public virtual int GetDescHashCode() { return 0; } + public virtual HashFNV1A32 GetDescHash() { return HashFNV1A32.Create(); } } [DebuggerDisplay("Resource ({GetType().Name}:{GetName()})")] @@ -270,11 +270,24 @@ public override void ReleaseGraphicsResource() graphicsResource = null; } - public override void CreatePooledGraphicsResource(int frameIndex, int executionCount) + public override void CreatePooledGraphicsResource(int frameIndex, int executionCount, bool usedByAsyncComputePass) { Debug.Assert(m_Pool != null, "RenderGraphResource: CreatePooledGraphicsResource should only be called for regular pooled resources"); - int hashCode = GetDescHashCode(); + var hash = GetDescHash(); + // Resource pooling is a problem with async compute because recycling a pooled resource introduces a + // hidden data dependency that is not visible to the compiler, causing data races between graphics and compute + // queues. In the general case this is solved by the "delayed last use" logic in NativePassCompiler.TryGetDelayedLastUsePassId(), + // which delays returning of the resource to the pool to a point where its memory can be safely reused. + // + // By mixing async usage into the pool hash, we split "graphics queue only" and "touched from async queue" + // into two separate pool buckets, across which memory is never shared. This allows graphics-only resources + // to be reused safely with each other within a frame without needing to delay their return to the pool. + // If we were to NOT do this, the delay logic would have to run for every graphics-only resource as well, + // extending their lifetimes in any graph that uses async compute at all and severely reducing the + // effectiveness of the pooling. + hash.Append(usedByAsyncComputePass); + int hashCode = hash.value; if (graphicsResource != null) throw new InvalidOperationException($"RenderGraphResource: Trying to create an already created resource ({GetName()}). Resource was probably declared for writing more than once in the same pass."); diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs index d72d21bfb9d..5ba44598188 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs @@ -398,7 +398,8 @@ public void AsyncPassReleaseTextureOnGraphicsPipe() builder.SetRenderFunc((RenderGraphTestPassData data, UnsafeGraphContext context) => { }); } - // Just here to add "padding" to the number of passes to ensure resources are not released right at the first sync pass. + // Just here to add "padding" to the number of passes to ensure resources are not released right after the + // last async pass using them. using (var builder = m_RenderGraph.AddUnsafePass("TestPass3", out var passData)) { builder.UseTexture(texture3, AccessFlags.Write); @@ -406,7 +407,7 @@ public void AsyncPassReleaseTextureOnGraphicsPipe() builder.SetRenderFunc((RenderGraphTestPassData data, UnsafeGraphContext context) => { }); } - // Pass prior to synchronization should be where textures are released. + // More padding, so that releasing at the synchronizing pass is distinguishable from releasing just before it. using (var builder = m_RenderGraph.AddUnsafePass("TestPass4", out var passData)) { builder.UseTexture(texture3, AccessFlags.Write); @@ -414,7 +415,9 @@ public void AsyncPassReleaseTextureOnGraphicsPipe() builder.SetRenderFunc((RenderGraphTestPassData data, UnsafeGraphContext context) => { }); } - // Graphics pass that reads texture1. This will request a sync with compute pipe. The previous pass should be the one releasing async textures. + // Graphics pass that reads texture1. This will request a sync with compute pipe. This pass should be the one + // releasing async textures: it creates its resources before waiting on the fence, so it must not be handed + // memory the compute pipe is still using either. using (var builder = m_RenderGraph.AddUnsafePass("TestPass5", out var passData)) { builder.UseTexture(texture1, AccessFlags.Read); @@ -436,18 +439,427 @@ public void AsyncPassReleaseTextureOnGraphicsPipe() var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); var compiledPasses = result.contextData.GetPasses(); - var releasedResourcePass4List = new List(); - foreach (ref readonly var releasedRes in compiledPasses[4].LastUsedResources(result.contextData)) + var releasedResourcePass5List = new List(); + foreach (ref readonly var releasedRes in compiledPasses[5].LastUsedResources(result.contextData)) { - releasedResourcePass4List.Add(releasedRes.index); + releasedResourcePass5List.Add(releasedRes.index); } Assert.AreEqual(7, compiledPasses.Count); Assert.AreEqual(5, compiledPasses[2].awaitingMyGraphicsFencePassId); Assert.AreEqual(2, compiledPasses[5].waitOnGraphicsFencePassId); - Assert.Contains(texture0.handle.index, releasedResourcePass4List); - Assert.Contains(texture2.handle.index, releasedResourcePass4List); + Assert.Contains(texture0.handle.index, releasedResourcePass5List); + Assert.Contains(texture2.handle.index, releasedResourcePass5List); + } + + // Helpers for the UUM-141896 tests below. Recycling a pooled resource creates a dependency between the pass + // releasing it and the pass receiving it that the compiler cannot see or fence. Two rules keep this safe with + // async compute: resources touched by an async compute pass are pooled separately from graphics queue only + // ones, and their release back to the pool is delayed until every queue with work in flight on them is + // provably done. + void AddTestComputePass(string name, bool asyncCompute, TextureHandle[] reads = null, + TextureHandle[] writes = null, bool allowCulling = true, Action captureFirstWrite = null) + { + using (var builder = m_RenderGraph.AddComputePass(name, out var passData)) + { + foreach (var texture in reads ?? Array.Empty()) + builder.UseTexture(texture, AccessFlags.Read); + foreach (var texture in writes ?? Array.Empty()) + builder.UseTexture(texture, AccessFlags.Write); + + if (!allowCulling) + builder.AllowPassCulling(false); + builder.EnableAsyncCompute(asyncCompute); + + if (captureFirstWrite != null) + { + passData.textures[0] = writes[0]; + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext context) => + { + captureFirstWrite(data.textures[0]); + }); + } + else + { + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext context) => { }); + } + } + } + + void AddTestComputePass(string name, bool asyncCompute, BufferHandle[] reads = null, + BufferHandle[] writes = null, bool allowCulling = true, Action captureFirstWrite = null) + { + using (var builder = m_RenderGraph.AddComputePass(name, out var passData)) + { + foreach (var buffer in reads ?? Array.Empty()) + builder.UseBuffer(buffer, AccessFlags.Read); + foreach (var buffer in writes ?? Array.Empty()) + builder.UseBuffer(buffer, AccessFlags.Write); + + if (!allowCulling) + builder.AllowPassCulling(false); + builder.EnableAsyncCompute(asyncCompute); + + if (captureFirstWrite != null) + { + passData.buffers[0] = writes[0]; + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext context) => + { + captureFirstWrite(data.buffers[0]); + }); + } + else + { + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext context) => { }); + } + } + } + + static List LastUsedResourceIndices(in PassData pass, CompilerContextData ctx) + { + var indices = new List(); + foreach (ref readonly var res in pass.LastUsedResources(ctx)) + indices.Add(res.index); + return indices; + } + + // The compiler records the last pass using each resource per queue; the pool split and the delayed release + // are driven by it. + [Test] + public void AsyncComputeResourceUsageIsTracked() + { + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + TextureHandle graphicsTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle graphicsCopy = m_RenderGraph.CreateTexture(desc); + TextureHandle asyncTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle asyncReadByGraphics = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Gfx_Produce", asyncCompute: false, writes: new[] { graphicsTexture }); + AddTestComputePass("Gfx_Copy", asyncCompute: false, + reads: new[] { graphicsTexture }, writes: new[] { graphicsCopy }); + AddTestComputePass("Async_Produce", asyncCompute: true, + writes: new[] { asyncTexture, asyncReadByGraphics }, allowCulling: false); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { graphicsCopy, asyncReadByGraphics }, allowCulling: false); + + var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); + var contextData = result.contextData; + + Assert.AreEqual(4, contextData.GetPasses().Count); + + const int gfxCopyPassId = 1; + const int asyncProducePassId = 2; + const int gfxConsumePassId = 3; + + ref readonly var graphicsTextureData = ref contextData.UnversionedResourceData(graphicsTexture.handle); + Assert.AreEqual(gfxCopyPassId, graphicsTextureData.lastGraphicsUsePassID); + Assert.AreEqual(-1, graphicsTextureData.lastAsyncComputeUsePassID); + + ref readonly var graphicsCopyData = ref contextData.UnversionedResourceData(graphicsCopy.handle); + Assert.AreEqual(gfxConsumePassId, graphicsCopyData.lastGraphicsUsePassID); + Assert.AreEqual(-1, graphicsCopyData.lastAsyncComputeUsePassID); + + ref readonly var asyncTextureData = ref contextData.UnversionedResourceData(asyncTexture.handle); + Assert.AreEqual(-1, asyncTextureData.lastGraphicsUsePassID); + Assert.AreEqual(asyncProducePassId, asyncTextureData.lastAsyncComputeUsePassID); + + // A read is a use: graphics never writes this texture, yet its graphics read must be tracked. + ref readonly var asyncReadByGraphicsData = ref contextData.UnversionedResourceData(asyncReadByGraphics.handle); + Assert.AreEqual(gfxConsumePassId, asyncReadByGraphicsData.lastGraphicsUsePassID); + Assert.AreEqual(asyncProducePassId, asyncReadByGraphicsData.lastAsyncComputeUsePassID); + } + + // A resource used from both queues cannot go back to the pool at the pass that last uses it: the work left on + // the other queue is not ordered against the passes that follow. With a later async compute pass that nothing + // orders after that work, the release can only happen at the end of the graph. + [Test] + public void ResourceUsedOnBothQueuesIsReleasedAtEndOfGraph() + { + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + TextureHandle mixedQueueTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle graphicsTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle laterAsyncTexture = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Async_Produce", asyncCompute: true, writes: new[] { mixedQueueTexture }); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { mixedQueueTexture }, writes: new[] { graphicsTexture }, allowCulling: false); + AddTestComputePass("Async_Later", asyncCompute: true, writes: new[] { laterAsyncTexture }); + // Padding, so that "released at the end of the graph" is distinguishable from "released at its last use". + AddTestComputePass("Gfx_Padding", asyncCompute: false, + reads: new[] { graphicsTexture, laterAsyncTexture }, allowCulling: false); + + var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); + var compiledPasses = result.contextData.GetPasses(); + + Assert.AreEqual(4, compiledPasses.Count); + + var lastPassId = compiledPasses.Count - 1; + + Assert.AreEqual(lastPassId, + result.contextData.UnversionedResourceData(mixedQueueTexture.handle).lastUsePassID); + Assert.Contains(mixedQueueTexture.handle.index, + LastUsedResourceIndices(compiledPasses[lastPassId], result.contextData)); + } + + // The delay ends at the first pass on the opposite queue that is ordered after the work left behind, just as + // in #78999: Async_Later waits on the graphics queue past the graphics use of mixedQueueTexture, so from that + // pass onwards the in-order async compute queue can safely be handed the texture. That pass is itself the + // release point, not the one before it, because a pass creates its resources before its own fence wait. + [Test] + public void ResourceUsedOnBothQueuesIsReleasedAtFirstOrderedAsyncPass() + { + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + TextureHandle mixedQueueTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle graphicsTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle asyncInput = m_RenderGraph.CreateTexture(desc); + TextureHandle laterAsyncTexture = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Async_Produce", asyncCompute: true, writes: new[] { mixedQueueTexture }); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { mixedQueueTexture }, writes: new[] { graphicsTexture }, allowCulling: false); + AddTestComputePass("Gfx_ProduceForAsync", asyncCompute: false, writes: new[] { asyncInput }); + AddTestComputePass("Async_Later", asyncCompute: true, + reads: new[] { asyncInput }, writes: new[] { laterAsyncTexture }); + AddTestComputePass("Gfx_Padding", asyncCompute: false, + reads: new[] { graphicsTexture, laterAsyncTexture }, allowCulling: false); + + var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); + var compiledPasses = result.contextData.GetPasses(); + + Assert.AreEqual(5, compiledPasses.Count); + + const int gfxProduceForAsyncPassId = 2; + const int asyncLaterPassId = 3; + + // The async compute pass really is ordered after the graphics use, otherwise this would prove nothing. + Assert.AreEqual(gfxProduceForAsyncPassId, compiledPasses[asyncLaterPassId].waitOnGraphicsFencePassId); + + // Released at it, rather than at the end of the graph. + Assert.AreEqual(asyncLaterPassId, + result.contextData.UnversionedResourceData(mixedQueueTexture.handle).lastUsePassID); + Assert.Contains(mixedQueueTexture.handle.index, + LastUsedResourceIndices(compiledPasses[asyncLaterPassId], result.contextData)); + } + + // The mirror of the test above: the last use of mixedQueueTexture is on the async compute queue, and that use + // already waits on a fence covering the graphics work, so what keeps the texture out of the pool is its own + // async write still in flight. The release waits for the first graphics pass awaiting an async fence signaled + // at or after that write. + [Test] + public void ResourceUsedOnBothQueuesIsReleasedAtFirstOrderedGraphicsPass() + { + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + TextureHandle mixedQueueTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle laterAsyncTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle paddingTexture = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Gfx_Produce", asyncCompute: false, writes: new[] { mixedQueueTexture }); + AddTestComputePass("Async_Consume", asyncCompute: true, + reads: new[] { mixedQueueTexture }, allowCulling: false); + AddTestComputePass("Async_Later", asyncCompute: true, writes: new[] { laterAsyncTexture }); + AddTestComputePass("Gfx_Padding", asyncCompute: false, writes: new[] { paddingTexture }); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { laterAsyncTexture, paddingTexture }, allowCulling: false); + + var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); + var compiledPasses = result.contextData.GetPasses(); + + Assert.AreEqual(5, compiledPasses.Count); + + const int gfxProducePassId = 0; + const int asyncConsumePassId = 1; + const int asyncLaterPassId = 2; + const int gfxConsumePassId = 4; + + // The graphics work is already fenced at the last use itself, so it is not what delays the release. + Assert.AreEqual(gfxProducePassId, compiledPasses[asyncConsumePassId].waitOnGraphicsFencePassId); + + // The graphics pass really is ordered after the async work, otherwise this would prove nothing. + Assert.AreEqual(asyncLaterPassId, compiledPasses[gfxConsumePassId].waitOnGraphicsFencePassId); + + // Released at it, rather than at the end of the graph. Not at Gfx_Padding, the pass before it: Gfx_Consume + // creates its resources before waiting on the fence, so it must not be handed the memory either. + Assert.AreEqual(gfxConsumePassId, + result.contextData.UnversionedResourceData(mixedQueueTexture.handle).lastUsePassID); + Assert.Contains(mixedQueueTexture.handle.index, + LastUsedResourceIndices(compiledPasses[gfxConsumePassId], result.contextData)); + } + + // Once the last async compute pass of the graph is behind us the delay is unnecessary: only resources touched + // by an async pass share the pool bucket, and such a resource is never created after the last async pass, so + // nothing that could be handed the memory remains. + [Test] + public void ResourceUsedOnBothQueuesIsReleasedAtLastUseWhenNoAsyncPassFollows() + { + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + TextureHandle mixedQueueTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle graphicsTexture = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Async_Produce", asyncCompute: true, writes: new[] { mixedQueueTexture }); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { mixedQueueTexture }, writes: new[] { graphicsTexture }, allowCulling: false); + // Padding, so that "released at its last use" is distinguishable from "released at the end of the graph". + AddTestComputePass("Gfx_Padding", asyncCompute: false, reads: new[] { graphicsTexture }, allowCulling: false); + + var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); + var compiledPasses = result.contextData.GetPasses(); + + Assert.AreEqual(3, compiledPasses.Count); + + const int gfxConsumePassId = 1; + + Assert.AreEqual(gfxConsumePassId, + result.contextData.UnversionedResourceData(mixedQueueTexture.handle).lastUsePassID); + Assert.Contains(mixedQueueTexture.handle.index, + LastUsedResourceIndices(compiledPasses[gfxConsumePassId], result.contextData)); + } + + // A resource released by a graphics pass must never be handed to an async compute pass by the pool, while + // pooling between passes on the same queue keeps working. + [Test] + public void AsyncPassDoesNotReuseGraphicsQueueResourceFromPool() + { + RTHandle graphicsRTHandle = null; + RTHandle asyncRTHandle = null; + RTHandle graphicsReuseRTHandle = null; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + // One shared descriptor, so pool reuse is constrained by the queue split alone. + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + var graphicsTexture = m_RenderGraph.CreateTexture(desc); + var graphicsCopy = m_RenderGraph.CreateTexture(desc); + var asyncTexture = m_RenderGraph.CreateTexture(desc); + var graphicsReuse = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Gfx_Produce", asyncCompute: false, writes: new[] { graphicsTexture }, + captureFirstWrite: rtHandle => graphicsRTHandle = rtHandle); + // Last use of graphicsTexture, so it goes back to the pool at the end of this pass. + AddTestComputePass("Gfx_Copy", asyncCompute: false, + reads: new[] { graphicsTexture }, writes: new[] { graphicsCopy }); + // Allocates right after that release, but on the async queue with no fence to wait on, exactly as in + // the bug report: it must get its own resource. + AddTestComputePass("Async_Produce", asyncCompute: true, writes: new[] { asyncTexture }, + captureFirstWrite: rtHandle => asyncRTHandle = rtHandle); + // The same allocation on the graphics queue is expected to recycle graphicsTexture. + AddTestComputePass("Gfx_Reuse", asyncCompute: false, writes: new[] { graphicsReuse }, + captureFirstWrite: rtHandle => graphicsReuseRTHandle = rtHandle); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { graphicsCopy, asyncTexture, graphicsReuse }, allowCulling: false); + }; + + m_Camera.Render(); + + Assert.IsNotNull(graphicsRTHandle); + Assert.IsNotNull(asyncRTHandle); + Assert.IsNotNull(graphicsReuseRTHandle); + + Assert.AreNotSame(graphicsRTHandle, asyncRTHandle); + + // Same queue reuse still happens, so the assert above cannot pass trivially. + Assert.AreSame(graphicsRTHandle, graphicsReuseRTHandle); + } + + // Companion to the test above: shows the reuse would race, not just waste memory. The graphics queue only + // resource is released at its last graphics use, nothing orders the async pass that follows after that + // release, and the only fence in the graph runs the other way, ordering the graphics consumer after the + // async pass. + [Test] + public void AsyncPassFollowingGraphicsResourceReleaseHasNoFenceToWaitOn() + { + var desc = new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }; + + TextureHandle graphicsTexture = m_RenderGraph.CreateTexture(desc); + TextureHandle graphicsCopy = m_RenderGraph.CreateTexture(desc); + TextureHandle asyncTexture = m_RenderGraph.CreateTexture(desc); + + AddTestComputePass("Gfx_Produce", asyncCompute: false, writes: new[] { graphicsTexture }); + AddTestComputePass("Gfx_Copy", asyncCompute: false, + reads: new[] { graphicsTexture }, writes: new[] { graphicsCopy }); + AddTestComputePass("Async_Produce", asyncCompute: true, writes: new[] { asyncTexture }); + AddTestComputePass("Gfx_Consume", asyncCompute: false, + reads: new[] { graphicsCopy, asyncTexture }, allowCulling: false); + + var result = m_RenderGraph.CompileNativeRenderGraph(m_RenderGraph.ComputeGraphHash()); + var compiledPasses = result.contextData.GetPasses(); + + Assert.AreEqual(4, compiledPasses.Count); + + const int gfxCopyPassId = 1; + const int asyncProducePassId = 2; + const int gfxConsumePassId = 3; + + // The async pass survives culling because its output is read, not because culling was disabled. + Assert.IsTrue(compiledPasses[asyncProducePassId].asyncCompute); + + // Graphics only, so nothing delays its release past its last graphics use. + Assert.AreEqual(-1, result.contextData.UnversionedResourceData(graphicsTexture.handle).lastAsyncComputeUsePassID); + Assert.AreEqual(gfxCopyPassId, result.contextData.UnversionedResourceData(graphicsTexture.handle).lastUsePassID); + + // Nothing orders the async pass after the pass that released the resource. + Assert.AreEqual(-1, compiledPasses[asyncProducePassId].waitOnGraphicsFencePassId); + + // The only fence involved runs the other way: the consumer waits for the async pass. + Assert.AreEqual(gfxConsumePassId, compiledPasses[asyncProducePassId].awaitingMyGraphicsFencePassId); + Assert.AreEqual(asyncProducePassId, compiledPasses[gfxConsumePassId].waitOnGraphicsFencePassId); + } + + // The buffer variant of the cross queue race: bufferA is written on the async queue and read on the graphics + // queue, and nothing makes the async queue wait for that read, so a later async pass must not be handed its + // buffer. Graphics queue only buffers keep pooling normally. + [Test] + public void AsyncComputePassDoesNotReuseBufferLastUsedByGraphicsPass() + { + GraphicsBuffer asyncWrittenBuffer = null; + GraphicsBuffer laterAsyncBuffer = null; + GraphicsBuffer graphicsWrittenBuffer = null; + GraphicsBuffer graphicsReuseBuffer = null; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + // One shared descriptor, so pool reuse is constrained by the queue split alone. + var desc = new BufferDesc(1024, 4, GraphicsBuffer.Target.Structured); + + var bufferA = m_RenderGraph.CreateBuffer(desc); + var bufferB = m_RenderGraph.CreateBuffer(desc); + var graphicsOnlyBuffer = m_RenderGraph.CreateBuffer(desc); + var graphicsReuse = m_RenderGraph.CreateBuffer(desc); + + AddTestComputePass("Async_WriteA", asyncCompute: true, writes: new[] { bufferA }, + captureFirstWrite: buffer => asyncWrittenBuffer = buffer); + // Last use of bufferA, on the graphics queue. + AddTestComputePass("Gfx_ReadA", asyncCompute: false, + reads: new[] { bufferA }, writes: new[] { graphicsOnlyBuffer }, allowCulling: false, + captureFirstWrite: buffer => graphicsWrittenBuffer = buffer); + // Last use of graphicsOnlyBuffer, so it goes back to the pool at the end of this pass. + AddTestComputePass("Gfx_ReadGraphicsOnly", asyncCompute: false, + reads: new[] { graphicsOnlyBuffer }, allowCulling: false); + // Allocates on the async queue with no fence to wait on: it must not receive bufferA's buffer. + AddTestComputePass("Async_WriteB", asyncCompute: true, writes: new[] { bufferB }, + allowCulling: false, captureFirstWrite: buffer => laterAsyncBuffer = buffer); + // The same allocation on the graphics queue is expected to recycle graphicsOnlyBuffer. + AddTestComputePass("Gfx_Reuse", asyncCompute: false, writes: new[] { graphicsReuse }, + allowCulling: false, captureFirstWrite: buffer => graphicsReuseBuffer = buffer); + }; + + m_Camera.Render(); + + Assert.IsNotNull(asyncWrittenBuffer); + Assert.IsNotNull(laterAsyncBuffer); + Assert.IsNotNull(graphicsWrittenBuffer); + Assert.IsNotNull(graphicsReuseBuffer); + + Assert.AreNotSame(asyncWrittenBuffer, laterAsyncBuffer); + + // Same queue reuse still happens, so the assert above cannot pass trivially. + Assert.AreSame(graphicsWrittenBuffer, graphicsReuseBuffer); } [Test] From b6235bf39dcd4ddb83cae599942eb97319ebcdcc Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Wed, 16 Sep 2026 13:35:21 +0000 Subject: [PATCH 015/192] =?UTF-8?q?[Port]=20[6000.7]=20Fix=20UUM-152236:?= =?UTF-8?q?=20"Assets=20located=20in=20Immutable=20packages=E2=80=9C=20war?= =?UTF-8?q?nings=20are=20thrown=20when=20creating=20a=20Unity=20project=20?= =?UTF-8?q?using=20the=20High=20Definition=203D=20template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DiffusionProfileSlotControlView.uss.meta | 9 +++++++-- .../Material/AreaLightCookieViewer.mat | 1 + .../Material/AreaLightViewer.mat | 1 + .../Material/DefaultHDTerrainMaterial.mat | 1 + .../Material/DefaultWaterMaterial.mat | 1 + .../Mesh/Cylinder.fbx.meta | 4 ++-- .../RenderPipelineResources/Mesh/Disc.fbx.meta | 4 ++-- .../Mesh/HumanEyeModel.fbx.meta | 4 ++-- .../RenderPipelineResources/Mesh/Quad.fbx.meta | 4 ++-- .../Mesh/Sphere.fbx.meta | 4 ++-- .../Mesh/TestBall.fbx.meta | 4 ++-- .../Mesh/TestBall_Base.fbx.meta | 4 ++-- .../AutodeskInteractive.shadergraph.meta | 17 +++++++++++++++-- .../AutodeskInteractiveMasked.shadergraph.meta | 17 +++++++++++++++-- ...odeskInteractiveTransparent.shadergraph.meta | 17 +++++++++++++++-- 15 files changed, 70 insertions(+), 22 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Resources/DiffusionProfileSlotControlView.uss.meta b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Resources/DiffusionProfileSlotControlView.uss.meta index e559f6a937b..ec788304a8e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Resources/DiffusionProfileSlotControlView.uss.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Resources/DiffusionProfileSlotControlView.uss.meta @@ -1,10 +1,15 @@ fileFormatVersion: 2 guid: a42e613b368b1a549badf6d03df79a75 ScriptedImporter: - fileIDToRecycleName: - 11400000: stylesheet + internalIDToNameTable: + - first: + 114: 11400000 + second: stylesheet externalObjects: {} + serializedVersion: 2 userData: assetBundleName: assetBundleVariant: script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} + disableValidation: 0 + unsupportedSelectorAction: 0 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightCookieViewer.mat b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightCookieViewer.mat index b9821a4def2..dc2c62cece2 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightCookieViewer.mat +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightCookieViewer.mat @@ -299,3 +299,4 @@ Material: - _UnlitColor: {r: 1, g: 1, b: 1, a: 1} - _UnlitColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightViewer.mat b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightViewer.mat index 011ff9fabb3..8bdff58404e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightViewer.mat +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/AreaLightViewer.mat @@ -298,3 +298,4 @@ Material: - _UnlitColor: {r: 1, g: 1, b: 1, a: 1} - _UnlitColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultHDTerrainMaterial.mat b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultHDTerrainMaterial.mat index 75ac40323f9..311c2b96a9b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultHDTerrainMaterial.mat +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultHDTerrainMaterial.mat @@ -73,3 +73,4 @@ Material: - _Color: {r: 1, g: 1, b: 1, a: 1} - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultWaterMaterial.mat b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultWaterMaterial.mat index dd4f3ff423a..32f9b22854b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultWaterMaterial.mat +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Material/DefaultWaterMaterial.mat @@ -132,3 +132,4 @@ Material: - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Cylinder.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Cylinder.fbx.meta index ffe7ab285c4..f5f5fe23656 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Cylinder.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Cylinder.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcbc21809f342c934125f46803b6e3dd734b0270613fde983301de053a1ccc59 -size 2351 +oid sha256:918663004424d46558a6630aa522bb4fd56928f45108d94e758b7e02d3aad22f +size 3138 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Disc.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Disc.fbx.meta index f88ee15bb2e..f7abdadee64 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Disc.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Disc.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1915836e56075615a72c3231a03bf14f0a5e11bc26dede035df7a1a9c56847c3 -size 2303 +oid sha256:edb937b648916492a9aeda01e851b716725b08ec3ecd2ab3a376f3df8fb5558e +size 3436 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/HumanEyeModel.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/HumanEyeModel.fbx.meta index c4792af3286..de94d3063e8 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/HumanEyeModel.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/HumanEyeModel.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0611e992518de46d43b4cf290ef20d6be86e5fdf4a240a3bf41427dbe92a4400 -size 2617 +oid sha256:90a517a7573541b96b711906e0c174e69bc368639d5c930ef104d9d5b1e12ff8 +size 3197 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Quad.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Quad.fbx.meta index e74bce43397..4ed3cfdff26 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Quad.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Quad.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:929ef26157c7cae57d73637726fbe01e6a8afae9528460c3eb4e7056bc9540b7 -size 2306 +oid sha256:ff31357fc3a8e8b49cd7fc2b9b0ed408b619c4fc388651166c801c9574de456d +size 3439 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Sphere.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Sphere.fbx.meta index d961287e1b0..8963eeef75e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Sphere.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/Sphere.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca176ebaef4c562d6d6e2362b6ab3fbee358460e1cf7b2be9eafa3a16c0ae45c -size 2303 +oid sha256:67f3c0e6de241b183f89d8323dfc4d77c20cec733525d8b7e0f0b04327918f45 +size 3436 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall.fbx.meta index 3786030f911..155edd60b0d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ca6ad27a511d984706722524870faf25316d2aa892ddeabd68d9cc3c6366e30 -size 3990 +oid sha256:58104c2c36e5fa9088548b062876dde5c608f2c09df470bee97901c748e69129 +size 4373 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall_Base.fbx.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall_Base.fbx.meta index 4a84dab2856..22d72d23eea 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall_Base.fbx.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Mesh/TestBall_Base.fbx.meta @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f401dabd75d0647fa443c15f1d114dbdaccf2447470b4f0e6082c797800cf6b -size 3248 +oid sha256:d32e79b361bbd45d0b76feb7b3d3397f855ced989067e9dee23c6d3270083dd4 +size 3631 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractive.shadergraph.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractive.shadergraph.meta index a3d5fee3b53..8b311fb5574 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractive.shadergraph.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractive.shadergraph.meta @@ -1,10 +1,23 @@ fileFormatVersion: 2 guid: 7252379db4c18b641b517f2c91bb57e1 ScriptedImporter: - fileIDToRecycleName: - 4800000: MainAsset + internalIDToNameTable: + - first: + 48: 4800000 + second: MainAsset externalObjects: {} + serializedVersion: 2 userData: assetBundleName: assetBundleVariant: script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} + useAsTemplate: 0 + exposeTemplateAsShader: 0 + indexedData: {fileID: -3424247175808206760, guid: 7252379db4c18b641b517f2c91bb57e1, type: 3} + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveMasked.shadergraph.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveMasked.shadergraph.meta index 03b365c7d9b..9749312b86e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveMasked.shadergraph.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveMasked.shadergraph.meta @@ -1,10 +1,23 @@ fileFormatVersion: 2 guid: 29c4adff654862b40a2e9fb2015a42c3 ScriptedImporter: - fileIDToRecycleName: - 4800000: MainAsset + internalIDToNameTable: + - first: + 48: 4800000 + second: MainAsset externalObjects: {} + serializedVersion: 2 userData: assetBundleName: assetBundleVariant: script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} + useAsTemplate: 0 + exposeTemplateAsShader: 0 + indexedData: {fileID: -3424247175808206760, guid: 29c4adff654862b40a2e9fb2015a42c3, type: 3} + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveTransparent.shadergraph.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveTransparent.shadergraph.meta index 0d09c35b9ee..bcbdd67e858 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveTransparent.shadergraph.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/ShaderGraph/AutodeskInteractiveTransparent.shadergraph.meta @@ -1,10 +1,23 @@ fileFormatVersion: 2 guid: ee2ce0be66f45d9449d71ba9b49c2acd ScriptedImporter: - fileIDToRecycleName: - 4800000: MainAsset + internalIDToNameTable: + - first: + 48: 4800000 + second: MainAsset externalObjects: {} + serializedVersion: 2 userData: assetBundleName: assetBundleVariant: script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} + useAsTemplate: 0 + exposeTemplateAsShader: 0 + indexedData: {fileID: -3424247175808206760, guid: ee2ce0be66f45d9449d71ba9b49c2acd, type: 3} + template: + name: + category: + description: + icon: {instanceID: 0} + thumbnail: {instanceID: 0} + order: 0 From f16c0d1b5f68f8d6d85cfdb9b6e3fddd491e50a2 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 17 Sep 2026 04:02:45 +0000 Subject: [PATCH 016/192] [Port] [6000.7] [UUM-150463] [SurfaceCache] Cover subgroup sizes 2 to 128 in the Defrag pass and assert variant presence via the shader --- .../Runtime/Lighting/SurfaceCache/Defrag.compute | 14 ++++++++++---- .../Runtime/Lighting/SurfaceCache/SurfaceCache.cs | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Defrag.compute b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Defrag.compute index 76b348cdf06..2956e6241f9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Defrag.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/Defrag.compute @@ -1,8 +1,14 @@ #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal ps5 switch2 -#pragma multi_compile_local SUB_GROUP_SIZE_8 SUB_GROUP_SIZE_16 SUB_GROUP_SIZE_32 SUB_GROUP_SIZE_48 SUB_GROUP_SIZE_64 +#pragma multi_compile_local SUB_GROUP_SIZE_2 SUB_GROUP_SIZE_4 SUB_GROUP_SIZE_8 SUB_GROUP_SIZE_16 SUB_GROUP_SIZE_32 SUB_GROUP_SIZE_64 SUB_GROUP_SIZE_128 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#ifdef SUB_GROUP_SIZE_2 +#define SUB_GROUP_SIZE 2 +#endif +#ifdef SUB_GROUP_SIZE_4 +#define SUB_GROUP_SIZE 4 +#endif #ifdef SUB_GROUP_SIZE_8 #define SUB_GROUP_SIZE 8 #endif @@ -12,12 +18,12 @@ #ifdef SUB_GROUP_SIZE_32 #define SUB_GROUP_SIZE 32 #endif -#ifdef SUB_GROUP_SIZE_48 -#define SUB_GROUP_SIZE 48 -#endif #ifdef SUB_GROUP_SIZE_64 #define SUB_GROUP_SIZE 64 #endif +#ifdef SUB_GROUP_SIZE_128 +#define SUB_GROUP_SIZE 128 +#endif #pragma kernel Defrag 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 5c9f65569d4..b1253b451f6 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 @@ -284,9 +284,9 @@ internal void Load( GlobalProbeShader = globalProbeShader; GlobalProbeKernel = globalProbeShader.FindKernel("Update"); - Debug.Assert(ComputeSubGroupSize == 8 || ComputeSubGroupSize == 16 || ComputeSubGroupSize == 32 || ComputeSubGroupSize == 48 || ComputeSubGroupSize == 64, $"Unexpected, ComputeSubGroupSize={ComputeSubGroupSize}"); DefragShader = defragShader; var defragKeyword = "SUB_GROUP_SIZE_" + ComputeSubGroupSize; + Debug.Assert(DefragShader.keywordSpace.FindKeyword(defragKeyword).isValid, $"Unexpected, ComputeSubGroupSize={ComputeSubGroupSize}"); DefragShader.EnableKeyword(defragKeyword); DefragKernel = DefragShader.FindKernel("Defrag"); DefragShader.GetKernelThreadGroupSizes(DefragKernel, out DefragKernelGroupSize.x, out DefragKernelGroupSize.y, out DefragKernelGroupSize.z); From 0f565a28ea543d5a6169e6ae2af799187cfd1de4 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 17 Sep 2026 18:32:08 +0000 Subject: [PATCH 017/192] [Port] [6000.7] [UUM-133166] Terrain: anchor the terrain layer controls to the texture field rather than the last laid out rect --- .../Editor/Material/TerrainLit/TerrainLitGUI.cs | 8 ++++++-- .../Material/UIBlocks/TerrainSurfaceOptionsUIBlock.cs | 8 ++++++-- .../Editor/ShaderGUI/TerrainLitShaderGUI.cs | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs index c2ff41e52a8..62267d58e69 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs @@ -197,6 +197,8 @@ bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain Undo.RecordObject(terrainLayer, "Terrain Layer Diffuse Texture"); terrainLayer.diffuseTexture = diffuseTexture; } + // Anchor before validation, which may insert help boxes. + var diffuseFieldRect = GUILayoutUtility.GetLastRect(); TerrainLayerUtility.ValidateDiffuseTextureUI(terrainLayer.diffuseTexture); var diffuseRemapMin = terrainLayer.diffuseRemapMin; @@ -206,7 +208,7 @@ bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain bool enableDensity = false; if (terrainLayer.diffuseTexture != null) { - var rect = GUILayoutUtility.GetLastRect(); + var rect = diffuseFieldRect; rect.y += 16 + 4; rect.width = EditorGUIUtility.labelWidth + 64; rect.height = 16; @@ -245,11 +247,13 @@ bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain Undo.RecordObject(terrainLayer, "Terrain Layer Normal Map"); terrainLayer.normalMapTexture = normalMapTexture; } + // Anchor before validation, which may insert help boxes. + var normalMapFieldRect = GUILayoutUtility.GetLastRect(); TerrainLayerUtility.ValidateNormalMapTextureUI(terrainLayer.normalMapTexture, TerrainLayerUtility.CheckNormalMapTextureType(terrainLayer.normalMapTexture)); if (terrainLayer.normalMapTexture != null) { - var rect = GUILayoutUtility.GetLastRect(); + var rect = normalMapFieldRect; rect.y += 16 + 4; rect.width = EditorGUIUtility.labelWidth + 64; rect.height = 16; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TerrainSurfaceOptionsUIBlock.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TerrainSurfaceOptionsUIBlock.cs index 4fabcd14118..11d1175338a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TerrainSurfaceOptionsUIBlock.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/TerrainSurfaceOptionsUIBlock.cs @@ -108,6 +108,8 @@ public bool OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain terrain) Undo.RecordObject(terrainLayer, "Terrain Layer Diffuse Texture"); terrainLayer.diffuseTexture = diffuseTexture; } + // Anchor before validation, which may insert help boxes. + var diffuseFieldRect = GUILayoutUtility.GetLastRect(); TerrainLayerUtility.ValidateDiffuseTextureUI(terrainLayer.diffuseTexture); var diffuseRemapMin = terrainLayer.diffuseRemapMin; @@ -117,7 +119,7 @@ public bool OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain terrain) bool enableDensity = false; if (terrainLayer.diffuseTexture != null) { - var rect = GUILayoutUtility.GetLastRect(); + var rect = diffuseFieldRect; rect.y += 16 + 4; rect.width = EditorGUIUtility.labelWidth + 64; rect.height = 16; @@ -156,11 +158,13 @@ public bool OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain terrain) Undo.RecordObject(terrainLayer, "Terrain Layer Normal Map"); terrainLayer.normalMapTexture = normalMapTexture; } + // Anchor before validation, which may insert help boxes. + var normalMapFieldRect = GUILayoutUtility.GetLastRect(); TerrainLayerUtility.ValidateNormalMapTextureUI(terrainLayer.normalMapTexture, TerrainLayerUtility.CheckNormalMapTextureType(terrainLayer.normalMapTexture)); if (terrainLayer.normalMapTexture != null) { - var rect = GUILayoutUtility.GetLastRect(); + var rect = normalMapFieldRect; rect.y += 16 + 4; rect.width = EditorGUIUtility.labelWidth + 64; rect.height = 16; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/TerrainLitShaderGUI.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/TerrainLitShaderGUI.cs index 32b16c8c44c..ee03091e68b 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/TerrainLitShaderGUI.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/TerrainLitShaderGUI.cs @@ -174,6 +174,8 @@ bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain Undo.RecordObject(terrainLayer, "Terrain Layer Diffuse Texture"); terrainLayer.diffuseTexture = diffuseTexture; } + // Anchor before validation, which may insert help boxes. + var diffuseFieldRect = GUILayoutUtility.GetLastRect(); TerrainLayerUtility.ValidateDiffuseTextureUI(terrainLayer.diffuseTexture); var diffuseRemapMin = terrainLayer.diffuseRemapMin; @@ -183,7 +185,7 @@ bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain bool enableDensity = false; if (terrainLayer.diffuseTexture != null) { - var rect = GUILayoutUtility.GetLastRect(); + var rect = diffuseFieldRect; rect.y += 16 + 4; rect.width = EditorGUIUtility.labelWidth + 64; rect.height = 16; @@ -223,11 +225,13 @@ bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain Undo.RecordObject(terrainLayer, "Terrain Layer Normal Map"); terrainLayer.normalMapTexture = normalMapTexture; } + // Anchor before validation, which may insert help boxes. + var normalMapFieldRect = GUILayoutUtility.GetLastRect(); TerrainLayerUtility.ValidateNormalMapTextureUI(terrainLayer.normalMapTexture, TerrainLayerUtility.CheckNormalMapTextureType(terrainLayer.normalMapTexture)); if (terrainLayer.normalMapTexture != null) { - var rect = GUILayoutUtility.GetLastRect(); + var rect = normalMapFieldRect; rect.y += 16 + 4; rect.width = EditorGUIUtility.labelWidth + 64; rect.height = 16; From 47fbe822f680c8ac2a248563975a8c4fe144176a Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Fri, 18 Sep 2026 00:35:15 +0000 Subject: [PATCH 018/192] [Port] [6000.7] SRP Core - Fix the allocation error in the Console --- .../Runtime/GPUDriven/GPUResidentDrawer.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs index 1a98bf857a7..8f1589bb7b9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs @@ -74,6 +74,9 @@ public partial class GPUResidentDrawer [NoAutoStaticsCleanup] // Manually cleaned up with [OnCodeUnloading] Cleanup() private static GPUResidentDrawer s_Instance = null; + [NoAutoStaticsCleanup] + private static readonly Action k_CleanupDelegate = Cleanup; + //////////////////////////////////////// // Public API for rendering pipelines // //////////////////////////////////////// @@ -399,11 +402,11 @@ private static void OnCodeUnloading() private static void Cleanup() { - RenderPipelineManager.activeRenderPipelineDisposed -= Cleanup; - if (s_Instance == null) return; + RenderPipelineManager.activeRenderPipelineDisposed -= k_CleanupDelegate; + s_Instance.Dispose(); s_Instance = null; ++s_InstanceVersion; @@ -418,7 +421,7 @@ private static void Recreate(GPUResidentDrawerSettings settings) if (IsGPUResidentDrawerSupportedBySRP(settings, out var message, out var severity)) { s_Instance = new GPUResidentDrawer(settings); - RenderPipelineManager.activeRenderPipelineDisposed += Cleanup; + RenderPipelineManager.activeRenderPipelineDisposed += k_CleanupDelegate; ++s_InstanceVersion; } else From e9caea0599bf38bdf250bf1682208df4a92d3e52 Mon Sep 17 00:00:00 2001 From: Evergreen Date: Fri, 18 Sep 2026 09:56:05 +0000 Subject: [PATCH 019/192] [UUM-152671] Disable 8 unstable Materials Playmode tests --- .../Assets/GraphicTests/Tests/SkyAndFog.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs index 833f2a99d05..ebe3135bca6 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs @@ -6,6 +6,7 @@ using UnityEngine.TestTools.Graphics; using UnityEngine.TestTools.Graphics.Contexts; using UnityEngine.TestTools.Graphics.Platforms; +using UnityEngine.Rendering; namespace UnityEngine.Rendering.HighDefinition.Tests { @@ -67,6 +68,54 @@ public SkyAndFogTests(GpuResidentDrawerContext grdContext) : base(grdContext) { "Disabled for Instability https://jira.unity3d.com/browse/UUM-144922", RuntimePlatform.LinuxEditor, RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor )] + [IgnoreGraphicsTest( + "5016_VolumetricFogMultipleScattering", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5020_SkyOverride", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5003_Fog_DensityVolumesShadows", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5004_Pbr_Sky_High_Altitude", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5005_Pbr_Sky_Med_Altitude", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5008_FogFiltering", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5002_Fog_DensityVolumes", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5009_HDRI_Sky_Flow", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan + )] [TestNotSupportedOn( "501[0-5]|5020", "Not XR compatible", From 02c9440ddc860abe2b915d1b03b04628bf96c85b Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Fri, 18 Sep 2026 09:56:05 +0000 Subject: [PATCH 020/192] [Port] [6000.7] Add alpha upscaling support for color-only upscalers --- .../Runtime/Upscaling/AlphaUpscale.compute | 360 ++++++++++++ .../Upscaling/AlphaUpscale.compute.meta | 7 + .../Runtime/Upscaling/AlphaUpscaler.cs | 291 +++++++++ .../Runtime/Upscaling/AlphaUpscaler.cs.meta | 11 + .../Runtime/Upscaling/IUpscaler.cs | 8 + .../Camera/HDCameraFrameHistoryType.cs | 2 + .../HDRenderPipeline.PostProcess.cs | 56 ++ .../Runtime/AlphaUpscaleUtils.cs | 60 ++ .../Runtime/AlphaUpscaleUtils.cs.meta | 2 + .../Runtime/FrameData/UniversalCameraData.cs | 6 + .../Runtime/History/AlphaUpscaleHistory.cs | 72 +++ .../History/AlphaUpscaleHistory.cs.meta | 2 + .../Passes/PostProcess/StpPostProcessPass.cs | 11 + .../PostProcess/UpscalerPostProcessPass.cs | 14 +- .../Runtime/UniversalRenderPipeline.cs | 28 + .../HDRP_Test_Both_FP16_PPAlpha_STP.asset | 552 ++++++++++++++++++ ...HDRP_Test_Both_FP16_PPAlpha_STP.asset.meta | 8 + .../4112_AlphaUpscaling-FP16Alpha.meta | 8 + .../4112_AlphaUpscaling-FP16Alpha.unity | 3 + .../4112_AlphaUpscaling-FP16Alpha.unity.meta | 7 + .../4112_AlphaUpscaling-FP16Alpha/.gitignore | 3 + .../DisplayRTTAlpha.mat | 29 + .../DisplayRTTAlpha.mat.meta | 8 + .../DisplayRTTAlpha.shader | 61 ++ .../DisplayRTTAlpha.shader.meta | 10 + .../SphereMaterial.mat | 307 ++++++++++ .../SphereMaterial.mat.meta | 8 + .../SphereMaterialTransp.mat | 310 ++++++++++ .../SphereMaterialTransp.mat.meta | 8 + .../SphereMaterialTranspWritesDepth.mat | 310 ++++++++++ .../SphereMaterialTranspWritesDepth.mat.meta | 8 + .../Volume.asset | 15 + .../Volume.asset.meta | 8 + .../GraphicTests/Tests/PostProcessing.cs | 6 +- .../HDRenderPipelineGlobalSettings.asset | 5 + .../ProjectSettings/EditorBuildSettings.asset | 3 + .../Assets/CommonAssets/ForwardRenderer.asset | 25 +- .../URP_Asset_UpScaling_STP_Alpha_NoHDR.asset | 192 ++++++ ...Asset_UpScaling_STP_Alpha_NoHDR.asset.meta | 8 + ...AlphaOutput_RGBA8_RenderScale_Up_STP.unity | 3 + ...Output_RGBA8_RenderScale_Up_STP.unity.meta | 7 + .../Assets/Scenes/283_AlphaUpscaling.meta | 8 + .../283_AlphaUpscaling/283_DisplayAlpha.mat | 29 + .../283_DisplayAlpha.mat.meta | 8 + .../283_DisplayAlpha.shader | 36 ++ .../283_DisplayAlpha.shader.meta | 9 + .../283_AlphaUpscaling/MatDiscardGreen.mat | 147 +++++ .../MatDiscardGreen.mat.meta | 8 + .../283_AlphaUpscaling/MatOpaqueRed.mat | 136 +++++ .../283_AlphaUpscaling/MatOpaqueRed.mat.meta | 8 + .../283_AlphaUpscaling/MatTransparentBlue.mat | 140 +++++ .../MatTransparentBlue.mat.meta | 8 + .../checkerboard_alpha0.png | 3 + .../checkerboard_alpha0.png.meta | 154 +++++ .../ProjectSettings/EditorBuildSettings.asset | 3 + .../ProjectSettings/QualitySettings.asset | 53 ++ 56 files changed, 3584 insertions(+), 8 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs.meta create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs.meta create mode 100644 Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset create mode 100644 Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/.gitignore create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat.meta create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset create mode 100644 Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute new file mode 100644 index 00000000000..a7c0a235412 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute @@ -0,0 +1,360 @@ +#pragma kernel UpscaleAlphaAndMergeColor + +#pragma multi_compile _ DISABLE_TEXTURE2D_X_ARRAY +#pragma multi_compile _ DIRECT_STENCIL_SAMPLE REACTIVE_MASK + +#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2 glcore webgpu + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl" + +// Include TextureXR.hlsl for XR macros +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" + +#if UNITY_REVERSED_Z + #define COMPARE_DEPTH(a, b) step(b, a) +#else + #define COMPARE_DEPTH(a, b) step(a, b) +#endif + +TEXTURE2D_X(_UpscaledColor); +// Pre-upscale color at rendering resolution. Only the alpha channel is read. +TEXTURE2D_X(_PreUpscaleAlpha); + +// Depth at rendering resolution, used to dilate the motion vectors at silhouettes. +TEXTURE2D_X(_DepthTexture); +// Motion vectors at rendering resolution, in UV space (current - previous frame position). +TEXTURE2D_X(_MotionVectorTexture); +// Post-upscale alpha accumulated over the previous frames. +TEXTURE2D_X(_AlphaHistory); + +#if defined(DIRECT_STENCIL_SAMPLE) +// Stencil at rendering resolution: pixels whose stencil equals _ExcludeTAABit skip the temporal +// accumulation, matching the TAA exclusion of FragTAA. +TYPED_TEXTURE2D_X(uint2, _StencilTexture); +uint _ExcludeTAABit; +#endif + +#if defined(REACTIVE_MASK) +TEXTURE2D_X(_ReactiveMaskTexture); +#endif + +RW_TEXTURE2D_X(float4, _OutputTexture); +RW_TEXTURE2D_X(float, _AlphaHistoryOutput); + +SAMPLER(s_linear_clamp_sampler); +SAMPLER(s_point_clamp_sampler); + +// xy: input (pre-upscale) viewport size in pixels, zw: rcp of the input texture size +float4 _AlphaUpscaleParams0; +// xy: output viewport size in pixels, zw: camera jitter of the current frame in input pixels +float4 _AlphaUpscaleParams1; +// x: history blend weight (0 disables the temporal accumulation for this frame), +// y: history buffers available (0 disables the history read and write entirely), +// zw: rcp of the history texture size +float4 _AlphaUpscaleParams2; + +// ------------------------------------------------------------------------------------------------ +// Scalar port of the TAA_UPSAMPLE path of HDRP's TAA, applied to the alpha channel only. +// Differences from HDRP's TAA: +// - The alpha value replaces the color luma in the luma-driven heuristics. +// - Color-only logic is not ported: YCoCg/tonemap/perceptual weighting, the upsample confidence +// and final blend-factor clamp, and the ENABLE_ALPHA color guards. +// - Fixed to a default TAAU camera configuration: bilinear history resampling, no +// history-contrast anti-flicker, no velocity rejection. +// ------------------------------------------------------------------------------------------------ + +// output over input scale and its inverse +#define _TAAUScale (_AlphaUpscaleParams1.x / _AlphaUpscaleParams0.x) +#define _TAAURenderScale (_AlphaUpscaleParams0.x / _AlphaUpscaleParams1.x) +// The current frame weight +#define _BaseBlendFactor (1.0 - _AlphaUpscaleParams2.x) +// Input and history viewport sizes and their reciprocals +#define _InputSize float4(_AlphaUpscaleParams0.xy, rcp(_AlphaUpscaleParams0.xy)) +#define _TaaHistorySize float4(_AlphaUpscaleParams1.xy, rcp(_AlphaUpscaleParams1.xy)) +// The camera jitter in input pixels (xy) and input UV (zw) +#define _TaaJitterStrength float4(_AlphaUpscaleParams1.zw, _AlphaUpscaleParams1.zw * rcp(_AlphaUpscaleParams0.xy)) +// The RTHandle scales: viewport over physical texture size +#define _RTHandleScaleForTAA (_AlphaUpscaleParams0.xy * _AlphaUpscaleParams0.zw) +#define _RTHandleScaleForTAAHistory (_AlphaUpscaleParams1.xy * _AlphaUpscaleParams2.zw) + +// _AntiFlickerIntensity / _ContrastForMaxAntiFlicker: PrepareTAAPassData values for the default +// camera taaAntiFlicker of 0.5: lerp(0, 3.5, 0.5) and 0.7 - lerp(0, 0.3, SmoothStep(0.5, 1, 0.5)) +#define _AntiFlickerIntensity 1.75 +#define _ContrastForMaxAntiFlicker 0.7 + +#define NEIGHBOUR_COUNT 8 +#define SAMPLE_COUNT (NEIGHBOUR_COUNT + 1) + +static const int2 NeighbourOffsets[NEIGHBOUR_COUNT] = +{ + int2(0, 1), int2(1, 0), int2(-1, 0), int2(0, -1), + int2(-1, 1), int2(1, -1), int2(1, 1), int2(-1, -1) +}; + +struct NeighbourhoodSamples +{ + float neighbours[NEIGHBOUR_COUNT]; + float central; + float minNeighbour; + float maxNeighbour; +}; + +// ------------------------------------------------------------------------------------------------ +// Input tile cached in groupshared memory: all alpha and depth taps land on input-resolution +// texel centers, so the threads of a group cooperatively load the input footprint of their +// output tile once (each texel fetched by one thread) instead of tapping the textures per pixel. Tap values match the direct taps, with the borders clamped +// to the input viewport. Since the pass only upscales, the footprint of GROUP_SIZE output +// pixels stays within GROUP_SIZE input texels, plus the one-texel neighbourhood/dilation border. +// ------------------------------------------------------------------------------------------------ + +#define GROUP_SIZE 16 +#define TILE_BORDER 1 +#define TILE_SIZE (GROUP_SIZE + 2 * TILE_BORDER) + +groupshared float gs_TileAlpha[TILE_SIZE * TILE_SIZE]; +groupshared float gs_TileDepth[TILE_SIZE * TILE_SIZE]; + +float TileAlpha(int2 tileCoord) +{ + return gs_TileAlpha[tileCoord.y * TILE_SIZE + tileCoord.x]; +} + +float TileDepth(int2 tileCoord) +{ + return gs_TileDepth[tileCoord.y * TILE_SIZE + tileCoord.x]; +} + +// The input texel containing the dejittered position of the group's first output pixel, minus the border. +int2 GetTileOrigin(uint2 groupOrigin) +{ + float2 firstPixInInput = (((float2)groupOrigin + 0.5) / _AlphaUpscaleParams1.xy) * _InputSize.xy - _TaaJitterStrength.xy; + return int2(floor(firstPixInInput)) - TILE_BORDER; +} + +void LoadInputTile(int2 tileOrigin, uint groupIndex) +{ + const int2 maxCoord = int2(_InputSize.xy) - 1; + const uint tileSize = TILE_SIZE; + + for (uint i = groupIndex; i < tileSize * tileSize; i += GROUP_SIZE * GROUP_SIZE) + { + int2 coord = clamp(tileOrigin + int2(i % tileSize, i / tileSize), 0, maxCoord); + gs_TileAlpha[i] = LOAD_TEXTURE2D_X_LOD(_PreUpscaleAlpha, coord, 0).a; + gs_TileDepth[i] = LOAD_TEXTURE2D_X_LOD(_DepthTexture, coord, 0).r; + } +} + +float FetchHistory(float2 coords, float2 scale) +{ + return SAMPLE_TEXTURE2D_X_LOD(_AlphaHistory, s_linear_clamp_sampler, coords * scale, 0).x; +} + +float2 GetClosestFragmentOffset(int2 tileCoord) +{ + float center = TileDepth(tileCoord); + + int2 offset0 = int2( 1, 1); + int2 offset1 = int2(-1, 1); + int2 offset2 = int2( 1, -1); + int2 offset3 = int2(-1, -1); + + float s3 = TileDepth(tileCoord + offset3); + float s2 = TileDepth(tileCoord + offset2); + float s1 = TileDepth(tileCoord + offset1); + float s0 = TileDepth(tileCoord + offset0); + + float3 closest = float3(0.0, 0.0, center); + closest = COMPARE_DEPTH(s0, closest.z) ? float3(offset0, s0) : closest; + closest = COMPARE_DEPTH(s3, closest.z) ? float3(offset3, s3) : closest; + closest = COMPARE_DEPTH(s2, closest.z) ? float3(offset2, s2) : closest; + closest = COMPARE_DEPTH(s1, closest.z) ? float3(offset1, s1) : closest; + + return closest.xy; +} + +float2 GetMotionVector(float2 uv, int2 tileCoord, float2 inputTexelSize, float2 inputScale) +{ + float2 closestOffset = GetClosestFragmentOffset(tileCoord); + + float2 motionVector = SAMPLE_TEXTURE2D_X_LOD(_MotionVectorTexture, s_point_clamp_sampler, (uv + closestOffset * inputTexelSize) * inputScale, 0).xy; + return motionVector.x > 1.0 ? 0.0 : motionVector; +} + +void GatherNeighbourhood(int2 tileCoord, float centralAlpha, out NeighbourhoodSamples samples) +{ + ZERO_INITIALIZE(NeighbourhoodSamples, samples); + + samples.central = centralAlpha; + + [unroll] + for (int i = 0; i < NEIGHBOUR_COUNT; ++i) + { + samples.neighbours[i] = TileAlpha(tileCoord + NeighbourOffsets[i]); + } +} + +void VarianceNeighbourhood(inout NeighbourhoodSamples samples, float historyAlpha, float filteredAlpha, float2 antiFlickerParams, float motionVecLenInPixels, float downsampleFactor) +{ + float moment1 = 0.0; + float moment2 = 0.0; + + [unroll] + for (int i = 0; i < NEIGHBOUR_COUNT; ++i) + { + moment1 += samples.neighbours[i]; + moment2 += samples.neighbours[i] * samples.neighbours[i]; + } + + moment1 += samples.central; + moment2 += samples.central * samples.central; + + moment1 *= rcp(SAMPLE_COUNT); + moment2 *= rcp(SAMPLE_COUNT); + + float stdDev = sqrt(abs(moment2 - moment1 * moment1)); + + float stDevMultiplier = 1.5; + + float aggressiveStdDev = stdDev * 0.5; + float aggressiveClampedHistory = clamp(historyAlpha, moment1 - aggressiveStdDev, moment1 + aggressiveStdDev); + + const float maxFactorScale = 2.25f; // when stationary + const float minFactorScale = 0.8f; // when moving more than slightly + + float localizedAntiFlicker = lerp(antiFlickerParams.x * minFactorScale, antiFlickerParams.x * maxFactorScale, saturate(1.0f - 2.0f * (motionVecLenInPixels))); + + float temporalContrast = saturate(abs(filteredAlpha - aggressiveClampedHistory) / Max3(0.15, filteredAlpha, aggressiveClampedHistory)); + stDevMultiplier += lerp(0.0, localizedAntiFlicker, smoothstep(0.05, antiFlickerParams.y, temporalContrast)); + + stDevMultiplier = lerp(stDevMultiplier, 0.75, saturate(motionVecLenInPixels / 50.0f)); + + // We shrink the bounding box when upscaling as ghosting is more likely. + stDevMultiplier = lerp(0.9f, stDevMultiplier, saturate(downsampleFactor)); + + samples.minNeighbour = moment1 - stdDev * stDevMultiplier; + samples.maxNeighbour = moment1 + stdDev * stDevMultiplier; +} + +// Polynomial approximation of the Gaussian sample weight in the following link. +// https://www.desmos.com/calculator/g2hr2hzj84 +float GetSampleWeight(float2 offsets, float4 filterParameters) +{ + const float2 inputToOutputVec = filterParameters.zw; + const float resolutionScale2 = filterParameters.y * filterParameters.y; + float2 d = offsets - inputToOutputVec; + + float x2 = saturate(resolutionScale2 * dot(d, d)); + float f = 0.9656852 * x2 - 1; + return f * f; +} + +float FilterCentralColor(NeighbourhoodSamples samples, float4 filterParameters) +{ + float totalWeight = GetSampleWeight(0, filterParameters); // center + float filtered = samples.central * totalWeight; + + [unroll] + for (int i = 0; i < NEIGHBOUR_COUNT; ++i) + { + float w = GetSampleWeight(NeighbourOffsets[i], filterParameters); + filtered += samples.neighbours[i] * w; + totalWeight += w; + } + filtered *= rcp(totalWeight); + return filtered; +} + +[numthreads(GROUP_SIZE, GROUP_SIZE, 1)] +void UpscaleAlphaAndMergeColor(uint3 groupId : SV_GroupID, uint groupIndex : SV_GroupIndex, uint3 dispatchThreadId : SV_DispatchThreadID) +{ + UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); + + int2 tileOrigin = GetTileOrigin(groupId.xy * GROUP_SIZE); + LoadInputTile(tileOrigin, groupIndex); + GroupMemoryBarrierWithGroupSync(); + + uint2 pos = dispatchThreadId.xy; + if (any(pos >= uint2(_AlphaUpscaleParams1.xy))) + return; + + float3 color = LOAD_TEXTURE2D_X(_UpscaledColor, pos).rgb; + + // The output pixel's dejittered position in the input, + // with the tap UV snapped to the center of the containing input texel (the sub-texel + // part goes into the filter weights below). + float2 outputUV = ((float2)pos + 0.5) / _AlphaUpscaleParams1.xy; + float2 outputPixInInput = outputUV * _InputSize.xy - _TaaJitterStrength.xy; + float2 uv = _InputSize.zw * (0.5f + floor(outputPixInInput)); + + // The containing texel in tile coordinates. + int2 tileCoord = clamp(int2(floor(outputPixInInput)) - tileOrigin, TILE_BORDER, TILE_SIZE - 1 - TILE_BORDER); + + bool excludeTAABit = false; +#if DIRECT_STENCIL_SAMPLE + uint stencil = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, int2(outputPixInInput))); + excludeTAABit = (stencil == _ExcludeTAABit); +#endif + +#if REACTIVE_MASK + float reactiveMask = LOAD_TEXTURE2D_X(_ReactiveMaskTexture, int2(outputPixInInput)).x; +#endif + + // --------------- Get closest motion vector --------------- + float2 motionVector = GetMotionVector(uv, tileCoord, _InputSize.zw, _RTHandleScaleForTAA); + + // --------------- Get resampled history --------------- + float2 prevUV = outputUV - motionVector; + + float history = FetchHistory(prevUV, _RTHandleScaleForTAAHistory); + bool offScreen = any(abs(prevUV * 2 - 1) >= (1.0f - (1.0 * _TaaHistorySize.zw))); + + // --------------- Gather neigbourhood data --------------- + float alpha = TileAlpha(tileCoord); + + if (!excludeTAABit) + { + NeighbourhoodSamples samples; + GatherNeighbourhood(tileCoord, alpha, samples); + + // --------------- Filter central sample --------------- + float4 filterParams = 0; + filterParams.y = _TAAUScale; + filterParams.zw = outputPixInInput - (floor(outputPixInInput) + 0.5f); + + float filteredAlpha = FilterCentralColor(samples, filterParams); + + if (offScreen) + history = filteredAlpha; + + // --------------- Get neighbourhood information and clamp history --------------- + float motionVectorLenInPixels = length(motionVector) * length(_InputSize.xy); + + VarianceNeighbourhood(samples, history, filteredAlpha, float2(_AntiFlickerIntensity, _ContrastForMaxAntiFlicker), motionVectorLenInPixels, _TAAURenderScale); + + // GetClippedHistory with DIRECT_CLIP reduces to a clamp for a scalar + history = clamp(history, samples.minNeighbour, samples.maxNeighbour); + + // --------------- Compute blend factor for history --------------- + // On a history reset, and in the spatial-only mode (no history buffers provided, dummy + // textures bound), the history weight is 0, so the blend factor is 1 and the result falls + // through to the filtered alpha. + float blendFactor = _BaseBlendFactor; + // BLEND_FACTOR_MV_TUNE + blendFactor = lerp(blendFactor, saturate(2.0f * blendFactor), saturate(motionVectorLenInPixels / 50.0f)); + +#if REACTIVE_MASK + blendFactor = lerp(blendFactor, 1.0f, reactiveMask); +#endif + + // --------------- Alpha handling --------------- + alpha = lerp(history, filteredAlpha, blendFactor); + } + // Keep NaNs out of the history feedback loop, where they would otherwise persist. + alpha = saturate(alpha); + + if (_AlphaUpscaleParams2.y != 0.0) + _AlphaHistoryOutput[COORD_TEXTURE2D_X(pos)] = alpha; + + _OutputTexture[COORD_TEXTURE2D_X(pos)] = float4(color, alpha); +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute.meta new file mode 100644 index 00000000000..de8a816ec5e --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscale.compute.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f10c23179af641eea368ee165b2e97cf +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs new file mode 100644 index 00000000000..2ce132136f3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs @@ -0,0 +1,291 @@ +using System; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering.RenderGraphModule; + +namespace UnityEngine.Rendering +{ + /// + /// Utility pass that rebuilds the alpha channel of an image produced by a color-only upscaler. + /// + public static class AlphaUpscaler + { + /// + /// Input textures and parameters for the alpha upscale pass. + /// + public struct Config + { + /// Color at rendering resolution, before upscaling. Only the alpha channel is read. + public TextureHandle preUpscaleAlpha; + + /// Upscaled color whose alpha channel is undefined. Only the RGB channels are read. + public TextureHandle upscaledColor; + + /// Size of the rendered viewport of preUpscaleAlpha, in pixels. + public Vector2Int preUpscaleSize; + + /// + /// Physical (allocation) size of preUpscaleAlpha when it is larger than preUpscaleSize, + /// e.g. with viewport-based dynamic resolution inside a larger texture. Leave zero when + /// the texture is allocated at exactly preUpscaleSize. + /// + public Vector2Int preUpscalePhysicalSize; + + /// Size of the upscaled output, in pixels. + public Vector2Int postUpscaleSize; + + /// Sub-pixel camera jitter applied to the pre-upscale frame, in pixels at the rendering resolution. + public Vector2 jitter; + + /// Indicates whether the textures are 2D texture arrays, as used by XR single-pass rendering. + public bool enableTexArray; + + /// Number of views to process. + public int viewCount; + + /// + /// Motion vectors at rendering resolution, in viewport UV space. Along with the depth and + /// the two history textures, this enables the temporal accumulation; leave invalid for a + /// spatial-only upsample. + /// + public TextureHandle motionVectors; + + /// Depth at rendering resolution, for the motion vector dilation at silhouettes. + public TextureHandle cameraDepth; + + /// + /// Reactive mask at rendering resolution, or leave invalid to disable. + /// + public TextureHandle reactiveMask; + + /// Stencil value that marks the excluded pixels when reactiveMask is a stencil buffer. + public int stencilExcludeBit; + + /// Single-channel alpha history accumulated over the previous frames. + public TextureHandle prevAlphaHistory; + + /// Single-channel alpha history the pass writes this frame. + public TextureHandle nextAlphaHistory; + + /// + /// Blend weight of the reprojected history. Use 0 when the history content is invalid (e.g. on a + /// history reset): the frame falls back to the spatial upsample but still initializes the history. + /// + public float historyBlendFactor; + } + + /// Default history blend weight of the temporal alpha accumulation. + public const float defaultHistoryBlendFactor = 0.85f; + + /// + /// Contains the compute shader used by the alpha upscale pass + /// + [Serializable] + [SupportedOnRenderPipeline] + [Categorization.CategoryInfo(Name = "R: Alpha Upscaler", Order = 1000)] + [Categorization.ElementInfo(Order = 0), HideInInspector] + internal class RuntimeResources : IRenderPipelineResources + { + public int version => 0; + + bool IRenderPipelineGraphicsSettings.isAvailableInPlayerBuild => true; + + [SerializeField, ResourcePath("Runtime/Upscaling/AlphaUpscale.compute")] + private ComputeShader m_AlphaUpscaleCS; + + public ComputeShader alphaUpscaleCS + { + get => m_AlphaUpscaleCS; + set => this.SetValueAndNotify(ref m_AlphaUpscaleCS, value); + } + } + + static class ShaderResources + { + public static readonly int _UpscaledColor = Shader.PropertyToID("_UpscaledColor"); + public static readonly int _PreUpscaleAlpha = Shader.PropertyToID("_PreUpscaleAlpha"); + public static readonly int _MotionVectorTexture = Shader.PropertyToID("_MotionVectorTexture"); + public static readonly int _DepthTexture = Shader.PropertyToID("_DepthTexture"); + public static readonly int _StencilTexture = Shader.PropertyToID("_StencilTexture"); + public static readonly int _ExcludeTAABit = Shader.PropertyToID("_ExcludeTAABit"); + public static readonly int _ReactiveMaskTexture = Shader.PropertyToID("_ReactiveMaskTexture"); + public static readonly int _AlphaHistory = Shader.PropertyToID("_AlphaHistory"); + public static readonly int _AlphaHistoryOutput = Shader.PropertyToID("_AlphaHistoryOutput"); + public static readonly int _OutputTexture = Shader.PropertyToID("_OutputTexture"); + public static readonly int _AlphaUpscaleParams0 = Shader.PropertyToID("_AlphaUpscaleParams0"); + public static readonly int _AlphaUpscaleParams1 = Shader.PropertyToID("_AlphaUpscaleParams1"); + public static readonly int _AlphaUpscaleParams2 = Shader.PropertyToID("_AlphaUpscaleParams2"); + } + + static class ShaderKeywords + { + public static readonly string DisableTexture2DXArray = "DISABLE_TEXTURE2D_X_ARRAY"; + public static readonly string DirectStencilSample = "DIRECT_STENCIL_SAMPLE"; + public static readonly string ReactiveMask = "REACTIVE_MASK"; + } + + enum ReactiveMaskMode + { + None, + Stencil, + Color + } + + class PassData + { + public ComputeShader cs; + public int kernelIndex; + public Vector2Int dispatchSize; + public int viewCount; + public Vector2Int preUpscaleSize; + public Vector2Int preUpscalePhysicalSize; + public Vector4 params1; + public float historyBlend; + public bool useHistory; + public ReactiveMaskMode reactiveMaskMode; + public int stencilExcludeBit; + + public TextureHandle preUpscaleAlpha; + public TextureHandle upscaledColor; + public TextureHandle motionVectors; + public TextureHandle cameraDepth; + public TextureHandle reactiveMask; + public TextureHandle prevAlphaHistory; + public TextureHandle nextAlphaHistory; + public TextureHandle destination; + } + + static readonly ProfilingSampler k_AlphaUpscale = new ProfilingSampler("AlphaUpscale"); + + /// + /// Executes the alpha upscale pass using the provided configuration in the target render graph + /// + /// render graph to execute the pass within + /// configuration parameters for the pass + /// Texture handle that contains the upscaled color with a valid alpha channel + public static TextureHandle Execute(RenderGraph renderGraph, ref Config config) + { + var runtimeResources = GraphicsSettings.GetRenderPipelineSettings(); + + using (var builder = renderGraph.AddComputePass("Upscale Alpha And Merge Color", out var passData, k_AlphaUpscale)) + { + passData.cs = runtimeResources.alphaUpscaleCS; + passData.cs.shaderKeywords = null; + + if (!config.enableTexArray) + passData.cs.EnableKeyword(ShaderKeywords.DisableTexture2DXArray); + + var maskMode = ReactiveMaskMode.None; + if (config.reactiveMask.IsValid()) + maskMode = config.stencilExcludeBit != 0 ? ReactiveMaskMode.Stencil : ReactiveMaskMode.Color; + passData.reactiveMaskMode = maskMode; + + if (maskMode != ReactiveMaskMode.None) + { + passData.cs.EnableKeyword(maskMode == ReactiveMaskMode.Stencil + ? ShaderKeywords.DirectStencilSample : ShaderKeywords.ReactiveMask); + passData.stencilExcludeBit = config.stencilExcludeBit; + passData.reactiveMask = config.reactiveMask; + builder.UseTexture(passData.reactiveMask, AccessFlags.Read); + } + + passData.kernelIndex = passData.cs.FindKernel("UpscaleAlphaAndMergeColor"); + passData.viewCount = config.viewCount; + + // Must match GROUP_SIZE in AlphaUpscale.compute + const int groupSize = 16; + passData.dispatchSize = new Vector2Int( + CoreUtils.DivRoundUp(config.postUpscaleSize.x, groupSize), + CoreUtils.DivRoundUp(config.postUpscaleSize.y, groupSize) + ); + + passData.preUpscaleSize = config.preUpscaleSize; + passData.preUpscalePhysicalSize = (config.preUpscalePhysicalSize.x > 0 && config.preUpscalePhysicalSize.y > 0) + ? config.preUpscalePhysicalSize : config.preUpscaleSize; + passData.params1 = new Vector4(config.postUpscaleSize.x, config.postUpscaleSize.y, config.jitter.x, config.jitter.y); + + passData.preUpscaleAlpha = config.preUpscaleAlpha; + builder.UseTexture(passData.preUpscaleAlpha, AccessFlags.Read); + passData.upscaledColor = config.upscaledColor; + builder.UseTexture(passData.upscaledColor, AccessFlags.Read); + + var destinationDesc = config.upscaledColor.GetDescriptor(renderGraph); + destinationDesc.name = "UpscaledColorWithAlpha"; + destinationDesc.enableRandomWrite = true; + destinationDesc.clearBuffer = false; + passData.destination = renderGraph.CreateTexture(destinationDesc); + builder.UseTexture(passData.destination, AccessFlags.WriteAll); + + bool useHistory = config.motionVectors.IsValid() && config.cameraDepth.IsValid() && config.prevAlphaHistory.IsValid() && config.nextAlphaHistory.IsValid(); + passData.useHistory = useHistory; + passData.historyBlend = config.historyBlendFactor; + + if (useHistory) + { + passData.motionVectors = config.motionVectors; + passData.cameraDepth = config.cameraDepth; + passData.prevAlphaHistory = config.prevAlphaHistory; + passData.nextAlphaHistory = config.nextAlphaHistory; + } + else + { + // The kernel never touches the history in this mode, but the bindings must still be valid. + passData.motionVectors = renderGraph.defaultResources.blackTextureXR; + passData.cameraDepth = renderGraph.defaultResources.blackTextureXR; + passData.prevAlphaHistory = renderGraph.defaultResources.blackTextureXR; + passData.nextAlphaHistory = renderGraph.CreateTexture(new TextureDesc(1, 1, false, config.enableTexArray) + { + name = "AlphaHistoryUnused", + format = GraphicsFormat.R16_SFloat, + enableRandomWrite = true + }); + } + + builder.UseTexture(passData.motionVectors, AccessFlags.Read); + builder.UseTexture(passData.cameraDepth, AccessFlags.Read); + builder.UseTexture(passData.prevAlphaHistory, AccessFlags.Read); + builder.UseTexture(passData.nextAlphaHistory, AccessFlags.Write); + + builder.SetRenderFunc( + static (PassData data, ComputeGraphContext ctx) => + { + var params0 = new Vector4(data.preUpscaleSize.x, data.preUpscaleSize.y, 1.0f / data.preUpscalePhysicalSize.x, 1.0f / data.preUpscalePhysicalSize.y); + + // zw: the history RTHandle can be larger than the post-upscale viewport, + // so the kernel samples it with the physical texture size. + var params2 = Vector4.zero; + if (data.useHistory) + { + var historyTexture = (RenderTexture)data.nextAlphaHistory; + params2 = new Vector4(data.historyBlend, 1.0f, 1.0f / historyTexture.width, 1.0f / historyTexture.height); + } + + ctx.cmd.SetComputeVectorParam(data.cs, ShaderResources._AlphaUpscaleParams0, params0); + ctx.cmd.SetComputeVectorParam(data.cs, ShaderResources._AlphaUpscaleParams1, data.params1); + ctx.cmd.SetComputeVectorParam(data.cs, ShaderResources._AlphaUpscaleParams2, params2); + + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._PreUpscaleAlpha, data.preUpscaleAlpha); + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._UpscaledColor, data.upscaledColor); + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._MotionVectorTexture, data.motionVectors); + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._DepthTexture, data.cameraDepth); + + if (data.reactiveMaskMode == ReactiveMaskMode.Stencil) + { + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._StencilTexture, data.reactiveMask, 0, RenderTextureSubElement.Stencil); + ctx.cmd.SetComputeIntParam(data.cs, ShaderResources._ExcludeTAABit, data.stencilExcludeBit); + } + else if (data.reactiveMaskMode == ReactiveMaskMode.Color) + { + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._ReactiveMaskTexture, data.reactiveMask); + } + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._AlphaHistory, data.prevAlphaHistory); + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._AlphaHistoryOutput, data.nextAlphaHistory); + ctx.cmd.SetComputeTextureParam(data.cs, data.kernelIndex, ShaderResources._OutputTexture, data.destination); + + ctx.cmd.DispatchCompute(data.cs, data.kernelIndex, data.dispatchSize.x, data.dispatchSize.y, data.viewCount); + }); + + return passData.destination; + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs.meta new file mode 100644 index 00000000000..182863ea5cf --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/AlphaUpscaler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2762c3adff164eee9cb41d3a0b52d5d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscaler.cs b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscaler.cs index 91294173661..ebc3e546174 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscaler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscaler.cs @@ -211,6 +211,11 @@ public interface IUpscaler : IRenderGraphRecorder /// bool supportsSharpening { get; } + /// + /// Returns true if the alpha channel of the upscaler's output is valid. + /// + bool supportsAlphaUpscaling { get; } + /// /// Returns true if the upscaler exposes a quality mode that can dictate the render resolution (e.g. the /// DLSS/FSR presets). When false, the upscaler has no opinion on resolution and the pipeline drives the render @@ -312,6 +317,9 @@ public abstract class AbstractUpscaler : IUpscaler /// public abstract bool supportsSharpening { get; } + /// + public virtual bool supportsAlphaUpscaling => false; + /// public virtual bool hasQualityMode => false; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index 331874f6975..a2e3cbab3c1 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -69,6 +69,8 @@ public enum HDCameraFrameHistoryType PathTracingVolumetricFogDenoised, /// Variable rate shading. Vrs, + /// Alpha channel history used to accumulate the upscaled alpha alongside color-only upscalers (DLSS, FSR2, STP). + AlphaUpscale, // For retro compatibility /// Main path tracing output buffer. It is recommended to use the PathTracingOutput enum value instead. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs index b8c5806b7aa..30a0781f41e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs @@ -621,11 +621,50 @@ public bool PerformsAntiAliasing() return null; } + TextureHandle DoAlphaUpscaling(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle preUpscaleColor, TextureHandle upscaledColor, + in TextureHandle depthBuffer, in TextureHandle motionVectors, in TextureHandle stencilBuffer, bool isTemporalUpscaler) + { + AlphaUpscaler.Config config = default; + config.preUpscaleAlpha = preUpscaleColor; + config.upscaledColor = upscaledColor; + config.preUpscaleSize = new Vector2Int(hdCamera.actualWidth, hdCamera.actualHeight); + // HDRP color textures are allocated at the maximum RTHandle size and rendered into a + // viewport-sized sub-rect; with hardware DRS the allocation itself is scaled as well. + var preUpscalePhysicalSize = new Vector2Int(RTHandles.maxWidth, RTHandles.maxHeight); + if (DynamicResolutionHandler.instance.HardwareDynamicResIsEnabled()) + preUpscalePhysicalSize = DynamicResolutionHandler.instance.ApplyScalesOnSize(preUpscalePhysicalSize); + config.preUpscalePhysicalSize = preUpscalePhysicalSize; + config.postUpscaleSize = new Vector2Int(Mathf.RoundToInt(hdCamera.finalViewport.width), Mathf.RoundToInt(hdCamera.finalViewport.height)); + config.jitter = new Vector2(hdCamera.taaJitter.x, hdCamera.taaJitter.y); + config.enableTexArray = TextureXR.useTexArray; + config.viewCount = hdCamera.viewCount; + + // Spatial upscalers render without jitter, so there is no per-frame phase + // variance to accumulate away; the default config (no motion vectors, depth, + // stencil or history) runs the spatial-only reconstruction. + if (isTemporalUpscaler) + { + bool validHistory = GrabPostProcessHistoryTextures(hdCamera, HDCameraFrameHistoryType.AlphaUpscale, "Alpha Upscale History", GraphicsFormat.R16_SFloat, out var prevAlphaHistory, out var nextAlphaHistory); + + config.motionVectors = motionVectors; + config.cameraDepth = depthBuffer; + config.reactiveMask = stencilBuffer; + config.stencilExcludeBit = (int)StencilUsage.ExcludeFromTUAndAA; + config.prevAlphaHistory = renderGraph.ImportTexture(prevAlphaHistory); + config.nextAlphaHistory = renderGraph.ImportTexture(nextAlphaHistory); + config.historyBlendFactor = (validHistory && !hdCamera.resetPostProcessingHistory) ? AlphaUpscaler.defaultHistoryBlendFactor : 0.0f; + } + + return AlphaUpscaler.Execute(renderGraph, ref config); + } + TextureHandle DoUpscalingAndAntiAliasing(RenderGraph renderGraph, HDCamera hdCamera, CurrentUpsamplerData upsamplerDataData, TextureHandle source, in TextureHandle depthBuffer, in TextureHandle motionVectors, in TextureHandle stencilBuffer, in TextureHandle depthBufferMipChain) { bool taaUsesCAS = hdCamera.antialiasing == HDAdditionalCameraData.AntialiasingMode.TemporalAntialiasing && hdCamera.taaSharpenMode == HDAdditionalCameraData.TAASharpenMode.ContrastAdaptiveSharpening; + TextureHandle preUpscaleColor = source; + source = upsamplerDataData switch { #if ENABLE_UPSCALER_FRAMEWORK @@ -647,6 +686,23 @@ TextureHandle DoUpscalingAndAntiAliasing(RenderGraph renderGraph, HDCamera hdCam _ => source }; + // Advanced upscalers (including IUpscalers without alpha upscaling support) only upscale the RGB channels + // and leave the output alpha undefined, so rebuild it here from the pre-upscale alpha. + if (upsamplerDataData.isAdvancedUpsampler && source != preUpscaleColor && PostProcessEnableAlpha(hdCamera)) + { + bool supportsAlphaUpscaling = false; + bool isTemporalUpscaler = true; +#if ENABLE_UPSCALER_FRAMEWORK + if (upsamplerDataData.advancedUpsampler == AdvancedUpscalers.IUpscaler) + { + supportsAlphaUpscaling = upscaling.activeUpscaler.supportsAlphaUpscaling; + isTemporalUpscaler = upscaling.activeUpscaler.isTemporal; + } +#endif + if (!supportsAlphaUpscaling) + source = DoAlphaUpscaling(renderGraph, hdCamera, preUpscaleColor, source, depthBuffer, motionVectors, stencilBuffer, isTemporalUpscaler); + } + SetCurrentResolutionGroup(renderGraph, hdCamera, ResolutionGroup.AfterDynamicResUpscale); if (hdCamera.RequiresCameraJitter()) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs b/Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs new file mode 100644 index 00000000000..49c315e56c3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs @@ -0,0 +1,60 @@ +using UnityEngine.Rendering.RenderGraphModule; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// Wires the core AlphaUpscaler into URP: it runs right after a color-only upscaler + /// and rebuilds the output alpha from the pre-upscale alpha, so the + /// alpha channel survives upscalers that only reconstruct the color channels. + /// + internal static class AlphaUpscaleUtils + { + internal static void Execute(RenderGraph renderGraph, UniversalCameraData cameraData, UniversalResourceData resourceData, + TextureHandle preUpscaleColor, bool isTemporalUpscaler, Vector2Int preUpscaleSize, Vector2Int postUpscaleSize, Vector2 jitter, + TextureHandle reactiveMask = default, bool reactiveMaskIsStencil = false) + { + if (!cameraData.isAlphaOutputEnabled) + return; + + // The upscaler may have skipped this frame (e.g. unmet runtime requirements). + var upscaledColor = resourceData.cameraColor; + if (!upscaledColor.IsValid() || upscaledColor == preUpscaleColor) + return; + + AlphaUpscaler.Config config = default; + config.reactiveMask = reactiveMask; + config.stencilExcludeBit = reactiveMaskIsStencil ? 0x1 : 0; + config.preUpscaleAlpha = preUpscaleColor; + config.upscaledColor = upscaledColor; + config.preUpscaleSize = preUpscaleSize; + // URP allocates the camera color at exactly the rendered size (render scale included, and + // hardware DRS scales the allocation itself), so preUpscalePhysicalSize keeps its default. + config.postUpscaleSize = postUpscaleSize; + config.jitter = jitter; + config.enableTexArray = cameraData.xr.enabled && cameraData.xr.singlePassEnabled; + config.viewCount = cameraData.xr.enabled ? cameraData.xr.viewCount : 1; + + // Setup temporal inputs. + var history = cameraData.alphaUpscaleHistory; + if (isTemporalUpscaler && history != null && + resourceData.motionVectorColor.IsValid() && resourceData.cameraDepthTexture.IsValid()) + { + int eyeIndex = (cameraData.xr.enabled && !cameraData.xr.singlePassEnabled) ? cameraData.xr.multipassId : 0; + RTHandle prevAlphaHistory = history.GetPreviousTexture(eyeIndex); + RTHandle nextAlphaHistory = history.GetCurrentTexture(eyeIndex); + + if (prevAlphaHistory != null && nextAlphaHistory != null) + { + config.motionVectors = resourceData.motionVectorColor; + config.cameraDepth = resourceData.cameraDepthTexture; + config.prevAlphaHistory = renderGraph.ImportTexture(prevAlphaHistory); + config.nextAlphaHistory = renderGraph.ImportTexture(nextAlphaHistory); + config.historyBlendFactor = (history.validHistory && !cameraData.resetHistory) + ? AlphaUpscaler.defaultHistoryBlendFactor : 0.0f; + } + } + + resourceData.cameraColor = AlphaUpscaler.Execute(renderGraph, ref config); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs.meta new file mode 100644 index 00000000000..4252d2eb04a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/AlphaUpscaleUtils.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5d3c6e12f49d4d4bb66a294156503e02 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs index 2f279aaa797..a859985c8ca 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs @@ -626,6 +626,11 @@ internal bool IsSTPEnabled() /// internal StpHistory stpHistory; + /// + /// Post-upscale alpha history for the alpha upscale pass that runs after color-only upscalers. + /// + internal AlphaUpscaleHistory alphaUpscaleHistory; + // TAA settings. internal TemporalAA.Settings taaSettings; @@ -712,6 +717,7 @@ public override void Reset() backgroundColor = Color.black; taaHistory = null; stpHistory = null; + alphaUpscaleHistory = null; taaSettings = default; subpixelJitter = default; baseCamera = null; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs new file mode 100644 index 00000000000..214e85cc08a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs @@ -0,0 +1,72 @@ +using UnityEngine.Experimental.Rendering; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// Double-buffered post-upscale alpha history consumed by the alpha upscale pass (core AlphaUpscaler). + /// + internal sealed class AlphaUpscaleHistory : CameraHistoryItem + { + // One id per eye for XR multi-pass rendering. + int[] m_Ids = new int[2]; + static readonly string[] k_Names = { "AlphaUpscaleHistory0", "AlphaUpscaleHistory1" }; + + Hash128 m_DescKey; + + // The frame the textures were (re)allocated on. XR multi-pass calls Update once per eye + // within the same frame; tracking the frame keeps the history invalid for both eye passes + // of the allocation frame, not just the one that performed the allocation. + int m_AllocFrameIndex = -1; + + // False for the whole frame of a (re)allocation: the previous-frame content is undefined. + internal bool validHistory { get; private set; } + + public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) + { + base.OnCreate(owner, typeId); + m_Ids[0] = MakeId(0); + m_Ids[1] = MakeId(1); + } + + internal RTHandle GetCurrentTexture(int eyeIndex = 0) => GetCurrentFrameRT(m_Ids[eyeIndex]); + internal RTHandle GetPreviousTexture(int eyeIndex = 0) => GetPreviousFrameRT(m_Ids[eyeIndex]); + + public override void Reset() + { + for (int i = 0; i < m_Ids.Length; i++) + ReleaseHistoryFrameRT(m_Ids[i]); + validHistory = false; + } + + internal void Update(UniversalCameraData cameraData, bool xrMultipassEnabled) + { + // The history lives at the post-upscale resolution. Base the descriptor on the camera + // target so the XR texture dimension carries over. + var desc = cameraData.cameraTargetDescriptor; + desc.width = cameraData.pixelWidth; + desc.height = cameraData.pixelHeight; + desc.graphicsFormat = GraphicsFormat.R16_SFloat; + desc.depthStencilFormat = GraphicsFormat.None; + desc.mipCount = 0; + desc.msaaSamples = 1; + desc.enableRandomWrite = true; + // The history lives at the fixed post-upscale resolution. + desc.useDynamicScale = false; + + var descKey = Hash128.Compute(ref desc); + if (descKey != m_DescKey && GetCurrentTexture() != null) + Reset(); + + if (GetCurrentTexture() == null) + { + AllocHistoryFrameRT(m_Ids[0], 2, ref desc, k_Names[0]); + if (xrMultipassEnabled) + AllocHistoryFrameRT(m_Ids[1], 2, ref desc, k_Names[1]); + m_DescKey = descKey; + m_AllocFrameIndex = Time.frameCount; + } + + validHistory = Time.frameCount != m_AllocFrameIndex; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs.meta new file mode 100644 index 00000000000..a13e53a83f0 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/AlphaUpscaleHistory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: dddb68852f1a4baf8d7a52726983af85 \ No newline at end of file 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 bd870769825..9431a9a8560 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 @@ -82,6 +82,17 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer UpscalerPostProcessPass.UpdateCameraResolution(renderGraph, frameData, new Vector2Int(destDesc.width, destDesc.height)); resourceData.cameraColor = destinationTexture; + +#if !ENABLE_UPSCALER_FRAMEWORK + // STP only upscales the color channels; rebuild the output alpha from the pre-upscale image. + // cameraData.jitter is in NDC space; converting it back to pixels at the rendering resolution + // recovers the applied sub-pixel jitter. Negated because the alpha upscale kernel follows + // HDRP's jitter sign convention, which is the opposite of URP's (see the IUpscaler sign note + // in HDCamera.GetJitteredProjectionMatrix). + Vector2 alphaJitter = -0.5f * new Vector2(cameraData.jitter.x * srcDesc.width, cameraData.jitter.y * srcDesc.height); + AlphaUpscaleUtils.Execute(renderGraph, cameraData, resourceData, sourceTexture, isTemporalUpscaler: true, + new Vector2Int(srcDesc.width, srcDesc.height), new Vector2Int(destDesc.width, destDesc.height), alphaJitter); +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs index f85bd11eda1..db9fb08e61f 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs @@ -56,8 +56,8 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // reconstructs to full resolution mid-frame, but ScalableBufferManager is a single global scale with no per-stage // render->display transition, so the post-upscale chain (UberPost, final blit) keeps writing into the // ScalableBufferManager-scaled sub-rect and only that sub-rect of the screen updates. - // Gate on camera.allowDynamicResolution (the stable opt-in), not the live ScalableBufferManager factor, - // which would flip per-frame as the app crosses factor 1.0. + // Gate on camera.allowDynamicResolution (the stable opt-in), not the live ScalableBufferManager factor, + // which would flip per-frame as the app crosses factor 1.0. if (cameraData.camera.allowDynamicResolution && postProcessingData.activeUpscaler.isTemporal) { if (Debug.isDebugBuild && !m_WarnedHardwareDrsTemporalUnsupported) @@ -125,7 +125,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer } return; } - + if (Debug.isDebugBuild) // Saw valid motion data: reset so a later missing-data camera warns again. m_WarnedMissingMotionData = false; @@ -233,6 +233,14 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // Use the output texture of upscaling resourceData.cameraColor = io.cameraColor; + + // The negated jitter follows HDRP's sign convention (see HDCamera.GetJitteredProjectionMatrix). + if (!upscaler.supportsAlphaUpscaling) + { + AlphaUpscaleUtils.Execute(renderGraph, cameraData, resourceData, sourceTexture, upscaler.isTemporal, + io.preUpscaleResolution, io.postUpscaleResolution, -io.subpixelJitter, + io.reactiveMask, upscaler.reactiveMaskSource == ReactiveMaskSource.Stencil); + } #endif } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index f4e490c8891..e39d127bdbc 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -55,6 +55,7 @@ internal class AutoUpscaler : AbstractUpscaler public override string name => k_UpscalerName_Auto; public override bool isTemporal => false; public override bool supportsSharpening => false; + public override bool supportsAlphaUpscaling => true; // RecordRenderGraph is an empty implementation from AbstractUpscaler } internal class BilinearUpscaler : AbstractUpscaler @@ -63,6 +64,7 @@ internal class BilinearUpscaler : AbstractUpscaler public override string name => k_UpscalerName_Linear; public override bool isTemporal => false; public override bool supportsSharpening => false; + public override bool supportsAlphaUpscaling => true; } internal class PointUpscaler : AbstractUpscaler { @@ -70,6 +72,7 @@ internal class PointUpscaler : AbstractUpscaler public override string name => k_UpscalerName_Point; public override bool isTemporal => false; public override bool supportsSharpening => false; + public override bool supportsAlphaUpscaling => true; } internal class FSR1Upscaler : AbstractUpscaler { @@ -78,6 +81,7 @@ internal class FSR1Upscaler : AbstractUpscaler public override bool isSupportedOnDevice => FSRUtils.IsSupported(); public override bool isTemporal => false; public override bool supportsSharpening => true; + public override bool supportsAlphaUpscaling => true; // the FSR1 class is only for registration / unifying API for choosing an upscaler. // The pass execution logic is still carried out by the internal Fsr1UpscalePostProcessPass.cs } @@ -2534,6 +2538,19 @@ private static void UpdateTemporalAAData(UniversalCameraData cameraData, Univers cameraData.stpHistory = additionalCameraData.historyManager.GetHistoryForWrite(); } + bool needsAlphaUpscaleHistory = cameraData.isAlphaOutputEnabled; +#if ENABLE_UPSCALER_FRAMEWORK + IUpscaler activeUpscaler = upscaling.activeUpscaler; + needsAlphaUpscaleHistory &= activeUpscaler != null && activeUpscaler.isTemporal && !activeUpscaler.supportsAlphaUpscaling; +#else + needsAlphaUpscaleHistory &= cameraData.IsSTPEnabled(); +#endif + if (needsAlphaUpscaleHistory) + { + additionalCameraData.historyManager.RequestAccess(); + cameraData.alphaUpscaleHistory = additionalCameraData.historyManager.GetHistoryForWrite(); + } + // Update TAA settings ref var taaSettings = ref additionalCameraData.taaSettings; cameraData.taaSettings = taaSettings; @@ -2578,6 +2595,17 @@ private static void UpdateTemporalAATargets(UniversalCameraData cameraData) if (cameraData.IsSTPRequested()) cameraData.stpHistory?.Reset(); } + + // The alpha history is common to all color-only temporal upscalers, + // so it is updated outside the per-upscaler branches above. + if (cameraData.alphaUpscaleHistory != null) + { + bool alphaXrMultipassEnabled = false; +#if ENABLE_VR && ENABLE_XR_MODULE + alphaXrMultipassEnabled = cameraData.xr.enabled && !cameraData.xr.singlePassEnabled; +#endif + cameraData.alphaUpscaleHistory.Update(cameraData, alphaXrMultipassEnabled); + } } static void UpdateCameraStereoMatrices(Camera camera, XRPass xr) diff --git a/Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset b/Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset new file mode 100644 index 00000000000..6ea1ff3c256 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset @@ -0,0 +1,552 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 0cf1dab834d4ec34195b920ea7bbf9ec, type: 3} + m_Name: HDRP_Test_Both_FP16_PPAlpha_STP + m_EditorClassIdentifier: + m_RenderPipelineSettings: + supportShadowMask: 1 + supportSSR: 1 + supportSSRTransparent: 0 + supportSSAO: 1 + supportSSGI: 0 + supportSubsurfaceScattering: 1 + sssSampleBudget: + m_Values: 140000002800000050000000 + m_SchemaId: + m_Id: With3Levels + sssDownsampleSteps: + m_Values: 000000000000000000000000 + m_SchemaId: + m_Id: With3Levels + supportVolumetrics: 1 + supportVolumetricClouds: 0 + supportLightLayers: 1 + renderingLayerMaskBuffer: 0 + supportWater: 0 + waterSimulationResolution: 128 + supportWaterExclusion: 0 + supportWaterDeformation: 0 + deformationAtlasSize: 512 + maximumDeformerCount: 64 + supportWaterFoam: 0 + foamAtlasSize: 512 + waterCPUSimulation: 0 + supportComputeThickness: 0 + computeThicknessResolution: 1 + computeThicknessLayerMask: + serializedVersion: 2 + m_Bits: 0 + supportDistortion: 1 + supportTransparentBackface: 1 + supportTransparentDepthPrepass: 1 + supportTransparentDepthPostpass: 1 + colorBufferFormat: 48 + supportCustomPass: 1 + customBufferFormat: 12 + supportedLitShaderMode: 3 + planarReflectionResolution: + m_Values: 000100000004000000080000 + m_SchemaId: + m_Id: With3Levels + cubeReflectionResolution: + m_Values: 800000000001000000020000 + m_SchemaId: + m_Id: With3Levels + supportDecals: 1 + supportDecalLayers: 0 + supportSurfaceGradient: 0 + decalNormalBufferHP: 0 + supportHighQualityLineRendering: 0 + highQualityLineRenderingMemoryBudget: 128 + msaaSampleCount: 1 + supportMotionVectors: 1 + supportScreenSpaceLensFlare: 1 + supportDataDrivenLensFlare: 1 + supportDitheringCrossFade: 0 + supportRuntimeAOVAPI: 0 + supportTerrainHole: 1 + lightProbeSystem: 0 + oldLightProbeSystem: 0 + probeVolumeMemoryBudget: 1024 + supportProbeVolumeGPUStreaming: 0 + supportProbeVolumeDiskStreaming: 0 + probeVolumeSHBands: 1 + supportProbeVolumeScenarios: 0 + supportProbeVolumeScenarioBlending: 1 + probeVolumeBlendingMemoryBudget: 128 + supportRayTracing: 0 + supportVFXRayTracing: 0 + supportedRayTracingMode: 3 + lightLoopSettings: + cookieAtlasSize: 512 + cookieFormat: 74 + cookieAtlasLastValidMip: 0 + cookieTexArraySize: 16 + planarReflectionAtlasSize: 2048 + reflectionProbeCacheSize: 128 + reflectionCubemapSize: 128 + maxEnvLightsOnScreen: 64 + reflectionCacheCompressed: 0 + reflectionProbeFormat: 74 + reflectionProbeTexCacheSize: 4096 + reflectionProbeTexLastValidCubeMip: 3 + reflectionProbeTexLastValidPlanarMip: 0 + reflectionProbeDecreaseResToFit: 1 + skyReflectionSize: 256 + skyLightingOverrideLayerMask: + serializedVersion: 2 + m_Bits: 0 + supportFabricConvolution: 0 + maxDirectionalLightsOnScreen: 16 + maxPunctualLightsOnScreen: 512 + maxAreaLightsOnScreen: 64 + maxCubeReflectionOnScreen: 48 + maxPlanarReflectionOnScreen: 16 + maxDecalsOnScreen: 512 + maxLightsPerClusterCell: 8 + maxLocalVolumetricFogSize: 32 + maxLocalVolumetricFogOnScreen: 64 + hdShadowInitParams: + maxShadowRequests: 128 + directionalShadowsDepthBits: 32 + punctualShadowFilteringQuality: 0 + directionalShadowFilteringQuality: 0 + areaShadowFilteringQuality: 0 + punctualLightShadowAtlas: + shadowAtlasResolution: 4096 + shadowAtlasDepthBits: 32 + useDynamicViewportRescale: 0 + areaLightShadowAtlas: + shadowAtlasResolution: 4096 + shadowAtlasDepthBits: 32 + useDynamicViewportRescale: 0 + cachedPunctualLightShadowAtlas: 2048 + cachedAreaLightShadowAtlas: 1024 + allowDirectionalMixedCachedShadows: 0 + shadowResolutionDirectional: + m_Values: 00010000000200000004000000080000 + m_SchemaId: + m_Id: With4Levels + shadowResolutionPunctual: + m_Values: 00010000000200000004000000080000 + m_SchemaId: + m_Id: With4Levels + shadowResolutionArea: + m_Values: 00010000000200000004000000080000 + m_SchemaId: + m_Id: With4Levels + maxDirectionalShadowMapResolution: 2048 + maxPunctualShadowMapResolution: 2048 + maxAreaShadowMapResolution: 2048 + supportScreenSpaceShadows: 0 + maxScreenSpaceShadowSlots: 4 + screenSpaceShadowBufferFormat: 48 + decalSettings: + drawDistance: 1000 + atlasWidth: 2048 + atlasHeight: 1024 + transparentTextureResolution: + m_Values: 000100000002000000040000 + m_SchemaId: + m_Id: With3Levels + perChannelMask: 1 + postProcessSettings: + m_LutSize: 32 + lutFormat: 48 + bufferFormat: 48 + dynamicResolutionSettings: + enabled: 1 + useMipBias: 1 + advancedUpscalerNames: + - STP + enableDLSS: 0 + DLSSPerfQualitySetting: 0 + DLSSInjectionPoint: 0 + DLSSUseOptimalSettings: 1 + DLSSSharpness: 0.5 + fsrOverrideSharpness: 0 + fsrSharpness: 0.92 + maxPercentage: 100 + minPercentage: 100 + dynResType: 0 + upsampleFilter: 5 + forceResolution: 1 + forcedPercentage: 50 + lowResTransparencyMinimumThreshold: 0 + rayTracingHalfResThreshold: 50 + lowresTransparentSettings: + enabled: 1 + checkerboardDepthBuffer: 1 + upsampleType: 1 + xrSettings: + singlePass: 1 + occlusionMesh: 1 + cameraJitter: 1 + allowMotionBlur: 0 + postProcessQualitySettings: + NearBlurSampleCount: 030000000500000008000000 + NearBlurMaxRadius: + - 2 + - 4 + - 7 + FarBlurSampleCount: 04000000070000000e000000 + FarBlurMaxRadius: + - 5 + - 8 + - 13 + DoFResolution: 040000000200000001000000 + DoFHighQualityFiltering: 000101 + DoFPhysicallyBased: 000000 + LimitManualRangeNearBlur: 000000 + MotionBlurSampleCount: 04000000080000000c000000 + BloomRes: 040000000200000002000000 + BloomHighQualityFiltering: 000101 + BloomHighQualityPrefiltering: 000001 + ChromaticAberrationMaxSamples: 03000000060000000c000000 + lightSettings: + useContactShadow: + m_Values: 000000 + m_SchemaId: + m_Id: + maximumLODLevel: + m_Values: 000000000000000000000000 + m_SchemaId: + m_Id: With3Levels + lodBias: + m_Values: + - 1 + - 1 + - 1 + m_SchemaId: + m_Id: With3Levels + lightingQualitySettings: + AOStepCount: 040000000600000010000000 + AOFullRes: 000001 + AOMaximumRadiusPixels: 200000002800000050000000 + AOBilateralUpsample: 000101 + AODirectionCount: 010000000200000004000000 + ContactShadowSampleCount: 060000000a00000010000000 + SSRMaxRaySteps: 100000002000000040000000 + SSGIRaySteps: 200000004000000080000000 + SSGIDenoise: 010101 + SSGIHalfResDenoise: 010000 + SSGIDenoiserRadius: + - 0.75 + - 0.5 + - 0.5 + SSGISecondDenoise: 010101 + RTAORayLength: + - 0.5 + - 3 + - 20 + RTAOSampleCount: 010000000200000008000000 + RTAODenoise: 010101 + RTAODenoiserRadius: + - 0.25 + - 0.5 + - 0.65 + RTGIRayLength: + - 50 + - 50 + - 50 + RTGIFullResolution: 000001 + RTGIClampValue: + - 0.5 + - 0.8 + - 1.5 + RTGIRaySteps: 200000003000000040000000 + RTGIDenoise: 010101 + RTGIHalfResDenoise: 010000 + RTGIDenoiserRadius: + - 0.75 + - 0.5 + - 0.25 + RTGISecondDenoise: 010101 + RTRMinSmoothness: + - 0.6 + - 0.4 + - 0 + RTRSmoothnessFadeStart: + - 0.7 + - 0.5 + - 0 + RTRRayLength: + - 50 + - 50 + - 50 + RTRClampValue: + - 0.8 + - 1 + - 1.2 + RTRFullResolution: 000001 + RTRRayMaxIterations: 200000003000000040000000 + RTRDenoise: 010101 + RTRDenoiserRadiusDimmer: + - 0.75 + - 0.75 + - 1 + RTRDenoiserAntiFlicker: + - 1 + - 1 + - 1 + Fog_ControlMode: 000000000000000000000000 + Fog_Budget: + - 0.166 + - 0.33 + - 0.666 + Fog_DepthRatio: + - 0.666 + - 0.666 + - 0.5 + m_ObsoleteLightLayerName0: Light Layer default + m_ObsoleteLightLayerName1: Light Layer 1 + m_ObsoleteLightLayerName2: Light Layer 2 + m_ObsoleteLightLayerName3: Light Layer 3 + m_ObsoleteLightLayerName4: Light Layer 4 + m_ObsoleteLightLayerName5: Light Layer 5 + m_ObsoleteLightLayerName6: Light Layer 6 + m_ObsoleteLightLayerName7: Light Layer 7 + m_ObsoleteDecalLayerName0: + m_ObsoleteDecalLayerName1: + m_ObsoleteDecalLayerName2: + m_ObsoleteDecalLayerName3: + m_ObsoleteDecalLayerName4: + m_ObsoleteDecalLayerName5: + m_ObsoleteDecalLayerName6: + m_ObsoleteDecalLayerName7: + m_ObsoleteSupportRuntimeDebugDisplay: 0 + allowShaderVariantStripping: 1 + enableSRPBatcher: 1 + availableMaterialQualityLevels: -1 + m_DefaultMaterialQualityLevel: 4 + diffusionProfileSettings: {fileID: 11400000, guid: 802c802428a2d9640a87e821dfcdd9e8, + type: 2} + m_VolumeProfile: {fileID: 0} + virtualTexturingSettings: + streamingCpuCacheSizeInMegaBytes: 80 + streamingMipPreloadTexturesPerFrame: 0 + streamingPreloadMipCount: 1 + streamingGpuCacheSettings: + - format: 0 + sizeInMegaBytes: 32 + m_UseRenderGraph: 1 + 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: 0} + m_ObsoleteDefaultLookDevProfile: {fileID: 0} + m_ObsoleteFrameSettingsMovedToDefaultSettings: + bitDatas: + data1: 139549384114013 + 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: 139713129348893 + 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: 140065316601629 + 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_ObsoleteRenderPipelineResources: {fileID: 11400000, guid: 3ce144cff5783da45aa5d4fdc2da14b7, + type: 2} + m_ObsoleteRenderPipelineRayTracingResources: {fileID: 0} + m_ObsoleteBeforeTransparentCustomPostProcesses: [] + m_ObsoleteBeforePostProcessCustomPostProcesses: [] + m_ObsoleteAfterPostProcessCustomPostProcesses: [] + m_ObsoleteBeforeTAACustomPostProcesses: [] + m_ObsoleteShaderVariantLogLevel: 1 + m_ObsoleteLensAttenuation: 0 + m_ObsoleteDiffusionProfileSettingsList: + - {fileID: 11400000, guid: 802c802428a2d9640a87e821dfcdd9e8, type: 2} + - {fileID: 11400000, guid: 09c63d8f96a14884e8efd2f01004f491, type: 2} + - {fileID: 11400000, guid: 8471a5bfcdb8fff4f9406cd8079b8554, type: 2} + - {fileID: 11400000, guid: 968a3176000311d42af174756ece7f4d, type: 2} + - {fileID: 11400000, guid: 768484f758b6f7b4daf53a7d9949f5af, type: 2} + - {fileID: 11400000, guid: fcb8f92518ca5d14bbd7e6751b28cd24, type: 2} + - {fileID: 11400000, guid: 64ca25f51b132ea4093511f7456ea220, type: 2} + - {fileID: 11400000, guid: fd29a6d903d5eae4d94833c2048bfd9d, type: 2} + - {fileID: 11400000, guid: 76f34276e6d50dc4bb0762b87af8931e, type: 2} + - {fileID: 11400000, guid: cd1cd5a7c0527844dbca2b7d562b9049, type: 2} + - {fileID: 11400000, guid: 385fff18b5c61754188b49a485ecb84a, type: 2} + - {fileID: 11400000, guid: d3dd41407c183554ca54bded902d4b7b, type: 2} + - {fileID: 11400000, guid: 86c1c808ebce1cc4992b9b0fd197a0b3, type: 2} + - {fileID: 11400000, guid: 3506ae472b257f042af66a183fbaac6a, type: 2} + - {fileID: 11400000, guid: 6be2047feaba36945b8fd12f29e3a7b5, type: 2} diff --git a/Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset.meta b/Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset.meta new file mode 100644 index 00000000000..eef652c3cb9 --- /dev/null +++ b/Tests/SRPTests/Packages/com.unity.testing.hdrp/RP_Assets/HDRP_Test_Both_FP16_PPAlpha_STP.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2fc7e7c78d3f4b29afb8f544ee1e1ae3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.meta new file mode 100644 index 00000000000..bb2a10f0509 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1b7df8c4f3dd1544a9a89bcaed43f2ea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity new file mode 100644 index 00000000000..f3d7b230e7f --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:475ce0d4b6960cdc14d4e33d03d3b0f295424573158d7d8ebb32d3b041f652b6 +size 30440 diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity.meta new file mode 100644 index 00000000000..be64d709bc8 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 861fa82a1b434385a3bf6f3536540712 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/.gitignore b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/.gitignore new file mode 100644 index 00000000000..1c33e83589d --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/.gitignore @@ -0,0 +1,3 @@ +Lightmap-*_comp* +LightingData.* +ReflectionProbe-* \ No newline at end of file diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat new file mode 100644 index 00000000000..4acb4586790 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat @@ -0,0 +1,29 @@ +%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: DisplayRTTAlpha + m_Shader: {fileID: 4800000, guid: 3687b28368c049c7bf70c618b9eb3bdd, 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: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: [] + m_Ints: [] + m_Floats: [] + m_Colors: [] + m_BuildTextureStacks: [] diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat.meta new file mode 100644 index 00000000000..01fa6c2cb77 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 61293c857b814ebb982da40204ec4d6e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader new file mode 100644 index 00000000000..d6b2318a5a6 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader @@ -0,0 +1,61 @@ +Shader "FullScreen/DisplayRTTAlpha" +{ + HLSLINCLUDE + + #pragma vertex Vert + + #pragma target 4.5 + #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2 + + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl" + + float4 CopyAlphaPass(Varyings varyings) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings); + + float alpha = LOAD_TEXTURE2D_X_LOD(_AfterPostProcessColorBuffer, varyings.positionCS.xy, 0).a; + + return float4(alpha.xxx, 1.0); + } + + float4 DisplayAlphaPass(Varyings varyings) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings); + + return float4(CustomPassLoadCustomColor(varyings.positionCS.xy).rgb, 1.0); + } + + ENDHLSL + + SubShader + { + Pass + { + Name "Copy Alpha" + + ZWrite Off + ZTest Always + Blend Off + Cull Off + + HLSLPROGRAM + #pragma fragment CopyAlphaPass + ENDHLSL + } + + Pass + { + Name "Display Alpha" + + ZWrite Off + ZTest Always + Blend Off + Cull Off + + HLSLPROGRAM + #pragma fragment DisplayAlphaPass + ENDHLSL + } + } + Fallback Off +} diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader.meta new file mode 100644 index 00000000000..be1d8474d5f --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/DisplayRTTAlpha.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3687b28368c049c7bf70c618b9eb3bdd +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat new file mode 100644 index 00000000000..f8766c655f4 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat @@ -0,0 +1,307 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5166128023983884676 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 13 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SphereMaterial + m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _DISABLE_SSR_TRANSPARENT + - _NORMALMAP_TANGENT_SPACE + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2225 + stringTagMap: {} + disabledShaderPasses: + - DistortionVectors + - MOTIONVECTORS + - ForwardEmissiveForDeferred + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AnisotropyMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 97a5684bc72c1704fadc965467f242ea, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _CoatMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DistortionVectorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissiveColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HeightMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 97a5684bc72c1704fadc965467f242ea, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecularColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SubsurfaceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmissionMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmittanceColorMap: + 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: + - _AORemapMax: 1 + - _AORemapMin: 0 + - _ATDistance: 1 + - _AddPrecomputedVelocity: 0 + - _AlbedoAffectEmissive: 0 + - _AlphaCutoff: 0.5 + - _AlphaCutoffEnable: 0 + - _AlphaCutoffPostpass: 0.5 + - _AlphaCutoffPrepass: 0.5 + - _AlphaCutoffShadow: 0.5 + - _AlphaDstBlend: 0 + - _AlphaRemapMax: 1 + - _AlphaRemapMin: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _Anisotropy: 0 + - _BlendMode: 0 + - _CoatMask: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailAlbedoScale: 1 + - _DetailNormalScale: 1 + - _DetailSmoothnessScale: 1 + - _DiffusionProfile: 0 + - _DiffusionProfileHash: 0 + - _DisplacementLockObjectScale: 1 + - _DisplacementLockTilingScale: 1 + - _DisplacementMode: 0 + - _DistortionBlendMode: 0 + - _DistortionBlurBlendMode: 0 + - _DistortionBlurDstBlend: 1 + - _DistortionBlurRemapMax: 1 + - _DistortionBlurRemapMin: 0 + - _DistortionBlurScale: 1 + - _DistortionBlurSrcBlend: 1 + - _DistortionDepthTest: 1 + - _DistortionDstBlend: 1 + - _DistortionEnable: 0 + - _DistortionScale: 1 + - _DistortionSrcBlend: 1 + - _DistortionVectorBias: -1 + - _DistortionVectorScale: 2 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 1 + - _DstBlend: 0 + - _DstBlend2: 0 + - _EmissiveColorMode: 1 + - _EmissiveExposureWeight: 1 + - _EmissiveIntensity: 1 + - _EmissiveIntensityUnit: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnableGeometricSpecularAA: 0 + - _EnergyConservingSpecularColor: 1 + - _ForceForwardEmissive: 0 + - _HdrpVersion: 2 + - _HeightAmplitude: 0.02 + - _HeightCenter: 0.5 + - _HeightMapParametrization: 0 + - _HeightMax: 1 + - _HeightMin: -1 + - _HeightOffset: 0 + - _HeightPoMAmplitude: 2 + - _HeightTessAmplitude: 2 + - _HeightTessCenter: 0.5 + - _InvTilingScale: 1 + - _Ior: 1.5 + - _IridescenceMask: 1 + - _IridescenceThickness: 1 + - _LinkDetailsWithBase: 1 + - _MaterialID: 1 + - _Metallic: 0 + - _MetallicRemapMax: 0 + - _MetallicRemapMin: 0 + - _NormalMapSpace: 0 + - _NormalScale: 1 + - _ObjectSpaceUVMapping: 0 + - _ObjectSpaceUVMappingEmissive: 0 + - _OpaqueCullMode: 2 + - _PPDLodThreshold: 5 + - _PPDMaxSamples: 15 + - _PPDMinSamples: 5 + - _PPDPrimitiveLength: 1 + - _PPDPrimitiveWidth: 1 + - _PerPixelSorting: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _SSRefractionProjectionModel: 0 + - _Smoothness: 0.5 + - _SmoothnessRemapMax: 1 + - _SmoothnessRemapMin: 0 + - _SpecularAAScreenSpaceVariance: 0.1 + - _SpecularAAThreshold: 0.2 + - _SpecularOcclusionMode: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 8 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 10 + - _StencilRefMV: 40 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 9 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 15 + - _StencilWriteMaskMV: 41 + - _SubsurfaceMask: 1 + - _SupportDecals: 1 + - _SurfaceType: 0 + - _TexWorldScale: 1 + - _TexWorldScaleEmissive: 1 + - _Thickness: 1 + - _TransmissionEnable: 1 + - _TransmissionMask: 1 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVBase: 0 + - _UVDetail: 0 + - _UVEmissive: 0 + - _UseEmissiveIntensity: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 3 + - _ZTestGBuffer: 4 + - _ZTestModeDistortion: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1} + - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0} + - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _SpecularColor: {r: 1, g: 1, b: 1, a: 1} + - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1} + - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat.meta new file mode 100644 index 00000000000..174bac4c8d1 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2fe7f1bc231935f4e87d147c6633aee5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat new file mode 100644 index 00000000000..b1ed35860d4 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat @@ -0,0 +1,310 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5166128023983884676 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 13 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SphereMaterialTransp + m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _DISABLE_SSR_TRANSPARENT + - _ENABLE_FOG_ON_TRANSPARENT + - _NORMALMAP_TANGENT_SPACE + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - DistortionVectors + - MOTIONVECTORS + - ForwardEmissiveForDeferred + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AnisotropyMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 97a5684bc72c1704fadc965467f242ea, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _CoatMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DistortionVectorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissiveColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HeightMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 97a5684bc72c1704fadc965467f242ea, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecularColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SubsurfaceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmissionMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmittanceColorMap: + 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: + - _AORemapMax: 1 + - _AORemapMin: 0 + - _ATDistance: 1 + - _AddPrecomputedVelocity: 0 + - _AlbedoAffectEmissive: 0 + - _AlphaCutoff: 0.5 + - _AlphaCutoffEnable: 0 + - _AlphaCutoffPostpass: 0.5 + - _AlphaCutoffPrepass: 0.5 + - _AlphaCutoffShadow: 0.5 + - _AlphaDstBlend: 10 + - _AlphaRemapMax: 1 + - _AlphaRemapMin: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _Anisotropy: 0 + - _BlendMode: 0 + - _CoatMask: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailAlbedoScale: 1 + - _DetailNormalScale: 1 + - _DetailSmoothnessScale: 1 + - _DiffusionProfile: 0 + - _DiffusionProfileHash: 0 + - _DisplacementLockObjectScale: 1 + - _DisplacementLockTilingScale: 1 + - _DisplacementMode: 0 + - _DistortionBlendMode: 0 + - _DistortionBlurBlendMode: 0 + - _DistortionBlurDstBlend: 1 + - _DistortionBlurRemapMax: 1 + - _DistortionBlurRemapMin: 0 + - _DistortionBlurScale: 1 + - _DistortionBlurSrcBlend: 1 + - _DistortionDepthTest: 1 + - _DistortionDstBlend: 1 + - _DistortionEnable: 0 + - _DistortionScale: 1 + - _DistortionSrcBlend: 1 + - _DistortionVectorBias: -1 + - _DistortionVectorScale: 2 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 1 + - _DstBlend: 10 + - _DstBlend2: 10 + - _EmissiveColorMode: 1 + - _EmissiveExposureWeight: 1 + - _EmissiveIntensity: 1 + - _EmissiveIntensityUnit: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnableGeometricSpecularAA: 0 + - _EnergyConservingSpecularColor: 1 + - _ForceForwardEmissive: 0 + - _HdrpVersion: 2 + - _HeightAmplitude: 0.02 + - _HeightCenter: 0.5 + - _HeightMapParametrization: 0 + - _HeightMax: 1 + - _HeightMin: -1 + - _HeightOffset: 0 + - _HeightPoMAmplitude: 2 + - _HeightTessAmplitude: 2 + - _HeightTessCenter: 0.5 + - _InvTilingScale: 1 + - _Ior: 1.5 + - _IridescenceMask: 1 + - _IridescenceThickness: 1 + - _LinkDetailsWithBase: 1 + - _MaterialID: 1 + - _Metallic: 0 + - _MetallicRemapMax: 0 + - _MetallicRemapMin: 0 + - _NormalMapSpace: 0 + - _NormalScale: 1 + - _ObjectSpaceUVMapping: 0 + - _ObjectSpaceUVMappingEmissive: 0 + - _OpaqueCullMode: 2 + - _PPDLodThreshold: 5 + - _PPDMaxSamples: 15 + - _PPDMinSamples: 5 + - _PPDPrimitiveLength: 1 + - _PPDPrimitiveWidth: 1 + - _PerPixelSorting: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _SSRefractionProjectionModel: 0 + - _Smoothness: 0.5 + - _SmoothnessRemapMax: 1 + - _SmoothnessRemapMin: 0 + - _SpecularAAScreenSpaceVariance: 0.1 + - _SpecularAAThreshold: 0.2 + - _SpecularOcclusionMode: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 0 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 2 + - _StencilRefMV: 32 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 9 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 15 + - _StencilWriteMaskMV: 41 + - _SubsurfaceMask: 1 + - _SupportDecals: 1 + - _SurfaceType: 1 + - _TexWorldScale: 1 + - _TexWorldScaleEmissive: 1 + - _Thickness: 1 + - _TransmissionEnable: 1 + - _TransmissionMask: 1 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 0 + - _UVBase: 0 + - _UVDetail: 0 + - _UVEmissive: 0 + - _UseEmissiveIntensity: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 4 + - _ZTestGBuffer: 4 + - _ZTestModeDistortion: 4 + - _ZTestTransparent: 4 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1} + - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0} + - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _SpecularColor: {r: 1, g: 1, b: 1, a: 1} + - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1} + - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat.meta new file mode 100644 index 00000000000..8ecbc45b89e --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTransp.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8904c5ec87b77374aa2bb5befbfe2284 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat new file mode 100644 index 00000000000..f43d7e5e160 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat @@ -0,0 +1,310 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5166128023983884676 +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: da692e001514ec24dbc4cca1949ff7e8, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 13 + hdPluginSubTargetMaterialVersions: + m_Keys: [] + m_Values: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: SphereMaterialTranspWritesDepth + m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _DISABLE_SSR_TRANSPARENT + - _ENABLE_FOG_ON_TRANSPARENT + - _NORMALMAP_TANGENT_SPACE + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - DistortionVectors + - MOTIONVECTORS + - ForwardEmissiveForDeferred + - TransparentDepthPrepass + - TransparentDepthPostpass + - TransparentBackface + - RayTracingPrepass + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AnisotropyMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BaseColorMap: + m_Texture: {fileID: 2800000, guid: 97a5684bc72c1704fadc965467f242ea, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BentNormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _CoatMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DistortionVectorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissiveColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _HeightMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _IridescenceThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: 97a5684bc72c1704fadc965467f242ea, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecularColorMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SubsurfaceMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TangentMapOS: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ThicknessMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmissionMaskMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TransmittanceColorMap: + 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: + - _AORemapMax: 1 + - _AORemapMin: 0 + - _ATDistance: 1 + - _AddPrecomputedVelocity: 0 + - _AlbedoAffectEmissive: 0 + - _AlphaCutoff: 0.5 + - _AlphaCutoffEnable: 0 + - _AlphaCutoffPostpass: 0.5 + - _AlphaCutoffPrepass: 0.5 + - _AlphaCutoffShadow: 0.5 + - _AlphaDstBlend: 10 + - _AlphaRemapMax: 1 + - _AlphaRemapMin: 0 + - _AlphaSrcBlend: 1 + - _AlphaToMask: 0 + - _AlphaToMaskInspectorValue: 0 + - _Anisotropy: 0 + - _BlendMode: 0 + - _CoatMask: 0 + - _CullMode: 2 + - _CullModeForward: 2 + - _Cutoff: 0.5 + - _DepthOffsetEnable: 0 + - _DetailAlbedoScale: 1 + - _DetailNormalScale: 1 + - _DetailSmoothnessScale: 1 + - _DiffusionProfile: 0 + - _DiffusionProfileHash: 0 + - _DisplacementLockObjectScale: 1 + - _DisplacementLockTilingScale: 1 + - _DisplacementMode: 0 + - _DistortionBlendMode: 0 + - _DistortionBlurBlendMode: 0 + - _DistortionBlurDstBlend: 1 + - _DistortionBlurRemapMax: 1 + - _DistortionBlurRemapMin: 0 + - _DistortionBlurScale: 1 + - _DistortionBlurSrcBlend: 1 + - _DistortionDepthTest: 1 + - _DistortionDstBlend: 1 + - _DistortionEnable: 0 + - _DistortionScale: 1 + - _DistortionSrcBlend: 1 + - _DistortionVectorBias: -1 + - _DistortionVectorScale: 2 + - _DoubleSidedEnable: 0 + - _DoubleSidedGIMode: 0 + - _DoubleSidedNormalMode: 1 + - _DstBlend: 10 + - _DstBlend2: 10 + - _EmissiveColorMode: 1 + - _EmissiveExposureWeight: 1 + - _EmissiveIntensity: 1 + - _EmissiveIntensityUnit: 0 + - _EnableBlendModePreserveSpecularLighting: 1 + - _EnableFogOnTransparent: 1 + - _EnableGeometricSpecularAA: 0 + - _EnergyConservingSpecularColor: 1 + - _ForceForwardEmissive: 0 + - _HdrpVersion: 2 + - _HeightAmplitude: 0.02 + - _HeightCenter: 0.5 + - _HeightMapParametrization: 0 + - _HeightMax: 1 + - _HeightMin: -1 + - _HeightOffset: 0 + - _HeightPoMAmplitude: 2 + - _HeightTessAmplitude: 2 + - _HeightTessCenter: 0.5 + - _InvTilingScale: 1 + - _Ior: 1.5 + - _IridescenceMask: 1 + - _IridescenceThickness: 1 + - _LinkDetailsWithBase: 1 + - _MaterialID: 1 + - _Metallic: 0 + - _MetallicRemapMax: 0 + - _MetallicRemapMin: 0 + - _NormalMapSpace: 0 + - _NormalScale: 1 + - _ObjectSpaceUVMapping: 0 + - _ObjectSpaceUVMappingEmissive: 0 + - _OpaqueCullMode: 2 + - _PPDLodThreshold: 5 + - _PPDMaxSamples: 15 + - _PPDMinSamples: 5 + - _PPDPrimitiveLength: 1 + - _PPDPrimitiveWidth: 1 + - _PerPixelSorting: 0 + - _RayTracing: 0 + - _ReceivesSSR: 1 + - _ReceivesSSRTransparent: 0 + - _RefractionModel: 0 + - _SSRefractionProjectionModel: 0 + - _Smoothness: 0.5 + - _SmoothnessRemapMax: 1 + - _SmoothnessRemapMin: 0 + - _SpecularAAScreenSpaceVariance: 0.1 + - _SpecularAAThreshold: 0.2 + - _SpecularOcclusionMode: 1 + - _SrcBlend: 1 + - _StencilRef: 0 + - _StencilRefDepth: 0 + - _StencilRefDistortionVec: 4 + - _StencilRefGBuffer: 2 + - _StencilRefMV: 32 + - _StencilWriteMask: 6 + - _StencilWriteMaskDepth: 9 + - _StencilWriteMaskDistortionVec: 4 + - _StencilWriteMaskGBuffer: 15 + - _StencilWriteMaskMV: 41 + - _SubsurfaceMask: 1 + - _SupportDecals: 1 + - _SurfaceType: 1 + - _TexWorldScale: 1 + - _TexWorldScaleEmissive: 1 + - _Thickness: 1 + - _TransmissionEnable: 1 + - _TransmissionMask: 1 + - _TransparentBackfaceEnable: 0 + - _TransparentCullMode: 2 + - _TransparentDepthPostpassEnable: 0 + - _TransparentDepthPrepassEnable: 0 + - _TransparentSortPriority: 0 + - _TransparentWritingMotionVec: 0 + - _TransparentZWrite: 1 + - _UVBase: 0 + - _UVDetail: 0 + - _UVEmissive: 0 + - _UseEmissiveIntensity: 0 + - _UseShadowThreshold: 0 + - _ZTestDepthEqualForOpaque: 4 + - _ZTestGBuffer: 4 + - _ZTestModeDistortion: 4 + - _ZTestTransparent: 4 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0} + - _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0} + - _EmissionColor: {r: 1, g: 1, b: 1, a: 1} + - _EmissiveColor: {r: 0, g: 0, b: 0, a: 1} + - _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1} + - _InvPrimScale: {r: 1, g: 1, b: 0, a: 0} + - _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _SpecularColor: {r: 1, g: 1, b: 1, a: 1} + - _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0} + - _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1} + - _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMask: {r: 1, g: 0, b: 0, a: 0} + - _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat.meta new file mode 100644 index 00000000000..73ca9c2b61c --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/SphereMaterialTranspWritesDepth.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c0725431a233e9e4cb2ac21116a04505 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset new file mode 100644 index 00000000000..1a6fff7c7f7 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset @@ -0,0 +1,15 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: d7fd9488000d3734a9e00ee676215985, type: 3} + m_Name: Volume + m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::UnityEngine.Rendering.VolumeProfile + components: [] diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset.meta b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset.meta new file mode 100644 index 00000000000..f190104cf19 --- /dev/null +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha/Volume.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 36b37cc0d34d87649b49143e55b76a95 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs index f711cdeda78..03b71fd3f10 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/PostProcessing.cs @@ -125,17 +125,17 @@ public PostProcessingTests(GpuResidentDrawerContext grdContext) : base(grdContex RuntimePlatform.WindowsEditor )] [IgnoreGraphicsTest( - "^(?!.*(4088_DRS-DLSS-Hardware|4089_DRS-DLSS-Software|4090_DRS-Hardware|4096_DRS-TAAU-Hardware|4100_DRS-STP-Hardware|4102_DRS-CAS-AfterPost|4103_DRS-DLSS-AfterPost|4104_DRS-STP-AfterPost|4106_DRS-TAAU-AfterPost|4107_DRS-FSR2-Hardware|4109_DRS-FSR2-AfterPost|4110_DRS-FSR2-With-CustomPass|4111_DRS-DLSS-With-CustomPass)).*", + "^(?!.*(4088_DRS-DLSS-Hardware|4089_DRS-DLSS-Software|4090_DRS-Hardware|4096_DRS-TAAU-Hardware|4100_DRS-STP-Hardware|4102_DRS-CAS-AfterPost|4103_DRS-DLSS-AfterPost|4104_DRS-STP-AfterPost|4106_DRS-TAAU-AfterPost|4107_DRS-FSR2-Hardware|4109_DRS-FSR2-AfterPost|4110_DRS-FSR2-With-CustomPass|4111_DRS-DLSS-With-CustomPass|4112_AlphaUpscaling-FP16Alpha)).*", "Upscaler-only job — non-upscaler tests excluded when ENABLE_UPSCALER_FRAMEWORK is defined", UpscalerFrameworkContext.UpscalerFrameworkEnabled )] [TestNotSupportedOn( - "4011|4013|4014|4038|4060|4061|4099|4100", + "4011|4013|4014|4038|4060|4061|4099|4100|4112", "Not XR compatible", StereoRenderingContext.StereoEnabled )] [TestNotSupportedOn( - "4011|4013|4014|4038|4060|4061|4099|4100", + "4011|4013|4014|4038|4060|4061|4099|4100|4112", "Not XR compatible", XrDevice.Any )] public IEnumerator GraphicsTest(SceneGraphicsTestCase testCase) diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset b/Tests/SRPTests/Projects/HDRP_Tests/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset index 47ceaca6cb5..93afd2118e6 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset @@ -215,6 +215,7 @@ MonoBehaviour: - rid: 6535566473957998597 - rid: 6535566473957998598 - rid: 7182773092123672577 + - rid: 7830723193898795008 m_RuntimeSettings: m_List: [] renderingLayerNames: @@ -959,3 +960,7 @@ MonoBehaviour: m_EmissiveTriangleRemovalComputeShader: {fileID: 7200000, guid: 3d386645a85b4e758a7b7eb1bf87fa24, type: 3} m_EstimationComputeShader: {fileID: -6772857160820960102, guid: 94a39d12848d8d64ca962a72b74e7c50, type: 3} m_EstimationRayTracingShader: {fileID: -5126288278712620388, guid: 94a39d12848d8d64ca962a72b74e7c50, type: 3} + - rid: 7830723193898795008 + type: {class: AlphaUpscaler/RuntimeResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} + data: + m_AlphaUpscaleCS: {fileID: 7200000, guid: f10c23179af641eea368ee165b2e97cf, type: 3} diff --git a/Tests/SRPTests/Projects/HDRP_Tests/ProjectSettings/EditorBuildSettings.asset b/Tests/SRPTests/Projects/HDRP_Tests/ProjectSettings/EditorBuildSettings.asset index 0bd9ea8bebb..b41af613246 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/ProjectSettings/EditorBuildSettings.asset +++ b/Tests/SRPTests/Projects/HDRP_Tests/ProjectSettings/EditorBuildSettings.asset @@ -755,6 +755,9 @@ EditorBuildSettings: - enabled: 1 path: Assets/GraphicTests/Scenes/4x_PostProcessing/4109_DRS-FSR2-AfterPost.unity guid: cbd1f7bf59ae04b46afbfcb1188b43b4 + - enabled: 1 + path: Assets/GraphicTests/Scenes/4x_PostProcessing/4112_AlphaUpscaling-FP16Alpha.unity + guid: 861fa82a1b434385a3bf6f3536540712 - enabled: 1 path: Assets/GraphicTests/Scenes/5x_SkyAndFog/5001_Fog_FogFallback.unity guid: d04c39af67e5e18449a44f6a7778862f diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/ForwardRenderer.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/ForwardRenderer.asset index 9f38699a3bf..8816ce8ce6c 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/ForwardRenderer.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/ForwardRenderer.asset @@ -188,7 +188,8 @@ MonoBehaviour: - {fileID: -3335404936333121951} - {fileID: -6013470097145452660} - {fileID: -3626063803437354403} - m_RendererFeatureMap: a53e77578376031beeb81c22f96decc1b449cb42e29eab32e724dd8896132ae9aa54f039e62662935813bc18adacf219a61d2aa0fd28d0fe61a6c7d3e142b6d18c2736b0cedc8bac5df236b72ea2adcd + - {fileID: 2833333333333333333} + m_RendererFeatureMap: a53e77578376031beeb81c22f96decc1b449cb42e29eab32e724dd8896132ae9aa54f039e62662935813bc18adacf219a61d2aa0fd28d0fe61a6c7d3e142b6d18c2736b0cedc8bac5df236b72ea2adcd55559bafa7055227 m_UseNativeRenderPass: 0 postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} xrSystemData: {fileID: 11400000, guid: 60e1133243b97e347b653163a8c01b64, type: 2} @@ -294,9 +295,29 @@ MonoBehaviour: passIndex: 0 bindDepthStencilAttachment: 0 m_Version: 1 +--- !u!114 &2833333333333333333 +MonoBehaviour: + m_ObjectHideFlags: 1 + 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: b00045f12942b46c698459096c89274e, type: 3} + m_Name: 283DisplayAlpha + m_EditorClassIdentifier: + m_Active: 0 + injectionPoint: 600 + fetchColorBuffer: 1 + requirements: 0 + passMaterial: {fileID: 2100000, guid: 0bc87505314942309c92f5f08614e5ad, type: 2} + passIndex: 0 + bindDepthStencilAttachment: 0 + m_Version: 1 --- !u!114 &3651186617534335412 MonoBehaviour: - m_ObjectHideFlags: 0 + m_ObjectHideFlags: 1 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset new file mode 100644 index 00000000000..0ccb329b5b6 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset @@ -0,0 +1,192 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8662253974725994463 +MonoBehaviour: + m_ObjectHideFlags: 1 + 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: 03be459180a06974d8583254adb17471, type: 3} + m_Name: STPOptions + m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::STPOptions + m_UpscalerName: Spatial-Temporal Post-Processing + m_InjectionPoint: 0 + m_ResolutionMode: 0 + m_EnableReactiveMaskPass: 0 + m_ReactiveMaskUseComponentMax: 0 + m_ReactiveMaskScale: 1 + m_ApplyReactiveMaskThreshold: 0 + m_ReactiveMaskThreshold: 0.2 + m_ReactiveMaskBinaryValue: 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: bf2edee5c58d82540a51f03df9d42094, type: 3} + m_Name: URP_Asset_UpScaling_STP_Alpha_NoHDR + m_EditorClassIdentifier: + k_AssetVersion: 13 + k_AssetPreviousVersion: 13 + m_RendererType: 1 + m_RendererData: {fileID: 0} + m_RendererDataList: + - {fileID: 11400000, guid: f59607d3476b54858a594ea904187fb5, type: 2} + m_DefaultRendererIndex: 0 + m_RequireDepthTexture: 1 + m_RequireOpaqueTexture: 1 + m_OpaqueDownsampling: 1 + m_SupportsTerrainHoles: 0 + m_SupportsHDR: 0 + m_HDRColorBufferPrecision: 0 + m_MSAA: 1 + m_RenderScale: 0.5 + m_UpscalingFilter: 4 + m_SelectedUpscalerName: Spatial-Temporal Post-Processing + m_UpscalerOptions: + - {fileID: -8662253974725994463} + - {fileID: 3746925265284549404} + m_FsrOverrideSharpness: 0 + m_FsrSharpness: 0.92 + m_EnableLODCrossFade: 0 + m_LODCrossFadeDitheringType: 1 + m_ShEvalMode: 0 + m_LightProbeSystem: 0 + m_ProbeVolumeMemoryBudget: 1024 + m_ProbeVolumeBlendingMemoryBudget: 128 + m_SupportProbeVolumeGPUStreaming: 0 + m_SupportProbeVolumeDiskStreaming: 0 + m_SupportProbeVolumeScenarios: 0 + m_SupportProbeVolumeScenarioBlending: 0 + m_ProbeVolumeSHBands: 1 + m_MainLightRenderingMode: 1 + m_MainLightShadowsSupported: 0 + m_MainLightShadowmapResolution: 2048 + m_AdditionalLightsRenderingMode: 0 + m_AdditionalLightsPerObjectLimit: 8 + m_AdditionalLightShadowsSupported: 0 + m_AdditionalLightsShadowmapResolution: 512 + m_AdditionalLightsShadowResolutionTierLow: 128 + m_AdditionalLightsShadowResolutionTierMedium: 256 + m_AdditionalLightsShadowResolutionTierHigh: 512 + m_ReflectionProbeBlending: 0 + m_ReflectionProbeBoxProjection: 0 + m_ReflectionProbeAtlas: 0 + m_ShadowDistance: 56 + m_ShadowCascadeCount: 4 + m_Cascade2Split: 0.25 + m_Cascade3Split: {x: 0.154, y: 0.478} + m_Cascade4Split: {x: 0.067, y: 0.2, z: 0.467} + m_CascadeBorder: 0.1 + m_ShadowDepthBias: 1 + m_ShadowNormalBias: 1 + m_AnyShadowsSupported: 1 + m_SoftShadowsSupported: 1 + m_ConservativeEnclosingSphere: 0 + m_NumIterationsEnclosingSphere: 64 + m_SoftShadowQuality: 2 + m_AdditionalLightsCookieResolution: 2048 + m_AdditionalLightsCookieFormat: 3 + m_UseSRPBatcher: 1 + m_SupportsDynamicBatching: 0 + m_MixedLightingSupported: 0 + m_SupportsLightCookies: 0 + m_SupportsLightLayers: 0 + m_StoreActionsOptimization: 0 + m_UseAdaptivePerformance: 1 + m_ColorGradingMode: 0 + m_ColorGradingLutSize: 32 + m_AllowPostProcessAlphaOutput: 1 + m_UseFastSRGBLinearConversion: 0 + m_SupportDataDrivenLensFlare: 1 + m_SupportScreenSpaceLensFlare: 1 + m_GPUResidentDrawerMode: 0 + m_SmallMeshScreenPercentage: 0 + m_ShadowSmallMeshScreenPercentages: {x: 0, y: 0, z: 0, w: 0} + m_GPUResidentDrawerEnableOcclusionCullingInCameras: 0 + m_ShadowType: 0 + m_LocalShadowsSupported: 1 + m_LocalShadowsAtlasResolution: 512 + m_MaxPixelLights: 4 + m_ShadowAtlasResolution: 2048 + m_VolumeFrameworkUpdateMode: 0 + m_VolumeProfile: {fileID: 0} + apvScenesData: + obsoleteSceneBounds: + m_Keys: [] + m_Values: [] + obsoleteHasProbeVolumes: + m_Keys: [] + m_Values: + m_PrefilteringModeMainLightShadows: 2 + m_PrefilteringModeAdditionalLight: 0 + m_PrefilteringModeAdditionalLightShadows: 1 + m_PrefilterXRKeywords: 1 + m_PrefilteringModeForwardPlus: 0 + m_PrefilteringModeDeferredRendering: 1 + m_PrefilteringModeScreenSpaceOcclusion: 0 + m_PrefilteringModeScreenSpaceReflection: 1 + m_PrefilterWriteSmoothness: 1 + m_PrefilterDebugKeywords: 1 + m_PrefilterWriteRenderingLayers: 1 + m_PrefilterHDROutput: 1 + m_PrefilterAlphaOutput: 0 + m_PrefilterSSAODepthNormals: 1 + m_PrefilterSSAOSourceDepthLow: 1 + m_PrefilterSSAOSourceDepthMedium: 1 + m_PrefilterSSAOSourceDepthHigh: 1 + m_PrefilterSSAOInterleaved: 1 + m_PrefilterSSAOBlueNoise: 1 + m_PrefilterSSAOSampleCountLow: 1 + m_PrefilterSSAOSampleCountMedium: 1 + m_PrefilterSSAOSampleCountHigh: 1 + m_PrefilterDBufferMRT1: 1 + m_PrefilterDBufferMRT2: 1 + m_PrefilterDBufferMRT3: 1 + m_PrefilterSoftShadowsQualityLow: 0 + m_PrefilterSoftShadowsQualityMedium: 0 + m_PrefilterSoftShadowsQualityHigh: 0 + m_PrefilterSoftShadows: 0 + m_PrefilterScreenCoord: 0 + m_PrefilterScreenSpaceIrradiance: 0 + m_PrefilterNativeRenderPass: 1 + m_PrefilterUseLegacyLightmaps: 0 + m_PrefilterBicubicLightmapSampling: 0 + m_PrefilterReflectionProbeRotation: 0 + m_PrefilterReflectionProbeBlending: 0 + m_PrefilterReflectionProbeBoxProjection: 0 + m_PrefilterReflectionProbeAtlas: 0 + m_PrefilterPointSamplingUpsampling: 0 + m_PrefilterExposure: 0 + m_Light2DPrefilteringMode: 0 + m_Light2DKeptVariantCombos: [] + m_ShaderVariantLogLevel: 0 + m_ShadowCascades: 3 + m_Textures: + blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3} + bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3} +--- !u!114 &3746925265284549404 +MonoBehaviour: + m_ObjectHideFlags: 1 + 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: 1b516656c1bb6634192a33e967e54491, type: 3} + m_Name: FSR2Options + m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::FSR2Options + m_UpscalerName: FidelityFX Super Resolution 2 + m_InjectionPoint: 0 + m_ResolutionMode: 0 + m_FSR2QualityMode: 0 + m_EnableSharpening: 0 + m_Sharpness: 0.92 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset.meta new file mode 100644 index 00000000000..fe08efaa958 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/URP_Asset_UpScaling_STP_Alpha_NoHDR.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ad10d5bd7127ec46900338a5b6cd5c5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity new file mode 100644 index 00000000000..3e9e0f97e6f --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec4d321cff411b0f4467900d55a89e31aea6b5ba84246b5e62388c547f68aef0 +size 19955 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity.meta new file mode 100644 index 00000000000..ab031ba182e --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: be536423526b4dd4aa210e86c248ac80 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling.meta new file mode 100644 index 00000000000..922209241ee --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a6e6150900025b7419a0d71e7159943f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat new file mode 100644 index 00000000000..700a98ea46c --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat @@ -0,0 +1,29 @@ +%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: 283_DisplayAlpha + m_Shader: {fileID: 4800000, guid: 267738cafd8c497ba7512f69d36bd77a, 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: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: [] + m_Ints: [] + m_Floats: [] + m_Colors: [] + m_BuildTextureStacks: [] diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat.meta new file mode 100644 index 00000000000..ae707f44706 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0bc87505314942309c92f5f08614e5ad +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader new file mode 100644 index 00000000000..8f2ab2a513e --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader @@ -0,0 +1,36 @@ +Shader "Hidden/Test/283_DisplayAlpha" +{ + SubShader + { + Tags + { + "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" + } + LOD 100 + + Pass + { + Name "DisplayAlpha" + ZTest Always + ZWrite Off + Cull Off + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment Fragment + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + + // Visualizes the alpha channel of the camera color as grayscale, so the graphics + // test compares the upscaled alpha instead of the composited color. + half4 Fragment(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + half alpha = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_PointClamp, input.texcoord.xy).a; + return half4(alpha.xxx, 1); + } + ENDHLSL + } + } +} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader.meta new file mode 100644 index 00000000000..5097d523505 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/283_DisplayAlpha.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 267738cafd8c497ba7512f69d36bd77a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat new file mode 100644 index 00000000000..525133c4c8a --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat @@ -0,0 +1,147 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2240418698902554757 +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: + version: 11 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MatDiscardGreen + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHATEST_ON + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - MOTIONVECTORS + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: b2cde6ec2e345ab44bf0fc256c819fad, type: 3} + 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: 2800000, guid: b2cde6ec2e345ab44bf0fc256c819fad, type: 3} + 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: 1 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 0 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossinessSource: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _ScreenSpaceReflectionsContributeTransparent: 1 + - _Shininess: 0 + - _Smoothness: 0.685 + - _SmoothnessSource: 0 + - _SmoothnessTextureChannel: 1 + - _SpecSource: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 5 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 0, g: 1, b: 0, a: 1} + - _Color: {r: 0, g: 1, b: 0, 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/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat.meta new file mode 100644 index 00000000000..69da709e752 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatDiscardGreen.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2d86341ffbb979f4a867545bc32ecec6 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat new file mode 100644 index 00000000000..edc607eda09 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat @@ -0,0 +1,136 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3963434338821335712 +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: + version: 11 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MatOpaqueRed + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, 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: + RenderType: Opaque + 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 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 0, b: 0, a: 1} + - _Color: {r: 1, g: 0, b: 0, 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/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat.meta new file mode 100644 index 00000000000..11feac4e2b6 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatOpaqueRed.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c5508f84bea0f274f9ba8af7072ec6ae +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat new file mode 100644 index 00000000000..a1dc5996e76 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat @@ -0,0 +1,140 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-1414899553356948808 +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: + version: 11 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: MatTransparentBlue + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - MOTIONVECTORS + - DepthOnly + - SHADOWCASTER + 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: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _WorkflowMode: 1 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 0, g: 0, b: 1, a: 0.37254903} + - _Color: {r: 0, g: 0, b: 1, a: 0.37254903} + - _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/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat.meta new file mode 100644 index 00000000000..31baefd1593 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/MatTransparentBlue.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: af310f5e2b32bc44c8e1cea42b9d97f4 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png new file mode 100644 index 00000000000..613002df862 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a52ce7723cc34779583eefe56e5d4fd97460f6934ea23b8f5fbe06fcac9a7935 +size 335 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png.meta new file mode 100644 index 00000000000..31fe78eeada --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/283_AlphaUpscaling/checkerboard_alpha0.png.meta @@ -0,0 +1,154 @@ +fileFormatVersion: 2 +guid: b2cde6ec2e345ab44bf0fc256c819fad +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: iOS + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: OSXUniversal + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/EditorBuildSettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/EditorBuildSettings.asset index 4cd763bdd88..7bdaf5370d5 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/EditorBuildSettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/EditorBuildSettings.asset @@ -191,6 +191,9 @@ EditorBuildSettings: - enabled: 1 path: Assets/Scenes/282_AlphaOutput_RGBA8_Stack_RenderScale_Up_FSR.unity guid: 33738bb1cfc644b2882c51fa88268a4f + - enabled: 1 + path: Assets/Scenes/283_AlphaOutput_RGBA8_RenderScale_Up_STP.unity + guid: febbdb38e483470cb3c6b69d4d9704dc - enabled: 1 path: Assets/Scenes/284_CameraColorSwap_HalfRes_RT.unity guid: a3f52c81d94e4b7f8a1c6d2e0b9f4712 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset index f392b10c1ec..15bf0e9a247 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset @@ -960,6 +960,59 @@ QualitySettings: terrainFadeLength: 5 terrainMaxTrees: 50 excludedTargetPlatforms: [] + - serializedVersion: 5 + name: 18-URP_Asset_UpScaling_STP_Alpha_NoHDR + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + skinWeights: 4 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 2 + antiAliasing: 0 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + useLegacyDetailDistribution: 1 + adaptiveVsync: 0 + vSyncCount: 1 + realtimeGICPUUsage: 25 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 2 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 11400000, guid: 7ad10d5bd7127ec46900338a5b6cd5c5, type: 2} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] m_TextureMipmapLimitGroupNames: [] m_PerPlatformDefaultQuality: Android: 0 From 4c7e1947f9b9cdf3d7b7d5e20830f7d7a1527e9c Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Fri, 18 Sep 2026 23:25:31 +0000 Subject: [PATCH 021/192] [Port] [6000.7] Reproject outer motion vectors for quad view inner pass --- .../Runtime/Passes/XRDepthMotionPass.cs | 103 ++++++++++++++++++ .../Shaders/XR/XRMotionVector.shader | 84 ++++++++++++++ 2 files changed, 187 insertions(+) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs index 5e5772472e9..a836309af4d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs @@ -19,6 +19,9 @@ public class XRDepthMotionPass : ScriptableRenderPass // ObjectMotionVectorFallback and the material XRMotionVectors passes (WriteMask 1, Ref 1). private const uint k_ObjectMotionMarkerMask = 0x1; private static readonly int k_XRDepthTextureUVScale = Shader.PropertyToID("_XRDepthTextureUVScale"); + private static readonly int k_QuadViewMVTex = Shader.PropertyToID("_QuadViewMVTex"); + private static readonly int k_QuadViewUVScales = Shader.PropertyToID("_QuadViewUVScales"); + private static readonly int k_QuadViewUVOffsets = Shader.PropertyToID("_QuadViewUVOffsets"); private RTHandle m_XRMotionVectorColor; private TextureHandle xrMotionVectorColor; private RTHandle m_XRMotionVectorDepth; @@ -26,6 +29,12 @@ public class XRDepthMotionPass : ScriptableRenderPass private bool m_XRSpaceWarpRightHandedNDC; private LayerMask m_transparentlayerMask; + // Store a stable RTHandle (separate from m_XRMotionVectorColor) that is never mutated by the inner pass's ImportXRMotionColorAndDepth call, + // so the render graph can resolve it to the correct native texture at execution time. + private RTHandle m_QuadViewOuterMV; + // Store outer dimensions; symmetric projection can give the outer swapchain a FoV-adjusted width that differs from the inner + private RenderTargetInfo m_QuadViewOuterMVImportInfo; + /// /// Creates a new XRDepthMotionPass instance. /// @@ -61,6 +70,12 @@ private class PassData internal Vector2 uvScale; } + private class ReprojectionPassData + { + internal TextureHandle outerMVSrc; + internal TextureHandle outerDepthSrc; + } + /// View projection data private Matrix4x4[] m_StagingMatrixArray = new Matrix4x4[k_XRViewCountPerPass]; // Staging matrix to avoid allocating memory every frame when setting shader properties. private Matrix4x4[] m_PreviousStagingMatrixArray = new Matrix4x4[k_XRViewCountPerPass]; // Staging matrix to avoid allocating memory every frame when setting shader properties. @@ -254,6 +269,56 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) // First, import XR motion color and depth targets into the RenderGraph ImportXRMotionColorAndDepth(renderGraph, cameraData); + // Skipped under Temporal Pixel Synthesis because reprojection does not write the stencil + // bits the TPS compositor uses to exclude transparents from temporal reuse. + if (!cameraData.xr.isTemporalPixelSynthesisActive) + { + // For Quad View inner pass: reproject the outer MV texture rather than re-rendering all objects + if (cameraData.xr.isQuadViewInnerPass) + { + if (m_QuadViewOuterMV != null) + { + RecordReprojectionPass(renderGraph, cameraData); + return; + } + } + else if (cameraData.xr.xrLayoutType == XRLayoutType.TwoPassQuadViews) + { + // Outer pass: capture the MV target for the inner reprojection to read + var outerTargetId = cameraData.xr.motionVectorRenderTarget; + if (m_QuadViewOuterMV == null) + m_QuadViewOuterMV = RTHandles.Alloc(outerTargetId); + else if (m_QuadViewOuterMV.nameID != outerTargetId) + RTHandleStaticHelpers.SetRTHandleUserManagedWrapper(ref m_QuadViewOuterMV, outerTargetId); + + // Save dimensions; symmetric projection can give the outer a different width than the inner + var desc = cameraData.xr.motionVectorRenderTargetDesc; + m_QuadViewOuterMVImportInfo = new RenderTargetInfo + { + width = desc.width, + height = desc.height, + volumeDepth = desc.volumeDepth, + msaaSamples = desc.msaaSamples, + format = desc.graphicsFormat + }; + + // m_XRMotionVectorColor/Depth would be mutated in-place when the inner pass calls ImportXRMotionColorAndDepth, corrupting the handles. + // Instead, re-import via separate m_QuadViewOuterMV so the outer pass's attachments resolve to the correct native texture at execution time. + var outerAttachmentParams = new ImportResourceParams + { + // Stencil must be cleared to 0 each frame for Pass 0's stencil test + clearOnFirstUse = true, + clearColor = Color.black, + discardOnLastUse = false + }; + xrMotionVectorColor = renderGraph.ImportTexture(m_QuadViewOuterMV, m_QuadViewOuterMVImportInfo, outerAttachmentParams); + var outerDepthInfo = m_QuadViewOuterMVImportInfo; + outerDepthInfo.format = desc.depthStencilFormat; + xrMotionVectorDepth = renderGraph.ImportTexture(m_QuadViewOuterMV, outerDepthInfo, outerAttachmentParams); + + } + } + // These flags are still required in SRP or the engine won't compute previous model matrices... // If the flag hasn't been set yet on this camera, motion vectors will skip a frame. cameraData.camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth; @@ -365,6 +430,43 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) }); } } + + private void RecordReprojectionPass(RenderGraph renderGraph, UniversalCameraData cameraData) + { + // The outer and inner cameras run in separate RecordAndExecuteRenderGraph executions so TextureHandles cannot be shared across them. + // Import fresh read-only handles for the outer MV within the inner pass execution. + var importParams = new ImportResourceParams { clearOnFirstUse = false, discardOnLastUse = false }; + var outerMVHandle = renderGraph.ImportTexture(m_QuadViewOuterMV, m_QuadViewOuterMVImportInfo, importParams); + var outerDepthImportInfo = m_QuadViewOuterMVImportInfo; + outerDepthImportInfo.format = cameraData.xr.motionVectorRenderTargetDesc.depthStencilFormat; + var outerDepthHandle = renderGraph.ImportTexture(m_QuadViewOuterMV, outerDepthImportInfo, importParams); + + var uvScales = cameraData.xr.uvScales; + var uvOffsets = cameraData.xr.uvOffsets; + + using (var builder = renderGraph.AddRasterRenderPass( + "XR MotionVector QuadView Reprojection", out var passData, base.profilingSampler)) + { + builder.SetRenderAttachment(xrMotionVectorColor, 0, AccessFlags.Write); + builder.SetRenderAttachmentDepth(xrMotionVectorDepth, AccessFlags.Write); + builder.UseTexture(outerMVHandle, AccessFlags.Read); + builder.UseTexture(outerDepthHandle, AccessFlags.Read); + builder.AllowGlobalStateModification(true); + + passData.outerMVSrc = outerMVHandle; + passData.outerDepthSrc = outerDepthHandle; + + builder.SetRenderFunc((ReprojectionPassData data, RasterGraphContext context) => + { + context.cmd.SetGlobalTexture(k_QuadViewMVTex, data.outerMVSrc); + context.cmd.SetGlobalTexture(k_XRDepthTextureNameID, data.outerDepthSrc, RenderTextureSubElement.Depth); + context.cmd.SetGlobalVector(k_QuadViewUVScales, uvScales); + context.cmd.SetGlobalVector(k_QuadViewUVOffsets, uvOffsets); + context.cmd.DrawProcedural(Matrix4x4.identity, m_XRMotionVectorMaterial, shaderPass: 2, + MeshTopology.Triangles, 3, 1); + }); + } + } #endregion private void ResetMotionData() @@ -413,6 +515,7 @@ public void Dispose() { m_XRMotionVectorColor?.Release(); m_XRMotionVectorDepth?.Release(); + m_QuadViewOuterMV?.Release(); CoreUtils.Destroy(m_XRMotionVectorMaterial); } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader b/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader index f619e0819da..1d242ac62e9 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader @@ -213,6 +213,90 @@ Shader "Hidden/Universal Render Pipeline/XR/XRMotionVector" } ENDHLSL } + + // Pass 2: Scale outer MVs into inner (foveal) view space for Quad View. + // Inner and outer views share the same eye; only FoV differs, so the transform is a constant per-axis scale with UV crop. + // Replaces the full inner XRDepthMotionPass. + Pass + { + Name "XR MotionVector QuadView Reprojection" + + Cull Off + ZWrite On + ZTest Always + ColorMask RGBA + + HLSLPROGRAM + #pragma target 3.5 + + #pragma vertex Vert + #pragma fragment Frag + + // ------------------------------------- + // Includes + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + // ------------------------------------- + // Constants + float4 _QuadViewUVScales; // inner-to-outer UV scale, xy = left eye, zw = right eye + float4 _QuadViewUVOffsets; // inner-to-outer UV offset, xy = left eye, zw = right eye + + TEXTURE2D_X(_QuadViewMVTex); + SAMPLER(sampler_QuadViewMVTex); + TEXTURE2D_X(_XRDepthTexture); + SAMPLER(sampler_XRDepthTexture); + + // ------------------------------------- + // Structs + struct Attributes + { + uint vertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 position : SV_POSITION; + float2 uv : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + }; + + // ------------------------------------- + // Vertex + Varyings Vert(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + output.position = GetFullScreenTriangleVertexPosition(input.vertexID, 1 - UNITY_NEAR_CLIP_VALUE); + output.uv = GetFullScreenTriangleTexCoord(input.vertexID); + return output; + } + + // ------------------------------------- + // Fragment + float4 Frag(Varyings input, out float outDepth : SV_Depth) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uvScale = unity_StereoEyeIndex == 0 ? _QuadViewUVScales.xy : _QuadViewUVScales.zw; + float2 uvOffset = unity_StereoEyeIndex == 0 ? _QuadViewUVOffsets.xy : _QuadViewUVOffsets.zw; + + // Remap inner UV to the outer MV texture. + // uvOffset.y uses (1 - uvScale.y - uvOffset.y) because the OpenXR Vulkan projection inverts the sign fed to ExtractFrustumBoundsFromProjection + // causing uvOffset.y to encode the top-edge distance instead of the bottom-edge distance required for BottomLeft UV sampling. + float2 outerUV = float2( + input.uv.x * uvScale.x + uvOffset.x, + input.uv.y * uvScale.y + (1.0 - uvScale.y - uvOffset.y) + ); + + outDepth = SAMPLE_TEXTURE2D_X(_XRDepthTexture, sampler_XRDepthTexture, outerUV).x; + + float4 outerMV = SAMPLE_TEXTURE2D_X(_QuadViewMVTex, sampler_QuadViewMVTex, outerUV); + return float4(outerMV.x / uvScale.x, outerMV.y / uvScale.y, outerMV.z, 0); + } + ENDHLSL + } } Fallback Off } From 3b0aabec8c3c5d3fa0cb344cd648b1b4b49be132 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Fri, 18 Sep 2026 23:25:31 +0000 Subject: [PATCH 022/192] [Port] [6000.7] HDRP SG uv4 fix. --- .../ShaderPass/MotionVectorVertexShaderCommon.hlsl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl index 842e2b06f45..701cd52c911 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl @@ -4,9 +4,17 @@ // Available semantic start from TEXCOORD4 struct AttributesPass { +#if defined(ATTRIBUTES_NEED_TEXCOORD4) + float4 previousPositionOS : TEXCOORD4; // SG declared TexCoord4 as float4 +#else float3 previousPositionOS : TEXCOORD4; // Contain previous transform position (in case of skinning for example) +#endif #if defined (_ADD_PRECOMPUTED_VELOCITY) + #if defined(ATTRIBUTES_NEED_TEXCOORD5) + float4 precomputedVelocity : TEXCOORD5; // SG declared TexCoord5 as float4 + #else float3 precomputedVelocity : TEXCOORD5; // Add Precomputed Velocity (Alembic computes velocities on runtime side). + #endif #endif }; @@ -149,7 +157,7 @@ VaryingsType MotionVectorVS_Internal(VaryingsType varyingsType, AttributesMesh i effectivePositionOS = inputMesh.positionOS; //no skin or morph target in vfx #else bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target - effectivePositionOS = (hasDeformation ? inputPass.previousPositionOS : inputMesh.positionOS); + effectivePositionOS = (hasDeformation ? inputPass.previousPositionOS.xyz : inputMesh.positionOS); #endif // See _TransparentCameraOnlyMotionVectors in HDCamera.cs @@ -223,7 +231,7 @@ VaryingsType MotionVectorVS_Internal(VaryingsType varyingsType, AttributesMesh i #endif #if defined(_ADD_PRECOMPUTED_VELOCITY) - previousMesh.positionOS -= inputPass.precomputedVelocity; + previousMesh.positionOS -= inputPass.precomputedVelocity.xyz; #endif #if defined(HAVE_VFX_MODIFICATION) && VFX_WORLD_SPACE @@ -246,7 +254,7 @@ VaryingsType MotionVectorVS_Internal(VaryingsType varyingsType, AttributesMesh i #endif #if defined(_ADD_PRECOMPUTED_VELOCITY) - effectivePositionOS -= inputPass.precomputedVelocity; + effectivePositionOS -= inputPass.precomputedVelocity.xyz; #endif previousPositionRWS = TransformPreviousObjectToWorld(effectivePositionOS); From 95a0ab9b380cb8c759f7d57a6e807ef748f8c098 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 21 Sep 2026 12:25:06 +0000 Subject: [PATCH 023/192] [Port] [6000.7] [GraphicsTools][RPConverter] Universal Render Pipeline (Universal Renderer) should be the default Target Pipeline (UUM-151492) --- .../2D/Converter/BuiltInToURP2DRenderSettingsConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/2D/Converter/BuiltInToURP2DRenderSettingsConverter.cs b/Packages/com.unity.render-pipelines.universal/Editor/2D/Converter/BuiltInToURP2DRenderSettingsConverter.cs index 7bad0f5893d..5bcbe1460c1 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/2D/Converter/BuiltInToURP2DRenderSettingsConverter.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/2D/Converter/BuiltInToURP2DRenderSettingsConverter.cs @@ -12,7 +12,7 @@ namespace UnityEditor.Rendering.Universal [PipelineConverter("Built-in", "Universal Render Pipeline (2D Renderer)")] [BatchModeConverterClassInfo("BuiltInToURP2D", "RenderSettings2D")] [ElementInfo(Name = "Rendering Settings", - Order = int.MinValue, + Order = int.MinValue + 1, Description = "This converter creates Universal Render Pipeline (URP) assets and corresponding Renderer assets, configuring their settings to match the equivalent settings from the Built-in Render Pipeline.")] class BuiltInToURP2DRenderSettingsConverter : RenderSettingsConverter { From 799366556cb1354b49fcaf70fb3259762fa0d3c1 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 21 Sep 2026 12:25:06 +0000 Subject: [PATCH 024/192] [Port] [6000.7] Avoid OOB GPU accesses in UnifiedRayTracing --- .../Compute/RadeonRays/kernels/bit_histogram.compute | 1 - .../RadeonRays/kernels/block_reduce_part.compute | 8 +++++--- .../Compute/RadeonRays/kernels/block_scan.compute | 12 ++++++++---- .../Compute/RadeonRays/kernels/scatter.compute | 1 - 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute index fd72142b807..d9795eb505d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute @@ -34,7 +34,6 @@ RWStructuredBuffer g_buffer : register(u0); #define KEYS_PER_THREAD 4u groupshared int lds_histograms[NUM_BINS]; -//[RootSignature(ROOT_SIGNATURE)] #pragma kernel BitHistogram [numthreads(GROUP_SIZE, 1, 1)] void BitHistogram( diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute index d170b1fb232..c8b68cfb2f3 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute @@ -20,6 +20,8 @@ THE SOFTWARE. // WebGPU has extremely strict uniformity requirements that are incompatible with the current implementation of this shader. #pragma exclude_renderers webgpu +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + uint g_constants_num_keys; uint g_constants_input_keys_offset; @@ -81,11 +83,9 @@ int BlockReduce(int key, uint lidx) #endif } -//[RootSignature(ROOT_SIGNATURE)] #pragma kernel BlockReducePart [numthreads(GROUP_SIZE, 1, 1)] void BlockReducePart( - in uint gidx: SV_DispatchThreadID, in uint lidx: SV_GroupThreadID, in uint bidx: SV_GroupID) { @@ -96,7 +96,9 @@ void BlockReducePart( for (uint i = 0; i < KEYS_PER_THREAD; ++i) { uint load_index = range_begin + i * GROUP_SIZE + lidx; - thread_sum += (load_index < g_constants_num_keys) ? g_buffer[g_constants_input_keys_offset + load_index] : 0; + UNITY_OUT_OF_BOUNDS_BRANCH + if (load_index < g_constants_num_keys) + thread_sum += g_buffer[g_constants_input_keys_offset + load_index]; } // Reduce sums diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute index c35d7e13cda..8758ba16713 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute @@ -20,6 +20,8 @@ THE SOFTWARE. // WebGPU has extremely strict uniformity requirements that are incompatible with the current implementation of this shader. #pragma exclude_renderers webgpu +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #pragma multi_compile __ ADD_PART_SUM uint g_constants_num_keys; @@ -112,15 +114,13 @@ int BlockScan(int key, uint lidx) #endif } -//[RootSignature(ROOT_SIGNATURE)] #pragma kernel BlockScanAdd [numthreads(GROUP_SIZE, 1, 1)] void BlockScanAdd( - in uint gidx: SV_DispatchThreadID, in uint lidx: SV_GroupThreadID, in uint bidx: SV_GroupID) { - uint i = 0; // Loop counter. + uint i; // Loop counter. // Perform coalesced load into LDS uint range_begin = bidx * GROUP_SIZE * KEYS_PER_THREAD; @@ -131,7 +131,11 @@ void BlockScanAdd( uint col = (i * GROUP_SIZE + lidx) / KEYS_PER_THREAD; uint row = (i * GROUP_SIZE + lidx) % KEYS_PER_THREAD; - lds_loads[row][col] = (load_index < g_constants_num_keys) ? g_buffer[g_constants_input_keys_offset + load_index] : 0; + UNITY_OUT_OF_BOUNDS_BRANCH + if (load_index < g_constants_num_keys) + lds_loads[row][col] = g_buffer[g_constants_input_keys_offset + load_index]; + else + lds_loads[row][col] = 0; } GroupMemoryBarrierWithGroupSync(); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute index 3d2bc469e1a..04a9ace9135 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute @@ -126,7 +126,6 @@ int BlockScan(int key, uint lidx) #endif } -//[RootSignature(ROOT_SIGNATURE)] #pragma kernel Scatter [numthreads(GROUP_SIZE, 1, 1)] void Scatter( From 007d24439116f76bd192da12b9d4802e36d78529 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 21 Sep 2026 12:25:06 +0000 Subject: [PATCH 025/192] [Port] [6000.7] [UUM-152840] [URP] Fix Surface Cache GI single-consumer exception and drain assert spam --- .../SurfaceCacheEntityChangeBridge.cs | 118 ++++++++-- .../SurfaceCacheGIRendererFeature.cs | 30 ++- .../SurfaceCacheWorldAdapter.cs | 13 +- .../SurfaceCacheEntityChangeBridgeTests.cs | 207 ++++++++++++++++++ ...urfaceCacheEntityChangeBridgeTests.cs.meta | 11 + ...elines.Universal.SurfaceCache.Tests.asmdef | 3 +- 6 files changed, 352 insertions(+), 30 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs create mode 100644 Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs.meta diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheEntityChangeBridge.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheEntityChangeBridge.cs index f3703914a0a..9055c786983 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheEntityChangeBridge.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheEntityChangeBridge.cs @@ -17,29 +17,32 @@ static class SurfaceCacheEntityChangeBridge static bool s_ConsumerRegistered; static bool s_DrainInProgress; static uint s_ConsumerVersion; + // Transforms below this index were retained by an aborted drain and predate any later push. + static int s_RetainedTransformCount; public static bool IsConsumerPresent => s_ConsumerRegistered; // Producers push their full state again when this changes, so a recreated consumer starts complete. public static uint ConsumerVersion => s_ConsumerVersion; - public static void RegisterConsumer() + public static bool TryRegisterConsumer() { if (s_ConsumerRegistered) - throw new InvalidOperationException("SurfaceCacheEntityChangeBridge supports only a single consumer."); + return false; s_ConsumerRegistered = true; s_ConsumerVersion++; s_PendingTransforms = new NativeList(Allocator.Persistent); ClearPending(); + return true; } public static void UnregisterConsumer() { Debug.Assert(s_ConsumerRegistered); - Debug.Assert(!s_DrainInProgress, "UnregisterConsumer during a drain."); s_ConsumerRegistered = false; + s_DrainInProgress = false; ClearPending(); if (s_PendingTransforms.IsCreated) @@ -61,6 +64,7 @@ public static void PushChanged(in SurfaceCacheEntityInstanceRecord record) if (!IsConsumerPresent) return; + DropRetainedTransforms(record.Key); s_PendingChanged[record.Key] = record; } @@ -83,15 +87,15 @@ public static void BeginDrain( Debug.Assert(!s_DrainInProgress, "BeginDrain without a matching EndDrain."); s_DrainInProgress = true; + if (s_PendingChanged.Count != 0 || s_PendingDestroyed.Count != 0) + FoldSupersededTransforms(); + foreach (var record in s_PendingChanged.Values) changed.Add(record); foreach (var key in s_PendingDestroyed) destroyed.Add(key); - if (s_PendingChanged.Count != 0 || s_PendingDestroyed.Count != 0) - DropSupersededTransforms(); - transformChanged = s_PendingTransforms.AsArray(); } @@ -102,15 +106,53 @@ public static void EndDrain() ClearPending(); } - static void DropSupersededTransforms() + public static void AbortDrain() + { + Debug.Assert(s_DrainInProgress, "AbortDrain without a matching BeginDrain."); + s_DrainInProgress = false; + s_RetainedTransformCount = s_PendingTransforms.Length; + } + + // A record push supersedes the retained transforms for its key: they are older, and the fold must not apply them over it. + static void DropRetainedTransforms(in EntityId key) + { + if (s_RetainedTransformCount == 0) + return; + + int kept = 0; + int retained = s_RetainedTransformCount; + for (int i = 0; i < s_PendingTransforms.Length; i++) + { + if (i < s_RetainedTransformCount && s_PendingTransforms[i].Key == key) + { + retained--; + continue; + } + + s_PendingTransforms[kept++] = s_PendingTransforms[i]; + } + + s_PendingTransforms.Length = kept; + s_RetainedTransformCount = retained; + } + + // A record retained by an aborted drain may predate a transform push, so fold the transform in rather than drop it. + static void FoldSupersededTransforms() { int kept = 0; for (int i = 0; i < s_PendingTransforms.Length; i++) { var key = s_PendingTransforms[i].Key; - if (s_PendingChanged.ContainsKey(key) || s_PendingDestroyed.Contains(key)) + if (s_PendingDestroyed.Contains(key)) continue; + if (s_PendingChanged.TryGetValue(key, out var record)) + { + record.LocalToWorld = s_PendingTransforms[i].LocalToWorld; + s_PendingChanged[key] = record; + continue; + } + s_PendingTransforms[kept++] = s_PendingTransforms[i]; } @@ -121,6 +163,7 @@ static void ClearPending() { s_PendingChanged.Clear(); s_PendingDestroyed.Clear(); + s_RetainedTransformCount = 0; if (s_PendingTransforms.IsCreated) s_PendingTransforms.Clear(); @@ -129,36 +172,77 @@ static void ClearPending() sealed class EntityChangeSource : IDisposable { + internal const string k_ContentionError = + "Multiple Surface Cache GI renderer features are loaded, but only one of them can receive entity (ECS) " + + "changes. Entities will be missing from this feature's global illumination until the other features are " + + "removed or their renderer is recreated. GameObject-based renderers are not affected."; + static readonly Unity.Profiling.ProfilerMarker k_CollectMarker = new("SurfaceCache.EntityChangeCollection"); - readonly List _changed = new(); - readonly List _destroyed = new(); + readonly List m_Changed = new(); + readonly List m_Destroyed = new(); + bool m_BridgeAcquired; + bool m_DrainBegun; + bool m_ContentionLogged; - public EntityChangeSource() + bool TryAcquireBridge() { - SurfaceCacheEntityChangeBridge.RegisterConsumer(); + if (!m_BridgeAcquired) + m_BridgeAcquired = SurfaceCacheEntityChangeBridge.TryRegisterConsumer(); + + return m_BridgeAcquired; } public void CollectChanges(SurfaceCacheWorldChangeSet changeSet) { using var _ = k_CollectMarker.Auto(); - _changed.Clear(); - _destroyed.Clear(); - SurfaceCacheEntityChangeBridge.BeginDrain(_changed, _destroyed, out var transformChanged); + if (!TryAcquireBridge()) + { + if (!m_ContentionLogged) + { + m_ContentionLogged = true; + Debug.LogError(k_ContentionError); + } + + return; + } + + m_Changed.Clear(); + m_Destroyed.Clear(); + SurfaceCacheEntityChangeBridge.BeginDrain(m_Changed, m_Destroyed, out var transformChanged); + m_DrainBegun = true; - changeSet.EntityInstanceChangedList = _changed; + changeSet.EntityInstanceChangedList = m_Changed; changeSet.EntityInstanceTransformChangedList = transformChanged; - changeSet.EntityInstanceDestroyedList = _destroyed; + changeSet.EntityInstanceDestroyedList = m_Destroyed; } public void EndCollectChanges() { + if (!m_DrainBegun) + return; + + m_DrainBegun = false; SurfaceCacheEntityChangeBridge.EndDrain(); } + public void AbortCollectChanges() + { + if (!m_DrainBegun) + return; + + m_DrainBegun = false; + SurfaceCacheEntityChangeBridge.AbortDrain(); + } + public void Dispose() { + if (!m_BridgeAcquired) + return; + + AbortCollectChanges(); + m_BridgeAcquired = false; SurfaceCacheEntityChangeBridge.UnregisterConsumer(); } } 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 43849e00ed1..bf897436325 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 @@ -370,17 +370,25 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer { _entityChangeSource.CollectChanges(changeSet.WorldChangeSet); - _worldAdapter.Update( - changeSet.WorldChangeSet, - RenderSettings.ambientMode, - RenderSettings.skybox, - RenderSettings.ambientSkyColor.linear, - RenderSettings.ambientEquatorColor.linear, - RenderSettings.ambientGroundColor.linear, - RenderSettings.ambientIntensity, - _conformToUnityGIFormat, - RenderingLayerMask, - _world); + try + { + _worldAdapter.Update( + changeSet.WorldChangeSet, + RenderSettings.ambientMode, + RenderSettings.skybox, + RenderSettings.ambientSkyColor.linear, + RenderSettings.ambientEquatorColor.linear, + RenderSettings.ambientGroundColor.linear, + RenderSettings.ambientIntensity, + _conformToUnityGIFormat, + RenderingLayerMask, + _world); + } + catch + { + _entityChangeSource.AbortCollectChanges(); + throw; + } _entityChangeSource.EndCollectChanges(); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs index f9faaa68338..ca9f566866e 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs @@ -566,7 +566,18 @@ void AddToWorld(int slot, in TSource source, Mesh mesh, SharedMaterialSet shared ResolveMaterialHandlesAndMasks(world, sharedMaterials, source, inputMats, acquiredMatHandles, acquiredMatIds, masks); var localToWorld = source.LocalToWorld; - _handles[slot] = world.AddInstance(mesh, acquiredMatHandles, masks, localToWorld); + try + { + _handles[slot] = world.AddInstance(mesh, acquiredMatHandles, masks, localToWorld); + } + catch + { + foreach (var matEntityId in acquiredMatIds) + sharedMaterials.Release(matEntityId, world); + _materialScratch.Clear(); + throw; + } + _meshes[slot] = mesh; _localToWorlds[slot] = localToWorld; _inputMaterialIds[slot] = inputMatIds.ToArray(); diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs new file mode 100644 index 00000000000..a96e907f11b --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs @@ -0,0 +1,207 @@ +#if SURFACE_CACHE_SUPPORTED || UNITY_EDITOR + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace UnityEngine.Rendering.Universal.Tests +{ + class SurfaceCacheEntityChangeBridgeTests + { + Mesh m_KeyDonor; + + [SetUp] + public void SetUp() + { + Assume.That(!SurfaceCacheEntityChangeBridge.IsConsumerPresent, + "These tests require exclusive ownership of the SurfaceCacheEntityChangeBridge."); + + m_KeyDonor = new Mesh { name = "SurfaceCacheEntityChangeBridgeTests KeyDonor" }; + } + + [TearDown] + public void TearDown() + { + if (SurfaceCacheEntityChangeBridge.IsConsumerPresent) + SurfaceCacheEntityChangeBridge.UnregisterConsumer(); + + Object.DestroyImmediate(m_KeyDonor); + } + + [Test] + public void EntityChangeSource_BridgeAlreadyTaken_DetachesInsteadOfThrowing() + { + var first = new EntityChangeSource(); + var second = new EntityChangeSource(); + Assert.IsFalse(SurfaceCacheEntityChangeBridge.IsConsumerPresent, "Constructing sources alone should not register a consumer."); + + first.CollectChanges(new SurfaceCacheWorldChangeSet()); + first.EndCollectChanges(); + + SurfaceCacheEntityChangeBridge.PushChanged(MakeRecord()); + + var secondChanges = new SurfaceCacheWorldChangeSet(); + LogAssert.Expect(LogType.Error, EntityChangeSource.k_ContentionError); + second.CollectChanges(secondChanges); + second.EndCollectChanges(); + Assert.IsEmpty(secondChanges.EntityInstanceChangedList, "A detached source should not receive records."); + + var firstChanges = new SurfaceCacheWorldChangeSet(); + first.CollectChanges(firstChanges); + first.EndCollectChanges(); + CollectionAssert.IsNotEmpty(firstChanges.EntityInstanceChangedList, "The registered source should receive the pushed record."); + + second.Dispose(); + Assert.IsTrue(SurfaceCacheEntityChangeBridge.IsConsumerPresent, "Disposing a detached source must not unregister the active consumer."); + + first.Dispose(); + Assert.IsFalse(SurfaceCacheEntityChangeBridge.IsConsumerPresent); + } + + [Test] + public void EntityChangeSource_CompetitorDisposed_AcquiresOnNextCollect() + { + var first = new EntityChangeSource(); + var second = new EntityChangeSource(); + + first.CollectChanges(new SurfaceCacheWorldChangeSet()); + first.EndCollectChanges(); + + LogAssert.Expect(LogType.Error, EntityChangeSource.k_ContentionError); + second.CollectChanges(new SurfaceCacheWorldChangeSet()); + second.EndCollectChanges(); + + // A second contended collect must not log the contention error again. + second.CollectChanges(new SurfaceCacheWorldChangeSet()); + second.EndCollectChanges(); + + first.Dispose(); + + second.CollectChanges(new SurfaceCacheWorldChangeSet()); + second.EndCollectChanges(); + Assert.IsTrue(SurfaceCacheEntityChangeBridge.IsConsumerPresent, "The surviving source should take over the freed bridge."); + + SurfaceCacheEntityChangeBridge.PushChanged(MakeRecord()); + + var changes = new SurfaceCacheWorldChangeSet(); + second.CollectChanges(changes); + second.EndCollectChanges(); + CollectionAssert.IsNotEmpty(changes.EntityInstanceChangedList, "A source that took over the bridge should receive records."); + + second.Dispose(); + Assert.IsFalse(SurfaceCacheEntityChangeBridge.IsConsumerPresent); + } + + [Test] + public void CollectChanges_DrainAborted_PendingIsRedeliveredOnNextCollect() + { + var source = new EntityChangeSource(); + source.CollectChanges(new SurfaceCacheWorldChangeSet()); + source.EndCollectChanges(); + + SurfaceCacheEntityChangeBridge.PushChanged(MakeRecord()); + + source.CollectChanges(new SurfaceCacheWorldChangeSet()); + source.AbortCollectChanges(); + + var retried = new SurfaceCacheWorldChangeSet(); + source.CollectChanges(retried); + source.EndCollectChanges(); + CollectionAssert.IsNotEmpty(retried.EntityInstanceChangedList, "An aborted drain should redeliver its records on the next collect."); + + var afterCommit = new SurfaceCacheWorldChangeSet(); + source.CollectChanges(afterCommit); + source.EndCollectChanges(); + Assert.IsEmpty(afterCommit.EntityInstanceChangedList, "A committed drain should clear the delivered records."); + + source.Dispose(); + } + + [Test] + public void CollectChanges_TransformPushedAfterAbort_FoldsIntoRetainedRecord() + { + var source = new EntityChangeSource(); + source.CollectChanges(new SurfaceCacheWorldChangeSet()); + source.EndCollectChanges(); + + SurfaceCacheEntityChangeBridge.PushChanged(MakeRecord()); + + source.CollectChanges(new SurfaceCacheWorldChangeSet()); + source.AbortCollectChanges(); + + var moved = Matrix4x4.Translate(new Vector3(1.0f, 2.0f, 3.0f)); + var transforms = SurfaceCacheEntityChangeBridge.AcquireTransformChangedList(); + transforms.Add(new SurfaceCacheEntityTransformRecord { Key = m_KeyDonor.GetEntityId(), LocalToWorld = moved }); + + var retried = new SurfaceCacheWorldChangeSet(); + source.CollectChanges(retried); + Assert.AreEqual(0, retried.EntityInstanceTransformChangedList.Length, "A transform superseded by a pending record should not be delivered separately."); + source.EndCollectChanges(); + + var retriedRecord = retried.EntityInstanceChangedList.Single(); + Assert.AreEqual(moved, retriedRecord.LocalToWorld, "The newer transform should be folded into the retained record."); + + source.Dispose(); + } + + [Test] + public void CollectChanges_RecordPushedAfterAbort_SupersedesRetainedTransform() + { + var source = new EntityChangeSource(); + source.CollectChanges(new SurfaceCacheWorldChangeSet()); + source.EndCollectChanges(); + + var stale = Matrix4x4.Translate(new Vector3(4.0f, 5.0f, 6.0f)); + var transforms = SurfaceCacheEntityChangeBridge.AcquireTransformChangedList(); + transforms.Add(new SurfaceCacheEntityTransformRecord { Key = m_KeyDonor.GetEntityId(), LocalToWorld = stale }); + + source.CollectChanges(new SurfaceCacheWorldChangeSet()); + source.AbortCollectChanges(); + + var moved = Matrix4x4.Translate(new Vector3(1.0f, 2.0f, 3.0f)); + var record = MakeRecord(); + record.LocalToWorld = moved; + SurfaceCacheEntityChangeBridge.PushChanged(record); + + var retried = new SurfaceCacheWorldChangeSet(); + source.CollectChanges(retried); + Assert.AreEqual(0, retried.EntityInstanceTransformChangedList.Length, "A transform retained from before the record must not be redelivered."); + source.EndCollectChanges(); + + var retriedRecord = retried.EntityInstanceChangedList.Single(); + Assert.AreEqual(moved, retriedRecord.LocalToWorld, "A retained transform must not be folded over a newer record."); + + source.Dispose(); + } + + [Test] + public void UnregisterConsumer_DuringStuckDrain_NextConsumerDrainsCleanly() + { + var changed = new List(); + var destroyed = new List(); + + Assert.IsTrue(SurfaceCacheEntityChangeBridge.TryRegisterConsumer()); + + SurfaceCacheEntityChangeBridge.BeginDrain(changed, destroyed, out _); + + SurfaceCacheEntityChangeBridge.UnregisterConsumer(); + + Assert.IsTrue(SurfaceCacheEntityChangeBridge.TryRegisterConsumer()); + SurfaceCacheEntityChangeBridge.BeginDrain(changed, destroyed, out _); + SurfaceCacheEntityChangeBridge.EndDrain(); + SurfaceCacheEntityChangeBridge.UnregisterConsumer(); + } + + SurfaceCacheEntityInstanceRecord MakeRecord() + { + return new SurfaceCacheEntityInstanceRecord + { + Key = m_KeyDonor.GetEntityId(), + Visible = true, + }; + } + } +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs.meta b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs.meta new file mode 100644 index 00000000000..329b01a5313 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheEntityChangeBridgeTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 538d1216c1ba4749b1e2543df1c71872 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/Unity.RenderPipelines.Universal.SurfaceCache.Tests.asmdef b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/Unity.RenderPipelines.Universal.SurfaceCache.Tests.asmdef index 92746a14fbe..98540f03bce 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/Unity.RenderPipelines.Universal.SurfaceCache.Tests.asmdef +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/Unity.RenderPipelines.Universal.SurfaceCache.Tests.asmdef @@ -7,7 +7,8 @@ "GUID:214c0945bb158c940aada223f3223ee8", "GUID:c49c619b6af2be941af9bcbca2641964", "GUID:df380645f10b7bc4b97d4f5eb6303d95", - "GUID:d8b63aba1907145bea998dd612889d6b" + "GUID:d8b63aba1907145bea998dd612889d6b", + "GUID:27619889b8ba8c24980f49ee34dbb44a" ], "includePlatforms": [ "Android", From c5bc39cd6d1e9c87dae6b258094cc82396a6e18a Mon Sep 17 00:00:00 2001 From: Simon Schossleitner Date: Tue, 22 Sep 2026 11:07:06 +0000 Subject: [PATCH 026/192] [content automatically redacted] touching PlatformDependent folder --- .../BuiltInGraphicsTest_Foundation/Packages/manifest.json | 2 +- .../BuiltInGraphicsTest_Lighting/Packages/manifest.json | 2 +- Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json | 2 +- Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_Foundation/Packages/manifest.json | 4 ++-- .../UniversalGraphicsTest_Lighting/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_PostPro/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_Terrain/Packages/manifest.json | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json index d2f5815c761..71db0a7a47a 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json @@ -9,7 +9,7 @@ "com.unity.ide.rider": "3.0.38", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", "com.unity.ide.vscode": "file:../../../../../ShadowPackages/com.unity.ide.vscode", - "com.unity.nuget.newtonsoft-json": "file:../../../../../ShadowPackages/com.unity.nuget.newtonsoft-json", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json index 1e4476264cb..24430b0a9cd 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json @@ -9,7 +9,7 @@ "com.unity.ide.rider": "3.0.38", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", "com.unity.ide.vscode": "file:../../../../../ShadowPackages/com.unity.ide.vscode", - "com.unity.nuget.newtonsoft-json": "file:../../../../../ShadowPackages/com.unity.nuget.newtonsoft-json", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json index 23375f7e58c..fcf6051ad93 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json @@ -6,7 +6,7 @@ "com.unity.ide.rider": "3.0.17", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", "com.unity.inputsystem": "1.19.0", - "com.unity.postprocessing": "file:../../../../../ShadowPackages/com.unity.postprocessing", + "com.unity.postprocessing": "3.5.4", "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/ShaderGraph/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json index 736a5fd1191..a3ffb59463e 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json @@ -10,7 +10,7 @@ "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", "com.unity.graph-authoring": "file:../../../../../Packages/com.unity.graph-authoring", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.test-framework.graphics", - "com.unity.testtools.codecoverage": "file:../../../../../ShadowPackages/com.unity.testtools.codecoverage", + "com.unity.testtools.codecoverage": "1.3.0", "com.unity.ugui": "2.0.0", "com.unity.visualeffectgraph": "file:../../../../../Packages/com.unity.visualeffectgraph", "com.unity.xr.management": "4.5.3", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json index 3e461104211..f6453967353 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json @@ -6,10 +6,10 @@ "com.unity.2d.tilemap": "1.0.0", "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", - "com.unity.formats.alembic": "file:../../../../../ShadowPackages/com.unity.formats.alembic", + "com.unity.formats.alembic": "2.4.7", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", - "com.unity.nuget.newtonsoft-json": "file:../../../../../ShadowPackages/com.unity.nuget.newtonsoft-json", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json index e703c9e8ddb..65664223a90 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json @@ -8,7 +8,7 @@ "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", - "com.unity.nuget.newtonsoft-json": "file:../../../../../ShadowPackages/com.unity.nuget.newtonsoft-json", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json index d10aef6472d..ac0e0f678b6 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json @@ -8,7 +8,7 @@ "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", - "com.unity.nuget.newtonsoft-json": "file:../../../../../ShadowPackages/com.unity.nuget.newtonsoft-json", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json index e703c9e8ddb..65664223a90 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json @@ -8,7 +8,7 @@ "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.7", "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", - "com.unity.nuget.newtonsoft-json": "file:../../../../../ShadowPackages/com.unity.nuget.newtonsoft-json", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", From da939c71e49ce27025fb9b67705eb7294f991a37 Mon Sep 17 00:00:00 2001 From: Minseok Lee Date: Tue, 22 Sep 2026 11:07:13 +0000 Subject: [PATCH 027/192] [Port][6000.7] Port reactive mask shader to HDRP --- .../Runtime/Upscaling/IUpscalerOptions.cs | 2 +- .../Runtime/Upscaling/UpscalerReactiveMask.cs | 101 ++++++++++ .../Upscaling/UpscalerReactiveMask.cs.meta | 2 + .../Upscaling}/UpscalerReactiveMask.shader | 26 ++- .../UpscalerReactiveMask.shader.meta | 0 .../Runtime/RenderPipeline/HDProfileId.cs | 1 + .../HDRenderPipeline.PostProcess.cs | 116 ++++++++++++ .../HDRenderPipeline.RenderGraph.cs | 38 +++- .../Runtime/Data/PostProcessData.asset | 1 - .../Runtime/Data/PostProcessData.cs | 6 - .../PostProcess/UpscalerPostProcessPass.cs | 92 ++++------ .../Runtime/PostProcess.cs | 5 +- ...UpscalerReactiveMaskUniversalRPAsset.asset | 173 ++++++++++++++++++ ...lerReactiveMaskUniversalRPAsset.asset.meta | 8 + .../Scenes/501_UpscalerReactiveMask.meta | 8 + .../Scenes/501_UpscalerReactiveMask.unity | 3 + .../501_UpscalerReactiveMask.unity.meta | 7 + .../CameraColor_PostAlpha.exr | 3 + .../CameraColor_PostAlpha.exr.meta | 145 +++++++++++++++ .../CameraColor_PreAlpha.exr | 3 + .../CameraColor_PreAlpha.exr.meta | 145 +++++++++++++++ .../OpaqueCutoutMaterial.mat | 141 ++++++++++++++ .../OpaqueCutoutMaterial.mat.meta | 8 + .../OpaqueMaterial.mat | 140 ++++++++++++++ .../OpaqueMaterial.mat.meta | 8 + .../ReactiveMaskShaderReference.asset | 16 ++ .../ReactiveMaskShaderReference.asset.meta | 8 + .../ResolveStencilReactiveMask.shader | 51 ++++++ .../ResolveStencilReactiveMask.shader.meta | 9 + .../Transparent100Material.mat | 144 +++++++++++++++ .../Transparent100Material.mat.meta | 8 + .../Transparent50Material.mat | 144 +++++++++++++++ .../Transparent50Material.mat.meta | 8 + .../ProjectSettings/QualitySettings.asset | 55 +++++- 34 files changed, 1552 insertions(+), 73 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs.meta rename Packages/{com.unity.render-pipelines.universal/Shaders/PostProcessing => com.unity.render-pipelines.core/Runtime/Upscaling}/UpscalerReactiveMask.shader (86%) rename Packages/{com.unity.render-pipelines.universal/Shaders/PostProcessing => com.unity.render-pipelines.core/Runtime/Upscaling}/UpscalerReactiveMask.shader.meta (100%) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat.meta diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscalerOptions.cs b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscalerOptions.cs index 37bdf644370..e351e2aae34 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscalerOptions.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/IUpscalerOptions.cs @@ -90,7 +90,7 @@ public UpscalerResolutionMode resolutionMode [SerializeField] [Tooltip("Execute reactive mask generation pass if current upscaler supports reactive mask.")] - private bool m_EnableReactiveMaskPass = true; + private bool m_EnableReactiveMaskPass = false; [SerializeField] [Tooltip("Use max difference among R, G, B channels instead of length of delta of (R, G, B) when calculating reactivity. This option is applied before thresholding.")] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs new file mode 100644 index 00000000000..7e10d5f1975 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs @@ -0,0 +1,101 @@ +using System; +using UnityEngine.Rendering.RenderGraphModule; + +namespace UnityEngine.Rendering +{ + /// + /// Resource class that handles the serialization of upscaler reactive mask shaders. + /// + [Serializable] + [SupportedOnRenderPipeline] + [Categorization.CategoryInfo(Name = "R: Upscaler Reactive Mask", Order = 1000), HideInInspector] + public sealed class UpscalerReactiveMaskResources : IRenderPipelineResources + { + [SerializeField, HideInInspector] + int m_Version = 0; + + /// + /// The version number of the resources container. + /// + public int version { get => m_Version; } + + bool IRenderPipelineGraphicsSettings.isAvailableInPlayerBuild => true; + + [SerializeField, ResourcePath("Runtime/Upscaling/UpscalerReactiveMask.shader")] + Shader m_reactiveMaskPS; + + /// + /// The reactive mask shader. + /// + public Shader reactiveMaskPS + { + get => m_reactiveMaskPS; + set => this.SetValueAndNotify(ref m_reactiveMaskPS, value, nameof(m_reactiveMaskPS)); + } + } + +#if ENABLE_UPSCALER_FRAMEWORK + /// + /// Common definitions for reactive mask pass. + /// + public static class UpscalerReactiveMask + { + /// + /// Render graph pass data for reactive mask pass. + /// + public class PassData + { + /// Material that represents the reactive mask shader. + public Material reactiveMaskMaterial; + /// Pass ID in the reactive mask shader. + public int reactiveMaskPassId; + /// Render target width. + public int destWidth; + /// Render target height. + public int destHeight; + /// Reactivity scale parameter. Applied after thresholding if active. + public float reactiveScale; + /// Threshold value applied if thresholding flag is set. + public float reactiveThreshold; + /// Reactivity value if thresholding is active and passed. + public float reactiveBinaryValue; + /// Bitflags of . + public uint reactiveFlags; + /// Camera color texture before transparency rendering. + public TextureHandle cameraColorPreAlpha; + /// Camera color texture after transparency rendering. + public TextureHandle cameraColorPostAlpha; + } + + /// + /// Shader keyword constants for reactive mask shader. + /// + public static class ShaderKeywords + { + public static readonly string k_InputTextureArrayKeyword = "_INPUT_TEXTURE_ARRAY"; + } + + /// Shader constant ids used to set parameters of reactive mask shader. + public static class ShaderConstants + { + public static readonly int _StencilRef = Shader.PropertyToID("_StencilRef"); + public static readonly int _StencilMask = Shader.PropertyToID("_StencilMask"); + public static readonly int _ReactiveScale = Shader.PropertyToID("_ReactiveScale"); + public static readonly int _ReactiveThreshold = Shader.PropertyToID("_ReactiveThreshold"); + public static readonly int _ReactiveBinaryValue = Shader.PropertyToID("_ReactiveBinaryValue"); + public static readonly int _ReactiveFlags = Shader.PropertyToID("_ReactiveFlags"); + public static readonly int _ColorPreAlpha = Shader.PropertyToID("_ColorPreAlpha"); + public static readonly int _ColorPostAlpha = Shader.PropertyToID("_ColorPostAlpha"); + } + + /// Bitflags for the _ReactiveFlags parameter of reactive mask shader. + public static class ReactiveFlags + { + public static readonly uint _ApplyTonemap = 1; + public static readonly uint _ApplyInverseTonemap = 2; + public static readonly uint _ApplyThreshold = 4; + public static readonly uint _UseComponentMax = 8; + } + } +#endif +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs.meta new file mode 100644 index 00000000000..013e253c614 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f18087558f7bb2e47a6bda5a7a85ec2c \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UpscalerReactiveMask.shader b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.shader similarity index 86% rename from Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UpscalerReactiveMask.shader rename to Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.shader index 092a84c9bb6..8dcf3384107 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UpscalerReactiveMask.shader +++ b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.shader @@ -1,6 +1,6 @@ // Based on AMD FSR3 auto reactive mask generation. // https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK/blob/v2.3.0/Kits/FidelityFX/upscalers/fsr3/internal/shaders/ffx_fsr3upscaler_autogen_reactive_pass.hlsl -Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" +Shader "Hidden/Core/UpscalerReactiveMask" { Properties { @@ -10,10 +10,11 @@ Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" } HLSLINCLUDE - #pragma target 4.5 + #pragma target 3.0 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GlobalSamplers.hlsl" #define AUTOREACTIVEFLAGS_APPLY_TONEMAP 1 #define AUTOREACTIVEFLAGS_APPLY_INVERSETONEMAP 2 @@ -27,9 +28,13 @@ Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" uint _ReactiveFlags; CBUFFER_END +#if _INPUT_TEXTURE_ARRAY + TEXTURE2D_X(_ColorPreAlpha); + TEXTURE2D_X(_ColorPostAlpha); +#else TEXTURE2D(_ColorPreAlpha); TEXTURE2D(_ColorPostAlpha); - SAMPLER(s_point_clamp_sampler); +#endif struct Attributes { @@ -56,8 +61,13 @@ Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" float ComputeReactivity(float2 uv) { - float3 colorPreAlpha = SAMPLE_TEXTURE2D_LOD(_ColorPreAlpha, s_point_clamp_sampler, uv, 0).rgb; - float3 colorPostAlpha = SAMPLE_TEXTURE2D_LOD(_ColorPostAlpha, s_point_clamp_sampler, uv, 0).rgb; +#if _INPUT_TEXTURE_ARRAY + float3 colorPreAlpha = SAMPLE_TEXTURE2D_X_LOD(_ColorPreAlpha, sampler_PointClamp, uv, 0).rgb; + float3 colorPostAlpha = SAMPLE_TEXTURE2D_X_LOD(_ColorPostAlpha, sampler_PointClamp, uv, 0).rgb; +#else + float3 colorPreAlpha = SAMPLE_TEXTURE2D_LOD(_ColorPreAlpha, sampler_PointClamp, uv, 0).rgb; + float3 colorPostAlpha = SAMPLE_TEXTURE2D_LOD(_ColorPostAlpha, sampler_PointClamp, uv, 0).rgb; +#endif if (_ReactiveFlags & AUTOREACTIVEFLAGS_APPLY_TONEMAP) { @@ -98,8 +108,6 @@ Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" SubShader { - Tags{ "RenderPipeline" = "UniversalPipeline" } - Pass { Name "ColorReactiveMask" @@ -107,6 +115,8 @@ Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" ZWrite Off ZTest Always Blend Off Cull Off HLSLPROGRAM + #pragma multi_compile_fragment _ _INPUT_TEXTURE_ARRAY + #pragma vertex Vert #pragma fragment ColorReactiveMaskPS @@ -136,6 +146,8 @@ Shader "Hidden/Universal Render Pipeline/UpscalerReactiveMask" ZWrite Off ZTest Always Blend Off Cull Off HLSLPROGRAM + #pragma multi_compile_fragment _ _INPUT_TEXTURE_ARRAY + #pragma vertex Vert #pragma fragment StencilReactiveMaskPS diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UpscalerReactiveMask.shader.meta b/Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.shader.meta similarity index 100% rename from Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UpscalerReactiveMask.shader.meta rename to Packages/com.unity.render-pipelines.core/Runtime/Upscaling/UpscalerReactiveMask.shader.meta diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs index fbcbcb60148..593f1fd3050 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs @@ -265,6 +265,7 @@ internal enum HDProfileId ApplyExposure, TemporalAntialiasing, UpscalerColorMask, + IUpscalerReactiveMask, FSR2, DeepLearningSuperSampling, DepthOfField, diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs index 30a0781f41e..39cf85ff3d4 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs @@ -51,6 +51,9 @@ public partial class HDRenderPipeline // AMD-CAS data ComputeBuffer m_ContrastAdaptiveSharpen; + // Upscaler reactive mask + Material m_ReactiveMaskMaterial; + // Bloom data const int k_MaxBloomMipCount = 16; Vector4 m_BloomBicubicParams; // Needed for uber pass @@ -197,6 +200,9 @@ void InitializePostProcess() m_LensFlareScreenSpaceShader = CoreUtils.CreateEngineMaterial(runtimeShaders.lensFlareScreenSpacePS); m_LensFlareScreenSpaceShader.SetOverrideTag("RenderType", "Transparent"); + var reactiveMaskResources = GraphicsSettings.GetRenderPipelineSettings(); + m_ReactiveMaskMaterial = CoreUtils.CreateEngineMaterial(reactiveMaskResources?.reactiveMaskPS); + // Some compute shaders fail on specific hardware or vendors so we'll have to use a // safer but slower code path for them m_UseSafePath = SystemInfo.graphicsDeviceVendor.Contains("intel", StringComparison.InvariantCultureIgnoreCase); @@ -304,6 +310,7 @@ void CleanupPostProcess() CoreUtils.Destroy(m_ClearBlackMaterial); CoreUtils.Destroy(m_SMAAMaterial); CoreUtils.Destroy(m_TemporalAAMaterial); + CoreUtils.Destroy(m_ReactiveMaskMaterial); CoreUtils.SafeRelease(m_HistogramBuffer); CoreUtils.SafeRelease(m_DebugImageHistogramBuffer); RTHandles.Release(m_DebugExposureData); @@ -314,6 +321,7 @@ void CleanupPostProcess() m_ClearBlackMaterial = null; m_SMAAMaterial = null; m_TemporalAAMaterial = null; + m_ReactiveMaskMaterial = null; m_HistogramBuffer = null; m_DebugImageHistogramBuffer = null; m_DebugExposureData = null; @@ -658,6 +666,95 @@ TextureHandle DoAlphaUpscaling(RenderGraph renderGraph, HDCamera hdCamera, Textu return AlphaUpscaler.Execute(renderGraph, ref config); } +#if ENABLE_UPSCALER_FRAMEWORK + static bool RequiresReactiveMaskPass(HDCamera camera, IUpscaler upscaler, UpscalerOptions upscalerOptions) + { + return camera.IsIUpscalerEnabled() && upscaler != null && upscaler.reactiveMaskSource != ReactiveMaskSource.None && upscalerOptions != null && upscalerOptions.enableReactiveMaskPass; + } + + static TextureHandle UpscalerReactiveMaskPass(RenderGraph renderGraph, IUpscaler upscaler, UpscalerOptions upscalerOptions, Material material, TextureHandle cameraColorPreAlpha, TextureHandle cameraColorPostAlpha, Vector2Int preUpscaleResolution, bool enableTexArray, bool hdrInput) + { + if (upscalerOptions == null || upscaler.reactiveMaskSource == ReactiveMaskSource.None) + return TextureHandle.nullHandle; + + TextureHandle output = TextureHandle.nullHandle; + + using (var builder = renderGraph.AddUnsafePass("Upscaler Reactive Mask", out var passData, ProfilingSampler.Get(HDProfileId.IUpscalerReactiveMask))) + { + int passId = 0; + if (upscaler.reactiveMaskSource == ReactiveMaskSource.Color) + { + output = renderGraph.CreateTexture( + new TextureDesc(preUpscaleResolution.x, preUpscaleResolution.y, xrReady: enableTexArray) + { + format = GraphicsFormat.R8_UNorm, + clearBuffer = true, + clearColor = Color.black, + name = "Upscaler Reactive Mask" + }); + builder.SetRenderAttachment(output, 0); + + passId = 0; + } + else if (upscaler.reactiveMaskSource == ReactiveMaskSource.Stencil) + { + output = renderGraph.CreateTexture( + new TextureDesc(preUpscaleResolution.x, preUpscaleResolution.y, xrReady: enableTexArray) + { + format = GraphicsFormatUtility.GetDepthStencilFormat(0, 8), + clearBuffer = true, + clearColor = Color.black, + name = "Upscaler Reactive Mask" + }); + builder.SetRenderAttachmentDepth(output, AccessFlags.Write); + + passId = 1; + } + + CoreUtils.SetKeyword(material, UpscalerReactiveMask.ShaderKeywords.k_InputTextureArrayKeyword, enableTexArray); + + uint reactiveFlags = 0; + if (hdrInput) + reactiveFlags |= UpscalerReactiveMask.ReactiveFlags._ApplyTonemap; + if (upscalerOptions.reactiveMaskUseComponentMax) + reactiveFlags |= UpscalerReactiveMask.ReactiveFlags._UseComponentMax; + if (upscalerOptions.applyReactiveMaskThreshold) + reactiveFlags |= UpscalerReactiveMask.ReactiveFlags._ApplyThreshold; + + passData.reactiveMaskMaterial = material; + passData.reactiveMaskPassId = passId; + passData.destWidth = preUpscaleResolution.x; + passData.destHeight = preUpscaleResolution.y; + passData.reactiveScale = upscalerOptions.reactiveMaskScale; + passData.reactiveThreshold = upscalerOptions.reactiveMaskThreshold; + passData.reactiveBinaryValue = upscalerOptions.reactiveMaskBinaryValue; + passData.reactiveFlags = reactiveFlags; + passData.cameraColorPreAlpha = cameraColorPreAlpha; + passData.cameraColorPostAlpha = cameraColorPostAlpha; + + builder.UseTexture(passData.cameraColorPreAlpha, AccessFlags.Read); + builder.UseTexture(passData.cameraColorPostAlpha, AccessFlags.Read); + + builder.SetRenderFunc((UpscalerReactiveMask.PassData data, UnsafeGraphContext ctx) => + { + var material = data.reactiveMaskMaterial; + material.SetFloat(UpscalerReactiveMask.ShaderConstants._ReactiveScale, data.reactiveScale); + material.SetFloat(UpscalerReactiveMask.ShaderConstants._ReactiveThreshold, data.reactiveThreshold); + material.SetFloat(UpscalerReactiveMask.ShaderConstants._ReactiveBinaryValue, data.reactiveBinaryValue); + material.SetInteger(UpscalerReactiveMask.ShaderConstants._ReactiveFlags, (int)data.reactiveFlags); + material.SetTexture(UpscalerReactiveMask.ShaderConstants._ColorPreAlpha, data.cameraColorPreAlpha); + material.SetTexture(UpscalerReactiveMask.ShaderConstants._ColorPostAlpha, data.cameraColorPostAlpha); + + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd); + cmd.SetViewport(new Rect(0, 0, data.destWidth, data.destHeight)); + Blitter.BlitTexture(cmd, new Vector4(1, 1, 0, 0), material, data.reactiveMaskPassId); + }); + } + + return output; + } +#endif + TextureHandle DoUpscalingAndAntiAliasing(RenderGraph renderGraph, HDCamera hdCamera, CurrentUpsamplerData upsamplerDataData, TextureHandle source, in TextureHandle depthBuffer, in TextureHandle motionVectors, in TextureHandle stencilBuffer, in TextureHandle depthBufferMipChain) { @@ -718,6 +815,7 @@ TextureHandle RenderPostProcess(RenderGraph renderGraph, TextureHandle uiBuffer, TextureHandle afterPostProcessBuffer, TextureHandle opticalFogTransmittance, + TextureHandle beforeTransparencyBuffer, CullingResults cullResults, HDCamera hdCamera, CubemapFace cubemapFace, @@ -759,6 +857,24 @@ TextureHandle RenderPostProcess(RenderGraph renderGraph, { source = StopNaNsPass(renderGraph, hdCamera, source); +#if ENABLE_UPSCALER_FRAMEWORK + { + var io = hdCamera.contextContainer.Get(); + var upscaler = upscaling.activeUpscaler; + var upscalerOptions = upscaling.GetGlobalOptions(upscaling.activeUpscaler); + + // Should be same as DoIUpscalerPasses() + var preUpscaleResolution = hdCamera.historyRTHandleProperties.currentViewportSize; + var enableTexArray = TextureXR.useTexArray; + var hdrInput = GraphicsFormatUtility.IsHDRFormat(inputColor.GetDescriptor(renderGraph).format); + + if (RequiresReactiveMaskPass(hdCamera, upscaler, upscalerOptions) && beforeTransparencyBuffer != TextureHandle.nullHandle) + io.reactiveMask = UpscalerReactiveMaskPass(renderGraph, upscaler, upscalerOptions, m_ReactiveMaskMaterial, beforeTransparencyBuffer, inputColor, preUpscaleResolution, enableTexArray, hdrInput); + else + io.reactiveMask = TextureHandle.nullHandle; + } +#endif + source = DynamicExposurePass(renderGraph, hdCamera, source); // Keep the "Before TAA" injection point before any temporal resolve algorithm, it doesn't have to be TAA only and also can perform upsampling. 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 20ee2e44026..685826cfb4b 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 @@ -96,6 +96,8 @@ void RecordRenderGraph(RenderRequest renderRequest, TextureHandle vtFeedbackBuffer = TextureHandle.nullHandle; #endif + TextureHandle opaqueColorBuffer = TextureHandle.nullHandle; + // Evaluate the ray tracing acceleration structure debug views EvaluateRTASDebugView(m_RenderGraph, hdCamera); @@ -259,6 +261,14 @@ void RecordRenderGraph(RenderRequest renderRequest, RenderClouds(m_RenderGraph, hdCamera, colorBuffer, transparentPrepass.depthBufferPreRefraction, in prepassOutput, ref transparentPrepass, ref opticalFogTransmittance); +#if ENABLE_UPSCALER_FRAMEWORK + if (RequiresReactiveMaskPass(hdCamera, upscaling.activeUpscaler, upscaling.GetGlobalOptions(upscaling.activeUpscaler))) + { + opaqueColorBuffer = m_RenderGraph.CreateTexture(colorBuffer, "CameraColorBeforeTransparency", false); + CopyOpaqueColor(m_RenderGraph, colorBuffer, opaqueColorBuffer); + } +#endif + 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); @@ -356,7 +366,7 @@ void RecordRenderGraph(RenderRequest renderRequest, bool postProcessIsFinalPass = HDUtils.PostProcessIsFinalPass(hdCamera, aovRequest); TextureHandle afterPostProcessBuffer = RenderAfterPostProcessObjects(m_RenderGraph, hdCamera, pathTracing, cullingResults, prepassOutput); var postProcessTargetFace = postProcessIsFinalPass ? target.face : CubemapFace.Unknown; - TextureHandle postProcessDest = RenderPostProcess(m_RenderGraph, prepassOutput, colorBuffer, colorBackBuffer, uiBuffer, afterPostProcessBuffer, opticalFogTransmittance, cullingResults, hdCamera, postProcessTargetFace, postProcessIsFinalPass); + TextureHandle postProcessDest = RenderPostProcess(m_RenderGraph, prepassOutput, colorBuffer, colorBackBuffer, uiBuffer, afterPostProcessBuffer, opticalFogTransmittance, opaqueColorBuffer, cullingResults, hdCamera, postProcessTargetFace, postProcessIsFinalPass); var xyMapping = GenerateDebugHDRxyMapping(m_RenderGraph, hdCamera, postProcessDest); GenerateDebugImageHistogram(m_RenderGraph, hdCamera, postProcessDest); @@ -736,6 +746,32 @@ void SetFinalTarget(RenderGraph renderGraph, HDCamera hdCamera, in TextureHandle } } +#if ENABLE_UPSCALER_FRAMEWORK + class CopyOpaqueColorPassData + { + public TextureHandle source; + public TextureHandle destination; + } + + static void CopyOpaqueColor(RenderGraph renderGraph, in TextureHandle inputColor, in TextureHandle outputColor) + { + using (var builder = renderGraph.AddUnsafePass("Copy cameraColor for upscalers", out var passData)) + { + passData.source = inputColor; + passData.destination = outputColor; + + builder.UseTexture(passData.source, AccessFlags.Read); + builder.UseTexture(passData.destination, AccessFlags.Write); + + builder.SetRenderFunc(static (CopyOpaqueColorPassData data, UnsafeGraphContext ctx) => + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd); + Blitter.BlitCameraTexture(cmd, data.source, data.destination, Vector2.one, 0.0f, false); + }); + } + } +#endif + class CopyXRDepthPassData { public Material copyDepth; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.asset b/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.asset index f58958ec1be..5e38bd21eea 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.asset +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.asset @@ -29,7 +29,6 @@ MonoBehaviour: easuPS: {fileID: 4800000, guid: 562b7ae4f629f144aa97780546fce7c6, type: 3} uberPostPS: {fileID: 4800000, guid: e7857e9d0c934dc4f83f270f8447b006, type: 3} finalPostPassPS: {fileID: 4800000, guid: c49e63ed1bbcb334780a3bd19dfed403, type: 3} - reactiveMaskPS: {fileID: 4800000, guid: a32e79e9a0e86a14894684c864a169a3, type: 3} m_ShaderResourcesVersion: 0 textures: blueNoise16LTex: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.cs index 8f8f8a16f75..10fd1b5a0d7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/PostProcessData.cs @@ -180,12 +180,6 @@ public sealed class ShaderResources : IRenderPipelineResources [ResourcePath("Shaders/PostProcessing/FinalPost.shader")] public Shader finalPostPassPS; - /// - /// The Upscaler Reactive Mask shader. - /// - [ResourcePath("Shaders/PostProcessing/UpscalerReactiveMask.shader")] - public Shader reactiveMaskPS; - #if UNITY_EDITOR /// /// Copies all fields and resources from a source object into this object. diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs index db9fb08e61f..8fbb4eaffc3 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/PostProcess/UpscalerPostProcessPass.cs @@ -17,6 +17,8 @@ internal sealed class UpscalerPostProcessPass : PostProcessPass #if ENABLE_UPSCALER_FRAMEWORK bool m_WarnedHardwareDrsTemporalUnsupported; bool m_WarnedMissingMotionData; + bool m_WarnedMissingOpaqueTexture; + bool m_WarnedOpaqueDownsamplingNotCompatible; #endif public UpscalerPostProcessPass(Shader reactiveMaskShader, Texture2D[] blueNoise16LTex) @@ -216,9 +218,15 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer if (RequiresReactiveMaskPass(upscaler)) { if (resourceData.cameraOpaqueTexture.IsValid()) + { io.reactiveMask = UpscalerReactiveMaskPass(renderGraph, frameData, m_UpscalerReactiveMaskMaterial, upscaler.reactiveMaskSource, upscalerOptions, io.enableTexArray); - else if (Debug.isDebugBuild) - Debug.LogWarning("UpscalerPostProcessPass: Opaque Texture is disabled in the URP asset; reactive mask generation will be skipped."); + m_WarnedMissingOpaqueTexture = false; + } + else if (Debug.isDebugBuild && !m_WarnedMissingOpaqueTexture) + { + Debug.LogWarning("UpscalerPostProcessPass: Opaque Texture is disabled in the current RP asset. Reactive mask generation will be skipped."); + m_WarnedMissingOpaqueTexture = true; + } } // Per-frame settings (sharpness, etc.); upscalers read these from io.options, not from the context. @@ -304,42 +312,33 @@ static internal bool RequiresReactiveMaskPass(IUpscaler upscaler) return upscalerOptions != null && upscalerOptions.enableReactiveMaskPass && upscaler.reactiveMaskSource != ReactiveMaskSource.None; } - private class UpscalerReactiveMaskPassData - { - public Material reactiveMaskMaterial; - public int reactiveMaskPassId; - public int destWidth; - public int destHeight; - public float reactiveScale; - public float reactiveThreshold; - public float reactiveBinaryValue; - public uint reactiveFlags; - public TextureHandle cameraColorPreAlpha; - public TextureHandle cameraColorPostAlpha; - } - - static internal TextureHandle UpscalerReactiveMaskPass(RenderGraph renderGraph, ContextContainer frameData, Material material, ReactiveMaskSource reactiveMaskSource, UpscalerOptions upscalerOptions, bool enableTexArray) + internal TextureHandle UpscalerReactiveMaskPass(RenderGraph renderGraph, ContextContainer frameData, Material material, ReactiveMaskSource reactiveMaskSource, UpscalerOptions upscalerOptions, bool enableTexArray) { if (reactiveMaskSource == ReactiveMaskSource.None) return TextureHandle.nullHandle; - TextureHandle output = TextureHandle.nullHandle; - var io = frameData.Get(); var cameraData = frameData.Get(); var resourceData = frameData.Get(); - if (Debug.isDebugBuild) + var preAlphaDesc = resourceData.cameraOpaqueTexture.GetDescriptor(renderGraph); + var postAlphaDesc = resourceData.cameraColorBeforePP.GetDescriptor(renderGraph); + if (preAlphaDesc.width != postAlphaDesc.width || preAlphaDesc.height != postAlphaDesc.height) { - var preAlphaDesc = resourceData.cameraOpaqueTexture.GetDescriptor(renderGraph); - var postAlphaDesc = resourceData.cameraColorBeforePP.GetDescriptor(renderGraph); - if (preAlphaDesc.width != postAlphaDesc.width || preAlphaDesc.height != postAlphaDesc.height) + if (Debug.isDebugBuild && !m_WarnedOpaqueDownsamplingNotCompatible) { - Debug.LogWarning("Opaque Downsampling in current URP Asset is not set to None. Reactive mask quality might degrade."); + Debug.LogWarning($"Opaque Downsampling in the current RP Asset should be None for reactive mask generation, but is set to {UniversalRenderPipeline.asset.opaqueDownsampling}."); + m_WarnedOpaqueDownsamplingNotCompatible = true; } + return TextureHandle.nullHandle; } - using (var builder = renderGraph.AddRasterRenderPass("Upscaler Reactive Mask", out var passData, k_ReactiveMaskProfilingSampler)) + if (Debug.isDebugBuild) + m_WarnedOpaqueDownsamplingNotCompatible = false; + + TextureHandle output = TextureHandle.nullHandle; + + using (var builder = renderGraph.AddRasterRenderPass("Upscaler Reactive Mask", out var passData, k_ReactiveMaskProfilingSampler)) { int passId = 0; if (reactiveMaskSource == ReactiveMaskSource.Color) @@ -371,11 +370,15 @@ static internal TextureHandle UpscalerReactiveMaskPass(RenderGraph renderGraph, passId = 1; } + CoreUtils.SetKeyword(material, UpscalerReactiveMask.ShaderKeywords.k_InputTextureArrayKeyword, enableTexArray); + uint reactiveFlags = 0; + if (io.hdrInput) + reactiveFlags |= UpscalerReactiveMask.ReactiveFlags._ApplyTonemap; if (upscalerOptions.reactiveMaskUseComponentMax) - reactiveFlags |= ReactiveFlags._UseComponentMax; + reactiveFlags |= UpscalerReactiveMask.ReactiveFlags._UseComponentMax; if (upscalerOptions.applyReactiveMaskThreshold) - reactiveFlags |= ReactiveFlags._ApplyThreshold; + reactiveFlags |= UpscalerReactiveMask.ReactiveFlags._ApplyThreshold; passData.reactiveMaskMaterial = material; passData.reactiveMaskPassId = passId; @@ -391,15 +394,15 @@ static internal TextureHandle UpscalerReactiveMaskPass(RenderGraph renderGraph, builder.UseTexture(passData.cameraColorPreAlpha, AccessFlags.Read); builder.UseTexture(passData.cameraColorPostAlpha, AccessFlags.Read); - builder.SetRenderFunc((UpscalerReactiveMaskPassData data, RasterGraphContext ctx) => + builder.SetRenderFunc((UpscalerReactiveMask.PassData data, RasterGraphContext ctx) => { var material = data.reactiveMaskMaterial; - material.SetFloat(ShaderConstants._ReactiveScale, data.reactiveScale); - material.SetFloat(ShaderConstants._ReactiveThreshold, data.reactiveThreshold); - material.SetFloat(ShaderConstants._ReactiveBinaryValue, data.reactiveBinaryValue); - material.SetInteger(ShaderConstants._ReactiveFlags, (int)data.reactiveFlags); - material.SetTexture(ShaderConstants._ColorPreAlpha, data.cameraColorPreAlpha); - material.SetTexture(ShaderConstants._ColorPostAlpha, data.cameraColorPostAlpha); + material.SetFloat(UpscalerReactiveMask.ShaderConstants._ReactiveScale, data.reactiveScale); + material.SetFloat(UpscalerReactiveMask.ShaderConstants._ReactiveThreshold, data.reactiveThreshold); + material.SetFloat(UpscalerReactiveMask.ShaderConstants._ReactiveBinaryValue, data.reactiveBinaryValue); + material.SetInteger(UpscalerReactiveMask.ShaderConstants._ReactiveFlags, (int)data.reactiveFlags); + material.SetTexture(UpscalerReactiveMask.ShaderConstants._ColorPreAlpha, data.cameraColorPreAlpha); + material.SetTexture(UpscalerReactiveMask.ShaderConstants._ColorPostAlpha, data.cameraColorPostAlpha); ctx.cmd.SetViewport(new Rect(0, 0, data.destWidth, data.destHeight)); Blitter.BlitTexture(ctx.cmd, new Vector4(1, 1, 0, 0), material, data.reactiveMaskPassId); @@ -409,26 +412,5 @@ static internal TextureHandle UpscalerReactiveMaskPass(RenderGraph renderGraph, return output; } #endif - - // Precomputed shader ids to same some CPU cycles (mostly affects mobile) - public static class ShaderConstants - { - public static readonly int _StencilRef = Shader.PropertyToID("_StencilRef"); - public static readonly int _StencilMask = Shader.PropertyToID("_StencilMask"); - public static readonly int _ReactiveScale = Shader.PropertyToID("_ReactiveScale"); - public static readonly int _ReactiveThreshold = Shader.PropertyToID("_ReactiveThreshold"); - public static readonly int _ReactiveBinaryValue = Shader.PropertyToID("_ReactiveBinaryValue"); - public static readonly int _ReactiveFlags = Shader.PropertyToID("_ReactiveFlags"); - public static readonly int _ColorPreAlpha = Shader.PropertyToID("_ColorPreAlpha"); - public static readonly int _ColorPostAlpha = Shader.PropertyToID("_ColorPostAlpha"); - } - - public static class ReactiveFlags - { - public static uint _ApplyTonemap = 1; - public static uint _ApplyInverseTonemap = 2; - public static uint _ApplyThreshold = 4; - public static uint _UseComponentMax = 8; - } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcess.cs b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcess.cs index 24afd599f03..35f1412901b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcess.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcess.cs @@ -49,6 +49,9 @@ public PostProcess(PostProcessData postProcessResourceAssetData) Assertions.Assert.IsNotNull(postProcessResourceAssetData, "PostProcessData and resources cannot be null."); m_Resources = postProcessResourceAssetData; + GraphicsSettings.TryGetRenderPipelineSettings(out var reactiveMaskResources); + var reactiveMaskPS = reactiveMaskResources?.reactiveMaskPS; + GraphicsSettings.TryGetRenderPipelineSettings(out var filmGrainResources); m_FilmGrainTextures = filmGrainResources?.textures; @@ -56,7 +59,7 @@ public PostProcess(PostProcessData postProcessResourceAssetData) m_SmaaPostProcessPass = new SmaaPostProcessPass(m_Resources.shaders.subpixelMorphologicalAntialiasingPS, m_Resources.textures.smaaAreaTex, m_Resources.textures.smaaSearchTex); m_DepthOfFieldGaussianPass = new DepthOfFieldGaussianPostProcessPass(m_Resources.shaders.gaussianDepthOfFieldPS); m_DepthOfFieldBokehPass = new DepthOfFieldBokehPostProcessPass(m_Resources.shaders.bokehDepthOfFieldPS); - m_UpscalerPostProcessPass = new UpscalerPostProcessPass(m_Resources.shaders.reactiveMaskPS, m_Resources.textures.blueNoise16LTex); + m_UpscalerPostProcessPass = new UpscalerPostProcessPass(reactiveMaskPS, m_Resources.textures.blueNoise16LTex); #if !ENABLE_UPSCALER_FRAMEWORK m_StpPostProcessPass = new StpPostProcessPass(m_Resources.textures.blueNoise16LTex); #endif diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset new file mode 100644 index 00000000000..276639a2f0b --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset @@ -0,0 +1,173 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: bf2edee5c58d82540a51f03df9d42094, type: 3} + m_Name: 501_UpscalerReactiveMaskUniversalRPAsset + m_EditorClassIdentifier: + k_AssetVersion: 13 + k_AssetPreviousVersion: 13 + m_RendererType: 1 + m_RendererData: {fileID: 0} + m_RendererDataList: + - {fileID: 11400000, guid: f59607d3476b54858a594ea904187fb5, type: 2} + m_DefaultRendererIndex: 0 + m_RequireDepthTexture: 1 + m_RequireOpaqueTexture: 1 + m_OpaqueDownsampling: 0 + m_SupportsTerrainHoles: 0 + m_SupportsHDR: 1 + m_HDRColorBufferPrecision: 0 + m_MSAA: 1 + m_RenderScale: 1 + m_UpscalingFilter: 4 + m_SelectedUpscalerName: Spatial-Temporal Post-Processing + m_UpscalerOptions: + - {fileID: 2306384786871819648} + m_FsrOverrideSharpness: 0 + m_FsrSharpness: 0.92 + m_EnableLODCrossFade: 0 + m_LODCrossFadeDitheringType: 1 + m_ShEvalMode: 0 + m_LightProbeSystem: 0 + m_ProbeVolumeMemoryBudget: 1024 + m_ProbeVolumeBlendingMemoryBudget: 128 + m_SupportProbeVolumeGPUStreaming: 0 + m_SupportProbeVolumeDiskStreaming: 0 + m_SupportProbeVolumeScenarios: 0 + m_SupportProbeVolumeScenarioBlending: 0 + m_ProbeVolumeSHBands: 1 + m_MainLightRenderingMode: 1 + m_MainLightShadowsSupported: 0 + m_MainLightShadowmapResolution: 2048 + m_AdditionalLightsRenderingMode: 0 + m_AdditionalLightsPerObjectLimit: 8 + m_AdditionalLightShadowsSupported: 0 + m_AdditionalLightsShadowmapResolution: 512 + m_AdditionalLightsShadowResolutionTierLow: 128 + m_AdditionalLightsShadowResolutionTierMedium: 256 + m_AdditionalLightsShadowResolutionTierHigh: 512 + m_ReflectionProbeBlending: 0 + m_ReflectionProbeBoxProjection: 0 + m_ReflectionProbeAtlas: 0 + m_ShadowDistance: 56 + m_ShadowCascadeCount: 4 + m_Cascade2Split: 0.25 + m_Cascade3Split: {x: 0.154, y: 0.478} + m_Cascade4Split: {x: 0.067, y: 0.2, z: 0.467} + m_CascadeBorder: 0.1 + m_ShadowDepthBias: 1 + m_ShadowNormalBias: 1 + m_AnyShadowsSupported: 1 + m_SoftShadowsSupported: 1 + m_ConservativeEnclosingSphere: 0 + m_NumIterationsEnclosingSphere: 64 + m_SoftShadowQuality: 2 + m_AdditionalLightsCookieResolution: 2048 + m_AdditionalLightsCookieFormat: 3 + m_UseSRPBatcher: 1 + m_SupportsDynamicBatching: 0 + m_MixedLightingSupported: 0 + m_SupportsLightCookies: 0 + m_SupportsLightLayers: 0 + m_StoreActionsOptimization: 0 + m_UseAdaptivePerformance: 1 + m_ColorGradingMode: 0 + m_ColorGradingLutSize: 32 + m_AllowPostProcessAlphaOutput: 0 + m_UseFastSRGBLinearConversion: 0 + m_SupportDataDrivenLensFlare: 1 + m_SupportScreenSpaceLensFlare: 1 + m_GPUResidentDrawerMode: 0 + m_SmallMeshScreenPercentage: 0 + m_ShadowSmallMeshScreenPercentages: {x: 0, y: 0, z: 0, w: 0} + m_GPUResidentDrawerEnableOcclusionCullingInCameras: 0 + m_ShadowType: 0 + m_LocalShadowsSupported: 1 + m_LocalShadowsAtlasResolution: 512 + m_MaxPixelLights: 4 + m_ShadowAtlasResolution: 2048 + m_VolumeFrameworkUpdateMode: 0 + m_VolumeProfile: {fileID: 0} + apvScenesData: + obsoleteSceneBounds: + m_Keys: [] + m_Values: [] + obsoleteHasProbeVolumes: + m_Keys: [] + m_Values: + m_PrefilteringModeMainLightShadows: 0 + m_PrefilteringModeAdditionalLight: 0 + m_PrefilteringModeAdditionalLightShadows: 0 + m_PrefilterXRKeywords: 1 + m_PrefilteringModeForwardPlus: 0 + m_PrefilteringModeDeferredRendering: 0 + m_PrefilteringModeScreenSpaceOcclusion: 0 + m_PrefilteringModeScreenSpaceReflection: 0 + m_PrefilterWriteSmoothness: 1 + m_PrefilterDebugKeywords: 1 + m_PrefilterWriteRenderingLayers: 1 + m_PrefilterHDROutput: 0 + m_PrefilterAlphaOutput: 1 + m_PrefilterSSAODepthNormals: 1 + m_PrefilterSSAOSourceDepthLow: 1 + m_PrefilterSSAOSourceDepthMedium: 1 + m_PrefilterSSAOSourceDepthHigh: 1 + m_PrefilterSSAOInterleaved: 1 + m_PrefilterSSAOBlueNoise: 1 + m_PrefilterSSAOSampleCountLow: 1 + m_PrefilterSSAOSampleCountMedium: 1 + m_PrefilterSSAOSampleCountHigh: 1 + m_PrefilterDBufferMRT1: 1 + m_PrefilterDBufferMRT2: 1 + m_PrefilterDBufferMRT3: 1 + m_PrefilterSoftShadowsQualityLow: 1 + m_PrefilterSoftShadowsQualityMedium: 1 + m_PrefilterSoftShadowsQualityHigh: 1 + m_PrefilterSoftShadows: 0 + m_PrefilterScreenCoord: 0 + m_PrefilterScreenSpaceIrradiance: 1 + m_PrefilterNativeRenderPass: 1 + m_PrefilterUseLegacyLightmaps: 0 + m_PrefilterBicubicLightmapSampling: 1 + m_PrefilterReflectionProbeRotation: 1 + m_PrefilterReflectionProbeBlending: 1 + m_PrefilterReflectionProbeBoxProjection: 1 + m_PrefilterReflectionProbeAtlas: 1 + m_PrefilterPointSamplingUpsampling: 1 + m_PrefilterExposure: 1 + m_Light2DPrefilteringMode: 0 + m_Light2DKeptVariantCombos: [] + m_ShaderVariantLogLevel: 0 + m_ShadowCascades: 3 + m_Textures: + blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3} + bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3} +--- !u!114 &2306384786871819648 +MonoBehaviour: + m_ObjectHideFlags: 1 + 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: 03be459180a06974d8583254adb17471, type: 3} + m_Name: STPOptions + m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::STPOptions + m_UpscalerName: Spatial-Temporal Post-Processing + m_InjectionPoint: 0 + m_ResolutionMode: 0 + m_EnableReactiveMaskPass: 1 + m_ReactiveMaskUseComponentMax: 0 + m_ReactiveMaskScale: 1 + m_ApplyReactiveMaskThreshold: 1 + m_ReactiveMaskThreshold: 0.2 + m_ReactiveMaskBinaryValue: 1 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset.meta new file mode 100644 index 00000000000..54cf1f63472 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/CommonAssets/URPAssets/501_UpscalerReactiveMaskUniversalRPAsset.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fbcd4274d18297940be533ecef904f09 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.meta new file mode 100644 index 00000000000..ac6cf687732 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a4c7091da05805343b16c718b6de8512 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity new file mode 100644 index 00000000000..a079cd4e2e1 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2568c780598d14ef1858f83ad0fcb744242491301f72d8ce0f1bf8d5df5adfb +size 28626 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity.meta new file mode 100644 index 00000000000..4621cb58550 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 82e594be765b3f5489348a5713297eff +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr new file mode 100644 index 00000000000..6bac270adad --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6122a4144dce50ef15a31ea222a38027f1227047c24bcc155df0044d3f4c5a49 +size 2105675 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr.meta new file mode 100644 index 00000000000..d8649a7715f --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PostAlpha.exr.meta @@ -0,0 +1,145 @@ +fileFormatVersion: 2 +guid: 9b5d7af667f57a04db00c9e781d9f475 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationMethod: 0 + spriteTessellationDetail: -1 + spriteGeometrySubdivision: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: CloudRendering + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr new file mode 100644 index 00000000000..5f03192d0f5 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e33e81b496e1b27af3b65120fd79c400de1c5ff827e63db094cb04954c136b33 +size 2105675 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr.meta new file mode 100644 index 00000000000..83f9aade144 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/CameraColor_PreAlpha.exr.meta @@ -0,0 +1,145 @@ +fileFormatVersion: 2 +guid: a21d8a0826f27d7418573017e1ce208c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationMethod: 0 + spriteTessellationDetail: -1 + spriteGeometrySubdivision: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: CloudRendering + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat new file mode 100644 index 00000000000..d7dd01b6b10 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat @@ -0,0 +1,141 @@ +%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: OpaqueCutoutMaterial + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHATEST_ON + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2450 + stringTagMap: + RenderType: TransparentCutout + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 400cf02f268b02e4497feb50a409aaf6, type: 3} + 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: 2800000, guid: 400cf02f268b02e4497feb50a409aaf6, type: 3} + 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: 1 + - _AlphaToMask: 1 + - _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 + - _ReceiveFog: 1 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _ScreenSpaceReflectionsContributeTransparent: 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 &4671375416149872921 +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: 11 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat.meta new file mode 100644 index 00000000000..7adf1a3786a --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueCutoutMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7589d5749fc2d024fa6fd7adddce2401 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat new file mode 100644 index 00000000000..52de8b2ca70 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat @@ -0,0 +1,140 @@ +%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: OpaqueMaterial + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, 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: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 6874c238818721b4bb43ff107174f4bf, type: 3} + 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: 2800000, guid: 6874c238818721b4bb43ff107174f4bf, type: 3} + 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 + - _ReceiveFog: 1 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _ScreenSpaceReflectionsContributeTransparent: 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 &4671375416149872921 +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: 11 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat.meta new file mode 100644 index 00000000000..b5747fb85c6 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/OpaqueMaterial.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 497242666cbf874499ebfbace0dc368e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset new file mode 100644 index 00000000000..54948c77c48 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset @@ -0,0 +1,16 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 31c28c59441ea9d43894faa636047638, type: 3} + m_Name: ReactiveMaskShaderReference + m_EditorClassIdentifier: Tests::Unity.Rendering.Universal.Tests.UpscalerReactiveMaskShaderReference + reactiveMaskShader: {fileID: 4800000, guid: a32e79e9a0e86a14894684c864a169a3, type: 3} + resolveStencilShader: {fileID: 4800000, guid: 2e0ac57a4a0a0a944a8231539c9710ca, type: 3} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset.meta new file mode 100644 index 00000000000..8a95552b754 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ReactiveMaskShaderReference.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc53085a569e07c49ab0bae7e7e04a47 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader new file mode 100644 index 00000000000..631c90e15f5 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader @@ -0,0 +1,51 @@ +Shader "Custom/ResolveStencilReactiveMask" +{ + SubShader + { + Pass + { + ZWrite Off ZTest Always Blend Off Cull Off + + Stencil + { + ReadMask 1 + Ref 1 + Comp Equal + Pass Keep + } + + HLSLPROGRAM + + #pragma target 4.5 + #pragma vertex vert + #pragma fragment frag + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + + struct Attributes + { + uint vertexID : SV_VertexID; + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float2 texcoord : TEXCOORD0; + }; + + Varyings vert(Attributes IN) + { + Varyings OUT; + OUT.positionCS = GetFullScreenTriangleVertexPosition(IN.vertexID); + OUT.texcoord = GetFullScreenTriangleTexCoord(IN.vertexID); + return OUT; + } + + float4 frag(Varyings IN) : SV_Target + { + return float4(1, 1, 1, 1); + } + ENDHLSL + } + } +} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader.meta new file mode 100644 index 00000000000..b6da8941d0b --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/ResolveStencilReactiveMask.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2e0ac57a4a0a0a944a8231539c9710ca +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat new file mode 100644 index 00000000000..d9acbe70d0d --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat @@ -0,0 +1,144 @@ +%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: Transparent100Material + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - MOTIONVECTORS + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 596a7aed90f7f414a95cf953fcf02963, type: 3} + 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: 2800000, guid: 596a7aed90f7f414a95cf953fcf02963, type: 3} + 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: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveFog: 1 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _ScreenSpaceReflectionsContributeTransparent: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 0 + 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 &4515003758395981007 +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: 11 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat.meta new file mode 100644 index 00000000000..aaa4bf2bb93 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent100Material.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cb45a0c3362c5c841850f022e5dd6f32 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat new file mode 100644 index 00000000000..519bfdb5e18 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat @@ -0,0 +1,144 @@ +%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: Transparent50Material + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - MOTIONVECTORS + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: 596a7aed90f7f414a95cf953fcf02963, type: 3} + 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: 2800000, guid: 596a7aed90f7f414a95cf953fcf02963, type: 3} + 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: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveFog: 1 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _ScreenSpaceReflectionsContributeTransparent: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 0.49803922} + - _Color: {r: 1, g: 1, b: 1, a: 0.49803922} + - _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 &4515003758395981007 +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: 11 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat.meta new file mode 100644 index 00000000000..2350a2fb4b5 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Assets/Scenes/501_UpscalerReactiveMask/Transparent50Material.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9fd36153be2964847bb46d2d2b68966a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset index 15bf0e9a247..f1ed26ed209 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/ProjectSettings/QualitySettings.asset @@ -4,7 +4,7 @@ QualitySettings: m_ObjectHideFlags: 0 serializedVersion: 5 - m_CurrentQuality: 17 + m_CurrentQuality: 19 m_QualitySettings: - serializedVersion: 5 name: 00-DefaultURPAsset @@ -1013,6 +1013,59 @@ QualitySettings: terrainFadeLength: 5 terrainMaxTrees: 50 excludedTargetPlatforms: [] + - serializedVersion: 5 + name: 19-501_UpscalerReactiveMask + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + skinWeights: 4 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 2 + antiAliasing: 0 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + useLegacyDetailDistribution: 1 + adaptiveVsync: 0 + vSyncCount: 1 + realtimeGICPUUsage: 25 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 2 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 11400000, guid: fbcd4274d18297940be533ecef904f09, type: 2} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] m_TextureMipmapLimitGroupNames: [] m_PerPlatformDefaultQuality: Android: 0 From 6f8ca86d7c03c79d2bafc2741a836a62354fb2ad Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Wed, 23 Sep 2026 19:15:27 +0000 Subject: [PATCH 028/192] [Port] [6000.7] [UUM-151723][7000.0] Fix camera sorting layer texture scaled by 2D Render Scale --- .../2D/Rendergraph/Renderer2DRendergraph.cs | 11 ++-- .../CommonAssets/UniversalRPAsset.asset | 25 ++++---- .../Assets/Scenes/019_CameraSortingLayer.meta | 8 +++ .../Scenes/019_CameraSortingLayer.unity | 3 + .../Scenes/019_CameraSortingLayer.unity.meta | 7 +++ .../019_CameraSortingLayer.asset | 57 +++++++++++++++++++ .../019_CameraSortingLayer.asset.meta | 8 +++ .../CameraSortingLayerShadergraph.shadergraph | 3 + ...raSortingLayerShadergraph.shadergraph.meta | 20 +++++++ 9 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph.meta 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 a7d3b0a95f4..4ccb66f1e28 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 @@ -515,7 +515,7 @@ void CreateResources(RenderGraph renderGraph) CreateShadowTextures(renderGraph, width, height); - CreateCameraSortingLayerTexture(renderGraph, cameraTargetDescriptor, width, height); + CreateCameraSortingLayerTexture(renderGraph, cameraTargetDescriptor); CreateRenderingLayersTexture(renderGraph, width, height); @@ -743,17 +743,14 @@ void CreateShadowTextures(RenderGraph renderGraph, int width, int height) resourceData.shadowDepth = UniversalRenderer.CreateRenderGraphTexture(renderGraph, shadowDepthDesc, "_ShadowDepth", false, FilterMode.Bilinear); } - void CreateCameraSortingLayerTexture(RenderGraph renderGraph, RenderTextureDescriptor cameraDesc, int width, int height) + void CreateCameraSortingLayerTexture(RenderGraph renderGraph, RenderTextureDescriptor cameraDesc) { if (m_Renderer2DData.useCameraSortingLayerTexture) { Universal2DResourceData resourceData = frameData.Get(); - var desc = new RenderTextureDescriptor(width, height); - desc.graphicsFormat = cameraDesc.graphicsFormat; - - CopyCameraSortingLayerPass.ConfigureDescriptor(m_Renderer2DData.cameraSortingLayerDownsamplingMethod, ref desc, out var filterMode); - RenderingUtils.ReAllocateHandleIfNeeded(ref m_CameraSortingLayerHandle, desc, filterMode, TextureWrapMode.Clamp, name: CopyCameraSortingLayerPass.k_CameraSortingLayerTexture); + CopyCameraSortingLayerPass.ConfigureDescriptor(m_Renderer2DData.cameraSortingLayerDownsamplingMethod, ref cameraDesc, out var filterMode); + RenderingUtils.ReAllocateHandleIfNeeded(ref m_CameraSortingLayerHandle, cameraDesc, filterMode, TextureWrapMode.Clamp, name: CopyCameraSortingLayerPass.k_CameraSortingLayerTexture); resourceData.cameraSortingLayerTexture = renderGraph.ImportTexture(m_CameraSortingLayerHandle); } } diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset index f7158b7ccfe..4e7a5784f31 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset @@ -12,8 +12,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: bf2edee5c58d82540a51f03df9d42094, type: 3} m_Name: UniversalRPAsset m_EditorClassIdentifier: - k_AssetVersion: 13 - k_AssetPreviousVersion: 13 + k_AssetVersion: 14 + k_AssetPreviousVersion: 14 m_RendererType: 1 m_RendererData: {fileID: 0} m_RendererDataList: @@ -29,6 +29,7 @@ MonoBehaviour: - {fileID: 11400000, guid: 01e79ba8f42c808448b7542939affccb, type: 2} - {fileID: 11400000, guid: 9b5b99c05ab3ae148b6d8faf2da44518, type: 2} - {fileID: 11400000, guid: 08012fb08abf2894db49f34a37e68159, type: 2} + - {fileID: 11400000, guid: 039e24411cea2f6498a6a0733989ae55, type: 2} m_DefaultRendererIndex: 2 m_RequireDepthTexture: 0 m_RequireOpaqueTexture: 0 @@ -36,7 +37,6 @@ MonoBehaviour: m_SupportsTerrainHoles: 1 m_SupportsHDR: 1 m_HDRColorBufferPrecision: 0 - m_IntermediateTextureMode: 1 m_MSAA: 4 m_RenderScale: 1 m_UpscalingFilter: 0 @@ -45,6 +45,7 @@ MonoBehaviour: m_EnableLODCrossFade: 1 m_LODCrossFadeDitheringType: 1 m_ShEvalMode: 0 + m_LightFalloffMode: 0 m_LightProbeSystem: 0 m_ProbeVolumeMemoryBudget: 1024 m_ProbeVolumeBlendingMemoryBudget: 256 @@ -86,7 +87,6 @@ MonoBehaviour: m_MixedLightingSupported: 1 m_SupportsLightCookies: 1 m_SupportsLightLayers: 0 - m_DebugLevel: 0 m_StoreActionsOptimization: 0 m_UseAdaptivePerformance: 1 m_ColorGradingMode: 0 @@ -97,6 +97,7 @@ MonoBehaviour: m_SupportScreenSpaceLensFlare: 1 m_GPUResidentDrawerMode: 0 m_SmallMeshScreenPercentage: 0 + m_ShadowSmallMeshScreenPercentages: {x: 0, y: 0, z: 0, w: 0} m_GPUResidentDrawerEnableOcclusionCullingInCameras: 0 m_ShadowType: 0 m_LocalShadowsSupported: 1 @@ -119,19 +120,13 @@ MonoBehaviour: m_PrefilteringModeForwardPlus: 1 m_PrefilteringModeDeferredRendering: 1 m_PrefilteringModeScreenSpaceOcclusion: 1 + m_PrefilteringModeScreenSpaceReflection: 1 + m_PrefilterWriteSmoothness: 1 m_PrefilterDebugKeywords: 0 m_PrefilterWriteRenderingLayers: 0 m_PrefilterHDROutput: 0 m_PrefilterAlphaOutput: 0 - m_PrefilterSSAODepthNormals: 0 - m_PrefilterSSAOSourceDepthLow: 0 - m_PrefilterSSAOSourceDepthMedium: 0 - m_PrefilterSSAOSourceDepthHigh: 0 - m_PrefilterSSAOInterleaved: 0 - m_PrefilterSSAOBlueNoise: 0 - m_PrefilterSSAOSampleCountLow: 0 - m_PrefilterSSAOSampleCountMedium: 0 - m_PrefilterSSAOSampleCountHigh: 0 + m_PrefilterSSAOKeywords: 0 m_PrefilterDBufferMRT1: 0 m_PrefilterDBufferMRT2: 0 m_PrefilterDBufferMRT3: 0 @@ -148,6 +143,10 @@ MonoBehaviour: m_PrefilterReflectionProbeBlending: 0 m_PrefilterReflectionProbeBoxProjection: 0 m_PrefilterReflectionProbeAtlas: 0 + m_PrefilterPointSamplingUpsampling: 0 + m_PrefilterExposure: 0 + m_Light2DPrefilteringMode: 0 + m_Light2DKeptVariantCombos: [] m_ShaderVariantLogLevel: 0 m_ShadowCascades: 3 m_Textures: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.meta new file mode 100644 index 00000000000..243ad472167 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8301aaa07078a7948bc53346a2460432 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity new file mode 100644 index 00000000000..41bf3b1908d --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5260dba0c55dbb5af1c2306eb860ba6e24628cef8422c294f49e2c6761b094d1 +size 15703 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity.meta new file mode 100644 index 00000000000..aabc3170314 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0e9e40b7c057ccd428e42df5b831425f +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset new file mode 100644 index 00000000000..fc160328dcf --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset @@ -0,0 +1,57 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 11145981673336645838492a2d98e247, type: 3} + m_Name: 019_CameraSortingLayer + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.2D.Runtime::UnityEngine.Rendering.Universal.Renderer2DData + 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: [] + m_RendererFeatureMap: + m_LayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 1, z: 0} + m_HDREmulationScale: 1 + m_LightRenderTextureScale: 1 + m_LightBlendStyles: + - name: Multiply + maskTextureChannel: 0 + blendMode: 1 + - name: Additive + maskTextureChannel: 0 + blendMode: 0 + - name: Multiply with Mask + maskTextureChannel: 1 + blendMode: 1 + - name: Additive with Mask + maskTextureChannel: 1 + blendMode: 0 + m_UseDepthStencilBuffer: 1 + m_UseCameraSortingLayersTexture: 1 + m_CameraSortingLayersTextureBound: -538112021 + m_CameraSortingLayerDownsamplingMethod: 0 + m_MaxLightRenderTextureCount: 16 + m_MaxShadowRenderTextureCount: 1 + m_PostProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} + m_DefaultMaterialType: 0 + m_DefaultCustomMaterial: {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset.meta new file mode 100644 index 00000000000..948d4ad539f --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/019_CameraSortingLayer.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 039e24411cea2f6498a6a0733989ae55 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph new file mode 100644 index 00000000000..8c3b52b7e6f --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5d7e24e9ff0e6eac80adcd7d76fc69795ba276d867590945b9b29a38d85bf83 +size 20658 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph.meta new file mode 100644 index 00000000000..342aaff336b --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/019_CameraSortingLayer/CameraSortingLayerShadergraph.shadergraph.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: 58348bacb03e6f248929a95f2514d1a3 +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 From 9b0ab8bbf30e69f92b9bc5e4465c4fac54b60d30 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Wed, 23 Sep 2026 19:15:30 +0000 Subject: [PATCH 029/192] [Port] [6000.7] Handle case where Meta Pass isn't compiled yet on modification with SCGI --- .../SurfaceCacheWorldAdapter.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs index ca9f566866e..17a254ba6d2 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs @@ -1186,10 +1186,7 @@ public MaterialHandle Acquire(EntityId matEntityId, Material mat, SurfaceCacheWo } else { - var oldAllowAsyncCompilation = UnityEditor.ShaderUtil.allowAsyncCompilation; - UnityEditor.ShaderUtil.allowAsyncCompilation = false; - descriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(_fallbackMaterial, kEmissionMode); - UnityEditor.ShaderUtil.allowAsyncCompilation = oldAllowAsyncCompilation; + descriptor = GetFallbackMaterialDescriptor(); _pendingMetaPassEvals.Add(matEntityId); UnityEditor.ShaderUtil.CompilePass(mat, metaPassIndex); } @@ -1245,6 +1242,27 @@ public void Update(EntityId matEntityId, Material material, SurfaceCacheWorld wo if (!_pendingMetaPassEvals.Contains(matEntityId)) { +#if UNITY_EDITOR + // If the shader was modified, the meta pass may have been deleted, or not yet compiled. + var metaPassIndex = material.FindPass("Meta"); + if (metaPassIndex == -1) + { + var fallbackEntry = _entries[matEntityId]; + DestroyDescriptorTextures(fallbackEntry.Descriptor); + fallbackEntry.Descriptor = GetFallbackMaterialDescriptor(); + _entries[matEntityId] = fallbackEntry; + + world.UpdateMaterial(fallbackEntry.WorldHandle, in fallbackEntry.Descriptor, kUVChannel); + return; + } + else if (!UnityEditor.ShaderUtil.IsPassCompiled(material, metaPassIndex)) + { + _pendingMetaPassEvals.Add(matEntityId); + UnityEditor.ShaderUtil.CompilePass(material, metaPassIndex); + return; + } +#endif + var entry = _entries[matEntityId]; DestroyDescriptorTextures(entry.Descriptor); entry.Descriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(material, kEmissionMode); @@ -1287,6 +1305,17 @@ public void CleanUp(SurfaceCacheWorld world) RemoveHandle(id, world); } +#if UNITY_EDITOR + MaterialPool.MaterialDescriptor GetFallbackMaterialDescriptor() + { + var oldAllowAsyncCompilation = UnityEditor.ShaderUtil.allowAsyncCompilation; + UnityEditor.ShaderUtil.allowAsyncCompilation = false; + var descriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(_fallbackMaterial, kEmissionMode); + UnityEditor.ShaderUtil.allowAsyncCompilation = oldAllowAsyncCompilation; + return descriptor; + } +#endif + void RemoveHandle(EntityId matEntityId, SurfaceCacheWorld world) { _pendingMetaPassEvals.Remove(matEntityId); From 316ddc621f7ef69192f898e56fef6d52373627ab Mon Sep 17 00:00:00 2001 From: Evergreen Date: Wed, 23 Sep 2026 19:15:31 +0000 Subject: [PATCH 030/192] [UUM-152671] Disable 3 unstable Materials Playmode tests --- .../Assets/GraphicTests/Tests/SkyAndFog.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs index ebe3135bca6..d047449a48b 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs +++ b/Tests/SRPTests/Projects/HDRP_Tests/Assets/GraphicTests/Tests/SkyAndFog.cs @@ -116,6 +116,24 @@ public SkyAndFogTests(GpuResidentDrawerContext grdContext) : base(grdContext) { RuntimePlatform.OSXEditor, RuntimePlatform.WindowsEditor, GraphicsDeviceType.Metal, GraphicsDeviceType.Vulkan )] + [IgnoreGraphicsTest( + "5011_VolumetricCloudsShadowsBake", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5011_VolumetricCloudsShadows", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Direct3D12, GraphicsDeviceType.Vulkan + )] + [IgnoreGraphicsTest( + "5011_VolumetricClouds", + "Disabled for Instability https://jira.unity3d.com/browse/UUM-152671", + RuntimePlatform.WindowsEditor, + GraphicsDeviceType.Vulkan + )] [TestNotSupportedOn( "501[0-5]|5020", "Not XR compatible", From b44cc05119e22ccbb378cc22bed368f7d2d86d6b Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 00:42:48 +0000 Subject: [PATCH 031/192] [Port] [6000.7] Fix MSAA error in the Rendering Debugger Motion Vector view --- .../Runtime/UniversalRendererDebug.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererDebug.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererDebug.cs index 9bafb524f7c..823ef55b132 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererDebug.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererDebug.cs @@ -6,8 +6,6 @@ namespace UnityEngine.Rendering.Universal { public sealed partial class UniversalRenderer { - Material m_DebugBlitMaterial = Blitter.GetBlitMaterial(TextureXR.dimension); - bool DebugHandlerRequireDepthPass(UniversalCameraData cameraData) { if ((DebugHandler != null) && DebugHandler.IsActiveForCamera(cameraData.isPreviewCamera)) @@ -25,6 +23,8 @@ void CreateDebugTexture(RenderTextureDescriptor descriptor) debugTexDescriptor.useMipMap = false; debugTexDescriptor.autoGenerateMips = false; debugTexDescriptor.bindMS = false; + // The debug texture is only sampled as a fullscreen overlay, it is never a multisampled attachment. + debugTexDescriptor.msaaSamples = 1; debugTexDescriptor.depthStencilFormat = GraphicsFormat.None; RenderingUtils.ReAllocateHandleIfNeeded(ref s_RenderGraphDebugTextureHandle, debugTexDescriptor, FilterMode.Point, TextureWrapMode.Clamp, name: "_RenderingDebuggerTexture"); @@ -109,7 +109,7 @@ private void SetupRenderGraphFinalPassDebug(RenderGraph renderGraph, ContextCont } case DebugFullScreenMode.MotionVector: { - BlitToDebugTexture(renderGraph, resourceData.motionVectorColor, debugTexture, isSourceTextureColor: true); + BlitToDebugTexture(renderGraph, resourceData.motionVectorColor, debugTexture); supportsStereo = true; // Motion vectors are in signed UV space, zoom in and normalize for visualization. (note: maybe add an option to use (angle, mag) visualization) const float zoom = 0.01f; @@ -230,25 +230,14 @@ class CopyToDebugTexturePassData internal TextureHandle dest; } - private void BlitToDebugTexture(RenderGraph renderGraph, in TextureHandle source, in TextureHandle destination, bool isSourceTextureColor = false) + private void BlitToDebugTexture(RenderGraph renderGraph, in TextureHandle source, in TextureHandle destination) { if (source.IsValid()) { - if (isSourceTextureColor) // Use AddCopyPass (RasterRenderPass) when we can - { - renderGraph.AddCopyPass(source, destination); - } - else // Use direct blit (UnsafePass) - { - var blitMaterialParameters = - new RenderGraphModule.Util.RenderGraphUtils.BlitMaterialParameters( - source, destination, - m_DebugBlitMaterial, 0); - - renderGraph.AddBlitPass(blitMaterialParameters); - } + // AddBlitPass does implicit CopyPass optimization when compatible. + renderGraph.AddBlitPass(source, destination, Vector2.one, Vector2.zero, filterMode: RenderGraphModule.Util.RenderGraphUtils.BlitFilterMode.ClampNearest); } - else // Texture is invalid, just show a black view + else { BlitEmptyTexture(renderGraph, destination); } From 0563c15b64af891ceff452cab26b53f21401a51d Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 05:47:34 +0000 Subject: [PATCH 032/192] [Port] [6000.7] [XR] Fix Quad View inset jitter artifacts from eye-tracking with AppSW --- .../Runtime/Passes/XRDepthMotionPass.cs | 90 ++++++++++--------- .../Shaders/XR/XRMotionVector.shader | 30 +++++-- 2 files changed, 70 insertions(+), 50 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs index a836309af4d..210b9350ea3 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs @@ -22,6 +22,7 @@ public class XRDepthMotionPass : ScriptableRenderPass private static readonly int k_QuadViewMVTex = Shader.PropertyToID("_QuadViewMVTex"); private static readonly int k_QuadViewUVScales = Shader.PropertyToID("_QuadViewUVScales"); private static readonly int k_QuadViewUVOffsets = Shader.PropertyToID("_QuadViewUVOffsets"); + private static readonly int k_QuadViewPrevUVOffsets = Shader.PropertyToID("_QuadViewPrevUVOffsets"); private RTHandle m_XRMotionVectorColor; private TextureHandle xrMotionVectorColor; private RTHandle m_XRMotionVectorDepth; @@ -34,6 +35,8 @@ public class XRDepthMotionPass : ScriptableRenderPass private RTHandle m_QuadViewOuterMV; // Store outer dimensions; symmetric projection can give the outer swapchain a FoV-adjusted width that differs from the inner private RenderTargetInfo m_QuadViewOuterMVImportInfo; + // Previous-frame inner UV offsets for the gaze-shift MV correction. NaN until the first inner pass Render. + private Vector4 m_PreviousQuadViewUVOffsets = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN); /// /// Creates a new XRDepthMotionPass instance. @@ -269,54 +272,51 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) // First, import XR motion color and depth targets into the RenderGraph ImportXRMotionColorAndDepth(renderGraph, cameraData); - // Skipped under Temporal Pixel Synthesis because reprojection does not write the stencil - // bits the TPS compositor uses to exclude transparents from temporal reuse. - if (!cameraData.xr.isTemporalPixelSynthesisActive) + // For Quad View inner pass: reproject the outer MV texture rather than re-rendering all objects + if (cameraData.xr.isQuadViewInnerPass) { - // For Quad View inner pass: reproject the outer MV texture rather than re-rendering all objects - if (cameraData.xr.isQuadViewInnerPass) + // Skipped under TPS because reprojection does not yet write the stencil bits needed to exclude transparents from temporal reuse. + if (m_QuadViewOuterMV != null && !cameraData.xr.isTemporalPixelSynthesisActive) { - if (m_QuadViewOuterMV != null) - { - RecordReprojectionPass(renderGraph, cameraData); - return; - } + RecordReprojectionPass(renderGraph, cameraData); + m_PreviousQuadViewUVOffsets = cameraData.xr.uvOffsets; + return; } - else if (cameraData.xr.xrLayoutType == XRLayoutType.TwoPassQuadViews) + m_PreviousQuadViewUVOffsets = cameraData.xr.uvOffsets; + } + else if (cameraData.xr.xrLayoutType == XRLayoutType.TwoPassQuadViews && !cameraData.xr.isTemporalPixelSynthesisActive) + { + // Outer pass: capture the MV target for the inner reprojection to read + var outerTargetId = cameraData.xr.motionVectorRenderTarget; + if (m_QuadViewOuterMV == null) + m_QuadViewOuterMV = RTHandles.Alloc(outerTargetId); + else if (m_QuadViewOuterMV.nameID != outerTargetId) + RTHandleStaticHelpers.SetRTHandleUserManagedWrapper(ref m_QuadViewOuterMV, outerTargetId); + + // Save dimensions; symmetric projection can give the outer a different width than the inner + var desc = cameraData.xr.motionVectorRenderTargetDesc; + m_QuadViewOuterMVImportInfo = new RenderTargetInfo { - // Outer pass: capture the MV target for the inner reprojection to read - var outerTargetId = cameraData.xr.motionVectorRenderTarget; - if (m_QuadViewOuterMV == null) - m_QuadViewOuterMV = RTHandles.Alloc(outerTargetId); - else if (m_QuadViewOuterMV.nameID != outerTargetId) - RTHandleStaticHelpers.SetRTHandleUserManagedWrapper(ref m_QuadViewOuterMV, outerTargetId); - - // Save dimensions; symmetric projection can give the outer a different width than the inner - var desc = cameraData.xr.motionVectorRenderTargetDesc; - m_QuadViewOuterMVImportInfo = new RenderTargetInfo - { - width = desc.width, - height = desc.height, - volumeDepth = desc.volumeDepth, - msaaSamples = desc.msaaSamples, - format = desc.graphicsFormat - }; - - // m_XRMotionVectorColor/Depth would be mutated in-place when the inner pass calls ImportXRMotionColorAndDepth, corrupting the handles. - // Instead, re-import via separate m_QuadViewOuterMV so the outer pass's attachments resolve to the correct native texture at execution time. - var outerAttachmentParams = new ImportResourceParams - { - // Stencil must be cleared to 0 each frame for Pass 0's stencil test - clearOnFirstUse = true, - clearColor = Color.black, - discardOnLastUse = false - }; - xrMotionVectorColor = renderGraph.ImportTexture(m_QuadViewOuterMV, m_QuadViewOuterMVImportInfo, outerAttachmentParams); - var outerDepthInfo = m_QuadViewOuterMVImportInfo; - outerDepthInfo.format = desc.depthStencilFormat; - xrMotionVectorDepth = renderGraph.ImportTexture(m_QuadViewOuterMV, outerDepthInfo, outerAttachmentParams); + width = desc.width, + height = desc.height, + volumeDepth = desc.volumeDepth, + msaaSamples = desc.msaaSamples, + format = desc.graphicsFormat + }; - } + // m_XRMotionVectorColor/Depth would be mutated in-place when the inner pass calls ImportXRMotionColorAndDepth, corrupting the handles. + // Instead, re-import via separate m_QuadViewOuterMV so the outer pass's attachments resolve to the correct native texture at execution time. + var outerAttachmentParams = new ImportResourceParams + { + // Stencil must be cleared to 0 each frame for Pass 0's stencil test + clearOnFirstUse = true, + clearColor = Color.black, + discardOnLastUse = false + }; + xrMotionVectorColor = renderGraph.ImportTexture(m_QuadViewOuterMV, m_QuadViewOuterMVImportInfo, outerAttachmentParams); + var outerDepthInfo = m_QuadViewOuterMVImportInfo; + outerDepthInfo.format = desc.depthStencilFormat; + xrMotionVectorDepth = renderGraph.ImportTexture(m_QuadViewOuterMV, outerDepthInfo, outerAttachmentParams); } // These flags are still required in SRP or the engine won't compute previous model matrices... @@ -443,6 +443,8 @@ private void RecordReprojectionPass(RenderGraph renderGraph, UniversalCameraData var uvScales = cameraData.xr.uvScales; var uvOffsets = cameraData.xr.uvOffsets; + // Fall back to the current offset if we don't have the immediately previous frame. + var prevUVOffsets = float.IsNaN(m_PreviousQuadViewUVOffsets.x) ? uvOffsets : m_PreviousQuadViewUVOffsets; using (var builder = renderGraph.AddRasterRenderPass( "XR MotionVector QuadView Reprojection", out var passData, base.profilingSampler)) @@ -462,6 +464,7 @@ private void RecordReprojectionPass(RenderGraph renderGraph, UniversalCameraData context.cmd.SetGlobalTexture(k_XRDepthTextureNameID, data.outerDepthSrc, RenderTextureSubElement.Depth); context.cmd.SetGlobalVector(k_QuadViewUVScales, uvScales); context.cmd.SetGlobalVector(k_QuadViewUVOffsets, uvOffsets); + context.cmd.SetGlobalVector(k_QuadViewPrevUVOffsets, prevUVOffsets); context.cmd.DrawProcedural(Matrix4x4.identity, m_XRMotionVectorMaterial, shaderPass: 2, MeshTopology.Triangles, 3, 1); }); @@ -477,6 +480,7 @@ private void ResetMotionData() m_PreviousViewProjection[i] = Matrix4x4.identity; } m_LastFrameIndex = -1; + m_PreviousQuadViewUVOffsets = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN); } /// diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader b/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader index 1d242ac62e9..348b2899193 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/XR/XRMotionVector.shader @@ -238,11 +238,13 @@ Shader "Hidden/Universal Render Pipeline/XR/XRMotionVector" // ------------------------------------- // Constants - float4 _QuadViewUVScales; // inner-to-outer UV scale, xy = left eye, zw = right eye - float4 _QuadViewUVOffsets; // inner-to-outer UV offset, xy = left eye, zw = right eye + float _SpaceWarpNDCModifier; + float4 _QuadViewUVScales; // inner-to-outer UV scale, xy = left eye, zw = right eye + float4 _QuadViewUVOffsets; // inner-to-outer UV offset (curr), xy = left eye, zw = right eye + float4 _QuadViewPrevUVOffsets; // inner-to-outer UV offset (prev), xy = left eye, zw = right eye TEXTURE2D_X(_QuadViewMVTex); - SAMPLER(sampler_QuadViewMVTex); + SAMPLER(s_point_clamp_sampler); TEXTURE2D_X(_XRDepthTexture); SAMPLER(sampler_XRDepthTexture); @@ -279,8 +281,9 @@ Shader "Hidden/Universal Render Pipeline/XR/XRMotionVector" { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - float2 uvScale = unity_StereoEyeIndex == 0 ? _QuadViewUVScales.xy : _QuadViewUVScales.zw; - float2 uvOffset = unity_StereoEyeIndex == 0 ? _QuadViewUVOffsets.xy : _QuadViewUVOffsets.zw; + float2 uvScale = unity_StereoEyeIndex == 0 ? _QuadViewUVScales.xy : _QuadViewUVScales.zw; + float2 uvOffset = unity_StereoEyeIndex == 0 ? _QuadViewUVOffsets.xy : _QuadViewUVOffsets.zw; + float2 prevUVOffset = unity_StereoEyeIndex == 0 ? _QuadViewPrevUVOffsets.xy : _QuadViewPrevUVOffsets.zw; // Remap inner UV to the outer MV texture. // uvOffset.y uses (1 - uvScale.y - uvOffset.y) because the OpenXR Vulkan projection inverts the sign fed to ExtractFrustumBoundsFromProjection @@ -292,8 +295,21 @@ Shader "Hidden/Universal Render Pipeline/XR/XRMotionVector" outDepth = SAMPLE_TEXTURE2D_X(_XRDepthTexture, sampler_XRDepthTexture, outerUV).x; - float4 outerMV = SAMPLE_TEXTURE2D_X(_QuadViewMVTex, sampler_QuadViewMVTex, outerUV); - return float4(outerMV.x / uvScale.x, outerMV.y / uvScale.y, outerMV.z, 0); + float4 outerMV = SAMPLE_TEXTURE2D_X(_QuadViewMVTex, s_point_clamp_sampler, outerUV); + + // Gaze-shift correction: when the inner frustum center moves between frames due to eye tracking, the inner MVs must also pan by that amount. + // The UV-space offset delta is converted to NDC-space ([0,1] UV -> [-1, 1] NDC) + // The Y term is then brought into the SpaceWarp NDC convention via _SpaceWarpNDCModifier, matching Passes 0 and 1 + float panX = 2.0 * (prevUVOffset.x - uvOffset.x) / uvScale.x; + float panY = 2.0 * (prevUVOffset.y - uvOffset.y) / uvScale.y; + #if UNITY_UV_STARTS_AT_TOP + panY *= _SpaceWarpNDCModifier; + #endif + + return float4(outerMV.x / uvScale.x + panX, + outerMV.y / uvScale.y + panY, + outerMV.z, + 0); } ENDHLSL } From ee99e7575afcdd2332b00775673d5bfd1c892d72 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:09 +0000 Subject: [PATCH 033/192] [Port] [6000.7] [UUM-153342] [URP 2D] [7000.0] Fix Render Objects feature failing when depth buffer is disabled --- .../Runtime/Passes/RenderObjectsPass.cs | 25 +++-- .../CommonAssets/UniversalRPAsset.asset | 1 + .../064_RenderObjectsRendererFeature.meta | 8 ++ .../064_RenderObjectsRendererFeature.unity | 3 + ...64_RenderObjectsRendererFeature.unity.meta | 7 ++ ...4_RenderObjectsFeature Renderer Data.asset | 103 ++++++++++++++++++ ...derObjectsFeature Renderer Data.asset.meta | 8 ++ 7 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset.meta 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 3988d6c3fe6..47f7f89922e 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/RenderObjectsPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/RenderObjectsPass.cs @@ -239,6 +239,7 @@ private void InitPassData(UniversalCameraData cameraData, ref PassData passData, passData.renderPassEvent = renderPassEvent; passData.cameraData = cameraData; passData.isActiveTargetBackBuffer = isActiveTargetBackBuffer; + passData.depthInputAttachment = false; } private void InitRendererLists(UniversalRenderingData renderingData, UniversalLightData lightData, @@ -283,18 +284,20 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.color = resourceData.activeColorTexture; builder.SetRenderAttachment(resourceData.activeColorTexture, 0, AccessFlags.Write); - // Configure depth attachment based on input attachment setting - if (m_DepthInputAttachment && SystemInfo.supportsDepthAttachmentAsInputAttachment) + if (resourceData.activeDepthTexture.IsValid()) { - // 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; + // 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); + } } TextureHandle mainShadowsTexture = resourceData.mainShadowsTexture; diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset index 4e7a5784f31..8e73cae5ae2 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/CommonAssets/UniversalRPAsset.asset @@ -30,6 +30,7 @@ MonoBehaviour: - {fileID: 11400000, guid: 9b5b99c05ab3ae148b6d8faf2da44518, type: 2} - {fileID: 11400000, guid: 08012fb08abf2894db49f34a37e68159, type: 2} - {fileID: 11400000, guid: 039e24411cea2f6498a6a0733989ae55, type: 2} + - {fileID: 11400000, guid: 47f3a0f49714d5f47948925871b58f11, type: 2} m_DefaultRendererIndex: 2 m_RequireDepthTexture: 0 m_RequireOpaqueTexture: 0 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.meta new file mode 100644 index 00000000000..ee7194ae5df --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 482f5f7db6d987e429befdd7278a5d9c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity new file mode 100644 index 00000000000..385a82b3244 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52dacc1ea49443096a32012db59f06d6e524175ae00515223655a716c9873479 +size 13671 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity.meta new file mode 100644 index 00000000000..b74731493a8 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e65c52bd72bcbed4d8916dfcf926bb4c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset new file mode 100644 index 00000000000..c5dfdc96bd3 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset @@ -0,0 +1,103 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5415328978193341103 +MonoBehaviour: + m_ObjectHideFlags: 1 + 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: 1 + LayerMask: + serializedVersion: 2 + m_Bits: 4294967295 + PassNames: [] + overrideMaterial: {fileID: 0} + overrideMaterialPassIndex: 0 + overrideShader: {fileID: 0} + overrideShaderPassIndex: 0 + overrideMode: 1 + overrideDepthState: 0 + depthCompareFunction: 4 + enableWrite: 1 + stencilSettings: + overrideStencilState: 0 + stencilReference: 0 + stencilReadMask: 15 + stencilWriteMask: 15 + stencilCompareFunction: 8 + passOperation: 0 + failOperation: 0 + zFailOperation: 0 + cameraSettings: + overrideCamera: 0 + restoreCamera: 1 + offset: {x: 0, y: 0, z: 0, w: 0} + cameraFieldOfView: 60 + depthInputAttachment: 0 +--- !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: 11145981673336645838492a2d98e247, type: 3} + m_Name: 064_RenderObjectsFeature Renderer Data + m_EditorClassIdentifier: Unity.RenderPipelines.Universal.2D.Runtime::UnityEngine.Rendering.Universal.Renderer2DData + 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: -5415328978193341103} + m_RendererFeatureMap: 5125e868fce2d8b4l + m_LayerMask: + serializedVersion: 2 + m_Bits: 0 + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 1, z: 0} + m_HDREmulationScale: 1 + m_LightRenderTextureScale: 0.5 + m_LightBlendStyles: + - name: Multiply + maskTextureChannel: 0 + blendMode: 1 + - name: Additive + maskTextureChannel: 0 + blendMode: 0 + - name: Multiply with Mask + maskTextureChannel: 1 + blendMode: 1 + - name: Additive with Mask + maskTextureChannel: 1 + blendMode: 0 + m_UseDepthStencilBuffer: 0 + m_UseCameraSortingLayersTexture: 0 + m_CameraSortingLayersTextureBound: -1 + m_CameraSortingLayerDownsamplingMethod: 0 + m_MaxLightRenderTextureCount: 16 + m_MaxShadowRenderTextureCount: 1 + m_PostProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} + m_DefaultMaterialType: 0 + m_DefaultCustomMaterial: {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset.meta new file mode 100644 index 00000000000..756a3402a97 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/064_RenderObjectsRendererFeature/064_RenderObjectsFeature Renderer Data.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 47f3a0f49714d5f47948925871b58f11 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: From e885964549212b6e20fb169d0bb496d01faafea7 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:09 +0000 Subject: [PATCH 034/192] [Port] [6000.7] Set HideAndDontSave on blit meshes so they survive scene reload --- .../Runtime/Utilities/Blitter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 27bdaebc584..c83b3312af5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs @@ -214,7 +214,7 @@ public static void Initialize(Shader blitPS, Shader blitColorAndDepthPS) { if (!s_TriangleMesh) { - s_TriangleMesh = new Mesh(); + s_TriangleMesh = new Mesh { hideFlags = HideFlags.HideAndDontSave }; s_TriangleMesh.vertices = GetFullScreenTriangleVertexPosition(nearClipZ); s_TriangleMesh.uv = GetFullScreenTriangleTexCoord(); s_TriangleMesh.triangles = new int[3] { 0, 1, 2 }; @@ -222,7 +222,7 @@ public static void Initialize(Shader blitPS, Shader blitColorAndDepthPS) } if (!s_QuadMesh) { - s_QuadMesh = new Mesh(); + s_QuadMesh = new Mesh { hideFlags = HideFlags.HideAndDontSave }; s_QuadMesh.vertices = GetQuadVertexPosition(nearClipZ); s_QuadMesh.uv = GetQuadTexCoord(); s_QuadMesh.triangles = new int[6] { 0, 1, 2, 0, 2, 3 }; From b3576ff438aabeb03505fec8358af3158256be82 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:10 +0000 Subject: [PATCH 035/192] [Port] [6000.7] Don't render SSR in material previews --- .../ScreenSpaceReflectionRendererFeature.cs | 5 +++++ 1 file changed, 5 insertions(+) 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 0f5334f9983..1a8b63af0dc 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 @@ -47,6 +47,11 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD if (UniversalRenderer.IsOffscreenDepthTexture(universalCameraData)) return; + // Only allow in preview cameras via the RenderRequest API (i.e. 'Cameras' overlay in scene view) + // Don't allow regular preview cameras (i.e. thumbnails, material previews) + if (universalCameraData.isPreviewCamera && !universalCameraData.camera.isProcessingRenderRequest) + return; + // Currently no orthographic support, so ignore these cameras. if (universalCameraData.camera.orthographic) return; From 317f4d6a76193732a2c9fa7012116c18bf99f6a5 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:10 +0000 Subject: [PATCH 036/192] [Port] [6000.7] Handle deleted meshes in SCGI --- .../SurfaceCache/SurfaceCacheWorld.cs | 2 +- .../ObjectDispatcherChangeSource.cs | 12 +++- .../SurfaceCacheWorldAdapter.cs | 40 +++++++++-- .../SurfaceCacheWorldChangeSet.cs | 2 + .../SurfaceCacheWorldAdapterTests.cs | 69 +++++++++++++++++++ 5 files changed, 115 insertions(+), 10 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCacheWorld.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCacheWorld.cs index 75c2c9a4091..3629281874b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCacheWorld.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/SurfaceCacheWorld.cs @@ -820,7 +820,7 @@ void UntrackInstance(InstanceHandle instanceHandle) bool foundInstanceIDs = _rayTracingAccelerationStructure.GetInstanceIDs(instanceHandle.Value, out int[] instanceIDs); Debug.Assert(foundInstanceIDs, "Instance was not in acceleration structure."); - for (int subMeshIdx = 0; subMeshIdx < info.Mesh.subMeshCount; subMeshIdx++) + for (int subMeshIdx = 0; subMeshIdx < info.SubMeshEmissiveMask.Length; subMeshIdx++) { if (!info.SubMeshEmissiveMask[subMeshIdx]) continue; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ObjectDispatcherChangeSource.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ObjectDispatcherChangeSource.cs index a122db4a2ab..5d3825db346 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ObjectDispatcherChangeSource.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/ObjectDispatcherChangeSource.cs @@ -22,6 +22,7 @@ public ObjectDispatcherChangeSource() _dispatcher.EnableTypeTracking(ObjectDispatcher.TypeTrackingFlags.SceneObjects); _dispatcher.EnableTransformTracking(ObjectDispatcher.TransformTrackingType.GlobalTRS); _dispatcher.EnableTypeTracking(ObjectDispatcher.TypeTrackingFlags.SceneObjects | ObjectDispatcher.TypeTrackingFlags.Assets); + _dispatcher.EnableTypeTracking(ObjectDispatcher.TypeTrackingFlags.SceneObjects | ObjectDispatcher.TypeTrackingFlags.Assets); #if ENABLE_TERRAIN_MODULE _dispatcher.EnableTypeTracking(ObjectDispatcher.TypeTrackingFlags.SceneObjects); _dispatcher.EnableTransformTracking(ObjectDispatcher.TransformTrackingType.GlobalTRS); @@ -40,6 +41,7 @@ public ObjectDispatcherChangeSet CollectChanges() var lightTransforms = _dispatcher.GetTransformChangesAndClear(ObjectDispatcher.TransformTrackingType.GlobalTRS, false); var lightTypeChanges = _dispatcher.GetTypeChangesAndClear(Allocator.Temp); var materialTypeChanges = _dispatcher.GetTypeChangesAndClear(Allocator.Temp); + var meshTypeChanges = _dispatcher.GetTypeChangesAndClear(Allocator.Temp, noScriptingArray: true); #if ENABLE_TERRAIN_MODULE var terrainTransforms = _dispatcher.GetTransformChangesAndClear(ObjectDispatcher.TransformTrackingType.GlobalTRS, false); var terrainTypeChanges = _dispatcher.GetTypeChangesAndClear(Allocator.Temp); @@ -56,6 +58,7 @@ public ObjectDispatcherChangeSet CollectChanges() LightChangedList = lightTypeChanges.changed, LightDestroyedList = lightTypeChanges.destroyedID, MaterialChangedList = materialTypeChanges.changed, + MeshDestroyedList = meshTypeChanges.destroyedID, #if ENABLE_TERRAIN_MODULE TerrainTransformChangedList = terrainTransforms, TerrainChangedList = terrainTypeChanges.changed, @@ -69,7 +72,8 @@ public ObjectDispatcherChangeSet CollectChanges() meshRendererTransforms, meshRendererTypeChanges, lightTypeChanges, - materialTypeChanges + materialTypeChanges, + meshTypeChanges #if ENABLE_TERRAIN_MODULE , terrainTypeChanges , terrainDataTypeChanges @@ -89,6 +93,7 @@ public void Dispose() readonly TypeDispatchData _meshRendererTypeChanges; readonly TypeDispatchData _lightTypeChanges; readonly TypeDispatchData _materialTypeChanges; + readonly TypeDispatchData _meshTypeChanges; #if ENABLE_TERRAIN_MODULE readonly TypeDispatchData _terrainTypeChanges; readonly TypeDispatchData _terrainDataTypeChanges; @@ -101,7 +106,8 @@ internal ObjectDispatcherChangeSet( TransformDispatchData meshRendererTransforms, TypeDispatchData meshRendererTypeChanges, TypeDispatchData lightTypeChanges, - TypeDispatchData materialTypeChanges + TypeDispatchData materialTypeChanges, + TypeDispatchData meshTypeChanges #if ENABLE_TERRAIN_MODULE , TypeDispatchData terrainTypeChanges , TypeDispatchData terrainDataTypeChanges @@ -113,6 +119,7 @@ TypeDispatchData materialTypeChanges _meshRendererTypeChanges = meshRendererTypeChanges; _lightTypeChanges = lightTypeChanges; _materialTypeChanges = materialTypeChanges; + _meshTypeChanges = meshTypeChanges; #if ENABLE_TERRAIN_MODULE _terrainTypeChanges = terrainTypeChanges; _terrainDataTypeChanges = terrainDataTypeChanges; @@ -125,6 +132,7 @@ public void Dispose() _meshRendererTypeChanges.Dispose(); _lightTypeChanges.Dispose(); _materialTypeChanges.Dispose(); + _meshTypeChanges.Dispose(); #if ENABLE_TERRAIN_MODULE _terrainTypeChanges.Dispose(); _terrainDataTypeChanges.Dispose(); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs index 17a254ba6d2..23018d4d7d9 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs @@ -16,6 +16,7 @@ class SurfaceCacheWorldAdapter readonly LightSet _lights; readonly InstanceSet _meshRenderers; readonly EntityInstanceSet _entityInstances; + readonly HashSet _destroyedMeshesThisFrame = new(); #if ENABLE_TERRAIN_MODULE readonly TerrainSet _terrains; // Per-frame set of TerrainData EntityIds that were reported changed by ObjectDispatcher. @@ -73,6 +74,8 @@ public void Update(SurfaceCacheWorldChangeSet changes, AmbientMode ambientMode, bool filterChanged = renderingLayerMaskFilter != _renderingLayerMaskFilter; _renderingLayerMaskFilter = renderingLayerMaskFilter; + RemoveInstancesWithDestroyedMeshes(changes.MeshDestroyedList, world); + UpdateMeshRenderers(changes.MeshRendererTransformChangedIds, changes.MeshRendererTransformChangedLocalToWorlds, changes.MeshRendererChangedList, changes.MeshRendererDestroyedList, world); UpdateEntityInstances(changes.EntityInstanceTransformChangedList, changes.EntityInstanceChangedList, changes.EntityInstanceDestroyedList, world); #if ENABLE_TERRAIN_MODULE @@ -116,6 +119,20 @@ public void Update(SurfaceCacheWorldChangeSet changes, AmbientMode ambientMode, static readonly Unity.Profiling.ProfilerMarker k_GameObjectTerrainUpdateMarker = new("SurfaceCache.GameObjectTerrainUpdate"); #endif + void RemoveInstancesWithDestroyedMeshes(NativeArray destroyedMeshes, SurfaceCacheWorld world) + { + if (destroyedMeshes.Length == 0) + return; + + foreach (var meshId in destroyedMeshes) + _destroyedMeshesThisFrame.Add(meshId); + + _meshRenderers.RemoveInstancesWithDestroyedMeshes(_destroyedMeshesThisFrame, _sharedMaterials, world); + _entityInstances.RemoveInstancesWithDestroyedMeshes(_destroyedMeshesThisFrame, _sharedMaterials, world); + + _destroyedMeshesThisFrame.Clear(); + } + void UpdateMeshRenderers(NativeArray transformChangedIds, NativeArray transformChangedLocalToWorlds, IEnumerable changed, IEnumerable destroyed, SurfaceCacheWorld world) { using var _ = k_GameObjectInstanceUpdateMarker.Auto(); @@ -374,7 +391,7 @@ class InstanceSet readonly List _sources = new(); readonly List _inWorld = new(); readonly List _handles = new(); - readonly List _meshes = new(); + readonly List _meshIds = new(); // The transform last applied to the world instance. readonly List _localToWorlds = new(); // Materials provided by the source the last time we checked ("null materials" are EntityId.None). @@ -469,6 +486,15 @@ public void TryRemove(TKey key, SharedMaterialSet sharedMaterials, SurfaceCacheW Unregister(slot); } + public void RemoveInstancesWithDestroyedMeshes(HashSet destroyedMeshes, SharedMaterialSet sharedMaterials, SurfaceCacheWorld world) + { + for (int i = 0; i < _keys.Count; i++) + { + if (_inWorld[i] && destroyedMeshes.Contains(_meshIds[i])) + RemoveFromWorld(i, sharedMaterials, world); + } + } + public void ReevaluateAll(SharedMaterialSet sharedMaterials, SurfaceCacheWorld world, uint renderingLayerMaskFilter) { // A copy is required because we mutate below. @@ -515,7 +541,7 @@ int Register(TKey key, in TSource source) _sources.Add(source); _inWorld.Add(false); _handles.Add(default); - _meshes.Add(null); + _meshIds.Add(EntityId.None); _localToWorlds.Add(default); _inputMaterialIds.Add(null); _acquiredMaterialIds.Add(null); @@ -533,7 +559,7 @@ void Unregister(int slot) _sources[slot] = _sources[last]; _inWorld[slot] = _inWorld[last]; _handles[slot] = _handles[last]; - _meshes[slot] = _meshes[last]; + _meshIds[slot] = _meshIds[last]; _localToWorlds[slot] = _localToWorlds[last]; _inputMaterialIds[slot] = _inputMaterialIds[last]; _acquiredMaterialIds[slot] = _acquiredMaterialIds[last]; @@ -543,7 +569,7 @@ void Unregister(int slot) _sources.RemoveAt(last); _inWorld.RemoveAt(last); _handles.RemoveAt(last); - _meshes.RemoveAt(last); + _meshIds.RemoveAt(last); _localToWorlds.RemoveAt(last); _inputMaterialIds.RemoveAt(last); _acquiredMaterialIds.RemoveAt(last); @@ -578,7 +604,7 @@ void AddToWorld(int slot, in TSource source, Mesh mesh, SharedMaterialSet shared throw; } - _meshes[slot] = mesh; + _meshIds[slot] = mesh.GetEntityId(); _localToWorlds[slot] = localToWorld; _inputMaterialIds[slot] = inputMatIds.ToArray(); _acquiredMaterialIds[slot] = acquiredMatIds.ToArray(); @@ -589,7 +615,7 @@ void AddToWorld(int slot, in TSource source, Mesh mesh, SharedMaterialSet shared void UpdateInWorld(int slot, in TSource source, Mesh mesh, SharedMaterialSet sharedMaterials, SurfaceCacheWorld world) { - if (_meshes[slot] != mesh) + if (_meshIds[slot] != mesh.GetEntityId()) { RemoveFromWorld(slot, sharedMaterials, world); AddToWorld(slot, source, mesh, sharedMaterials, world); @@ -660,7 +686,7 @@ void RemoveFromWorld(int slot, SharedMaterialSet sharedMaterials, SurfaceCacheWo foreach (var matEntityId in _acquiredMaterialIds[slot]) sharedMaterials.Release(matEntityId, world); _handles[slot] = default; - _meshes[slot] = null; + _meshIds[slot] = EntityId.None; _localToWorlds[slot] = default; _inputMaterialIds[slot] = null; _acquiredMaterialIds[slot] = null; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldChangeSet.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldChangeSet.cs index b2f5f377f25..44fd785af04 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldChangeSet.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldChangeSet.cs @@ -20,6 +20,8 @@ sealed class SurfaceCacheWorldChangeSet public IEnumerable MaterialChangedList { get; set; } = Array.Empty(); + public NativeArray MeshDestroyedList { get; set; } + public IEnumerable EntityInstanceChangedList { get; set; } = Array.Empty(); public NativeArray EntityInstanceTransformChangedList { get; set; } public IEnumerable EntityInstanceDestroyedList { get; set; } = Array.Empty(); diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheWorldAdapterTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheWorldAdapterTests.cs index eb70afca7fd..ea76c3625d1 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheWorldAdapterTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/SurfaceCache/SurfaceCacheWorldAdapterTests.cs @@ -295,6 +295,42 @@ public void UpdateMeshRenderer_MeshClearedAndMovedInSameFrame_RendererIsRemoved( } } + [Test] + public void UpdateMeshRenderer_MeshDestroyedWhileInWorld_InstanceIsRemoved() + { + var env = CreateEnvironmentOrIgnore(); + var changeSource = new ObjectDispatcherChangeSource(); + var mesh = CreateQuadMesh(); + GameObject go = null; + try + { + go = CreateMeshRendererGameObject(mesh, out var renderer); + + using (var collected = changeSource.CollectChanges()) + Update(env.Adapter, collected.WorldChangeSet, env.World); + + Assert.AreEqual(1, env.World.GetInstanceCount(), "The renderer should be in the world before the mesh is destroyed."); + + Object.DestroyImmediate(mesh); + mesh = null; + + using (var collected = changeSource.CollectChanges()) + Update(env.Adapter, collected.WorldChangeSet, env.World); + + Assert.AreEqual(0, env.World.GetInstanceCount(), "The instance should be removed once its mesh is reported as destroyed."); + Assert.AreEqual(0, env.World.GetMaterialCount(), "The fallback material should be released with the instance."); + } + finally + { + changeSource.Dispose(); + env.Dispose(); + if (go != null) + Object.DestroyImmediate(go); + if (mesh != null) + Object.DestroyImmediate(mesh); + } + } + [Test] public void UpdateMeshRenderer_ChangedTwice_RendererIsNotDuplicated() { @@ -1172,6 +1208,39 @@ public void UpdateEntityInstance_ChangedThenDestroyed_InstanceIsAddedThenRemoved } } + [Test] + public void UpdateEntityInstance_MeshDestroyedWhileInWorld_InstanceIsRemoved() + { + var env = CreateEnvironmentOrIgnore(); + var changeSource = new ObjectDispatcherChangeSource(); + var mesh = CreateQuadMesh(); + try + { + var key = CreateEntityKey(1); + + Update(env.Adapter, new SurfaceCacheWorldChangeSet { EntityInstanceChangedList = new[] { CreateEntityRecord(key, mesh) } }, env.World); + Assert.AreEqual(1, env.World.GetInstanceCount(), "The entity instance should be in the world before the mesh is destroyed."); + + changeSource.CollectChanges().Dispose(); + + Object.DestroyImmediate(mesh); + mesh = null; + + using (var collected = changeSource.CollectChanges()) + Update(env.Adapter, collected.WorldChangeSet, env.World); + + Assert.AreEqual(0, env.World.GetInstanceCount(), "The instance should be removed once its mesh is reported as destroyed."); + Assert.AreEqual(0, env.World.GetMaterialCount(), "The fallback material should be released with the instance."); + } + finally + { + changeSource.Dispose(); + env.Dispose(); + if (mesh != null) + Object.DestroyImmediate(mesh); + } + } + [Test] public void UpdateEntityInstance_ChangedWhileInvisible_InstanceIsNotAdded() { From 99e86167286e7362cc584c0490cbb3a8018056d7 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:10 +0000 Subject: [PATCH 037/192] [Port] [6000.7] Fix seams with box projection in URP on platforms supporting half precision --- .../ShaderLibrary/GlobalIllumination.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl index c0944eff02f..c3dc3aa1bb0 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl @@ -343,7 +343,7 @@ half3 BoxProjectedCubemapDirection(half3 reflectionWS, float3 positionWS, float4 if (cubemapPositionWS.w > 0.0f) { float3 boxMinMax = (reflectionWS > 0.0f) ? boxMax.xyz : boxMin.xyz; - half3 rbMinMax = half3(boxMinMax - positionWS) / reflectionWS; + half3 rbMinMax = (reflectionWS != 0.0f) ? half3(boxMinMax - positionWS) / reflectionWS : HALF_MAX; half fa = half(min(min(rbMinMax.x, rbMinMax.y), rbMinMax.z)); From 5917c7c8ebc5d4b189e2a85fcf0cafa3462a3edc Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:11 +0000 Subject: [PATCH 038/192] [Port] [6000.7] SRP-1352: Update HDRP Sample template --- .../HDRenderPipelineGlobalSettings.asset | 19 +- .../Assets/Settings.meta | 8 + .../Assets/Settings/Build Profiles.meta | 8 + .../Settings/Build Profiles/Linux.asset | 56 +++ .../Settings/Build Profiles/Linux.asset.meta | 8 + .../Settings/Build Profiles/Windows.asset | 55 +++ .../Build Profiles/Windows.asset.meta | 8 + .../Settings/Build Profiles/macOS.asset | 52 +++ .../Settings/Build Profiles/macOS.asset.meta | 8 + .../com.unity.template.hd/CHANGELOG.md | 5 + .../ValidationExceptions.json | 2 +- .../com.unity.template.hd/package.json | 22 +- .../Packages/manifest.json | 52 +-- .../Packages/packages-lock.json | 349 +++-------------- .../ProjectSettings/EditorSettings.asset | 8 +- .../ProjectAuditorSettings.asset | 22 ++ .../ProjectSettings/ProjectSettings.asset | 361 ++++++++++++++++-- .../ProjectSettings/ProjectVersion.txt | 4 +- .../ProjectSettings/QualitySettings.asset | 39 +- .../Switch2PlayerSettings.asset | 72 ++++ 20 files changed, 757 insertions(+), 401 deletions(-) create mode 100644 Templates/com.unity.template-hd/Assets/Settings.meta create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles.meta create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset.meta create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset.meta create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset create mode 100644 Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset.meta create mode 100644 Templates/com.unity.template-hd/ProjectSettings/ProjectAuditorSettings.asset create mode 100644 Templates/com.unity.template-hd/ProjectSettings/Switch2PlayerSettings.asset diff --git a/Templates/com.unity.template-hd/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset b/Templates/com.unity.template-hd/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset index 523e1982dc3..2dca81e9fd5 100644 --- a/Templates/com.unity.template-hd/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset +++ b/Templates/com.unity.template-hd/Assets/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset @@ -198,6 +198,7 @@ MonoBehaviour: - rid: 6588238014074322947 - rid: 6588238014074322948 - rid: 6588238014074322949 + - rid: 5029281996214894596 m_RuntimeSettings: m_List: [] renderingLayerNames: @@ -243,10 +244,25 @@ MonoBehaviour: obsoleteHasProbeVolumes: m_Keys: - 3db1837cc97a95e4c98610966fac2b0b - m_Values: 01 + m_Values: 01y references: version: 2 RefIds: + - rid: 5029281996214894596 + type: {class: SurfaceCacheRenderPipelineResourceSet, ns: UnityEngine.Rendering, asm: Unity.SurfaceCache.Runtime} + data: + m_Version: 5 + m_TemporalFilteringShader: {fileID: 7200000, guid: c23523f04780d754f927b9daf4f975b9, type: 3} + m_SpatialFilteringShader: {fileID: 7200000, guid: 63e59de460463bb4c9d64bc58051d12c, type: 3} + m_ScrollingShader: {fileID: 7200000, guid: 47bbc3edf61978b498603cc2a1b87eea, type: 3} + m_GlobalProbeShader: {fileID: 7200000, guid: 4dccb71ac6af46018e56b6ccc3974c80, type: 3} + m_DefragShader: {fileID: 7200000, guid: a183a2d0b1da4904fb3bd71c6111ebb1, type: 3} + m_EstimationShader: {fileID: 7200000, guid: 7aa73e4f3b424c41bee95499324c9297, type: 3} + m_PunctualLightSamplingShader: {fileID: 7200000, guid: 046dc07e95c240fda3212abb90fcb736, type: 3} + m_EvictionShader: {fileID: 7200000, guid: c9f2aeed6ef396f4d9134e4da1edfe19, type: 3} + m_PatchAllocationShader: {fileID: 7200000, guid: b271ec1ddd8048458fa529e8e7cfe960, type: 3} + m_EmissiveTriangleAdditionComputeShader: {fileID: 7200000, guid: 2e583cebf11e4785b8a5b0d8f7b20ab6, type: 3} + m_EmissiveTriangleRemovalComputeShader: {fileID: 7200000, guid: 3d386645a85b4e758a7b7eb1bf87fa24, type: 3} - rid: 5053671556450091008 type: {class: HDRPRayTracingResources, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: @@ -855,6 +871,7 @@ MonoBehaviour: _skyBoxMesh: {fileID: 4300000, guid: 0529e6c5f6dea8c4a8c2835ed7de57cb, type: 2} _sixFaceSkyBoxMesh: {fileID: 4300000, guid: a80925ceebd011741b42509226cefc74, type: 2} _buildLightGridShader: {fileID: 7200000, guid: 16e47c1641bd0104e92b624601457bb0, type: 3} + _solidColorShader: {fileID: 4800000, guid: 3765a7ac691541038de4d587b94ae768, type: 3} - rid: 6588238014074322945 type: {class: RayTracingRenderPipelineResources, ns: UnityEngine.Rendering.UnifiedRayTracing, asm: Unity.UnifiedRayTracing.Runtime} data: diff --git a/Templates/com.unity.template-hd/Assets/Settings.meta b/Templates/com.unity.template-hd/Assets/Settings.meta new file mode 100644 index 00000000000..340c5335f2b --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a182b0611fa02934fb8ef7a4118f4eab +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles.meta b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles.meta new file mode 100644 index 00000000000..1ddec2aaf88 --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c1155cafe5c60254a9f1d95cdb84a476 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset new file mode 100644 index 00000000000..2b1075613a5 --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: Linux + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 3 + m_BuildTarget: 24 + m_Subtarget: 2 + m_PlatformId: cb423bfea44b4d658edb8bc5d91a3024 + m_PlatformBuildProfile: + rid: 5029282017802453049 + m_SelectedPlatformGuid: + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + requiredComponents: [] + references: + version: 2 + RefIds: + - rid: 5029282017802453049 + type: {class: LinuxPlatformSettings, ns: UnityEditor.LinuxStandalone, asm: UnityEditor.LinuxStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_BuildWithCodeCoverage: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 0 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 2 + m_AdaptivePerformanceEnabled: 0 + m_Architecture: 0 + m_RemoteDeviceSectionFoldoutOpen: 0 + m_DeployTarget: 0 + m_RemoteDeviceAddress: + m_RemoteDeviceUsername: + m_RemoteDeviceExports: + m_PathOnRemoteDevice: diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset.meta b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset.meta new file mode 100644 index 00000000000..584980a83bc --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Linux.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bab3a811c4e1cb04793ce05a24199977 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset new file mode 100644 index 00000000000..83a21c63a5d --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset @@ -0,0 +1,55 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: Windows + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 3 + m_BuildTarget: 19 + m_Subtarget: 2 + m_PlatformId: 4e3c793746204150860bf175a9a41a05 + m_PlatformBuildProfile: + rid: 5029282017802453004 + m_SelectedPlatformGuid: + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + requiredComponents: [] + references: + version: 2 + RefIds: + - rid: 5029282017802453004 + type: {class: WindowsPlatformSettings, ns: UnityEditor.WindowsStandalone, asm: UnityEditor.WindowsStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_BuildWithCodeCoverage: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 0 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 2 + m_AdaptivePerformanceEnabled: 0 + m_WindowsBuildAndRunDeployTarget: 0 + m_Architecture: 0 + m_CreateSolution: 0 + m_CopyPDBFiles: 0 + m_WindowsDevicePortalAddress: + m_WindowsDevicePortalUsername: diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset.meta b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset.meta new file mode 100644 index 00000000000..a0fe0c233d7 --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/Windows.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 622f5e8cf567863489834f424293d181 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset new file mode 100644 index 00000000000..fab63e3bf10 --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: macOS + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 3 + m_BuildTarget: 2 + m_Subtarget: 2 + m_PlatformId: 0d2129357eac403d8b359c2dcbf82502 + m_PlatformBuildProfile: + rid: 5029282017802453048 + m_SelectedPlatformGuid: + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + requiredComponents: [] + references: + version: 2 + RefIds: + - rid: 5029282017802453048 + type: {class: OSXStandaloneBuildProfile, ns: UnityEditor.OSXStandalone, asm: UnityEditor.OSXStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_BuildWithCodeCoverage: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 0 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 2 + m_AdaptivePerformanceEnabled: 0 + m_MacOSXcodeBuildConfig: 1 + m_Architecture: 1 + m_CreateXcodeProject: 0 diff --git a/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset.meta b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset.meta new file mode 100644 index 00000000000..d22e1406203 --- /dev/null +++ b/Templates/com.unity.template-hd/Assets/Settings/Build Profiles/macOS.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 91ac2194dee31c14486c0756beb1e8ac +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template-hd/Packages/com.unity.template.hd/CHANGELOG.md b/Templates/com.unity.template-hd/Packages/com.unity.template.hd/CHANGELOG.md index 30a9b009c47..1e481bde1a2 100644 --- a/Templates/com.unity.template-hd/Packages/com.unity.template.hd/CHANGELOG.md +++ b/Templates/com.unity.template-hd/Packages/com.unity.template.hd/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project template will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [16.3.0] - 2026-09-16 + +- Upgraded version to Unity 6000.7.0b1 +- Disabled Static Batching + ## [16.2.2] - 2026-08-07 - Bump SRP packages to 17.7.0 diff --git a/Templates/com.unity.template-hd/Packages/com.unity.template.hd/ValidationExceptions.json b/Templates/com.unity.template-hd/Packages/com.unity.template.hd/ValidationExceptions.json index 027953fcf40..a7ec26b47c0 100644 --- a/Templates/com.unity.template-hd/Packages/com.unity.template.hd/ValidationExceptions.json +++ b/Templates/com.unity.template-hd/Packages/com.unity.template.hd/ValidationExceptions.json @@ -2,7 +2,7 @@ "ErrorExceptions": [ { "ValidationTest": "Primed Library Validation", - "PackageVersion": "16.2.2" + "PackageVersion": "16.3.0" } ], "WarningExceptions": [] diff --git a/Templates/com.unity.template-hd/Packages/com.unity.template.hd/package.json b/Templates/com.unity.template-hd/Packages/com.unity.template.hd/package.json index a3dea3ce0b6..7c347e64f50 100644 --- a/Templates/com.unity.template-hd/Packages/com.unity.template.hd/package.json +++ b/Templates/com.unity.template-hd/Packages/com.unity.template.hd/package.json @@ -1,20 +1,18 @@ { "name": "com.unity.template.hd", - "displayName": "High Definition RP", - "version": "16.2.2", + "displayName": "High Definition Render Pipeline Sample", + "version": "16.3.0", "type": "template", "host": "hub", - "unity": "6000.6", - "description": "This template utilizes the High Definition Render Pipeline. Making it a good starting point for people focused on high-end graphics that want to develop games for platforms that support Shader Model 5.0 (DX11 and above). \n\nBeyond being tuned for High End visuals this project includes\n\u25aa Shadergraph \n\u25aa Visual Effect Graph \n\u25aa Presets \n\u25aa Example content", + "unity": "6000.7", + "description": "This template utilizes the High Definition Render Pipeline. Making it a good starting point for people focused on high-end graphics that want to develop games for platforms that support Shader Model 5.0 (DX11 and above). \n\nBeyond being tuned for High End visuals this project includes\n▪ Shadergraph \n▪ Visual Effect Graph \n▪ Presets \n▪ Example content", "dependencies": { - "com.unity.collab-proxy": "2.12.4", - "com.unity.feature.development": "1.0.2", - "com.unity.cinemachine": "6.6.0", - "com.unity.inputsystem": "1.19.0", - "com.unity.learn.iet-framework": "5.0.4", + "com.unity.cinemachine": "6.7.0", + "com.unity.inputsystem": "6.7.0", "com.unity.render-pipelines.high-definition": "17.7.0", - "com.unity.timeline": "6.6.0", - "com.unity.ugui": "2.6.0", - "com.unity.visualscripting": "1.9.11" + "com.unity.timeline": "6.7.0", + "com.unity.ugui": "2.7.0", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.28" } } diff --git a/Templates/com.unity.template-hd/Packages/manifest.json b/Templates/com.unity.template-hd/Packages/manifest.json index fb89226d24c..4d19de25c87 100644 --- a/Templates/com.unity.template-hd/Packages/manifest.json +++ b/Templates/com.unity.template-hd/Packages/manifest.json @@ -1,49 +1,13 @@ { "dependencies": { - "com.unity.cinemachine": "6.6.0", - "com.unity.collab-proxy": "2.12.4", - "com.unity.feature.development": "1.0.2", - "com.unity.inputsystem": "1.19.0", - "com.unity.learn.iet-framework": "5.0.4", - "com.unity.learn.iet-framework.authoring": "1.5.4", + "com.unity.cinemachine": "6.7.0", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.28", + "com.unity.inputsystem": "6.7.0", + "com.unity.learn.iet-framework": "6.0.7", + "com.unity.learn.iet-framework.authoring": "2.0.7", "com.unity.render-pipelines.high-definition": "17.7.0", - "com.unity.timeline": "6.6.0", - "com.unity.ugui": "2.6.0", - "com.unity.visualscripting": "1.9.11", - "com.unity.modules.adaptiveperformance": "1.0.0", - "com.unity.modules.ai": "1.0.0", - "com.unity.modules.androidjni": "1.0.0", - "com.unity.modules.animation": "1.0.0", - "com.unity.modules.assetbundle": "1.0.0", - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.cloth": "1.0.0", - "com.unity.modules.director": "1.0.0", - "com.unity.modules.imageconversion": "1.0.0", - "com.unity.modules.imgui": "1.0.0", - "com.unity.modules.jsonserialize": "1.0.0", - "com.unity.modules.nvidia": "1.0.0", - "com.unity.modules.particlesystem": "1.0.0", - "com.unity.modules.physics": "1.0.0", - "com.unity.modules.physics2d": "1.0.0", - "com.unity.modules.physicscore2d": "1.0.0", - "com.unity.modules.screencapture": "1.0.0", - "com.unity.modules.terrain": "1.0.0", - "com.unity.modules.terrainphysics": "1.0.0", - "com.unity.modules.tilemap": "1.0.0", - "com.unity.modules.timelinefoundation": "1.0.0", - "com.unity.modules.ui": "1.0.0", - "com.unity.modules.uielements": "1.0.0", - "com.unity.modules.umbra": "1.0.0", - "com.unity.modules.unityanalytics": "1.0.0", - "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.modules.unitywebrequestassetbundle": "1.0.0", - "com.unity.modules.unitywebrequestaudio": "1.0.0", - "com.unity.modules.unitywebrequesttexture": "1.0.0", - "com.unity.modules.unitywebrequestwww": "1.0.0", - "com.unity.modules.vectorgraphics": "1.0.0", - "com.unity.modules.vehicles": "1.0.0", - "com.unity.modules.video": "1.0.0", - "com.unity.modules.wind": "1.0.0", - "com.unity.modules.xr": "1.0.0" + "com.unity.timeline": "6.7.0", + "com.unity.ugui": "2.7.0" } } diff --git a/Templates/com.unity.template-hd/Packages/packages-lock.json b/Templates/com.unity.template-hd/Packages/packages-lock.json index 6658101e302..f113a2b9a03 100644 --- a/Templates/com.unity.template-hd/Packages/packages-lock.json +++ b/Templates/com.unity.template-hd/Packages/packages-lock.json @@ -1,17 +1,13 @@ { "dependencies": { "com.unity.burst": { - "version": "1.8.29", + "version": "2.0.0", "depth": 2, - "source": "registry", - "dependencies": { - "com.unity.mathematics": "1.2.1", - "com.unity.modules.jsonserialize": "1.0.0" - }, - "url": "https://packages.unity.com" + "source": "builtin", + "dependencies": {} }, "com.unity.cinemachine": { - "version": "6.6.0", + "version": "6.7.0", "depth": 0, "source": "builtin", "dependencies": { @@ -19,15 +15,8 @@ "com.unity.modules.imgui": "1.0.0" } }, - "com.unity.collab-proxy": { - "version": "2.12.4", - "depth": 0, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, "com.unity.collections": { - "version": "6.5.0", + "version": "6.7.0", "depth": 2, "source": "builtin", "dependencies": { @@ -44,27 +33,20 @@ "dependencies": {} }, "com.unity.ext.nunit": { - "version": "2.1.0", - "depth": 2, + "version": "2.1.1", + "depth": 1, "source": "builtin", "dependencies": {} }, - "com.unity.feature.development": { - "version": "1.0.2", - "depth": 0, + "com.unity.graph-authoring": { + "version": "1.0.0", + "depth": 2, "source": "builtin", - "dependencies": { - "com.unity.ide.visualstudio": "2.0.27", - "com.unity.ide.rider": "3.0.40", - "com.unity.editorcoroutines": "6.6.0", - "com.unity.performance.profile-analyzer": "1.3.4", - "com.unity.test-framework": "1.8.0", - "com.unity.testtools.codecoverage": "1.3.0" - } + "dependencies": {} }, "com.unity.ide.rider": { "version": "3.0.40", - "depth": 1, + "depth": 0, "source": "registry", "dependencies": { "com.unity.ext.nunit": "1.0.6" @@ -72,8 +54,8 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.27", - "depth": 1, + "version": "2.0.28", + "depth": 0, "source": "registry", "dependencies": { "com.unity.test-framework": "1.1.33" @@ -81,16 +63,15 @@ "url": "https://packages.unity.com" }, "com.unity.inputsystem": { - "version": "1.19.0", + "version": "6.7.0", "depth": 0, - "source": "registry", + "source": "builtin", "dependencies": { "com.unity.modules.uielements": "1.0.0" - }, - "url": "https://packages.unity.com" + } }, "com.unity.learn.iet-framework": { - "version": "5.0.4", + "version": "6.0.7", "depth": 0, "source": "registry", "dependencies": { @@ -100,11 +81,11 @@ "url": "https://packages.unity.com" }, "com.unity.learn.iet-framework.authoring": { - "version": "1.5.4", + "version": "2.0.7", "depth": 0, "source": "registry", "dependencies": { - "com.unity.learn.iet-framework": "5.0.3" + "com.unity.learn.iet-framework": "6.0.7" }, "url": "https://packages.unity.com" }, @@ -121,12 +102,11 @@ "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.performance.profile-analyzer": { - "version": "1.3.4", - "depth": 1, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" + "com.unity.profiling.core": { + "version": "1.0.3", + "depth": 2, + "source": "builtin", + "dependencies": {} }, "com.unity.render-pipelines.core": { "version": "17.7.0", @@ -135,7 +115,9 @@ "dependencies": { "com.unity.burst": "1.8.14", "com.unity.collections": "2.4.3", - "com.unity.modules.jsonserialize": "1.0.0" + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.profiling.core": "1.0.3" } }, "com.unity.render-pipelines.high-definition": { @@ -163,7 +145,7 @@ } }, "com.unity.searcher": { - "version": "4.9.4", + "version": "4.9.5", "depth": 2, "source": "registry", "dependencies": {}, @@ -182,11 +164,12 @@ "source": "builtin", "dependencies": { "com.unity.render-pipelines.core": "17.7.0", - "com.unity.searcher": "4.9.3" + "com.unity.searcher": "4.9.5", + "com.unity.graph-authoring": "1.0.0" } }, "com.unity.splines": { - "version": "2.8.4", + "version": "2.9.0", "depth": 1, "source": "registry", "dependencies": { @@ -201,49 +184,35 @@ "depth": 0, "source": "embedded", "dependencies": { - "com.unity.collab-proxy": "2.12.4", - "com.unity.feature.development": "1.0.2", - "com.unity.cinemachine": "6.6.0", - "com.unity.inputsystem": "1.19.0", - "com.unity.learn.iet-framework": "5.0.4", + "com.unity.cinemachine": "6.7.0", + "com.unity.inputsystem": "6.7.0", "com.unity.render-pipelines.high-definition": "17.7.0", - "com.unity.timeline": "6.6.0", - "com.unity.ugui": "2.6.0", - "com.unity.visualscripting": "1.9.11" + "com.unity.timeline": "6.7.0", + "com.unity.ugui": "2.7.0", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.28" } }, "com.unity.test-framework": { - "version": "1.8.0", + "version": "1.9.0", "depth": 1, "source": "builtin", "dependencies": { "com.unity.ext.nunit": "2.1.0", - "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" } }, "com.unity.test-framework.performance": { - "version": "3.4.0", + "version": "6.7.0", "depth": 3, - "source": "registry", + "source": "builtin", "dependencies": { "com.unity.test-framework": "1.1.33", "com.unity.modules.jsonserialize": "1.0.0" - }, - "url": "https://packages.unity.com" - }, - "com.unity.testtools.codecoverage": { - "version": "1.3.0", - "depth": 1, - "source": "registry", - "dependencies": { - "com.unity.test-framework": "1.4.5", - "com.unity.settings-manager": "2.0.0" - }, - "url": "https://packages.unity.com" + } }, "com.unity.timeline": { - "version": "6.6.0", + "version": "6.7.0", "depth": 0, "source": "builtin", "dependencies": { @@ -254,15 +223,12 @@ } }, "com.unity.ugui": { - "version": "2.6.0", + "version": "2.7.0", "depth": 0, "source": "builtin", "dependencies": { "com.unity.modules.ui": "1.0.0", - "com.unity.modules.imgui": "1.0.0", - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.physics2d": "1.0.0", - "com.unity.modules.physics": "1.0.0" + "com.unity.modules.imgui": "1.0.0" } }, "com.unity.visualeffectgraph": { @@ -274,67 +240,27 @@ "com.unity.render-pipelines.core": "17.7.0" } }, - "com.unity.visualscripting": { - "version": "1.9.11", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.ugui": "1.0.0", - "com.unity.modules.jsonserialize": "1.0.0" - }, - "url": "https://packages.unity.com" - }, - "com.unity.modules.adaptiveperformance": { + "com.unity.modules.accessibility": { "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.subsystems": "1.0.0" - } - }, - "com.unity.modules.ai": { - "version": "1.0.0", - "depth": 0, + "depth": 2, "source": "builtin", "dependencies": {} }, - "com.unity.modules.androidjni": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.jsonserialize": "1.0.0" - } - }, "com.unity.modules.animation": { "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.assetbundle": { - "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, "com.unity.modules.audio": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, - "com.unity.modules.cloth": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.physics": "1.0.0" - } - }, "com.unity.modules.director": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": { "com.unity.modules.audio": "1.0.0", @@ -343,116 +269,55 @@ }, "com.unity.modules.hierarchycore": { "version": "1.0.0", - "depth": 1, + "depth": 2, "source": "builtin", "dependencies": {} }, "com.unity.modules.imageconversion": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, "com.unity.modules.imgui": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, "com.unity.modules.jsonserialize": { "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.nvidia": { - "version": "1.0.0", - "depth": 0, + "depth": 2, "source": "builtin", "dependencies": {} }, "com.unity.modules.particlesystem": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, "com.unity.modules.physics": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.physics2d": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.physicscore2d": "1.0.0" - } - }, - "com.unity.modules.physicscore2d": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.screencapture": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.imageconversion": "1.0.0" - } - }, - "com.unity.modules.subsystems": { "version": "1.0.0", "depth": 1, "source": "builtin", - "dependencies": { - "com.unity.modules.jsonserialize": "1.0.0" - } + "dependencies": {} }, "com.unity.modules.terrain": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, - "com.unity.modules.terrainphysics": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.physics": "1.0.0", - "com.unity.modules.terrain": "1.0.0" - } - }, - "com.unity.modules.tilemap": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.physics2d": "1.0.0" - } - }, - "com.unity.modules.timelinefoundation": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.jsonserialize": "1.0.0" - } - }, "com.unity.modules.ui": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": {} }, "com.unity.modules.uielements": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": { "com.unity.modules.ui": "1.0.0", @@ -460,113 +325,25 @@ "com.unity.modules.jsonserialize": "1.0.0", "com.unity.modules.hierarchycore": "1.0.0", "com.unity.modules.physics": "1.0.0", - "com.unity.modules.animation": "1.0.0" - } - }, - "com.unity.modules.umbra": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.unityanalytics": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.modules.jsonserialize": "1.0.0" + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.accessibility": "1.0.0" } }, "com.unity.modules.unitywebrequest": { "version": "1.0.0", - "depth": 0, + "depth": 2, "source": "builtin", "dependencies": {} }, - "com.unity.modules.unitywebrequestassetbundle": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.assetbundle": "1.0.0", - "com.unity.modules.unitywebrequest": "1.0.0" - } - }, - "com.unity.modules.unitywebrequestaudio": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.modules.audio": "1.0.0" - } - }, - "com.unity.modules.unitywebrequesttexture": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.modules.imageconversion": "1.0.0" - } - }, - "com.unity.modules.unitywebrequestwww": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.modules.unitywebrequestassetbundle": "1.0.0", - "com.unity.modules.unitywebrequestaudio": "1.0.0", - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.assetbundle": "1.0.0", - "com.unity.modules.imageconversion": "1.0.0" - } - }, - "com.unity.modules.vectorgraphics": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.uielements": "1.0.0", - "com.unity.modules.imageconversion": "1.0.0", - "com.unity.modules.imgui": "1.0.0" - } - }, - "com.unity.modules.vehicles": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.physics": "1.0.0" - } - }, "com.unity.modules.video": { "version": "1.0.0", - "depth": 0, + "depth": 1, "source": "builtin", "dependencies": { "com.unity.modules.audio": "1.0.0", "com.unity.modules.ui": "1.0.0", "com.unity.modules.unitywebrequest": "1.0.0" } - }, - "com.unity.modules.wind": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.xr": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.physics": "1.0.0", - "com.unity.modules.jsonserialize": "1.0.0", - "com.unity.modules.subsystems": "1.0.0" - } } } } diff --git a/Templates/com.unity.template-hd/ProjectSettings/EditorSettings.asset b/Templates/com.unity.template-hd/ProjectSettings/EditorSettings.asset index 936f3744c16..63109437abc 100644 --- a/Templates/com.unity.template-hd/ProjectSettings/EditorSettings.asset +++ b/Templates/com.unity.template-hd/ProjectSettings/EditorSettings.asset @@ -23,11 +23,10 @@ EditorSettings: m_EnableTextureStreamingInPlayMode: 1 m_EnableEditorAsyncCPUTextureLoading: 0 m_AsyncShaderCompilation: 1 - m_BlockShaders: 0 - m_UnlockBlockShaders: 0 m_PrefabModeAllowAutoSave: 1 + m_EnableMSBuildCompilationPipeline: 0 m_EnterPlayModeOptionsEnabled: 1 - m_EnterPlayModeOptions: 3 + m_EnterPlayModeOptions: 1 m_GameObjectNamingDigits: 1 m_GameObjectNamingScheme: 0 m_AssetNamingUsesSpace: 1 @@ -49,4 +48,5 @@ EditorSettings: m_EnableEnlightenBakedGI: 0 m_ReferencedClipsExactNaming: 0 m_ForceAssetUnloadAndGCOnSceneLoad: 1 - m_HideBuildProfileClassicPlatforms: 0 + m_HideBuildProfileClassicPlatforms: 1 + m_UseLegacyHierarchy: 0 diff --git a/Templates/com.unity.template-hd/ProjectSettings/ProjectAuditorSettings.asset b/Templates/com.unity.template-hd/ProjectSettings/ProjectAuditorSettings.asset new file mode 100644 index 00000000000..2fe9472e94c --- /dev/null +++ b/Templates/com.unity.template-hd/ProjectSettings/ProjectAuditorSettings.asset @@ -0,0 +1,22 @@ +%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: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.ProjectAuditorModule:Unity.ProjectAuditor.Editor:ProjectAuditorSettings + Rules: + rules: [] + DiagnosticParams: + paramsStack: + - PlatformGroup: + m_String: Unknown + m_SerializedParams: [] + CurrentParamsIndex: 0 diff --git a/Templates/com.unity.template-hd/ProjectSettings/ProjectSettings.asset b/Templates/com.unity.template-hd/ProjectSettings/ProjectSettings.asset index 041337ba3c1..dd1cefecf14 100644 --- a/Templates/com.unity.template-hd/ProjectSettings/ProjectSettings.asset +++ b/Templates/com.unity.template-hd/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,8 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 24 + m_BuildProfilePlayerSettings: {fileID: 0} + serializedVersion: 32 productGUID: c71a6e77368cc6048998f34f4bbe2b86 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -41,18 +42,21 @@ PlayerSettings: height: 1 m_SplashScreenLogos: [] m_VirtualRealitySplashScreen: {fileID: 0} - m_HolographicTrackingLossScreen: {fileID: 0} defaultScreenWidth: 1920 defaultScreenHeight: 1080 defaultScreenWidthWeb: 960 defaultScreenHeightWeb: 600 + webProgressiveAssetLoading: 0 m_StereoRenderingPath: 0 m_ActiveColorSpace: 1 + unsupportedMSAAFallback: 0 + m_SpriteBatchMaxVertexCount: 65535 m_SpriteBatchVertexThreshold: 300 m_MTRendering: 1 mipStripping: 0 numberOfMipsStripped: 0 - m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + numberOfMipsStrippedPerMipmapLimitGroup: {} + m_StackTraceTypes: 010000000100000001000000010000000100000001000000i iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 iosUseCustomAppBackgroundBehavior: 0 @@ -63,28 +67,47 @@ PlayerSettings: useOSAutorotation: 1 use32BitDisplayBuffer: 1 preserveFramebufferAlpha: 0 + adjustIOSFPSUsingThermalState: 1 + thermalStateSeriousIOSFPS: 30 + thermalStateCriticalIOSFPS: 15 disableDepthAndStencilBuffers: 0 androidStartInFullscreen: 1 androidRenderOutsideSafeArea: 0 androidUseSwappy: 0 + androidRequestedVisibleInsets: 1 + m_AndroidWindowInsets: + 2: + overlapping: 0 + appearance: 0 + 1: + overlapping: 0 + appearance: 0 + androidSystemBarsBehavior: 2 + androidSystemBarsBackground: 0 + androidDisplayOptions: 1 androidBlitType: 0 - androidResizableWindow: 0 + androidResizeableActivity: 0 androidDefaultWindowWidth: 1920 androidDefaultWindowHeight: 1080 androidMinimumWindowWidth: 400 androidMinimumWindowHeight: 300 androidFullscreenMode: 1 + androidAutoRotationBehavior: 1 + androidPredictiveBackSupport: 1 + androidApplicationEntry: 1 defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 1 - captureSingleScreen: 0 + callOnDisableOnAssetBundleUnload: 1 muteOtherAudioSources: 0 Prepare IOS For Recording: 0 Force IOS Speakers When Recording: 0 + audioSpatialExperience: 0 deferSystemGesturesMode: 0 hideHomeButton: 0 submitAnalytics: 1 usePlayerLog: 1 + dedicatedServerOptimizations: 1 bakeCollisionMeshes: 0 forceSingleInstance: 0 useFlipModelSwapchain: 1 @@ -92,6 +115,7 @@ PlayerSettings: useMacAppStoreValidation: 0 macAppStoreCategory: public.app-category.games gpuSkinning: 1 + meshDeformation: 2 xboxPIXTextureCapture: 0 xboxEnableAvatar: 0 xboxEnableKinect: 0 @@ -105,6 +129,7 @@ PlayerSettings: xboxEnableGuest: 0 xboxEnablePIXSampling: 0 metalFramebufferOnly: 0 + metalUseMetalDisplayLink: 0 xboxOneResolution: 0 xboxOneSResolution: 0 xboxOneXResolution: 3 @@ -123,46 +148,51 @@ PlayerSettings: switchAllowGpuScratchShrinking: 0 switchNVNMaxPublicTextureIDCount: 0 switchNVNMaxPublicSamplerIDCount: 0 + switchMaxWorkerMultiple: 8 switchNVNGraphicsFirmwareMemory: 32 - stadiaPresentMode: 0 - stadiaTargetFramerate: 0 + switchGraphicsJobsSyncAfterKick: 1 vulkanNumSwapchainBuffers: 3 vulkanEnableSetSRGBWrite: 0 vulkanEnablePreTransform: 0 vulkanEnableLateAcquireNextImage: 0 vulkanEnableCommandBufferRecycling: 1 loadStoreDebugModeEnabled: 0 + visionOSBundleVersion: 1.0 + tvOSBundleVersion: 1.0 bundleVersion: 0.1 preloadedAssets: [] metroInputSource: 0 wsaTransparentSwapchain: 0 - m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 1 xboxOneEnable7thCore: 1 vrSettings: enable360StereoCapture: 0 - isWsaHolographicRemotingEnabled: 0 enableFrameTimingStats: 0 enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 useHDRDisplay: 0 - D3DHDRBitDepth: 0 - m_ColorGamuts: 00000000 + hdrBitDepth: 0 + m_ColorGamuts: 00000000i targetPixelDensity: 30 resolutionScalingMode: 0 resetResolutionOnWindowResize: 0 androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 + androidMinAspectRatio: 1 applicationIdentifier: - Standalone: com.UnityTechnologies.TemplateHD + Standalone: com.Unity-Technologies.Template-HD buildNumber: Standalone: 0 + VisionOS: 0 iPhone: 0 tvOS: 0 overrideDefaultApplicationIdentifier: 0 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 22 + AndroidMinSdkVersion: 26 AndroidTargetSdkVersion: 0 + AndroidCompileSdkVersion: 0 AndroidPreferredInstallLocation: 1 + AndroidPreferredDataLocation: 1 aotOptions: stripEngineCode: 1 iPhoneStrippingLevel: 0 @@ -170,16 +200,21 @@ PlayerSettings: ForceInternetPermission: 0 ForceSDCardPermission: 0 CreateWallpaper: 0 - APKExpansionFiles: 0 + androidSplitApplicationBinary: 0 keepLoadedShadersAlive: 0 StripUnusedMeshComponents: 1 strictShaderVariantMatching: 1 VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 12.0 + iOSSimulatorArchitecture: 0 + iOSTargetOSVersionString: 16.0 tvOSSdkVersion: 0 + tvOSSimulatorArchitecture: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 12.0 + tvOSTargetOSVersionString: 16.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 + xcodeProjectType: 0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 @@ -204,7 +239,6 @@ PlayerSettings: rgba: 0 iOSLaunchScreenFillPct: 100 iOSLaunchScreenSize: 100 - iOSLaunchScreenCustomXibPath: iOSLaunchScreeniPadType: 0 iOSLaunchScreeniPadImage: {fileID: 0} iOSLaunchScreeniPadBackgroundColor: @@ -212,7 +246,6 @@ PlayerSettings: rgba: 0 iOSLaunchScreeniPadFillPct: 100 iOSLaunchScreeniPadSize: 100 - iOSLaunchScreeniPadCustomXibPath: iOSLaunchScreenCustomStoryboardPath: iOSLaunchScreeniPadCustomStoryboardPath: iOSDeviceRequirements: [] @@ -222,16 +255,18 @@ PlayerSettings: iOSMetalForceHardShadows: 0 metalEditorSupport: 1 metalAPIValidation: 1 + metalCompileShaderBinary: 0 iOSRenderExtraFrameOnPause: 0 iosCopyPluginsCodeInsteadOfSymlink: 0 appleDeveloperTeamID: iOSManualSigningProvisioningProfileID: tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: iOSManualSigningProvisioningProfileType: 0 tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 appleEnableAutomaticSigning: 0 iOSRequireARKit: 0 - iOSAutomaticallyDetectAndAddCapabilities: 1 appleEnableProMotion: 0 shaderPrecisionModel: 0 clonedFromGUID: 3af42c8365426634f9c7aed1f0e829fa @@ -243,39 +278,241 @@ PlayerSettings: useCustomLauncherGradleManifest: 0 useCustomBaseGradleTemplate: 0 useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 useCustomProguardFile: 0 AndroidTargetArchitectures: 5 - AndroidTargetDevices: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} AndroidKeystoreName: '{inproject}: ' AndroidKeyaliasName: AndroidEnableArmv9SecurityFeatures: 0 + AndroidEnableArm64MTE: 0 AndroidBuildApkPerCpuArchitecture: 0 AndroidTVCompatibility: 0 AndroidIsGame: 1 - AndroidEnableTango: 0 + androidAppCategory: 3 + useAndroidAppCategory: 1 + androidAppCategoryOther: androidEnableBanner: 1 androidUseLowAccuracyLocation: 0 androidUseCustomKeystore: 0 + androidRenderServiceUseVirtualDisplay: 0 m_AndroidBanners: - width: 320 height: 180 banner: {fileID: 0} androidGamepadSupportLevel: 0 - chromeosInputEmulation: 1 - AndroidMinifyWithR8: 0 AndroidMinifyRelease: 0 AndroidMinifyDebug: 0 AndroidValidateAppBundleSize: 1 AndroidAppBundleSizeToValidate: 150 + AndroidReportGooglePlayAppDependencies: 1 + androidSymbolsSizeThreshold: 800 + androidIconSourceType: 0 + androidAdaptiveIconVectorDrawableBackground: {fileID: 0} + androidAdaptiveIconVectorDrawableForeground: {fileID: 0} + androidAdaptiveIconVectorDrawableMonochrome: {fileID: 0} + androidAdaptiveBannerVectorDrawableBackground: {fileID: 0} + androidAdaptiveBannerVectorDrawableForeground: {fileID: 0} m_BuildTargetIcons: [] - m_BuildTargetPlatformIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: tvOS + m_Icons: + - m_Textures: [] + m_Width: 1280 + m_Height: 768 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 800 + m_Height: 480 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 400 + m_Height: 240 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 4640 + m_Height: 1440 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 2320 + m_Height: 720 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 3840 + m_Height: 1440 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 1920 + m_Height: 720 + m_Kind: 1 + m_SubKind: + - m_BuildTarget: iPhone + m_Icons: + - m_Textures: [] + m_Width: 180 + m_Height: 180 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 167 + m_Height: 167 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 152 + m_Height: 152 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 76 + m_Height: 76 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 87 + m_Height: 87 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 60 + m_Height: 60 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 20 + m_Height: 20 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 1024 + m_Height: 1024 + m_Kind: 4 + m_SubKind: App Store + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 640 + m_Height: 360 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 480 + m_Height: 270 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 320 + m_Height: 180 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 240 + m_Height: 135 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 160 + m_Height: 90 + m_Kind: 3 + m_SubKind: m_BuildTargetBatching: - m_BuildTarget: Standalone m_StaticBatching: 0 m_DynamicBatching: 0 m_UseLegacyStaticBatchingDefault: 0 + m_BuildTargetShaderSettings: [] m_BuildTargetGraphicsJobs: - m_BuildTarget: MacStandaloneSupport m_GraphicsJobs: 0 @@ -306,24 +543,31 @@ PlayerSettings: m_BuildTargetGraphicsJobMode: [] m_BuildTargetGraphicsAPIs: - m_BuildTarget: LinuxStandaloneSupport - m_APIs: 15000000 - m_Automatic: 0 + m_APIs: 15000000i + m_UGKFlags: 00000000i + m_Automatic: 1 - m_BuildTarget: MacStandaloneSupport - m_APIs: 10000000 - m_Automatic: 0 + m_APIs: 10000000i + m_UGKFlags: 00000000i + m_Automatic: 1 - m_BuildTarget: WindowsStandaloneSupport - m_APIs: 1200000002000000 - m_Automatic: 0 + m_APIs: 1200000002000000i + m_UGKFlags: 0000000000000000i + m_Automatic: 1 - m_BuildTarget: iOSSupport - m_APIs: 10000000 + m_APIs: 10000000i + m_UGKFlags: 00000000i m_Automatic: 1 - m_BuildTarget: AndroidPlayer - m_APIs: 0b000000 + m_APIs: 0b000000i + m_UGKFlags: 00000000i m_Automatic: 0 - m_BuildTarget: MetroSupport - m_APIs: 1200000002000000 + m_APIs: 1200000002000000i + m_UGKFlags: 0000000000000000i m_Automatic: 0 - m_BuildTargetVRSettings: [] + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 openGLRequireES31AEP: 0 openGLRequireES32: 0 @@ -374,6 +618,7 @@ PlayerSettings: playModeTestRunnerEnabled: 0 runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 + editorGfxJobOverride: 1 enableInternalProfiler: 0 logObjCUncaughtExceptions: 1 enableCrashReportAPI: 0 @@ -381,7 +626,7 @@ PlayerSettings: locationUsageDescription: microphoneUsageDescription: bluetoothUsageDescription: - macOSTargetOSVersion: 10.13.0 + macOSTargetOSVersion: 12.0 switchNMETAOverride: switchNetLibKey: switchSocketMemoryPoolSize: 6144 @@ -389,7 +634,7 @@ PlayerSettings: switchSocketConcurrencyLimit: 14 switchScreenResolutionBehavior: 2 switchUseCPUProfiler: 0 - switchUseGOLDLinker: 0 + switchEnableFileSystemTrace: 0 switchLTOSetting: 0 switchApplicationID: 0x01004b9000490000 switchNSODependencies: @@ -467,7 +712,6 @@ PlayerSettings: switchReleaseVersion: 0 switchDisplayVersion: 1.0.0 switchStartupUserAccount: 0 - switchTouchScreenUsage: 0 switchSupportedLanguagesMask: 0 switchLogoType: 0 switchApplicationErrorCodeCategory: @@ -509,6 +753,7 @@ PlayerSettings: switchNativeFsCacheSize: 32 switchIsHoldTypeHorizontal: 0 switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 switchSocketConfigEnabled: 0 switchTcpInitialSendBufferSize: 32 switchTcpInitialReceiveBufferSize: 64 @@ -519,12 +764,20 @@ PlayerSettings: switchSocketBufferEfficiency: 4 switchSocketInitializeEnabled: 1 switchNetworkInterfaceManagerInitializeEnabled: 1 - switchPlayerConnectionEnabled: 1 + switchDisableHTCSPlayerConnection: 0 switchUseNewStyleFilepaths: 0 + switchUseLegacyFmodPriorities: 0 switchUseMicroSleepForYield: 1 switchEnableRamDiskSupport: 0 switchMicroSleepForYieldTime: 25 switchRamDiskSpaceSize: 12 + switchUpgradedPlayerSettingsToNMETA: 1 + switchCaStoreSource: 0 + switchCaStoreFilePath: + switchStorageMode: 0 + switchStorageMounts: [] + switchPersistentDataPathMountName: + switchTemporaryCachePathMountName: ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -638,6 +891,12 @@ PlayerSettings: webGLMemoryLinearGrowthStep: 16 webGLMemoryGeometricGrowthStep: 0.2 webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 + webGLWebAssemblyTable: 0 + webGLWebAssemblyBigInt: 0 + webGLCloseOnQuit: 0 + webWasm2023: 1 + webEnableSubmoduleStrippingCompatibility: 0 scriptingDefineSymbols: : UNITY_POST_PROCESSING_STACK_V2 Android: UNITY_POST_PROCESSING_STACK_V2 @@ -653,22 +912,27 @@ PlayerSettings: additionalCompilerArguments: {} platformArchitecture: {} scriptingBackend: + Android: 0 Standalone: 0 il2cppCompilerConfiguration: {} il2cppCodeGeneration: {} + il2cppLTOMode: {} + il2cppStacktraceInformation: {} managedStrippingLevel: {} incrementalIl2cppBuild: {} suppressCommonWarnings: 1 allowUnsafeCode: 0 useDeterministicCompilation: 1 - enableRoslynAnalyzers: 1 additionalIl2CppArgs: scriptingRuntimeVersion: 1 gcIncremental: 1 gcWBarrierValidation: 0 + managedCodeVariant: {} apiCompatibilityLevelPerPlatform: {} + editorAssembliesCompatibilityLevel: 1 m_RenderingPath: 1 m_MobileRenderingPath: 1 + windowsCopyVCRuntime: 1 metroPackageName: Template_HD metroPackageVersion: metroCertificatePath: @@ -690,6 +954,7 @@ PlayerSettings: metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 platformCapabilities: {} metroTargetDeviceFamilies: {} metroFTAName: @@ -723,7 +988,6 @@ PlayerSettings: XboxOneXTitleMemory: 8 XboxOneOverrideIdentityName: XboxOneOverrideIdentityPublisher: - vrEditorSettings: {} cloudServicesEnabled: UNet: 1 luminIcon: @@ -737,10 +1001,17 @@ PlayerSettings: luminVersion: m_VersionCode: 1 m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 1 + embeddedLinuxEnableGamepadInput: 0 + hmiCpuConfiguration: + hmiLogStartupTiming: 0 + qnxGraphicConfPath: apiCompatibilityLevel: 6 captureStartupLogs: {} activeInputHandler: 1 windowsGamepadBackendHint: 0 + enableDirectStorage: 1 cloudProjectId: framebufferDepthMemorylessMode: 0 qualitySettingsNames: [] @@ -748,7 +1019,13 @@ PlayerSettings: organizationId: cloudEnabled: 0 legacyClampBlendShapeWeights: 0 - playerDataPath: - forceSRGBBlit: 1 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 virtualTexturingSupportEnabled: 0 insecureHttpOption: 0 + androidVulkanDenyFilterList: [] + androidVulkanAllowFilterList: [] + androidVulkanDeviceFilterListAsset: {fileID: 0} + d3d12DeviceFilterListAsset: {fileID: 0} + webGPUDeviceFilterListAsset: {fileID: 0} + allowedHttpConnections: 3 diff --git a/Templates/com.unity.template-hd/ProjectSettings/ProjectVersion.txt b/Templates/com.unity.template-hd/ProjectSettings/ProjectVersion.txt index 5ef0181eab9..d5c3df95dca 100644 --- a/Templates/com.unity.template-hd/ProjectSettings/ProjectVersion.txt +++ b/Templates/com.unity.template-hd/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 6000.6.0a6 -m_EditorVersionWithRevision: 6000.6.0a6 (c0efeb39a188) +m_EditorVersion: 6000.7.0b1 +m_EditorVersionWithRevision: 6000.7.0b1 (6f112f2bea37) diff --git a/Templates/com.unity.template-hd/ProjectSettings/QualitySettings.asset b/Templates/com.unity.template-hd/ProjectSettings/QualitySettings.asset index 7a384b42fee..98f158c0358 100644 --- a/Templates/com.unity.template-hd/ProjectSettings/QualitySettings.asset +++ b/Templates/com.unity.template-hd/ProjectSettings/QualitySettings.asset @@ -6,7 +6,7 @@ QualitySettings: serializedVersion: 5 m_CurrentQuality: 3 m_QualitySettings: - - serializedVersion: 4 + - serializedVersion: 5 name: Ray Tracing (Realtime GI) pixelLightCount: 2 shadows: 2 @@ -34,6 +34,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -57,8 +58,14 @@ QualitySettings: terrainBillboardStart: 50 terrainFadeLength: 5 terrainMaxTrees: 50 - excludedTargetPlatforms: [] - - serializedVersion: 4 + excludedTargetPlatforms: + - Nintendo Switch 2 + - tvOS + - WebGL + - Nintendo Switch + - iPhone + - Android + - serializedVersion: 5 name: Ray Tracing pixelLightCount: 2 shadows: 2 @@ -86,6 +93,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -109,8 +117,14 @@ QualitySettings: terrainBillboardStart: 50 terrainFadeLength: 5 terrainMaxTrees: 50 - excludedTargetPlatforms: [] - - serializedVersion: 4 + excludedTargetPlatforms: + - Nintendo Switch 2 + - tvOS + - WebGL + - Nintendo Switch + - iPhone + - Android + - serializedVersion: 5 name: High Fidelity pixelLightCount: 2 shadows: 2 @@ -138,6 +152,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -162,7 +177,7 @@ QualitySettings: terrainFadeLength: 5 terrainMaxTrees: 50 excludedTargetPlatforms: [] - - serializedVersion: 4 + - serializedVersion: 5 name: Balanced pixelLightCount: 2 shadows: 2 @@ -190,6 +205,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -214,7 +230,7 @@ QualitySettings: terrainFadeLength: 5 terrainMaxTrees: 50 excludedTargetPlatforms: [] - - serializedVersion: 4 + - serializedVersion: 5 name: Performant pixelLightCount: 2 shadows: 2 @@ -242,6 +258,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -268,11 +285,15 @@ QualitySettings: excludedTargetPlatforms: [] m_TextureMipmapLimitGroupNames: [] m_PerPlatformDefaultQuality: + Android: 3 GameCoreScarlett: 2 GameCoreXboxOne: 3 Nintendo Switch: 4 - Nintendo Switch 2: 4 + Nintendo Switch 2: 3 PS4: 3 PS5: 2 Server: 3 - Standalone: 3 + Standalone: 2 + WebGL: 4 + iPhone: 3 + tvOS: 4 diff --git a/Templates/com.unity.template-hd/ProjectSettings/Switch2PlayerSettings.asset b/Templates/com.unity.template-hd/ProjectSettings/Switch2PlayerSettings.asset new file mode 100644 index 00000000000..0491399c378 --- /dev/null +++ b/Templates/com.unity.template-hd/ProjectSettings/Switch2PlayerSettings.asset @@ -0,0 +1,72 @@ +%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: 2 + 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: 16384 + 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_StorageMode: 0 + m_StorageMounts: [] + m_PersistentDataPathMountName: + m_TemporaryCachePathMountName: + m_DockedResolution: 1 + m_HandheldResolution: 1 + m_SupportedNpadStyles: 4118 + m_ExtendedStructuredBufferBindings: 0 + m_EnableExecuteOnlyMemory: 1 + m_CaStoreSource: 0 + m_CaStoreFilePath: From 23ff2cb7741d0114a4fc18170daff25b64168090 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:12 +0000 Subject: [PATCH 039/192] [Port] [6000.7] SRP-1365: Update HDRP Blank / SRP-1355: Update URP Sample template --- .../com.unity.template.hdrp-blank/.gitignore | 1 + .../Assets/Readme.asset | 11 +- .../Assets/Scenes.meta | 8 + .../SampleScene.unity} | 0 .../SampleScene.unity.meta} | 0 .../Assets/Settings/Build Profiles.meta | 8 + .../Settings/Build Profiles/Linux.asset | 56 ++ .../Settings/Build Profiles/Linux.asset.meta | 8 + .../Settings/Build Profiles/Windows.asset | 55 ++ .../Build Profiles/Windows.asset.meta | 8 + .../Settings/Build Profiles/macOS.asset | 52 ++ .../Settings/Build Profiles/macOS.asset.meta | 8 + .../HDRenderPipelineGlobalSettings.asset | 16 + .../Assets/TutorialInfo/Icons/Help_Icon.png | 3 - .../TutorialInfo/Icons/Help_Icon.png.meta | 108 --- .../Assets/TutorialInfo/Layout.wlt | 654 ------------------ .../Scripts/Editor/ReadmeEditor.cs | 250 ++----- .../Assets/TutorialInfo/Scripts/Readme.cs | 7 +- .../{Layout.wlt.meta => StyleSheets.meta} | 5 +- .../TutorialInfo/StyleSheets/ReadmeEditor.uss | 73 ++ .../StyleSheets/ReadmeEditor.uss.meta | 11 + .../StyleSheets/ReadmeEditorDark.uss | 3 + .../StyleSheets/ReadmeEditorDark.uss.meta | 11 + .../StyleSheets/ReadmeEditorLight.uss | 3 + .../StyleSheets/ReadmeEditorLight.uss.meta | 11 + .../CHANGELOG.md | 5 + .../ValidationExceptions.json | 2 +- .../package.json | 16 +- .../Packages/manifest.json | 15 +- .../Packages/packages-lock.json | 230 ++---- .../ProjectSettings/EditorSettings.asset | 6 +- .../ProjectSettings/GraphicsSettings.asset | 21 +- .../ProjectAuditorSettings.asset | 16 +- .../ProjectSettings/ProjectSettings.asset | 466 +++++++++---- .../ProjectSettings/ProjectVersion.txt | 4 +- .../ProjectSettings/QualitySettings.asset | 26 +- .../Switch2PlayerSettings.asset | 72 ++ 37 files changed, 931 insertions(+), 1318 deletions(-) create mode 100644 Templates/com.unity.template.hdrp-blank/.gitignore create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Scenes.meta rename Templates/com.unity.template.hdrp-blank/Assets/{OutdoorsScene.unity => Scenes/SampleScene.unity} (100%) rename Templates/com.unity.template.hdrp-blank/Assets/{OutdoorsScene.unity.meta => Scenes/SampleScene.unity.meta} (100%) create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles.meta create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset.meta create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset.meta create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset.meta delete mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png delete mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png.meta delete mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt rename Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/{Layout.wlt.meta => StyleSheets.meta} (58%) create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss.meta create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss.meta create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss create mode 100644 Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss.meta create mode 100644 Templates/com.unity.template.hdrp-blank/ProjectSettings/Switch2PlayerSettings.asset diff --git a/Templates/com.unity.template.hdrp-blank/.gitignore b/Templates/com.unity.template.hdrp-blank/.gitignore new file mode 100644 index 00000000000..7fb3cb8e291 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/.gitignore @@ -0,0 +1 @@ +/ProjectSettings/PackageManager.policy diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Readme.asset b/Templates/com.unity.template.hdrp-blank/Assets/Readme.asset index 186e39b3ff6..efc633d6145 100644 --- a/Templates/com.unity.template.hdrp-blank/Assets/Readme.asset +++ b/Templates/com.unity.template.hdrp-blank/Assets/Readme.asset @@ -12,12 +12,14 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: fcf7219bab7fe46a1ad266029b2fee19, type: 3} m_Name: Readme m_EditorClassIdentifier: + commonStyle: {fileID: 7433441132597879392, guid: d2c670ece470f4c4fa6712b8dc28a9bb, type: 3} + darkStyle: {fileID: 7433441132597879392, guid: 1f902e57f049a7f47986618de93f5ee1, type: 3} + lightStyle: {fileID: 7433441132597879392, guid: 69e7ab73923f93149821ac3a88b84856, type: 3} icon: {fileID: 2800000, guid: d19680cd422524695938fbe55cc3b3bd, type: 3} title: HDRP Empty Template sections: - heading: Welcome to the HDRP Empty Template - text: This template includes the settings and assets you need to start creating - with HDRP. + text: This template includes the settings and assets you need to start creating with HDRP. linkText: url: - heading: Documentation @@ -27,13 +29,12 @@ MonoBehaviour: - heading: Samples text: linkText: Samples and content you can use in your project - url: https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest?subfolder=/manual/HDRP-Sample-Content.html + url: https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@17.6/manual/HDRP-Sample-Content.html - heading: Forums text: linkText: Get answers and support - url: https://forum.unity.com/forums/high-definition-render-pipeline.386/ + url: https://discussions.unity.com/tags/c/graphics/133/all/high-definition-render-pipeline/159335 - heading: Bugs text: linkText: Report any bugs url: https://unity3d.com/unity/qa/bug-reporting - loadedLayout: 1 diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Scenes.meta b/Templates/com.unity.template.hdrp-blank/Assets/Scenes.meta new file mode 100644 index 00000000000..2eb1ae8db7a --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8473054d9f8e3ac4391633e381bed959 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/OutdoorsScene.unity b/Templates/com.unity.template.hdrp-blank/Assets/Scenes/SampleScene.unity similarity index 100% rename from Templates/com.unity.template.hdrp-blank/Assets/OutdoorsScene.unity rename to Templates/com.unity.template.hdrp-blank/Assets/Scenes/SampleScene.unity diff --git a/Templates/com.unity.template.hdrp-blank/Assets/OutdoorsScene.unity.meta b/Templates/com.unity.template.hdrp-blank/Assets/Scenes/SampleScene.unity.meta similarity index 100% rename from Templates/com.unity.template.hdrp-blank/Assets/OutdoorsScene.unity.meta rename to Templates/com.unity.template.hdrp-blank/Assets/Scenes/SampleScene.unity.meta diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles.meta b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles.meta new file mode 100644 index 00000000000..a187cf87414 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8f2faa4632e36954b97428a9b2a1a123 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset new file mode 100644 index 00000000000..401eabece16 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: Linux + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 3 + m_BuildTarget: 24 + m_Subtarget: 2 + m_PlatformId: cb423bfea44b4d658edb8bc5d91a3024 + m_PlatformBuildProfile: + rid: 5029282017742684162 + m_SelectedPlatformGuid: + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + requiredComponents: [] + references: + version: 2 + RefIds: + - rid: 5029282017742684162 + type: {class: LinuxPlatformSettings, ns: UnityEditor.LinuxStandalone, asm: UnityEditor.LinuxStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_BuildWithCodeCoverage: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 0 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 2 + m_AdaptivePerformanceEnabled: 0 + m_Architecture: 0 + m_RemoteDeviceSectionFoldoutOpen: 0 + m_DeployTarget: 0 + m_RemoteDeviceAddress: + m_RemoteDeviceUsername: + m_RemoteDeviceExports: + m_PathOnRemoteDevice: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset.meta b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset.meta new file mode 100644 index 00000000000..f0543f899c1 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Linux.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 75ab5da139bf0f944a9dce4ea872c461 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset new file mode 100644 index 00000000000..42a01f26e1c --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset @@ -0,0 +1,55 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: Windows + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 3 + m_BuildTarget: 19 + m_Subtarget: 2 + m_PlatformId: 4e3c793746204150860bf175a9a41a05 + m_PlatformBuildProfile: + rid: 5029282017742684160 + m_SelectedPlatformGuid: + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + requiredComponents: [] + references: + version: 2 + RefIds: + - rid: 5029282017742684160 + type: {class: WindowsPlatformSettings, ns: UnityEditor.WindowsStandalone, asm: UnityEditor.WindowsStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_BuildWithCodeCoverage: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 0 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 2 + m_AdaptivePerformanceEnabled: 0 + m_WindowsBuildAndRunDeployTarget: 0 + m_Architecture: 0 + m_CreateSolution: 0 + m_CopyPDBFiles: 0 + m_WindowsDevicePortalAddress: + m_WindowsDevicePortalUsername: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset.meta b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset.meta new file mode 100644 index 00000000000..5ef5e4beb8b --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/Windows.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5ef6a2c15bff61c44b1f67e16b709240 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset new file mode 100644 index 00000000000..64cd4502bec --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !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: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: macOS + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 3 + m_BuildTarget: 2 + m_Subtarget: 2 + m_PlatformId: 0d2129357eac403d8b359c2dcbf82502 + m_PlatformBuildProfile: + rid: 5029282017742684161 + m_SelectedPlatformGuid: + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + requiredComponents: [] + references: + version: 2 + RefIds: + - rid: 5029282017742684161 + type: {class: OSXStandaloneBuildProfile, ns: UnityEditor.OSXStandalone, asm: UnityEditor.OSXStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_BuildWithCodeCoverage: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 0 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 2 + m_AdaptivePerformanceEnabled: 0 + m_MacOSXcodeBuildConfig: 1 + m_Architecture: 1 + m_CreateXcodeProject: 0 diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset.meta b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset.meta new file mode 100644 index 00000000000..d2a15d775a0 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/Build Profiles/macOS.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 967e66536f3aa664b8cbc369a6e5a503 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/Settings/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset b/Templates/com.unity.template.hdrp-blank/Assets/Settings/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset index 03bc6d12c02..1a763e99c7b 100644 --- a/Templates/com.unity.template.hdrp-blank/Assets/Settings/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset +++ b/Templates/com.unity.template.hdrp-blank/Assets/Settings/HDRPDefaultResources/HDRenderPipelineGlobalSettings.asset @@ -198,6 +198,7 @@ MonoBehaviour: - rid: 6588237625476251651 - rid: 6588237625476251652 - rid: 6588237625476251653 + - rid: 5029281976493539338 m_RuntimeSettings: m_List: [] renderingLayerNames: @@ -243,6 +244,21 @@ MonoBehaviour: references: version: 2 RefIds: + - rid: 5029281976493539338 + type: {class: SurfaceCacheRenderPipelineResourceSet, ns: UnityEngine.Rendering, asm: Unity.SurfaceCache.Runtime} + data: + m_Version: 5 + m_TemporalFilteringShader: {fileID: 7200000, guid: c23523f04780d754f927b9daf4f975b9, type: 3} + m_SpatialFilteringShader: {fileID: 7200000, guid: 63e59de460463bb4c9d64bc58051d12c, type: 3} + m_ScrollingShader: {fileID: 7200000, guid: 47bbc3edf61978b498603cc2a1b87eea, type: 3} + m_GlobalProbeShader: {fileID: 7200000, guid: 4dccb71ac6af46018e56b6ccc3974c80, type: 3} + m_DefragShader: {fileID: 7200000, guid: a183a2d0b1da4904fb3bd71c6111ebb1, type: 3} + m_EstimationShader: {fileID: 7200000, guid: 7aa73e4f3b424c41bee95499324c9297, type: 3} + m_PunctualLightSamplingShader: {fileID: 7200000, guid: 046dc07e95c240fda3212abb90fcb736, type: 3} + m_EvictionShader: {fileID: 7200000, guid: c9f2aeed6ef396f4d9134e4da1edfe19, type: 3} + m_PatchAllocationShader: {fileID: 7200000, guid: b271ec1ddd8048458fa529e8e7cfe960, type: 3} + m_EmissiveTriangleAdditionComputeShader: {fileID: 7200000, guid: 2e583cebf11e4785b8a5b0d8f7b20ab6, type: 3} + m_EmissiveTriangleRemovalComputeShader: {fileID: 7200000, guid: 3d386645a85b4e758a7b7eb1bf87fa24, type: 3} - rid: 5747374308318511104 type: {class: LensSettings, ns: UnityEngine.Rendering.HighDefinition, asm: Unity.RenderPipelines.HighDefinition.Runtime} data: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png deleted file mode 100644 index 3026257b842..00000000000 --- a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c18c946842525d4b53a6fc3c9371c8be3ba6a58a1ec28c1ddff2f5c87d5ca57 -size 18108 diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png.meta b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png.meta deleted file mode 100644 index 876228111c6..00000000000 --- a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Icons/Help_Icon.png.meta +++ /dev/null @@ -1,108 +0,0 @@ -fileFormatVersion: 2 -guid: 9266273b8f123004195741f969177dda -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 11 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - vTOnly: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 1 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 0 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 1 - spriteTessellationDetail: -1 - textureType: 2 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 0 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt deleted file mode 100644 index 7b50a252d4f..00000000000 --- a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt +++ /dev/null @@ -1,654 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &1 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_PixelRect: - serializedVersion: 2 - x: 0 - y: 45 - width: 1666 - height: 958 - m_ShowMode: 4 - m_Title: - m_RootView: {fileID: 6} - m_MinSize: {x: 950, y: 542} - m_MaxSize: {x: 10000, y: 10000} ---- !u!114 &2 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 0 - y: 466 - width: 290 - height: 442 - m_MinSize: {x: 234, y: 271} - m_MaxSize: {x: 10004, y: 10021} - m_ActualView: {fileID: 14} - m_Panes: - - {fileID: 14} - m_Selected: 0 - m_LastSelected: 0 ---- !u!114 &3 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: - - {fileID: 4} - - {fileID: 2} - m_Position: - serializedVersion: 2 - x: 973 - y: 0 - width: 290 - height: 908 - m_MinSize: {x: 234, y: 492} - m_MaxSize: {x: 10004, y: 14042} - vertical: 1 - controlID: 226 ---- !u!114 &4 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 0 - y: 0 - width: 290 - height: 466 - m_MinSize: {x: 204, y: 221} - m_MaxSize: {x: 4004, y: 4021} - m_ActualView: {fileID: 17} - m_Panes: - - {fileID: 17} - m_Selected: 0 - m_LastSelected: 0 ---- !u!114 &5 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 0 - y: 466 - width: 973 - height: 442 - m_MinSize: {x: 202, y: 221} - m_MaxSize: {x: 4002, y: 4021} - m_ActualView: {fileID: 15} - m_Panes: - - {fileID: 15} - m_Selected: 0 - m_LastSelected: 0 ---- !u!114 &6 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: - - {fileID: 7} - - {fileID: 8} - - {fileID: 9} - m_Position: - serializedVersion: 2 - x: 0 - y: 0 - width: 1666 - height: 958 - m_MinSize: {x: 950, y: 542} - m_MaxSize: {x: 10000, y: 10000} ---- !u!114 &7 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 0 - y: 0 - width: 1666 - height: 30 - m_MinSize: {x: 0, y: 0} - m_MaxSize: {x: 0, y: 0} - m_LastLoadedLayoutName: Tutorial ---- !u!114 &8 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: - - {fileID: 10} - - {fileID: 3} - - {fileID: 11} - m_Position: - serializedVersion: 2 - x: 0 - y: 30 - width: 1666 - height: 908 - m_MinSize: {x: 713, y: 492} - m_MaxSize: {x: 18008, y: 14042} - vertical: 0 - controlID: 74 ---- !u!114 &9 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 0 - y: 938 - width: 1666 - height: 20 - m_MinSize: {x: 0, y: 0} - m_MaxSize: {x: 0, y: 0} ---- !u!114 &10 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: - - {fileID: 12} - - {fileID: 5} - m_Position: - serializedVersion: 2 - x: 0 - y: 0 - width: 973 - height: 908 - m_MinSize: {x: 202, y: 442} - m_MaxSize: {x: 4002, y: 8042} - vertical: 1 - controlID: 75 ---- !u!114 &11 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 1263 - y: 0 - width: 403 - height: 908 - m_MinSize: {x: 277, y: 71} - m_MaxSize: {x: 4002, y: 4021} - m_ActualView: {fileID: 13} - m_Panes: - - {fileID: 13} - m_Selected: 0 - m_LastSelected: 0 ---- !u!114 &12 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_Children: [] - m_Position: - serializedVersion: 2 - x: 0 - y: 0 - width: 973 - height: 466 - m_MinSize: {x: 202, y: 221} - m_MaxSize: {x: 4002, y: 4021} - m_ActualView: {fileID: 16} - m_Panes: - - {fileID: 16} - m_Selected: 0 - m_LastSelected: 0 ---- !u!114 &13 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_AutoRepaintOnSceneChange: 0 - m_MinSize: {x: 275, y: 50} - m_MaxSize: {x: 4000, y: 4000} - m_TitleContent: - m_Text: Inspector - m_Image: {fileID: -6905738622615590433, guid: 0000000000000000d000000000000000, - type: 0} - m_Tooltip: - m_DepthBufferBits: 0 - m_Pos: - serializedVersion: 2 - x: 2 - y: 19 - width: 401 - height: 887 - m_ScrollPosition: {x: 0, y: 0} - m_InspectorMode: 0 - m_PreviewResizer: - m_CachedPref: -160 - m_ControlHash: -371814159 - m_PrefName: Preview_InspectorPreview - m_PreviewWindow: {fileID: 0} ---- !u!114 &14 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_AutoRepaintOnSceneChange: 0 - m_MinSize: {x: 230, y: 250} - m_MaxSize: {x: 10000, y: 10000} - m_TitleContent: - m_Text: Project - m_Image: {fileID: -7501376956915960154, guid: 0000000000000000d000000000000000, - type: 0} - m_Tooltip: - m_DepthBufferBits: 0 - m_Pos: - serializedVersion: 2 - x: 2 - y: 19 - width: 286 - height: 421 - m_SearchFilter: - m_NameFilter: - m_ClassNames: [] - m_AssetLabels: [] - m_AssetBundleNames: [] - m_VersionControlStates: [] - m_ReferencingInstanceIDs: - m_ScenePaths: [] - m_ShowAllHits: 0 - m_SearchArea: 0 - m_Folders: - - Assets - m_ViewMode: 0 - m_StartGridSize: 64 - m_LastFolders: - - Assets - m_LastFoldersGridSize: -1 - m_LastProjectPath: /Users/danielbrauer/Unity Projects/New Unity Project 47 - m_IsLocked: 0 - m_FolderTreeState: - scrollPos: {x: 0, y: 0} - m_SelectedIDs: ee240000 - m_LastClickedID: 9454 - m_ExpandedIDs: ee24000000ca9a3bffffff7f - m_RenameOverlay: - m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: - m_EditFieldRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 0 - height: 0 - m_UserData: 0 - m_IsWaitingForDelay: 0 - m_IsRenaming: 0 - m_OriginalEventType: 11 - m_IsRenamingFilename: 1 - m_ClientGUIView: {fileID: 0} - m_SearchString: - m_CreateAssetUtility: - m_EndAction: {fileID: 0} - m_InstanceID: 0 - m_Path: - m_Icon: {fileID: 0} - m_ResourceFile: - m_AssetTreeState: - scrollPos: {x: 0, y: 0} - m_SelectedIDs: 68fbffff - m_LastClickedID: 0 - m_ExpandedIDs: ee240000 - m_RenameOverlay: - m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: - m_EditFieldRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 0 - height: 0 - m_UserData: 0 - m_IsWaitingForDelay: 0 - m_IsRenaming: 0 - m_OriginalEventType: 11 - m_IsRenamingFilename: 1 - m_ClientGUIView: {fileID: 0} - m_SearchString: - m_CreateAssetUtility: - m_EndAction: {fileID: 0} - m_InstanceID: 0 - m_Path: - m_Icon: {fileID: 0} - m_ResourceFile: - m_ListAreaState: - m_SelectedInstanceIDs: 68fbffff - m_LastClickedInstanceID: -1176 - m_HadKeyboardFocusLastEvent: 0 - m_ExpandedInstanceIDs: c6230000 - m_RenameOverlay: - m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: - m_EditFieldRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 0 - height: 0 - m_UserData: 0 - m_IsWaitingForDelay: 0 - m_IsRenaming: 0 - m_OriginalEventType: 11 - m_IsRenamingFilename: 1 - m_ClientGUIView: {fileID: 0} - m_CreateAssetUtility: - m_EndAction: {fileID: 0} - m_InstanceID: 0 - m_Path: - m_Icon: {fileID: 0} - m_ResourceFile: - m_NewAssetIndexInList: -1 - m_ScrollPosition: {x: 0, y: 0} - m_GridSize: 64 - m_DirectoriesAreaWidth: 110 ---- !u!114 &15 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_AutoRepaintOnSceneChange: 1 - m_MinSize: {x: 200, y: 200} - m_MaxSize: {x: 4000, y: 4000} - m_TitleContent: - m_Text: Game - m_Image: {fileID: -2087823869225018852, guid: 0000000000000000d000000000000000, - type: 0} - m_Tooltip: - m_DepthBufferBits: 32 - m_Pos: - serializedVersion: 2 - x: 0 - y: 19 - width: 971 - height: 421 - m_MaximizeOnPlay: 0 - m_Gizmos: 0 - m_Stats: 0 - m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 - m_TargetDisplay: 0 - m_ZoomArea: - m_HRangeLocked: 0 - m_VRangeLocked: 0 - m_HBaseRangeMin: -242.75 - m_HBaseRangeMax: 242.75 - m_VBaseRangeMin: -101 - m_VBaseRangeMax: 101 - m_HAllowExceedBaseRangeMin: 1 - m_HAllowExceedBaseRangeMax: 1 - m_VAllowExceedBaseRangeMin: 1 - m_VAllowExceedBaseRangeMax: 1 - m_ScaleWithWindow: 0 - m_HSlider: 0 - m_VSlider: 0 - m_IgnoreScrollWheelUntilClicked: 0 - m_EnableMouseInput: 1 - m_EnableSliderZoom: 0 - m_UniformScale: 1 - m_UpDirection: 1 - m_DrawArea: - serializedVersion: 2 - x: 0 - y: 17 - width: 971 - height: 404 - m_Scale: {x: 2, y: 2} - m_Translation: {x: 485.5, y: 202} - m_MarginLeft: 0 - m_MarginRight: 0 - m_MarginTop: 0 - m_MarginBottom: 0 - m_LastShownAreaInsideMargins: - serializedVersion: 2 - x: -242.75 - y: -101 - width: 485.5 - height: 202 - m_MinimalGUI: 1 - m_defaultScale: 2 - m_TargetTexture: {fileID: 0} - m_CurrentColorSpace: 0 - m_LastWindowPixelSize: {x: 1942, y: 842} - m_ClearInEditMode: 1 - m_NoCameraWarning: 1 - m_LowResolutionForAspectRatios: 01000000000100000100 ---- !u!114 &16 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_AutoRepaintOnSceneChange: 1 - m_MinSize: {x: 200, y: 200} - m_MaxSize: {x: 4000, y: 4000} - m_TitleContent: - m_Text: Scene - m_Image: {fileID: 2318424515335265636, guid: 0000000000000000d000000000000000, - type: 0} - m_Tooltip: - m_DepthBufferBits: 32 - m_Pos: - serializedVersion: 2 - x: 0 - y: 19 - width: 971 - height: 445 - m_SceneLighting: 1 - lastFramingTime: 0 - m_2DMode: 0 - m_isRotationLocked: 0 - m_AudioPlay: 0 - m_Position: - m_Target: {x: 0, y: 0, z: 0} - speed: 2 - m_Value: {x: 0, y: 0, z: 0} - m_RenderMode: 0 - m_ValidateTrueMetals: 0 - m_SceneViewState: - showFog: 1 - showMaterialUpdate: 0 - showSkybox: 1 - showFlares: 1 - showImageEffects: 1 - grid: - xGrid: - m_Target: 0 - speed: 2 - m_Value: 0 - yGrid: - m_Target: 1 - speed: 2 - m_Value: 1 - zGrid: - m_Target: 0 - speed: 2 - m_Value: 0 - m_Rotation: - m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} - speed: 2 - m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} - m_Size: - m_Target: 10 - speed: 2 - m_Value: 10 - m_Ortho: - m_Target: 0 - speed: 2 - m_Value: 0 - m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0} - m_LastSceneViewOrtho: 0 - m_ReplacementShader: {fileID: 0} - m_ReplacementString: - m_LastLockedObject: {fileID: 0} - m_ViewIsLockedToObject: 0 ---- !u!114 &17 -MonoBehaviour: - m_ObjectHideFlags: 52 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 1 - m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: - m_AutoRepaintOnSceneChange: 0 - m_MinSize: {x: 200, y: 200} - m_MaxSize: {x: 4000, y: 4000} - m_TitleContent: - m_Text: Hierarchy - m_Image: {fileID: -590624980919486359, guid: 0000000000000000d000000000000000, - type: 0} - m_Tooltip: - m_DepthBufferBits: 0 - m_Pos: - serializedVersion: 2 - x: 2 - y: 19 - width: 286 - height: 445 - m_TreeViewState: - scrollPos: {x: 0, y: 0} - m_SelectedIDs: 68fbffff - m_LastClickedID: -1176 - m_ExpandedIDs: 7efbffff00000000 - m_RenameOverlay: - m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: - m_EditFieldRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 0 - height: 0 - m_UserData: 0 - m_IsWaitingForDelay: 0 - m_IsRenaming: 0 - m_OriginalEventType: 11 - m_IsRenamingFilename: 0 - m_ClientGUIView: {fileID: 0} - m_SearchString: - m_ExpandedScenes: - - - m_CurrenRootInstanceID: 0 - m_Locked: 0 - m_CurrentSortingName: TransformSorting 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 ac2579a74c5..b07cef0f555 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 @@ -1,235 +1,115 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using UnityEngine; using UnityEditor; using System.IO; -using System.Reflection; +using Unity.Scripting.LifecycleManagement; +using UnityEditor.SceneManagement; +using UnityEditorInternal; +using UnityEngine.SceneManagement; +using UnityEngine.UIElements; [CustomEditor(typeof(Readme))] -[InitializeOnLoad] -public class ReadmeEditor : Editor +sealed partial class ReadmeEditor : Editor { + const string k_ShowedReadmeSessionStateName = "ReadmeEditor.showedReadme"; + const string k_ReadmeSourceDirectory = "Assets/TutorialInfo"; - static readonly string s_ShowedReadmeSessionStateName = "ReadmeEditor.showedReadme"; - static readonly string s_ReadmeSourceDirectory = "Assets/TutorialInfo"; + [OnCodeLoaded] + static void OnCodeLoaded() + => EditorApplication.delayCall += SelectReadmeAutomatically; - const float k_Space = 16f; + static void SelectReadmeAutomatically() + { + if (!SessionState.GetBool(k_ShowedReadmeSessionStateName, false)) + { + SelectReadme(); + SessionState.SetBool(k_ShowedReadmeSessionStateName, true); + } + } - static ReadmeEditor() + static Readme SelectReadme() { - EditorApplication.delayCall += SelectReadmeAutomatically; + var ids = AssetDatabase.FindAssetGUIDs("Readme t:Readme"); + if (ids.Length != 1) + { + Debug.LogWarning("Couldn't find a readme"); + return null; + } + + var readmeObject = AssetDatabase.LoadAssetByGUID(ids[0]); + Selection.activeObject = readmeObject; + return readmeObject; } static void RemoveTutorial() { if (EditorUtility.DisplayDialog("Remove Readme Assets", - - $"All contents under {s_ReadmeSourceDirectory} will be removed, are you sure you want to proceed?", - "Proceed", - "Cancel")) + $"All contents under {k_ReadmeSourceDirectory} will be removed, are you sure you want to proceed?", + "Proceed", + "Cancel")) { - if (Directory.Exists(s_ReadmeSourceDirectory)) - { - FileUtil.DeleteFileOrDirectory(s_ReadmeSourceDirectory); - FileUtil.DeleteFileOrDirectory(s_ReadmeSourceDirectory + ".meta"); - } + if (Directory.Exists(k_ReadmeSourceDirectory)) + AssetDatabase.DeleteAsset(k_ReadmeSourceDirectory); else - { - Debug.Log($"Could not find the Readme folder at {s_ReadmeSourceDirectory}"); - } + Debug.LogWarning($"Could not find the Readme folder at {k_ReadmeSourceDirectory}"); var readmeAsset = SelectReadme(); if (readmeAsset != null) { var path = AssetDatabase.GetAssetPath(readmeAsset); - FileUtil.DeleteFileOrDirectory(path + ".meta"); - FileUtil.DeleteFileOrDirectory(path); + AssetDatabase.DeleteAsset(path); } AssetDatabase.Refresh(); } } - static void SelectReadmeAutomatically() - { - if (!SessionState.GetBool(s_ShowedReadmeSessionStateName, false)) - { - var readme = SelectReadme(); - SessionState.SetBool(s_ShowedReadmeSessionStateName, true); - - if (readme && !readme.loadedLayout) - { - LoadLayout(); - readme.loadedLayout = true; - } - } - } - - static void LoadLayout() - { - var assembly = typeof(EditorApplication).Assembly; - var windowLayoutType = assembly.GetType("UnityEditor.WindowLayout", true); - var method = windowLayoutType.GetMethod("LoadWindowLayout", BindingFlags.Public | BindingFlags.Static); - method.Invoke(null, new object[] { Path.Combine(Application.dataPath, "TutorialInfo/Layout.wlt"), false }); - } - - static Readme SelectReadme() - { - var ids = AssetDatabase.FindAssets("Readme t:Readme"); - if (ids.Length == 1) - { - var readmeObject = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(ids[0])); - - Selection.objects = new UnityEngine.Object[] { readmeObject }; - - return (Readme)readmeObject; - } - else - { - Debug.Log("Couldn't find a readme"); - return null; - } - } - - protected override void OnHeaderGUI() + public override VisualElement CreateInspectorGUI() { var readme = (Readme)target; - Init(); - var iconWidth = Mathf.Min(EditorGUIUtility.currentViewWidth / 3f - 20f, 128f); + VisualElement root = new(); + root.styleSheets.Add(readme.commonStyle); + root.styleSheets.Add(EditorGUIUtility.isProSkin ? readme.darkStyle : readme.lightStyle); - GUILayout.BeginHorizontal("In BigTitle"); + VisualElement ChainWithClass(VisualElement created, string className) { - if (readme.icon != null) - { - GUILayout.Space(k_Space); - GUILayout.Label(readme.icon, GUILayout.Width(iconWidth), GUILayout.Height(iconWidth)); - } - GUILayout.Space(k_Space); - GUILayout.BeginVertical(); - { - - GUILayout.FlexibleSpace(); - GUILayout.Label(readme.title, TitleStyle); - GUILayout.FlexibleSpace(); - } - GUILayout.EndVertical(); - GUILayout.FlexibleSpace(); + created.AddToClassList(className); + return created; } - GUILayout.EndHorizontal(); - } - public override void OnInspectorGUI() - { - var readme = (Readme)target; - Init(); + //Header + VisualElement title = new(); + title.AddToClassList("title"); + title.Add(ChainWithClass(new Image { image = readme.icon }, "title__icon")); + title.Add(ChainWithClass(new Label(readme.title), "title__text")); + root.Add(title); + //Content foreach (var section in readme.sections) { + VisualElement part = new(); + part.AddToClassList("section"); + if (!string.IsNullOrEmpty(section.heading)) - { - GUILayout.Label(section.heading, HeadingStyle); - } + part.Add(ChainWithClass(new Label(section.heading), "section__header")); if (!string.IsNullOrEmpty(section.text)) - { - GUILayout.Label(section.text, BodyStyle); - } + part.Add(ChainWithClass(new Label(section.text), "section__body")); if (!string.IsNullOrEmpty(section.linkText)) { - if (LinkLabel(new GUIContent(section.linkText))) - { - Application.OpenURL(section.url); - } + var link = ChainWithClass(new Label(section.linkText), "section__link"); + link.RegisterCallback((_, url) => Application.OpenURL(url), section.url); + part.Add(link); } - GUILayout.Space(k_Space); - } - - if (GUILayout.Button("Remove Readme Assets", ButtonStyle)) - { - RemoveTutorial(); + root.Add(part); } - } - - GUIStyle LinkStyle - { - get { return m_LinkStyle; } - } - - [SerializeField] - GUIStyle m_LinkStyle; - - GUIStyle TitleStyle - { - get { return m_TitleStyle; } - } - - [SerializeField] - GUIStyle m_TitleStyle; - - GUIStyle HeadingStyle - { - get { return m_HeadingStyle; } - } - - [SerializeField] - GUIStyle m_HeadingStyle; - - GUIStyle BodyStyle - { - get { return m_BodyStyle; } - } - - [SerializeField] - GUIStyle m_BodyStyle; - - GUIStyle ButtonStyle - { - get { return m_ButtonStyle; } - } - - [SerializeField] - GUIStyle m_ButtonStyle; - - void Init() - { - m_BodyStyle = new GUIStyle(EditorStyles.label); - m_BodyStyle.wordWrap = true; - m_BodyStyle.fontSize = 14; - m_BodyStyle.richText = true; - - m_TitleStyle = new GUIStyle(m_BodyStyle); - m_TitleStyle.fontSize = 26; - - m_HeadingStyle = new GUIStyle(m_BodyStyle); - m_HeadingStyle.fontStyle = FontStyle.Bold; - m_HeadingStyle.fontSize = 18; - - m_LinkStyle = new GUIStyle(m_BodyStyle); - m_LinkStyle.wordWrap = false; - - // Match selection color which works nicely for both light and dark skins - m_LinkStyle.normal.textColor = new Color(0x00 / 255f, 0x78 / 255f, 0xDA / 255f, 1f); - m_LinkStyle.stretchWidth = false; - - m_ButtonStyle = new GUIStyle(EditorStyles.miniButton); - m_ButtonStyle.fontStyle = FontStyle.Bold; - } - - bool LinkLabel(GUIContent label, params GUILayoutOption[] options) - { - var position = GUILayoutUtility.GetRect(label, LinkStyle, options); - - Handles.BeginGUI(); - Handles.color = LinkStyle.normal.textColor; - Handles.DrawLine(new Vector3(position.xMin, position.yMax), new Vector3(position.xMax, position.yMax)); - Handles.color = Color.white; - Handles.EndGUI(); - EditorGUIUtility.AddCursorRect(position, MouseCursor.Link); + var button = new Button(RemoveTutorial) { text = "Remove Readme Assets" }; + button.AddToClassList("remove-readme-button"); + root.Add(button); - return GUI.Button(position, label, LinkStyle); + return root; } } diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Readme.cs b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Readme.cs index 9b0ae32d4f0..a1cea2b3433 100644 --- a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Readme.cs +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Scripts/Readme.cs @@ -1,12 +1,15 @@ -using System; +using System; using UnityEngine; +using UnityEngine.UIElements; public class Readme : ScriptableObject { + public StyleSheet commonStyle; + public StyleSheet darkStyle; + public StyleSheet lightStyle; public Texture2D icon; public string title; public Section[] sections; - public bool loadedLayout; [Serializable] public class Section diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt.meta b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets.meta similarity index 58% rename from Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt.meta rename to Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets.meta index c0c8c77338f..fb4ba9d4ac9 100644 --- a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/Layout.wlt.meta +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 -guid: eabc9546105bf4accac1fd62a63e88e6 -timeCreated: 1487337779 +guid: ade3f55374df8bf46adf8442a80f057a +folderAsset: yes +timeCreated: 1475835190 licenseType: Store DefaultImporter: userData: diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss new file mode 100644 index 00000000000..a44b0c02fd2 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss @@ -0,0 +1,73 @@ +:root { + --link-color: blue; +} + +.title +{ + margin: -2px -6px 14px -15px; + padding: 20px 6px 20px 15px; + flex-direction: row; + align-items: center; + background-color: var(--unity-colors-inspector_titlebar-background); + border-bottom-width: 1px; + border-bottom-color: var(--unity-colors-inspector_titlebar-border); +} + +.title__icon +{ + max-width: 120px; + max-height: 69px; +} + +.title__text +{ + margin-left: 16px; + padding: 0; + font-size: 26px; + flex-shrink: 1; + white-space: normal; + overflow: hidden; +} + +.section +{ + align-items:flex-start; + margin-bottom: 16px; +} + +.section__header +{ + font-size: 20px; + white-space: normal; + -unity-font-style: bold; +} + +.section__body +{ + font-size: 14px; + white-space: normal; +} + +.section__link +{ + font-size: 14px; + white-space: nowrap; + overflow: hidden; + border-bottom-width: 1px; + margin-bottom: -1px; + border-bottom-color: transparent; + color: var(--link-color); +} + +.section__link:hover +{ + border-bottom-color: var(--link-color); + cursor: link; +} + +.remove-readme-button +{ + font-size: 13px; + -unity-font-style: bold; + margin: 1px 0px 1px 0px; +} diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss.meta b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss.meta new file mode 100644 index 00000000000..cb3639fb639 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditor.uss.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2c670ece470f4c4fa6712b8dc28a9bb +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} + disableValidation: 0 diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss new file mode 100644 index 00000000000..b9bc823c7d4 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss @@ -0,0 +1,3 @@ +:root { + --link-color: #7DA0FF; +} \ No newline at end of file diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss.meta b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss.meta new file mode 100644 index 00000000000..07fda7218d6 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorDark.uss.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f902e57f049a7f47986618de93f5ee1 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} + disableValidation: 0 diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss new file mode 100644 index 00000000000..72fa34b90b6 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss @@ -0,0 +1,3 @@ +:root { + --link-color: #3C28D2; +} \ No newline at end of file diff --git a/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss.meta b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss.meta new file mode 100644 index 00000000000..d3aa3274595 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/Assets/TutorialInfo/StyleSheets/ReadmeEditorLight.uss.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69e7ab73923f93149821ac3a88b84856 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} + disableValidation: 0 diff --git a/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/CHANGELOG.md b/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/CHANGELOG.md index a7205610e20..7c2888b1fc4 100644 --- a/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/CHANGELOG.md +++ b/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project template will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [17.3.0] - 2026-09-15 + +- Upgraded to Unity 6000.7.0b1 +- Disabled static batching + ## [17.2.4] - 2026-08-07 ### Changed diff --git a/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/ValidationExceptions.json b/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/ValidationExceptions.json index 4bab8388ca4..54c22d959fb 100644 --- a/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/ValidationExceptions.json +++ b/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/ValidationExceptions.json @@ -2,7 +2,7 @@ "ErrorExceptions": [ { "ValidationTest": "Primed Library Validation", - "PackageVersion": "17.2.4" + "PackageVersion": "17.3.0" } ], "WarningExceptions": [] diff --git a/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/package.json b/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/package.json index 9a82e189ecb..f42d65efeed 100644 --- a/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/package.json +++ b/Templates/com.unity.template.hdrp-blank/Packages/com.unity.template.hdrp-blank/package.json @@ -1,18 +1,16 @@ { "name": "com.unity.template.hdrp-blank", - "displayName":"3D HDRP", - "version": "17.2.4", + "displayName": "3D HDRP", + "version": "17.3.0", "type": "template", "host": "hub", - "unity": "6000.6", + "unity": "6000.7", "description": "This template includes the settings and assets you need to start creating with the High Definition Render Pipeline (HDRP).", "dependencies": { - "com.unity.collab-proxy": "2.13.5", - "com.unity.feature.development": "1.0.2", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.28", "com.unity.render-pipelines.high-definition": "17.7.0", - "com.unity.timeline": "6.6.0", - "com.unity.ugui": "2.6.0", - "com.unity.visualscripting": "1.9.12", - "com.unity.inputsystem": "1.20.0" + "com.unity.ugui": "2.7.0", + "com.unity.inputsystem": "6.7.0" } } diff --git a/Templates/com.unity.template.hdrp-blank/Packages/manifest.json b/Templates/com.unity.template.hdrp-blank/Packages/manifest.json index 34393494f76..00c35ccd33a 100644 --- a/Templates/com.unity.template.hdrp-blank/Packages/manifest.json +++ b/Templates/com.unity.template.hdrp-blank/Packages/manifest.json @@ -1,16 +1,9 @@ { "dependencies": { - "com.unity.collab-proxy": "2.13.5", - "com.unity.feature.development": "1.0.2", - "com.unity.inputsystem": "1.20.0", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.28", + "com.unity.inputsystem": "6.7.0", "com.unity.render-pipelines.high-definition": "17.7.0", - "com.unity.timeline": "6.6.0", - "com.unity.ugui": "2.6.0", - "com.unity.visualscripting": "1.9.12", - "com.unity.modules.accessibility": "1.0.0", - "com.unity.modules.adaptiveperformance": "1.0.0", - "com.unity.modules.physicscore2d": "1.0.0", - "com.unity.modules.timelinefoundation": "1.0.0", - "com.unity.modules.vectorgraphics": "1.0.0" + "com.unity.ugui": "2.7.0" } } diff --git a/Templates/com.unity.template.hdrp-blank/Packages/packages-lock.json b/Templates/com.unity.template.hdrp-blank/Packages/packages-lock.json index c706897d32e..f0cd0dcece3 100644 --- a/Templates/com.unity.template.hdrp-blank/Packages/packages-lock.json +++ b/Templates/com.unity.template.hdrp-blank/Packages/packages-lock.json @@ -6,18 +6,9 @@ "source": "builtin", "dependencies": {} }, - "com.unity.collab-proxy": { - "version": "2.13.5", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.collections": "2.6.8" - }, - "url": "https://packages.unity.com" - }, "com.unity.collections": { - "version": "6.6.0", - "depth": 1, + "version": "6.7.0", + "depth": 2, "source": "builtin", "dependencies": { "com.unity.burst": "1.8.25", @@ -26,31 +17,12 @@ "com.unity.test-framework.performance": "3.2.0" } }, - "com.unity.editorcoroutines": { - "version": "6.6.0", - "depth": 1, - "source": "builtin", - "dependencies": {} - }, "com.unity.ext.nunit": { - "version": "2.1.0", - "depth": 2, + "version": "2.1.1", + "depth": 1, "source": "builtin", "dependencies": {} }, - "com.unity.feature.development": { - "version": "1.0.2", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.ide.visualstudio": "2.0.26", - "com.unity.ide.rider": "3.0.38", - "com.unity.editorcoroutines": "6.6.0", - "com.unity.performance.profile-analyzer": "1.4.0", - "com.unity.test-framework": "1.8.0", - "com.unity.testtools.codecoverage": "1.3.0" - } - }, "com.unity.graph-authoring": { "version": "1.0.0", "depth": 2, @@ -58,8 +30,8 @@ "dependencies": {} }, "com.unity.ide.rider": { - "version": "3.0.38", - "depth": 1, + "version": "3.0.40", + "depth": 0, "source": "registry", "dependencies": { "com.unity.ext.nunit": "1.0.6" @@ -67,8 +39,8 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.26", - "depth": 1, + "version": "2.0.28", + "depth": 0, "source": "registry", "dependencies": { "com.unity.test-framework": "1.1.33" @@ -76,24 +48,16 @@ "url": "https://packages.unity.com" }, "com.unity.inputsystem": { - "version": "1.20.0", + "version": "6.7.0", "depth": 0, - "source": "registry", + "source": "builtin", "dependencies": { "com.unity.modules.uielements": "1.0.0" - }, - "url": "https://packages.unity.com" + } }, "com.unity.nuget.mono-cecil": { "version": "1.11.6", - "depth": 2, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, - "com.unity.performance.profile-analyzer": { - "version": "1.4.0", - "depth": 1, + "depth": 3, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" @@ -101,23 +65,23 @@ "com.unity.profiling.core": { "version": "1.0.3", "depth": 2, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" + "source": "builtin", + "dependencies": {} }, "com.unity.render-pipelines.core": { - "version": "17.6.0", + "version": "17.7.0", "depth": 1, "source": "builtin", "dependencies": { "com.unity.burst": "1.8.14", "com.unity.collections": "2.4.3", + "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0", "com.unity.profiling.core": "1.0.3" } }, "com.unity.render-pipelines.high-definition": { - "version": "17.6.0", + "version": "17.7.0", "depth": 0, "source": "builtin", "dependencies": { @@ -126,41 +90,34 @@ "com.unity.modules.imageconversion": "1.0.0", "com.unity.modules.physics": "1.0.0", "com.unity.modules.terrain": "1.0.0", - "com.unity.render-pipelines.core": "17.6.0", - "com.unity.shadergraph": "17.6.0", - "com.unity.visualeffectgraph": "17.6.0", - "com.unity.render-pipelines.high-definition-config": "17.6.0" + "com.unity.render-pipelines.core": "17.7.0", + "com.unity.shadergraph": "17.7.0", + "com.unity.visualeffectgraph": "17.7.0", + "com.unity.render-pipelines.high-definition-config": "17.7.0" } }, "com.unity.render-pipelines.high-definition-config": { - "version": "17.6.0", + "version": "17.7.0", "depth": 1, "source": "builtin", "dependencies": { - "com.unity.render-pipelines.core": "17.6.0" + "com.unity.render-pipelines.core": "17.7.0" } }, "com.unity.searcher": { - "version": "4.9.4", - "depth": 2, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, - "com.unity.settings-manager": { - "version": "2.1.1", + "version": "4.9.5", "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, "com.unity.shadergraph": { - "version": "17.6.0", + "version": "17.7.0", "depth": 1, "source": "builtin", "dependencies": { - "com.unity.render-pipelines.core": "17.6.0", - "com.unity.searcher": "4.9.3", + "com.unity.render-pipelines.core": "17.7.0", + "com.unity.searcher": "4.9.5", "com.unity.graph-authoring": "1.0.0" } }, @@ -169,100 +126,55 @@ "depth": 0, "source": "embedded", "dependencies": { - "com.unity.collab-proxy": "2.13.5", - "com.unity.feature.development": "1.0.2", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.28", "com.unity.render-pipelines.high-definition": "17.7.0", - "com.unity.timeline": "6.6.0", - "com.unity.ugui": "2.6.0", - "com.unity.visualscripting": "1.9.12", - "com.unity.inputsystem": "1.20.0" + "com.unity.ugui": "2.7.0", + "com.unity.inputsystem": "6.7.0" } }, "com.unity.test-framework": { - "version": "1.8.0", + "version": "1.9.0", "depth": 1, "source": "builtin", "dependencies": { "com.unity.ext.nunit": "2.1.0", - "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" } }, "com.unity.test-framework.performance": { - "version": "6.6.0", - "depth": 2, + "version": "6.7.0", + "depth": 3, "source": "builtin", "dependencies": { "com.unity.test-framework": "1.1.33", "com.unity.modules.jsonserialize": "1.0.0" } }, - "com.unity.testtools.codecoverage": { - "version": "1.3.0", - "depth": 1, - "source": "registry", - "dependencies": { - "com.unity.test-framework": "1.4.5", - "com.unity.settings-manager": "2.0.0" - }, - "url": "https://packages.unity.com" - }, - "com.unity.timeline": { - "version": "6.6.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.director": "1.0.0", - "com.unity.modules.animation": "1.0.0", - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.particlesystem": "1.0.0" - } - }, "com.unity.ugui": { - "version": "2.6.0", + "version": "2.7.0", "depth": 0, "source": "builtin", "dependencies": { "com.unity.modules.ui": "1.0.0", - "com.unity.modules.imgui": "1.0.0", - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.physics2d": "1.0.0", - "com.unity.modules.physics": "1.0.0" + "com.unity.modules.imgui": "1.0.0" } }, "com.unity.visualeffectgraph": { - "version": "17.6.0", + "version": "17.7.0", "depth": 1, "source": "builtin", "dependencies": { - "com.unity.shadergraph": "17.6.0", - "com.unity.render-pipelines.core": "17.6.0" + "com.unity.shadergraph": "17.7.0", + "com.unity.render-pipelines.core": "17.7.0" } }, - "com.unity.visualscripting": { - "version": "1.9.12", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.ugui": "2.0.0", - "com.unity.modules.jsonserialize": "1.0.0" - }, - "url": "https://packages.unity.com" - }, "com.unity.modules.accessibility": { "version": "1.0.0", - "depth": 0, + "depth": 2, "source": "builtin", "dependencies": {} }, - "com.unity.modules.adaptiveperformance": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.subsystems": "1.0.0" - } - }, "com.unity.modules.animation": { "version": "1.0.0", "depth": 1, @@ -271,19 +183,10 @@ }, "com.unity.modules.audio": { "version": "1.0.0", - "depth": 1, + "depth": 2, "source": "builtin", "dependencies": {} }, - "com.unity.modules.director": { - "version": "1.0.0", - "depth": 1, - "source": "builtin", - "dependencies": { - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.animation": "1.0.0" - } - }, "com.unity.modules.hierarchycore": { "version": "1.0.0", "depth": 2, @@ -304,13 +207,7 @@ }, "com.unity.modules.jsonserialize": { "version": "1.0.0", - "depth": 1, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.particlesystem": { - "version": "1.0.0", - "depth": 1, + "depth": 2, "source": "builtin", "dependencies": {} }, @@ -320,42 +217,12 @@ "source": "builtin", "dependencies": {} }, - "com.unity.modules.physics2d": { - "version": "1.0.0", - "depth": 1, - "source": "builtin", - "dependencies": { - "com.unity.modules.physicscore2d": "1.0.0" - } - }, - "com.unity.modules.physicscore2d": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": {} - }, - "com.unity.modules.subsystems": { - "version": "1.0.0", - "depth": 1, - "source": "builtin", - "dependencies": { - "com.unity.modules.jsonserialize": "1.0.0" - } - }, "com.unity.modules.terrain": { "version": "1.0.0", "depth": 1, "source": "builtin", "dependencies": {} }, - "com.unity.modules.timelinefoundation": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.jsonserialize": "1.0.0" - } - }, "com.unity.modules.ui": { "version": "1.0.0", "depth": 1, @@ -372,7 +239,8 @@ "com.unity.modules.jsonserialize": "1.0.0", "com.unity.modules.hierarchycore": "1.0.0", "com.unity.modules.physics": "1.0.0", - "com.unity.modules.animation": "1.0.0" + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.accessibility": "1.0.0" } }, "com.unity.modules.unitywebrequest": { @@ -381,16 +249,6 @@ "source": "builtin", "dependencies": {} }, - "com.unity.modules.vectorgraphics": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.uielements": "1.0.0", - "com.unity.modules.imageconversion": "1.0.0", - "com.unity.modules.imgui": "1.0.0" - } - }, "com.unity.modules.video": { "version": "1.0.0", "depth": 1, diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/EditorSettings.asset b/Templates/com.unity.template.hdrp-blank/ProjectSettings/EditorSettings.asset index 9ad93d57267..c1850efd328 100644 --- a/Templates/com.unity.template.hdrp-blank/ProjectSettings/EditorSettings.asset +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/EditorSettings.asset @@ -23,11 +23,10 @@ EditorSettings: m_EnableTextureStreamingInPlayMode: 1 m_EnableEditorAsyncCPUTextureLoading: 0 m_AsyncShaderCompilation: 1 - m_BlockShaders: 0 - m_UnlockBlockShaders: 0 m_PrefabModeAllowAutoSave: 1 + m_EnableMSBuildCompilationPipeline: 0 m_EnterPlayModeOptionsEnabled: 1 - m_EnterPlayModeOptions: 3 + m_EnterPlayModeOptions: 1 m_GameObjectNamingDigits: 1 m_GameObjectNamingScheme: 0 m_AssetNamingUsesSpace: 1 @@ -50,3 +49,4 @@ EditorSettings: m_ReferencedClipsExactNaming: 0 m_ForceAssetUnloadAndGCOnSceneLoad: 1 m_HideBuildProfileClassicPlatforms: 1 + m_UseLegacyHierarchy: 0 diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/GraphicsSettings.asset b/Templates/com.unity.template.hdrp-blank/ProjectSettings/GraphicsSettings.asset index b94499ad16e..d5a7af4cb98 100644 --- a/Templates/com.unity.template.hdrp-blank/ProjectSettings/GraphicsSettings.asset +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/GraphicsSettings.asset @@ -36,7 +36,18 @@ GraphicsSettings: - {fileID: 10783, 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_SkinningComputeShader: {fileID: 300, guid: 0000000000000000f000000000000000, type: 0} + m_BlendShapeComputeShader: {fileID: 301, guid: 0000000000000000f000000000000000, type: 0} m_CustomRenderPipeline: {fileID: 11400000, guid: 36dd385e759c96147b6463dcd1149c11, type: 2} m_TransparencySortMode: 0 m_TransparencySortAxis: {x: 0, y: 0, z: 1} @@ -46,7 +57,8 @@ GraphicsSettings: m_LightmapStripping: 0 m_FogStripping: 0 m_InstancingStripping: 0 - m_BrgStripping: 2 + m_BrgStripping: 0 + m_DefaultLightBaker: 0 m_LightmapKeepPlain: 1 m_LightmapKeepDirCombined: 1 m_LightmapKeepDynamicPlain: 1 @@ -59,9 +71,16 @@ GraphicsSettings: m_AlbedoSwatchInfos: [] m_RenderPipelineGlobalSettingsMap: UnityEngine.Rendering.HighDefinition.HDRenderPipeline: {fileID: 11400000, guid: ac0316ca287ba459492b669ff1317a6f, type: 2} + m_ShaderBuildSettings: + keywordDeclarationOverrides: [] + numInternalDefines: 0 + defines: [] + compilerSettings: [] + fastBuildMode: 0 m_LightsUseLinearIntensity: 1 m_LightsUseColorTemperature: 1 m_LogWhenShaderIsCompiled: 0 m_LightProbeOutsideHullStrategy: 0 m_CameraRelativeLightCulling: 0 m_CameraRelativeShadowCulling: 0 + m_DefaultMeshBufferTarget: 0 diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectAuditorSettings.asset b/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectAuditorSettings.asset index 8e078340c4c..2fe9472e94c 100644 --- a/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectAuditorSettings.asset +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectAuditorSettings.asset @@ -18,19 +18,5 @@ MonoBehaviour: paramsStack: - PlatformGroup: m_String: Unknown - m_SerializedParams: - - Key: SpriteAtlasEmptySpaceLimit - Value: 50 - - Key: TextureStreamingMipmapsSizeLimit - Value: 4000 - - Key: StreamingAssetsFolderSizeLimit - Value: 50 - - Key: StreamingClipThresholdBytes - Value: 218294 - - Key: LongDecompressedClipThresholdBytes - Value: 204800 - - Key: LongCompressedMobileClipThresholdBytes - Value: 204800 - - Key: LoadInBackGroundClipSizeThresholdBytes - Value: 204800 + m_SerializedParams: [] CurrentParamsIndex: 0 diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectSettings.asset b/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectSettings.asset index d5bb1d0eb38..3b4bdd8487d 100644 --- a/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectSettings.asset +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,8 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 28 + m_BuildProfilePlayerSettings: {fileID: 0} + serializedVersion: 32 productGUID: c71a6e77368cc6048998f34f4bbe2b86 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -45,15 +46,17 @@ PlayerSettings: defaultScreenHeight: 768 defaultScreenWidthWeb: 960 defaultScreenHeightWeb: 600 + webProgressiveAssetLoading: 0 m_StereoRenderingPath: 0 m_ActiveColorSpace: 1 unsupportedMSAAFallback: 0 + m_SpriteBatchMaxVertexCount: 65535 m_SpriteBatchVertexThreshold: 300 m_MTRendering: 1 mipStripping: 0 numberOfMipsStripped: 0 numberOfMipsStrippedPerMipmapLimitGroup: {} - m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000i iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 iosUseCustomAppBackgroundBehavior: 0 @@ -64,27 +67,42 @@ PlayerSettings: useOSAutorotation: 1 use32BitDisplayBuffer: 1 preserveFramebufferAlpha: 0 + adjustIOSFPSUsingThermalState: 1 + thermalStateSeriousIOSFPS: 30 + thermalStateCriticalIOSFPS: 15 disableDepthAndStencilBuffers: 0 androidStartInFullscreen: 1 androidRenderOutsideSafeArea: 1 androidUseSwappy: 0 + androidRequestedVisibleInsets: 0 + m_AndroidWindowInsets: + 2: + overlapping: 0 + appearance: 0 + 1: + overlapping: 0 + appearance: 0 + androidSystemBarsBehavior: 2 + androidSystemBarsBackground: 0 + androidDisplayOptions: 1 androidBlitType: 0 - androidResizableWindow: 0 + androidResizeableActivity: 0 androidDefaultWindowWidth: 1920 androidDefaultWindowHeight: 1080 androidMinimumWindowWidth: 400 androidMinimumWindowHeight: 300 androidFullscreenMode: 1 androidAutoRotationBehavior: 1 - androidApplicationEntry: 1 androidPredictiveBackSupport: 0 + androidApplicationEntry: 1 defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 0 - captureSingleScreen: 0 + callOnDisableOnAssetBundleUnload: 1 muteOtherAudioSources: 0 Prepare IOS For Recording: 0 Force IOS Speakers When Recording: 0 + audioSpatialExperience: 0 deferSystemGesturesMode: 0 hideHomeButton: 0 submitAnalytics: 1 @@ -111,6 +129,7 @@ PlayerSettings: xboxEnableGuest: 0 xboxEnablePIXSampling: 0 metalFramebufferOnly: 0 + metalUseMetalDisplayLink: 0 xboxOneResolution: 0 xboxOneSResolution: 0 xboxOneXResolution: 3 @@ -131,12 +150,15 @@ PlayerSettings: switchNVNMaxPublicSamplerIDCount: 0 switchMaxWorkerMultiple: 8 switchNVNGraphicsFirmwareMemory: 32 + switchGraphicsJobsSyncAfterKick: 1 vulkanNumSwapchainBuffers: 3 vulkanEnableSetSRGBWrite: 0 vulkanEnablePreTransform: 0 vulkanEnableLateAcquireNextImage: 0 vulkanEnableCommandBufferRecycling: 1 loadStoreDebugModeEnabled: 0 + visionOSBundleVersion: 1.0 + tvOSBundleVersion: 1.0 bundleVersion: 0.1.0 preloadedAssets: [] metroInputSource: 0 @@ -150,7 +172,7 @@ PlayerSettings: allowHDRDisplaySupport: 0 useHDRDisplay: 0 hdrBitDepth: 0 - m_ColorGamuts: 00000000 + m_ColorGamuts: 00000000i targetPixelDensity: 30 resolutionScalingMode: 0 resetResolutionOnWindowResize: 0 @@ -166,10 +188,12 @@ PlayerSettings: tvOS: 0 overrideDefaultApplicationIdentifier: 0 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 23 + AndroidMinSdkVersion: 26 AndroidTargetSdkVersion: 0 + AndroidCompileSdkVersion: 0 AndroidPreferredInstallLocation: 1 - aotOptions: + AndroidPreferredDataLocation: 1 + aotOptions: stripEngineCode: 1 iPhoneStrippingLevel: 0 iPhoneScriptCallOptimization: 0 @@ -182,12 +206,15 @@ PlayerSettings: strictShaderVariantMatching: 0 VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 13.0 + iOSSimulatorArchitecture: 0 + iOSTargetOSVersionString: 16.0 tvOSSdkVersion: 0 + tvOSSimulatorArchitecture: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 13.0 + tvOSTargetOSVersionString: 16.0 VisionOSSdkVersion: 0 VisionOSTargetOSVersionString: 1.0 + xcodeProjectType: 0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 @@ -219,8 +246,8 @@ PlayerSettings: rgba: 0 iOSLaunchScreeniPadFillPct: 100 iOSLaunchScreeniPadSize: 100 - iOSLaunchScreenCustomStoryboardPath: - iOSLaunchScreeniPadCustomStoryboardPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: iOSDeviceRequirements: [] iOSURLSchemes: [] macOSURLSchemes: [] @@ -231,20 +258,19 @@ PlayerSettings: metalCompileShaderBinary: 0 iOSRenderExtraFrameOnPause: 0 iosCopyPluginsCodeInsteadOfSymlink: 0 - appleDeveloperTeamID: - iOSManualSigningProvisioningProfileID: - tvOSManualSigningProvisioningProfileID: - VisionOSManualSigningProvisioningProfileID: + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: iOSManualSigningProvisioningProfileType: 0 tvOSManualSigningProvisioningProfileType: 0 VisionOSManualSigningProvisioningProfileType: 0 appleEnableAutomaticSigning: 0 iOSRequireARKit: 0 - iOSAutomaticallyDetectAndAddCapabilities: 1 appleEnableProMotion: 0 shaderPrecisionModel: 0 clonedFromGUID: 00000000000000000000000000000000 - templatePackageId: + templatePackageId: templateDefaultScene: Assets/OutdoorsScene.unity useCustomMainManifest: 0 useCustomLauncherManifest: 0 @@ -255,31 +281,39 @@ PlayerSettings: useCustomGradleSettingsTemplate: 0 useCustomProguardFile: 0 AndroidTargetArchitectures: 1 - AndroidTargetDevices: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} - AndroidKeystoreName: - AndroidKeyaliasName: + AndroidKeystoreName: + AndroidKeyaliasName: AndroidEnableArmv9SecurityFeatures: 0 AndroidEnableArm64MTE: 0 AndroidBuildApkPerCpuArchitecture: 0 AndroidTVCompatibility: 0 AndroidIsGame: 1 - AndroidEnableTango: 0 + androidAppCategory: 3 + useAndroidAppCategory: 1 + androidAppCategoryOther: androidEnableBanner: 1 androidUseLowAccuracyLocation: 0 androidUseCustomKeystore: 0 + androidRenderServiceUseVirtualDisplay: 0 m_AndroidBanners: - width: 320 height: 180 banner: {fileID: 0} androidGamepadSupportLevel: 0 - chromeosInputEmulation: 1 AndroidMinifyRelease: 0 AndroidMinifyDebug: 0 AndroidValidateAppBundleSize: 1 AndroidAppBundleSizeToValidate: 150 AndroidReportGooglePlayAppDependencies: 1 + androidSymbolsSizeThreshold: 800 + androidIconSourceType: 0 + androidAdaptiveIconVectorDrawableBackground: {fileID: 0} + androidAdaptiveIconVectorDrawableForeground: {fileID: 0} + androidAdaptiveIconVectorDrawableMonochrome: {fileID: 0} + androidAdaptiveBannerVectorDrawableBackground: {fileID: 0} + androidAdaptiveBannerVectorDrawableForeground: {fileID: 0} m_BuildTargetIcons: [] m_BuildTargetPlatformIcons: - m_BuildTarget: iPhone @@ -385,92 +419,154 @@ PlayerSettings: m_Width: 432 m_Height: 432 m_Kind: 2 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 324 m_Height: 324 m_Kind: 2 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 216 m_Height: 216 m_Kind: 2 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 162 m_Height: 162 m_Kind: 2 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 108 m_Height: 108 m_Kind: 2 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 81 m_Height: 81 m_Kind: 2 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 192 m_Height: 192 m_Kind: 1 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 144 m_Height: 144 m_Kind: 1 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 96 m_Height: 96 m_Kind: 1 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 72 m_Height: 72 m_Kind: 1 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 48 m_Height: 48 m_Kind: 1 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 36 m_Height: 36 m_Kind: 1 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 192 m_Height: 192 m_Kind: 0 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 144 m_Height: 144 m_Kind: 0 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 96 m_Height: 96 m_Kind: 0 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 72 m_Height: 72 m_Kind: 0 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 48 m_Height: 48 m_Kind: 0 - m_SubKind: + m_SubKind: - m_Textures: [] m_Width: 36 m_Height: 36 m_Kind: 0 - m_SubKind: + m_SubKind: + - m_Textures: [] + m_Width: 640 + m_Height: 360 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 480 + m_Height: 270 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 320 + m_Height: 180 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 240 + m_Height: 135 + m_Kind: 3 + m_SubKind: + - m_Textures: [] + m_Width: 160 + m_Height: 90 + m_Kind: 3 + m_SubKind: + - m_BuildTarget: tvOS + m_Icons: + - m_Textures: [] + m_Width: 1280 + m_Height: 768 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 800 + m_Height: 480 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 400 + m_Height: 240 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 4640 + m_Height: 1440 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 2320 + m_Height: 720 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 3840 + m_Height: 1440 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 1920 + m_Height: 720 + m_Kind: 1 + m_SubKind: m_BuildTargetBatching: - m_BuildTarget: Standalone m_StaticBatching: 0 @@ -507,21 +603,25 @@ PlayerSettings: m_BuildTargetGraphicsJobMode: [] m_BuildTargetGraphicsAPIs: - m_BuildTarget: LinuxStandaloneSupport - m_APIs: 15000000 + m_APIs: 15000000i + m_UGKFlags: 00000000i m_Automatic: 0 - m_BuildTarget: MacStandaloneSupport - m_APIs: 10000000 + m_APIs: 10000000i + m_UGKFlags: 00000000i m_Automatic: 0 - m_BuildTarget: WindowsStandaloneSupport - m_APIs: 1200000002000000 + m_APIs: 1200000002000000i + m_UGKFlags: 0000000000000000i m_Automatic: 0 - m_BuildTarget: iOSSupport - m_APIs: 10000000 + m_APIs: 10000000i + m_UGKFlags: 00000000i m_Automatic: 1 - m_BuildTarget: AndroidPlayer - m_APIs: 0b000000 + m_APIs: 0b000000i + m_UGKFlags: 00000000i m_Automatic: 0 - m_BuildTargetVRSettings: [] m_DefaultShaderChunkSizeInMB: 16 m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 @@ -551,6 +651,7 @@ PlayerSettings: - serializedVersion: 2 m_BuildTarget: Switch m_EncodingQuality: 2 + m_BuildTargetGroupHDRCubemapEncodingQuality: [] m_BuildTargetGroupLightmapSettings: [] m_BuildTargetGroupLoadStoreDebugModeSettings: [] m_BuildTargetNormalMapEncoding: [] @@ -558,16 +659,17 @@ PlayerSettings: playModeTestRunnerEnabled: 0 runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 + editorGfxJobOverride: 1 enableInternalProfiler: 0 logObjCUncaughtExceptions: 1 enableCrashReportAPI: 0 - cameraUsageDescription: - locationUsageDescription: - microphoneUsageDescription: - bluetoothUsageDescription: - macOSTargetOSVersion: 10.13.0 - switchNMETAOverride: - switchNetLibKey: + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 12.0 + switchNMETAOverride: + switchNetLibKey: switchSocketMemoryPoolSize: 6144 switchSocketAllocatorPoolSize: 128 switchSocketConcurrencyLimit: 14 @@ -575,8 +677,119 @@ PlayerSettings: switchUseCPUProfiler: 0 switchEnableFileSystemTrace: 0 switchLTOSetting: 0 - switchNSODependencies: - switchCompilerFlags: + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchCompilerFlags: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 switchSupportedNpadStyles: 22 switchNativeFsCacheSize: 32 switchIsHoldTypeHorizontal: 0 @@ -599,36 +812,43 @@ PlayerSettings: switchEnableRamDiskSupport: 0 switchMicroSleepForYieldTime: 25 switchRamDiskSpaceSize: 12 + switchUpgradedPlayerSettingsToNMETA: 1 + switchCaStoreSource: 0 + switchCaStoreFilePath: + switchStorageMode: 0 + switchStorageMounts: [] + switchPersistentDataPathMountName: + switchTemporaryCachePathMountName: ps4NPAgeRating: 12 - ps4NPTitleSecret: - ps4NPTrophyPackPath: + ps4NPTitleSecret: + ps4NPTrophyPackPath: ps4ParentalLevel: 11 ps4ContentID: ED1633-NPXX51362_00-0000000000000000 ps4Category: 0 ps4MasterVersion: 01.00 ps4AppVersion: 01.00 ps4AppType: 0 - ps4ParamSfxPath: + ps4ParamSfxPath: ps4VideoOutPixelFormat: 0 ps4VideoOutInitialWidth: 1920 ps4VideoOutBaseModeInitialWidth: 1920 ps4VideoOutReprojectionRate: 60 - ps4PronunciationXMLPath: - ps4PronunciationSIGPath: - ps4BackgroundImagePath: - ps4StartupImagePath: - ps4StartupImagesFolder: - ps4IconImagesFolder: - ps4SaveDataImagePath: - ps4SdkOverride: - ps4BGMPath: - ps4ShareFilePath: - ps4ShareOverlayImagePath: - ps4PrivacyGuardImagePath: - ps4ExtraSceSysFile: - ps4NPtitleDatPath: + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: ps4RemotePlayKeyAssignment: -1 - ps4RemotePlayKeyMappingDir: + ps4RemotePlayKeyMappingDir: ps4PlayTogetherPlayerCount: 0 ps4EnterButtonAssignment: 2 ps4ApplicationParam1: 0 @@ -656,9 +876,9 @@ PlayerSettings: ps4ScriptOptimizationLevel: 2 ps4Audio3dVirtualSpeakerCount: 14 ps4attribCpuUsage: 0 - ps4PatchPkgPath: - ps4PatchLatestPkgPath: - ps4PatchChangeinfoPath: + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: ps4PatchDayOne: 0 ps4attribUserManagement: 0 ps4attribMoveSupport: 0 @@ -674,19 +894,19 @@ PlayerSettings: ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] ps4attribVROutputEnabled: 0 - monoEnv: + monoEnv: splashScreenBackgroundSourceLandscape: {fileID: 0} splashScreenBackgroundSourcePortrait: {fileID: 0} blurSplashScreenBackground: 1 - spritePackerPolicy: + spritePackerPolicy: webGLMemorySize: 32 webGLExceptionSupport: 1 webGLNameFilesAsHashes: 0 webGLShowDiagnostics: 0 webGLDataCaching: 1 webGLDebugSymbols: 0 - webGLEmscriptenArgs: - webGLModulesDirectory: + webGLEmscriptenArgs: + webGLModulesDirectory: webGLTemplate: APPLICATION:Default webGLAnalyzeBuildSize: 0 webGLUseEmbeddedResources: 0 @@ -701,11 +921,12 @@ PlayerSettings: webGLMemoryLinearGrowthStep: 16 webGLMemoryGeometricGrowthStep: 0.2 webGLMemoryGeometricGrowthCap: 96 - webGLEnableWebGPU: 0 webGLPowerPreference: 2 webGLWebAssemblyTable: 0 webGLWebAssemblyBigInt: 0 webGLCloseOnQuit: 0 + webWasm2023: 1 + webEnableSubmoduleStrippingCompatibility: 0 scriptingDefineSymbols: {} additionalCompilerArguments: {} platformArchitecture: {} @@ -713,30 +934,33 @@ PlayerSettings: Android: 0 il2cppCompilerConfiguration: {} il2cppCodeGeneration: {} + il2cppLTOMode: {} il2cppStacktraceInformation: {} managedStrippingLevel: {} incrementalIl2cppBuild: {} suppressCommonWarnings: 1 allowUnsafeCode: 0 useDeterministicCompilation: 1 - additionalIl2CppArgs: + additionalIl2CppArgs: scriptingRuntimeVersion: 1 gcIncremental: 1 gcWBarrierValidation: 0 + managedCodeVariant: {} apiCompatibilityLevelPerPlatform: {} editorAssembliesCompatibilityLevel: 1 m_RenderingPath: 1 m_MobileRenderingPath: 1 + windowsCopyVCRuntime: 1 metroPackageName: com.unity.template-starter-kit - metroPackageVersion: - metroCertificatePath: - metroCertificatePassword: - metroCertificateSubject: - metroCertificateIssuer: + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: metroCertificateNotAfter: 0000000000000000 metroApplicationDescription: com.unity.template-starter-kit wsaImages: {} - metroTileShortName: + metroTileShortName: metroTileShowName: 0 metroMediumTileShowName: 0 metroLargeTileShowName: 0 @@ -746,28 +970,28 @@ PlayerSettings: metroDefaultTileSize: 1 metroTileForegroundText: 2 metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} - metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, - a: 1} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 platformCapabilities: {} metroTargetDeviceFamilies: {} - metroFTAName: + metroFTAName: metroFTAFileTypes: [] - metroProtocolName: - vcxProjDefaultLanguage: - XboxOneProductId: - XboxOneUpdateKey: - XboxOneSandboxId: - XboxOneContentId: - XboxOneTitleId: - XboxOneSCId: - XboxOneGameOsOverridePath: - XboxOnePackagingOverridePath: - XboxOneAppManifestOverridePath: + metroProtocolName: + vcxProjDefaultLanguage: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: XboxOneVersion: 1.0.0.0 XboxOnePackageEncryption: 0 XboxOnePackageUpdateGranularity: 2 - XboxOneDescription: + XboxOneDescription: XboxOneLanguage: - enus XboxOneCapability: [] @@ -780,39 +1004,45 @@ PlayerSettings: XboxOneAllowedProductIds: [] XboxOnePersistentLocalStorageSize: 0 XboxOneXTitleMemory: 8 - XboxOneOverrideIdentityName: - XboxOneOverrideIdentityPublisher: - vrEditorSettings: {} + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: cloudServicesEnabled: {} luminIcon: - m_Name: - m_ModelFolderPath: - m_PortalFolderPath: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: luminCert: - m_CertPath: + m_CertPath: m_SignPackage: 1 luminIsChannelApp: 0 luminVersion: m_VersionCode: 1 - m_VersionName: - hmiPlayerDataPath: + m_VersionName: + hmiPlayerDataPath: hmiForceSRGBBlit: 1 embeddedLinuxEnableGamepadInput: 0 - hmiCpuConfiguration: + hmiCpuConfiguration: hmiLogStartupTiming: 0 - qnxGraphicConfPath: + qnxGraphicConfPath: apiCompatibilityLevel: 6 captureStartupLogs: {} activeInputHandler: 1 windowsGamepadBackendHint: 0 - cloudProjectId: + enableDirectStorage: 1 + cloudProjectId: framebufferDepthMemorylessMode: 0 qualitySettingsNames: [] - projectName: - organizationId: + projectName: + organizationId: cloudEnabled: 0 legacyClampBlendShapeWeights: 0 hmiLoadingImage: {fileID: 0} platformRequiresReadableAssets: 0 virtualTexturingSupportEnabled: 0 insecureHttpOption: 0 + androidVulkanDenyFilterList: [] + androidVulkanAllowFilterList: [] + androidVulkanDeviceFilterListAsset: {fileID: 0} + d3d12DeviceFilterListAsset: {fileID: 0} + webGPUDeviceFilterListAsset: {fileID: 0} + allowedHttpConnections: 3 diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectVersion.txt b/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectVersion.txt index d2104a0a0db..d5c3df95dca 100644 --- a/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectVersion.txt +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 6000.6.0b7 -m_EditorVersionWithRevision: 6000.6.0b7 (53d4abb44f07) +m_EditorVersion: 6000.7.0b1 +m_EditorVersionWithRevision: 6000.7.0b1 (6f112f2bea37) diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/QualitySettings.asset b/Templates/com.unity.template.hdrp-blank/ProjectSettings/QualitySettings.asset index b07df8d9b5f..5a64929a7e5 100644 --- a/Templates/com.unity.template.hdrp-blank/ProjectSettings/QualitySettings.asset +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/QualitySettings.asset @@ -6,7 +6,7 @@ QualitySettings: serializedVersion: 5 m_CurrentQuality: 0 m_QualitySettings: - - serializedVersion: 4 + - serializedVersion: 5 name: High Fidelity pixelLightCount: 0 shadows: 2 @@ -34,6 +34,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -47,8 +48,7 @@ QualitySettings: asyncUploadBufferSize: 16 asyncUploadPersistentBuffer: 1 resolutionScalingFixedDPIFactor: 1 - customRenderPipeline: {fileID: 11400000, guid: 36dd385e759c96147b6463dcd1149c11, - type: 2} + customRenderPipeline: {fileID: 11400000, guid: 36dd385e759c96147b6463dcd1149c11, type: 2} terrainQualityOverrides: 0 terrainPixelError: 1 terrainDetailDensityScale: 1 @@ -59,7 +59,7 @@ QualitySettings: terrainFadeLength: 5 terrainMaxTrees: 50 excludedTargetPlatforms: [] - - serializedVersion: 4 + - serializedVersion: 5 name: Balanced pixelLightCount: 0 shadows: 2 @@ -87,6 +87,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -100,8 +101,7 @@ QualitySettings: asyncUploadBufferSize: 16 asyncUploadPersistentBuffer: 1 resolutionScalingFixedDPIFactor: 1 - customRenderPipeline: {fileID: 11400000, guid: 3e2e6bfc59709614ab90c0cd7d755e48, - type: 2} + customRenderPipeline: {fileID: 11400000, guid: 3e2e6bfc59709614ab90c0cd7d755e48, type: 2} terrainQualityOverrides: 0 terrainPixelError: 1 terrainDetailDensityScale: 1 @@ -112,7 +112,7 @@ QualitySettings: terrainFadeLength: 5 terrainMaxTrees: 50 excludedTargetPlatforms: [] - - serializedVersion: 4 + - serializedVersion: 5 name: Performant pixelLightCount: 0 shadows: 2 @@ -140,6 +140,7 @@ QualitySettings: adaptiveVsyncExtraA: 0 adaptiveVsyncExtraB: 0 lodBias: 1 + meshLodThreshold: 1 maximumLODLevel: 0 enableLODCrossFade: 1 streamingMipmapsActive: 0 @@ -153,8 +154,7 @@ QualitySettings: asyncUploadBufferSize: 16 asyncUploadPersistentBuffer: 1 resolutionScalingFixedDPIFactor: 1 - customRenderPipeline: {fileID: 11400000, guid: 168a2336534e4e043b2a210b6f8d379a, - type: 2} + customRenderPipeline: {fileID: 11400000, guid: 168a2336534e4e043b2a210b6f8d379a, type: 2} terrainQualityOverrides: 0 terrainPixelError: 1 terrainDetailDensityScale: 1 @@ -167,7 +167,7 @@ QualitySettings: excludedTargetPlatforms: [] m_TextureMipmapLimitGroupNames: [] m_PerPlatformDefaultQuality: - Android: 0 + Android: 2 CloudRendering: 0 Lumin: 0 Nintendo Switch: 2 @@ -176,8 +176,8 @@ QualitySettings: Server: 0 Stadia: 0 Standalone: 0 - WebGL: 0 + WebGL: 2 Windows Store Apps: 0 XboxOne: 0 - iPhone: 0 - tvOS: 0 + iPhone: 2 + tvOS: 2 diff --git a/Templates/com.unity.template.hdrp-blank/ProjectSettings/Switch2PlayerSettings.asset b/Templates/com.unity.template.hdrp-blank/ProjectSettings/Switch2PlayerSettings.asset new file mode 100644 index 00000000000..0491399c378 --- /dev/null +++ b/Templates/com.unity.template.hdrp-blank/ProjectSettings/Switch2PlayerSettings.asset @@ -0,0 +1,72 @@ +%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: 2 + 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: 16384 + 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_StorageMode: 0 + m_StorageMounts: [] + m_PersistentDataPathMountName: + m_TemporaryCachePathMountName: + m_DockedResolution: 1 + m_HandheldResolution: 1 + m_SupportedNpadStyles: 4118 + m_ExtendedStructuredBufferBindings: 0 + m_EnableExecuteOnlyMemory: 1 + m_CaStoreSource: 0 + m_CaStoreFilePath: From 5f1898e5407dfc294b970ab39b9b10b43535548a Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Thu, 24 Sep 2026 12:48:12 +0000 Subject: [PATCH 040/192] [Port] [6000.7] [UUM-153981] Fix Surface Cache pixels that never resolve to a patch --- .../SurfaceCacheGIRendererFeature.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 bf897436325..e1f8a184559 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 @@ -802,8 +802,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer { Debug.Assert(k_UpscaleFactor == 4); - uint cycleIndex = CurrentPerCameraState.FrameIndex % 4; - uint shuffledCycleIndex = cycleIndex * 7 % 16; + uint shuffledCycleIndex = CurrentPerCameraState.FrameIndex / (uint)cameraInfo.ViewCount * 7 % 16; passData.FullResPixelOffset = new uint2(shuffledCycleIndex / 4, shuffledCycleIndex % 4); } From 926b39555a1f267f4df787a04ef7c0f942d4f9ee Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Fri, 25 Sep 2026 13:18:14 +0000 Subject: [PATCH 041/192] [Port] [6000.7] Fix speckles/white spots with APV --- .../Lighting/ProbeVolume/ProbeVolume.hlsl | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl index 96c6b36d79b..f5ec966672a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl @@ -6,6 +6,7 @@ #endif // SHADER_API_MOBILE || SHADER_API_SWITCH || SHADER_API_SWITCH2 #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ShaderVariablesProbeVolumes.cs.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/SurfaceCache/VectorLogic.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SphericalHarmonics.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" @@ -283,11 +284,8 @@ bool LoadCellIndexMetaData(uint cellFlatIdx, out uint chunkIndex, out int stepSi return metaData.x != 0xFFFFFFFF; } -uint GetIndexData(APVResources apvRes, float3 posWS) +uint GetIndexData(APVResources apvRes, float3 entryPos, float3 residualPosWS) { - float3 entryPos = floor(posWS * _APVRcpIndirectionEntryDim); - float3 topLeftEntryWS = entryPos * _APVIndirectionEntryDim; - bool isALoadedCell = all(entryPos >= _APVMinLoadedCellInEntries) && all(entryPos <= _APVMaxLoadedCellInEntries); // Make sure we start from 0 @@ -304,7 +302,6 @@ uint GetIndexData(APVResources apvRes, float3 posWS) uint chunkIdx; if (LoadCellIndexMetaData(flatIdx, chunkIdx, stepSize, minRelativeIdx, sizeOfValid)) { - float3 residualPosWS = posWS - topLeftEntryWS; uint3 localBrickIndex = floor(residualPosWS / (_APVMinBrickSize * stepSize)); localBrickIndex = min(localBrickIndex, (uint3)(3 * 3 * 3 - 1)); // due to floating point issue, we may query an invalid brick localBrickIndex -= minRelativeIdx; // Relative to valid region @@ -353,8 +350,10 @@ APVResources FillAPVResources() bool TryToGetPoolUVWAndSubdiv(APVResources apvRes, float3 posWSForSample, out float3 uvw, out uint subdiv) { - // resolve the index - uint packed_pool_idx = GetIndexData(apvRes, posWSForSample.xyz); + float3 posInEntries = posWSForSample.xyz * _APVRcpIndirectionEntryDim; + float3 entryPos = floor(posInEntries); // integer coord of indirection entry + float3 residualPosWS = min(posInEntries - entryPos, 0.999999) * _APVIndirectionEntryDim; // WS position relative to indirection entry + uint packed_pool_idx = GetIndexData(apvRes, entryPos, residualPosWS); // unpack pool idx // size is encoded in the upper 4 bits @@ -368,8 +367,17 @@ bool TryToGetPoolUVWAndSubdiv(APVResources apvRes, float3 posWSForSample, out fl pool_idx.x = floor(flattened_pool_idx - (pool_idx.y * _APVPoolDim.x)); // calculate uv offset and scale - float brickSizeWS = pow(3.0, subdiv) * _APVMinBrickSize; - float3 offset = frac(posWSForSample.xyz / brickSizeWS); // [0;1] in brick space + float brickSizeWS = round(pow(3.0, subdiv)) * _APVMinBrickSize; + float3 offset = frac(residualPosWS / brickSizeWS); // [0;1] in brick space + + // special case when bricks are large enough to span multiple indirection entries + if (brickSizeWS > _APVIndirectionEntryDim) + { + float entriesPerBrick = round(brickSizeWS * _APVRcpIndirectionEntryDim); + float3 entryOffsetInBrick = entryPos - entriesPerBrick * floor(entryPos / entriesPerBrick); // entryPos mod entriesPerBrick + entryOffsetInBrick = VECTOR_LOGIC_SELECT(entryOffsetInBrick >= entriesPerBrick, entryOffsetInBrick - entriesPerBrick, entryOffsetInBrick); + offset = min((entryOffsetInBrick * _APVIndirectionEntryDim + residualPosWS) / brickSizeWS, 0.9999); + } //offset = clamp( offset, 0.25, 0.75 ); // [0.25;0.75] in brick space (is this actually necessary?) uvw = (pool_idx + 0.5 + (3.0 * offset)) * _APVRcpPoolDim; // add offset with brick footprint converted to text footprint in pool texel space From b136a869a4656e225390d2fde696408ffd2be945 Mon Sep 17 00:00:00 2001 From: Simon Schossleitner Date: Fri, 25 Sep 2026 13:18:14 +0000 Subject: [PATCH 042/192] [content automatically redacted] touching PlatformDependent folder --- .../BuiltInGraphicsTest_Foundation/Packages/manifest.json | 2 +- .../BuiltInGraphicsTest_Lighting/Packages/manifest.json | 2 +- Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json | 2 +- .../SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json | 2 +- Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json | 2 +- Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json | 2 +- Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json | 2 +- .../Projects/ShaderGraphUniversalStereo/Packages/manifest.json | 2 +- .../Projects/UniversalGraphicsTest_2D/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_Foundation/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_Lighting/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_PostPro/Packages/manifest.json | 2 +- .../UniversalGraphicsTest_Terrain/Packages/manifest.json | 2 +- .../Projects/VisualEffectGraph_HDRP/Packages/manifest.json | 2 +- .../Projects/VisualEffectGraph_URP/Packages/manifest.json | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json index 71db0a7a47a..8837a89fa2c 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json @@ -7,7 +7,7 @@ "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.38", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.ide.vscode": "file:../../../../../ShadowPackages/com.unity.ide.vscode", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json index 24430b0a9cd..ffaa8a4d7ea 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json @@ -7,7 +7,7 @@ "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.38", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.ide.vscode": "file:../../../../../ShadowPackages/com.unity.ide.vscode", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json index e661d618a53..19f92f4b703 100644 --- a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json @@ -2,7 +2,7 @@ "enableLockFile": false, "disableProjectUpdate": true, "dependencies": { - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "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/HDRP_RuntimeTests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json index 592df5d6ac9..e3050aea989 100644 --- a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json @@ -2,7 +2,7 @@ "enableLockFile": false, "dependencies": { "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.ide.rider": "3.0.16", "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/HDRP_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json index bdaa83f853d..31e33ef76af 100644 --- a/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_Tests/Packages/manifest.json @@ -4,7 +4,7 @@ "com.unity.collections": "1.4.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.16", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "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/SRP_SmokeTest/Packages/manifest.json b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json index fcf6051ad93..380ae29677a 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json @@ -4,7 +4,7 @@ "dependencies": { "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.17", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.inputsystem": "1.19.0", "com.unity.postprocessing": "3.5.4", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json index a3ffb59463e..45f1108b745 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json @@ -2,7 +2,7 @@ "enableLockFile": false, "dependencies": { "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.ide.vscode": "file:../../../../../ShadowPackages/com.unity.ide.vscode", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", diff --git a/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json index c78fa9f0102..d587e54ac0f 100644 --- a/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json @@ -3,7 +3,7 @@ "dependencies": { "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.ide.vscode": "file:../../../../../ShadowPackages/com.unity.ide.vscode", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json index 12221d2482a..47e9757eaef 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json @@ -9,7 +9,7 @@ "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.feature.2d": "file:../../../../../Packages/com.unity.feature.2d", "com.unity.ide.rider": "3.0.38", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json index f6453967353..b76339d3e36 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json @@ -8,7 +8,7 @@ "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.formats.alembic": "2.4.7", "com.unity.ide.rider": "3.0.7", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json index 65664223a90..36a22a0d843 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json @@ -7,7 +7,7 @@ "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.7", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json index ac0e0f678b6..d9c3c674ae5 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json @@ -7,7 +7,7 @@ "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.7", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json index 65664223a90..36a22a0d843 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json @@ -7,7 +7,7 @@ "com.unity.ext.nunit": "1.0.0", "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.7", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json index 2e56bfb5942..86bfc8ea0d4 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json @@ -4,7 +4,7 @@ "dependencies": { "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.22", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.inputsystem": "1.19.0", "com.unity.performance.profile-analyzer": "file:../../../../../ShadowPackages/com.unity.performance.profile-analyzer", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json b/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json index b545b716c11..6251cff8ae3 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json @@ -4,7 +4,7 @@ "dependencies": { "com.unity.external.test-protocol": "file:../../../../../ShadowPackages/com.unity.external.test-protocol", "com.unity.ide.rider": "3.0.22", - "com.unity.ide.visualstudio": "file:../../../../../ShadowPackages/com.unity.ide.visualstudio", + "com.unity.ide.visualstudio": "2.0.26", "com.unity.performance.profile-analyzer": "file:../../../../../ShadowPackages/com.unity.performance.profile-analyzer", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", From 1904c296d3be3113f8efd58692f0ee2a6f6b3dfe Mon Sep 17 00:00:00 2001 From: Robert Badea Date: Fri, 25 Sep 2026 13:18:16 +0000 Subject: [PATCH 043/192] [Port] [6000.7] [UUM-152170] Fix VFX crash when repeatedly undoing component add --- .../Editor/VisualEffectGraphEditorTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Packages/com.unity.visualeffectgraph/Tests/Editor/VisualEffectGraphEditorTests.cs b/Packages/com.unity.visualeffectgraph/Tests/Editor/VisualEffectGraphEditorTests.cs index 224a5ead060..fdf6d207606 100644 --- a/Packages/com.unity.visualeffectgraph/Tests/Editor/VisualEffectGraphEditorTests.cs +++ b/Packages/com.unity.visualeffectgraph/Tests/Editor/VisualEffectGraphEditorTests.cs @@ -1,7 +1,9 @@ using System; using NUnit.Framework; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; +using UnityEngine.VFX; class VisualEffectGraphEditorTests { @@ -10,4 +12,25 @@ public void DummyTest() { Assert.IsTrue(true); } + + [Test] + public void Undo_AddVisualEffectComponent_DoesNotCrash() + { + var gameObject = new GameObject("UUM_136309"); + try + { + for (int i = 0; i < 10; i++) + { + Undo.IncrementCurrentGroup(); + Undo.AddComponent(gameObject); // Implicitly adds the coupled VFXRenderer + Undo.PerformUndo(); + Assert.That(gameObject.GetComponent(), Is.Null); + Assert.That(gameObject.GetComponent(), Is.Null); + } + } + finally + { + UnityEngine.Object.DestroyImmediate(gameObject); + } + } } From 78c91cb9528c6cddbe933ed6260d7f1b65780f8c Mon Sep 17 00:00:00 2001 From: Pema Malling Date: Fri, 25 Sep 2026 22:16:55 +0000 Subject: [PATCH 044/192] [Backport] UUM-134596: URP fix shadow casters for deferred & transparents receiving shadows [V2] --- .../Runtime/DeferredLights.cs | 4 + .../Runtime/FrameData/UniversalShadowData.cs | 4 + .../AdditionalLightsShadowCasterPass.cs | 119 ++++++++++++--- .../CommonAssets/Materials/Transparent.mat | 143 ++++++++++++++++++ .../Materials/Transparent.mat.meta | 8 + ...009_AdditionalLightsShadows_Deferred.unity | 3 + ...dditionalLightsShadows_Deferred.unity.meta | 7 + 7 files changed, 264 insertions(+), 24 deletions(-) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity.meta diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs b/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs index 85c7ce8deec..b4bb4c4ceb7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs @@ -602,6 +602,10 @@ internal void ExecuteDeferredPass(RasterCommandBuffer cmd, UniversalCameraData c cmd.SetKeyword(ShaderGlobalKeywords.AdditionalLightShadows, shadowData.isKeywordAdditionalLightShadowsEnabled); ShadowUtils.SetSoftShadowQualityShaderKeywords(cmd, shadowData); cmd.SetKeyword(ShaderGlobalKeywords.LightCookies, m_LightCookieManager != null && m_LightCookieManager.IsKeywordLightCookieEnabled); + + // Everything rendered after the deferred lighting uses forward shaders, which expect a different numbering of + // _AdditionalShadowParams than the one the deferred lighting just used. + AdditionalLightsShadowCasterPass.BindAdditionalShadowParamsForForwardRendering(cmd, shadowData); } internal Matrix4x4[] GetScreenToWorldMatrix(UniversalCameraData cameraData, TextureUVOrigin depthTextureOrigin) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalShadowData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalShadowData.cs index 4ce1e71cd5e..5a012878d1b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalShadowData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalShadowData.cs @@ -100,6 +100,8 @@ public class UniversalShadowData : ContextItem // Owned by AdditionalLightsShadowCasterPass internal GraphicsBuffer emptyAdditionalLightShadowsBuffer; + internal GraphicsBuffer extraForwardAdditionalLightShadowsBuffer; + internal Vector4[] extraForwardAdditionalLightShadowParams; internal short[] visibleLightIndexToAdditionalLightIndex; internal bool[] visibleLightIndexToIsCastingShadows; @@ -141,6 +143,8 @@ public override void Reset() visibleLightIndexToIsCastingShadows = null; emptyAdditionalLightShadowsBuffer = null; + extraForwardAdditionalLightShadowsBuffer = null; + extraForwardAdditionalLightShadowParams = null; useCachedShadowMap = false; shadowMapCachingEnabled = false; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs index cc8d243f921..23e1a7e22a4 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs @@ -49,6 +49,8 @@ static void ResetStaticsOnLoad() private short[] m_VisibleLightIndexToAdditionalLightIndex; // maps a "global" visible light index (index to lightData.visibleLights) to an "additional light index" (index to arrays _AdditionalLightsPosition, _AdditionalShadowParams, ...), or -1 if it is not an additional light (i.e if it is the main light) private short[] m_AdditionalLightIndexToVisibleLightIndex; // maps additional light index (index to arrays _AdditionalLightsPosition, _AdditionalShadowParams, ...) to its "global" visible light index (index to lightData.visibleLights) private Vector4[] m_AdditionalLightIndexToShadowParams; // per-additional-light shadow info passed to the lighting shader (x: shadowStrength, y: softShadows, z: light type, w: perLightFirstShadowSliceIndex) + private Vector4[] m_ExtraForwardAdditionalLightIndexToShadowParams; // same as m_AdditionalLightIndexToShadowParams, but always indexed by visible light index. m_AdditionalLightIndexToShadowParams is indexed by shadowcasting light index when using deferred rendering. + private bool m_NeedExtraForwardShadowParamsCopy; // do we need to populate m_ExtraForwardAdditionalLightIndexToShadowParams? private Matrix4x4[] m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix; // per-shadow-slice info passed to the lighting shader private ShadowSliceData[] m_AdditionalLightsShadowSlices; private readonly List m_GlobalShadowSliceIndexToPerLightShadowSliceIndex = new(); // For each shadow slice, store its "per-light shadow slice index" in the punctual light that casts it (can be up to 5 for point lights) @@ -71,9 +73,11 @@ static void ResetStaticsOnLoad() private const int k_AdditionalLightShadowsChannelCount = k_ShadowParamsChannel + 1; // 4 (matrix) + 1 (shadow params) private const string k_AdditionalLightShadowsCBName = "Additional Light Shadows Buffer"; private const string k_EmptyAdditionalLightShadowsCBName = "Empty Additional Light Shadows Buffer"; + private const string k_ExtraForwardAdditionalLightShadowsCBName = "Extra Forward Additional Light Shadows Buffer"; - private NativeArray m_AdditionalLightShadowsData; + private NativeArray m_AdditionalLightShadowsScratch; // write-only on CPU, just used to upload to GraphicsBuffer without allocating private GraphicsBuffer m_AdditionalLightShadowsBuffer; + private GraphicsBuffer m_ExtraForwardAdditionalLightShadowsBuffer; // only used with deferred renderer, see m_ExtraForwardAdditionalLightIndexToShadowParams private GraphicsBuffer m_EmptyAdditionalLightShadowsBuffer; // x is used in RenderAdditionalShadowMapAtlas to skip shadow map rendering for non-shadow-casting lights. @@ -147,14 +151,25 @@ public AdditionalLightsShadowCasterPass(RenderPassEvent evt) /// private void EnsureBuffersCreated() { - if (!m_UsePersistentConstantBuffer || m_AdditionalLightShadowsBuffer != null) + if (!m_UsePersistentConstantBuffer) return; int length = m_MaxVisibleAdditionalLights * k_AdditionalLightShadowsChannelCount; if (length <= 0) return; - m_AdditionalLightShadowsData = new NativeArray(length, Allocator.Persistent); + if (m_NeedExtraForwardShadowParamsCopy && m_ExtraForwardAdditionalLightShadowsBuffer == null) + { + m_ExtraForwardAdditionalLightShadowsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Constant, length, UnsafeUtility.SizeOf()) + { + name = k_ExtraForwardAdditionalLightShadowsCBName + }; + } + + if (m_AdditionalLightShadowsBuffer != null) + return; + + m_AdditionalLightShadowsScratch = new NativeArray(length, Allocator.Persistent); m_AdditionalLightShadowsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Constant, length, UnsafeUtility.SizeOf()) { @@ -186,14 +201,17 @@ public void Dispose() if (m_UsePersistentConstantBuffer) { - if (m_AdditionalLightShadowsData.IsCreated) - m_AdditionalLightShadowsData.Dispose(); + if (m_AdditionalLightShadowsScratch.IsCreated) + m_AdditionalLightShadowsScratch.Dispose(); Shader.SetGlobalConstantBuffer(AdditionalShadowsConstantBuffer._AdditionalLightShadowsBufferID, (ComputeBuffer)null, 0, 0); m_AdditionalLightShadowsBuffer?.Dispose(); m_AdditionalLightShadowsBuffer = null; + m_ExtraForwardAdditionalLightShadowsBuffer?.Dispose(); + m_ExtraForwardAdditionalLightShadowsBuffer = null; + m_EmptyAdditionalLightShadowsBuffer?.Dispose(); m_EmptyAdditionalLightShadowsBuffer = null; } @@ -440,12 +458,21 @@ internal bool Setup(UniversalRenderingData renderingData, UniversalCameraData ca shadowData.visibleLightIndexToAdditionalLightIndex = m_VisibleLightIndexToAdditionalLightIndex; shadowData.visibleLightIndexToIsCastingShadows = m_VisibleLightIndexToIsCastingShadows; + // Left null when there is nothing extra to bind, the empty shadowmap path already sets the params. + bool bindExtraForwardShadowParams = m_NeedExtraForwardShadowParamsCopy && m_ShadowPassMode != ShadowPassMode.Empty; + shadowData.extraForwardAdditionalLightShadowsBuffer = bindExtraForwardShadowParams ? m_ExtraForwardAdditionalLightShadowsBuffer : null; + shadowData.extraForwardAdditionalLightShadowParams = bindExtraForwardShadowParams ? m_ExtraForwardAdditionalLightIndexToShadowParams : null; + return willRenderShadowGeometry; } // Decides the ShadowPassMode for the frame and prepares the state RecordRenderGraph() needs for it. bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalLightData lightData, UniversalShadowData shadowData, bool stencilBuffer, bool shadowsEnabledByCamera) { + UniversalRenderer universalRenderer = cameraData.renderer as UniversalRenderer; + bool isStencilDeferred = universalRenderer != null && universalRenderer.renderingModeActual == RenderingMode.Deferred; + m_NeedExtraForwardShadowParamsCopy = isStencilDeferred && universalRenderer.shadowTransparentReceive; + // Lazy init: ensure buffers exist (may have been destroyed by domain reload or graphics device reset) EnsureBuffersCreated(); @@ -566,6 +593,15 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa for (int i = 0; i < maxAdditionalLightShadowParams; ++i) m_AdditionalLightIndexToShadowParams[i] = c_DefaultShadowParams; + if (m_NeedExtraForwardShadowParamsCopy) + { + // Match length of m_AdditionalLightIndexToShadowParams, so the array can be copied into the constant buffer as-is. + if (m_ExtraForwardAdditionalLightIndexToShadowParams == null || m_ExtraForwardAdditionalLightIndexToShadowParams.Length < m_AdditionalLightIndexToShadowParams.Length) + m_ExtraForwardAdditionalLightIndexToShadowParams = new Vector4[m_AdditionalLightIndexToShadowParams.Length]; + + Array.Copy(m_AdditionalLightIndexToShadowParams, m_ExtraForwardAdditionalLightIndexToShadowParams, maxAdditionalLightShadowParams); + } + for (int i = 0; i < m_VisibleLightIndexToAdditionalLightIndex.Length; ++i) { m_VisibleLightIndexToAdditionalLightIndex[i] = -1; @@ -574,18 +610,16 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa short additionalLightCount = 0; short validShadowCastingLightsCount = 0; + short stencilDeferredLightIndex = 0; bool supportsSoftShadows = shadowData.supportsSoftShadows; - UniversalRenderer universalRenderer = (UniversalRenderer)cameraData.renderer; - bool isDeferred = universalRenderer.renderingModeActual == RenderingMode.Deferred; - bool shadowTransparentReceive = universalRenderer.shadowTransparentReceive; - bool hasForwardShadowPass = !isDeferred || shadowTransparentReceive; for (int visibleLightIndex = 0; visibleLightIndex < visibleLights.Length; ++visibleLightIndex) { // Skip main directional light as it is not packed into the shadow atlas if (visibleLightIndex == lightData.mainLightIndex) continue; - short lightIndexToUse = !hasForwardShadowPass ? validShadowCastingLightsCount : additionalLightCount++; + short forwardLightIndex = additionalLightCount++; + short lightIndexToUse = isStencilDeferred ? stencilDeferredLightIndex : forwardLightIndex; // We need to always set these indices, even if the light is not shadow casting or doesn't fit in the shadow slices (UUM-46577) m_VisibleLightIndexToAdditionalLightIndex[visibleLightIndex] = lightIndexToUse; @@ -621,6 +655,8 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa break; } + bool copyExtraForwardShadowParams = m_NeedExtraForwardShadowParamsCopy && forwardLightIndex < m_ExtraForwardAdditionalLightIndexToShadowParams.Length; + int perLightFirstShadowSliceIndex = m_ShadowSliceToAdditionalLightIndex.Count; // shadowSliceIndex within the global array of all additional light shadow slices bool shouldAddLight = false; for (byte perLightShadowSlice = 0; perLightShadowSlice < perLightShadowSlicesCount; ++perLightShadowSlice) @@ -639,6 +675,11 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa { shadowParams.w = lightIndexToUse; m_AdditionalLightIndexToShadowParams[lightIndexToUse] = shadowParams; + if (copyExtraForwardShadowParams) + { + shadowParams.w = forwardLightIndex; + m_ExtraForwardAdditionalLightIndexToShadowParams[forwardLightIndex] = shadowParams; + } m_VisibleLightIndexToIsCastingShadows[visibleLightIndex] = usesBakedShadows; } continue; @@ -665,6 +706,8 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix[globalShadowSliceIndex] = sliceData.shadowTransform; shadowParams.w = perLightFirstShadowSliceIndex; m_AdditionalLightIndexToShadowParams[lightIndexToUse] = shadowParams; + if (copyExtraForwardShadowParams) + m_ExtraForwardAdditionalLightIndexToShadowParams[forwardLightIndex] = shadowParams; shouldAddLight = true; } } @@ -684,6 +727,8 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix[globalShadowSliceIndex] = sliceData.shadowTransform; shadowParams.w = perLightFirstShadowSliceIndex; m_AdditionalLightIndexToShadowParams[lightIndexToUse] = shadowParams; + if (copyExtraForwardShadowParams) + m_ExtraForwardAdditionalLightIndexToShadowParams[forwardLightIndex] = shadowParams; shouldAddLight = true; } } @@ -701,7 +746,14 @@ bool SetupShadowPassMode(UniversalRenderingData renderingData, UniversalCameraDa m_VisibleLightIndexToIsCastingShadows[visibleLightIndex] = usesBakedShadows; shadowParams.w = c_DefaultShadowParams.w; m_AdditionalLightIndexToShadowParams[lightIndexToUse] = shadowParams; + if (copyExtraForwardShadowParams) + m_ExtraForwardAdditionalLightIndexToShadowParams[forwardLightIndex] = shadowParams; } + + // Every light that is reachable through m_VisibleLightIndexToIsCastingShadows needs its own slot, + // even mixed lights that only have baked shadows. + if (m_VisibleLightIndexToIsCastingShadows[visibleLightIndex]) + stencilDeferredLightIndex++; } // Lights that need to be rendered in the shadow map atlas @@ -904,6 +956,18 @@ private void Clear() m_GlobalShadowSliceIndexToPerLightShadowSliceIndex.Clear(); } + + // Binds _AdditionalShadowParams using the visible light numbering, for the passes that still use forward rendering + // after the deferred lighting. + internal static void BindAdditionalShadowParamsForForwardRendering(RasterCommandBuffer cmd, UniversalShadowData shadowData) + { + GraphicsBuffer constantBuffer = shadowData.extraForwardAdditionalLightShadowsBuffer; + if (constantBuffer != null) + cmd.SetGlobalConstantBuffer(constantBuffer, AdditionalShadowsConstantBuffer._AdditionalLightShadowsBufferID, 0, constantBuffer.count * constantBuffer.stride); + else if (shadowData.extraForwardAdditionalLightShadowParams != null) + cmd.SetGlobalVectorArray(AdditionalShadowsConstantBuffer._AdditionalShadowParams, shadowData.extraForwardAdditionalLightShadowParams); + } + internal static void SetShadowParamsForEmptyShadowmap(IBaseCommandBuffer cmd, GraphicsBuffer emptyShadowsBuffer) { cmd.SetGlobalVector(AdditionalShadowsConstantBuffer._AdditionalShadowFadeParams, s_EmptyAdditionalShadowFadeParams); @@ -1042,6 +1106,21 @@ private void SetShadowGlobalKeywordsAndConstants(RasterCommandBuffer cmd, ref Pa SetupAdditionalLightsShadowReceiverConstants(cmd, data.usePersistentConstantBuffer); } + // Fills a graphics buffer with the data corresponding to the CBUFFER(AdditionalLightShadows) layout. + private void PackShadowsConstantBuffer(GraphicsBuffer constantBuffer, Matrix4x4[] worldToShadowMatrices, Vector4[] shadowParams) + { + int worldToShadowOffset = m_MaxVisibleAdditionalLights * k_WorldToShadowChannel; + int shadowParamsOffset = m_MaxVisibleAdditionalLights * k_ShadowParamsChannel; + + if (worldToShadowMatrices != null && worldToShadowMatrices.Length > 0) + m_AdditionalLightShadowsScratch.GetSubArray(worldToShadowOffset, shadowParamsOffset).Reinterpret(UnsafeUtility.SizeOf()).CopyFrom(worldToShadowMatrices); + + if (shadowParams != null && shadowParams.Length > 0) + m_AdditionalLightShadowsScratch.GetSubArray(shadowParamsOffset, m_MaxVisibleAdditionalLights).CopyFrom(shadowParams); + + constantBuffer.SetData(m_AdditionalLightShadowsScratch); + } + // Set constant buffer data that will be used during the lighting/shadowing pass private void SetupAdditionalLightsShadowReceiverConstants(RasterCommandBuffer cmd, bool usePersistentCBuffer) { @@ -1050,24 +1129,16 @@ private void SetupAdditionalLightsShadowReceiverConstants(RasterCommandBuffer cm if (usePersistentCBuffer) { - if (m_AdditionalLightShadowsData.IsCreated && m_AdditionalLightShadowsBuffer != null) + if (m_AdditionalLightShadowsScratch.IsCreated && m_AdditionalLightShadowsBuffer != null) { - // Pack per-channel managed arrays into the Vector4 backing store, matching CBUFFER(AdditionalLightShadows) layout. - int worldToShadowOffset = m_MaxVisibleAdditionalLights * k_WorldToShadowChannel; - int shadowParamsOffset = m_MaxVisibleAdditionalLights * k_ShadowParamsChannel; + PackShadowsConstantBuffer(m_AdditionalLightShadowsBuffer, m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix, m_AdditionalLightIndexToShadowParams); + cmd.SetGlobalConstantBuffer(m_AdditionalLightShadowsBuffer, AdditionalShadowsConstantBuffer._AdditionalLightShadowsBufferID, 0, m_AdditionalLightShadowsScratch.Length * UnsafeUtility.SizeOf()); - if (m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix != null && m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix.Length > 0) + if (m_NeedExtraForwardShadowParamsCopy && m_ExtraForwardAdditionalLightShadowsBuffer != null) { - m_AdditionalLightShadowsData.GetSubArray(worldToShadowOffset, shadowParamsOffset).Reinterpret(UnsafeUtility.SizeOf()).CopyFrom(m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix); + // Will be bound later in the frame, in BindAdditionalShadowParamsForForwardRendering + PackShadowsConstantBuffer(m_ExtraForwardAdditionalLightShadowsBuffer, m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix, m_ExtraForwardAdditionalLightIndexToShadowParams); } - - if (m_AdditionalLightIndexToShadowParams != null && m_AdditionalLightIndexToShadowParams.Length > 0) - { - m_AdditionalLightShadowsData.GetSubArray(shadowParamsOffset, m_MaxVisibleAdditionalLights).CopyFrom(m_AdditionalLightIndexToShadowParams); - } - - m_AdditionalLightShadowsBuffer.SetData(m_AdditionalLightShadowsData); - cmd.SetGlobalConstantBuffer(m_AdditionalLightShadowsBuffer, AdditionalShadowsConstantBuffer._AdditionalLightShadowsBufferID, 0, m_AdditionalLightShadowsData.Length * UnsafeUtility.SizeOf()); } } else diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat new file mode 100644 index 00000000000..060af4c6bd2 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat @@ -0,0 +1,143 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-2677342806866868952 +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: Transparent + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _SURFACE_TYPE_TRANSPARENT + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - MOTIONVECTORS + - DepthOnly + - SHADOWCASTER + 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: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _ScreenSpaceReflections: 1 + - _ScreenSpaceReflectionsContributeTransparent: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 0.47058824} + - _Color: {r: 1, g: 1, b: 1, a: 0.47058824} + - _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/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat.meta new file mode 100644 index 00000000000..8167a59d9f7 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/CommonAssets/Materials/Transparent.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 77205ff6023799548a516c6dc0013da2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity new file mode 100644 index 00000000000..2060578ce10 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03905dcdd6c7ea9abb64cb357b6e70e2ed0019c8905fe84773c3aae86a406cf4 +size 1180516 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity.meta new file mode 100644 index 00000000000..c7a91a707c8 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Assets/Scenes/009_AdditionalLightsShadows_Deferred.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5c626e8cf00997340b36f9933b055278 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 4729a0b0cfa7a003b0a5e0fd75060d17df413650 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Sun, 27 Sep 2026 19:35:09 +0000 Subject: [PATCH 045/192] [Port] [6000.7] [UUM-152815] Fix Shadow Displacement space, negative scale and flip --- .../Includes/ShadowCaster2DPass.hlsl | 48 ++++++++++------- .../Nodes/ShadowCaster2DLightNode.cs | 27 ++++++---- .../ShaderGraph/UniversalBlockFields.cs | 21 ++++---- .../Runtime/2D/Lights/Light2D.cs | 6 +++ .../2D/Rendergraph/Renderer2DRendergraph.cs | 14 ++++- .../Runtime/2D/Shadows/ShadowCaster2D.cs | 7 +++ .../Runtime/2D/Shadows/ShadowRendering.cs | 28 +++++++++- .../2D/Include/SoftShadowProjectVertex.hlsl | 52 +++++++++++++++++++ 8 files changed, 161 insertions(+), 42 deletions(-) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/ShadowCaster2DPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/ShadowCaster2DPass.hlsl index 21ecd45bd1b..1724885978d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/ShadowCaster2DPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Includes/ShadowCaster2DPass.hlsl @@ -145,15 +145,15 @@ PackedVaryings vert(Attributes input) SoftShadowSoftness softness; pointAttributes.positionOS.xy = payload.positionOS.xy; - { VertexDescription d = BuildVertexDescription(pointAttributes); pV = d.Position.xy; disp.v = d.ShadowDisplacement; softness.side = _SoftShadowAngle * saturate(d.ShadowSideSoftness); softness.back = _SoftShadowAngle * saturate(d.ShadowBackSoftness); } + { VertexDescription d = BuildVertexDescription(pointAttributes); pV = d.Position.xy; disp.v = SoftShadowWorldDirectionToLocal(d.ShadowDisplacement); softness.side = _SoftShadowAngle * saturate(d.ShadowSideSoftness); softness.back = _SoftShadowAngle * saturate(d.ShadowBackSoftness); } pointAttributes.positionOS.xy = payload.tangent.zw; - { VertexDescription d = BuildVertexDescription(pointAttributes); pP = d.Position.xy; disp.prev = d.ShadowDisplacement; softness.backPrev = _SoftShadowAngle * saturate(d.ShadowBackSoftness); } + { VertexDescription d = BuildVertexDescription(pointAttributes); pP = d.Position.xy; disp.prev = SoftShadowWorldDirectionToLocal(d.ShadowDisplacement); softness.backPrev = _SoftShadowAngle * saturate(d.ShadowBackSoftness); } pointAttributes.positionOS.xy = payload.next.xy; - { VertexDescription d = BuildVertexDescription(pointAttributes); pN = d.Position.xy; disp.next = d.ShadowDisplacement; softness.backNext = _SoftShadowAngle * saturate(d.ShadowBackSoftness); } + { VertexDescription d = BuildVertexDescription(pointAttributes); pN = d.Position.xy; disp.next = SoftShadowWorldDirectionToLocal(d.ShadowDisplacement); softness.backNext = _SoftShadowAngle * saturate(d.ShadowBackSoftness); } pointAttributes.positionOS.xy = payload.neighbor2.xy; - { VertexDescription d = BuildVertexDescription(pointAttributes); pP2 = d.Position.xy; disp.prev2 = d.ShadowDisplacement; } + { VertexDescription d = BuildVertexDescription(pointAttributes); pP2 = d.Position.xy; disp.prev2 = SoftShadowWorldDirectionToLocal(d.ShadowDisplacement); } pointAttributes.positionOS.xy = payload.neighbor2.zw; - { VertexDescription d = BuildVertexDescription(pointAttributes); pN2 = d.Position.xy; disp.next2 = d.ShadowDisplacement; } + { VertexDescription d = BuildVertexDescription(pointAttributes); pN2 = d.Position.xy; disp.next2 = SoftShadowWorldDirectionToLocal(d.ShadowDisplacement); } payload.positionOS.xy = pV; payload.tangent.zw = pP; @@ -175,24 +175,32 @@ PackedVaryings vert(Attributes input) // caster meets the B-channel unshadow interlock, which assumes the projected shadow leaves the // caster. That composite is outside what this file can guard. - // The displacement is read in the CASTER'S OWN FRAME and needs no transform at all. + // The displacement is authored in WORLD space, and converted into the caster's frame at each of + // the five reads above. // - // That frame is the space the projection runs in, and it reaches world through _ShadowModelMatrix, - // which ShadowCaster2D.CacheValues builds as TRS with only a +/-1 flip for scale -- an isometry. So - // a displacement here is a world-length offset along the caster's local axes, and (0, -2) means - // "two units along this sprite's own down", not "two units along world -Y". + // The projection runs in the caster's own frame, which reaches world through _ShadowModelMatrix -- + // built by ShadowCaster2D.CacheValues as TRS with only a +/-1 flip for scale, so an isometry. Its + // inverse therefore carries a world direction into that frame without changing its length, which is + // all SoftShadowWorldDirectionToLocal does. So (0, -2) means "two units along world -Y", whatever + // the sprite's rotation or flip, and the offset is still a world LENGTH. // - // This is what makes a rigid transform of an entire scene -- camera, lights and casters together -- - // leave the rendered shadow unchanged: the caster's frame rotates with the scene, so a constant - // typed into the port rotates with it too. Reading the port as WORLD instead cannot have that - // property, because a graph literal does not rotate while _ShadowModelInvMatrix does, and the - // shadow swings by the scene's own rotation. A graph that computes its displacement from world - // quantities -- Position (World), the Active Shadow2D Light node -- must therefore convert, - // either with a Transform (World -> Object) node or by working in this frame to begin with, which - // is what SoftShadowLightLocal / SoftShadowPointToLocal give a Custom Function node directly. + // World rather than the caster's frame because that is what an author means by a shadow offset: one + // constant throws every caster the same way, and a sun does not care how a sprite is rotated. Read + // in the caster's frame, the same literal pointed a different direction per caster, and nothing in + // the UI said which space the port was in or that a conversion was needed. See UUM-152815. // - // The flip travels with the frame: a flipped sprite mirrors its local axes, so its authored - // displacement mirrors too, which is the behaviour a flipped sprite's shadow wants. + // THE COST, and it is real. A rigid transform of an entire scene -- camera, lights and casters + // together -- no longer leaves the rendered shadow unchanged, because a graph literal does not + // rotate with the scene while the conversion above does. That invariance is now the graph's to keep + // rather than the port's to guarantee. A graph that wants it states its displacement in the caster's + // frame and converts back with a Transform (Object -> World) node, or works from SoftShadowLightLocal + // / SoftShadowPointToLocal and converts the result the same way. Both helpers still report the + // caster's frame and are unchanged. + // + // The flip no longer reaches the authored value. Undoing it here and reapplying it in + // _ShadowModelMatrix cancels exactly, so a flipped sprite throws its shadow the same way in world as + // an unflipped one -- which is what a world-space offset has to mean. That is a deliberate reversal: + // the caster-frame port mirrored the authored displacement with the sprite. float2 light; SoftShadowPrepare(payload, light); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Nodes/ShadowCaster2DLightNode.cs b/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Nodes/ShadowCaster2DLightNode.cs index 630c70ce4be..a4f640c5072 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Nodes/ShadowCaster2DLightNode.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/2D/ShaderGraph/Nodes/ShadowCaster2DLightNode.cs @@ -18,18 +18,23 @@ namespace UnityEditor.Rendering.Universal.ShaderGraph /// Three components on purpose, and world so that it pairs with Position (World) without the author /// having to know which space the projection runs in. /// - /// DO NOT build a fake-3D shadow length out of this. The obvious construction -- difference this - /// against Position (World), split off a world axis as "height", take the rest as planar distance, - /// similar triangles -- hard-codes the world axes as the game's frame, and is wrong the moment - /// anything is rotated out of them. Rotating an entire scene as a rigid body then changes the - /// shadows, which is not a visible change and should not produce one. Do that arithmetic against - /// the caster's own plane instead: SoftShadowLightLocal and SoftShadowPointToLocal - /// are declared pre-graph by ShadowCaster2DGlobals.hlsl, so a Custom Function node can call them - /// and reach the light and the point in a frame with no world axis named anywhere. + /// This feeds Shadow Displacement directly. That port is read in WORLD space and this node reports + /// the light in world space, so a displacement built from it and Position (World) needs no + /// conversion node. Before UUM-152815 the port was read in the caster's frame and a Transform + /// (World -> Object) was required; graphs written against that need the node removed. /// - /// Nor can this be fed to Shadow Displacement directly: that port is read in the CASTER'S frame, so - /// a world vector derived from this node needs a Transform (World -> Object) first. A projection - /// built on those two helpers stays in the caster's frame throughout and needs no conversion. + /// Know what a fake-3D shadow length built out of this costs. The obvious construction -- + /// difference this against Position (World), split off a world axis as "height", take the rest as + /// planar distance, similar triangles -- hard-codes the world axes as the game's frame, so rotating + /// an entire scene as a rigid body changes the shadows. Shadow Displacement is itself read in world + /// now, so that invariance is no longer something the port preserves either: this is a trade-off to + /// take knowingly, and it is the right one whenever the game's ground plane is the world's. + /// + /// To keep the invariance, do the arithmetic against the caster's own plane: SoftShadowLightLocal + /// and SoftShadowPointToLocal are declared pre-graph by ShadowCaster2DGlobals.hlsl, so a + /// Custom Function node can call them and reach the light and the point in a frame with no world + /// axis named anywhere -- then convert the result back with a Transform (Object -> World) before it + /// reaches the port. /// /// What it is still good for is anything that wants the light itself rather than a projection: the /// distance to it, a falloff, a flicker keyed to which light is drawing. diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalBlockFields.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalBlockFields.cs index a96f0b79dce..3a673a3fd6e 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalBlockFields.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/UniversalBlockFields.cs @@ -30,15 +30,18 @@ public struct VertexDescription // height math still works; it just has to resolve to a 2D offset inside the graph, which a // projection built on SoftShadowLightLocal / SoftShadowPointToLocal does. // - // Read in the CASTER'S OWN FRAME, not in world. That frame reaches world through an - // isometry, so this is a world-LENGTH offset along the sprite's local axes: (0, -2) means - // "two units along this sprite's own down". World would be the more obvious choice and it is - // the wrong one -- a graph literal does not rotate with the scene while the caster's inverse - // matrix does, so rotating an entire scene as a rigid body would swing every shadow by the - // scene's own rotation. See ShadowCaster2DPass.hlsl for the argument in full. A graph built - // from world quantities converts with a Transform (World -> Object) node, or sidesteps the - // question by working from SoftShadowLightLocal / SoftShadowPointToLocal, which report the - // light and the point in the caster's frame already. + // Read in WORLD space: (0, -2) means "two units along world -Y", whatever the sprite's + // rotation or flip. So a graph built from world quantities -- Position (World), the Active + // Shadow2D Light node -- feeds this port directly, with no conversion node in between. + // + // The pass converts into the caster's frame with SoftShadowWorldDirectionToLocal, which is + // length-preserving, so this is still a world-LENGTH offset. The cost is that rotating a + // whole scene as a rigid body now swings its shadows, because a graph literal does not + // rotate with the scene while that conversion does. A graph that wants the old, + // rotation-invariant behaviour states its displacement in the caster's frame -- from + // SoftShadowLightLocal / SoftShadowPointToLocal, which still report that frame -- and + // converts back with a Transform (Object -> World) node. See ShadowCaster2DPass.hlsl for + // the argument in full, and UUM-152815 for why the port moved. // // Default is a downward throw rather than anything radial: an unconnected port is a // CONSTANT, and "2 units along this point's own ray from the light" is not a constant. This diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Lights/Light2D.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Lights/Light2D.cs index f61a5bc741d..b9aa74b6122 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Lights/Light2D.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Lights/Light2D.cs @@ -242,6 +242,9 @@ private enum ComponentVersions Bounds m_LocalBounds; internal BoundingSphere boundingSphere { get; private set; } + // Unit normal of the light's mesh plane, cached here because ShadowCaster2D.IsLit projects onto it per light per caster. + internal Vector3 planeNormal { get; private set; } + internal Mesh lightMesh { get @@ -761,6 +764,9 @@ internal void UpdateMesh(bool forceUpdate = false) internal void UpdateBoundingSphere() { + // Unit length whatever the scale, because Transform.forward normalises. + planeNormal = transform.forward; + if (isPointLight) { boundingSphere = new BoundingSphere(transform.position, m_PointLightOuterRadius); 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 4ccb66f1e28..5e608b3cee6 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 @@ -1049,8 +1049,20 @@ private void OnBeforeRendering(RenderGraph renderGraph) culledLights[i].CacheValues(); } - ShadowCasterGroup2DManager.CacheValues(); + // Providers FIRST, then cache. CallOnBeforeRender is what finally reaches each shape + // provider's OnBeforeRender, and the SpriteRenderer and SpriteSkin providers set the + // caster's flip there from SpriteRenderer.flipX / flipY. ShadowCaster2D.CacheValues READS + // that flip and bakes it into m_CachedShadowMatrix, which is the matrix the shader gets. + // + // Caching first therefore drew every shadow with the PREVIOUS frame's flip: a flip toggled + // at runtime lagged the sprite by a frame, and on the first frame after a caster + // initialised the stored flip was still false, so the shadow was not flipped at all. + // + // Safe in this order because the dependency runs one way only. No provider reads the + // caster's cached state, and CallOnBeforeRender needs just the camera and the light cull + // result -- the lights' own CacheValues is the loop above and still precedes it. ShadowRendering.CallOnBeforeRender(cameraData.camera, renderingData.lightCullResult); + ShadowCasterGroup2DManager.CacheValues(); RendererLighting.lightBatch.Reset(); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs index 1b56e99c879..2e0fca2d5b9 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs @@ -296,6 +296,13 @@ internal bool IsLit(Light2D light) deltaPos.y = light.boundingSphere.position.y - boundingSphere.position.y; deltaPos.z = light.boundingSphere.position.z - boundingSphere.position.z; + // Separation in the light's own plane, since its influence is that mesh extruded along its normal rather than a sphere, and its frame rotates with the scene where a world axis would not. + Vector3 planeNormal = light.planeNormal; + float alongNormal = deltaPos.x * planeNormal.x + deltaPos.y * planeNormal.y + deltaPos.z * planeNormal.z; + deltaPos.x -= alongNormal * planeNormal.x; + deltaPos.y -= alongNormal * planeNormal.y; + deltaPos.z -= alongNormal * planeNormal.z; + float distanceSq = Vector3.SqrMagnitude(deltaPos); float radiiLength = light.boundingSphere.radius + boundingSphere.radius; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowRendering.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowRendering.cs index 56db1051d80..a0ffab72aef 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowRendering.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowRendering.cs @@ -587,7 +587,33 @@ private static void RenderProjectedShadows(UnsafeCommandBuffer cmdBuffer, int la continue; SetShadowProjectionGlobals(cmdBuffer, shadowCaster, light); - cmdBuffer.DrawMesh(shadowCaster.mesh, shadowCaster.transform.localToWorldMatrix, material, 0, pass); + + // unity_ObjectToWorld must be the SAME map the projection uses, flip included. + // + // The projection runs in the caster's frame and reaches world through + // _ShadowModelMatrix (T*R*flip) applied to a payload already scaled by + // _ShadowModelScale (lossy). transform.localToWorldMatrix is T*R*lossy -- the same + // thing WITHOUT the sprite flip. Passing that made a graph's Position (World) report, + // for every payload point, the position of that point's MIRROR IMAGE. + // + // A graph that throws each point radially away from the light -- the standard fake-3D + // projection -- then computes each vertex's displacement at the wrong point, so + // vertices swap throws with their mirrored partners and the projected geometry + // degenerates. A y-flipped centred sprite keeps its silhouette while its top and + // bottom throws exchange, which inverts the trapezoid into a converging wedge; an + // x-flip exchanges near and far and skews it. Unflipped, the two matrices are equal + // and nothing was ever wrong, which is why this only ever showed up under flip. + // + // Built from the cached values rather than the live transform so the draw cannot + // disagree with the globals set just above, which are cached. + // + // Only the PROJECTED draw needs this. The caster passes below apply the flip + // themselves in the shader, through UnityFlipSprite on positionOS, and so must keep + // the unflipped matrix or the flip would be applied twice. + Matrix4x4 projectedObjectToWorld = + shadowCaster.m_CachedShadowMatrix * Matrix4x4.Scale(shadowCaster.m_CachedLossyScale); + + cmdBuffer.DrawMesh(shadowCaster.mesh, projectedObjectToWorld, material, 0, pass); } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SoftShadowProjectVertex.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SoftShadowProjectVertex.hlsl index 5fed74a9322..35b85d35cdd 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SoftShadowProjectVertex.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/SoftShadowProjectVertex.hlsl @@ -688,6 +688,32 @@ float2 SoftShadowPointToLocal(float2 positionOS) #endif } +// A WORLD-space direction in the space the projection runs in. +// +// The counterpart to SoftShadowPointToLocal, for vectors rather than points -- so no translation, since +// a direction has none. _ShadowModelMatrix is an isometry (ShadowCaster2D.CacheValues builds it as TRS +// with only a +/-1 flip for scale), so its inverse rotates and mirrors a direction without changing its +// length. A world-length offset therefore stays a world-length offset, and stays one under non-uniform +// caster scale as well: the scale is already spent bringing the payload into this space, and a +// direction never picks it up. +// +// w = 0 rather than 1, which is the whole difference between transforming a direction and transforming +// a point: it drops the matrix's translation column, and SoftShadowLightLocal above passes 1 +// because the light IS a point. Taking .xy afterwards projects onto the caster's plane for a caster +// rotated out of it, the same truncation the rest of this file makes -- the projection is strictly 2D. +// +// Exposed because the ShadowCaster2D SubTarget's Shadow Displacement port is authored in world space +// and converted with exactly this, and a Custom Function node deriving its own displacement from world +// quantities needs the identical conversion rather than a second copy of it. +float2 SoftShadowWorldDirectionToLocal(float2 worldDirection) +{ +#if NOT_TRANSFORMABLE + return worldDirection; +#else + return mul(_ShadowModelInvMatrix, float4(worldDirection, 0.0f, 0.0f)).xy; +#endif +} + // Brings the payload and the light into one space. // // Exposed separately because a caller that evaluates the projection length per point must do so in the @@ -707,6 +733,32 @@ void SoftShadowPrepare(inout SoftShadowPayload a, out float2 light) a.next.xy *= _ShadowModelScale.xy; a.neighbor2.xy *= _ShadowModelScale.xy; a.neighbor2.zw *= _ShadowModelScale.xy; + + // A MIRRORING scale flips the ring's orientation, so the baked winding sign stops describing the + // geometry the projection actually runs on. + // + // next.z is that sign, and SoftShadowGeometryGenerator bakes it from the signed area of the + // caster's UNSCALED local outline ("winding = area < 0 ? -1 : 1"). Every outward normal in + // SoftShadowVert is wg * Perp(edge), so an uncorrected sign points them all inward and BOTH away + // tests invert. + // + // The visible symptom is oddly specific, which is worth knowing when this is diagnosed from a + // screenshot: the band collapses to nothing because it gates on edgeAway directly, while the fin + // survives untouched because it gates on isPole == (awayPrev != awayNext), and that XOR is + // invariant when both flip. So only the BACK softness disappears. The shadow keeps its silhouette + // and its side penumbra, which makes it look like a softness bug rather than a winding one. + // + // The DETERMINANT's sign is the test, not either axis alone: two negative axes are a 180 degree + // rotation, which preserves orientation and must not flip anything. + // + // Corrected here rather than in the generator because lossy scale is transform state that can + // change -- an animated or script-driven flip -- without the shadow mesh being rebuilt, so a value + // baked at generation time cannot stay right. This also sits outside the vertex program that + // SoftShadowVertexReference and sim_shader.py verify: they consume an already-prepared payload and + // have no scale concept, so this changes which payload is built, not what SoftShadowVert does + // with one, and no goldens move. + if (_ShadowModelScale.x * _ShadowModelScale.y < 0.0f) + a.next.z = -a.next.z; #endif } From 3425808350d563f6583b68eda96010c91e3a2900 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Sun, 27 Sep 2026 19:35:10 +0000 Subject: [PATCH 046/192] [Port] [6000.7] Fixed URP LOD UI duplication issue. --- .../UniversalRenderPipelineAssetUI.Drawers.cs | 14 -------------- 1 file changed, 14 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 aeb238e22d9..6fcb2fe71e4 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 @@ -437,20 +437,6 @@ static void DrawQuality(SerializedUniversalRenderPipelineAsset serialized, Edito { DrawXRProjectValidationInfoBox(Styles.xrUpscalingInfo, Styles.xrUpscalingInfoButton); } - - EditorGUILayout.PropertyField(serialized.enableLODCrossFadeProp, Styles.enableLODCrossFadeText); - EditorGUI.BeginDisabledGroup(!serialized.enableLODCrossFadeProp.boolValue); - EditorGUILayout.PropertyField(serialized.lodCrossFadeDitheringTypeProp, Styles.lodCrossFadeDitheringTypeText); - if (serialized.asset.enableLODCrossFade && serialized.asset.lodCrossFadeDitheringType == LODCrossFadeDitheringType.Stencil) - { - var rendererData = serialized.asset.m_RendererDataList[serialized.asset.m_DefaultRendererIndex]; - if (rendererData is UniversalRendererData && ((UniversalRendererData)rendererData).defaultStencilState.overrideStencilState) - { - EditorGUILayout.HelpBox(Styles.stencilLodCrossFadeWarningMessage.text, MessageType.Warning, true); - } - } - - EditorGUI.EndDisabledGroup(); } static void DrawUpscalerListAndOptions(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) From 89297a5bcd9e49b5bbda89c7f32650e6d587cef4 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 28 Sep 2026 09:16:07 +0000 Subject: [PATCH 047/192] [Port] [6000.7] Project Auditor / URP migration: dont report disabled items --- .../Editor/Tools/Converters/Converters.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/Converters.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/Converters.cs index 2f192edf86c..d63e09ff885 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/Converters.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/Converters.cs @@ -441,6 +441,9 @@ void OnConverterCompleteDataCollection(List items) foreach (var item in leafItems) { + if (!item.isEnabled) + continue; + converterResult.items.Add(new ScanResultItem { name = item.name, From 94293cc6d007306ddb6cfee91cd34fa4e4f60699 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 28 Sep 2026 09:16:08 +0000 Subject: [PATCH 048/192] [Port] [6000.7] [UUM-151894] Fix PS4 2D projected shadows, and re-enable the tests disabled to land PR #123379 --- .../Runtime/2D/Rendergraph/DrawLight2DPass.cs | 17 ++- .../LegacyShadowGeometryGenerator.cs | 2 +- .../Generation/SoftShadowGeometryGenerator.cs | 8 +- .../Shadow Provider Utility/ShadowUtility.cs | 27 +++-- .../Editor/ShadowCaster2DPreviewTests.cs | 1 - .../Editor/ShadowCaster2DSubTargetTests.cs | 1 - .../Tests/Runtime/Light2DTests.cs | 3 - .../Assets/Scenes/056_2D_Lights/Empty.mat | 59 ++++++++++ .../Scenes/056_2D_Lights/Empty.mat.meta | 8 ++ .../Scenes/056_2D_Lights/Empty.shadergraph | 3 + .../056_2D_Lights/Empty.shadergraph.meta | 20 ++++ .../Sprites/GrassThinSprite-White.png | 3 + .../Sprites/GrassThinSprite-White.png.meta | 103 ++++++++++++++++++ .../056_2D_Lights_Material_Override.unity | 3 + ...056_2D_Lights_Material_Override.unity.meta | 7 ++ ...ights_Shader_Graph_Material_Override.unity | 3 + ..._Shader_Graph_Material_Override.unity.meta | 7 ++ ...dows.unity => 056_2D_Lights_Shadows.unity} | 0 ....meta => 056_2D_Lights_Shadows.unity.meta} | 0 .../Assets/Scenes/056_2D_Lights_Simple.unity | 3 + .../Scenes/056_2D_Lights_Simple.unity.meta | 7 ++ .../056_2D_Lights_Simple_NoVolumetric.unity | 3 + ...6_2D_Lights_Simple_NoVolumetric.unity.meta | 7 ++ .../Test/Editor/Light2DMaterialFilterTests.cs | 1 - .../Test/Editor/Light2DTypeDropdownTests.cs | 1 - .../Test/Editor/Provider2DMultiSelectTests.cs | 1 - .../Editor/Provider2DSerializationTests.cs | 1 - .../Test/Editor/Shadow2DGeneratorTagTests.cs | 1 - .../Test/Editor/Shadow2DGeometryPathTests.cs | 23 ++-- .../Editor/ShadowProviderCallbackTests.cs | 1 - .../Editor/SoftShadowGeneratorTagTests.cs | 1 - .../Test/Editor/SoftShadowGeneratorTests.cs | 21 ++-- .../Test/Editor/SoftShadowGoldenTests.cs | 1 - .../Editor/SoftShadowInteriorFillTests.cs | 1 - .../Test/Editor/SoftShadowRenderMatchTests.cs | 1 - .../Test/Editor/SoftShadowShaderTests.cs | 1 - .../Editor/SoftShadowSpriteOutlineTests.cs | 1 - .../Editor/SoftShadowVertexFormatTests.cs | 1 - .../ProjectSettings/EditorBuildSettings.asset | 14 ++- 39 files changed, 313 insertions(+), 53 deletions(-) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity.meta rename Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/{056_2D_Lights-Shadows.unity => 056_2D_Lights_Shadows.unity} (100%) rename Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/{056_2D_Lights-Shadows.unity.meta => 056_2D_Lights_Shadows.unity.meta} (100%) create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity.meta create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity create mode 100644 Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity.meta 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 91c27a95294..ac8b2af3d38 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 @@ -134,11 +134,19 @@ private static void Execute(RasterCommandBuffer cmd, PassData passData, LayerBat if (breakBatch && LightBatch.isBatchingSupported) RendererLighting.lightBatch.Flush(cmd); + // s_PropertyBlock is shared and never cleared, so a stale texture stays bound. + // Render Graph can recycle that texture into this pass's own render target, and + // the ShaderGraph light shader samples _ShadowTex in every variant. Rebind both + // every draw so an unused slot holds black rather than a live colour target. if (passData.layerBatch.lightStats.useNormalMap) s_PropertyBlock.SetTexture(k_NormalMapID, passData.normalMap); + else + s_PropertyBlock.SetTexture(k_NormalMapID, passData.fallbackTexture); if (useShadows && TryGetShadowIndex(ref layerBatch, j, out var shadowIndex)) s_PropertyBlock.SetTexture(k_ShadowMapID, passData.shadowTextures[shadowIndex]); + else + s_PropertyBlock.SetTexture(k_ShadowMapID, passData.fallbackTexture); if (!passData.isVolumetric || (passData.isVolumetric && light.volumetricEnabled)) RendererLighting.SetCookieShaderProperties(light, s_PropertyBlock); @@ -191,13 +199,14 @@ internal class PassData internal TextureHandle normalMap; internal TextureHandle[] shadowTextures; + internal TextureHandle fallbackTexture; internal int lightTextureIndex; internal bool useRenderingLayers; internal RenderingLayerUtils.MaskSize maskSize; } - void InitializeRenderPass(IRasterRenderGraphBuilder builder, ContextContainer frameData, PassData passData, int batchIndex, bool isVolumetric = false) + void InitializeRenderPass(RenderGraph graph, IRasterRenderGraphBuilder builder, ContextContainer frameData, PassData passData, int batchIndex, bool isVolumetric = false) { Universal2DResourceData universal2DResourceData = frameData.Get(); CommonResourceData commonResourceData = frameData.Get(); @@ -234,6 +243,8 @@ void InitializeRenderPass(IRasterRenderGraphBuilder builder, ContextContainer fr passData.rendererData = rendererData; passData.isVolumetric = isVolumetric; passData.normalMap = layerBatch.lightStats.useNormalMap ? universal2DResourceData.normalsTexture[batchIndex] : TextureHandle.nullHandle; + passData.fallbackTexture = graph.defaultResources.blackTexture; + builder.UseTexture(passData.fallbackTexture); builder.AllowGlobalStateModification(true); } @@ -262,7 +273,7 @@ internal void Render(RenderGraph graph, ContextContainer frameData, int batchInd { using (var builder = graph.AddRasterRenderPass(passName, out var passData, LayerDebug.GetProfilingSampler(passName, ProfilerMarkers.s_ProfilingSampleSRT))) { - InitializeRenderPass(builder, frameData, passData, batchIndex, isVolumetric); + InitializeRenderPass(graph, builder, frameData, passData, batchIndex, isVolumetric); var lightTextures = universal2DResourceData.lightTextures[batchIndex]; @@ -288,7 +299,7 @@ internal void Render(RenderGraph graph, ContextContainer frameData, int batchInd // Default Raster Pass with MRTs using (var builder = graph.AddRasterRenderPass(passName, out var passData, LayerDebug.GetProfilingSampler(passName, profilingSampler))) { - InitializeRenderPass(builder, frameData, passData, batchIndex, isVolumetric); + InitializeRenderPass(graph, builder, frameData, passData, batchIndex, isVolumetric); var lightTextures = !isVolumetric ? universal2DResourceData.lightTextures[batchIndex] : intermediateTexture; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/LegacyShadowGeometryGenerator.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/LegacyShadowGeometryGenerator.cs index edd32900270..b8c119bda53 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/LegacyShadowGeometryGenerator.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/LegacyShadowGeometryGenerator.cs @@ -75,7 +75,7 @@ internal override void Build(ref ShadowShapeInput input, ref ShadowGeometryResul internal override void UploadMesh(ref Mesh mesh, in ShadowGeometryResult result) { - ShadowUtility.GenerateShadowMesh(ref mesh, result.vertices, result.indices, vertexLayout, result.localBounds); + ShadowUtility.GenerateShadowMesh(ref mesh, result.vertices, result.indices, vertexLayout); } // ------------------------------------------------------------------------------------ diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/SoftShadowGeometryGenerator.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/SoftShadowGeometryGenerator.cs index 5eea84b1dad..d7be720220d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/SoftShadowGeometryGenerator.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Generation/SoftShadowGeometryGenerator.cs @@ -650,11 +650,11 @@ internal override void UploadMesh(ref Mesh mesh, in ShadowGeometryResult result) mesh.SetIndexBufferParams(result.indices.Length, IndexFormat.UInt32); mesh.SetIndexBufferData(result.indices, 0, 0, result.indices.Length); - var subMesh = new SubMeshDescriptor(0, result.indices.Length); - subMesh.bounds = result.localBounds; - mesh.SetSubMesh(0, subMesh, MeshUpdateFlags.DontRecalculateBounds); + // Bounds are deliberately left unset -- see the UUM-151894 note in + // ShadowUtility.GenerateShadowMesh. Assigning them makes PS4 drop the draw, and + // nothing consumes them. + mesh.SetSubMesh(0, new SubMeshDescriptor(0, result.indices.Length)); mesh.subMeshCount = 1; - mesh.bounds = result.localBounds; } #if UNITY_EDITOR diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShadowUtility.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShadowUtility.cs index 15b3d5e8897..06d13a4ab19 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShadowUtility.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShadowUtility.cs @@ -459,7 +459,7 @@ static void GenerateInteriorMesh(ref NativeArray inVertices, r // NON-BURST WRAPPER - Mesh operations are not Burst compatible // vertexLayout comes from the calling ShadowGeometryGenerator rather than a static here, // so a generator cannot declare one vertex format and upload another. - static public void GenerateShadowMesh(ref Mesh mesh, NativeArray inVertices, NativeArray inIndices, VertexAttributeDescriptor[] vertexLayout, Bounds localBounds) + static public void GenerateShadowMesh(ref Mesh mesh, NativeArray inVertices, NativeArray inIndices, VertexAttributeDescriptor[] vertexLayout) { if (mesh == null) mesh = new Mesh(); @@ -471,13 +471,26 @@ static public void GenerateShadowMesh(ref Mesh mesh, NativeArray(inVertices, 0, 0, inVertices.Length); mesh.SetIndexBufferParams(inIndices.Length, IndexFormat.UInt32); mesh.SetIndexBufferData(inIndices, 0, 0, inIndices.Length); - // Bounds are assigned rather than recalculated: the caller already has them, and - // RecalculateBounds would walk the whole vertex buffer on every upload. - SubMeshDescriptor subMesh = new SubMeshDescriptor(0, inIndices.Length); - subMesh.bounds = localBounds; - mesh.SetSubMesh(0, subMesh, MeshUpdateFlags.DontRecalculateBounds); + // Bounds are deliberately left unset on this mesh. + // + // UUM-151894: assigning them makes PS4 drop every draw of this mesh, whatever + // value is assigned. A correct AABB of the uploaded vertices fails (Yamato + // 75212051), a deliberately huge box fails (75212047), the outline AABB fails + // (75212045), and only leaving them unset passes (75212050, 75267226). Device + // instrumentation measured zero containment violations, so the numbers were never + // wrong. The mechanism is unexplained and sits in native draw submission. + // + // Nothing consumes these bounds. No managed code reads Mesh.bounds for this mesh, + // and CommandBuffer.DrawMesh is not frustum-culled against them -- URP's own 2D + // shadow culling uses the caster bounding sphere built from + // ShadowMesh2D.m_LocalBounds, which is unaffected by this. Leaving them unset is + // measurably rendering-neutral: zero deltaE on both PS4 and StandaloneWindows64 + // (75267226, 75278638). + // + // Do not reintroduce an assignment here. It buys nothing -- computing a correct + // bounds still walks the whole vertex buffer -- and it reintroduces UUM-151894. + mesh.SetSubMesh(0, new SubMeshDescriptor(0, inIndices.Length)); mesh.subMeshCount = 1; - mesh.bounds = localBounds; } else { diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DPreviewTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DPreviewTests.cs index 779afd63f98..bc103c52402 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DPreviewTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DPreviewTests.cs @@ -25,7 +25,6 @@ namespace UnityEditor.Rendering.Universal.Tests /// concluded the opposite and inferred that preview render state and passes could be ignored. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class ShadowCaster2DPreviewTests { // Built exactly as NewGraphAction does, so this is the graph the Create menu produces. diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DSubTargetTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DSubTargetTests.cs index 9f073878351..564d51c3b06 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DSubTargetTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShadowCaster2DSubTargetTests.cs @@ -30,7 +30,6 @@ namespace UnityEditor.Rendering.Universal.Tests /// .shadergraph asset. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class ShadowCaster2DSubTargetTests { static SubShaderDescriptor GetSubShader() diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/Light2DTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/Light2DTests.cs index 1558a118786..3407df8fa12 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/Light2DTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/Light2DTests.cs @@ -166,7 +166,6 @@ public void EnsureShapeMeshGenerationDoesNotOverflowAllocation() // Verifies UVs are computed from the vertex XY extents and normalized into [0,1] // for Freeform lights. The mesh XY bounds should touch UV (0,0) and (1,1). - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] [Test] public void FreeformMeshHasPositionDerivedUVs() { @@ -217,7 +216,6 @@ public void FreeformMeshHasPositionDerivedUVs() // direction in color.rg and are pushed outward by falloffDistance * color.rg in // the vert shader, so the CPU-side UV normalization must use those same extended // positions to keep UV [0,1] spanning the visible falloff band. - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] [Test] public void ParametricMeshHasPositionDerivedUVs() { @@ -273,7 +271,6 @@ public void ParametricMeshHasPositionDerivedUVs() // Sprite light meshes must retain the sprite's own UVs; the new // position-derived UV logic must not affect them. - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] [Test] public void SpriteMeshWithNullSpriteClearsMesh() { diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat new file mode 100644 index 00000000000..9a47a01ef77 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat @@ -0,0 +1,59 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8069092641640906684 +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: Empty + m_Shader: {fileID: -6465566751694194690, guid: 0d483cc1dbf854c41a36221be84ef5f8, 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: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - 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: + - _DstBlend: 0 + - _SrcBlend: 1 + - _VolDstBlend: 1 + - _VolSrcBlend: 5 + m_Colors: [] + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat.meta new file mode 100644 index 00000000000..3259ec36b12 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 91b425c35f966c44296de14970f7ba3f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph new file mode 100644 index 00000000000..4535cfc5eb6 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aea923ff65dfe160ccdd5b016af716365f2a4c3df89dcb1f0672d9b814fbbdb2 +size 8842 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph.meta new file mode 100644 index 00000000000..f1f99d5e0a4 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Empty.shadergraph.meta @@ -0,0 +1,20 @@ +fileFormatVersion: 2 +guid: 0d483cc1dbf854c41a36221be84ef5f8 +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_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png new file mode 100644 index 00000000000..1feb62bb3b1 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89d3db3b29389ef7a27cf35fa7b7f42ca30fa815f20f8471caedb9c593ed87dc +size 4971 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png.meta new file mode 100644 index 00000000000..70f0552f64d --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights/Sprites/GrassThinSprite-White.png.meta @@ -0,0 +1,103 @@ +fileFormatVersion: 2 +guid: 6965632c11d5b0c4baa4c4e8b839beb7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 9 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 1024 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 50 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 0 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 1024 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity new file mode 100644 index 00000000000..478081b48e2 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4354f5506bf1efd069a25c8400375fd2eefa3ace50858f5db1d792f83130733f +size 47611 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity.meta new file mode 100644 index 00000000000..a208fbd357e --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Material_Override.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 72a131eb80d04134aaee267020f5672d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity new file mode 100644 index 00000000000..e14f80973fa --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b730552c928b507aa74d0a966a8883fe291d367e29c459a789ad41b19f7e66e4 +size 55392 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity.meta new file mode 100644 index 00000000000..b0dd80588a5 --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 805a46958fade0b4a8e91dcd9c586fe4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights-Shadows.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shadows.unity similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights-Shadows.unity rename to Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shadows.unity diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights-Shadows.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shadows.unity.meta similarity index 100% rename from Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights-Shadows.unity.meta rename to Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Shadows.unity.meta diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity new file mode 100644 index 00000000000..4cdd5e31e0c --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d57b36ec9615bfb09e4328c535359ecc64b650b67e6d0c4d4574b40d74cf94aa +size 13820 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity.meta new file mode 100644 index 00000000000..805f4f2b05d --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 37b237f218ffbca44b34db6596537473 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity new file mode 100644 index 00000000000..5f9997b9fba --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1210edce824166a59695aef03379f295b540289880a265edd805a9b17021ec0 +size 13875 diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity.meta b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity.meta new file mode 100644 index 00000000000..8cdf27f284f --- /dev/null +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 41625d32980ba9c4a9986fdd1ddd28a5 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DMaterialFilterTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DMaterialFilterTests.cs index ff3da92f974..a1ce06958f4 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DMaterialFilterTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DMaterialFilterTests.cs @@ -5,7 +5,6 @@ // The Light2D material field offers only Materials whose shader declares the passes the renderer // draws, the same way the shadow material field does. -[Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class Light2DMaterialFilterTests { // Declares both Light2D passes. diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DTypeDropdownTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DTypeDropdownTests.cs index 3da5deaaa59..ac764511081 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DTypeDropdownTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Light2DTypeDropdownTests.cs @@ -4,7 +4,6 @@ using UnityEngine; using UnityEngine.Rendering.Universal; -[Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class Light2DTypeDropdownTests : Provider2DTestBase { // A light whose stored selection names nothing available -- a provider whose script was deleted, diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DMultiSelectTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DMultiSelectTests.cs index 27c92b370ef..34a99db7a62 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DMultiSelectTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DMultiSelectTests.cs @@ -5,7 +5,6 @@ using UnityEngine; using UnityEngine.Rendering.Universal; -[Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class Provider2DMultiSelectTests : Provider2DTestBase { static readonly Shadow2DProviderSources_PropertyDrawer s_ShadowDrawer = new Shadow2DProviderSources_PropertyDrawer(); diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DSerializationTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DSerializationTests.cs index eea295abe52..ce6fd171133 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DSerializationTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Provider2DSerializationTests.cs @@ -3,7 +3,6 @@ using UnityEngine; using UnityEngine.Rendering.Universal; -[Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class Provider2DSerializationTests : Provider2DTestBase { // Opening the inspector must not make a light reference every provider type in the project: that diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeneratorTagTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeneratorTagTests.cs index 97a8dd640f9..15c058a9573 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeneratorTagTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeneratorTagTests.cs @@ -15,7 +15,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// Shadow2DGeometrySettings.geometryVersion, so the tag no longer selects anything at runtime; what /// is left to protect is that Hidden/Shadow2D's authored tag and the C# copy of it agree. /// - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class Shadow2DGeneratorTagTests { readonly List m_Created = new List(); diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeometryPathTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeometryPathTests.cs index f91fd5e7fdb..7d45399a020 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeometryPathTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/Shadow2DGeometryPathTests.cs @@ -19,7 +19,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// 14-float layout verified to 1e-12 against the Python model, where a shared-layout bug fails /// loudly rather than by byte comparison. /// - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class Shadow2DGeometryPathTests { NativeArray m_Vertices; @@ -183,17 +182,23 @@ public void GeneratorIdImpliesAFixedVertexLayout() } [Test] - public void MeshBoundsMatchTheGeneratedGeometry() + public void MeshBoundsAreLeftUnsetSoThatPS4StillDraws() { - // GenerateShadowMesh writes the vertex buffer directly, so bounds have to be assigned - // explicitly; they used to stay at zero, which reads as "no geometry" to anything that - // culls or frames by bounds. + // Inverted from what this test originally asserted, on purpose. + // + // UUM-151894: assigning bounds on this mesh makes PS4 drop every draw of it, whatever + // value is assigned -- the exact vertex AABB, the outline AABB and a deliberately huge + // box all fail, and only leaving them unset renders. Nothing consumes these bounds: + // no managed code reads Mesh.bounds for this mesh, and CommandBuffer.DrawMesh is not + // frustum-culled against them. URP's 2D shadow culling uses the caster bounding sphere + // built from ShadowMesh2D.m_LocalBounds, which is a separate value and unaffected. + // + // This test exists to stop the assignment being reintroduced as an "obvious" fix. var shadowMesh = BuildWith(LegacyShadowGeometryGenerator.k_Id); - Bounds bounds = shadowMesh.mesh.bounds; - Assert.AreNotEqual(Vector3.zero, bounds.size, "Mesh bounds were never assigned."); - Assert.That(bounds.extents.x, Is.GreaterThan(0.5f).And.LessThanOrEqualTo(1.5f), "Bounds do not enclose the unit square outline."); - Assert.That(bounds.extents.y, Is.GreaterThan(0.5f).And.LessThanOrEqualTo(1.5f), "Bounds do not enclose the unit square outline."); + Assert.Greater(shadowMesh.mesh.vertexCount, 0, "Sanity: the shape must produce geometry."); + Assert.AreEqual(Vector3.zero, shadowMesh.mesh.bounds.size, + "Shadow mesh bounds must stay unset -- assigning them reintroduces UUM-151894 on PS4."); } [Test] diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/ShadowProviderCallbackTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/ShadowProviderCallbackTests.cs index 783a75bf538..7c7ffa39e02 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/ShadowProviderCallbackTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/ShadowProviderCallbackTests.cs @@ -51,7 +51,6 @@ public override void OnBeforeRender(Camera camera, Component sourceComponent, Bo } } -[Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class ShadowProviderCallbackTests : Provider2DTestBase { Component NewSourceComponent() diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTagTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTagTests.cs index 7684857dda3..0f4c7f943c0 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTagTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTagTests.cs @@ -19,7 +19,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// anything at runtime -- what it still has to do is describe each shader honestly. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowGeneratorTagTests { const string k_FixtureDir = "Assets/Scenes/140_Shadow_Materials"; diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTests.cs index 0cdf1661445..d62344d4eca 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGeneratorTests.cs @@ -26,7 +26,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// SRP_SmokeTest, which does not have the 2D packages. Those tests live in /// UniversalGraphicsTest_2D's Assets/Test/Editor/SoftShadowInteriorFillTests.cs instead. /// - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowGeneratorTests { const int k_FixedRolesPerVertex = 7; @@ -228,18 +227,20 @@ public void WindingSignIsCarriedPerVertexAndIsUnit() } [Test] - public void BoundsAreTheOutlineBoundsRatherThanTheProjectedExtent() + public void BoundsAreLeftUnsetSoThatPS4StillDraws() { - // The mesh is light-independent, so a projected extent is not even computable here. The - // outline AABB is exact rather than approximate, because POSITION is always the - // caster-space vertex. + // This previously asserted that the bounds were the outline AABB. That assignment is + // gone: UUM-151894 showed PS4 drops every draw of this mesh when the bounds are + // assigned, whatever the value, and nothing consumes them. See the note in + // ShadowUtility.GenerateShadowMesh. + // + // The outline extent is still available where it is actually used -- + // ShadowMesh2D.m_LocalBounds feeds the caster bounding sphere that URP culls on. ShadowMesh2D shadowMesh = BuildLines(3); - Bounds b = shadowMesh.mesh.bounds; - Assert.AreEqual(-1.0f, b.min.x, 1e-5f); - Assert.AreEqual(-1.0f, b.min.y, 1e-5f); - Assert.AreEqual(1.0f, b.max.x, 1e-5f); - Assert.AreEqual(1.0f, b.max.y, 1e-5f); + Assert.Greater(shadowMesh.mesh.vertexCount, 0, "Sanity: the shape must produce geometry."); + Assert.AreEqual(Vector3.zero, shadowMesh.mesh.bounds.size, + "Shadow mesh bounds must stay unset -- assigning them reintroduces UUM-151894 on PS4."); } // ------------------------------------------------------------------------------------ diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGoldenTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGoldenTests.cs index ff81eb50ec8..277e88e5839 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGoldenTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowGoldenTests.cs @@ -26,7 +26,6 @@ namespace UnityEngine.Rendering.Universal.Tests // META line pins the parameters, so a change to them fails loudly rather than silently comparing // against the wrong configuration. [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowGoldenTests { const string k_GoldenFile = "Test/Editor/softshadow_goldens.txt"; diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowInteriorFillTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowInteriorFillTests.cs index 92949c51cf1..f0919a5d700 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowInteriorFillTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowInteriorFillTests.cs @@ -27,7 +27,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// caster has no Renderer, which is exactly when those passes draw this mesh. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowInteriorFillTests { const int k_Segments = 3; diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowRenderMatchTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowRenderMatchTests.cs index 8700805e6df..4a29ec99b3f 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowRenderMatchTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowRenderMatchTests.cs @@ -31,7 +31,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// region, which either statistic catches easily; what they tolerate is a one-pixel seam. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowRenderMatchTests { const string k_MaterialPath = diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowShaderTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowShaderTests.cs index 43702e02d89..5d73d413b50 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowShaderTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowShaderTests.cs @@ -14,7 +14,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// include, and without a test like this the first sign of trouble is an unhelpfully pink shadow. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowShaderTests { const string k_ShaderName = "Test/Shadow2D-SoftShadow"; diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowSpriteOutlineTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowSpriteOutlineTests.cs index c4e4b81a4d9..b76070f1eca 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowSpriteOutlineTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowSpriteOutlineTests.cs @@ -31,7 +31,6 @@ namespace UnityEngine.Rendering.Universal.Tests /// sprites cannot drift from what the model was verified against. /// [TestFixture] - [Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowSpriteOutlineTests { const string k_ShapeDir = "Assets/Scenes/140_Shadow_Materials/Shapes"; diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowVertexFormatTests.cs b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowVertexFormatTests.cs index a4d8b3a506a..4c7c0288f39 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowVertexFormatTests.cs +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Assets/Test/Editor/SoftShadowVertexFormatTests.cs @@ -25,7 +25,6 @@ // These tests deliberately declare their own copy of the struct and layout rather than referencing // the generator, so they are meaningful before it exists and keep working if it moves. [TestFixture] -[Ignore("TEMP-DISABLED-PR-123379: disabled to land PR #123379; re-enable per docs/pr/123379-disabled-tests.md")] class SoftShadowVertexFormatTests { // The payload, mirroring SoftShadowGeometryGenerator.SoftShadowMeshVertex: diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/ProjectSettings/EditorBuildSettings.asset b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/ProjectSettings/EditorBuildSettings.asset index 33a177c5123..d7c7c95ba92 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/ProjectSettings/EditorBuildSettings.asset +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/ProjectSettings/EditorBuildSettings.asset @@ -198,14 +198,26 @@ EditorBuildSettings: path: Assets/Scenes/022_Normals_FlipXY.unity guid: 0fd9ba64f5114634b81f084fb92123e1 - enabled: 1 - path: Assets/Scenes/056_2D_Lights-Shadows.unity + path: Assets/Scenes/056_2D_Lights_Shadows.unity guid: 4f7a50da47cfeca46b45fe14be17081d - enabled: 1 path: Assets/Scenes/056_2D_Lights.unity guid: c0c276a91b93d254b957277941d2329b + - enabled: 1 + path: Assets/Scenes/056_2D_Lights_Material_Override.unity + guid: 72a131eb80d04134aaee267020f5672d - enabled: 1 path: Assets/Scenes/056_2D_Lights_Shader_Graph.unity guid: 381306730e4f1b141bf8e0e1c35f16e9 + - enabled: 1 + path: Assets/Scenes/056_2D_Lights_Shader_Graph_Material_Override.unity + guid: 805a46958fade0b4a8e91dcd9c586fe4 + - enabled: 1 + path: Assets/Scenes/056_2D_Lights_Simple.unity + guid: 37b237f218ffbca44b34db6596537473 + - enabled: 1 + path: Assets/Scenes/056_2D_Lights_Simple_NoVolumetric.unity + guid: 41625d32980ba9c4a9986fdd1ddd28a5 - enabled: 1 path: Assets/Scenes/057_2D_Lights_Blending.unity guid: f6eb3eed1eb0a004797f00a2a4435f32 From b8f9359f6b8f58d64e02fefeed9eeecfc727d4c9 Mon Sep 17 00:00:00 2001 From: Petros Bantolas Date: Mon, 28 Sep 2026 17:58:07 +0000 Subject: [PATCH 049/192] [Port] [6000.7] [Umbra] Deprecate Umbra static occlusion culling --- .../Editor/Camera/CameraUI.Rendering.Drawers.cs | 2 ++ .../Editor/Lighting/Reflection/CameraSettingsUI.Drawers.cs | 4 ++++ .../Editor/Tools/LookDev/Stage.cs | 2 ++ .../Runtime/Utilities/CameraSettings.cs | 6 ++++++ .../Runtime/Utilities/CameraSettingsUtilities.cs | 2 ++ .../Tests/Editor/CameraSettingsUtilitiesTests.cs | 4 ++++ .../Editor/HDAdditionalReflectionData.MigrationTests.cs | 4 ++++ .../Tests/Editor/PlanarReflectionProbe.MigrationTests.cs | 2 ++ .../UniversalRenderPipelineCameraUI.Rendering.Drawers.cs | 2 ++ .../Editor/Drawing/MaterialGraphPreviewGenerator.cs | 2 ++ .../Editor/Drawing/Views/PreviewSceneResources.cs | 2 ++ 11 files changed, 32 insertions(+) diff --git a/Packages/com.unity.render-pipelines.core/Editor/Camera/CameraUI.Rendering.Drawers.cs b/Packages/com.unity.render-pipelines.core/Editor/Camera/CameraUI.Rendering.Drawers.cs index 535b42bb721..354bb635a27 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Camera/CameraUI.Rendering.Drawers.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Camera/CameraUI.Rendering.Drawers.cs @@ -33,7 +33,9 @@ public static void Drawer_Rendering_CullingMask(ISerializedCamera p, Editor owne /// The editor owner calling this drawer public static void Drawer_Rendering_OcclusionCulling(ISerializedCamera p, Editor owner) { + #pragma warning disable CS0618 EditorGUILayout.PropertyField(p.baseCameraSettings.occlusionCulling, Styles.occlusionCulling); + #pragma warning restore CS0618 } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/CameraSettingsUI.Drawers.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/CameraSettingsUI.Drawers.cs index cc788913fc8..05cbb193944 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/CameraSettingsUI.Drawers.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/CameraSettingsUI.Drawers.cs @@ -43,9 +43,11 @@ CameraSettingsOverride displayedFields | CameraSettingsFields.bufferClearColorMode; const CameraSettingsFields volumesFields = CameraSettingsFields.volumesAnchorOverride | CameraSettingsFields.volumesLayerMask; + #pragma warning disable CS0618 const CameraSettingsFields cullingFields = CameraSettingsFields.cullingCullingMask | CameraSettingsFields.cullingInvertFaceCulling | CameraSettingsFields.cullingUseOcclusionCulling; + #pragma warning restore CS0618 const CameraSettingsFields frustumFields = CameraSettingsFields.frustumAspect | CameraSettingsFields.frustumFarClipPlane | CameraSettingsFields.frustumMode @@ -71,7 +73,9 @@ CameraSettingsOverride displayedFields if ((displayedFields.camera & cullingFields) != 0) { + #pragma warning disable CS0618 PropertyFieldWithoutToggle(CameraSettingsFields.cullingUseOcclusionCulling, serialized.cullingUseOcclusionCulling, Styles.cullingUseOcclusionCulling, displayedFields.camera); + #pragma warning restore CS0618 PropertyFieldWithoutToggle(CameraSettingsFields.cullingCullingMask, serialized.cullingCullingMask, Styles.cullingCullingMask, displayedFields.camera); PropertyFieldWithoutToggle(CameraSettingsFields.cullingInvertFaceCulling, serialized.cullingInvertFaceCulling, Styles.cullingInvertFaceCulling, displayedFields.camera); EditorGUILayout.Space(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Tools/LookDev/Stage.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Tools/LookDev/Stage.cs index 3cbdfa66222..42ac3329738 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Tools/LookDev/Stage.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Tools/LookDev/Stage.cs @@ -65,7 +65,9 @@ public Stage(string sceneName) m_Camera.clearFlags = CameraClearFlags.Depth; m_Camera.cullingMask = 1 << k_PreviewCullingLayerIndex; m_Camera.renderingPath = RenderingPath.DeferredShading; + #pragma warning disable CS0618 m_Camera.useOcclusionCulling = false; + #pragma warning restore CS0618 m_Camera.scene = m_PreviewScene; var lightGO = EditorUtility.CreateGameObjectWithHideFlags("Look Dev Sun", HideFlags.HideAndDontSave, typeof(Light)); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs index c08a0a8c200..b610a2a8271 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs @@ -34,6 +34,7 @@ public enum CameraSettingsFields /// frustum.projectionMatrix frustumProjectionMatrix = 1 << 11, /// culling.useOcclusionCulling + [Obsolete("CameraSettingsFields.cullingUseOcclusionCulling is deprecated and will be removed in a future release. Consider migrating to GPU Occlusion Culling where your target platform supports it. #from(6000.7)", false)] cullingUseOcclusionCulling = 1 << 12, /// culling.cullingMask cullingCullingMask = 1 << 13, @@ -279,14 +280,17 @@ public struct Culling public static readonly Culling @default = default; /// Default value. /// The default value. + #pragma warning disable CS0618 public static Culling NewDefault() => new Culling { cullingMask = -1, useOcclusionCulling = true, sceneCullingMaskOverride = 0 }; + #pragma warning restore CS0618 /// True when occlusion culling will be performed during rendering, false otherwise. + [Obsolete("CameraSettings.Culling.useOcclusionCulling is deprecated and will be removed in a future release. Consider migrating to GPU Occlusion Culling where your target platform supports it. #from(6000.7)", false)] public bool useOcclusionCulling; /// The mask for visible objects. public LayerMask cullingMask; @@ -325,7 +329,9 @@ public static CameraSettings From(HDCamera hdCamera) { var settings = defaultCameraSettingsNonAlloc; settings.culling.cullingMask = hdCamera.camera.cullingMask; + #pragma warning disable CS0618 settings.culling.useOcclusionCulling = hdCamera.camera.useOcclusionCulling; + #pragma warning restore CS0618 settings.culling.sceneCullingMaskOverride = HDUtils.GetSceneCullingMaskFromCamera(hdCamera.camera); settings.frustum.aspect = hdCamera.camera.aspect; settings.frustum.farClipPlaneRaw = hdCamera.camera.farClipPlane; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettingsUtilities.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettingsUtilities.cs index 9b01e26e69b..65fcefbfff9 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettingsUtilities.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettingsUtilities.cs @@ -24,7 +24,9 @@ public static void ApplySettings(this Camera cam, CameraSettings settings) cam.aspect = settings.frustum.aspect; cam.projectionMatrix = settings.frustum.GetUsedProjectionMatrix(); // Culling + #pragma warning disable CS0618 cam.useOcclusionCulling = settings.culling.useOcclusionCulling; + #pragma warning restore CS0618 cam.cullingMask = settings.culling.cullingMask; cam.overrideSceneCullingMask = settings.culling.sceneCullingMaskOverride; // Buffer clearing diff --git a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/CameraSettingsUtilitiesTests.cs b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/CameraSettingsUtilitiesTests.cs index 8d128b92ad4..29c921b9d23 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/CameraSettingsUtilitiesTests.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/CameraSettingsUtilitiesTests.cs @@ -35,7 +35,9 @@ public void ApplySettings() culling = new CameraSettings.Culling { cullingMask = RandomUtilities.RandomInt(i), + #pragma warning disable CS0618 useOcclusionCulling = RandomUtilities.RandomBool(i + 0.5f), + #pragma warning restore CS0618 }, renderingPathCustomFrameSettings = default, renderingPathCustomFrameSettingsOverrideMask = default, @@ -103,7 +105,9 @@ public void ApplySettings() break; } // Culling + #pragma warning disable CS0618 Assert.AreEqual(settings.culling.useOcclusionCulling, cam.useOcclusionCulling); + #pragma warning restore CS0618 Assert.AreEqual(settings.culling.cullingMask, (LayerMask)cam.cullingMask); // Buffer clearing Assert.AreEqual(settings.bufferClearing.clearColorMode, add.clearColorMode); diff --git a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAdditionalReflectionData.MigrationTests.cs b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAdditionalReflectionData.MigrationTests.cs index 8f9760f178e..ec7ba3da1ac 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAdditionalReflectionData.MigrationTests.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAdditionalReflectionData.MigrationTests.cs @@ -125,7 +125,9 @@ out GameObject prefab Assert.AreEqual(legacyProbeData.backgroundColorHDR, settings.cameraSettings.bufferClearing.backgroundColorHDR); Assert.AreEqual(legacyProbeData.clearDepth, settings.cameraSettings.bufferClearing.clearDepth); Assert.AreEqual(legacyProbeData.cullingMask, (int)settings.cameraSettings.culling.cullingMask); + #pragma warning disable CS0618 Assert.AreEqual(legacyProbeData.useOcclusionCulling, settings.cameraSettings.culling.useOcclusionCulling); + #pragma warning restore CS0618 Assert.AreEqual(legacyProbeData.volumeLayerMask, (int)settings.cameraSettings.volumes.layerMask); Assert.AreEqual(legacyProbeData.nearClipPlane, settings.cameraSettings.frustum.nearClipPlane); Assert.AreEqual(legacyProbeData.farClipPlane, settings.cameraSettings.frustum.farClipPlane); @@ -476,7 +478,9 @@ out GameObject prefab Assert.AreEqual(legacyProbeData.intensity, settings.lighting.multiplier); Assert.AreEqual(legacyProbeData.boxSize, settings.influence.boxSize); Assert.AreEqual(legacyProbeData.boxProjection, settings.proxySettings.useInfluenceVolumeAsProxyVolume); + #pragma warning disable CS0618 Assert.AreEqual(legacyProbeData.useOcclusionCulling, settings.cameraSettings.culling.useOcclusionCulling); + #pragma warning restore CS0618 Assert.AreEqual(legacyProbeData.nearClipPlane, settings.cameraSettings.frustum.nearClipPlane); Assert.AreEqual(legacyProbeData.farClipPlane, settings.cameraSettings.frustum.farClipPlane); Assert.AreEqual(ProbeSettings.ProbeType.ReflectionProbe, settings.type); diff --git a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/PlanarReflectionProbe.MigrationTests.cs b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/PlanarReflectionProbe.MigrationTests.cs index 24a6a577372..e8d91c34c52 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/PlanarReflectionProbe.MigrationTests.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/PlanarReflectionProbe.MigrationTests.cs @@ -133,7 +133,9 @@ out GameObject prefab Assert.AreEqual(legacyProbeData.backgroundColorHDR, settings.cameraSettings.bufferClearing.backgroundColorHDR); Assert.AreEqual(legacyProbeData.clearDepth, settings.cameraSettings.bufferClearing.clearDepth); Assert.AreEqual(legacyProbeData.cullingMask, (int)settings.cameraSettings.culling.cullingMask); + #pragma warning disable CS0618 Assert.AreEqual(legacyProbeData.useOcclusionCulling, settings.cameraSettings.culling.useOcclusionCulling); + #pragma warning restore CS0618 Assert.AreEqual(legacyProbeData.volumeLayerMask, (int)settings.cameraSettings.volumes.layerMask); Assert.AreEqual(legacyProbeData.nearClipPlane, settings.cameraSettings.frustum.nearClipPlane); Assert.AreEqual(legacyProbeData.farClipPlane, settings.cameraSettings.frustum.farClipPlane); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs index 2740c3c6471..8342a98a085 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Camera/UniversalRenderPipelineCameraUI.Rendering.Drawers.cs @@ -319,7 +319,9 @@ static void DrawerRenderingOpaqueTexture(UniversalRenderPipelineSerializedCamera static void OcclusionCullingWithWarningTileOnlyMode(UniversalRenderPipelineSerializedCamera serialized, Editor owner) { + #pragma warning disable CS0618 DisplayTileOnlyModeWarning(serialized.baseCameraSettings.occlusionCulling, p => p.boolValue, CameraUI.Rendering.Styles.occlusionCulling, serialized); + #pragma warning restore CS0618 } } } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphPreviewGenerator.cs b/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphPreviewGenerator.cs index 9bb3be62f49..5f572be02a1 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphPreviewGenerator.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphPreviewGenerator.cs @@ -52,7 +52,9 @@ public MaterialGraphPreviewGenerator() // (deferred fails when generating some static previews at editor launch; and we never want // vertex lit previews if that is chosen in the player settings) m_Camera.renderingPath = RenderingPath.Forward; + #pragma warning disable CS0618 m_Camera.useOcclusionCulling = false; + #pragma warning restore CS0618 m_Camera.scene = m_Scene; var l0 = CreateLight(); diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/PreviewSceneResources.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/PreviewSceneResources.cs index 59bb991eef9..83dc216d6b5 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/PreviewSceneResources.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/PreviewSceneResources.cs @@ -52,7 +52,9 @@ public PreviewSceneResources() // (deferred fails when generating some static previews at editor launch; and we never want // vertex lit previews if that is chosen in the player settings) camera.renderingPath = RenderingPath.Forward; + #pragma warning disable CS0618 camera.useOcclusionCulling = false; + #pragma warning restore CS0618 camera.scene = m_Scene; var l0 = CreateLight(); From 2d4744131d2c6c44dc9011a30054da9969842516 Mon Sep 17 00:00:00 2001 From: Reach Platform Support Date: Mon, 28 Sep 2026 17:58:10 +0000 Subject: [PATCH 050/192] [Port] [6000.7] Render Pipeline Converter - Keep converter state on assembly reloads --- .../Tools/Converter/ConverterItemState.cs | 142 +++++++-- .../Tools/Converter/ConverterState.cs | 86 +++++ .../RenderPipelineConverterAssetItem.cs | 17 +- .../RenderPipelineConverterManager.cs | 16 +- ...RenderPipelineConverterMaterialUpgrader.cs | 28 +- .../RenderPipelineConverterUtility.cs | 97 +++++- .../Converter/RenderSettingsConverter.cs | 112 +++---- .../RenderPipelineConverterVisualElement.cs | 295 ++++++++++++++---- ...ipelineConverterVisualElementListFilter.cs | 15 + .../Window/RenderPipelineConvertersEditor.cs | 121 ++++--- .../Tools/Converter/ConverterStateTests.cs | 160 +++++++++- 11 files changed, 857 insertions(+), 232 deletions(-) diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterItemState.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterItemState.cs index 75c648a7fba..d0f717d5a2d 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterItemState.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterItemState.cs @@ -16,29 +16,34 @@ internal static class CheckboxStateHelper /// public static (bool isChecked, bool isIndeterminate) CalculateCheckboxState(IEnumerable childItems) { - int selectedCount = 0; - int enabledCount = 0; + bool hasSelected = false; + bool hasUnselected = false; foreach (var child in childItems) { if (child.item.isEnabled) { - enabledCount++; if (child.isSelected == true) - selectedCount++; + hasSelected = true; + else + hasUnselected = true; + + // Early exit: mixed state found + if (hasSelected && hasUnselected) + return (false, true); } } - if (enabledCount == 0) - return (false, false); // No enabled children - - if (selectedCount == 0) - return (false, false); // None selected + // No enabled children + if (!hasSelected && !hasUnselected) + return (false, false); - if (selectedCount == enabledCount) - return (true, false); // All selected + // All selected (hasSelected && !hasUnselected) + if (hasSelected) + return (true, false); - return (false, true); // Mixed state (some selected) + // None selected (!hasSelected && hasUnselected) + return (false, false); } /// @@ -59,6 +64,7 @@ public static (bool isChecked, bool isIndeterminate) CalculateCheckboxState(IEnu interface IConverterItemState { bool? isSelected { get; set; } + bool isExpanded { get; set; } IRenderPipelineConverterItem item { get; } (Status Status, string Message) conversionResult { get; } bool hasConverted { get; } @@ -70,6 +76,7 @@ interface IConverterItemState void SetSelectionChangedHandler(Action handler); void Clear(); int CountItemsWithStatus(Status status); + int CountSelectedItemsWithStatus(Status status); int GetTotalItemCount(); int GetSelectedItemCount(); bool IsFolder(); @@ -89,6 +96,7 @@ public Action onIsSelectedChanged set => m_OnIsSelectedChanged = value; } + [SerializeField] private bool m_IsSelected; public bool? isSelected { @@ -103,16 +111,27 @@ public bool? isSelected } } + // Leaf items are never expanded + public bool isExpanded { get => false; set { } } + + [field:SerializeReference] public IRenderPipelineConverterItem item { get; set; } - [NonSerialized] - private (Status Status, string Message) m_ConversionResult = (Status.Pending, string.Empty); + [SerializeField] + private Status m_ConversionStatus = Status.Pending; + [SerializeField] + private string m_ConversionMessage = string.Empty; + public (Status Status, string Message) conversionResult { - get => m_ConversionResult; - set => m_ConversionResult = value; + get => (m_ConversionStatus, m_ConversionMessage); + set + { + m_ConversionStatus = value.Status; + m_ConversionMessage = value.Message; + } } - public bool hasConverted => m_ConversionResult.Status != Status.Pending; + public bool hasConverted => m_ConversionStatus != Status.Pending; public void OnSelectionChanged(ClickEvent _) { @@ -136,7 +155,12 @@ public void SetSelectionChangedHandler(Action handler) public int CountItemsWithStatus(Status status) { - return m_ConversionResult.Status == status ? 1 : 0; + return m_ConversionStatus == status ? 1 : 0; + } + + public int CountSelectedItemsWithStatus(Status status) + { + return (m_IsSelected && m_ConversionStatus == status) ? 1 : 0; } public int GetTotalItemCount() @@ -160,15 +184,26 @@ public bool IsFolder() public int CompareTo(IConverterItemState other) { + if (other == null) + return 1; + if (other.IsFolder()) return 1; + // Handle null items gracefully + if (item == null && other.item == null) + return 0; + if (item == null) + return -1; + if (other.item == null) + return 1; + return string.Compare(item.name, other.item.name, StringComparison.Ordinal); } public DisplayFilter GetDisplayFilter() { - return m_ConversionResult.Status switch + return m_ConversionStatus switch { Status.Pending => DisplayFilter.Pending, Status.Warning => DisplayFilter.Warnings, @@ -209,14 +244,30 @@ public bool? isSelected } } + [SerializeField] + private bool m_IsExpanded = true; // Default to true so folders are expanded by default + public bool isExpanded + { + get => m_IsExpanded; + set => m_IsExpanded = value; + } + + [field:SerializeReference] public IRenderPipelineConverterItem item { get; set; } - [NonSerialized] - private (Status Status, string Message) m_ConversionResult = (Status.Pending, string.Empty); + [SerializeField] + private Status m_ConversionStatus = Status.Pending; + [SerializeField] + private string m_ConversionMessage = string.Empty; + public (Status Status, string Message) conversionResult { - get => m_ConversionResult; - set => m_ConversionResult = value; + get => (m_ConversionStatus, m_ConversionMessage); + set + { + m_ConversionStatus = value.Status; + m_ConversionMessage = value.Message; + } } public bool hasConverted => false; @@ -265,6 +316,30 @@ public void SubscribeToChildren() } } + /// + /// Recalculates folder selection state from children. + /// Called after deserialization since nullable bool can't be serialized. + /// + public void RecalculateSelectionFromChildren() + { + // Recursively recalculate for nested folders first, so this folder + // aggregates up-to-date child states + foreach (var child in children) + { + if (child is FolderItemState childFolder) + childFolder.RecalculateSelectionFromChildren(); + } + + m_IsSelected = CheckboxStateHelper.CalculateSelectionState(children); + + // Recursively recalculate for nested folders + foreach (var child in children) + { + if (child is FolderItemState childFolder) + childFolder.RecalculateSelectionFromChildren(); + } + } + public void UnsubscribeFromChildren() { foreach (var child in children) @@ -315,6 +390,16 @@ public int CountItemsWithStatus(Status status) return count; } + public int CountSelectedItemsWithStatus(Status status) + { + int count = 0; + foreach (var child in children) + { + count += child.CountSelectedItemsWithStatus(status); + } + return count; + } + public int GetTotalItemCount() { int count = 0; @@ -347,9 +432,20 @@ public bool IsFolder() public int CompareTo(IConverterItemState other) { + if (other == null) + return 1; + if (!other.IsFolder()) return -1; + // Handle null items gracefully + if (item == null && other.item == null) + return 0; + if (item == null) + return -1; + if (other.item == null) + return 1; + return string.Compare(item.name, other.item.name, StringComparison.Ordinal); } diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterState.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterState.cs index 16f592ede19..a64b85439d0 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterState.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/ConverterState.cs @@ -89,7 +89,19 @@ private int CountItemWithFlag(Status status) } return count; } + + private int CountSelectedItemWithFlag(Status status) + { + int count = 0; + foreach (var itemState in items) + { + count += itemState.CountSelectedItemsWithStatus(status); + } + return count; + } + public int pending => CountItemWithFlag(Status.Pending); + public int selectedPending => CountSelectedItemWithFlag(Status.Pending); public int warnings => CountItemWithFlag(Status.Warning); public int errors => CountItemWithFlag(Status.Error); public int success => CountItemWithFlag(Status.Success); @@ -111,6 +123,10 @@ public void Clear() m_FilteredItemsTree.Clear(); m_CachedFullTree.Clear(); m_TreeCacheDirty = true; + + // Reset filter to show all items when re-scanning + // (prevents blank tree when filter doesn't match new scan results) + currentFilter = DisplayFilter.All; } private bool IsVisible(DisplayFilter filter) @@ -133,6 +149,76 @@ internal void SetupRootEventHandlers(Action onRootSelectionChanged) } } + /// + /// Cleans up invalid items after deserialization. + /// Called automatically after assembly reload. + /// Note: Root event handlers are re-established by the window during CreateGUI. + /// Note: Tree cache rebuild is deferred - window should call ApplyFilter() before using filteredItemsTree. + /// + internal void OnAfterDeserialize() + { + // Recursively validate and clean up items + bool hasValidItems = ValidateAndCleanItems(items); + + if (!hasValidItems) + { + isInitialized = false; + return; + } + + // Re-subscribe folder items to their children's selection changes + // and recalculate folder selection states from children + foreach (var itemState in items) + { + if (itemState is FolderItemState folderState) + { + folderState.SubscribeToChildren(); + folderState.RecalculateSelectionFromChildren(); + } + } + + // Mark tree cache as dirty - window will call ApplyFilter() when needed + m_TreeCacheDirty = true; + } + + /// + /// Recursively validates items and removes invalid ones. + /// Returns true if any valid items remain. + /// + private bool ValidateAndCleanItems(List itemList) + { + bool hasValidItems = false; + + for (int i = itemList.Count - 1; i >= 0; i--) + { + var itemState = itemList[i]; + if (itemState == null || itemState.item == null) + { + itemList.RemoveAt(i); + } + else + { + hasValidItems = true; + + // Recursively validate children of folders + if (itemState is FolderItemState folderState && folderState.children != null && folderState.children.Count > 0) + { + ValidateAndCleanItems(folderState.children); + } + } + } + + return hasValidItems; + } + + /// + /// No-op - event handlers are [NonSerialized] and don't need cleanup. + /// Kept for ISerializationCallbackReceiver contract. + /// + internal void OnBeforeSerialize() + { + } + /// /// Recursively creates the appropriate state type (FolderItemState or ConverterItemState) for an item /// diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs index bb4626e60bd..e12f2d34b3f 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs @@ -79,8 +79,21 @@ public string info set => m_Info = value; } - public bool isEnabled { get; set; } = true; - public string isDisabledMessage { get; set; } = string.Empty; + [SerializeField] + private bool m_IsEnabled = true; + public bool isEnabled + { + get => m_IsEnabled; + set => m_IsEnabled = value; + } + + [SerializeField] + private string m_IsDisabledMessage = string.Empty; + public string isDisabledMessage + { + get => m_IsDisabledMessage; + set => m_IsDisabledMessage = value; + } public Texture2D icon { diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterManager.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterManager.cs index 7dcfc84eea9..7756030fa7f 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterManager.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterManager.cs @@ -71,15 +71,17 @@ internal void Reset() public void OnBeforeSerialize() { - // TODO: As the converters have data stored inside during initialization we need to clear the states - // Once we keep the items to be classes and converters can inherit them to store any kind of data this can be removed + // Clear event handlers before serialization + // They will be re-established by the window during CreateGUI after reload foreach (var state in converterStates) - state.Clear(); + { + state.OnBeforeSerialize(); + } } public void OnAfterDeserialize() { - // Something null, remove it + // Remove null states for (int i = converterStates.Count - 1; i >= 0; i--) { if (converterStates[i] == null || converterStates[i].converter == null) @@ -87,6 +89,12 @@ public void OnAfterDeserialize() converterStates.RemoveAt(i); } } + + // Clean up invalid items and rebuild trees + foreach (var state in converterStates) + { + state.OnAfterDeserialize(); + } } } } diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs index 5c9bb00b331..265638d5077 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs @@ -8,15 +8,18 @@ namespace UnityEditor.Rendering.Converter [Serializable] internal class RenderPipelineConverterMaterialUpgraderItem : IRenderPipelineConverterItem { - public string assetPath { get; } - public List variantsPaths { get; } - - public string name { get; } - - public string info { get; } - - public bool isEnabled { get; set; } = true; - public string isDisabledMessage { get; set; } = string.Empty; + [SerializeField] + private string m_AssetPath; + public string assetPath => m_AssetPath; + + [SerializeField] + private List m_VariantsPaths; + public List variantsPaths => m_VariantsPaths; + + [field:SerializeField] public string name { get; set; } + [field:SerializeField] public string info { get; set; } + [field:SerializeField] public bool isEnabled { get; set; } = true; + [field:SerializeField] public string isDisabledMessage { get; set; } public Texture2D icon { @@ -42,8 +45,8 @@ public RenderPipelineConverterMaterialUpgraderItem(string shaderPath, string mat if (string.IsNullOrEmpty(materialPath)) throw new ArgumentException(nameof(materialPath)); - assetPath = materialPath; - this.variantsPaths = variantsPaths; + m_AssetPath = materialPath; + m_VariantsPaths = variantsPaths; if (material == null) throw new ArgumentException($"Unable to load material at path {materialPath}"); @@ -170,6 +173,9 @@ public void Scan(Action> onScanFinish) public Status Convert(IRenderPipelineConverterItem item, out string message) { + // Lazy initialization of upgraders cache (needed after assembly reload since it's not serialized) + m_UpgradersCache ??= upgraders; + if (item is not RenderPipelineConverterMaterialUpgraderItem materialUpgraderItem) { message = $"Item is not a {nameof(RenderPipelineConverterMaterialUpgraderItem)}."; diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterUtility.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterUtility.cs index c089b1f8c6f..6bdd92e38e9 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterUtility.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterUtility.cs @@ -15,13 +15,40 @@ internal static class RenderPipelineConverterUtility /// /// Helper class to represent a folder item with children /// + [Serializable] internal class FolderItem : IFolderRenderPipelineConverterItem { - public string name { get; set; } - public string info { get; set; } - public bool isEnabled { get; set; } = true; - public string isDisabledMessage { get; set; } - public IList children { get; set; } = new List(); + [field:SerializeField] public string name { get; set; } + [field:SerializeField] public string info { get; set; } + + /// + /// Folder is enabled if at least one child is enabled. + /// This follows Unity Editor Design System guidelines: disable controls that aren't available right now. + /// + public bool isEnabled + { + get + { + // A folder is enabled if any of its children are enabled + foreach (var child in m_Children) + { + if (child.isEnabled) + return true; + } + return false; + } + set { /* Computed property, setter is no-op */ } + } + + [field:SerializeField] public string isDisabledMessage { get; set; } + + [SerializeReference] + private List m_Children = new List(); + public IList children + { + get => m_Children; + set => m_Children = value == null ? new List() : (value as List ?? new List(value)); + } public virtual Texture2D icon => s_FolderIconCache ??= EditorGUIUtility.FindTexture("Folder Icon"); @@ -32,21 +59,64 @@ public void OnClicked() { } /// Helper class to represent an asset group (not a file system folder) with children /// Shows an asset type icon instead of a folder icon /// - internal class AssetGroupItem : IFolderRenderPipelineConverterItem + [Serializable] + internal class AssetGroupItem : IFolderRenderPipelineConverterItem, ISerializationCallbackReceiver { - public string name { get; set; } - public string info { get; set; } - public bool isEnabled { get; set; } = true; - public string isDisabledMessage { get; set; } - public IList children { get; set; } = new List(); + [field:SerializeField] public string name { get; set; } + [field:SerializeField] public string info { get; set; } + + /// + /// Asset group is enabled if at least one child is enabled. + /// This follows Unity Editor Design System guidelines: disable controls that aren't available right now. + /// + public bool isEnabled + { + get + { + // An asset group is enabled if any of its children are enabled + foreach (var child in m_Children) + { + if (child.isEnabled) + return true; + } + return false; + } + set { /* Computed property, setter is no-op */ } + } + + [field:SerializeField] public string isDisabledMessage { get; set; } + + [SerializeReference] + private List m_Children = new List(); + public IList children + { + get => m_Children; + set => m_Children = value == null ? new List() : (value as List ?? new List(value)); + } /// /// The asset type to use for the icon (e.g., typeof(Material), typeof(Shader)) /// public System.Type assetType { get; set; } + [SerializeField] + private string m_AssetTypeAssemblyQualifiedName; + private Texture2D m_CachedIcon; + public void OnBeforeSerialize() + { + m_AssetTypeAssemblyQualifiedName = assetType?.AssemblyQualifiedName; + } + + public void OnAfterDeserialize() + { + if (!string.IsNullOrEmpty(m_AssetTypeAssemblyQualifiedName)) + { + assetType = System.Type.GetType(m_AssetTypeAssemblyQualifiedName); + } + } + public virtual Texture2D icon { get @@ -66,11 +136,12 @@ public void Reset() { name = null; info = null; - isEnabled = true; + // isEnabled is now computed from children, no need to reset it isDisabledMessage = null; assetType = null; + m_AssetTypeAssemblyQualifiedName = null; m_CachedIcon = null; - children.Clear(); + m_Children.Clear(); } } diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderSettingsConverter.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderSettingsConverter.cs index e67b25f6499..86ea0d80000 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderSettingsConverter.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderSettingsConverter.cs @@ -20,19 +20,12 @@ internal static class RenderPipelineTarget [Serializable] internal class RenderSettingsConverterItem : IRenderPipelineConverterItem { - public int qualityLevelIndex { get; set; } - - public string name { get; set; } - - public string info { get; set; } - - public bool isEnabled { get; set; } - public string isDisabledMessage { get; set; } - - /// - /// Settings path to open when clicked (e.g., "Project/Quality" or "Project/Graphics") - /// - public string settingsPath { get; set; } = "Project/Quality"; + [field:SerializeField] public int qualityLevelIndex { get; set; } + [field:SerializeField] public string name { get; set; } + [field:SerializeField] public string info { get; set; } + [field:SerializeField] public bool isEnabled { get; set; } = true; + [field:SerializeField] public string isDisabledMessage { get; set; } + [field:SerializeField] public string settingsPath { get; set; } = "Project/Quality"; // Settings path to open when clicked (e.g., "Project/Quality" or "Project/Graphics") private static Texture2D s_CachedIcon; @@ -135,89 +128,74 @@ public Status Convert(IRenderPipelineConverterItem item, out string message) { message = string.Empty; - if (item is RenderSettingsConverterItem qualityLevelItem) + if (item is not RenderSettingsConverterItem qualityLevelItem) { - if (CreateRPAssetForQualityLevel(qualityLevelItem.qualityLevelIndex, out message)) - { - if (qualityLevelItem.qualityLevelIndex == RenderPipelineTarget.DefaultGraphicsSettings) - { - message = "Default Render Pipeline Asset created and assigned to Graphics Settings."; - } - else - { - message = "Each Quality Level now has a new, unique Render Pipeline Asset, but all share identical settings. Modify each asset to restore your performance/quality tiers."; - } - return Status.Warning; - } + message = $"Item is not a {nameof(RenderSettingsConverterItem)}."; + return Status.Error; } - return Status.Error; + return CreateRPAssetForQualityLevel(qualityLevelItem.qualityLevelIndex, out message); } - private bool CreateRPAssetForQualityLevel(int qualityIndex, out string message) + private Status CreateRPAssetForQualityLevel(int qualityIndex, out string message) { - bool ok = false; message = string.Empty; if (qualityIndex == RenderPipelineTarget.DefaultGraphicsSettings) { if (GraphicsSettings.defaultRenderPipeline is RenderPipelineAsset rpAsset) { - message = $"Graphics Settings already reference a default Render Pipeline Asset: {rpAsset.name}."; + message = $"Graphics Settings already references a Render Pipeline Asset: {rpAsset.name}."; + return Status.Warning; } - else + + var asset = CreateAsset("DefaultRenderPipeline"); + if (asset == null) { - var asset = CreateAsset("DefaultRenderPipeline"); - - if (asset != null) - { - SetPipelineSettings(asset); - EditorUtility.SetDirty(asset); - AssetDatabase.SaveAssetIfDirty(asset); - - GraphicsSettings.defaultRenderPipeline = asset; - ok = true; - } - else - { - message = "Failed to create Render Pipeline Asset for Graphics Settings."; - } + message = "Failed to create Render Pipeline Asset for Graphics Settings."; + return Status.Error; } - return ok; + SetPipelineSettings(asset); + EditorUtility.SetDirty(asset); + AssetDatabase.SaveAssetIfDirty(asset); + GraphicsSettings.defaultRenderPipeline = asset; + + message = "Default Render Pipeline Asset created and assigned to Graphics Settings."; + return Status.Warning; } var currentQualityLevel = QualitySettings.GetQualityLevel(); - QualitySettings.SetQualityLevel(qualityIndex); - if (QualitySettings.renderPipeline is RenderPipelineAsset qualityRPAsset) + try { - message = $"Quality Level {qualityIndex} already references a Render Pipeline Asset: {qualityRPAsset.name}."; - } - else - { - var asset = CreateAsset($"{QualitySettings.names[qualityIndex]}"); - - if (asset != null) + if (QualitySettings.renderPipeline is RenderPipelineAsset qualityRPAsset) { - SetPipelineSettings(asset); - EditorUtility.SetDirty(asset); - AssetDatabase.SaveAssetIfDirty(asset); - - QualitySettings.renderPipeline = asset; - ok = true; + message = $"Quality Level {qualityIndex} already references a Render Pipeline Asset: {qualityRPAsset.name}."; + return Status.Warning; } - else + + var asset = CreateAsset($"{QualitySettings.names[qualityIndex]}"); + if (asset == null) { message = "Failed to create Render Pipeline Asset."; + return Status.Error; } - } - // Restore back the quality level - QualitySettings.SetQualityLevel(currentQualityLevel); + SetPipelineSettings(asset); + EditorUtility.SetDirty(asset); + AssetDatabase.SaveAssetIfDirty(asset); + QualitySettings.renderPipeline = asset; - return ok; + message = "Render Pipeline Asset created. Modify each asset to restore your performance/quality tiers."; + return Status.Warning; + } + finally + { + // Restore back the quality level + QualitySettings.SetQualityLevel(currentQualityLevel); + } } protected abstract RenderPipelineAsset CreateAsset(string name); diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs index 0bc67d2d24a..422c207b297 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs @@ -7,6 +7,16 @@ namespace UnityEditor.Rendering.Converter { + /// + /// User data stored in toggle elements for folder items in the tree view. + /// Contains the node data and optional callback for event cleanup. + /// + internal struct FolderToggleUserData + { + public TreeNodeData nodeData; + public EventCallback> callback; + } + internal class RenderPipelineConverterVisualElement : VisualElement { const string k_Uxml = "Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.uxml"; @@ -111,11 +121,29 @@ public RenderPipelineConverterVisualElement(Node converterInfo) m_PressScan = m_RootVisualElement.Q("pressScanHelpBox"); m_TreeView = m_RootVisualElement.Q("converterItemsTreeView"); + + // Ensure tree is built (may be needed after assembly reload since OnAfterDeserialize only marks dirty) + state.ApplyFilter(); m_TreeView.SetRootItems(state.filteredItemsTree); // Disable column sorting - items are pre-sorted (folders first, then by name) m_TreeView.sortingMode = ColumnSortingMode.None; + // Register callbacks to track expanded/collapsed state in real-time + m_TreeView.itemExpandedChanged += (args) => + { + // Get the tree node data directly and update its folder state + var nodeData = m_TreeView.GetItemDataForId(args.id); + if (nodeData != null && nodeData.itemState is FolderItemState folderState) + { + folderState.isExpanded = args.isExpanded; + + // Handle recursive collapse/expand (Alt+click or programmatic) + // If this item has children, update their states recursively + UpdateDescendantExpandedStates(nodeData, args.isExpanded); + } + }; + m_Filter = m_RootVisualElement.Q("listViewFilter"); m_Filter.Bind(state); m_Filter.onFilterChanged += () => @@ -123,7 +151,7 @@ public RenderPipelineConverterVisualElement(Node converterInfo) state.ApplyFilter(); m_TreeView.SetRootItems(state.filteredItemsTree); m_TreeView.RefreshItems(); - ExpandAllFolders(state.filteredItemsTree); + RestoreTreeViewExpandedState(); }; var nameColumn = m_TreeView.columns[k_ColumnName]; @@ -203,9 +231,29 @@ public RenderPipelineConverterVisualElement(Node converterInfo) }; Add(m_RootVisualElement); + + // Set up event handlers for state changes + // This is needed both for new states and after assembly reload + SetupStateEventHandlers(); + + // Restore tree view expanded state after assembly reload + RestoreTreeViewExpandedState(); + Refresh(); } + private void SetupStateEventHandlers() + { + // Set up event handlers on root items to refresh UI when selection changes + // This needs to be called both during initial scan and after assembly reload + state.SetupRootEventHandlers((isSelected) => + { + m_TreeView.RefreshItems(); + UpdateSelectedConverterItemsLabel(); + UpdateAllNoneLabels(); + }); + } + private void SetItemsActive(bool value) { state.SetAllItemsSelected(value); @@ -292,8 +340,10 @@ private void ExpandAllFolders(IEnumerable> items) { foreach (var item in items) { - if (item.data.isFolder) + if (item.data.isFolder && item.data.itemState is FolderItemState folderState) { + // Set the folder state to expanded + folderState.isExpanded = true; m_TreeView.ExpandItem(item.id); // Recursively expand children @@ -331,6 +381,35 @@ public void Refresh() m_HeaderFoldout.SetEnabled(converter.isEnabled); } + /// + /// Restores tree view expanded state from folder states. + /// Should only be called after SetRootItems, not on every refresh. + /// + private void RestoreTreeViewExpandedState() + { + if (m_TreeView == null) + return; + + RestoreExpandedStateRecursive(state.filteredItemsTree); + } + + private void RestoreExpandedStateRecursive(IEnumerable> items) + { + foreach (var item in items) + { + if (item.data.isFolder && item.data.itemState is FolderItemState folderState) + { + if (folderState.isExpanded) + m_TreeView.ExpandItem(item.id); + else + m_TreeView.CollapseItem(item.id); + + if (item.hasChildren) + RestoreExpandedStateRecursive(item.children); + } + } + } + public void Scan(Action onScanFinish) { state.Clear(); @@ -344,17 +423,15 @@ void OnConverterCompleteDataCollection(List items) state.AddItem(item); } - // Set up event handlers on root items to refresh UI when selection changes - state.SetupRootEventHandlers((isSelected) => - { - m_TreeView.RefreshItems(); - UpdateSelectedConverterItemsLabel(); - UpdateAllNoneLabels(); - }); + // Set up event handlers (using the shared method) + SetupStateEventHandlers(); state.isLoading = false; state.isInitialized = true; - m_HeaderFoldout.value = true; // Expand the foldout when we perform a search + + // Expand the foldout when we perform a search + state.isExpanded = true; + m_HeaderFoldout.value = true; // Build the tree structure from the items state.ApplyFilter(); @@ -365,6 +442,9 @@ void OnConverterCompleteDataCollection(List items) // Expand all folders recursively by default ExpandAllFolders(state.filteredItemsTree); + // Refresh filter toggle states (filter was reset to All in Clear()) + m_Filter.RefreshToggleStates(); + Refresh(); onScanFinish?.Invoke(); } @@ -372,7 +452,8 @@ void OnConverterCompleteDataCollection(List items) public void Convert(string progressTitle, StringBuilder sb) { - if (state.pending == 0) + int selectedPendingCount = state.selectedPending; + if (selectedPendingCount == 0) { sb.AppendLine($"[{displayName}] Skipping conversion."); return; @@ -381,46 +462,51 @@ public void Convert(string progressTitle, StringBuilder sb) sb.AppendLine($"[{displayName}]"); converter.BeforeConvert(); - int itemIndex = 0; int itemToConvertIndex = 0; foreach (var itemState in state.GetAllLeafItems()) { + // Skip invalid items (can happen after failed deserialization) + if (itemState.item == null) + continue; + + // Skip items that are not selected or already converted + if (itemState.hasConverted || itemState.isSelected != true) + continue; + + var itemName = itemState.item.name ?? "(unnamed)"; + if (EditorUtility.DisplayCancelableProgressBar(progressTitle, - $"({itemToConvertIndex} of {state.pending}) {itemState.item.name}", - itemToConvertIndex / (float)state.pending)) + $"({itemToConvertIndex + 1} of {selectedPendingCount}) {itemName}", + itemToConvertIndex / (float)selectedPendingCount)) break; - if (!itemState.hasConverted && itemState.isSelected == true) + try { - try + var status = converter.Convert(itemState.item, out var message); + switch (status) { - var status = converter.Convert(itemState.item, out var message); - switch (status) + case Status.Pending: + throw new InvalidOperationException("Converter returned a pending status when converting. This is not supported."); + case Status.Error: + case Status.Warning: + sb.AppendLine($"\t- {itemName} ({status}) ({message})"); + break; + case Status.Success: { - case Status.Pending: - throw new InvalidOperationException("Converter returned a pending status when converting. This is not supported."); - case Status.Error: - case Status.Warning: - sb.AppendLine($"\t- {itemState.item.name} ({status}) ({message})"); - break; - case Status.Success: - { - sb.AppendLine($"\t- {itemState.item.name} ({status})"); - message = "Conversion successful!"; - } - break; + sb.AppendLine($"\t- {itemName} ({status})"); + message = "Conversion successful!"; } - - // Update the tuple as a whole - itemState.conversionResult = (status, message); - } - catch(Exception ex) - { - Debug.LogError($"Exception {ex.Message} while converting {itemState.item.name} from {displayName}"); + break; } - itemToConvertIndex++; + + // Update the tuple as a whole + itemState.conversionResult = (status, message); } - itemIndex++; + catch(Exception ex) + { + Debug.LogError($"Exception {ex.Message} while converting {itemName} from {displayName}"); + } + itemToConvertIndex++; } converter.AfterConvert(); @@ -500,41 +586,61 @@ private void BindNameCell(VisualElement element, int index) // FOLDER NODE - Tri-state checkbox toggle.style.display = DisplayStyle.Flex; toggle.style.visibility = Visibility.Visible; - toggle.SetEnabled(true); + + // Check if folder is enabled (at least one child is enabled) + bool folderEnabled = nodeData.itemState?.item.isEnabled ?? false; + toggle.SetEnabled(folderEnabled); var (isChecked, isIndeterminate) = nodeData.GetFolderCheckboxState(); toggle.showMixedValue = isIndeterminate; toggle.SetValueWithoutNotify(isChecked); - if (isIndeterminate) + if (folderEnabled) { - toggle.tooltip = "Some items selected - click to select all"; - } - else - { - toggle.tooltip = isChecked ? "All items selected - click to deselect all" : "No items selected - click to select all"; - } + if (isIndeterminate) + { + toggle.tooltip = "Some items selected - click to select all"; + } + else + { + toggle.tooltip = isChecked ? "All items selected - click to deselect all" : "No items selected - click to select all"; + } - // Create callback that captures the current nodeData - EventCallback> callback = (evt) => - { - bool newValue = evt.newValue; + // Create callback that captures the current nodeData + EventCallback> callback = (evt) => + { + bool newValue = evt.newValue; - // If currently indeterminate, clicking should select all (set to true) - var (currentIsChecked, currentIsIndeterminate) = nodeData.GetFolderCheckboxState(); - if (currentIsIndeterminate) - newValue = true; + // If currently indeterminate, clicking should select all (set to true) + var (currentIsChecked, currentIsIndeterminate) = nodeData.GetFolderCheckboxState(); + if (currentIsIndeterminate) + newValue = true; - nodeData.itemState.SetSelectedWithoutNotify(newValue); - Refresh(); - }; + nodeData.itemState.SetSelectedWithoutNotify(newValue); + Refresh(); + }; - // Store callback in toggle's userData for later cleanup - // We'll use a tuple to store both the TreeNodeData and the callback - toggle.userData = (nodeData, callback); + // Store callback in toggle's userData for later cleanup + toggle.userData = new FolderToggleUserData + { + nodeData = nodeData, + callback = callback + }; - toggle.RegisterValueChangedCallback(callback); + toggle.RegisterValueChangedCallback(callback); + } + else + { + // Folder is disabled - show reason in tooltip + toggle.tooltip = nodeData.itemState?.item.isDisabledMessage ?? "All items in this folder are already converted or disabled"; + // Store nodeData for consistency (no callback since it's disabled) + toggle.userData = new FolderToggleUserData + { + nodeData = nodeData, + callback = null + }; + } } else if (nodeData.itemState != null) { @@ -585,10 +691,10 @@ private void UnbindNameCell(VisualElement element, int index) // Unregister callbacks based on what was stored in userData // Check if it's a folder with callback stored - if (toggle.userData is (TreeNodeData node, EventCallback> callback)) + if (toggle.userData is FolderToggleUserData folderData && folderData.callback != null) { // Unregister the folder's value changed callback - toggle.UnregisterValueChangedCallback(callback); + toggle.UnregisterValueChangedCallback(folderData.callback); toggle.userData = null; } // Or if it's a leaf item with click callback @@ -615,26 +721,79 @@ private void ExpandCollapseAll(bool expand) return; ExpandCollapseAllRecursive(state.filteredItemsTree, expand); + // State is automatically updated via itemExpandedChanged callback } private void ExpandCollapseAllRecursive(IEnumerable> items, bool expand) { foreach (var item in items) { - if (item.data.isFolder) + if (item.data.isFolder && item.data.itemState is FolderItemState folderState) { + // Explicitly update state (don't rely solely on callback) + folderState.isExpanded = expand; + if (expand) m_TreeView.ExpandItem(item.id); else m_TreeView.CollapseItem(item.id); - // Recursively process children if (item.hasChildren) - { ExpandCollapseAllRecursive(item.children, expand); - } } } } + + /// + /// Updates the expanded state of all descendant folders when a parent folder is collapsed/expanded. + /// This ensures recursive collapse (Alt+click) persists correctly across assembly reloads. + /// + private void UpdateDescendantExpandedStates(TreeNodeData parentNode, bool isExpanded) + { + // Get the TreeViewItemData for this node to access its children + var treeItem = FindTreeViewItem(state.filteredItemsTree, parentNode); + if (treeItem.HasValue && treeItem.Value.hasChildren) + { + UpdateDescendantExpandedStatesRecursive(treeItem.Value.children, isExpanded); + } + } + + /// + /// Recursively updates expanded state for all descendant folders + /// + private void UpdateDescendantExpandedStatesRecursive(IEnumerable> items, bool isExpanded) + { + foreach (var item in items) + { + if (item.data.isFolder && item.data.itemState is FolderItemState folderState) + { + folderState.isExpanded = isExpanded; + + if (item.hasChildren) + UpdateDescendantExpandedStatesRecursive(item.children, isExpanded); + } + } + } + + /// + /// Finds a TreeViewItemData that contains the specified TreeNodeData + /// + private TreeViewItemData? FindTreeViewItem(IEnumerable> items, TreeNodeData targetNode) + { + foreach (var item in items) + { + if (item.data == targetNode) + return item; + + if (item.hasChildren) + { + var found = FindTreeViewItem(item.children, targetNode); + if (found.HasValue) + return found; + } + } + + return null; + } } } diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElementListFilter.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElementListFilter.cs index 3a773c136b5..330de48c7be 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElementListFilter.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElementListFilter.cs @@ -87,5 +87,20 @@ public void Update(ConverterState state) m_Error.Q