diff --git a/TestProjects/HDRP_RuntimeTests/Packages/manifest.json b/TestProjects/HDRP_RuntimeTests/Packages/manifest.json index b3fe4f73c2c..eb8a5c99261 100644 --- a/TestProjects/HDRP_RuntimeTests/Packages/manifest.json +++ b/TestProjects/HDRP_RuntimeTests/Packages/manifest.json @@ -7,10 +7,10 @@ "com.unity.render-pipelines.high-definition": "file:../../../com.unity.render-pipelines.high-definition", "com.unity.render-pipelines.high-definition-config": "file:../../../com.unity.render-pipelines.high-definition-config", "com.unity.shadergraph": "file:../../../com.unity.shadergraph", - "com.unity.test-framework": "1.1.5", - "com.unity.test-framework.build": "0.0.1-preview.3", - "com.unity.test-framework.utp-reporter": "0.1.3-preview.17", - "com.unity.testframework.graphics": "7.1.12-preview", + "com.unity.test-framework": "1.1.14", + "com.unity.test-framework.build": "0.0.1-preview.12", + "com.unity.test-framework.utp-reporter": "1.0.0-preview", + "com.unity.testframework.graphics": "7.1.13-preview", "com.unity.testing.hdrp": "file:../../../com.unity.testing.hdrp", "com.unity.ugui": "1.0.0", "com.unity.visualeffectgraph": "file:../../../com.unity.visualeffectgraph", diff --git a/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.cs b/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.cs index 2dd6c162e83..38845ceeda3 100644 --- a/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.cs +++ b/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.cs @@ -36,10 +36,12 @@ protected T Cast(object o) where T : class { var casted = o as T; - string typeName = o == null ? "null" : o.GetType().ToString(); if (casted == null) + { + string typeName = o == null ? "null" : o.GetType().ToString(); throw new InvalidOperationException("Can't cast " + typeName + " to " + typeof(T)); + } return casted; } diff --git a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs index a9f9c22b96c..aeeb5986e1a 100644 --- a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs +++ b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs @@ -236,6 +236,17 @@ public void UnRegisterDebug() //m_DebugParameters.UnRegisterDebug(); } + /// + /// Resets the reference size of the internal RTHandle System. + /// This allows users to reduce the memory footprint of render textures after doing a super sampled rendering pass for example. + /// + /// New width of the internal RTHandle System. + /// New height of the internal RTHandle System. + public void ResetRTHandleReferenceSize(int width, int height) + { + m_Resources.ResetRTHandleReferenceSize(width, height); + } + /// /// Import an external texture to the Render Graph. /// diff --git a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs index 292d96b51b4..f8b5fc64097 100644 --- a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs +++ b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs @@ -659,6 +659,11 @@ internal void Clear() #endif } + internal void ResetRTHandleReferenceSize(int width, int height) + { + m_RTHandleSystem.ResetReferenceSize(width, height); + } + internal void Cleanup() { foreach (var value in m_TexturePool) diff --git a/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs b/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs index 7d10f4fe881..51888e2e4aa 100644 --- a/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs +++ b/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs @@ -134,6 +134,17 @@ public void SwapAndSetReferenceSize(int width, int height, MSAASamples msaaSampl m_RTHandleSystem.SetReferenceSize(width, height, msaaSamples); } + /// + /// Reset the reference size of the system and reallocate all textures. + /// + /// New width. + /// New height. + public void ResetReferenceSize(int width, int height) + { + m_RTHandleSystem.ResetReferenceSize(width, height); + } + + void Swap() { foreach (var item in m_RTHandles) diff --git a/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs b/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs index 155686bc188..2f75277b5af 100644 --- a/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs +++ b/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs @@ -125,13 +125,25 @@ internal void Remove(RTHandle rth) m_AutoSizedRTs.Remove(rth); } + /// + /// Reset the reference size of the system and reallocate all textures. + /// + /// New width. + /// New height. + public void ResetReferenceSize(int width, int height) + { + m_MaxWidths = width; + m_MaxHeights = height; + SetReferenceSize(width, height, m_ScaledRTCurrentMSAASamples, reset: true); + } + /// /// Sets the reference rendering size for subsequent rendering for the RTHandle System /// /// Reference rendering width for subsequent rendering. /// Reference rendering height for subsequent rendering. /// Number of MSAA samples for multisampled textures for subsequent rendering. - public void SetReferenceSize(int width, int height, MSAASamples msaaSamples) + public void SetReferenceSize(int width, int height, MSAASamples msaaSamples, bool reset = false) { m_RTHandleProperties.previousViewportSize = m_RTHandleProperties.currentViewportSize; m_RTHandleProperties.previousRenderTargetSize = m_RTHandleProperties.currentRenderTargetSize; @@ -140,7 +152,7 @@ public void SetReferenceSize(int width, int height, MSAASamples msaaSamples) width = Mathf.Max(width, 1); height = Mathf.Max(height, 1); - bool sizeChanged = width > GetMaxWidth() || height > GetMaxHeight(); + bool sizeChanged = width > GetMaxWidth() || height > GetMaxHeight() || reset; bool msaaSamplesChanged = (msaaSamples != m_ScaledRTCurrentMSAASamples); if (sizeChanged || msaaSamplesChanged) diff --git a/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs b/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs index 4b748445f94..8ad0ff6c6a3 100644 --- a/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs +++ b/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs @@ -294,5 +294,15 @@ MSAASamples msaaSamples msaaSamples ); } + + /// + /// Reset the reference size of the system and reallocate all textures. + /// + /// New width. + /// New height. + public static void ResetReferenceSize(int width, int height) + { + s_DefaultInstance.ResetReferenceSize(width, height); + } } } diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index b9f13e37500..30c628abc59 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -1,4 +1,4 @@ -# Changelog +# Changelog All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) @@ -6,8 +6,33 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] -Version Updated -The version number for this package has increased due to a version update of a related graphics package. +### Added +- Added a function (HDRenderPipeline.ResetRTHandleReferenceSize) to reset the reference size of RTHandle systems. + +### Fixed +- Fixed shadowmask UI now correctly showing shadowmask disable +- Fixed the indirect diffuse texture not being ignored when it should (ray tracing disabled). +- Fixed a performance issue with stochastic ray traced area shadows. +- Made more explicit the warning about raytracing and asynchronous compute. Also fixed the condition in which it appears. +- Fixed a null ref exception in static sky when the default volume profile is invalid. +- Fixed an error about procedural sky being logged by mistake. +- Fixed flickering of the game/scene view when lookdev is running. +- Fixed some GCAlloc in the debug window. +- Removed logic in the UI to disable parameters for contact shadows and fog volume components as it was going against the concept of the volume system. +- Fixed over consumption of GPU memory by the Physically Based Sky. +- Put more information in Camera background type tooltip and fixed inconsistent exposure behavior when changing bg type. +- Fixed an issue where asset preview could be rendered white because of static lighting sky. +- Fixed an issue where static lighting was not updated when removing the static lighting sky profile. +- Fixed SceneView Draw Modes not being properly updated after opening new scene view panels or changing the editor layout. +- Fixed depth prepass and postpass being disabled after changing the shader in the material UI. +- Fix an issue in reading the gbuffer for ray traced subsurface scattering (case 1248358). +- Fixed an issue where editing the Look Dev default profile would not reflect directly in the Look Dev window. +- Fix issue causing blocky artifacts when decals affect metallic and are applied on material with specular color workflow. + +### Changed +- Shadowmask and realtime reflection probe property are hide in Quality settings +- Made the StaticLightingSky class public so that users can change it by script for baking purpose. +- Changed default exposure compensation to 0. ### Fixed - Fixed a cause of NaN when a normal of 0-length is generated (usually via shadergraph). @@ -78,7 +103,6 @@ The version number for this package has increased due to a version update of a r - Fixed scalarization code for contact shadows - Fix MaterialBalls having same guid issue - Fix spelling and grammatical errors in material samples -- Fixed SceneView Draw Modes not being properly updated after opening new scene view panels or changing the editor layout. ### Changed - Rejecting history for ray traced reflections based on a threshold evaluated on the neighborhood of the sampled history. @@ -654,6 +678,8 @@ The version number for this package has increased due to a version update of a r - Added a fix script to handle the warning 'referenced script in (GameObject 'SceneIDMap') is missing' - Fix Wizard load when none selected for RenderPipelineAsset - Fixed issue with unclear naming of debug menu for decals. +- Fixed issue with reflection probes in realtime time mode with OnEnable baking having wrong lighting with sky set to dynamic (case 1238047). +- Fixed corrupted values on LayeredLit when using Vertex Color multiply mode to multiply and MSAA is activated. ### Changed - Color buffer pyramid is not allocated anymore if neither refraction nor distortion are enabled diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Creating-a-Custom-Sky.md b/com.unity.render-pipelines.high-definition/Documentation~/Creating-a-Custom-Sky.md index a165bdddd69..58efdb653bb 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Creating-a-Custom-Sky.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Creating-a-Custom-Sky.md @@ -59,6 +59,12 @@ public class NewSky : SkySettings } return hash; } + + public override int GetHashCode(Camera camera) + { + // Implement if your sky depends on the camera settings (like position for instance) + return GetHashCode(); + } } ``` @@ -159,6 +165,10 @@ class NewSkyRenderer : SkyRenderer } ``` +### Important note: +If your sky renderer has to manage heavy data (like precomputed textures or similar things) then particular care has to be taken. Indeed, one instance of the renderer will exist per camera so by default if this data is a member of the renderer, it willl also be duplicated in memory. +Since each sky renderer can have very different needs, the responsbility to share this kind of data is the renderer's and need to be implemented by the user. + ## Sky rendering Shader diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2019.3-to-2020.1.md b/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2019.3-to-2020.1.md index 6cd48c9c77a..aaf04d2c617 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2019.3-to-2020.1.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2019.3-to-2020.1.md @@ -8,4 +8,8 @@ From Unity 2020.1, the HDRP-specific settings of the scene view camera (anti-ali ## Cookie baking -From Unity 2020.1, Cookie on light are not taken into account for the lightmaps / Lightprobes. This support is always enable with HDRP. \ No newline at end of file +From Unity 2020.1, Cookie on light are not taken into account for the lightmaps / Lightprobes. This support is always enable with HDRP. + +## Default Volume Profile + +From Unity 2020.1, the Default Volume Profile asset has changed so that the Exposure component sets the default Compensation to 0. \ No newline at end of file diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Shadow/ContactShadowsEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Lighting/Shadow/ContactShadowsEditor.cs index 8f365d80abc..a97685d796e 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Shadow/ContactShadowsEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Shadow/ContactShadowsEditor.cs @@ -40,22 +40,19 @@ public override void OnInspectorGUI() if (!m_Enable.value.hasMultipleDifferentValues) { - using (new EditorGUI.DisabledGroupScope(!m_Enable.value.boolValue)) - { - PropertyField(m_Length, EditorGUIUtility.TrTextContent("Length", "Controls the length of the rays HDRP uses to calculate Contact Shadows. Uses meters.")); - PropertyField(m_DistanceScaleFactor, EditorGUIUtility.TrTextContent("Distance Scale Factor", "Dampens the scale up effect HDRP process with distance from the Camera.")); - m_MinDistance.value.floatValue = Mathf.Clamp(m_MinDistance.value.floatValue, 0.0f, m_MaxDistance.value.floatValue); - PropertyField(m_MinDistance, EditorGUIUtility.TrTextContent("Min Distance", "Sets the distance from the camera at which HDRP begins to fade in Contact Shadows. Uses meters.")); - PropertyField(m_MaxDistance, EditorGUIUtility.TrTextContent("Max Distance", "Sets the distance from the Camera at which HDRP begins to fade out Contact Shadows. Uses meters.")); - m_FadeInDistance.value.floatValue = Mathf.Clamp(m_FadeInDistance.value.floatValue, 0.0f, m_MaxDistance.value.floatValue); - PropertyField(m_FadeInDistance, EditorGUIUtility.TrTextContent("Fade In Distance", "Sets the distance over which HDRP fades Contact Shadows in when past the Min Distance. Uses meters.")); - PropertyField(m_FadeDistance, EditorGUIUtility.TrTextContent("Fade Out Distance", "Sets the distance over which HDRP fades Contact Shadows out when at the Max Distance. Uses meters.")); - PropertyField(m_Opacity, EditorGUIUtility.TrTextContent("Opacity", "Controls the opacity of the Contact Shadow.")); - base.OnInspectorGUI(); - GUI.enabled = useCustomValue; - PropertyField(m_SampleCount, EditorGUIUtility.TrTextContent("Sample Count", "Controls the number of samples HDRP uses for ray casting.")); - GUI.enabled = true; - } + PropertyField(m_Length, EditorGUIUtility.TrTextContent("Length", "Controls the length of the rays HDRP uses to calculate Contact Shadows. Uses meters.")); + PropertyField(m_DistanceScaleFactor, EditorGUIUtility.TrTextContent("Distance Scale Factor", "Dampens the scale up effect HDRP process with distance from the Camera.")); + m_MinDistance.value.floatValue = Mathf.Clamp(m_MinDistance.value.floatValue, 0.0f, m_MaxDistance.value.floatValue); + PropertyField(m_MinDistance, EditorGUIUtility.TrTextContent("Min Distance", "Sets the distance from the camera at which HDRP begins to fade in Contact Shadows. Uses meters.")); + PropertyField(m_MaxDistance, EditorGUIUtility.TrTextContent("Max Distance", "Sets the distance from the Camera at which HDRP begins to fade out Contact Shadows. Uses meters.")); + m_FadeInDistance.value.floatValue = Mathf.Clamp(m_FadeInDistance.value.floatValue, 0.0f, m_MaxDistance.value.floatValue); + PropertyField(m_FadeInDistance, EditorGUIUtility.TrTextContent("Fade In Distance", "Sets the distance over which HDRP fades Contact Shadows in when past the Min Distance. Uses meters.")); + PropertyField(m_FadeDistance, EditorGUIUtility.TrTextContent("Fade Out Distance", "Sets the distance over which HDRP fades Contact Shadows out when at the Max Distance. Uses meters.")); + PropertyField(m_Opacity, EditorGUIUtility.TrTextContent("Opacity", "Controls the opacity of the Contact Shadow.")); + base.OnInspectorGUI(); + GUI.enabled = useCustomValue; + PropertyField(m_SampleCount, EditorGUIUtility.TrTextContent("Sample Count", "Controls the number of samples HDRP uses for ray casting.")); + GUI.enabled = true; } } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Eye/ShaderGraph/EyeMasterNode.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Eye/ShaderGraph/EyeMasterNode.cs index db67c7bdc70..bc1fca3d904 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Eye/ShaderGraph/EyeMasterNode.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Eye/ShaderGraph/EyeMasterNode.cs @@ -783,6 +783,7 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera ); HDSubShaderUtilities.AddAlphaCutoffShaderProperties(collector, alphaTest.isOn, false); HDSubShaderUtilities.AddDoubleSidedProperty(collector, doubleSidedMode); + HDSubShaderUtilities.AddPrePostPassProperties(collector, alphaTestDepthPrepass.isOn, alphaTestDepthPostpass.isOn); base.CollectShaderProperties(collector, generationMode); } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Fabric/ShaderGraph/FabricMasterNode.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Fabric/ShaderGraph/FabricMasterNode.cs index dcdbacbe89f..070f81ac458 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Fabric/ShaderGraph/FabricMasterNode.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Fabric/ShaderGraph/FabricMasterNode.cs @@ -794,6 +794,7 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera ); HDSubShaderUtilities.AddAlphaCutoffShaderProperties(collector, alphaTest.isOn, false); HDSubShaderUtilities.AddDoubleSidedProperty(collector, doubleSidedMode); + HDSubShaderUtilities.AddPrePostPassProperties(collector, false, false); base.CollectShaderProperties(collector, generationMode); } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Hair/ShaderGraph/HairMasterNode.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Hair/ShaderGraph/HairMasterNode.cs index 9d7c6df5740..700b2149105 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Hair/ShaderGraph/HairMasterNode.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Hair/ShaderGraph/HairMasterNode.cs @@ -899,6 +899,7 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera ); HDSubShaderUtilities.AddAlphaCutoffShaderProperties(collector, alphaTest.isOn, alphaTestShadow.isOn); HDSubShaderUtilities.AddDoubleSidedProperty(collector, doubleSidedMode); + HDSubShaderUtilities.AddPrePostPassProperties(collector, alphaTestDepthPrepass.isOn, alphaTestDepthPostpass.isOn); base.CollectShaderProperties(collector, generationMode); } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitGUI.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitGUI.cs index f0f3d03b87d..affca5d0f81 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitGUI.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitGUI.cs @@ -14,8 +14,7 @@ class HDLitGUI : HDShaderGUI // For surface option shader graph we only want all unlit features but alpha clip and back then front rendering const SurfaceOptionUIBlock.Features surfaceOptionFeatures = SurfaceOptionUIBlock.Features.Unlit ^ SurfaceOptionUIBlock.Features.AlphaCutoffThreshold - ^ SurfaceOptionUIBlock.Features.BackThenFrontRendering - ^ SurfaceOptionUIBlock.Features.ShowAfterPostProcessPass; + ^ SurfaceOptionUIBlock.Features.BackThenFrontRendering; MaterialUIBlockList uiBlocks = new MaterialUIBlockList { diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitMasterNode.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitMasterNode.cs index 4a416f917a6..e5062d7e708 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitMasterNode.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitMasterNode.cs @@ -1119,6 +1119,7 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera ); HDSubShaderUtilities.AddAlphaCutoffShaderProperties(collector, alphaTest.isOn, alphaTestShadow.isOn); HDSubShaderUtilities.AddDoubleSidedProperty(collector, doubleSidedMode); + HDSubShaderUtilities.AddPrePostPassProperties(collector, alphaTestDepthPrepass.isOn, alphaTestDepthPostpass.isOn); base.CollectShaderProperties(collector, generationMode); } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/StackLitMasterNode.cs b/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/StackLitMasterNode.cs index 5a26461c754..6a212a98848 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/StackLitMasterNode.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/StackLit/ShaderGraph/StackLitMasterNode.cs @@ -1424,6 +1424,7 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera ); HDSubShaderUtilities.AddAlphaCutoffShaderProperties(collector, alphaTest.isOn, false); HDSubShaderUtilities.AddDoubleSidedProperty(collector, doubleSidedMode); + HDSubShaderUtilities.AddPrePostPassProperties(collector, false, false); base.CollectShaderProperties(collector, generationMode); } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs index 053bac86cbd..86bc32c050e 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs @@ -26,6 +26,7 @@ public enum Features ReceiveSSR = 1 << 8, ShowAfterPostProcessPass = 1 << 9, Unlit = Surface | BlendMode | DoubleSided | DoubleSidedNormalMode | AlphaCutoff | AlphaCutoffShadowThreshold | AlphaCutoffThreshold | BackThenFrontRendering | ShowAfterPostProcessPass, + ShowPrePassAndPostPass = 1 << 11, Lit = All, All = ~0, } @@ -483,11 +484,14 @@ void DrawSurfaceGUI() if (transparentBackfaceEnable != null) materialEditor.ShaderProperty(transparentBackfaceEnable, Styles.transparentBackfaceEnableText); - if (transparentDepthPrepassEnable != null) - materialEditor.ShaderProperty(transparentDepthPrepassEnable, Styles.transparentDepthPrepassEnableText); + if ((m_Features & Features.ShowPrePassAndPostPass) != 0) + { + if (transparentDepthPrepassEnable != null) + materialEditor.ShaderProperty(transparentDepthPrepassEnable, Styles.transparentDepthPrepassEnableText); - if (transparentDepthPostpassEnable != null) - materialEditor.ShaderProperty(transparentDepthPostpassEnable, Styles.transparentDepthPostpassEnableText); + if (transparentDepthPostpassEnable != null) + materialEditor.ShaderProperty(transparentDepthPostpassEnable, Styles.transparentDepthPostpassEnableText); + } if (transparentWritingMotionVec != null) materialEditor.ShaderProperty(transparentWritingMotionVec, Styles.transparentWritingMotionVecText); diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/HDShaderGUI.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/HDShaderGUI.cs index 0c887989336..01994b5ccc1 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/HDShaderGUI.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/HDShaderGUI.cs @@ -90,7 +90,8 @@ protected static void ResetMaterialCustomRenderQueue(Material material) } readonly static string[] floatPropertiesToSynchronize = { - "_UseShadowThreshold", kReceivesSSR, kUseSplitLighting + "_UseShadowThreshold", kReceivesSSR, kUseSplitLighting, + kTransparentDepthPrepassEnable, kTransparentDepthPostpassEnable }; protected static void SynchronizeShaderGraphProperties(Material material) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitMasterNode.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitMasterNode.cs index 796960e98f0..3ad1dc98b42 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitMasterNode.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Unlit/ShaderGraph/HDUnlitMasterNode.cs @@ -495,6 +495,7 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera ); HDSubShaderUtilities.AddAlphaCutoffShaderProperties(collector, alphaTest.isOn, false); HDSubShaderUtilities.AddDoubleSidedProperty(collector, doubleSided.isOn ? DoubleSidedMode.Enabled : DoubleSidedMode.Disabled); + HDSubShaderUtilities.AddPrePostPassProperties(collector, false, false); base.CollectShaderProperties(collector, generationMode); } diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs index 527ea9b2e5e..8ea6009a9c8 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Camera/HDCameraUI.Skin.cs @@ -13,7 +13,7 @@ static partial class HDCameraUI const string msaaWarningMessage = "Manual MSAA target set with deferred rendering. This will lead to undefined behavior."; - static readonly GUIContent clearModeContent = EditorGUIUtility.TrTextContent("Background Type", "Specifies the type of background the Camera applies when it clears the screen before rendering a frame."); + static readonly GUIContent clearModeContent = EditorGUIUtility.TrTextContent("Background Type", "Specifies the type of background the Camera applies when it clears the screen before rendering a frame. Be aware that when setting this to None, the background is never cleared and since HDRP shares render texture between cameras, you may end up with garbage from previous rendering."); static readonly GUIContent backgroundColorContent = EditorGUIUtility.TrTextContent("Background Color", "The Background Color used to clear the screen when selecting Background Color before rendering."); static readonly GUIContent cullingMaskContent = EditorGUIUtility.TrTextContent("Culling Mask"); static readonly GUIContent volumeLayerMaskContent = EditorGUIUtility.TrTextContent("Volume Layer Mask"); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs index 3a5972baca5..38e6edc192a 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/FrameSettingsUI.Drawers.cs @@ -105,8 +105,11 @@ internal static CED.IDrawer InspectorInnerbox(bool withOverride = true) => CED.G RenderPipelineSettings hdrpSettings = GetHDRPAssetFor(owner).currentPlatformRenderPipelineSettings; if (hdrpSettings.supportRayTracing) { - if (serialized.IsEnabled(FrameSettingsField.AsyncCompute) ?? false) - EditorGUILayout.HelpBox("With Raytracing, the Asynchronous Execution will be forced to false", MessageType.Warning); + bool rtEffectUseAsync = (serialized.IsEnabled(FrameSettingsField.SSRAsync) ?? false) || (serialized.IsEnabled(FrameSettingsField.SSAOAsync) ?? false) + //|| (serialized.IsEnabled(FrameSettingsField.ContactShadowsAsync) ?? false) // Contact shadow async is not visible in the UI for now and defaults to true. + ; + if (rtEffectUseAsync) + EditorGUILayout.HelpBox("Asynchronous execution of Raytracing effects is not supported. Asynchronous Execution will be forced to false for them", MessageType.Warning); } })); diff --git a/com.unity.render-pipelines.high-definition/Editor/RenderPipelineResources/DefaultSettingsVolumeProfile.asset b/com.unity.render-pipelines.high-definition/Editor/RenderPipelineResources/DefaultSettingsVolumeProfile.asset index a5fe482a2e2..86c0e736098 100644 --- a/com.unity.render-pipelines.high-definition/Editor/RenderPipelineResources/DefaultSettingsVolumeProfile.asset +++ b/com.unity.render-pipelines.high-definition/Editor/RenderPipelineResources/DefaultSettingsVolumeProfile.asset @@ -87,10 +87,18 @@ MonoBehaviour: m_OverrideState: 0 m_Value: 50 min: 0 + minDistance: + m_OverrideState: 0 + m_Value: 0 + min: 0 fadeDistance: m_OverrideState: 0 m_Value: 5 min: 0 + fadeInDistance: + m_OverrideState: 0 + m_Value: 0 + min: 0 m_SampleCount: m_OverrideState: 1 m_Value: 12 @@ -322,8 +330,8 @@ MonoBehaviour: m_OverrideState: 0 m_Value: 0 compensation: - m_OverrideState: 1 - m_Value: 1 + m_OverrideState: 0 + m_Value: 0 limitMin: m_OverrideState: 0 m_Value: -10 diff --git a/com.unity.render-pipelines.high-definition/Editor/ShaderGraph/HDSubShaderUtilities.cs b/com.unity.render-pipelines.high-definition/Editor/ShaderGraph/HDSubShaderUtilities.cs index f82016794c1..53e7f002fa0 100644 --- a/com.unity.render-pipelines.high-definition/Editor/ShaderGraph/HDSubShaderUtilities.cs +++ b/com.unity.render-pipelines.high-definition/Editor/ShaderGraph/HDSubShaderUtilities.cs @@ -1336,6 +1336,12 @@ public static void AddDoubleSidedProperty(PropertyCollector collector, DoubleSid }); } + public static void AddPrePostPassProperties(PropertyCollector collector, bool prepass, bool postpass) + { + collector.AddToggleProperty(kTransparentDepthPrepassEnable, prepass); + collector.AddToggleProperty(kTransparentDepthPostpassEnable, postpass); + } + public static string RenderQueueName(HDRenderQueue.RenderQueueType value) { switch (value) diff --git a/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs index ce918bb696b..26a6e07fb47 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Sky/AtmosphericScattering/FogEditor.cs @@ -106,22 +106,20 @@ public override void OnInspectorGUI() if (volumetricLightingAvailable) { PropertyField(m_EnableVolumetricFog, s_EnableVolumetricFog); - if (m_EnableVolumetricFog.value.boolValue) + + EditorGUI.indentLevel++; + PropertyField(m_Albedo, s_AlbedoLabel); + PropertyField(m_Anisotropy, s_AnisotropyLabel); + PropertyField(m_GlobalLightProbeDimmer, s_GlobalLightProbeDimmerLabel); + + if (isInAdvancedMode) { - EditorGUI.indentLevel++; - PropertyField(m_Albedo, s_AlbedoLabel); - PropertyField(m_Anisotropy, s_AnisotropyLabel); - PropertyField(m_GlobalLightProbeDimmer, s_GlobalLightProbeDimmerLabel); - - if (isInAdvancedMode) - { - PropertyField(m_DepthExtent); - PropertyField(m_SliceDistributionUniformity); - PropertyField(m_Filter); - } - - EditorGUI.indentLevel--; + PropertyField(m_DepthExtent); + PropertyField(m_SliceDistributionUniformity); + PropertyField(m_Filter); } + + EditorGUI.indentLevel--; } } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Sky/HDLightingWindowEnvironmentSection.cs b/com.unity.render-pipelines.high-definition/Editor/Sky/HDLightingWindowEnvironmentSection.cs index 813fdf8a5cd..682cba36804 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Sky/HDLightingWindowEnvironmentSection.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Sky/HDLightingWindowEnvironmentSection.cs @@ -32,17 +32,13 @@ class SerializedStaticLightingSky { SerializedObject serializedObject; public SerializedProperty skyUniqueID; - - public VolumeProfile volumeProfile - { - get => (serializedObject.targetObject as StaticLightingSky).profile; - set => (serializedObject.targetObject as StaticLightingSky).profile = value; - } + public SerializedProperty profile; public SerializedStaticLightingSky(StaticLightingSky staticLightingSky) { serializedObject = new SerializedObject(staticLightingSky); skyUniqueID = serializedObject.FindProperty("m_StaticLightingSkyUniqueID"); + profile = serializedObject.FindProperty("m_Profile"); } public void Apply() => serializedObject.ApplyModifiedProperties(); @@ -174,10 +170,10 @@ void DrawGUI() ++EditorGUI.indentLevel; //cannot use SerializeProperty due to logic in the property - var profile = m_SerializedActiveSceneLightingSky.volumeProfile; - var newProfile = EditorGUILayout.ObjectField(EditorGUIUtility.TrTextContent("Profile"), profile, typeof(VolumeProfile), allowSceneObjects: false) as VolumeProfile; + var profile = m_SerializedActiveSceneLightingSky.profile.objectReferenceValue; + var newProfile = EditorGUILayout.ObjectField(EditorGUIUtility.TrTextContent("Profile"), m_SerializedActiveSceneLightingSky.profile.objectReferenceValue, typeof(VolumeProfile), allowSceneObjects: false) as VolumeProfile; if (profile != newProfile) - m_SerializedActiveSceneLightingSky.volumeProfile = newProfile; + m_SerializedActiveSceneLightingSky.profile.objectReferenceValue = newProfile; using (new EditorGUI.DisabledScope(m_SkyClassNames.Count == 1)) // Only "None" { @@ -204,7 +200,7 @@ void UpdateSkyIntPopupData() m_SkyClassNames.Add(new GUIContent("None")); m_SkyUniqueIDs.Add(0); - VolumeProfile profile = m_SerializedActiveSceneLightingSky.volumeProfile; + VolumeProfile profile = m_SerializedActiveSceneLightingSky.profile.objectReferenceValue as VolumeProfile; if (profile != null) { var skyTypesDict = SkyManager.skyTypesDict; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDProbe.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDProbe.cs index d7acda444b7..145981a32b3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDProbe.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/HDProbe.cs @@ -428,6 +428,13 @@ public virtual void PrepareCulling() { } /// public void RequestRenderNextUpdate() => m_WasRenderedSinceLastOnDemandRequest = false; + // Forces the re-rendering for both OnDemand and OnEnable + internal void ForceRenderingNextUpdate() + { + m_WasRenderedSinceLastOnDemandRequest = false; + wasRenderedAfterOnEnable = false; + } + void UpdateProbeName() { // TODO: ask if this is ok: diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl index ab216729cbc..821ee5814e8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl @@ -494,7 +494,7 @@ float4 GetBlendMask(LayerTexCoord layerTexCoord, float4 vertexColor, bool useLod // It also means that when using wind, users can't use vertex color to modulate the effect of influence from the main layer. float4 maskVertexColor = vertexColor; #if defined(_LAYER_MASK_VERTEX_COLOR_MUL) - blendMasks *= maskVertexColor; + blendMasks *= saturate(maskVertexColor); #elif defined(_LAYER_MASK_VERTEX_COLOR_ADD) blendMasks = saturate(blendMasks + maskVertexColor * 2.0 - 1.0); #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl index 06951a7e204..eff35477336 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDecalData.hlsl @@ -16,7 +16,7 @@ void ApplyDecalToSurfaceData(DecalSurfaceData decalSurfaceData, inout SurfaceDat #ifdef DECALS_4RT // only smoothness in 3RT mode #ifdef _MATERIAL_FEATURE_SPECULAR_COLOR float3 decalSpecularColor = ComputeFresnel0((decalSurfaceData.HTileMask & DBUFFERHTILEBIT_DIFFUSE) ? decalSurfaceData.baseColor.xyz : float3(1.0, 1.0, 1.0), decalSurfaceData.mask.x, DEFAULT_SPECULAR_VALUE); - surfaceData.specularColor = surfaceData.specularColor * decalSurfaceData.MAOSBlend.x + decalSpecularColor; + surfaceData.specularColor = surfaceData.specularColor * decalSurfaceData.MAOSBlend.x + decalSpecularColor * (1.0f - decalSurfaceData.MAOSBlend.x); #else surfaceData.metallic = surfaceData.metallic * decalSurfaceData.MAOSBlend.x + decalSurfaceData.mask.x; #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs index 08419191dcb..114ccae3f06 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs @@ -350,10 +350,6 @@ void RenderSubsurfaceScattering(HDCamera hdCamera, CommandBuffer cmd, RTHandle c // Bind the textures for ray generation cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._DepthTexture, sharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._NormalBufferTexture, sharedRTManager.GetNormalBuffer()); - cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._GBufferTexture[0], m_GbufferManager.GetBuffer(0)); - cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._GBufferTexture[1], m_GbufferManager.GetBuffer(1)); - cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._GBufferTexture[2], m_GbufferManager.GetBuffer(2)); - cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._GBufferTexture[3], m_GbufferManager.GetBuffer(3)); cmd.SetRayTracingTextureParam(subSurfaceShader, HDShaderIDs._SSSBufferTexture, m_SSSColor); cmd.SetGlobalTexture(HDShaderIDs._StencilTexture, sharedRTManager.GetDepthStencilBuffer(), RenderTextureSubElement.Stencil); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index f935ef4e77a..d59f6cc0911 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Collections.Generic; using System.Linq; using Utilities; @@ -18,6 +19,7 @@ namespace UnityEngine.Rendering.HighDefinition /// HDCamera class. /// This class holds all information for a given camera. Constants used for shading as well as buffers persistent from one frame to another etc. /// + [DebuggerDisplay("({camera.name})")] public class HDCamera { #region Public API @@ -254,6 +256,9 @@ internal HDAdditionalCameraData.ClearColorMode clearColorMode } } + HDAdditionalCameraData.ClearColorMode m_PreviousClearColorMode = HDAdditionalCameraData.ClearColorMode.None; + + internal Color backgroundColorHDR { get @@ -555,6 +560,20 @@ internal static void CleanUnused() s_Cleanup.Clear(); } + internal static void ResetAllHistoryRTHandleSystems(int width, int height) + { + foreach (var kvp in s_Cameras) + { + var hdCamera = kvp.Value; + var currentHistorySize = hdCamera.m_HistoryRTSystem.rtHandleProperties.currentRenderTargetSize; + // We only reset if the new size if smaller than current reference (otherwise we might increase the size of off screen camera with lower resolution than the new reference. + if (width < currentHistorySize.x || height < currentHistorySize.y) + { + hdCamera.m_HistoryRTSystem.ResetReferenceSize(width, height); + } + } + } + // Set up UnityPerView CBuffer. internal void SetupGlobalParams(CommandBuffer cmd, int frameCount) { @@ -864,9 +883,11 @@ void UpdateAntialiasing() } // When changing antialiasing mode to TemporalAA we must reset the history, otherwise we get one frame of garbage - if (previousAntialiasing != antialiasing && antialiasing == AntialiasingMode.TemporalAntialiasing) + if ( (previousAntialiasing != antialiasing && antialiasing == AntialiasingMode.TemporalAntialiasing) + || (m_PreviousClearColorMode != clearColorMode)) { resetPostProcessingHistory = true; + m_PreviousClearColorMode = clearColorMode; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LookDev.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LookDev.cs index b8cc17d3187..1d3aa84ec17 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LookDev.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LookDev.cs @@ -5,6 +5,10 @@ namespace UnityEngine.Rendering.HighDefinition { public partial class HDRenderPipeline : IDataProvider { +#if UNITY_EDITOR + int m_LookDevVolumeProfileHash = -1; +#endif + struct LookDevDataForHDRP { public HDAdditionalCameraData additionalCameraData; @@ -14,6 +18,65 @@ struct LookDevDataForHDRP public Volume volume; } +#if UNITY_EDITOR + bool UpdateVolumeProfile(Volume volume, out VisualEnvironment visualEnvironment, out HDRISky sky) + { + HDRenderPipelineAsset hdrpAsset = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset; + if (hdrpAsset.defaultLookDevProfile == null) + hdrpAsset.defaultLookDevProfile = hdrpAsset.renderPipelineEditorResources.lookDev.defaultLookDevVolumeProfile; + + int newHashCode = hdrpAsset.defaultLookDevProfile.GetHashCode(); + if (newHashCode != m_LookDevVolumeProfileHash) + { + VolumeProfile oldProfile = volume.sharedProfile; + + m_LookDevVolumeProfileHash = newHashCode; + + VolumeProfile profile = ScriptableObject.Instantiate(hdrpAsset.defaultLookDevProfile); + volume.sharedProfile = profile; + + // Remove potentially existing components in the user profile. + if (profile.TryGet(out visualEnvironment)) + profile.Remove(); + + if (profile.TryGet(out sky)) + profile.Remove(); + + // If there was a profile before we needed to re-instantiate the new profile, we need to copy the data over for sky settings. + if (oldProfile != null) + { + if (oldProfile.TryGet(out HDRISky oldSky)) + { + sky = Object.Instantiate(oldSky); + profile.components.Add(sky); + } + if (oldProfile.TryGet(out VisualEnvironment oldVisualEnv)) + { + visualEnvironment = Object.Instantiate(oldVisualEnv); + profile.components.Add(visualEnvironment); + } + + CoreUtils.Destroy(oldProfile); + } + else + { + visualEnvironment = profile.Add(); + visualEnvironment.skyType.Override((int)SkyType.HDRI); + visualEnvironment.skyAmbientMode.Override(SkyAmbientMode.Dynamic); + sky = profile.Add(); + } + + return true; + } + else + { + visualEnvironment = null; + sky = null; + return false; + } + } +#endif + /// /// This hook allows HDRP to init the scene when creating the view /// @@ -51,24 +114,11 @@ void IDataProvider.FirstInitScene(StageRuntimeInterface SRI) volume.priority = float.MaxValue; volume.enabled = false; -#if UNITY_EDITOR - HDRenderPipelineAsset hdrpAsset = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset; - if (hdrpAsset.defaultLookDevProfile == null) - hdrpAsset.defaultLookDevProfile = hdrpAsset.renderPipelineEditorResources.lookDev.defaultLookDevVolumeProfile; - VolumeProfile profile = ScriptableObject.Instantiate(hdrpAsset.defaultLookDevProfile); - volume.sharedProfile = profile; - VisualEnvironment visualEnvironment; - if (profile.TryGet(out visualEnvironment)) - profile.Remove(); - visualEnvironment = profile.Add(); - visualEnvironment.skyType.Override((int)SkyType.HDRI); - visualEnvironment.skyAmbientMode.Override(SkyAmbientMode.Dynamic); - - HDRISky sky; - if (profile.TryGet(out sky)) - profile.Remove(); - sky = profile.Add(); +#if UNITY_EDITOR + // Make sure we invalidate the current volume when first loading a scene. + m_LookDevVolumeProfileHash = -1; + UpdateVolumeProfile(volume, out var visualEnvironment, out var sky); SRI.SRPData = new LookDevDataForHDRP() { @@ -79,7 +129,7 @@ void IDataProvider.FirstInitScene(StageRuntimeInterface SRI) volume = volume }; #else - //remove unasigned warnings when building + //remove unassigned warnings when building SRI.SRPData = new LookDevDataForHDRP() { additionalCameraData = null, @@ -122,6 +172,15 @@ void IDataProvider.UpdateSky(Camera camera, Sky sky, StageRuntimeInterface SRI) void IDataProvider.OnBeginRendering(StageRuntimeInterface SRI) { LookDevDataForHDRP data = (LookDevDataForHDRP)SRI.SRPData; +#if UNITY_EDITOR + // The default volume can change in the HDRP asset so if it does we need to re-instantiate it. + if (UpdateVolumeProfile(data.volume, out var visualEnv, out var sky)) + { + data.sky = sky; + data.visualEnvironment = visualEnv; + SRI.SRPData = data; + } +#endif data.volume.enabled = true; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index ec15219e6f3..b7678a90b1b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -103,6 +103,12 @@ internal static Volume GetOrCreateDefaultVolume() readonly PostProcessSystem m_PostProcessSystem; readonly XRSystem m_XRSystem; + // Keep track of previous Graphic and QualitySettings value to reset when switching to another pipeline + bool m_PreviousLightsUseLinearIntensity; + bool m_PreviousLightsUseColorTemperature; + bool m_PreviousSRPBatcher; + ShadowmaskMode m_PreviousShadowMaskMode; + bool m_FrameSettingsHistoryEnabled = false; #if UNITY_EDITOR bool m_PreviousEnableCookiesInLightmapper = false; @@ -561,6 +567,20 @@ void ValidateResources() #endif + /// + /// Resets the reference size of the internal RTHandle System. + /// This allows users to reduce the memory footprint of render textures after doing a super sampled rendering pass for example. + /// + /// New width of the internal RTHandle System. + /// New height of the internal RTHandle System. + public void ResetRTHandleReferenceSize(int width, int height) + { + RTHandles.ResetReferenceSize(width, height); + HDCamera.ResetAllHistoryRTHandleSystems(width, height); + if (m_RenderGraph != null) + m_RenderGraph.ResetRTHandleReferenceSize(width, height); + } + void InitializeRenderTextures() { RenderPipelineSettings settings = m_Asset.currentPlatformRenderPipelineSettings; @@ -663,16 +683,22 @@ void SetRenderingFeatures() Shader.globalRenderPipeline = "HDRenderPipeline"; // HD use specific GraphicsSettings + m_PreviousLightsUseLinearIntensity = GraphicsSettings.lightsUseLinearIntensity; GraphicsSettings.lightsUseLinearIntensity = true; + m_PreviousLightsUseColorTemperature = GraphicsSettings.lightsUseColorTemperature; GraphicsSettings.lightsUseColorTemperature = true; - + m_PreviousSRPBatcher = GraphicsSettings.useScriptableRenderPipelineBatching; GraphicsSettings.useScriptableRenderPipelineBatching = m_Asset.enableSRPBatcher; + // In case shadowmask mode isn't setup correctly, force it to correct usage (as there is no UI to fix it) + m_PreviousShadowMaskMode = QualitySettings.shadowmaskMode; + QualitySettings.shadowmaskMode = ShadowmaskMode.DistanceShadowmask; + SupportedRenderingFeatures.active = new SupportedRenderingFeatures() { reflectionProbeModes = SupportedRenderingFeatures.ReflectionProbeModes.Rotation, defaultMixedLightingModes = SupportedRenderingFeatures.LightmapMixedBakeModes.IndirectOnly, - mixedLightingModes = SupportedRenderingFeatures.LightmapMixedBakeModes.IndirectOnly | SupportedRenderingFeatures.LightmapMixedBakeModes.Shadowmask, + mixedLightingModes = SupportedRenderingFeatures.LightmapMixedBakeModes.IndirectOnly | (m_Asset.currentPlatformRenderPipelineSettings.supportShadowMask ? SupportedRenderingFeatures.LightmapMixedBakeModes.Shadowmask : 0), lightmapBakeTypes = LightmapBakeType.Baked | LightmapBakeType.Mixed | LightmapBakeType.Realtime, lightmapsModes = LightmapsMode.NonDirectional | LightmapsMode.CombinedDirectional, lightProbeProxyVolumes = true, @@ -688,6 +714,8 @@ void SetRenderingFeatures() , overridesLODBias = true , overridesMaximumLODLevel = true , terrainDetailUnsupported = true + , overridesShadowmask = true // Don't display the shadow mask UI in Quality Settings + , overridesRealtimeReflectionProbes = true // Don't display the real time reflection probes checkbox UI in Quality Settings }; Lightmapping.SetDelegate(GlobalIlluminationUtils.hdLightsDelegate); @@ -781,10 +809,12 @@ void UnsetRenderingFeatures() { Shader.globalRenderPipeline = ""; - SupportedRenderingFeatures.active = new SupportedRenderingFeatures(); + GraphicsSettings.lightsUseLinearIntensity = m_PreviousLightsUseLinearIntensity; + GraphicsSettings.lightsUseColorTemperature = m_PreviousLightsUseColorTemperature; + GraphicsSettings.useScriptableRenderPipelineBatching = m_PreviousSRPBatcher; + QualitySettings.shadowmaskMode = m_PreviousShadowMaskMode; - // Reset srp batcher state just in case - GraphicsSettings.useScriptableRenderPipelineBatching = false; + SupportedRenderingFeatures.active = new SupportedRenderingFeatures(); Lightmapping.ResetDelegate(); @@ -955,7 +985,7 @@ void DisposeProbeCameraPool() // Dispose of Render Pipeline can be call either by OnValidate() or by OnDisable(). // Inside an OnValidate() call we can't call a DestroyImmediate(). // Here we are releasing our singleton to not leak while doing a domain reload. - // However this is doing a call to DestroyImmediate(). + // However this is doing a call to DestroyImmediate(). // To workaround this, and was we only leak with Singleton while doing domain reload (and not in OnValidate) // we are detecting if we are in an OnValidate call and releasing the Singleton only if it is not the case. if (!m_Asset.isInOnValidateCall) @@ -1056,6 +1086,10 @@ void PushGlobalParams(HDCamera hdCamera, CommandBuffer cmd) // Bind the camera's ray tracing frame index cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, RayTracingFrameIndex(hdCamera)); } + else + { + cmd.SetGlobalInt(HDShaderIDs._RaytracedIndirectDiffuse, 0); + } cmd.SetGlobalFloat(HDShaderIDs._ContactShadowOpacity, m_ContactShadows.opacity.value); } } @@ -1613,6 +1647,14 @@ ref _cullingResults continue; } + // HACK! We render the probe until we know the ambient probe for the associated sky context is ready. + // For one-off rendering the dynamic ambient probe will be set to black until they are not processed, leading to faulty rendering. + // So we enqueue another rendering and then we will not set the probe texture until we have rendered with valid ambient probe. + if (!m_SkyManager.HasSetValidAmbientProbe(hdCamera)) + { + visibleProbe.ForceRenderingNextUpdate(); + } + hdCamera.parentCamera = parentCamera; // Used to inherit the properties of the view HDAdditionalCameraData hdCam; @@ -1659,26 +1701,30 @@ ref _cullingResults // TODO: store DecalCullResult }; - // As we render realtime texture on GPU side, we must tag the texture so our texture array cache detect that something have change - visibleProbe.realtimeTexture.IncrementUpdateCount(); - - if (cameraSettings.Count > 1) + if (m_SkyManager.HasSetValidAmbientProbe(hdCamera)) { - var face = (CubemapFace)j; - request.target = new RenderRequest.Target + // As we render realtime texture on GPU side, we must tag the texture so our texture array cache detect that something have change + visibleProbe.realtimeTexture.IncrementUpdateCount(); + + if (cameraSettings.Count > 1) { - copyToTarget = visibleProbe.realtimeTexture, - face = face - }; - } - else - { - request.target = new RenderRequest.Target + var face = (CubemapFace)j; + request.target = new RenderRequest.Target + { + copyToTarget = visibleProbe.realtimeTexture, + face = face + }; + } + else { - id = visibleProbe.realtimeTexture, - face = CubemapFace.Unknown - }; + request.target = new RenderRequest.Target + { + id = visibleProbe.realtimeTexture, + face = CubemapFace.Unknown + }; + } } + renderRequests.Add(request); @@ -1960,7 +2006,6 @@ AOVRequestData aovRequest m_PostProcessSystem.BeginFrame(cmd, hdCamera, this); ApplyDebugDisplaySettings(hdCamera, cmd); - m_SkyManager.UpdateCurrentSkySettings(hdCamera); SetupCameraProperties(hdCamera, renderContext, cmd); @@ -2737,6 +2782,7 @@ ref HDCullingResults cullingResults hdProbeCullState = HDProbeSystem.PrepareCull(camera); // We need to set the ambient probe here because it's passed down to objects during the culling process. + skyManager.UpdateCurrentSkySettings(hdCamera); skyManager.SetupAmbientProbe(hdCamera); using (new ProfilingScope(null, ProfilingSampler.Get(HDProfileId.CullResultsCull))) @@ -3122,7 +3168,7 @@ void RenderDBuffer(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext { // We still bind black textures to make sure that something is bound (can be a problem on some platforms) m_DbufferManager.BindBlackTextures(cmd); - + // Bind buffer to make sure that something is bound . cmd.SetGlobalBuffer(HDShaderIDs._DecalPropertyMaskBufferSRV, m_DbufferManager.propertyMaskBuffer); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace index faffd8f5997..85762c9926e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/RayTracingSubSurface.raytrace @@ -66,13 +66,9 @@ void RayGenSubSurface() PositionInputs posInput = GetPositionInput(currentPixelCoord, 1.0/LaunchDim.xy, depthValue, UNITY_MATRIX_I_VP, GetWorldToViewMatrix(), 0); posInput.positionWS = GetAbsolutePositionWS(posInput.positionWS); - // Read the bsdf data and builtin data from the gbuffer - BSDFData bsdfData; - ZERO_INITIALIZE(BSDFData, bsdfData); - BuiltinData builtinData; - ZERO_INITIALIZE(BuiltinData, builtinData); - uint featureFlags = MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; - DecodeFromGBuffer(currentPixelCoord, featureFlags, bsdfData, builtinData); + // Read the normal data + NormalData normalData; + DecodeFromNormalBuffer(currentPixelCoord, normalData); // Read the SSS Data SSSData sssData; @@ -88,7 +84,7 @@ void RayGenSubSurface() // Do our walk ScatteringResult scatteringResult; - ScatteringWalk(bsdfData.normalWS, bsdfData.diffuseColor, scatteringDistance, currentPixelCoord, globalSampleIndex, posInput.positionWS, scatteringResult); + ScatteringWalk(normalData.normalWS, sssData.diffuseColor, scatteringDistance, currentPixelCoord, globalSampleIndex, posInput.positionWS, scatteringResult); // Normalize the throughput scatteringResult.outputThroughput /= (float)_RaytracingNumSamples; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Shadows/SphericalQuad.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Shadows/SphericalQuad.hlsl index a2edee5e38f..48f5b932b71 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Shadows/SphericalQuad.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/Shaders/Shadows/SphericalQuad.hlsl @@ -1,7 +1,11 @@ +// I am not sure why exactly, by a lower epsilon generates ray that even if they give a valid result with ray tracing +// nuke the performance. Changing the epsilon from 1e-6 to 1e-5 seems to solve the issue. +#define PLANE_INTERSECTION_EPSILON 1e-5 + bool IntersectPlane(float3 ray_origin, float3 ray_dir, float3 pos, float3 normal, out float t) { float denom = dot(normal, ray_dir); - if (abs(denom) > 1e-6) + if (abs(denom) > PLANE_INTERSECTION_EPSILON) { float3 d = pos - ray_origin; t = dot(d, normal) / denom; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSky.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSky.cs index 202f4be7312..03bb3b49385 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSky.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSky.cs @@ -289,24 +289,6 @@ internal int GetPrecomputationHashCode() unchecked { #if UNITY_2019_3 // In 2019.3, when we call GetHashCode on a VolumeParameter it generate garbage (due to the boxing of the generic parameter) - // These parameters affect precomputation. - hash = hash * 23 + earthPreset.value.GetHashCode(); - hash = hash * 23 + planetaryRadius.value.GetHashCode(); - hash = hash * 23 + groundTint.value.GetHashCode(); - - hash = hash * 23 + airMaximumAltitude.value.GetHashCode(); - hash = hash * 23 + airDensityR.value.GetHashCode(); - hash = hash * 23 + airDensityG.value.GetHashCode(); - hash = hash * 23 + airDensityB.value.GetHashCode(); - hash = hash * 23 + airTint.value.GetHashCode(); - - hash = hash * 23 + aerosolMaximumAltitude.value.GetHashCode(); - hash = hash * 23 + aerosolDensity.value.GetHashCode(); - hash = hash * 23 + aerosolTint.value.GetHashCode(); - hash = hash * 23 + aerosolAnisotropy.value.GetHashCode(); - - hash = hash * 23 + numberOfBounces.value.GetHashCode(); - // These parameters affect precomputation. hash = hash * 23 + earthPreset.overrideState.GetHashCode(); hash = hash * 23 + planetaryRadius.overrideState.GetHashCode(); @@ -376,32 +358,6 @@ public override int GetHashCode() { #if UNITY_2019_3 // In 2019.3, when we call GetHashCode on a VolumeParameter it generate garbage (due to the boxing of the generic parameter) // These parameters do NOT affect precomputation. - hash = hash * 23 + sphericalMode.value.GetHashCode(); - hash = hash * 23 + seaLevel.value.GetHashCode(); - hash = hash * 23 + planetCenterPosition.value.GetHashCode(); - hash = hash * 23 + planetRotation.value.GetHashCode(); - - if (groundColorTexture.value != null) - hash = hash * 23 + groundColorTexture.value.GetHashCode(); - - if (groundEmissionTexture.value != null) - hash = hash * 23 + groundEmissionTexture.value.GetHashCode(); - - hash = hash * 23 + groundEmissionMultiplier.value.GetHashCode(); - - hash = hash * 23 + spaceRotation.value.GetHashCode(); - - if (spaceEmissionTexture.value != null) - hash = hash * 23 + spaceEmissionTexture.value.GetHashCode(); - - hash = hash * 23 + spaceEmissionMultiplier.value.GetHashCode(); - hash = hash * 23 + colorSaturation.value.GetHashCode(); - hash = hash * 23 + alphaSaturation.value.GetHashCode(); - hash = hash * 23 + alphaMultiplier.value.GetHashCode(); - hash = hash * 23 + horizonTint.value.GetHashCode(); - hash = hash * 23 + zenithTint.value.GetHashCode(); - hash = hash * 23 + horizonZenithShift.value.GetHashCode(); - hash = hash * 23 + sphericalMode.overrideState.GetHashCode(); hash = hash * 23 + seaLevel.overrideState.GetHashCode(); hash = hash * 23 + planetCenterPosition.overrideState.GetHashCode(); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs index 6c206f55888..03767aec550 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs @@ -1,10 +1,291 @@ using System; +using System.Collections.Generic; using UnityEngine.Experimental.Rendering; namespace UnityEngine.Rendering.HighDefinition { class PhysicallyBasedSkyRenderer : SkyRenderer { + class PrecomputationCache + { + class RefCountedData + { + public int refCount; + public PrecomputationData data = new PrecomputationData(); + } + + ObjectPool m_DataPool = new ObjectPool(null, null); + Dictionary m_CachedData = new Dictionary(); + + public PrecomputationData Get(int hash) + { + RefCountedData result; + if (m_CachedData.TryGetValue(hash, out result)) + { + result.refCount++; + return result.data; + } + else + { + result = m_DataPool.Get(); + result.refCount = 1; + result.data.Allocate(); + m_CachedData.Add(hash, result); + return result.data; + } + } + + public void Release(int hash) + { + if (m_CachedData.TryGetValue(hash, out var result)) + { + result.refCount--; + if (result.refCount == 0) + { + result.data.Release(); + m_CachedData.Remove(hash); + m_DataPool.Release(result); + } + } + } + } + + class PrecomputationData + { + // We compute at most one bounce per frame for perf reasons. + // We need to store the frame index because more than one render can happen during a frame (cubemap update + regular rendering). + int m_LastPrecomputedBounce; + int m_LastFrameComputation; + + RTHandle[] m_GroundIrradianceTables; // All orders, one order + RTHandle[] m_InScatteredRadianceTables; // Air SS, Aerosol SS, Atmosphere MS, Atmosphere one order, Temp + + RTHandle AllocateGroundIrradianceTable(int index) + { + var table = RTHandles.Alloc((int)PbrSkyConfig.GroundIrradianceTableSize, 1, + colorFormat: s_ColorFormat, + enableRandomWrite: true, + name: string.Format("GroundIrradianceTable{0}", index)); + + Debug.Assert(table != null); + + return table; + } + + RTHandle AllocateInScatteredRadianceTable(int index) + { + // Emulate a 4D texture with a "deep" 3D texture. + var table = RTHandles.Alloc((int)PbrSkyConfig.InScatteredRadianceTableSizeX, + (int)PbrSkyConfig.InScatteredRadianceTableSizeY, + (int)PbrSkyConfig.InScatteredRadianceTableSizeZ * + (int)PbrSkyConfig.InScatteredRadianceTableSizeW, + dimension: TextureDimension.Tex3D, + colorFormat: s_ColorFormat, + enableRandomWrite: true, + name: string.Format("InScatteredRadianceTable{0}", index)); + + Debug.Assert(table != null); + + return table; + } + + public void Allocate() + { + m_LastFrameComputation = -1; + m_LastPrecomputedBounce = 0; + + // No temp tables. + m_GroundIrradianceTables = new RTHandle[2]; + m_GroundIrradianceTables[0] = AllocateGroundIrradianceTable(0); + + m_InScatteredRadianceTables = new RTHandle[5]; + m_InScatteredRadianceTables[0] = AllocateInScatteredRadianceTable(0); + m_InScatteredRadianceTables[1] = AllocateInScatteredRadianceTable(1); + m_InScatteredRadianceTables[2] = AllocateInScatteredRadianceTable(2); + } + + public void Release() + { + RTHandles.Release(m_GroundIrradianceTables[0]); m_GroundIrradianceTables[0] = null; + RTHandles.Release(m_GroundIrradianceTables[1]); m_GroundIrradianceTables[1] = null; + RTHandles.Release(m_InScatteredRadianceTables[0]); m_InScatteredRadianceTables[0] = null; + RTHandles.Release(m_InScatteredRadianceTables[1]); m_InScatteredRadianceTables[1] = null; + RTHandles.Release(m_InScatteredRadianceTables[2]); m_InScatteredRadianceTables[2] = null; + RTHandles.Release(m_InScatteredRadianceTables[3]); m_InScatteredRadianceTables[3] = null; + RTHandles.Release(m_InScatteredRadianceTables[4]); m_InScatteredRadianceTables[4] = null; + } + + void PrecomputeTables(CommandBuffer cmd) + { + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.InScatteredRadiancePrecomputation))) + { + int order = m_LastPrecomputedBounce + 1; + { + // For efficiency reasons, multiple scattering is computed in 2 passes: + // 1. Gather the in-scattered radiance over the entire sphere of directions. + // 2. Accumulate the in-scattered radiance along the ray. + // Single scattering performs both steps during the same pass. + + int firstPass = Math.Min(order - 1, 2); + int accumPass = 3; + int numPasses = Math.Min(order, 2); + + for (int i = 0; i < numPasses; i++) + { + int pass = (i == 0) ? firstPass : accumPass; + + switch (pass) + { + case 0: + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AirSingleScatteringTable, m_InScatteredRadianceTables[0]); + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AerosolSingleScatteringTable, m_InScatteredRadianceTables[1]); + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[2]); // MS orders + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTableOrder, m_InScatteredRadianceTables[3]); // One order + break; + case 1: + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._GroundIrradianceTexture, m_GroundIrradianceTables[1]); // One order + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[4]); // Temp + break; + case 2: + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[3]); // One order + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._GroundIrradianceTexture, m_GroundIrradianceTables[1]); // One order + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[4]); // Temp + break; + case 3: + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[4]); // Temp + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTableOrder, m_InScatteredRadianceTables[3]); // One order + cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[2]); // MS orders + break; + default: + Debug.Assert(false); + break; + } + + // Re-illuminate the sky with each bounce. + // Emulate a 4D dispatch with a "deep" 3D dispatch. + cmd.DispatchCompute(s_InScatteredRadiancePrecomputationCS, pass, (int)PbrSkyConfig.InScatteredRadianceTableSizeX / 4, + (int)PbrSkyConfig.InScatteredRadianceTableSizeY / 4, + (int)PbrSkyConfig.InScatteredRadianceTableSizeZ / 4 * + (int)PbrSkyConfig.InScatteredRadianceTableSizeW); + } + + { + // Used by all passes. + cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._GroundIrradianceTable, m_GroundIrradianceTables[0]); // All orders + cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._GroundIrradianceTableOrder, m_GroundIrradianceTables[1]); // One order + } + + switch (firstPass) + { + case 0: + break; + case 1: + cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); + cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); + break; + case 2: + cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[3]); // One order + break; + default: + Debug.Assert(false); + break; + } + + // Re-illuminate the ground with each bounce. + cmd.DispatchCompute(s_GroundIrradiancePrecomputationCS, firstPass, (int)PbrSkyConfig.GroundIrradianceTableSize / 64, 1, 1); + } + } + } + + public void BindGlobalBuffers(CommandBuffer cmd) + { + // TODO: ground irradiance table? Volume SH? Something else? + if (m_LastPrecomputedBounce > 0) + { + cmd.SetGlobalTexture(HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); + cmd.SetGlobalTexture(HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); + cmd.SetGlobalTexture(HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[2]); + } + else + { + cmd.SetGlobalTexture(HDShaderIDs._AirSingleScatteringTexture, CoreUtils.blackVolumeTexture); + cmd.SetGlobalTexture(HDShaderIDs._AerosolSingleScatteringTexture, CoreUtils.blackVolumeTexture); + cmd.SetGlobalTexture(HDShaderIDs._MultipleScatteringTexture, CoreUtils.blackVolumeTexture); + } + } + + public void BindBuffers(CommandBuffer cmd, MaterialPropertyBlock mpb) + { + if (m_LastPrecomputedBounce != 0) + { + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._GroundIrradianceTexture, m_GroundIrradianceTables[0]); + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[2]); + } + else + { + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._GroundIrradianceTexture, Texture2D.blackTexture); + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AirSingleScatteringTexture, CoreUtils.blackVolumeTexture); + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AerosolSingleScatteringTexture, CoreUtils.blackVolumeTexture); + s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._MultipleScatteringTexture, CoreUtils.blackVolumeTexture); + } + + } + + public bool Update(BuiltinSkyParameters builtinParams, PhysicallyBasedSky pbrSky) + { + if (builtinParams.frameIndex <= m_LastFrameComputation) + return false; + + m_LastFrameComputation = builtinParams.frameIndex; + + if (m_LastPrecomputedBounce == 0) + { + // Allocate temp tables if needed + if (m_GroundIrradianceTables[1] == null) + { + m_GroundIrradianceTables[1] = AllocateGroundIrradianceTable(1); + } + + if (m_InScatteredRadianceTables[3] == null) + { + m_InScatteredRadianceTables[3] = AllocateInScatteredRadianceTable(3); + } + + if (m_InScatteredRadianceTables[4] == null) + { + m_InScatteredRadianceTables[4] = AllocateInScatteredRadianceTable(4); + } + } + + if (m_LastPrecomputedBounce == pbrSky.numberOfBounces.value) + { + // Free temp tables. + // This is a deferred release (one frame late)! + RTHandles.Release(m_GroundIrradianceTables[1]); + RTHandles.Release(m_InScatteredRadianceTables[3]); + RTHandles.Release(m_InScatteredRadianceTables[4]); + m_GroundIrradianceTables[1] = null; + m_InScatteredRadianceTables[3] = null; + m_InScatteredRadianceTables[4] = null; + } + + if (m_LastPrecomputedBounce < pbrSky.numberOfBounces.value) + { + PrecomputeTables(builtinParams.commandBuffer); + m_LastPrecomputedBounce++; + + // If the sky is realtime, an upcoming update will update the sky lighting. Otherwise we need to force an update. + return builtinParams.skySettings.updateMode != EnvironmentUpdateMode.Realtime; + } + + return false; + } + } + [GenerateHLSL] public enum PbrSkyConfig { @@ -22,49 +303,18 @@ public enum PbrSkyConfig // If the hash does not match, we must recompute our data. int m_LastPrecomputationParamHash; - // We compute at most one bounce per frame for perf reasons. - // We need to store the frame index because more than one render can happen during a frame (cubemap update + regular rendering). - int m_LastPrecomputedBounce; - // Precomputed data below. - RTHandle[] m_GroundIrradianceTables; // All orders, one order - RTHandle[] m_InScatteredRadianceTables; // Air SS, Aerosol SS, Atmosphere MS, Atmosphere one order, Temp + PrecomputationData m_PrecomputedData; static ComputeShader s_GroundIrradiancePrecomputationCS; static ComputeShader s_InScatteredRadiancePrecomputationCS; - Material s_PbrSkyMaterial; + Material m_PbrSkyMaterial; static MaterialPropertyBlock s_PbrSkyMaterialProperties; - static GraphicsFormat s_ColorFormat = GraphicsFormat.R16G16B16A16_SFloat; - - RTHandle AllocateGroundIrradianceTable(int index) - { - var table = RTHandles.Alloc((int)PbrSkyConfig.GroundIrradianceTableSize, 1, - colorFormat: s_ColorFormat, - enableRandomWrite: true, - name: string.Format("GroundIrradianceTable{0}", index)); + static PrecomputationCache s_PrecomputaionCache = new PrecomputationCache(); - Debug.Assert(table != null); - - return table; - } + static GraphicsFormat s_ColorFormat = GraphicsFormat.R16G16B16A16_SFloat; - RTHandle AllocateInScatteredRadianceTable(int index) - { - // Emulate a 4D texture with a "deep" 3D texture. - var table = RTHandles.Alloc((int)PbrSkyConfig.InScatteredRadianceTableSizeX, - (int)PbrSkyConfig.InScatteredRadianceTableSizeY, - (int)PbrSkyConfig.InScatteredRadianceTableSizeZ * - (int)PbrSkyConfig.InScatteredRadianceTableSizeW, - dimension: TextureDimension.Tex3D, - colorFormat: s_ColorFormat, - enableRandomWrite: true, - name: string.Format("InScatteredRadianceTable{0}", index)); - - Debug.Assert(table != null); - - return table; - } public PhysicallyBasedSkyRenderer() { @@ -80,54 +330,28 @@ public override void Build() s_InScatteredRadiancePrecomputationCS = hdrpResources.shaders.inScatteredRadiancePrecomputationCS; s_PbrSkyMaterialProperties = new MaterialPropertyBlock(); - s_PbrSkyMaterial = CoreUtils.CreateEngineMaterial(hdrpResources.shaders.physicallyBasedSkyPS); + m_PbrSkyMaterial = CoreUtils.CreateEngineMaterial(hdrpResources.shaders.physicallyBasedSkyPS); Debug.Assert(s_GroundIrradiancePrecomputationCS != null); Debug.Assert(s_InScatteredRadiancePrecomputationCS != null); - - // No temp tables. - m_GroundIrradianceTables = new RTHandle[2]; - m_GroundIrradianceTables[0] = AllocateGroundIrradianceTable(0); - - m_InScatteredRadianceTables = new RTHandle[5]; - m_InScatteredRadianceTables[0] = AllocateInScatteredRadianceTable(0); - m_InScatteredRadianceTables[1] = AllocateInScatteredRadianceTable(1); - m_InScatteredRadianceTables[2] = AllocateInScatteredRadianceTable(2); } public override void SetGlobalSkyData(CommandBuffer cmd, BuiltinSkyParameters builtinParams) { UpdateGlobalConstantBuffer(cmd, builtinParams); - - // TODO: ground irradiance table? Volume SH? Something else? - if (m_LastPrecomputedBounce > 0) - { - cmd.SetGlobalTexture(HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); - cmd.SetGlobalTexture(HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); - cmd.SetGlobalTexture(HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[2]); - } - else - { - cmd.SetGlobalTexture(HDShaderIDs._AirSingleScatteringTexture, CoreUtils.blackVolumeTexture); - cmd.SetGlobalTexture(HDShaderIDs._AerosolSingleScatteringTexture, CoreUtils.blackVolumeTexture); - cmd.SetGlobalTexture(HDShaderIDs._MultipleScatteringTexture, CoreUtils.blackVolumeTexture); - } - + if (m_PrecomputedData != null) + m_PrecomputedData.BindGlobalBuffers(builtinParams.commandBuffer); } public override void Cleanup() { - RTHandles.Release(m_GroundIrradianceTables[0]); m_GroundIrradianceTables[0] = null; - RTHandles.Release(m_GroundIrradianceTables[1]); m_GroundIrradianceTables[1] = null; - RTHandles.Release(m_InScatteredRadianceTables[0]); m_InScatteredRadianceTables[0] = null; - RTHandles.Release(m_InScatteredRadianceTables[1]); m_InScatteredRadianceTables[1] = null; - RTHandles.Release(m_InScatteredRadianceTables[2]); m_InScatteredRadianceTables[2] = null; - RTHandles.Release(m_InScatteredRadianceTables[3]); m_InScatteredRadianceTables[3] = null; - RTHandles.Release(m_InScatteredRadianceTables[4]); m_InScatteredRadianceTables[4] = null; - - CoreUtils.Destroy(s_PbrSkyMaterial); - - m_LastPrecomputedBounce = 0; + if (m_PrecomputedData != null) + { + s_PrecomputaionCache.Release(m_LastPrecomputationParamHash); + m_LastPrecomputationParamHash = 0; + m_PrecomputedData = null; + } + CoreUtils.Destroy(m_PbrSkyMaterial); } static float CornetteShanksPhasePartConstant(float anisotropy) @@ -197,90 +421,6 @@ void UpdateGlobalConstantBuffer(CommandBuffer cmd, BuiltinSkyParameters builtinP cmd.SetGlobalFloat( HDShaderIDs._HorizonZenithShiftScale, expParams.y); } - void PrecomputeTables(CommandBuffer cmd) - { - using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.InScatteredRadiancePrecomputation))) - { - int order = m_LastPrecomputedBounce + 1; - { - // For efficiency reasons, multiple scattering is computed in 2 passes: - // 1. Gather the in-scattered radiance over the entire sphere of directions. - // 2. Accumulate the in-scattered radiance along the ray. - // Single scattering performs both steps during the same pass. - - int firstPass = Math.Min(order - 1, 2); - int accumPass = 3; - int numPasses = Math.Min(order, 2); - - for (int i = 0; i < numPasses; i++) - { - int pass = (i == 0) ? firstPass : accumPass; - - switch (pass) - { - case 0: - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AirSingleScatteringTable, m_InScatteredRadianceTables[0]); - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AerosolSingleScatteringTable, m_InScatteredRadianceTables[1]); - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[2]); // MS orders - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTableOrder, m_InScatteredRadianceTables[3]); // One order - break; - case 1: - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._GroundIrradianceTexture, m_GroundIrradianceTables[1]); // One order - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[4]); // Temp - break; - case 2: - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[3]); // One order - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._GroundIrradianceTexture, m_GroundIrradianceTables[1]); // One order - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[4]); // Temp - break; - case 3: - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[4]); // Temp - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTableOrder, m_InScatteredRadianceTables[3]); // One order - cmd.SetComputeTextureParam(s_InScatteredRadiancePrecomputationCS, pass, HDShaderIDs._MultipleScatteringTable, m_InScatteredRadianceTables[2]); // MS orders - break; - default: - Debug.Assert(false); - break; - } - - // Re-illuminate the sky with each bounce. - // Emulate a 4D dispatch with a "deep" 3D dispatch. - cmd.DispatchCompute(s_InScatteredRadiancePrecomputationCS, pass, (int)PbrSkyConfig.InScatteredRadianceTableSizeX / 4, - (int)PbrSkyConfig.InScatteredRadianceTableSizeY / 4, - (int)PbrSkyConfig.InScatteredRadianceTableSizeZ / 4 * - (int)PbrSkyConfig.InScatteredRadianceTableSizeW); - } - - { - // Used by all passes. - cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._GroundIrradianceTable, m_GroundIrradianceTables[0]); // All orders - cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._GroundIrradianceTableOrder, m_GroundIrradianceTables[1]); // One order - } - - switch (firstPass) - { - case 0: - break; - case 1: - cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); - cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); - break; - case 2: - cmd.SetComputeTextureParam(s_GroundIrradiancePrecomputationCS, firstPass, HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[3]); // One order - break; - default: - Debug.Assert(false); - break; - } - - // Re-illuminate the ground with each bounce. - cmd.DispatchCompute(s_GroundIrradiancePrecomputationCS, firstPass, (int)PbrSkyConfig.GroundIrradianceTableSize / 64, 1, 1); - } - } - } - protected override bool Update(BuiltinSkyParameters builtinParams) { UpdateGlobalConstantBuffer(builtinParams.commandBuffer, builtinParams); @@ -289,54 +429,13 @@ protected override bool Update(BuiltinSkyParameters builtinParams) int currPrecomputationParamHash = pbrSky.GetPrecomputationHashCode(); if (currPrecomputationParamHash != m_LastPrecomputationParamHash) { - // Hash does not match, have to restart the precomputation from scratch. - m_LastPrecomputedBounce = 0; - } - - if (m_LastPrecomputedBounce == 0) - { - // Allocate temp tables if needed - if (m_GroundIrradianceTables[1] == null) - { - m_GroundIrradianceTables[1] = AllocateGroundIrradianceTable(1); - } - - if (m_InScatteredRadianceTables[3] == null) - { - m_InScatteredRadianceTables[3] = AllocateInScatteredRadianceTable(3); - } - - if (m_InScatteredRadianceTables[4] == null) - { - m_InScatteredRadianceTables[4] = AllocateInScatteredRadianceTable(4); - } - } - - if (m_LastPrecomputedBounce == pbrSky.numberOfBounces.value) - { - // Free temp tables. - // This is a deferred release (one frame late)! - RTHandles.Release(m_GroundIrradianceTables[1]); - RTHandles.Release(m_InScatteredRadianceTables[3]); - RTHandles.Release(m_InScatteredRadianceTables[4]); - m_GroundIrradianceTables[1] = null; - m_InScatteredRadianceTables[3] = null; - m_InScatteredRadianceTables[4] = null; - } - - if (m_LastPrecomputedBounce < pbrSky.numberOfBounces.value) - { - PrecomputeTables(builtinParams.commandBuffer); - m_LastPrecomputedBounce++; - - // Update the hash for the current bounce. + if (m_LastPrecomputationParamHash != 0) + s_PrecomputaionCache.Release(m_LastPrecomputationParamHash); + m_PrecomputedData = s_PrecomputaionCache.Get(currPrecomputationParamHash); m_LastPrecomputationParamHash = currPrecomputationParamHash; - - // If the sky is realtime, an upcoming update will update the sky lighting. Otherwise we need to force an update. - return builtinParams.skySettings.updateMode != EnvironmentUpdateMode.Realtime; } - return false; + return m_PrecomputedData.Update(builtinParams, pbrSky); } // 'renderSunDisk' parameter is not supported. @@ -370,20 +469,7 @@ public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderFo s_PbrSkyMaterialProperties.SetMatrix(HDShaderIDs._PlanetRotation, Matrix4x4.Rotate(planetRotation)); s_PbrSkyMaterialProperties.SetMatrix(HDShaderIDs._SpaceRotation, Matrix4x4.Rotate(spaceRotation)); - if (m_LastPrecomputedBounce != 0) - { - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._GroundIrradianceTexture, m_GroundIrradianceTables[0]); - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AirSingleScatteringTexture, m_InScatteredRadianceTables[0]); - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AerosolSingleScatteringTexture, m_InScatteredRadianceTables[1]); - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._MultipleScatteringTexture, m_InScatteredRadianceTables[2]); - } - else - { - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._GroundIrradianceTexture, Texture2D.blackTexture); - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AirSingleScatteringTexture, CoreUtils.blackVolumeTexture); - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._AerosolSingleScatteringTexture, CoreUtils.blackVolumeTexture); - s_PbrSkyMaterialProperties.SetTexture(HDShaderIDs._MultipleScatteringTexture, CoreUtils.blackVolumeTexture); - } + m_PrecomputedData.BindBuffers(cmd, s_PbrSkyMaterialProperties); int hasGroundAlbedoTexture = 0; @@ -418,7 +504,7 @@ public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderFo int pass = (renderForCubemap ? 0 : 2) + (isPbrSkyActive ? 0 : 1); - CoreUtils.DrawFullScreen(builtinParams.commandBuffer, s_PbrSkyMaterial, s_PbrSkyMaterialProperties, pass); + CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_PbrSkyMaterial, s_PbrSkyMaterialProperties, pass); } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index 52bb03f685c..ba9ba4d50de 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -413,6 +413,24 @@ internal SphericalHarmonicsL2 GetAmbientProbe(HDCamera hdCamera) return GetAmbientProbe(hdCamera.lightingSky); } + internal bool HasSetValidAmbientProbe(HDCamera hdCamera) + { + SkyAmbientMode ambientMode = hdCamera.volumeStack.GetComponent().skyAmbientMode.value; + if (ambientMode == SkyAmbientMode.Static) + return true; + + if (hdCamera.skyAmbientMode == SkyAmbientMode.Dynamic && hdCamera.lightingSky != null && + hdCamera.lightingSky.IsValid() && IsCachedContextValid(hdCamera.lightingSky)) + { + ref CachedSkyContext cachedContext = ref m_CachedSkyContexts[hdCamera.lightingSky.cachedSkyRenderingContextId]; + var renderingContext = cachedContext.renderingContext; + return renderingContext.ambientProbeIsReady; + } + + return false; + + } + internal void SetupAmbientProbe(HDCamera hdCamera) { // Working around GI current system @@ -697,7 +715,7 @@ public void UpdateEnvironment( HDCamera hdCamera, // This is to avoid cases in which the probe camera is below ground and the parent is not, leading to // in case of PBR sky to a black sky. All other parameters are left as is. // This can introduce inaccuracies, but they should be acceptable if the distance parent camera - probe camera is - // small. + // small. if (hdCamera.camera.cameraType == CameraType.Reflection && hdCamera.parentCamera != null) { worldSpaceCameraPos = hdCamera.parentCamera.transform.position; @@ -794,13 +812,14 @@ public void UpdateEnvironment(HDCamera hdCamera, ScriptableRenderContext renderC // because we only maintain one static sky. Since we don't care that the static lighting may be a bit different in the preview we never recompute // and we use the one from the main camera. bool forceStaticUpdate = false; + StaticLightingSky staticLightingSky = GetStaticLightingSky(); #if UNITY_EDITOR - // In the editor, we might need the static sky ready for baking lightmaps/lightprobes regardless of the current ambient mode so we force it to update in this case. - forceStaticUpdate = true; + // In the editor, we might need the static sky ready for baking lightmaps/lightprobes regardless of the current ambient mode so we force it to update in this case if it's not been computed yet.. + // We don't test if the hash of the static sky has changed here because it depends on the sun direction and in the case of LookDev, sun will be different from the main rendering so it will induce improper recomputation. + forceStaticUpdate = staticLightingSky != null && m_StaticLightingSky.skyParametersHash == -1; ; #endif if ((ambientMode == SkyAmbientMode.Static || forceStaticUpdate) && hdCamera.camera.cameraType != CameraType.Preview) { - StaticLightingSky staticLightingSky = GetStaticLightingSky(); if (staticLightingSky != null) { m_StaticLightingSky.skySettings = staticLightingSky.skySettings; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderingContext.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderingContext.cs index d03791d1d2b..9016477b396 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderingContext.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderingContext.cs @@ -14,6 +14,8 @@ internal class SkyRenderingContext public CubemapArray skyboxBSDFCubemapArray { get; private set; } public bool supportsConvolution { get; private set; } = false; + internal bool ambientProbeIsReady = false; + public SkyRenderingContext(int resolution, int bsdfCount, bool supportsConvolution, SphericalHarmonicsL2 ambientProbe, string name) { m_AmbientProbe = ambientProbe; @@ -71,6 +73,8 @@ public void OnComputeAmbientProbeDone(AsyncGPUReadbackRequest request) m_AmbientProbe[channel, coeff] = result[channel * 9 + coeff]; } } + + ambientProbeIsReady = true; } } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUpdateContext.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUpdateContext.cs index 3ae3591daa4..9127a4824f0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUpdateContext.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUpdateContext.cs @@ -16,6 +16,15 @@ public SkySettings skySettings get { return m_SkySettings; } set { + // We cleanup the renderer first here because in some cases, after scene unload, the skySettings field will be "null" because the object got destroyed. + // In this case, the renderer might stay allocated until a non null value is set. To avoid a lingering allocation, we cleanup first before anything else. + // So next frame after scene unload, renderer will be freed. + if (skyRenderer != null && (value == null || value.GetSkyRendererType() != skyRenderer.GetType())) + { + skyRenderer.Cleanup(); + skyRenderer = null; + } + if (m_SkySettings == value) return; @@ -23,13 +32,8 @@ public SkySettings skySettings m_SkySettings = value; currentUpdateTime = 0.0f; - if (m_SkySettings != null && (skyRenderer == null || m_SkySettings.GetSkyRendererType() != skyRenderer.GetType())) + if (m_SkySettings != null && skyRenderer == null) { - if (skyRenderer != null) - { - skyRenderer.Cleanup(); - } - var rendererType = m_SkySettings.GetSkyRendererType(); skyRenderer = (SkyRenderer)Activator.CreateInstance(rendererType); skyRenderer.Build(); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/StaticLightingSky.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/StaticLightingSky.cs index d3aa6bb1293..16729facca7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/StaticLightingSky.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/StaticLightingSky.cs @@ -4,10 +4,13 @@ namespace UnityEngine.Rendering.HighDefinition { + /// + /// Class controlling which sky is used for static and baked lighting. + /// [HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "Static-Lighting-Sky" + Documentation.endURL)] [ExecuteAlways] [AddComponentMenu("")] // Hide this object from the Add Component menu - class StaticLightingSky : MonoBehaviour + public class StaticLightingSky : MonoBehaviour { [SerializeField] VolumeProfile m_Profile; @@ -16,12 +19,10 @@ class StaticLightingSky : MonoBehaviour int m_LastComputedHash; bool m_NeedUpdateStaticLightingSky; - [NonSerialized] - public SkySettings m_SkySettings; // This one contain only property values from overridden properties in the original profile component - [NonSerialized] - public SkySettings m_SkySettingsFromProfile; + SkySettings m_SkySettings; // This one contain only property values from overridden properties in the original profile component + SkySettings m_SkySettingsFromProfile; - public SkySettings skySettings + internal SkySettings skySettings { get { @@ -42,7 +43,9 @@ public SkySettings skySettings List m_VolumeSkyList = new List(); - + /// + /// Volume profile where the sky settings used for static lighting will be fetched. + /// public VolumeProfile profile { get @@ -69,6 +72,10 @@ public VolumeProfile profile } } + /// + /// Unique ID of the sky used for static lighting. + /// The unique ID should be for a sky that is present in the profile. See SkySettings.GetUniqueID to get the ID per sky type. + /// public int staticLightingSkyUniqueID { get @@ -125,7 +132,9 @@ void UpdateCurrentStaticLightingSky() var profileSkyParameters = m_SkySettingsFromProfile.parameters; var defaultVolume = HDRenderPipeline.GetOrCreateDefaultVolume(); - defaultVolume.sharedProfile.TryGet(skyType, out SkySettings defaultSky); + SkySettings defaultSky = null; + if (defaultVolume.sharedProfile != null) // This can happen with old projects. + defaultVolume.sharedProfile.TryGet(skyType, out defaultSky); var defaultSkyParameters = defaultSky != null ? defaultSky.parameters : null; // Can be null if the profile does not contain the component. // Seems to inexplicably happen sometimes on domain reload. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/VisualEnvironment.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/VisualEnvironment.cs index 531e03b333f..94618852e64 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/VisualEnvironment.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/VisualEnvironment.cs @@ -11,7 +11,7 @@ namespace UnityEngine.Rendering.HighDefinition public sealed class VisualEnvironment : VolumeComponent { /// Type of sky that should be used for rendering. - public IntParameter skyType = new IntParameter(0); + public NoInterpIntParameter skyType = new NoInterpIntParameter(0); /// Defines the way the ambient probe should be computed. public SkyAmbientModeParameter skyAmbientMode = new SkyAmbientModeParameter(SkyAmbientMode.Static);