diff --git a/.gitattributes b/.gitattributes index fcc798703c2..efda4190108 100644 --- a/.gitattributes +++ b/.gitattributes @@ -348,6 +348,9 @@ Editor/Resources/unity[[:space:]]editor[[:space:]]resources filter=lfs diff=lfs **/HDRP_RuntimeTests/Assets/Scenes/002-HDMaterials/cloud2.asset filter=lfs diff=lfs merge=lfs -text **/HDRP_RuntimeTests/Assets/Scenes/002-HDMaterials/perlin.asset filter=lfs diff=lfs merge=lfs -text +# Gfx ML acceleration test assets +**/MachineLearning/**/*.bytes filter=lfs diff=lfs merge=lfs -text + #GfxTests **/GfxTestProjectFolder/**/*.[hH][dD][rR] filter=lfs diff=lfs merge=lfs -text **/GfxTestProjectFolder/**/*.[tT][gG][aA] filter=lfs diff=lfs merge=lfs -text @@ -382,3 +385,6 @@ Editor/Resources/unity[[:space:]]editor[[:space:]]resources filter=lfs diff=lfs # search test cases /Modules/QuickSearch/Tests/QuickSearch/Assets/Cases/UUM-113048/uum-113048.index filter=lfs diff=lfs merge=lfs -text +# documentation images +Documentation/ManualDocs/uploads/Main/unity-xr-tech-stack.png filter=lfs diff=lfs merge=lfs -text + diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs index 3d3f66c16fd..bdf56fad216 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs @@ -1409,8 +1409,11 @@ Vector3Int GetCellPositionFromVoxel(Vector3Int voxelToLookup, int cellSizeInBric continue; // 3. - // Overwrite lighting data with trilinear sampled data from the brick with highest subdiv level - float brickSize = ProbeReferenceVolume.instance.BrickSize(largestBrick.subdivisionLevel - 1); + // Overwrite lighting data with trilinear sampled data from the brick with highest subdiv level. + // Use minBrickSize from m_ProfileInfo (live bake settings), not ProbeReferenceVolume.instance, + // because that runtime state is restored to the previous bake's snapshot at the end of + // ApplySubdivisionResults and would be stale here. UUM-141983. + float brickSize = ProbeVolumeUtil.BrickSize(minBrickSize, largestBrick.subdivisionLevel - 1); float3 uvw = math.clamp((pos - (Vector3)largestBrick.position * minBrickSize) / brickSize, 0, 3); var probe = Vector3Int.FloorToInt(uvw); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCullingBatcherBurst.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCullingBatcherBurst.cs index ae60d8d5546..9beffdccc7c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCullingBatcherBurst.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCullingBatcherBurst.cs @@ -177,6 +177,7 @@ private static void ProcessRenderer(int i, bool implicitInstanceIndices, in GPUD Span packedMaterialDatas = stackalloc GPUDrivenPackedMaterialData[materialsCount]; var supportsIndirect = true; + var isMetal = SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal; for (int matIndex = 0; matIndex < materialsCount; ++matIndex) { if (matIndex >= submeshCount) @@ -198,7 +199,14 @@ private static void ProcessRenderer(int i, bool implicitInstanceIndices, in GPUD bool isFound = packedMaterialDataHash.TryGetValue(materialID, out packedMaterialData); Assert.IsTrue(isFound); } - supportsIndirect &= packedMaterialData.isIndirectSupported; + + var submeshIndex = startSubMesh + matIndex; + var subMesh = rendererData.subMeshDesc[subMeshDescOffset + submeshIndex]; + + // The indirect path does not support topology adjustment; use the direct path when this is required. + // Concretely, for quads, only use the indirect path if we allow quads natively (e.g. tessellation shaders). + supportsIndirect &= subMesh.topology != MeshTopology.Quads || packedMaterialData.hasTessellation; + supportsIndirect &= !isMetal || !packedMaterialData.hasTessellation; packedMaterialDatas[matIndex] = packedMaterialData; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs index c956c8e9057..c95327c7623 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs @@ -109,6 +109,23 @@ internal struct CellStreamingScratchBufferLayout public int _ProbeCountInChunkSlice; } + internal struct BufferLayoutBuilder + { + int _Offset; + + public BufferLayoutBuilder(int initialOffset = 0) + { + _Offset = initialOffset; + } + + public int AddBlock(int blockSize) + { + int currentOffset = _Offset; + _Offset += blockSize; + return currentOffset; + } + } + internal class CellStreamingScratchBuffer { public CellStreamingScratchBuffer(int chunkCount, int chunkSize, bool allocateGraphicsBuffers) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs index ff5e52958b4..b1241474be2 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs @@ -769,13 +769,13 @@ void ReleaseStreamableAssetData(NativeArray buffer) where T : struct m_ReadOperationScratchBuffers.Push(buffer.Reinterpret(UnsafeUtility.SizeOf())); } - void PruneCellIndexList(List cellIndices, List prunedIndexList) + internal void PruneCellIndexList(List cellIndices, List prunedIndexList) { prunedIndexList.Clear(); foreach (var cellIndex in cellIndices) { // When clearing data only partially (ie: not all scenes are loaded), there can be left over indices here but no cells in the set. - if (!cellDataMap.ContainsKey(cellIndex)) + if (!cellDataMap.ContainsKey(cellIndex) && cellDescs.ContainsKey(cellIndex)) { prunedIndexList.Add(cellIndex); } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeScratchBufferPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeScratchBufferPool.cs index f5404a10aec..293d8cfc078 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeScratchBufferPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeScratchBufferPool.cs @@ -133,18 +133,20 @@ CellStreamingScratchBufferLayout GetOrCreateScratchBufferLayout(int chunkCount) // First destination chunks at offset 0 (no explicit member for this). // Then, shared data destination chunks. Can be different from SH data destination in case of blending // (one pool for blending and one other pool for shared data and blending destination). - bufferLayout._SharedDestChunksOffset = destChunksSize; - bufferLayout._L0L1rxOffset = bufferLayout._SharedDestChunksOffset + destChunksSize; - bufferLayout._L1GryOffset = bufferLayout._L0L1rxOffset + m_L0Size * chunkCount; - bufferLayout._L1BrzOffset = bufferLayout._L1GryOffset + m_L1Size * chunkCount; - bufferLayout._ValidityOffset = bufferLayout._L1BrzOffset + m_L1Size * chunkCount; - bufferLayout._ProbeOcclusionOffset = bufferLayout._ValidityOffset + m_ValiditySize * chunkCount; - bufferLayout._SkyOcclusionOffset = bufferLayout._ProbeOcclusionOffset + m_ProbeOcclusionSize * chunkCount; - bufferLayout._SkyShadingDirectionOffset = bufferLayout._SkyOcclusionOffset + m_SkyOcclusionSize * chunkCount; - bufferLayout._L2_0Offset = bufferLayout._SkyShadingDirectionOffset + m_SkyShadingDirectionSize * chunkCount; - bufferLayout._L2_1Offset = bufferLayout._L2_0Offset + m_L2Size * chunkCount; - bufferLayout._L2_2Offset = bufferLayout._L2_1Offset + m_L2Size * chunkCount; - bufferLayout._L2_3Offset = bufferLayout._L2_2Offset + m_L2Size * chunkCount; + + ProbeReferenceVolume.BufferLayoutBuilder layoutBuilder = new(destChunksSize); + bufferLayout._SharedDestChunksOffset = layoutBuilder.AddBlock(destChunksSize); + bufferLayout._L0L1rxOffset = layoutBuilder.AddBlock(m_L0Size * chunkCount); + bufferLayout._L1GryOffset = layoutBuilder.AddBlock(m_L1Size * chunkCount); + bufferLayout._L1BrzOffset = layoutBuilder.AddBlock(m_L1Size * chunkCount); + bufferLayout._ValidityOffset = layoutBuilder.AddBlock(m_ValiditySize * chunkCount); + bufferLayout._SkyOcclusionOffset = layoutBuilder.AddBlock(m_SkyOcclusionSize * chunkCount); + bufferLayout._SkyShadingDirectionOffset = layoutBuilder.AddBlock(m_SkyShadingDirectionSize * chunkCount); + bufferLayout._L2_0Offset = layoutBuilder.AddBlock(m_L2Size * chunkCount); + bufferLayout._L2_1Offset = layoutBuilder.AddBlock(m_L2Size * chunkCount); + bufferLayout._L2_2Offset = layoutBuilder.AddBlock(m_L2Size * chunkCount); + bufferLayout._L2_3Offset = layoutBuilder.AddBlock(m_L2Size * chunkCount); + bufferLayout._ProbeOcclusionOffset = layoutBuilder.AddBlock(m_ProbeOcclusionSize * chunkCount); bufferLayout._ProbeCountInChunkLine = ProbeBrickPool.kChunkProbeCountPerDim; bufferLayout._ProbeCountInChunkSlice = ProbeBrickPool.kChunkProbeCountPerDim * ProbeBrickPool.kBrickProbeCountPerDim; @@ -234,7 +236,7 @@ public void ReleaseScratchBuffer(CellStreamingScratchBuffer scratchBuffer) { if (scratchBuffer.chunkSize != chunkSize) { - scratchBuffer.Dispose(); + scratchBuffer.Dispose(); return; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs index 346b28985b8..6e19b8858d6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs @@ -830,15 +830,15 @@ static Vector3 WorldToViewport(Camera camera, bool isLocalLight, bool isCameraRe { if (isLocalLight) { - return WorldToViewportLocal(isCameraRelative, viewProjMatrix, camera.transform.position, positionWS); + return WorldToViewportLocal(isCameraRelative, viewProjMatrix, camera.transform.position, positionWS, !camera.orthographic); } else { - return WorldToViewportDistance(camera, positionWS); + return WorldToViewportDistance(camera, positionWS, !camera.orthographic); } } - static Vector3 WorldToViewportLocal(bool isCameraRelative, Matrix4x4 viewProjMatrix, Vector3 cameraPosWS, Vector3 positionWS) + static Vector3 WorldToViewportLocal(bool isCameraRelative, Matrix4x4 viewProjMatrix, Vector3 cameraPosWS, Vector3 positionWS, bool isPerspective) { Vector3 localPositionWS = positionWS; if (isCameraRelative) @@ -847,7 +847,8 @@ static Vector3 WorldToViewportLocal(bool isCameraRelative, Matrix4x4 viewProjMat } Vector4 viewportPos4 = viewProjMatrix * localPositionWS; Vector3 viewportPos = new Vector3(viewportPos4.x, viewportPos4.y, 0f); - viewportPos /= viewportPos4.w; + if (isPerspective) + viewportPos /= viewportPos4.w; viewportPos.x = viewportPos.x * 0.5f + 0.5f; viewportPos.y = viewportPos.y * 0.5f + 0.5f; viewportPos.y = 1.0f - viewportPos.y; @@ -855,12 +856,13 @@ static Vector3 WorldToViewportLocal(bool isCameraRelative, Matrix4x4 viewProjMat return viewportPos; } - static Vector3 WorldToViewportDistance(Camera cam, Vector3 positionWS) + static Vector3 WorldToViewportDistance(Camera cam, Vector3 positionWS, bool isPerspective) { Vector4 camPos = cam.worldToCameraMatrix * positionWS; Vector4 viewportPos4 = cam.projectionMatrix * camPos; Vector3 viewportPos = new Vector3(viewportPos4.x, viewportPos4.y, 0f); - viewportPos /= viewportPos4.w; + if (isPerspective) + viewportPos /= viewportPos4.w; viewportPos.x = viewportPos.x * 0.5f + 0.5f; viewportPos.y = viewportPos.y * 0.5f + 0.5f; viewportPos.z = viewportPos4.w; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs index 49b0d721fbf..f1b60fc3a1c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs @@ -58,6 +58,7 @@ void AllocateNativeDataStructuresIfNeeded(int estimatedNumPasses) // These are risky heuristics that only work because we purposely estimate a very high number of passes // We need to fix this with a proper size computation passData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent); + compactedNonCulledRasterPasses = new NativeList(0, AllocatorManager.Persistent); // Will be resized during the compilation inputData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); outputData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); fragmentData = new NativeList(estimatedNumPasses * 4, AllocatorManager.Persistent); @@ -87,6 +88,7 @@ public void Clear() if (m_AreNativeListsAllocated) { passData.Clear(); + compactedNonCulledRasterPasses.Clear(); fences.Clear(); inputData.Clear(); outputData.Clear(); @@ -139,6 +141,7 @@ public ref ResourceReaderData ResourceReader(in ResourceHandle h, int i) // Data per graph level renderpass public NativeList passData; + public NativeList compactedNonCulledRasterPasses; public Dictionary fences; public DynamicArray passNames; @@ -369,6 +372,7 @@ void Cleanup() if (m_AreNativeListsAllocated) { passData.Dispose(); + compactedNonCulledRasterPasses.Dispose(); inputData.Dispose(); outputData.Dispose(); fragmentData.Dispose(); 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 0235dbbd32a..6dbc4c3395c 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 @@ -35,6 +35,9 @@ internal struct RenderGraphInputInfo NativeList m_BeginRenderPassAttachments; + // Contains the index of the non culled passes for native render passes that has at least one pass culled. + NativeList m_NonCulledPassIndicesForRasterPasses; + internal static bool s_ForceGenerateAuditsForTests = false; public NativePassCompiler(RenderGraphCompilationCache cache) @@ -76,6 +79,11 @@ public void Cleanup() { m_BeginRenderPassAttachments.Dispose(); } + + if (m_NonCulledPassIndicesForRasterPasses.IsCreated) + { + m_NonCulledPassIndicesForRasterPasses.Dispose(); + } } public bool Initialize(RenderGraphResourceRegistry resources, List renderPasses, RenderGraphDebugParams debugParams, string debugName, bool useCompilationCaching, @@ -155,6 +163,8 @@ public void Compile(RenderGraphResourceRegistry resources) if (graph.renderTextureUVOriginStrategy == RenderTextureUVOriginStrategy.PropagateAttachmentOrientation) PropagateTextureUVOrigin(); + + CompactNonCulledPassesForRasterPasses(); } public void Clear(bool clearContextData) @@ -632,6 +642,9 @@ void TryMergeNativePasses() #if UNITY_EDITOR || DEVELOPMENT_BUILD bool generatePassBreakAudits = RenderGraphDebugSession.hasActiveDebugSession || s_ForceGenerateAuditsForTests; #endif + int indexSinceLastCulledPass = 0; + bool passWasCulled = false; + bool nonCulledPassIndicesListWasCleared = false; for (var passIdx = 0; passIdx < ctx.passData.Length; ++passIdx) { @@ -640,6 +653,7 @@ void TryMergeNativePasses() // If the pass has been culled, just ignore it if (passToAdd.culled) { + passWasCulled = true; continue; } @@ -653,6 +667,9 @@ void TryMergeNativePasses() ctx.nativePassData.Add(new NativePassData(ref passToAdd, ctx)); passToAdd.nativePassIndex = ctx.nativePassData.LastIndex(); activeNativePassId = passToAdd.nativePassIndex; + + indexSinceLastCulledPass = passIdx; + passWasCulled = false; } } // There is an native pass currently open, try to add the current graph pass to it @@ -684,10 +701,33 @@ void TryMergeNativePasses() passToAdd.nativePassIndex = ctx.nativePassData.LastIndex(); activeNativePassId = passToAdd.nativePassIndex; } + + if (passWasCulled) + { + CollectNonCulledPassIndicesForRasterPasses(passIdx, indexSinceLastCulledPass, mergeTestResult.reason != PassBreakReason.NonRasterPass, !nonCulledPassIndicesListWasCleared); + passWasCulled = false; + nonCulledPassIndicesListWasCleared = true; + } + + indexSinceLastCulledPass = passIdx; } } } + // Handle the last native pass + if (passWasCulled) + { + CollectNonCulledPassIndicesForRasterPasses(ctx.passData.Length, indexSinceLastCulledPass, clearList: !nonCulledPassIndicesListWasCleared); + nonCulledPassIndicesListWasCleared = true; + } + + // We need to clear this data to avoid reusing stale data from a previously compiled graph. + if (!nonCulledPassIndicesListWasCleared && m_NonCulledPassIndicesForRasterPasses.IsCreated) + { + m_NonCulledPassIndicesForRasterPasses.Clear(); + m_NonCulledPassIndicesForRasterPasses.SetCapacity(ctx.passData.Length); + } + if (activeNativePassId >= 0) { // "Close" the last native pass by marking the last graph pass as end @@ -703,6 +743,66 @@ void TryMergeNativePasses() } } + void CollectNonCulledPassIndicesForRasterPasses(int currentPassIdx, int indexSinceLastCulledPass, bool usePreviousNativePass = false, bool clearList = false) + { + var ctx = contextData; + + // In some cases, we create a new native render pass (we allocate a new stand-alone native renderpass based on the current pass) + // but we need to update the data of the previous native pass and not the newly one created. + var indexLastNativePassData = (usePreviousNativePass) ? ctx.nativePassData.LastIndex() - 1 : ctx.nativePassData.LastIndex(); + + // In case we have a graph without any render pass. + if (indexLastNativePassData == -1) + return; + + // Filling the attachments array to be sent to the rendering command buffer + if (!m_NonCulledPassIndicesForRasterPasses.IsCreated) + { + m_NonCulledPassIndicesForRasterPasses = new NativeList(ctx.passData.Length, Allocator.Persistent); + } + else if (clearList) + { + m_NonCulledPassIndicesForRasterPasses.Clear(); + m_NonCulledPassIndicesForRasterPasses.SetCapacity(ctx.passData.Length); + } + + ref var lastNativePassData = ref ctx.nativePassData.ElementAt(indexLastNativePassData); + lastNativePassData.firstCompactedNonCulledRasterPass = m_NonCulledPassIndicesForRasterPasses.Length; + + // The native pass has at least one pass culled, so we iterate over each pass to retrieve + // the index of the non culled pass, so they can be copied later on in a new NativeList that + // will be contiguous in memory. + for (var nonCulledPassIdx = 0; nonCulledPassIdx < currentPassIdx - indexSinceLastCulledPass; ++nonCulledPassIdx) + { + ref var passToCopy = ref ctx.passData.ElementAt(indexSinceLastCulledPass + nonCulledPassIdx); + + if (!passToCopy.culled) + { + m_NonCulledPassIndicesForRasterPasses.Add(indexSinceLastCulledPass + nonCulledPassIdx); + } + } + + lastNativePassData.lastCompactedNonCulledRasterPass = m_NonCulledPassIndicesForRasterPasses.Length - 1; + } + + // Must be called at the end of the compilation, when PassData is not modified anymore. + void CompactNonCulledPassesForRasterPasses() + { + if (!m_NonCulledPassIndicesForRasterPasses.IsCreated || m_NonCulledPassIndicesForRasterPasses.Length == 0) + return; + + var ctx = contextData; + ctx.compactedNonCulledRasterPasses.ResizeUninitialized(m_NonCulledPassIndicesForRasterPasses.Length); + + // Copy and cache only the PassData that were not contiguous in memory because of culling. + // They are copied in a new NativeArray that is contiguous in memory so we avoid further copies + // later at many places (Initialize, Destroy, etc.) by using directly a ReadOnlySpan of this array. + for (int i = 0; i < m_NonCulledPassIndicesForRasterPasses.Length; ++i) + { + ctx.compactedNonCulledRasterPasses[i] = ctx.passData.ElementAt(m_NonCulledPassIndicesForRasterPasses[i]); + } + } + bool FindFirstPassIdOnGraphicsQueueAwaitingFenceGoingForward(ref PassData startAsyncPass, out int firstPassIdAwaiting) { var ctx = contextData; @@ -1078,9 +1178,12 @@ void DetectMemoryLessResources() foreach (ref readonly var nativePass in contextData.NativePasses) { // Loop over all created resources by this nrp - var graphPasses = nativePass.GraphPasses(contextData); - foreach (ref readonly var subPass in graphPasses) + for (int passIdx = nativePass.firstGraphPass; passIdx < nativePass.lastGraphPass + 1; ++passIdx) { + ref var subPass = ref contextData.passData.ElementAt(passIdx); + if (subPass.culled) + continue; + foreach (ref readonly var createdRes in subPass.FirstUsedResources(contextData)) { ref var createInfo = ref contextData.UnversionedResourceData(createdRes); @@ -1097,8 +1200,12 @@ void DetectMemoryLessResources() // But to avoid execution errors we still need to create the resource in this case. // Check if it is in the destroy list of any of the subpasses > if yes > memoryless - foreach (ref readonly var subPass2 in graphPasses) + for (int passIdx2 = nativePass.firstGraphPass; passIdx2 < nativePass.lastGraphPass + 1; ++passIdx2) { + ref var subPass2 = ref contextData.passData.ElementAt(passIdx2); + if (subPass2.culled) + continue; + foreach (ref readonly var destroyedRes in subPass2.LastUsedResources(contextData)) { ref var destInfo = ref contextData.UnversionedResourceData(destroyedRes); 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 cdb8b770e6c..b9aece61b79 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 @@ -668,6 +668,9 @@ internal struct NativePassData public int lastGraphPass; public int numGraphPasses; + public int firstCompactedNonCulledRasterPass; + public int lastCompactedNonCulledRasterPass; + public int firstNativeSubPass; // Offset+count in context subpass array public int numNativeSubPasses; public int width; @@ -693,6 +696,8 @@ public NativePassData(ref PassData pass, CompilerContextData ctx) numGraphPasses = 1; firstNativeSubPass = -1; // Set up during compile numNativeSubPasses = 0; + firstCompactedNonCulledRasterPass = -1; + lastCompactedNonCulledRasterPass = -1; fragments = new FixedAttachmentArray(); attachments = new FixedAttachmentArray(); @@ -768,6 +773,8 @@ public void Clear() { firstGraphPass = 0; numGraphPasses = 0; + firstCompactedNonCulledRasterPass = -1; + lastCompactedNonCulledRasterPass = -1; attachments.Clear(); fragments.Clear(); loadAudit.Clear(); @@ -780,6 +787,7 @@ public readonly bool IsValid() return numGraphPasses > 0; } + // This method cannot be called during the Compile step. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly ReadOnlySpan GraphPasses(CompilerContextData ctx) { @@ -789,20 +797,10 @@ public readonly ReadOnlySpan GraphPasses(CompilerContextData ctx) return ctx.passData.MakeReadOnlySpan(firstGraphPass, numGraphPasses); } - var actualPasses = - new NativeArray(numGraphPasses, Allocator.Temp, - NativeArrayOptions.UninitializedMemory); + if (ctx.compactedNonCulledRasterPasses.IsEmpty) + throw new Exception(RenderGraph.RenderGraphExceptionMessages.k_GraphPassesCalledBeforeCompactedNonCulledRasterPasses); - for (int i = firstGraphPass, index = 0; i < lastGraphPass + 1; ++i) - { - var pass = ctx.passData[i]; - if (!pass.culled) - { - actualPasses[index++] = pass; - } - } - - return actualPasses; + return ctx.compactedNonCulledRasterPasses.MakeReadOnlySpan(firstCompactedNonCulledRasterPass, lastCompactedNonCulledRasterPass - firstCompactedNonCulledRasterPass + 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -953,9 +951,12 @@ public static PassBreakAudit CanMerge(CompilerContextData contextData, int activ // Temporary cache of sampled textures in current Native Render Pass for conflict detection against fragments using (HashSetPool.Get(out var tempSampledTextures)) { - var graphPasses = nativePass.GraphPasses(contextData); - foreach (ref readonly var graphPass in graphPasses) + for (int i = nativePass.firstGraphPass; i < nativePass.lastGraphPass + 1; ++i) { + ref var graphPass = ref contextData.passData.ElementAt(i); + if (graphPass.culled) + continue; + if (graphPass.numSampledOnlyRaster > 0) // Skip passes with no sampled textures { foreach (ref readonly var earlierInput in graphPass.SampledTexturesIfRaster(contextData)) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs index 2e8091abfdb..f97c9e45f34 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs @@ -58,6 +58,8 @@ internal static class RenderGraphExceptionMessages internal const string k_AddingOlderAttachmentVersion = "The pass adds an older version while a higher version is already registered with the pass. Make sure you only access the latest version."; + internal const string k_GraphPassesCalledBeforeCompactedNonCulledRasterPasses = "Cannot iterate over compactedNonCulledRasterPasses, the data is null. Did you use GraphPasses() before calling CompactNonCulledPassesForRasterPasses?"; + // Users shouldn't be seeing these, they are a sort of catch for internal RG mistakes. internal const string k_NonIncrementalCreationCall = "Something went wrong when compiling the graph. The Creation lists must be set-up incrementally for all passes, but AddFirstUse is called in an arbitrary non-incremental way."; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs index e2b014d2789..feba8336164 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs @@ -118,7 +118,6 @@ public class InternalRenderGraphContext internal RenderGraphPass executingPass; internal NativeRenderPassCompiler.CompilerContextData compilerContext; internal bool contextlessTesting; - internal bool forceResourceCreation; } // InternalRenderGraphContext is public (but all members are internal) @@ -1624,13 +1623,15 @@ public void BeginRecording(in RenderGraphParameters parameters) // With the actual implementation of the Frame Debugger, we cannot re-use resources during the same frame // or it breaks the rendering of the pass preview, since the FD copies the texture after the execution of the RG. - m_RenderGraphContext.forceResourceCreation = + // When disabled, this mode prevents resources released in the current frame from being reused until the next frame. #if UNITY_EDITOR || DEVELOPMENT_BUILD - FrameDebugger.enabled; + bool enableMemoryAliasing = !FrameDebugger.enabled; #else - false; + bool enableMemoryAliasing = true; #endif + m_Resources.EnableIntraFrameMemoryAliasing(enableMemoryAliasing); + if (m_DebugParameters.immediateMode) { UpdateCurrentCompiledGraph(graphHash: -1, forceNoCaching: true); @@ -3170,6 +3171,33 @@ internal void ClearGlobalBindings() m_RenderGraphContext.cmd.SetGlobalTexture(globalTex.Key, defaultResources.blackTexture); } } + + /// + /// Enables or disables intra-frame memory aliasing for render graph resources. + /// When enabled, resources released within the same execution can be immediately reused by subsequent passes. + /// When disabled, resources released in the current execution cannot be reused until the next execution. + /// Note: An execution corresponds to a single RenderGraph recording/execution cycle. Multiple executions can occur + /// within the same frame (e.g., Frame Debugger cascade-repaints, multiple cameras). + /// This is primarily used for testing purposes and for Frame Debugger compatibility. + /// + /// True to enable intra-frame memory aliasing, false to disable it. + internal void SetIntraFrameMemoryAliasing(bool enabled) + { + m_Resources.EnableIntraFrameMemoryAliasing(enabled); + } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] + static void ResetStaticsOnLoad() + { + s_RegisteredExecutions.Clear(); + s_EnableCompilationCachingForTests = null; + onGraphRegistered = null; + onGraphUnregistered = null; + onExecutionRegistered = null; + s_DebugSessionWasActive = false; + } +#endif } /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs index 509a871c4ab..090ad9482fb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs @@ -10,13 +10,35 @@ abstract class IRenderGraphResourcePool public abstract void Cleanup(); public abstract void CheckFrameAllocation(bool onException, int frameIndex); public abstract void LogResources(RenderGraphLogger logger); + + // When disabled, resources released in the current execution cannot be reused until the next execution. + // This is useful for Frame Debugger to ensure each pass uses unique resources within an execution. + public bool IntraFrameMemoryAliasing { get; set; } = true; + } + + /// + /// Encapsulates a pooled resource along with its frame and execution tracking metadata. + /// This allows the pool to track when resources were released for proper reuse and purging decisions. + /// + readonly struct PooledResourceEntry where Type : class + { + public readonly Type resource; + public readonly int frameIndex; + public readonly int executionCount; + + public PooledResourceEntry(Type resource, int frameIndex, int executionCount) + { + this.resource = resource; + this.frameIndex = frameIndex; + this.executionCount = executionCount; + } } abstract class RenderGraphResourcePool : IRenderGraphResourcePool where Type : class { // Dictionary tracks resources by hash and stores resources with same hash in a List (list instead of a stack because we need to be able to remove stale allocations, potentially in the middle of the stack). // The list needs to be sorted otherwise you could get inconsistent resource usage from one frame to another. - protected Dictionary> m_ResourcePool = new Dictionary>(); + protected Dictionary>> m_ResourcePool = new Dictionary>>(); // This list allows us to determine if all resources were correctly released in the frame when validity checks are enabled. // This is useful to warn in case of user error or avoid leaks when a render graph execution error occurs for example. @@ -30,25 +52,50 @@ abstract class RenderGraphResourcePool : IRenderGraphResourcePool where Ty protected abstract string GetResourceTypeName(); protected abstract ulong GetSortIndex(Type res); - public void ReleaseResource(int hash, Type resource, int currentFrameIndex) + public void ReleaseResource(int hash, Type resource, int currentFrameIndex, int currentExecutionCount) { if (!m_ResourcePool.TryGetValue(hash, out var list)) { - list = new SortedList(); + list = new SortedList>(); m_ResourcePool.Add(hash, list); } - list.Add(GetSortIndex(resource), (resource, currentFrameIndex)); + list.Add(GetSortIndex(resource), new PooledResourceEntry(resource, currentFrameIndex, currentExecutionCount)); } - public bool TryGetResource(int hashCode, out Type resource) + public bool TryGetResource(int hashCode, out Type resource, int currentFrameIndex, int currentExecutionCount) { - if (m_ResourcePool.TryGetValue(hashCode, out SortedList list) && list.Count > 0) + if (m_ResourcePool.TryGetValue(hashCode, out SortedList> list) && list.Count > 0) { - var index = list.Count - 1; - resource = list.Values[index].resource; - list.RemoveAt(index); // O(1) since it's the last element. - return true; + // When "intra frame memory aliasing" mode is disabled, skip resources that were released in the current execution. + // They will only be available for reuse in the next execution. + if (!IntraFrameMemoryAliasing) + { + // Iterate from the end to find a resource not from the current execution. + for (int i = list.Count - 1; i >= 0; i--) + { + var entry = list.Values[i]; + + // Allow reuse if the resource was released in a previous frame (normal case), + // or in a previous execution within the same frame (Frame Debugger cascade-repaints). + // This handles both standard frame-to-frame reuse and rapid repaints in Frame Debugger. + if (entry.frameIndex < currentFrameIndex || entry.executionCount < currentExecutionCount) + { + resource = entry.resource; + list.RemoveAt(i); + return true; + } + } + // All available resources are from the current execution, so we need to create a new one. + } + else + { + // Normal mode: take the most recent resource. + var index = list.Count - 1; + resource = list.Values[index].resource; + list.RemoveAt(index); // O(1) since it's the last element. + return true; + } } resource = null; @@ -104,7 +151,9 @@ public override void CheckFrameAllocation(bool onException, int frameIndex) { if (!onException) logMessage = $"{logMessage}\n\t{GetResourceName(value.Item2)}"; - ReleaseResource(value.Item1, value.Item2, frameIndex); + // When releasing on exception/error, use -1 as executionCount marker. + // This ensures the resource goes back to the pool but won't interfere with normal execution tracking. + ReleaseResource(value.Item1, value.Item2, frameIndex, -1); } if (!onException) // If onException is true, logMessage is "" 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 95d8f2a14b6..d5c21fff63d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs @@ -328,6 +328,17 @@ internal void EndExecute() current = null; } + internal void EnableIntraFrameMemoryAliasing(bool enabled) + { + for (int i = 0; i < (int)RenderGraphResourceType.Count; ++i) + { + if (m_RenderGraphResources[i].pool != null) + { + m_RenderGraphResources[i].pool.IntraFrameMemoryAliasing = enabled; + } + } + } + [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] [MethodImpl(MethodImplOptions.AggressiveInlining)] void CheckHandleValidity(in ResourceHandle res) @@ -1017,7 +1028,7 @@ internal bool CreatePooledResource(InternalRenderGraphContext rgContext, int typ var resource = m_RenderGraphResources[type].resourceArray[index]; if (!resource.imported) { - resource.CreatePooledGraphicsResource(rgContext.forceResourceCreation); + resource.CreatePooledGraphicsResource(m_CurrentFrameIndex, m_ExecutionCount); if (m_RenderGraphDebug.enableLogging) resource.LogCreation(m_FrameInformationLogger); @@ -1095,7 +1106,7 @@ internal void ReleasePooledResource(InternalRenderGraphContext rgContext, int ty resource.LogRelease(m_FrameInformationLogger); } - resource.ReleasePooledGraphicsResource(m_CurrentFrameIndex); + resource.ReleasePooledGraphicsResource(m_CurrentFrameIndex, m_ExecutionCount); } } 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 27b3a51cc65..86904ed5935 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs @@ -198,10 +198,10 @@ public virtual bool NeedsFallBack() return requestFallBack && writeCount == 0; } - public virtual void CreatePooledGraphicsResource(bool forceResourceCreation) { } + public virtual void CreatePooledGraphicsResource(int frameIndex, int executionCount) { } public virtual void CreateGraphicsResource() { } public virtual void UpdateGraphicsResource() { } - public virtual void ReleasePooledGraphicsResource(int frameIndex) { } + public virtual void ReleasePooledGraphicsResource(int frameIndex, int executionCount) { } public virtual void ReleaseGraphicsResource() { } public virtual void LogCreation(RenderGraphLogger logger) { } public virtual void LogRelease(RenderGraphLogger logger) { } @@ -246,7 +246,7 @@ public override void ReleaseGraphicsResource() graphicsResource = null; } - public override void CreatePooledGraphicsResource(bool forceResourceCreation) + public override void CreatePooledGraphicsResource(int frameIndex, int executionCount) { Debug.Assert(m_Pool != null, "RenderGraphResource: CreatePooledGraphicsResource should only be called for regular pooled resources"); @@ -257,7 +257,7 @@ public override void CreatePooledGraphicsResource(bool forceResourceCreation) // If the pool doesn't have any available resource that we can use, we will create one // In any case, we will update the graphicsResource name based on the RenderGraph resource name - if (forceResourceCreation || !m_Pool.TryGetResource(hashCode, out graphicsResource)) + if (!m_Pool.TryGetResource(hashCode, out graphicsResource, frameIndex, executionCount)) { CreateGraphicsResource(); } @@ -270,7 +270,7 @@ public override void CreatePooledGraphicsResource(bool forceResourceCreation) m_Pool.RegisterFrameAllocation(cachedHash, graphicsResource); } - public override void ReleasePooledGraphicsResource(int frameIndex) + public override void ReleasePooledGraphicsResource(int frameIndex, int executionCount) { if (graphicsResource == null) throw new InvalidOperationException($"RenderGraphResource: Tried to release a resource ({GetName()}) that was never created. Check that there is at least one pass writing to it first."); @@ -278,7 +278,7 @@ public override void ReleasePooledGraphicsResource(int frameIndex) // Shared resources don't use the pool if (m_Pool != null) { - m_Pool.ReleaseResource(cachedHash, graphicsResource, frameIndex); + m_Pool.ReleaseResource(cachedHash, graphicsResource, frameIndex, executionCount); m_Pool.UnregisterFrameAllocation(cachedHash, graphicsResource); } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs index ed76b8f56de..9c7c5311db6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs @@ -5,6 +5,16 @@ namespace UnityEngine.Rendering { + /// + /// Incremental 32-bit FNV-1a hash builder. + /// Use this for change detection or other non-cryptographic hashing where + /// equally-shaped inputs should produce well-distributed hashes. + /// + /// + /// As a ref struct, instances cannot be stored in fields, boxed, or + /// captured by lambdas/async methods; create one, append inputs, then read + /// . + /// internal ref struct HashFNV1A32 { /// @@ -19,11 +29,17 @@ internal ref struct HashFNV1A32 uint m_Hash; + /// + /// Creates a new hash builder seeded with the FNV offset basis. + /// + /// An empty ready to receive calls. public static HashFNV1A32 Create() { return new HashFNV1A32 { m_Hash = k_OffsetBasis }; } + /// Mixes an into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in int input) { @@ -33,6 +49,8 @@ public void Append(in int input) } } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in uint input) { @@ -42,12 +60,16 @@ public void Append(in uint input) } } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in bool input) { m_Hash = (m_Hash ^ (input ? 1u : 0u)) * k_Prime; } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in float input) { @@ -57,6 +79,8 @@ public void Append(in float input) } } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in double input) { @@ -66,33 +90,39 @@ public void Append(in double input) } } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in Vector2 input) { - unchecked - { - m_Hash = (m_Hash ^ (uint)input.GetHashCode()) * k_Prime; - } + Append(input.x); + Append(input.y); } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in Vector3 input) { - unchecked - { - m_Hash = (m_Hash ^ (uint)input.GetHashCode()) * k_Prime; - } + Append(input.x); + Append(input.y); + Append(input.z); } + /// Mixes a into the running hash. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(in Vector4 input) { - unchecked - { - m_Hash = (m_Hash ^ (uint)input.GetHashCode()) * k_Prime; - } + Append(input.x); + Append(input.y); + Append(input.z); + Append(input.w); } + /// Mixes any value-type input into the running hash via its . + /// Any value type. + /// Value to fold in. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(T input) where T : struct { @@ -102,8 +132,10 @@ public void Append(T input) where T : struct } } + /// The current hash value as a signed 32-bit integer. public int value => (int)m_Hash; + /// public override int GetHashCode() { return value; @@ -144,4 +176,4 @@ public static int GetFuncHashCode(Delegate del) internal static void ClearCache() => s_MethodHashCodeToSkipTargetHashMap.Value.Clear(); } -} \ No newline at end of file +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs index c125c1c7bf9..264b592be13 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs @@ -342,6 +342,26 @@ public bool AnyPropertiesIsOverridden() return false; } + /// + /// Computes a hash of the current state of every parameter on this component + /// (values and override flags). Intended for change detection — for example, + /// invalidating a cached render target when any parameter changes. + /// + /// + /// This value mutates as parameters change, so it must not be used as a key in + /// a , + /// , or any other structure + /// that assumes a stable hash. Use for that. + /// + /// A hash that changes whenever any parameter's value or override state changes. + public int GetStateHash() + { + var hash = HashFNV1A32.Create(); + for (int i = 0; i < parameterList.Length; i++) + hash.Append(parameterList[i].GetHashCode()); + return hash.value; + } + /// /// Unity calls this method before the object is destroyed. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs index 38e3e6f29cf..7475939a712 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs @@ -334,6 +334,36 @@ internal int GetComponentListHashCode() } } + /// + /// Computes a hash of the current state of every component on this profile + /// (the values and override flags of all their parameters). + /// Intended for change detection — for example, detecting that a Volume Profile + /// asset has been edited and a dependent cached resource must be rebuilt. + /// + /// + /// This value mutates as parameters change, so it must not be used as a key in + /// a , + /// , or any other structure + /// that assumes a stable hash. Use for that. + /// + /// This hash covers parameter state only. To detect changes to the *set* of + /// components on the profile (additions/removals), use + /// . + /// + /// A hash that changes whenever any component's state changes. + public int GetStateHash() + { + var hash = HashFNV1A32.Create(); + for (int i = 0; i < components.Count; i++) + { + var comp = components[i]; + if (comp == null) + continue; + hash.Append(comp.GetStateHash()); + } + return hash.value; + } + /// /// Removes any components that were destroyed externally from the iternal list of components /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs index ba7dbb8ad8d..469506cf490 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs @@ -90,6 +90,7 @@ void DisposeResources() validatedShadingRateFragmentSizeBuffer = null; m_VisualizationShader = null; + CoreUtils.Destroy(m_VisualizationMaterial); m_VisualizationMaterial = null; } diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl index 3acb16aa771..121d13365c2 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl @@ -80,9 +80,8 @@ Also, for tiles to be automatically loaded, you need to write to the VT Feedback texture (SV_Target1) by yourself in the "ForwardOnly" pass. For example: - #if defined(UNITY_VIRTUAL_TEXTURING) && defined(SHADER_API_PSSL) - // Prevent loss of precision on some Sony platforms. - #pragma PSSL_target_output_format(target 1 FMT_32_ABGR) + #if defined(UNITY_VIRTUAL_TEXTURING) + #pragma rendertarget_format_hint MRT1 R16G16_UNorm #endif void Frag(PackedVaryingsToPS packedInput, out float4 outColor : SV_Target0 diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs index 09fbb08b539..a033dc2e052 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs @@ -1566,7 +1566,6 @@ public void GraphPassesDoesNotAlloc() // Goes into possible alloc path Assert.IsFalse(passes[0].lastGraphPass - passes[0].firstGraphPass + 1 == passes[0].numGraphPasses); - ValidateNoGCAllocs(() => { passes[0].GraphPasses(result.contextData); @@ -2138,5 +2137,206 @@ public void TextureUVOrigin_CheckInvalidMixedUVOriginDirect_InputCheck() builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); } } + + [Test] + public void CompactedNonCulledRasterPassesWorks_FirstPassIsCulled() + { + var g = AllocateRenderGraph(); + var renderTargets = ImportAndCreateRenderTargets(g); + + using (var builder = g.AddRasterRenderPass("Pass0", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(true); + } + + // Same attachments, we should merge in the same subpass as Pass0's one + using (var builder = g.AddRasterRenderPass("Pass1", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[2], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Unsafe pass, we break the previous native renderpass + using (var builder = g.AddUnsafePass("Pass2", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, UnsafeGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // New native renderpass + using (var builder = g.AddRasterRenderPass("Pass3", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass3's one + // This pass is being culled + using (var builder = g.AddRasterRenderPass("Pass4", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[2], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass4's one + using (var builder = g.AddRasterRenderPass("Pass5", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + // Only 2 native passes and 3 passes in the last one + Assert.IsTrue(passes != null && passes.Count == 2 && passes[1].numGraphPasses == 3); + + // No need of the compact algorithm for this test. + Assert.IsTrue(result.contextData.compactedNonCulledRasterPasses.Length == 0); + Assert.IsTrue(passes[1].firstCompactedNonCulledRasterPass == -1 && passes[1].lastCompactedNonCulledRasterPass == -1); + } + + [Test] + public void CompactedNonCulledRasterPassesWorks_MiddlePassIsCulled() + { + var g = AllocateRenderGraph(); + var renderTargets = ImportAndCreateRenderTargets(g); + + using (var builder = g.AddRasterRenderPass("Pass0", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass0's one + using (var builder = g.AddRasterRenderPass("Pass1", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[2], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Unsafe pass, we break the previous native renderpass + using (var builder = g.AddUnsafePass("Pass2", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, UnsafeGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // New native renderpass + using (var builder = g.AddRasterRenderPass("Pass3", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass3's one + // This pass is being culled + using (var builder = g.AddRasterRenderPass("Pass4", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[2], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(true); + } + + // Same attachments, we should merge in the same subpass as Pass4's one + using (var builder = g.AddRasterRenderPass("Pass5", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + // Only 2 native passes and 2 passes in the last one + Assert.IsTrue(passes != null && passes.Count == 2 && passes[1].numGraphPasses == 2); + + // Pass 3 and Pass 5 are copied so they are contiguous in memory (Pass 4 is skipped since it's a culled pass). + Assert.IsTrue(result.contextData.compactedNonCulledRasterPasses.Length == 2); + + // First index is pointing Pass 3 (element 0 of nonCulledPassData) and last index Pass 5 (element 1 of nonCulledPassData) + // They are now contiguous in memory. + Assert.IsTrue(passes[1].firstCompactedNonCulledRasterPass == 0 && passes[1].lastCompactedNonCulledRasterPass == 1); + } + + [Test] + public void CompactedNonCulledRasterPassesWorks_LastPassIsCulled() + { + var g = AllocateRenderGraph(); + var renderTargets = ImportAndCreateRenderTargets(g); + + using (var builder = g.AddRasterRenderPass("Pass0", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass0's one + using (var builder = g.AddRasterRenderPass("Pass1", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[2], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Unsafe pass, we break the previous native renderpass + using (var builder = g.AddUnsafePass("Pass2", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, UnsafeGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // New native renderpass + using (var builder = g.AddRasterRenderPass("Pass3", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass3's one + // This pass is being culled + using (var builder = g.AddRasterRenderPass("Pass4", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[2], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Same attachments, we should merge in the same subpass as Pass4's one + using (var builder = g.AddRasterRenderPass("Pass5", out var passData)) + { + builder.SetRenderAttachment(renderTargets.extraTextures[1], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(true); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + // Only 2 native passes and 2 passes in the last one + Assert.IsTrue(passes != null && passes.Count == 2 && passes[1].numGraphPasses == 2); + + // Pass 3 and Pass 4 are copied so they are contiguous in memory (Pass 5 is skipped since it's a culled pass). + Assert.IsTrue(result.contextData.compactedNonCulledRasterPasses.Length == 2); + + // First index is pointing Pass 3 (element 0 of nonCulledPassData) and last index Pass 4 (element 1 of nonCulledPassData) + // They are now contiguous in memory. + Assert.IsTrue(passes[1].firstCompactedNonCulledRasterPass == 0 && passes[1].lastCompactedNonCulledRasterPass == 1); + } } } 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 3389eb7540f..fcb37de3f90 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs @@ -2372,8 +2372,8 @@ public void ResourcePool_Cleanup_ReleaseGfxResourceAndClearPool() useMipMap: false, autoGenerateMips: false, name: "DummyPoolTexture"); - // Release it into the pool - texturePool.ReleaseResource(0, resIn, 0); + // Release it into the pool (frameIndex=0, executionCount=0) + texturePool.ReleaseResource(0, resIn, 0, 0); Assert.IsTrue(texturePool.GetMemorySizeInMB() > 0); Assert.IsTrue(texturePool.GetNumResourcesAvailable() == 1); @@ -2400,12 +2400,13 @@ public void ResourcePool_TryGet() useMipMap: false, autoGenerateMips: false, name: "DummyPoolTexture"); - // Release it into the pool - texturePool.ReleaseResource(0, resIn, 0); + // Release it into the pool (frameIndex=0, executionCount=0) + texturePool.ReleaseResource(0, resIn, 0, 0); // Retrieve it from the pool and make sure this is the right one RTHandle resOut; - texturePool.TryGetResource(0, out resOut); + // Use frameIndex=1, executionCount=1 to ensure reuse (different frame and execution) + texturePool.TryGetResource(0, out resOut, 1, 1); Assert.IsTrue(resIn.GetUniqueID() == resOut.GetUniqueID()); texturePool.Cleanup(); @@ -2572,5 +2573,244 @@ public void TextureUVOrigin_CheckTextureReadBreaksBackbufferUVOriginInherited() m_RenderGraph.Cleanup(); } + + [Test] + public void IntraFrameMemoryAliasing_WhenEnabled_ResourcesCanBeReusedWithinSameFrame() + { + var format = GraphicsFormat.R8G8B8A8_UNorm; + if (!SystemInfo.IsFormatSupported(format, GraphicsFormatUsage.LoadStore)) + { + Assert.Ignore($"Platform does not support random writes (LoadStore) for {format}"); + } + + const int kWidth = 512; + const int kHeight = 512; + + EntityId pass1ResourceID = default; + EntityId pass2ResourceID = default; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + // Enable intra-frame memory aliasing + m_RenderGraph.SetIntraFrameMemoryAliasing(true); + + // TODO: Create texture 1 with enableRandomWrite to allow UAV access (compute/non-fragment usage). + // This prevents memoryless detection on Metal. When textures are used as fragment attachments + // (render targets), Metal's compiler marks them as memoryless even with disablePassMerging=true, + // which modifies TextureDesc.memoryless and breaks resource pooling hash matching. + // Using compute passes with UAV access avoids the fragment attachment path entirely. + var texture1 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = format, enableRandomWrite = true, name = "Texture1" }); + + using (var builder = m_RenderGraph.AddComputePass("Pass1_WriteTexture1", out var passData)) + { + passData.textures[0] = texture1; + builder.UseTexture(texture1, AccessFlags.Write); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext ctx) => + { + RTHandle rtHandle = data.textures[0]; + if (rtHandle != null && rtHandle.rt != null) + pass1ResourceID = rtHandle.rt.GetEntityId(); + }); + } + + // Read texture1 to complete its lifetime (this will cause it to be released after this pass) + using (var builder = m_RenderGraph.AddComputePass("Pass1b_ReadTexture1", out var passData)) + { + builder.UseTexture(texture1, AccessFlags.Read); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext ctx) => { }); + } + + // Create texture 2 with same spec (should reuse texture1's resource when intra-frame aliasing is enabled) + var texture2 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = format, enableRandomWrite = true, name = "Texture2" }); + + using (var builder = m_RenderGraph.AddComputePass("Pass2_WriteTexture2", out var passData)) + { + passData.textures[0] = texture2; + builder.UseTexture(texture2, AccessFlags.Write); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, ComputeGraphContext ctx) => + { + RTHandle rtHandle = data.textures[0]; + if (rtHandle != null && rtHandle.rt != null) + pass2ResourceID = rtHandle.rt.GetEntityId(); + }); + } + }; + + m_Camera.Render(); + + // When intra-frame memory aliasing is enabled (default), both textures should share the same underlying RenderTexture + Assert.AreNotEqual(default(EntityId), pass1ResourceID, "Pass 1 resource ID should not be default"); + Assert.AreNotEqual(default(EntityId), pass2ResourceID, "Pass 2 resource ID should not be default"); + Assert.AreEqual(pass1ResourceID, pass2ResourceID, "With intra-frame aliasing enabled, both textures should reuse the same underlying RenderTexture"); + } + + [Test] + public void IntraFrameMemoryAliasing_WhenDisabled_ResourcesCannotBeReusedWithinSameFrame() + { + const int kWidth = 256; + const int kHeight = 256; + + EntityId pass1ResourceID = default; + EntityId pass2ResourceID = default; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + // Disable intra-frame memory aliasing + m_RenderGraph.SetIntraFrameMemoryAliasing(false); + + // Create texture 1, write to it, then read from it so it has a complete lifetime + var texture1 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture1" }); + + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass1_WriteTexture1", out var passData)) + { + passData.textures[0] = texture1; + builder.SetRenderAttachment(texture1, 0, AccessFlags.Write); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => + { + RTHandle rtHandle = data.textures[0]; + if (rtHandle != null && rtHandle.rt != null) + pass1ResourceID = rtHandle.rt.GetEntityId(); + }); + } + + // Read texture1 to complete its lifetime (this will cause it to be released after this pass) + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass1b_ReadTexture1", out var passData)) + { + builder.UseTexture(texture1, AccessFlags.Read); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => { }); + } + + // Create texture 2 with same spec (should NOT reuse texture1's resource when intra-frame aliasing is disabled) + var texture2 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture2" }); + + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass2_WriteTexture2", out var passData)) + { + passData.textures[0] = texture2; + builder.SetRenderAttachment(texture2, 0, AccessFlags.Write); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => + { + RTHandle rtHandle = data.textures[0]; + if (rtHandle != null && rtHandle.rt != null) + pass2ResourceID = rtHandle.rt.GetEntityId(); + }); + } + }; + + m_Camera.Render(); + + // When intra-frame memory aliasing is disabled, both textures should use different underlying RenderTextures + Assert.AreNotEqual(default(EntityId), pass1ResourceID, "Pass 1 resource ID should not be default"); + Assert.AreNotEqual(default(EntityId), pass2ResourceID, "Pass 2 resource ID should not be default"); + Assert.AreNotEqual(pass1ResourceID, pass2ResourceID, "With intra-frame aliasing disabled, both textures should use different underlying RenderTextures"); + } + + [Test] + public void IntraFrameMemoryAliasing_RuntimeToggle_AffectsResourcePooling() + { + const int kWidth = 256; + const int kHeight = 256; + + int executionCount = 0; + EntityId[] capturedResourceIDs = new EntityId[6]; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + int currentExecution = executionCount; + + // Toggle intra-frame memory aliasing based on execution + if (currentExecution == 0) + { + // Start with enabled + m_RenderGraph.SetIntraFrameMemoryAliasing(true); + } + else if (currentExecution == 1) + { + // Switch to disabled for second execution + m_RenderGraph.SetIntraFrameMemoryAliasing(false); + } + else if (currentExecution == 2) + { + // Switch back to enabled for third execution + m_RenderGraph.SetIntraFrameMemoryAliasing(true); + } + + // Create and use two textures with same specs + var texture1 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture1" }); + + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass1", out var passData)) + { + passData.textures[0] = texture1; + builder.SetRenderAttachment(texture1, 0, AccessFlags.Write); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => + { + RTHandle rtHandle = data.textures[0]; + if (rtHandle != null && rtHandle.rt != null) + capturedResourceIDs[currentExecution * 2] = rtHandle.rt.GetEntityId(); + }); + } + + // Read texture1 to complete its lifetime + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass1b_ReadTexture1", out var passData)) + { + builder.UseTexture(texture1, AccessFlags.Read); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => { }); + } + + var texture2 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture2" }); + + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass2", out var passData)) + { + passData.textures[0] = texture2; + builder.SetRenderAttachment(texture2, 0, AccessFlags.Write); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => + { + RTHandle rtHandle = data.textures[0]; + if (rtHandle != null && rtHandle.rt != null) + capturedResourceIDs[currentExecution * 2 + 1] = rtHandle.rt.GetEntityId(); + }); + } + + // Read texture2 to ensure it's not culled + using (var builder = m_RenderGraph.AddRasterRenderPass("Pass3_Read", out var passData)) + { + builder.UseTexture(texture2, AccessFlags.Read); + builder.AllowPassCulling(false); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext ctx) => { }); + } + + executionCount++; + }; + + // Execute 3 times with different settings + m_Camera.Render(); // Execution 0: aliasing enabled + m_Camera.Render(); // Execution 1: aliasing disabled + m_Camera.Render(); // Execution 2: aliasing enabled again + + Assert.AreEqual(3, executionCount, "Should have executed 3 times"); + + // Execution 0: Aliasing enabled - resources should be same + Assert.AreNotEqual(default(EntityId), capturedResourceIDs[0], "Resource 0 ID should not be default"); + Assert.AreNotEqual(default(EntityId), capturedResourceIDs[1], "Resource 1 ID should not be default"); + Assert.AreEqual(capturedResourceIDs[0], capturedResourceIDs[1], "Execution 0: Resources should be aliased when enabled"); + + // Execution 1: Aliasing disabled - resources should be different + Assert.AreNotEqual(default(EntityId), capturedResourceIDs[2], "Resource 2 ID should not be default"); + Assert.AreNotEqual(default(EntityId), capturedResourceIDs[3], "Resource 3 ID should not be default"); + Assert.AreNotEqual(capturedResourceIDs[2], capturedResourceIDs[3], "Execution 1: Resources should NOT be aliased when disabled"); + + // Execution 2: Aliasing enabled again - resources should be same again + Assert.AreNotEqual(default(EntityId), capturedResourceIDs[4], "Resource 4 ID should not be default"); + Assert.AreNotEqual(default(EntityId), capturedResourceIDs[5], "Resource 5 ID should not be default"); + Assert.AreEqual(capturedResourceIDs[4], capturedResourceIDs[5], "Execution 2: Resources should be aliased again when re-enabled"); + } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Documentation~/deep-learning-super-sampling-in-hdrp.md b/Packages/com.unity.render-pipelines.high-definition/Documentation~/deep-learning-super-sampling-in-hdrp.md index 15565a39b90..518e462415f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Documentation~/deep-learning-super-sampling-in-hdrp.md +++ b/Packages/com.unity.render-pipelines.high-definition/Documentation~/deep-learning-super-sampling-in-hdrp.md @@ -84,9 +84,9 @@ Available presets are marked as '1' in the table below. |- |- |- |- |- |- |- |- | | Preset F | | | | 1 | 1 | Marked for deprecation in upcoming DLSS releases. Don't use for new projects. | CNN | | Preset J | 1 | 1 | 1| 1 | 1 | Slightly lowers ghosting but increases flickering.
NVIDIA recommends using **Preset K** instead of **Preset J**. | Transformer | -| Preset K | 1 | 1 | 1| 1 | 1 | Default preset for DLAA/Balanced/Quality modes. Requires fewer resources than Preset L. | Transformer | -| Preset L | | | | 1 | | Delivers a sharper, more stable image with less ghosting than Preset J, K, but lowers performance. Recommended for RTX 40 Series GPUs and above. | Transformer Gen 2 | -Provides about the same image quality as **Preset L**. This preset is slower than presets **J** and **K**, but faster than preset **L**. Recommended for RTX 40 Series GPUs and above. +| Preset K | 1 | 1 | 1| 1 | 1 | Default preset for DLAA/Balanced/Quality modes. Requires fewer resources than **Preset L**. | Transformer | +| Preset L | | | | 1 | | Delivers a sharper, more stable image with less ghosting than **Preset J** and **Preset K**, but lowers performance. Recommended for RTX 40 Series GPUs and above. | Transformer Gen 2 | +| Preset M | | | 1| | | Provides about the same image quality as **Preset L**. This preset is slower than **Preset J** and **Preset K**, but faster than **Preset L**. Recommended for RTX 40 Series GPUs and above. | Transformer Gen 2 | The defaults for each quality mode are: diff --git a/Packages/com.unity.render-pipelines.high-definition/Documentation~/physically-based-sky-volume-override-reference.md b/Packages/com.unity.render-pipelines.high-definition/Documentation~/physically-based-sky-volume-override-reference.md index 6d8937705a2..b5ccacca34e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Documentation~/physically-based-sky-volume-override-reference.md +++ b/Packages/com.unity.render-pipelines.high-definition/Documentation~/physically-based-sky-volume-override-reference.md @@ -18,7 +18,7 @@ The Physically Based Sky’s atmosphere has three types of particles: * Air particles with [Rayleigh scattering](). * Aerosol particles with anisotropic [Mie scattering](https://en.wikipedia.org/wiki/Mie_scattering). You can use aerosols to model pollution, height fog, or mist. -* Ozone particles, which do not contribute to scattering but absorp light. It contributes greatly to the blue color of the sky during twilight. +* Ozone particles, which do not contribute to scattering but absorb light. It contributes greatly to the blue color of the sky during twilight. You can use the Physically Based Sky to simulate the sky during both daytime and night-time. You can change the time of day at runtime without reducing performance. diff --git a/Packages/com.unity.render-pipelines.high-definition/Documentation~/skin-and-diffusive-surfaces-subsurface-scattering.md b/Packages/com.unity.render-pipelines.high-definition/Documentation~/skin-and-diffusive-surfaces-subsurface-scattering.md index b2680f20e4a..71ec8619b7c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Documentation~/skin-and-diffusive-surfaces-subsurface-scattering.md +++ b/Packages/com.unity.render-pipelines.high-definition/Documentation~/skin-and-diffusive-surfaces-subsurface-scattering.md @@ -49,11 +49,11 @@ To add subsurface scattering to a Material: 3. In the Surface Inputs section, select [Diffusion Profile](diffusion-profile-reference.md) and assign a diffusion profile. 4. If a warning box appears below the Diffusion Profile property, select **Fix**. -The following image displays grass in an environment scene. In the left image the grass renders correctly. The grass in the right image has the bright green tint that HDRP applies to a Material that doesn't have a valid diffusion profile: +The following image displays grass in an environment scene. In the left image the grass renders correctly. The grass in the right image has the bright magenta tint that HDRP applies to a Material that doesn't have a valid diffusion profile: ![Grass in an environment scene: In the left image the grass renders correctly. The grass in the right image has the bright green tint that HDRP applies to a Material that doesn't have a valid diffusion profile.](Images/missing_profile.png) -The Material appears bright green in the following cases: +The Material appears bright magenta in the following cases: - The Material doesn't have a diffusion profile assigned. diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Canvas/ShaderGraph/HDCanvasSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Canvas/ShaderGraph/HDCanvasSubTarget.cs index 8b7ee534bc1..e301f798e06 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Canvas/ShaderGraph/HDCanvasSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Canvas/ShaderGraph/HDCanvasSubTarget.cs @@ -37,7 +37,7 @@ public override void Setup(ref TargetSetupContext context) }; protected override IncludeCollection postgraphIncludes => new IncludeCollection { - {kHDCanvasPass, IncludeLocation.Postgraph}, + {kHDCanvasPass, IncludeLocation.Postgraph, true}, }; HDCanvasData m_CanvasData; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs index ac6a03af39b..7db838be8f1 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs @@ -46,6 +46,7 @@ public HDLitData litData protected override string pathtracingInclude => CoreIncludes.kLitPathtracing; protected override FieldDescriptor subShaderField => new FieldDescriptor(kSubShader, "Lit Subshader", ""); protected override string subShaderInclude => CoreIncludes.kLit; + protected override bool subShaderIncludeWithPragmas => true; protected override string customInspector => "Rendering.HighDefinition.LitShaderGraphGUI"; // SubShader features diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs index b6d6f796630..07801f9e284 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs @@ -488,9 +488,9 @@ IncludeCollection GenerateIncludes() } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); if (supportLighting) - includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph, true); else - includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph, true); return includes; } @@ -545,9 +545,9 @@ IncludeCollection GenerateIncludes() } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); if (supportLighting) - includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph, true); else - includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph, true); return includes; } @@ -865,7 +865,7 @@ public static PassDescriptor GenerateLitForward(bool useVFX, bool useTessellatio { CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph }, { CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, - { CoreIncludes.kPassForward, IncludeLocation.Postgraph }, + { CoreIncludes.kPassForward, IncludeLocation.Postgraph, true }, }; #endregion diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs index 64bb92c72ea..baa5f97e74a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs @@ -62,6 +62,7 @@ public SystemData systemData protected virtual string pathtracingInclude => null; protected virtual bool supportPathtracing => false; protected virtual bool supportRaytracing => false; + protected virtual bool subShaderIncludeWithPragmas => false; protected virtual string[] sharedTemplatePath => new string[]{ $"{HDUtils.GetHDRenderPipelinePath()}Editor/Material/ShaderGraph/Templates/", $"{HDUtils.GetVFXPath()}/Editor/ShaderGraph/Templates" @@ -171,9 +172,13 @@ protected SubShaderDescriptor PostProcessSubShader(SubShaderDescriptor subShader foreach (var include in passDescriptor.includes) { var path = include.path; + bool shouldIncludeWithPragmas = include.shouldIncludeWithPragmas; if (path == CoreIncludes.kPassPlaceholder) + { path = subShaderInclude; + shouldIncludeWithPragmas = subShaderIncludeWithPragmas; + } if (path == CoreIncludes.kPostDecalsPlaceholder) path = postDecalsInclude; if (path == CoreIncludes.kRaytracingPlaceholder) @@ -182,7 +187,7 @@ protected SubShaderDescriptor PostProcessSubShader(SubShaderDescriptor subShader path = pathtracingInclude; if (!String.IsNullOrEmpty(path)) - finalIncludes.Add(path, include.location, include.fieldConditions); + finalIncludes.Add(path, include.location, include.fieldConditions, shouldIncludeWithPragmas); } passDescriptor.includes = finalIncludes; @@ -253,9 +258,13 @@ protected KernelDescriptor PostProcessKernel(KernelDescriptor kernel) foreach (var include in passDescriptor.includes) { var path = include.path; + bool shouldIncludeWithPragmas = include.shouldIncludeWithPragmas; if (path == CoreIncludes.kPassPlaceholder) + { path = subShaderInclude; + shouldIncludeWithPragmas = subShaderIncludeWithPragmas; + } if (path == CoreIncludes.kPostDecalsPlaceholder) path = postDecalsInclude; if (path == CoreIncludes.kRaytracingPlaceholder) @@ -264,7 +273,7 @@ protected KernelDescriptor PostProcessKernel(KernelDescriptor kernel) path = pathtracingInclude; if (!String.IsNullOrEmpty(path)) - finalIncludes.Add(path, include.location, include.fieldConditions); + finalIncludes.Add(path, include.location, include.fieldConditions, shouldIncludeWithPragmas); } passDescriptor.includes = finalIncludes; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/SixWayLit/ShaderGraph/HDSixWaySubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/SixWayLit/ShaderGraph/HDSixWaySubTarget.cs index adb49b3aaec..baba564f024 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/SixWayLit/ShaderGraph/HDSixWaySubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/SixWayLit/ShaderGraph/HDSixWaySubTarget.cs @@ -104,7 +104,7 @@ IncludeCollection GenerateIncludes() includes.Add(CoreIncludes.CoreUtility); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); - includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph, true); return includes; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/ShaderGraph/TerrainLitSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/ShaderGraph/TerrainLitSubTarget.cs index a569ae0bfbb..5175230dcaf 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/ShaderGraph/TerrainLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/ShaderGraph/TerrainLitSubTarget.cs @@ -29,6 +29,7 @@ sealed partial class TerrainLitSubTarget : LightingSubTarget, IRequiresData ShaderGraphAPI.ValidateTerrain; protected override FieldDescriptor subShaderField => new FieldDescriptor(kSubShader, "TerrainLit SubShader", ""); protected override string subShaderInclude => CoreIncludes.kTerrainLit; + protected override bool subShaderIncludeWithPragmas => true; protected override string postDecalsInclude => "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl"; protected override string raytracingInclude => CoreIncludes.kTerrainRaytracing; @@ -647,7 +648,7 @@ static class TerrainIncludes { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, { TerrainIncludes.kTerrainLitSurfaceData, IncludeLocation.Pregraph }, { TerrainIncludes.kSplatmap, IncludeLocation.Pregraph }, - { CoreIncludes.kPassForward, IncludeLocation.Postgraph }, + { CoreIncludes.kPassForward, IncludeLocation.Postgraph, true }, }; #endregion @@ -997,9 +998,9 @@ IncludeCollection GenerateIncludes() includes.Add(TerrainIncludes.kTerrainLitSurfaceData, IncludeLocation.Pregraph); includes.Add(TerrainIncludes.kSplatmap, IncludeLocation.Pregraph); if (supportLighting) - includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph, true); else - includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph); + includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph, true); return includes; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitSubTarget.cs index f69ece9b98a..4fd87e47753 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitSubTarget.cs @@ -28,6 +28,7 @@ sealed partial class HDUnlitSubTarget : SurfaceSubTarget, IRequiresData new FieldDescriptor(kSubShader, "Unlit SubShader", ""); protected override string raytracingInclude => CoreIncludes.kUnlitRaytracing; protected override string subShaderInclude => CoreIncludes.kUnlit; + protected override bool subShaderIncludeWithPragmas => true; protected override bool supportDistortion => true; protected override bool supportForward => true; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/CustomPassRenderersShader.template b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/CustomPassRenderersShader.template index aedd36d7d7b..7fb0295a202 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/CustomPassRenderersShader.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/CustomPassRenderersShader.template @@ -102,7 +102,7 @@ CBUFFER_END surfaceData.color = color; } - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForwardUnlit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForwardUnlit.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/LineRendering/HDShaderPasses.LineRendering.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/LineRendering/HDShaderPasses.LineRendering.cs index 08bb03c6497..6ac164aef7b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/LineRendering/HDShaderPasses.LineRendering.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/LineRendering/HDShaderPasses.LineRendering.cs @@ -87,9 +87,9 @@ IncludeCollection GenerateIncludes() includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); if (supportLighting) - includes.Add(kPassForward, IncludeLocation.Postgraph); + includes.Add(kPassForward, IncludeLocation.Postgraph, true); else - includes.Add(kPassForwardUnlit, IncludeLocation.Postgraph); + includes.Add(kPassForwardUnlit, IncludeLocation.Postgraph, true); return includes; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLit.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLit.template index 899f7275606..5d94b74c5ae 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLit.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLit.template @@ -1,4 +1,4 @@ -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLit.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLit.hlsl" #ifndef VFX_SHADERGRAPH diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewMaterialGBuffer.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewMaterialGBuffer.shader index fcdfc6cc4f5..fdb5a77d473 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewMaterialGBuffer.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewMaterialGBuffer.shader @@ -28,7 +28,7 @@ Shader "Hidden/HDRP/DebugViewMaterialGBuffer" // Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new // deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem), // the deferred shader will require to use multicompile. - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" struct Attributes { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewTiles.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewTiles.shader index b35b92900d9..206a3fdb44f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewTiles.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugViewTiles.shader @@ -38,7 +38,7 @@ Shader "Hidden/HDRP/DebugViewTiles" // Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new // deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem), // the deferred shader will require to use multicompile. - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" //------------------------------------------------------------------------------------- // variable declaration diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.LightLoop.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.LightLoop.cs index 64dc5fbacb1..dd78d84f97f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.LightLoop.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.LightLoop.cs @@ -600,6 +600,7 @@ internal unsafe void UpdateShadowRequestsAndCalculateShadowIndices( ref HDShadowRequest shadowRequest = ref requestStorageUnsafe.ElementAt(shadowRequestHandle.storageIndexForRequestIndex); int additionalLightDataIndex = directionalUpdateInfo.additionalLightDataIndex; int lightIndex = directionalUpdateInfo.lightIndex; + int dataIndex = visibleLights.visibleLightEntityDataIndices[lightIndex]; Vector2 viewportSize = directionalUpdateInfo.viewportSize; VisibleLight* visibleLightPtr = visibleLightsArrayPtr + lightIndex; ref VisibleLight visibleLight = ref UnsafeUtility.AsRef(visibleLightPtr); @@ -619,7 +620,7 @@ internal unsafe void UpdateShadowRequestsAndCalculateShadowIndices( SetDirectionalRequestSettings(ref shadowRequest, shadowRequestHandle, visibleLight, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, shadowRequest.cullingSplit.deviceProjectionMatrix, viewportSize, - lightIndex, directionalShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, dataIndex, directionalShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); shadowRequest.shouldUseCachedShadowData = false; shadowRequest.shouldRenderCachedComponent = true; @@ -640,7 +641,6 @@ internal unsafe void UpdateShadowRequestsAndCalculateShadowIndices( shadowRequest.cullingSplit.deviceProjectionYFlip = _ProjMatrix; } - int dataIndex = visibleLights.visibleLightEntityDataIndices[lightIndex]; HDAdditionalLightData additionalLightData = lightEntities.hdAdditionalLightData[dataIndex]; if (needToUpdateCachedContent && hdCamera.camera.cameraType != CameraType.Reflection) { @@ -669,7 +669,7 @@ internal unsafe void UpdateShadowRequestsAndCalculateShadowIndices( SetDirectionalRequestSettings(ref shadowRequest, shadowRequestHandle, visibleLight, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, shadowRequest.cullingSplit.deviceProjectionMatrix, viewportSize, - lightIndex, directionalShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, directionalShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } @@ -786,7 +786,7 @@ internal static unsafe void UpdateCachedSpotShadowRequestsAndResolutionRequests( SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight, 0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, shadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, shadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); hasUpdatedRequestData = true; shadowRequest.shouldUseCachedShadowData = false; @@ -812,7 +812,7 @@ internal static unsafe void UpdateCachedSpotShadowRequestsAndResolutionRequests( SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight, 0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, shadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, shadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } } @@ -853,7 +853,7 @@ internal static unsafe void UpdateDynamicSpotShadowRequestsAndResolutionRequests SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight, 0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, shadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, shadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } } @@ -958,7 +958,7 @@ internal static Vector3 GetPositionFromVisibleLight(in VisibleLight visibleLight [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetDirectionalRequestSettings(ref HDShadowRequest shadowRequest, HDShadowRequestHandle shadowRequestHandle, in VisibleLight visibleLight, Vector3 cameraPos, - Matrix4x4 invViewProjection, in Matrix4x4 projection, in Matrix4x4 devProjMatrix, Vector2 viewportSize, int lightIndex, HDShadowFilteringQuality filteringQuality, + Matrix4x4 invViewProjection, in Matrix4x4 projection, in Matrix4x4 devProjMatrix, Vector2 viewportSize, int lightIndex, int dataIndex, HDShadowFilteringQuality filteringQuality, in HDAdditionalLightDataUpdateInfo additionalLightData, int shaderConfigCameraRelativeRendering, NativeList frustumPlanesStorage) { MakeViewAndViewProjectionCameraRelative(ref shadowRequest, ref invViewProjection, shaderConfigCameraRelativeRendering, cameraPos); @@ -972,7 +972,7 @@ internal static void SetDirectionalRequestSettings(ref HDShadowRequest shadowReq float baseBias = GetBaseBias(filteringQuality == HDShadowFilteringQuality.High, 0.0f); SetCommonShadowRequestSettings(ref shadowRequest, shadowRequestHandle, cameraPos, invViewProjection, projection, - viewportSize, lightIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, + viewportSize, lightIndex, dataIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, ShadowMapType.CascadedDirectional, zBufferParam, softnessAndRangeScale.x, position, baseBias, true, false); @@ -1004,7 +1004,7 @@ internal static void SetDirectionalRequestSettings(ref HDShadowRequest shadowReq [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetAreaRequestSettings(ref HDShadowRequest shadowRequest, HDShadowRequestHandle shadowRequestHandle, in VisibleLight visibleLight, float forwardOffset, - Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, + Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, int dataIndex, HDAreaShadowFilteringQuality areaFilteringQuality, in HDAdditionalLightDataUpdateInfo additionalLightData, int shaderConfigCameraRelativeRendering, NativeList frustumPlanesStorage) @@ -1019,7 +1019,7 @@ internal static void SetAreaRequestSettings(ref HDShadowRequest shadowRequest, float baseBias = GetBaseBias(areaFilteringQuality == HDAreaShadowFilteringQuality.High, softness); SetCommonShadowRequestSettings(ref shadowRequest, shadowRequestHandle, cameraPos, invViewProjection, projection, - viewportSize, lightIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, + viewportSize, lightIndex, dataIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, ShadowMapType.AreaLightAtlas, zBufferParam, softness, position, baseBias, false, true); @@ -1035,7 +1035,7 @@ internal static void SetAreaRequestSettings(ref HDShadowRequest shadowRequest, [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetSpotRequestSettings(ref HDShadowRequest shadowRequest, HDShadowRequestHandle shadowRequestHandle, in VisibleLight visibleLight, float forwardOffset, - Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, + Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, int dataIndex, HDShadowFilteringQuality filteringQuality, in HDAdditionalLightDataUpdateInfo additionalLightData, int shaderConfigCameraRelativeRendering, NativeList frustumPlanesStorage) @@ -1060,7 +1060,7 @@ internal static void SetSpotRequestSettings(ref HDShadowRequest shadowRequest, float baseBias = GetBaseBias(filteringQuality == HDShadowFilteringQuality.High, softness); SetCommonShadowRequestSettings(ref shadowRequest, shadowRequestHandle, cameraPos, invViewProjection, projection, - viewportSize, lightIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, + viewportSize, lightIndex, dataIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, ShadowMapType.PunctualAtlas, zBufferParam, softness, position, baseBias, hasOrthoMatrix, true); } @@ -1068,7 +1068,7 @@ internal static void SetSpotRequestSettings(ref HDShadowRequest shadowRequest, [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetPointRequestSettings(ref HDShadowRequest shadowRequest, HDShadowRequestHandle shadowRequestHandle, in VisibleLight visibleLight, - Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, + Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, int dataIndex, HDShadowFilteringQuality filteringQuality, in HDAdditionalLightDataUpdateInfo additionalLightData, int shaderConfigCameraRelativeRendering, NativeList frustumPlanesStorage) @@ -1082,14 +1082,14 @@ internal static void SetPointRequestSettings(ref HDShadowRequest shadowRequest, float baseBias = GetBaseBias(filteringQuality == HDShadowFilteringQuality.High, softness); SetCommonShadowRequestSettings(ref shadowRequest, shadowRequestHandle, cameraPos, invViewProjection, projection, - viewportSize, lightIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, + viewportSize, lightIndex, dataIndex, additionalLightData, shaderConfigCameraRelativeRendering, frustumPlanesStorage, ShadowMapType.PunctualAtlas, zBufferParam, softness, position, baseBias, false, true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void SetCommonShadowRequestSettings(ref HDShadowRequest shadowRequest, - HDShadowRequestHandle shadowRequestHandle, Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, + HDShadowRequestHandle shadowRequestHandle, Vector3 cameraPos, Matrix4x4 invViewProjection, Matrix4x4 projection, Vector2 viewportSize, int lightIndex, int dataIndex, in HDAdditionalLightDataUpdateInfo additionalLightData, int shaderConfigCameraRelativeRendering, NativeList frustumPlanesStorage, ShadowMapType shadowMapType, float4 zBufferParam, float softness, Vector3 position, float baseBias, bool hasOrthoMatrix, bool zClip) { @@ -1102,6 +1102,7 @@ internal static void SetCommonShadowRequestSettings(ref HDShadowRequest shadowRe shadowRequest.shadowToWorld = invViewProjection.transpose; shadowRequest.zClip = zClip; shadowRequest.lightIndex = lightIndex; + shadowRequest.dataIndex = dataIndex; // We don't allow shadow resize for directional cascade shadow shadowRequest.shadowMapType = shadowMapType; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDShadowRequestUpdateJob.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDShadowRequestUpdateJob.cs index b0321d3ea32..4650b79af5d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDShadowRequestUpdateJob.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDShadowRequestUpdateJob.cs @@ -323,7 +323,7 @@ public void UpdateCachedPointShadowRequestsAndResolutionRequests() HDGpuLightsBuilder.SetPointRequestSettings(ref shadowRequest, shadowRequestHandle, in pointUpdateInfo.visibleLight, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); hasUpdatedRequestData = true; shadowRequest.shouldUseCachedShadowData = false; @@ -344,7 +344,7 @@ public void UpdateCachedPointShadowRequestsAndResolutionRequests() HDGpuLightsBuilder.SetPointRequestSettings(ref shadowRequest, shadowRequestHandle, in pointUpdateInfo.visibleLight, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } } @@ -370,7 +370,7 @@ public void UpdateDynamicPointShadowRequestsAndResolutionRequests() HDGpuLightsBuilder.SetPointRequestSettings(ref shadowRequest, shadowRequestHandle, in pointUpdateInfo.visibleLight, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } @@ -407,7 +407,7 @@ public void UpdateCachedSpotShadowRequestsAndResolutionRequests() HDGpuLightsBuilder.SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight, 0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); hasUpdatedRequestData = true; shadowRequest.shouldUseCachedShadowData = false; @@ -428,7 +428,7 @@ public void UpdateCachedSpotShadowRequestsAndResolutionRequests() HDGpuLightsBuilder.SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight, 0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } } @@ -454,7 +454,7 @@ public void UpdateDynamicSpotShadowRequestsAndResolutionRequests() HDGpuLightsBuilder.SetSpotRequestSettings(ref shadowRequest, shadowRequestHandle, spotUpdateInfo.visibleLight, 0f, worldSpaceCameraPos, shadowRequest.cullingSplit.invViewProjection, shadowRequest.cullingSplit.projection, viewportSize, - lightIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); + lightIndex, additionalLightDataIndex, punctualShadowFilteringQuality, updateInfo, shaderConfigCameraRelativeRendering, frustumPlanesStorage); } } @@ -487,7 +487,7 @@ public void UpdateCachedAreaShadowRequestsAndResolutionRequests(NativeList visibleLightEntityDataIndices; } private void SetCommonRenderPassData(RenderShadowMapsCommonPassData passData, in IUnsafeRenderGraphBuilder builder, RenderGraph renderGraph, in ShaderVariablesGlobal globalCBData) @@ -429,7 +430,10 @@ private static void ResetDepthState(CommandBuffer cmd) } public static Vector4[] frustumPlanesScratchpad = new Vector4[HDShadowRequest.frustumPlanesCount]; - internal unsafe TextureHandle RenderShadowMaps(RenderGraph renderGraph, ScriptableRenderContext renderContext, CullingResults cullResults, in ShaderVariablesGlobal globalCBData, FrameSettings frameSettings, string shadowPassName) + internal unsafe TextureHandle RenderShadowMaps( + RenderGraph renderGraph, ScriptableRenderContext renderContext, + CullingResults cullResults, NativeArray visibleLightEntityDataIndices, + in ShaderVariablesGlobal globalCBData, FrameSettings frameSettings, string shadowPassName) { TextureHandle atlasTexture; @@ -442,6 +446,7 @@ internal unsafe TextureHandle RenderShadowMaps(RenderGraph renderGraph, Scriptab passData.shadowDrawSettings = new ShadowDrawingSettings(cullResults, 0); passData.shadowDrawSettings.useRenderingLayerMaskTest = frameSettings.IsEnabled(FrameSettingsField.LightLayers); passData.renderContext = renderContext; + passData.visibleLightEntityDataIndices = visibleLightEntityDataIndices; builder.SetRenderFunc( static (RenderShadowMapsPassData data, UnsafeGraphContext ctx) => @@ -460,9 +465,27 @@ internal unsafe TextureHandle RenderShadowMaps(RenderGraph renderGraph, Scriptab Vector4[] planesScratchpad = frustumPlanesScratchpad; + var cullResults = data.shadowDrawSettings.cullingResults; + var visibleLightCount = cullResults.visibleLights.Length; + // Build mapping from stable dataIndex to current light index. + // Allocated per-pass (not shared) to remain RenderGraph-compliant and avoid + // implicit dependencies if the execution model changes. + var dataIndexToCurrentLightIndex = new NativeHashMap(visibleLightCount, Allocator.Temp); + + for (int i = 0; i < visibleLightCount; ++i) + { + int dataIndex = data.visibleLightEntityDataIndices[i]; + if (dataIndex >= 0) + dataIndexToCurrentLightIndex[dataIndex] = i; + } + foreach (var shadowRequestHandle in data.shadowRequests) { ref var shadowRequest = ref requestStorageUnsafe.ElementAt(shadowRequestHandle.storageIndexForShadowRequest); + + if (!dataIndexToCurrentLightIndex.TryGetValue(shadowRequest.dataIndex, out int currentCorrectIndex)) + continue; + var commonState = CommonPerShadowRequestUpdate(natCmd, data, shadowRequest, shadowRequestHandle, ref planesScratchpad, ref frustumPlanesStorageUnsafe); if (commonState.shouldSkipRequest) continue; @@ -482,7 +505,7 @@ internal unsafe TextureHandle RenderShadowMaps(RenderGraph renderGraph, Scriptab if (!commonState.mixedInDynamicAtlas) CoreUtils.DrawFullScreen(natCmd, data.clearMaterial, null, 0); - data.shadowDrawSettings.lightIndex = shadowRequest.lightIndex; + data.shadowDrawSettings.lightIndex = currentCorrectIndex; data.shadowDrawSettings.splitIndex = shadowRequest.cullingSplit.splitIndex; //TODO(ddebaets) as the shadowDrawSettings are modified in this loop, we generate this RL very last minute @@ -491,6 +514,8 @@ internal unsafe TextureHandle RenderShadowMaps(RenderGraph renderGraph, Scriptab natCmd.DrawRendererList(rl); } + dataIndexToCurrentLightIndex.Dispose(); + ResetDepthState(natCmd); }); @@ -739,14 +764,17 @@ internal TextureHandle BlurShadows(RenderGraph renderGraph) return m_ShadowMapOutput; } } - internal TextureHandle RenderShadows(RenderGraph renderGraph, ScriptableRenderContext renderContext, CullingResults cullResults, in ShaderVariablesGlobal globalCB, FrameSettings frameSettings, string shadowPassName) + internal TextureHandle RenderShadows( + RenderGraph renderGraph, ScriptableRenderContext renderContext, + CullingResults cullResults, NativeArray visibleLightEntityDataIndices, + in ShaderVariablesGlobal globalCB, FrameSettings frameSettings, string shadowPassName) { if (m_ShadowRequests.Length == 0) { return renderGraph.defaultResources.defaultShadowTexture; } - RenderShadowMaps(renderGraph, renderContext, cullResults, globalCB, frameSettings, shadowPassName); + RenderShadowMaps(renderGraph, renderContext, cullResults, visibleLightEntityDataIndices, globalCB, frameSettings, shadowPassName); if (m_BlurAlgorithm == BlurAlgorithm.EVSM) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs index f10a5d64f70..f78e7a7ec41 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs @@ -195,6 +195,7 @@ internal struct HDShadowRequest // TODO: Remove these field once scriptable culling is here (currently required by ScriptableRenderContext.DrawShadows) public int lightIndex; + public int dataIndex; // end public float normalBias; @@ -298,6 +299,7 @@ public void InitDefault() zClip = default; shadowMapType = ShadowMapType.PunctualAtlas; lightIndex = default; + dataIndex = HDLightRenderDatabase.InvalidDataIndex; normalBias = default; worldTexelSize = default; slopeBias = default; @@ -1226,7 +1228,7 @@ public int GetShadowRequestCount() { return m_ShadowRequestCount; } - + internal void GetUnmanageDataForComputeCullingSplitsJob(ref HDShadowManagerDataForComputeCullingSplitsJob shadowManagerData) { shadowManagerData.requestCount = GetShadowRequestCount(); @@ -1373,7 +1375,11 @@ internal static ShadowResult ReadShadowResult(in ShadowResult shadowResult, IUns return result; } - internal void RenderShadows(RenderGraph renderGraph, ScriptableRenderContext renderContext, in ShaderVariablesGlobal globalCB, HDCamera hdCamera, CullingResults cullResults, ref ShadowResult result) + internal void RenderShadows( + RenderGraph renderGraph, ScriptableRenderContext renderContext, + in ShaderVariablesGlobal globalCB, HDCamera hdCamera, + CullingResults cullResults, NativeArray visibleLightEntityIndices, + ref ShadowResult result) { InvalidateAtlasOutputs(); @@ -1382,15 +1388,15 @@ internal void RenderShadows(RenderGraph renderGraph, ScriptableRenderContext ren (hdCamera.frameSettings.IsEnabled(FrameSettingsField.OpaqueObjects) || hdCamera.frameSettings.IsEnabled(FrameSettingsField.TransparentObjects))) { // Punctual - result.cachedPunctualShadowResult = cachedShadowManager.punctualShadowAtlas.RenderShadows(renderGraph, renderContext, cullResults, globalCB, hdCamera.frameSettings, "Render Cached Punctual Lights Shadow Maps"); + result.cachedPunctualShadowResult = cachedShadowManager.punctualShadowAtlas.RenderShadows(renderGraph, renderContext, cullResults, visibleLightEntityIndices, globalCB, hdCamera.frameSettings, "Render Cached Punctual Lights Shadow Maps"); BlitCachedShadows(renderGraph, ShadowMapType.PunctualAtlas); - result.punctualShadowResult = m_Atlas.RenderShadows(renderGraph, renderContext, cullResults, globalCB, hdCamera.frameSettings, "Render Punctual Lights Shadow Maps"); + result.punctualShadowResult = m_Atlas.RenderShadows(renderGraph, renderContext, cullResults, visibleLightEntityIndices, globalCB, hdCamera.frameSettings, "Render Punctual Lights Shadow Maps"); if (ShaderConfig.s_AreaLights == 1) { - cachedShadowManager.areaShadowAtlas.RenderShadowMaps(renderGraph, renderContext, cullResults, globalCB, hdCamera.frameSettings, "Render Cached Area Lights Shadow Maps"); + cachedShadowManager.areaShadowAtlas.RenderShadowMaps(renderGraph, renderContext, cullResults, visibleLightEntityIndices, globalCB, hdCamera.frameSettings, "Render Cached Area Lights Shadow Maps"); BlitCachedShadows(renderGraph, ShadowMapType.AreaLightAtlas); - m_AreaLightShadowAtlas.RenderShadowMaps(renderGraph, renderContext, cullResults, globalCB, hdCamera.frameSettings, "Render Area Light Shadow Maps"); + m_AreaLightShadowAtlas.RenderShadowMaps(renderGraph, renderContext, cullResults, visibleLightEntityIndices, globalCB, hdCamera.frameSettings, "Render Area Light Shadow Maps"); result.areaShadowResult = m_AreaLightShadowAtlas.BlurShadows(renderGraph); result.cachedAreaShadowResult = cachedShadowManager.areaShadowAtlas.BlurShadows(renderGraph); } @@ -1401,11 +1407,11 @@ internal void RenderShadows(RenderGraph renderGraph, ScriptableRenderContext ren if (cachedShadowManager.directionalLightAtlas.HasShadowRequests()) { cachedShadowManager.UpdateDirectionalCacheTexture(renderGraph); - cachedShadowManager.directionalLightAtlas.RenderShadows(renderGraph, renderContext, cullResults, globalCB, hdCamera.frameSettings, "Render Cached Directional Lights Shadow Maps"); + cachedShadowManager.directionalLightAtlas.RenderShadows(renderGraph, renderContext, cullResults, visibleLightEntityIndices, globalCB, hdCamera.frameSettings, "Render Cached Directional Lights Shadow Maps"); } BlitCachedShadows(renderGraph, ShadowMapType.CascadedDirectional); } - result.directionalShadowResult = m_CascadeAtlas.RenderShadows(renderGraph, renderContext, cullResults, globalCB, hdCamera.frameSettings, "Render Directional Light Shadow Maps"); + result.directionalShadowResult = m_CascadeAtlas.RenderShadows(renderGraph, renderContext, cullResults, visibleLightEntityIndices, globalCB, hdCamera.frameSettings, "Render Directional Light Shadow Maps"); } // TODO RENDERGRAPH diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader index f73538de569..3c17e22f06c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader @@ -558,7 +558,7 @@ Shader "HDRP/AxF" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/ShaderPass/AxFSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl index e193e59e2c1..5485af4a840 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl @@ -78,6 +78,7 @@ void InitBuiltinData(PositionInputs posInput, float alpha, float3 normalWS, floa #if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) // If we are using APV with mixed lighting on a probe-lit renderer, occlusion is stored in APV. float3 unusedDiffuseLighting; + float3 unusedBackDiffuseLighting; EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), normalWS, backNormalWS, @@ -85,7 +86,7 @@ void InitBuiltinData(PositionInputs posInput, float alpha, float3 normalWS, floa posInput.positionSS, builtinData.renderingLayers, unusedDiffuseLighting, - unusedDiffuseLighting, + unusedBackDiffuseLighting, shadowMask); #else // Otherwise occlusion is stored in shadowmask texture, or in unity_ProbesOcclusion for renderers lit by legacy probes. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl index ce526019b65..6128b055555 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl @@ -154,12 +154,7 @@ PackedVaryings vert(Attributes input) #ifdef UNITY_VIRTUAL_TEXTURING #define VT_BUFFER_TARGET SV_Target1 #define EXTRA_BUFFER_TARGET SV_Target2 -#if defined(SHADER_API_PSSL) -//For exact packing on pssl, we want to write exact 16 bit unorm (respect exact bit packing). -//In some sony platforms, the default is FMT_16_ABGR, which would incur in loss of precision. -//Thus, when VT is enabled, we force FMT_32_ABGR -#pragma PSSL_target_output_format(target 1 FMT_32_ABGR) -#endif +#pragma rendertarget_format_hint MRT1 R16G16_UNorm #else #define EXTRA_BUFFER_TARGET SV_Target1 #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader index c732a87acba..02d13cb6502 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader @@ -747,7 +747,7 @@ Shader "HDRP/LayeredLit" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" #endif #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassGBuffer.hlsl" @@ -1166,7 +1166,7 @@ Shader "HDRP/LayeredLit" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader index 67504f64e6e..c85de9fbce4 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader @@ -788,7 +788,7 @@ Shader "HDRP/LayeredLitTessellation" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" #endif #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl" @@ -1220,7 +1220,7 @@ Shader "HDRP/LayeredLitTessellation" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl index fb73c092f7a..37f49b3bf75 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl @@ -60,12 +60,7 @@ TEXTURE2D_X(_ShadowMaskTexture); // Alias for shadow mask, so we don't need to k #define OUT_GBUFFER_OPTIONAL_SLOT_1 outGBuffer5 #define OUT_GBUFFER_OPTIONAL_SLOT_2 outGBuffer6 #if (SHADERPASS == SHADERPASS_GBUFFER) - #if defined(SHADER_API_PSSL) - //For exact packing on pssl, we want to write exact 16 bit unorm (respect exact bit packing). - //In some sony platforms, the default is FMT_16_ABGR, which would incur in loss of precision. - //Thus, when VT is enabled, we force FMT_32_ABGR - #pragma PSSL_target_output_format(target 4 FMT_32_ABGR) - #endif + #pragma rendertarget_format_hint MRT4 R16G16_UNorm #endif #else #define OUT_GBUFFER_OPTIONAL_SLOT_1 outGBuffer4 @@ -1789,7 +1784,7 @@ IndirectLighting EvaluateBSDF_ScreenSpaceReflection(PositionInputs posInput, // // Note that the SSR with clear coat is a binary state, which means we should never enter the if condition if we don't have an active // clear coat (which is not guaranteed by the HasFlag condition in deferred mode in some cases). We then need to make sure that coatMask is actually non zero. - if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && bsdfData.coatMask >= 0.0) + if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) && bsdfData.coatMask > 0.0) { // We use the coat-traced light according to how similar the base lobe roughness is to the coat roughness // (we can assume the coat is always smoother): diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader index a1d73f1f002..ebf4e70de54 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader @@ -512,7 +512,7 @@ Shader "HDRP/Lit" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" #endif #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" @@ -940,7 +940,7 @@ Shader "HDRP/Lit" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag @@ -1078,7 +1078,7 @@ Shader "HDRP/Lit" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader index c8c56fd60e0..7abeeb63436 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader @@ -529,7 +529,7 @@ Shader "HDRP/LitTessellation" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" #endif #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" @@ -968,7 +968,7 @@ Shader "HDRP/LitTessellation" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag @@ -1102,7 +1102,7 @@ Shader "HDRP/LitTessellation" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.hlsl index c7ed157b6f8..7174222d364 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.hlsl @@ -9,4 +9,4 @@ #endif #endif -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader index bdb2892316f..f880f68cb7d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader @@ -144,7 +144,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile_fragment _ RENDERING_LAYERS #define SHADERPASS SHADERPASS_GBUFFER - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl" ENDHLSL @@ -175,7 +175,7 @@ Shader "HDRP/TerrainLit" #define SHADERPASS SHADERPASS_LIGHT_TRANSPORT #pragma shader_feature EDITOR_VISUALIZATION - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl" ENDHLSL @@ -205,7 +205,7 @@ Shader "HDRP/TerrainLit" #pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap #define SHADERPASS SHADERPASS_SHADOWS - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl" ENDHLSL @@ -246,7 +246,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile _ WRITE_MSAA_DEPTH #define SHADERPASS SHADERPASS_DEPTH_ONLY - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #ifdef WRITE_NORMAL_BUFFER #if defined(_NORMALMAP) #define OVERRIDE_SPLAT_SAMPLER_NAME sampler_Normal0 @@ -307,7 +307,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST #define SHADERPASS SHADERPASS_FORWARD - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl" ENDHLSL @@ -333,7 +333,7 @@ Shader "HDRP/TerrainLit" #pragma editor_sync_compilation #define SHADERPASS SHADERPASS_DEPTH_ONLY #define SCENESELECTIONPASS - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl" ENDHLSL diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl index ee3374bc52a..a3b874cc747 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl @@ -47,7 +47,7 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl" #else - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" #endif #if defined(WRITE_DECAL_BUFFER) || (defined(WRITE_RENDERING_LAYER) && !defined(_DISABLE_DECALS)) @@ -97,5 +97,5 @@ #elif SHADERPASS == SHADERPASS_SHADOWS || SHADERPASS == SHADERPASS_DEPTH_ONLY #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl" #elif SHADERPASS == SHADERPASS_FORWARD -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" +#include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForward.hlsl" #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader index 04e6633db21..dd658a2cc9a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader @@ -99,7 +99,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile_fragment _ RENDERING_LAYERS #define SHADERPASS SHADERPASS_GBUFFER - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.hlsl" ENDHLSL @@ -127,7 +127,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" // both direct and indirect lighting) will hand up in the "regular" lightmap->LIGHTMAP_ON. #define SHADERPASS SHADERPASS_LIGHT_TRANSPORT - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.hlsl" ENDHLSL @@ -155,7 +155,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma fragment Frag #define SHADERPASS SHADERPASS_SHADOWS - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.hlsl" ENDHLSL @@ -194,7 +194,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile _ WRITE_MSAA_DEPTH #define SHADERPASS SHADERPASS_DEPTH_ONLY - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.hlsl" ENDHLSL @@ -245,7 +245,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST #define SHADERPASS SHADERPASS_FORWARD - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.hlsl" ENDHLSL diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader index 59fcfa7761e..c06b3e7ad95 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader @@ -309,7 +309,7 @@ Shader "HDRP/Unlit" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/ShaderPass/UnlitSharePass.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/UnlitData.hlsl" - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForwardUnlit.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassForwardUnlit.hlsl" #pragma vertex Vert #pragma fragment Frag diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/MotionBlurMergeTilePass.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/MotionBlurMergeTilePass.compute index bf92d87e716..5d0afff6e70 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/MotionBlurMergeTilePass.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/MotionBlurMergeTilePass.compute @@ -25,7 +25,7 @@ void TileMerge(uint3 dispatchID : SV_DispatchThreadID) if (maxVelLen > TILE_SIZE*0.5f) { int tileCount = maxVelLen / TILE_SIZE; - if (tileCount > 4) tileCount = 4; + tileCount = clamp(tileCount, 1, 4); minVel = 999999.0f; // This is sub-optimal, but the texture is tiny and should be fairly cache efficient. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 05051fd4977..e2d1e2716d9 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -481,7 +481,7 @@ unsafe void PrepareBuildGPULightListPassData( passData.clearLightLists = true; tileAndClusterData.listsAreInitialized = true; } - + // Always build the light list in XR mode to avoid issues with multi-pass if (hdCamera.xr.enabled) { @@ -721,7 +721,7 @@ void PushGlobalCameraParams(RenderGraph renderGraph, HDCamera hdCamera) internal ShadowResult RenderShadows(RenderGraph renderGraph, ScriptableRenderContext renderContext, HDCamera hdCamera, CullingResults cullResults, ref ShadowResult result) { - m_ShadowManager.RenderShadows(m_RenderGraph, renderContext, m_ShaderVariablesGlobalCB, hdCamera, cullResults, ref result); + m_ShadowManager.RenderShadows(m_RenderGraph, renderContext, m_ShaderVariablesGlobalCB, hdCamera, cullResults, m_ProcessedLightsBuilder.visibleLightEntityDataIndices, ref result); // Need to restore global camera parameters. PushGlobalCameraParams(renderGraph, hdCamera); return result; 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 93cf4ef4cc3..c8cd9eab3b6 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 @@ -425,23 +425,26 @@ void BeginPostProcessFrame(CommandBuffer cmd, HDCamera camera, HDRenderPipeline int ComputeLUTHash(HDCamera hdCamera) { - return m_Tonemapping.GetHashCode() * 23 + - m_WhiteBalance.GetHashCode() * 23 + - m_ColorAdjustments.GetHashCode() * 23 + - m_ChannelMixer.GetHashCode() * 23 + - m_SplitToning.GetHashCode() * 23 + - m_LiftGammaGain.GetHashCode() * 23 + - m_ShadowsMidtonesHighlights.GetHashCode() * 23 + - m_Curves.GetHashCode() * 23 + - m_TonemappingFS.GetHashCode() * 23 + - m_ColorGradingFS.GetHashCode() * 23 + - HDROutputActiveForCameraType(hdCamera).GetHashCode() + unchecked + { + int hash = 17; + hash = hash * 23 + m_Tonemapping.GetStateHash(); + hash = hash * 23 + m_WhiteBalance.GetStateHash(); + hash = hash * 23 + m_ColorAdjustments.GetStateHash(); + hash = hash * 23 + m_ChannelMixer.GetStateHash(); + hash = hash * 23 + m_SplitToning.GetStateHash(); + hash = hash * 23 + m_LiftGammaGain.GetStateHash(); + hash = hash * 23 + m_ShadowsMidtonesHighlights.GetStateHash(); + hash = hash * 23 + m_Curves.GetStateHash(); + hash = hash * 23 + m_TonemappingFS.GetHashCode(); + hash = hash * 23 + m_ColorGradingFS.GetHashCode(); + hash = hash * 23 + HDROutputActiveForCameraType(hdCamera).GetHashCode(); #if UNITY_EDITOR - * 23 - + m_ColorGradingSettings.space.GetHashCode() * 23 + - + UnityEditor.PlayerSettings.hdrBitDepth.GetHashCode() + hash = hash * 23 + m_ColorGradingSettings.space.GetHashCode(); + hash = hash * 23 + UnityEditor.PlayerSettings.hdrBitDepth.GetHashCode(); #endif - ; + return hash; + } } static void ValidateComputeBuffer(ref ComputeBuffer cb, int size, int stride, ComputeBufferType type = ComputeBufferType.Default) 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 34adbd6ece4..b92b4471778 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 @@ -166,6 +166,8 @@ void RecordRenderGraph(RenderRequest renderRequest, Debug.LogWarning("Path Tracing is not supported with XR single-pass rendering."); } + uiBuffer = PrepareOffscreenUIBuffer(hdCamera, renderContext, colorBackBuffer); + #if ENABLE_VIRTUALTEXTURES resolveVirtualTextureFeedback = false; #endif @@ -258,23 +260,7 @@ void RecordRenderGraph(RenderRequest renderRequest, colorBuffer = RenderTransparency(m_RenderGraph, hdCamera, renderContext, colorBuffer, prepassOutput.resolvedNormalBuffer, vtFeedbackBuffer, currentColorPyramid, volumetricLighting, rayCountTexture, opticalFogTransmittance, m_SkyManager.GetSkyReflection(hdCamera), gpuLightListOutput, transparentPrepass, ref prepassOutput, shadowResult, cullingResults, customPassCullingResults, aovRequest, aovCustomPassBuffers); - bool rendersOffscreenUI = !m_OffscreenUIRenderedInCurrentFrame && HDROutputActiveForCameraType(hdCamera) && SupportedRenderingFeatures.active.rendersUIOverlay && !NeedHDRDebugMode(m_CurrentDebugDisplaySettings); - if (rendersOffscreenUI) - { - uiBuffer = RenderHDROffscreenUI(m_RenderGraph, hdCamera, renderContext); - m_OffscreenUIRenderedInCurrentFrame = true; - } - else - { - // We do not render offscreen ui for the rest of cameras. - uiBuffer = m_OffscreenUIRenderedInCurrentFrame ? m_RenderGraph.ImportTexture(m_OffscreenUIColorBuffer.Value) : m_RenderGraph.defaultResources.blackTextureXR; - } - - bool blitsOffscreenUICover = rendersOffscreenUI && m_RequireOffscreenUICoverPrepass; - if (blitsOffscreenUICover) - { - BlitFullscreenUIToOffscreen(m_RenderGraph, colorBackBuffer, uiBuffer, hdCamera); - } + uiBuffer = PrepareOffscreenUIBuffer(hdCamera, renderContext, colorBackBuffer); if (NeedMotionVectorForTransparent(hdCamera.frameSettings)) { @@ -1063,6 +1049,30 @@ TextureHandle CreateOffscreenUIDepthBuffer(RenderGraph renderGraph, MSAASamples { format = CoreUtils.GetDefaultDepthStencilFormat(), clearBuffer = true, msaaSamples = msaaSamples, name = "UI Depth Buffer" }); } + TextureHandle PrepareOffscreenUIBuffer(HDCamera hdCamera, ScriptableRenderContext renderContext, TextureHandle colorBackBuffer) + { + TextureHandle uiBuffer; + bool rendersOffscreenUI = !m_OffscreenUIRenderedInCurrentFrame && HDROutputActiveForCameraType(hdCamera) && SupportedRenderingFeatures.active.rendersUIOverlay && !NeedHDRDebugMode(m_CurrentDebugDisplaySettings);; + if (rendersOffscreenUI) + { + uiBuffer = RenderHDROffscreenUI(m_RenderGraph, hdCamera, renderContext); + m_OffscreenUIRenderedInCurrentFrame = true; + } + else + { + // We do not render offscreen ui for the rest of cameras. + uiBuffer = m_OffscreenUIRenderedInCurrentFrame ? m_RenderGraph.ImportTexture(m_OffscreenUIColorBuffer.Value) : m_RenderGraph.defaultResources.blackTextureXR; + } + + bool blitsOffscreenUICover = rendersOffscreenUI && m_RequireOffscreenUICoverPrepass; + if (blitsOffscreenUICover) + { + BlitFullscreenUIToOffscreen(m_RenderGraph, colorBackBuffer, uiBuffer, hdCamera); + } + + return uiBuffer; + } + TextureHandle RenderHDROffscreenUI(RenderGraph renderGraph, HDCamera hdCamera, ScriptableRenderContext renderContext) { TextureHandle output; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 9d28ebc46d1..1e8e5340dfd 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2187,12 +2187,12 @@ protected override void Render(ScriptableRenderContext renderContext, List(); + UniversalCameraData cameraData = frameData.Get(); TextureDesc textureDesc = new TextureDesc(descriptor); DrawScreenSpaceUIPass.ConfigureOffscreenUITextureDesc(ref textureDesc); RenderingUtils.ReAllocateHandleIfNeeded(ref m_OffscreenUIColorHandle, textureDesc, name: "_OverlayUITexture"); - resourceData.overlayUITexture = renderGraph.ImportTexture(m_OffscreenUIColorHandle); + + // Clear the texture to avoid stale data from previous frames + ImportResourceParams importParams = new ImportResourceParams(); + importParams.clearOnFirstUse = cameraData.rendersOffscreenUI; + importParams.clearColor = Color.clear; + importParams.discardOnLastUse = false; + resourceData.overlayUITexture = renderGraph.ImportTexture(m_OffscreenUIColorHandle, importParams); } public override void OnBeginRenderGraphFrame() 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 0d45a6e8ae6..3bb20354a79 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 @@ -195,9 +195,10 @@ public ShadowCastingOptions castingOption } /// - /// If selfShadows is true, useRendererSilhoutte specifies that the renderer's sihouette should be considered part of the shadow. If selfShadows is false, useRendererSilhoutte specifies that the renderer's sihouette should be excluded from the shadow + /// This property is obsolete and no longer has any effect. Its functionality has been removed because it is no longer required. + /// To achieve similar behavior, add a ShadowCaster2D component to an empty parent GameObject instead. /// - [Obsolete("useRendererSilhoutte is deprecated. Use selfShadows instead. #from(2023.1)")] + [Obsolete("useRendererSilhouette is obsolete and no longer has any effect. To achieve similar behavior, add a ShadowCaster2D component to an empty parent GameObject. #from(2023.1)")] public bool useRendererSilhouette { set { m_UseRendererSilhouette = value; } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs b/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs index 6a0f880c667..f906037b564 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs @@ -156,6 +156,7 @@ internal enum ClusterDeferredPasses internal int GBufferInputAttachmentCount { get { return 4 + (UseShadowMask ? 1 : 0); } } + // Keep these formats in sync with the formats in GBufferOutputFormat.hlsl internal GraphicsFormat GetGBufferFormat(int index) { if (index == GBufferAlbedoIndex) // sRGB albedo, materialFlags diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index 35d92faf5b9..a394c6f1139 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -795,14 +795,16 @@ internal void BeginRenderGraphXRRendering(RenderGraph renderGraph) // Must be configured during the recording timeline before adding other XR intermediate passes. cameraData.xrUniversal.canFoveateIntermediatePasses = !PlatformAutoDetect.isXRMobile || isDefaultXRViewport; - using (var builder = renderGraph.AddRasterRenderPass("BeginXRRendering", out var passData, + // Since cmd.ConfigureFoveatedRendering will dispatch a compute shader we run into issues if it happens inside native render pass (especially true for DX12) + // As a workaround we use unsafe pass here + using (var builder = renderGraph.AddUnsafePass("BeginXRRendering", out var passData, Profiling.beginXRRendering)) { passData.cameraData = cameraData; builder.AllowGlobalStateModification(true); - builder.SetRenderFunc((BeginXRPassData data, RasterGraphContext context) => + builder.SetRenderFunc((BeginXRPassData data, UnsafeGraphContext context) => { if (data.cameraData.xr.enabled) { diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 118872dee1e..637364293f8 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -1068,12 +1068,8 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera baseCameraData.stackAnyPostProcessingEnabled = stackAnyPostProcessingEnabled; baseCameraData.stackLastCameraOutputToHDR = finalOutputHDR; - // Render the offscreen overlay UI only in the first base camera. - var rendersOffscreenUI = baseCameraData.rendersOverlayUI && finalOutputHDR && !offscreenUIRenderedInCurrentFrame; - if (rendersOffscreenUI) - offscreenUIRenderedInCurrentFrame = true; - baseCameraData.rendersOffscreenUI = rendersOffscreenUI; - baseCameraData.blitsOffscreenUICover = rendersOffscreenUI && requireOffscreenUICoverPrepass; + // Render the HDR offscreen overlay UI only in the first base camera if it renders overlay UI. + UpdateOffscreenUIRendering(baseCameraData, finalOutputHDR); RenderSingleCamera(context, baseCameraData); } @@ -1125,6 +1121,10 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera overlayCameraData.stackAnyPostProcessingEnabled = stackAnyPostProcessingEnabled; overlayCameraData.stackLastCameraOutputToHDR = finalOutputHDR; + // Render the HDR offscreen overlay UI from the stack's last camera if earlier base camera did not render overlay UI. + if (isLastOverlayCamera) + UpdateOffscreenUIRendering(overlayCameraData, finalOutputHDR); + xrLayout.ReconfigurePass(overlayCameraData.xr, overlayCamera); RenderSingleCamera(context, overlayCameraData); @@ -1205,6 +1205,16 @@ static void UpdateCameraData(UniversalCameraData baseCameraData, in XRPass xr) #endif } + static void UpdateOffscreenUIRendering(UniversalCameraData cameraData, bool finalOutputHDR) + { + // The first eligible camera in the frame draws HDR offscreen overlay UI. + var rendersOffscreenUI = cameraData.rendersOverlayUI && finalOutputHDR && !offscreenUIRenderedInCurrentFrame; + if (rendersOffscreenUI) + offscreenUIRenderedInCurrentFrame = true; + cameraData.rendersOffscreenUI = rendersOffscreenUI; + cameraData.blitsOffscreenUICover = rendersOffscreenUI && requireOffscreenUICoverPrepass; + } + static void UpdateVolumeFramework(Camera camera, UniversalAdditionalCameraData additionalCameraData) { using var profScope = new ProfilingScope(ProfilingSampler.Get(URPProfileId.UpdateVolumeFramework)); @@ -1297,14 +1307,16 @@ static void SetSupportedRenderingFeatures(UniversalRenderPipelineAsset pipelineA particleSystemInstancing = true, overridesEnableLODCrossFade = true }; - if (GraphicsSettings.TryGetRenderPipelineSettings(out var reflectionProbeSettings) - && !reflectionProbeSettings.UseReflectionProbeRotation) - { - SupportedRenderingFeatures.active.reflectionProbeModes = SupportedRenderingFeatures.ReflectionProbeModes.None; - } SceneViewDrawMode.SetupDrawMode(); #endif + if (GraphicsSettings.TryGetRenderPipelineSettings(out var reflectionProbeSettings)) + { + SupportedRenderingFeatures.active.reflectionProbeModes = + reflectionProbeSettings.UseReflectionProbeRotation + ? SupportedRenderingFeatures.ReflectionProbeModes.Rotation + : SupportedRenderingFeatures.ReflectionProbeModes.None; + } SupportedRenderingFeatures.active.supportsHDR = pipelineAsset.supportsHDR; SupportedRenderingFeatures.active.rendersUIOverlay = true; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs index 557377db42c..b871cad48e3 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs @@ -1927,9 +1927,16 @@ void CreateRenderingLayersTexture(RenderGraph renderGraph, TextureDesc descripto void CreateOffscreenUITexture(RenderGraph renderGraph, TextureDesc descriptor) { UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData cameraData = frameData.Get(); DrawScreenSpaceUIPass.ConfigureOffscreenUITextureDesc(ref descriptor); RenderingUtils.ReAllocateHandleIfNeeded(ref s_OffscreenUIColorHandle, descriptor, name: "_OverlayUITexture"); - resourceData.overlayUITexture = renderGraph.ImportTexture(s_OffscreenUIColorHandle); + + // Clear the texture to avoid stale data from previous frames + ImportResourceParams importParams = new ImportResourceParams(); + importParams.clearOnFirstUse = cameraData.rendersOffscreenUI; + importParams.clearColor = Color.clear; + importParams.discardOnLastUse = false; + resourceData.overlayUITexture = renderGraph.ImportTexture(s_OffscreenUIColorHandle, importParams); } void DepthNormalPrepassRender(RenderGraph renderGraph, RenderPassInputSummary renderPassInputs, in TextureHandle depthTarget, uint batchLayerMask, bool setGlobalDepth, bool setGlobalTextures, bool partialPass) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl new file mode 100644 index 00000000000..50a38ec224a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl @@ -0,0 +1,25 @@ +// This file contains functionality for letting the Unity Shader Compiler know what render target formats could be used +// The functionality provided here is intended to be used during in the material GBuffer pass. +#ifndef UNIVERSAL_GBUFFEROUTPUTFORMAT_INCLUDED +#define UNIVERSAL_GBUFFEROUTPUTFORMAT_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferCommon.hlsl" + +// Keep these formats in sync with the formats returned in DeferredLights.GetGBufferFormat +#pragma rendertarget_format_hint MRT0 R8G8B8A8_SRGB +#pragma rendertarget_format_hint MRT1 R8G8B8A8_SRGB +#pragma rendertarget_format_hint MRT2 R8G8B8A8_SRGB +#pragma rendertarget_format_hint MRT3 R8G8B8A8_SRGB,B10G11R11_UFloatPack32 +#pragma rendertarget_format_hint MRT4 R32_SFloat // Assume GBUFFER_FEATURE_DEPTH is always enabled at the moment. +#if defined(GBUFFER_FEATURE_RENDERING_LAYERS) +#pragma rendertarget_format_hint MRT5 R8_UInt, R16_UInt, R32_UInt +#if defined(GBUFFER_FEATURE_SHADOWMASK) +#pragma rendertarget_format_hint MRT6 B8G8R8A8_UNorm, R8G8B8A8_UNorm +#endif +#else // GBUFFER_FEATURE_RENDERING_LAYERS +#if defined(GBUFFER_FEATURE_SHADOWMASK) +#pragma rendertarget_format_hint MRT5 B8G8R8A8_UNorm, R8G8B8A8_UNorm +#endif +#endif + +#endif // UNIVERSAL_GBUFFEROUTPUTFORMAT_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta new file mode 100644 index 00000000000..a7178b5a276 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 87322610c9b88a64e8bce40c056d8116 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl index 3b888875bd5..06b21292140 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl @@ -100,7 +100,7 @@ float3 UnitySkinSprite( in float3 inputData, in uint4 blendIndices, in float4 bl void SetUpSpriteInstanceProperties() { -#ifdef UNITY_INSTANCING_ENABLED +#if defined(UNITY_INSTANCING_ENABLED) && !defined(HAVE_VFX_MODIFICATION) unity_SpriteProps.xy = unity_SpriteFlip; #endif } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader index 4361ccfdd5e..967b54e3bfe 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader @@ -316,6 +316,7 @@ Shader "Universal Render Pipeline/Complex Lit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader index 83bc8c01933..2166579f089 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader @@ -314,6 +314,7 @@ Shader "Universal Render Pipeline/Lit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader index 22527c1a269..6e1fddc57e4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7.shader @@ -173,6 +173,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7" #include "SpeedTree7Input.hlsl" #include "SpeedTree7Passes.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader index bf07ebea661..f3b42d851f4 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree7Billboard.shader @@ -117,6 +117,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree7 Billboard" #include "SpeedTree7BillboardInput.hlsl" #include "SpeedTree7BillboardPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader index f728bc82a0e..c7c842bb8b3 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader @@ -170,7 +170,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #include "SpeedTree8Input.hlsl" #include "SpeedTree8Passes.hlsl" - + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader index 50f952ebdc6..6b2ecd86132 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader @@ -222,6 +222,7 @@ Shader "Universal Render Pipeline/Particles/Lit" #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED #pragma multi_compile _ _CLUSTER_LIGHT_LOOP #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" // ------------------------------------- // Unity defined keywords @@ -234,6 +235,7 @@ Shader "Universal Render Pipeline/Particles/Lit" // Includes #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl index d6990f8616e..7cd1e868442 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitGbufferPass.hlsl @@ -90,7 +90,7 @@ VaryingsParticle ParticlesGBufferVertex(AttributesParticle input) output.positionWS.xyz = vertexInput.positionWS; output.clipPos = vertexInput.positionCS; - output.color = input.color; + output.color = GetParticleColor(input.color); #if defined(_FLIPBOOKBLENDING_ON) #if defined(UNITY_PARTICLE_INSTANCING_ENABLED) 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 b0c05dd22e3..d14801d1a38 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader @@ -225,6 +225,7 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ProbeVolumeVariants.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" // ------------------------------------- // Unity defined keywords @@ -241,6 +242,7 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" // Includes #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader index 7b883dad1ff..7805c4a2c0b 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader @@ -271,6 +271,7 @@ Shader "Universal Render Pipeline/Simple Lit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader index 95cb5fad49d..fbfae98c886 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader @@ -199,6 +199,7 @@ Shader "Universal Render Pipeline/Terrain/Lit" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader index 063504bd47b..ad293cd90d6 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader @@ -166,6 +166,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader index c92bbb4ab92..4b8de69df4e 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader @@ -160,6 +160,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader index 800b36c96fe..fbc031855cf 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrass.shader @@ -120,6 +120,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/WavingDoublePass" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader index 86f24509d19..0622e983e67 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassBillboard.shader @@ -104,6 +104,7 @@ Shader "Hidden/TerrainEngine/Details/UniversalPipeline/BillboardWavingDoublePass #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader index 22bc54765fc..7eda6131479 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader @@ -139,6 +139,7 @@ Shader "Universal Render Pipeline/Unlit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitGBufferPass.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GBufferOutputFormat.hlsl" ENDHLSL } diff --git a/Packages/com.unity.shadergraph/Documentation~/Block-Node.md b/Packages/com.unity.shadergraph/Documentation~/Block-Node.md index b98826160a4..6df0e78eadf 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Block-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Block-Node.md @@ -1,29 +1,7 @@ -# Block Node +# Block node reference -## Description +Block nodes are a specific type of node for the [Master Stack](Master-Stack.md). Each Block represents one piece of surface or vertex data that Shader Graph uses in the final shader output. -A Block is a specific type of node for the Master Stack. A Block represents a single piece of the surface (or vertex) description data that Shader Graph uses in the final shader output. [Built In Block nodes](Built-In-Blocks.md) are always available, but nodes that are specific to a certain render pipeline are only available for that pipeline. For example, Universal Block nodes are only available for the Universal Render Pipeline (URP), and High Definition Block nodes are only available for the High Definition Render Pipeline (HDRP). - -Some blocks are only compatible with specific [Graph Settings](Graph-Settings-Tab.md), and might become active or inactive based on the graph settings you select. You can't cut, copy, or paste Blocks. - -## Add and Remove Block Nodes - -To add a new Block node to a Context in the Master Stack, place the cursor over an empty area in the Context, then press the Spacebar or right-click and select **Create Node**. - -This brings up the Create Node menu, which displays only Block nodes that are valid for the Context. For example, Vertex Blocks don't appear in the Create Node menu of a Fragment Context. - -Select a Block node from the menu to add it to the Context. To remove a Block from the Context, select the Block node in the Context, then press the Delete key or right-click and select **Delete**. - -### Automatically Add or Remove Blocks - -You can also enable or disable an option in the Shader Graph Preferences to automatically add and remove Blocks from a Context. - -If you enable **Automatically Add or Remove Blocks**, Shader Graph automatically adds the required Block nodes for that particular asset's Target or material type. It automatically removes any incompatible Block nodes that have no connections and default values. - -If you disable **Automatically Add or Remove Blocks**, Shader Graph doesn't automatically add and remove Block nodes. You must manually add and remove all Block nodes. - -## Active and Inactive Blocks - -Active Block nodes are Blocks that contribute to the final shader. Inactive Block nodes are Blocks that are present in the Shader Graph, but don't contribute to the final shader. - -When you change the graph settings, certain Blocks might become active or inactive. Inactive Block nodes and any node streams that are connected only to Inactive Block nodes appear grayed out. +| Page | Description | +| :--- | :--- | +| [Built-In Blocks](Built-In-Blocks.md) | Block nodes that are always available, regardless of the active render pipeline. | diff --git a/Packages/com.unity.shadergraph/Documentation~/Fade-Transition-Node.md b/Packages/com.unity.shadergraph/Documentation~/Fade-Transition-Node.md index a585dc7af74..1e8afb66a35 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Fade-Transition-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Fade-Transition-Node.md @@ -4,7 +4,7 @@ Fade Transition is a method of adding noise to add variation while a function transitions from on to off. This node takes in a fade value and remaps it using the noise value (usually from a texture). When FadeValue is 0, the output is always 0, and when FadeValue is 1, the output is always exactly 1. In between 0 and 1 the transition will follow the pattern in the noise. -This [Node](Node.md) is commonly used as an input to **Alpha** on a [Master Node](Master-Node.md) to provide an LOD transition. +This [Node](Node.md) is commonly used as an input to the **Alpha** block in the [Master Stack](Master-Stack.md) to provide an LOD transition. ## Ports diff --git a/Packages/com.unity.shadergraph/Documentation~/Is-Front-Face-Node.md b/Packages/com.unity.shadergraph/Documentation~/Is-Front-Face-Node.md index 34b449a9f56..587416c9237 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Is-Front-Face-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Is-Front-Face-Node.md @@ -2,7 +2,7 @@ ## Description -Returns true if currently rendering a front face and false if rendering a back face. This value is always true unless the [Master Node](Master-Node.md)'s **Two Sided** value is set to true in the **Material Options**. This is useful for [Branching](Branch-Node.md). +Returns true if currently rendering a front face and false if rendering a back face. This value is always true unless the **Render Face** property in the [Graph Settings](Graph-Settings-Tab.md) is set to **Both**. This is useful for [Branching](Branch-Node.md). NOTE: This [Node](Node.md) can only be used in the **Fragment** [Shader Stage](Shader-Stage.md). diff --git a/Packages/com.unity.shadergraph/Documentation~/Keywords-reference.md b/Packages/com.unity.shadergraph/Documentation~/Keywords-reference.md index 98576807ab3..abc1e7b669b 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Keywords-reference.md +++ b/Packages/com.unity.shadergraph/Documentation~/Keywords-reference.md @@ -12,7 +12,8 @@ Parameters that all keyword types have in common. | **Reference** | The internal name for the keyword in the shader. Use this **Reference** name instead of the display **Name** when you reference the keyword in a script.

If you overwrite this parameter, be aware of the following:
  • A Keyword **Reference** has to be in full capitals. Unity converts any lowercase letters to uppercase.
  • If the string contains any characters that HLSL does not support, Unity replaces those characters with underscores.
  • You can revert to the default value: right-click on the **Reference** field label, and select **Reset Reference**.
| | **Promote to final Shader** | Makes the keyword available across the entire shader rather than only within the subgraph. | | **Definition** | Sets the keyword declaration type, which determines how Unity compiles the shader code. This allows you to [optimize the balance between build time, runtime, and file sizes](Keywords-concepts.md#keyword-impact-optimization).

The options are:
  • **Shader Feature**: Unity only compiles shader variants for keyword combinations used by materials in your build, and removes other shader variants.
  • **Multi Compile**: Unity compiles shader variants for all keyword combinations regardless of whether the build uses these variants.
  • **Predefined**: Specifies that the target/sub-target already defines the keyword and you just want to reuse it. Predefined Keywords can either use a [built-in macro](https://docs.unity3d.com/Manual/shader-branching-built-in-macros.html), which results in static branching at build time, or any of the keywords already defined by the Shader Graph Target (for example, [URP](https://docs.unity3d.com/Manual/urp/urp-shaders/shader-keywords-macros.html)), including [Built-In keyword sets](https://docs.unity3d.com/Manual/SL-MultipleProgramVariants-shortcuts.html), and where the branching depends on that definition.
  • **Dynamic Branch**: Unity keeps branching code in one compiled shader program.
| -| **Is Overridable** | Indicates whether the keyword's state can be overridden.
For more information, refer to [Toggle shader keywords in a script](https://docs.unity3d.com/Manual/shader-keywords-scripts.html). | +| **Allow Definition Override** | Makes the keyword's **Definition** overridable at compile time through the project's [Shader Build Settings](https://docs.unity3d.com/Manual/class-GraphicsSettings.html#shader-build-settings). When this option is enabled, Shader Graph uses dynamic branching (`if`) in generated code instead of preprocessor directives (`#if`). Enabling this option doesn't affect the shader's runtime performance unless the Shader Build Settings override the Definition to Dynamic Branch at compile time. | +| **Allow State Override** | Sets the keyword scope to Global, making the keyword state overridable at runtime. If this option is disabled, the keyword scope is set to Local and the keyword state is not overridable.
For more information, refer to [Toggle shader keywords in a script](https://docs.unity3d.com/Manual/shader-keywords-scripts.html). | | **Generate Material Property** | Generates a material property declaration to display the keyword as a property in the material inspector.
This adds a `[Toggle(_KEYWORD)]` attribute to the material property. For more information, refer to [`MaterialPropertyDrawer`](https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html). | | **Stages** | Set the stage the keyword applies to.

The following options are available:
  • **All** - Applies this keyword to all shader stages.
  • **Vertex** - Applies this keyword to the vertex stage.
  • **Fragment** - Applies this keyword to the fragment stage.
| @@ -34,7 +35,8 @@ Parameters specific to Enum keywords in addition to the [common parameters](#com | **Name** | **Description** | | :--- | :--- | -| **Default Value** | Select an entry from the drop-down menu to determine which value to use for the keyword when Shader Graph generates previews. This also defines the keyword's default value when you use this shader to create a new Material. When you edit the Entries list, Shader Graph automatically updates the options in this control. | +| **Include "none" entry** | Includes a special entry in addition to the **Entries** list to allow the enum to have a "no value selected" state.
For more details about the corresponding shader code behind this option, refer to [Branch when all keywords in a set are disabled](https://docs.unity3d.com/Manual/SL-MultipleProgramVariants-make-conditionals.html). | +| **Default Value** | Selects an entry from the drop-down menu to determine which value to use for the keyword when Shader Graph generates previews. This also defines the keyword's default value when you use this shader to create a new Material. When you edit the **Entries** list, Shader Graph automatically updates the options in this control. | | **Entries** | This list defines all the states for the keyword. Each state has a separate **Entry Name** and **Reference Suffix**.
  • **Entry Name**: The name displayed in drop-down menus for the keyword on the [Internal Inspector](Internal-Inspector.md) and the Material Inspector. Shader Graph also uses this name for port labels on nodes that reference the keyword.
  • **Reference Suffix**: This identifies the final keyword, presented in the format `Reference_ReferenceSuffix`.
| When you define an Enum keyword, Shader Graph displays labels for each state consisting of a version of the Enum's **Entry Name** appended to the main **Reference** name. diff --git a/Packages/com.unity.shadergraph/Documentation~/Master-Stack.md b/Packages/com.unity.shadergraph/Documentation~/Master-Stack.md index 442f31fa5e8..72aa58d053f 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Master-Stack.md +++ b/Packages/com.unity.shadergraph/Documentation~/Master-Stack.md @@ -11,3 +11,34 @@ The content of the Master Stack might change depending on the [Graph Settings](G ## Contexts The Master Stack contains two Contexts: Vertex and Fragment. These represent the two stages of a shader. Nodes that you connect to Blocks in the Vertex Context become part of the final shader's vertex function. Nodes that you connect to Blocks in the Fragment Context become part of the final shader's fragment (or pixel) function. If you connect any nodes to both Contexts, they are executed twice, once in the vertex function and then again in the fragment function. You can't cut, copy, or paste Contexts. + +## Block Node + +A Block is a specific type of node for the Master Stack. A Block represents a single piece of the surface (or vertex) description data that Shader Graph uses in the final shader output. [Built In Block nodes](Built-In-Blocks.md) are always available, but nodes that are specific to a certain render pipeline are only available for that pipeline. + +Some blocks are only compatible with specific [Graph Settings](Graph-Settings-Tab.md), and might become active or inactive based on the graph settings you select. You can't cut, copy, or paste Blocks. + +### Add and Remove Block Nodes + +To add a new Block node to a Context in the Master Stack: + +1. Place the cursor over an empty area in the Context. +2. Press the Spacebar, or right-click and select **Create Node**. + + This brings up the Create Node menu, which displays only Block nodes that are valid for the Context. + +3. Select a Block node from the menu to add it to the Context. + +To remove a Block from the Context: + +1. Select the Block node in the Context. +2. Press the Delete key, or right-click and select **Delete**. + +> [!NOTE] +> You can configure Shader Graph to automatically add and remove Block nodes. For more information, refer to [Shader Graph preferences](Shader-Graph-Preferences.md). + +### Active and Inactive Blocks + +Active Block nodes are Blocks that contribute to the final shader. Inactive Block nodes are Blocks that are present in the Shader Graph, but don't contribute to the final shader. + +When you change the graph settings, certain Blocks might become active or inactive. Inactive Block nodes and any node streams that are connected only to Inactive Block nodes appear grayed out. diff --git a/Packages/com.unity.shadergraph/Documentation~/Metal-Reflectance-Node.md b/Packages/com.unity.shadergraph/Documentation~/Metal-Reflectance-Node.md index 5cff97de58e..477e8772a88 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Metal-Reflectance-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Metal-Reflectance-Node.md @@ -4,7 +4,7 @@ Returns a **Metal Reflectance** value for a physically based material. The material to use can be selected with the **Material** dropdown parameter on the [Node](Node.md). -When using **Specular** **Workflow** on a [PBR Master Node](PBR-Master-Node.md) this value should be supplied to the **Specular** [Port](Port.md). When using **Metallic** **Workflow** this value should be supplied to the **Albedo** [Port](Port.md). +When using the **Specular** workflow, supply this value to the **Specular** block in the [Master Stack](Master-Stack.md). When using the **Metallic** workflow, supply it to the **Base Color** block instead. ## Ports diff --git a/Packages/com.unity.shadergraph/Documentation~/Property-Types.md b/Packages/com.unity.shadergraph/Documentation~/Property-Types.md index e432a1b79c7..d82f60c1457 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Property-Types.md +++ b/Packages/com.unity.shadergraph/Documentation~/Property-Types.md @@ -122,6 +122,7 @@ Defines a [Texture 2D](https://docs.unity3d.com/Manual/class-TextureImporter.htm | **Mode** | Defines the fallback texture Unity uses when none is provided.

The options are:
  • **White**: Sets a solid white (1,1,1) texture to ensure full-intensity sampling.
  • **Black**: Sets a solid black (0,0,0) texture to yield zero contribution.
  • **Grey**: Sets a mid-grey in sRGB (~0.5) as a neutral fallback.
  • **Normal Map**: Sets a flat normal value to keep surfaces flat without a normal texture.
  • **Linear Grey**: Sets a mid-grey in linear color space.
  • **Red**: Sets a solid red (1,0,0) texture, useful for data expected in the red channel.
| | **Use Tiling and Offset** | Toggles the property `NoScaleOffset` to enable manipulating scale and offset separately from other texture properties; see [SplitTextureTransformNode](Split-Texture-Transform-Node.md).
A boolean value. | | **Use TexelSize** | Uses the size of texels expressed in UV space. | +| **Is HDR** | Allows any node that samples the texture to automatically decode the sampled value if the texture is stored in an encoded HDR format (for example, dLDR). | ## Texture 2D Array @@ -130,6 +131,7 @@ Defines a [Texture 2D Array](https://docs.unity3d.com/Manual/class-TextureImport | Parameter | Description | | :--- | :--- | | **Default Value** | Sets the initial value of the [Property](https://docs.unity3d.com/Manual/SL-Properties.html).
A texture asset reference. | +| **Is HDR** | Allows any node that samples the texture to automatically decode the sampled value if the texture is stored in an encoded HDR format (for example, dLDR). | ## Texture 3D @@ -138,6 +140,7 @@ Defines a [Texture 3D](https://docs.unity3d.com/Manual/class-TextureImporter.htm | Parameter | Description | | :--- | :--- | | **Default Value** | Sets the initial value of the [Property](https://docs.unity3d.com/Manual/SL-Properties.html).
A texture asset reference. | +| **Is HDR** | Allows any node that samples the texture to automatically decode the sampled value if the texture is stored in an encoded HDR format (for example, dLDR). | ## Cubemap @@ -146,6 +149,7 @@ Defines a [Cubemap](https://docs.unity3d.com/Manual/class-Cubemap.html) value. D | Parameter | Description | | :--- | :--- | | **Default Value** | Sets the initial value of the [Property](https://docs.unity3d.com/Manual/SL-Properties.html).
A cubemap asset reference. | +| **Is HDR** | Allows any node that samples the texture to automatically decode the sampled value if the texture is stored in an encoded HDR format (for example, dLDR). | ## Virtual Texture diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Preferences.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Preferences.md index bb40ef0108b..abc5ae11c78 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Preferences.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Preferences.md @@ -7,7 +7,7 @@ To open the preferences, go to **Edit** > **Preferences** > **Shader Graph** (ma | Property | Description | | :--- | :--- | | **Preview Variant Limit** | Sets the maximum number of variants allowed in local projects. This is a local version of the **Shader Variant Limit** in the project settings. If your graph exceeds this maximum value, Unity returns the following error:
_Validation: Graph is generating too many variants. Either delete Keywords, reduce Keyword variants, or increase the **Shader Variant Limit** in Preferences > Shader Graph._
For more information about shader variants, refer to [Making multiple shader program variants](https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html). For more information about the Shader Variant Limit, refer to [Shader graph project settings](Shader-Graph-Project-Settings.md) | -| **Automatically Add and Remove Block Nodes** | Adds to the [Master Stack](Master-Stack.md) any needed [Block nodes](Block-Node.md) and removes from the Master Stack any Block nodes with no incoming connections. | +| **Automatically Add and Remove Block Nodes** | When enabled, Shader Graph automatically adds the required [Block nodes](Block-Node.md) for the asset's Target or material type to the [Master Stack](Master-Stack.md), and removes any incompatible Block nodes that have no connections and default values. When disabled, you must manually add and remove all Block nodes. | | **Enable Deprecated Nodes** | Disables warnings for deprecated nodes and properties. When enabled, Shader Graph doesn't display warnings if your graph contains deprecated nodes or properties. When disabled, Shader Graph displays warnings for deprecated nodes and properties, and the new nodes and properties you create use the latest version. | | **Zoom Step Size** | Adjusts how much the Shader Graph camera zooms with each mouse wheel movement. This helps balance zoom speed, since touchpads can zoom much faster than regular mouse wheels.
Only affects materials created automatically, such as when you make a new shader graph from a Decal Projector or Fullscreen Renderer Feature. | | **Graph Template Workflow** | Sets whether Unity creates new materials as [material variants](https://docs.unity3d.com/Manual/materialvariant-concept.html) from the child asset of the shader graph asset, or as standalone materials. The options are:
  • **Material Variant**: Unity creates material variants from the child asset of the shader graph asset.
  • **Material**: Unity creates standalone materials.
| diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GradientInputMaterialSlot.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GradientInputMaterialSlot.cs index 837ffd2af80..f26ea6e63e9 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GradientInputMaterialSlot.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GradientInputMaterialSlot.cs @@ -18,6 +18,11 @@ class GradientInputMaterialSlot : GradientMaterialSlot, IMaterialSlotHasValue GradientPicker.visible && m_Field.isShowingGradientPicker; + + public GradientSlotControlView(GradientInputMaterialSlot slot, bool showGradientEditor) { m_Slot = slot; styleSheets.Add(Resources.Load("Styles/Controls/GradientSlotControlView")); @@ -33,9 +36,12 @@ public GradientSlotControlView(GradientInputMaterialSlot slot) m_GradientObject.gradient.SetKeys(m_Slot.value.colorKeys, m_Slot.value.alphaKeys); m_GradientObject.gradient.mode = m_Slot.value.mode; - var gradientField = new GradientField() { value = m_GradientObject.gradient, colorSpace = ColorSpace.Linear, hdr = true }; - gradientField.RegisterValueChangedCallback(OnValueChanged); - Add(gradientField); + m_Field = new GradientField() { value = m_GradientObject.gradient, colorSpace = ColorSpace.Linear, hdr = true }; + m_Field.RegisterValueChangedCallback(OnValueChanged); + Add(m_Field); + + if (showGradientEditor) + m_Field.ShowGradientPicker(); } void OnValueChanged(ChangeEvent evt) diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index ae53e7ef3cc..cd94d88fbb5 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -504,7 +504,7 @@ internal static string GetShaderText(string path, out List configuredTextures, AssetCollection assetCollection, out GraphData graph) { - var textGraph = File.ReadAllText(path, Encoding.UTF8); + var textGraph = FileUtilities.ReadAllTextUTF8(path); graph = new GraphData { messageManager = new MessageManager(), diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs index a8affe50e5e..9409cec0adc 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs @@ -25,7 +25,7 @@ public override void OnInspectorGUI() { GraphData GetGraphData(AssetImporter importer) { - var textGraph = File.ReadAllText(importer.assetPath, Encoding.UTF8); + var textGraph = FileUtilities.ReadAllTextUTF8(importer.assetPath); var graphObject = CreateInstance(); graphObject.hideFlags = HideFlags.HideAndDontSave; bool isSubGraph; diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index bc4907b071a..daccda2e4a7 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -78,7 +78,7 @@ public override void OnImportAsset(AssetImportContext ctx) var subGraphPath = ctx.assetPath; var subGraphGuid = AssetDatabase.AssetPathToGUID(subGraphPath); graphAsset.assetGuid = subGraphGuid; - var textGraph = File.ReadAllText(subGraphPath, Encoding.UTF8); + var textGraph = FileUtilities.ReadAllTextUTF8(subGraphPath); var messageManager = new MessageManager(); var graphData = new GraphData { diff --git a/Packages/com.unity.visualeffectgraph/Documentation~/Block-FlipbookPlayer.md b/Packages/com.unity.visualeffectgraph/Documentation~/Block-FlipbookPlayer.md index 9ad1e8663b3..483f1b0c654 100644 --- a/Packages/com.unity.visualeffectgraph/Documentation~/Block-FlipbookPlayer.md +++ b/Packages/com.unity.visualeffectgraph/Documentation~/Block-FlipbookPlayer.md @@ -10,7 +10,7 @@ Flipbook textures are texture sheets that consist of multiple smaller sub-images To generate a Flipbook, use external digital content creation tools. -To set an output to use flipbooks, change its **UV Mode** to **Flipbook**. For more information on the different UV Modes, refer to the documentation for the various output Contexts. +To set an output to use flipbooks, change its **UV Mode** to **Flipbook**. For more information on the different UV Modes, refer to the documentation for the various output contexts. If you use a Shader Graph output context, refer to [Use the Flipbook Player with a Shader Graph output](#use-the-flipbook-player-with-a-shadergraph-output). There are two different modes to control the playback: **Frame Rate** and **Cycles**. Additionally, in both modes, you can control the **Animation Range**. @@ -48,6 +48,26 @@ You can select a subset of frames to be played: - **Flipbook Column**: Only play the frames in the column selected by **Index**. - **Start End Frames**: Specify the start and end frames of the animation, inclusive. +## Use the Flipbook Player with a Shader Graph output + +Shader graph output contexts, such as **Output Particle ShaderGraph Quad**, do not have a **UV Mode** setting. Instead, set up flipbook texture sampling inside the shader graph. + +To use the Flipbook Player block with a Shader Graph output: + +1. Open your shader graph in the Shader Graph window. +2. In the **Graph Settings** tab, enable **Support VFX Graph**. For more information, refer to [Working with Shader Graph in the Visual Effect Graph](sg-working-with.md). +3. In the **Blackboard**, add a **Float** property and name it **Particle TexIndex**. +4. Add a [**Flipbook**](https://docs.unity3d.com/Packages/com.unity.shadergraph@latest?subfolder=/manual/Flipbook-Node.html) node to the graph. +5. Connect the **Particle TexIndex** property node to the **Tile** input of the **Flipbook** node. +6. Set the **Width** and **Height** inputs of the **Flipbook** node to the column and row count of your flipbook texture. +7. Connect the **Out** output of the **Flipbook** node to the **UV** input of a **Sample Texture 2D** node, and connect your flipbook texture to the **Texture** input. +8. Assign the shader graph to an **Output Particle ShaderGraph** output context in your Visual Effect Graph. +9. In the output context, add a **[Get Attribute: texIndex](Operator-GetAttributeTexIndex.md)** operator and connect its output to the **Particle TexIndex** port. + +The Flipbook Player block updates the `texIndex` attribute each frame. The shader graph uses this value to select the correct sub-image from the flipbook texture. + +**Note**: The Visual Effect Graph package includes sample shader graphs for flipbook effects. To access the sample shader graphs, go to **Window** > **Package Manager**, select **Visual Effect Graph**, and import the **VFX Graph Additions** sample. + ## Block compatibility This Block is compatible with the following Contexts: diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionDecodeDepth.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionDecodeDepth.cs new file mode 100644 index 00000000000..4b8a8191e5e --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionDecodeDepth.cs @@ -0,0 +1,26 @@ +using System; +using UnityEngine; +using UnityEngine.VFX; + +namespace UnityEditor.VFX +{ + class VFXExpressionDecodeDepth : VFXExpression + { + public VFXExpressionDecodeDepth() : this(VFXValue.Default) + { + } + + public VFXExpressionDecodeDepth(VFXExpression depth) + : base(Flags.InvalidOnCPU, new VFXExpression[] { depth }) + { + } + + public sealed override VFXExpressionOperation operation { get { return VFXExpressionOperation.None; } } + public sealed override VFXValueType valueType { get { return VFXValueType.Float; } } + + public sealed override string GetCodeString(string[] parents) + { + return string.Format("DecodeDepth({0})", parents[0]); + } + } +} diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionDecodeDepth.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionDecodeDepth.cs.meta new file mode 100644 index 00000000000..f5c43c83add --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionDecodeDepth.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4a1a658b4b2aab742951cc9c4db81618 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/Collision/CollisionDepth.cs b/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/Collision/CollisionDepth.cs index 43c04251366..3a60feae92b 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/Collision/CollisionDepth.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/Collision/CollisionDepth.cs @@ -116,9 +116,7 @@ protected sealed override string collisionDetection { float2 uv = projPos.xy * 0.5f + 0.5f; float depth = LOAD_TEXTURE2D_X(Camera_depthBuffer.t, uv*Camera_scaledPixelDimensions).r; - #if UNITY_REVERSED_Z - depth = 1.0f - depth; // reversed z - #endif + depth = DecodeDepth(depth); const float n = Camera_nearPlane; const float f = Camera_farPlane; @@ -154,11 +152,8 @@ protected sealed override string collisionDetection float depth10 = LOAD_TEXTURE2D_X(Camera_depthBuffer.t, depthPos10).r; float depth01 = LOAD_TEXTURE2D_X(Camera_depthBuffer.t, depthPos01).r; - - #if UNITY_REVERSED_Z - depth10 = 1.0f - depth10; - depth01 = 1.0f - depth01; - #endif + depth10 = DecodeDepth(depth10); + depth01 = DecodeDepth(depth01); float4 vPos10 = mul(ClipToView,float4(projPos10,depth10 * 2.0f - 1.0f,1.0f)); float4 vPos01 = mul(ClipToView,float4(projPos01,depth01 * 2.0f - 1.0f,1.0f)); diff --git a/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/HLSL/HLSLParser.cs b/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/HLSL/HLSLParser.cs index b2b10bfb543..82b8c6170a2 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/HLSL/HLSLParser.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/HLSL/HLSLParser.cs @@ -147,7 +147,7 @@ public HLSLMissingIncludeFile(string filePath) class HLSLFunctionParameter { // Match inout/in/out accessor then any whitespace then the parameter type then optionally a template type any whitespace and then the parameter name - static readonly Regex s_ParametersParser = new Regex(@"(?(inout|in|out)\b)?\s*(?\w+)(?:[<](?