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/Editor/Volume/VolumeComponentListEditor.cs b/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs index 21a110079a0..9669c56a435 100644 --- a/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs +++ b/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs @@ -199,10 +199,10 @@ public void OnGUI() // Even if the asset is not dirty, the list of component may have been changed by another inspector. // In this case, only the hash will tell us that we need to refresh. - if (asset.isDirty || asset.GetHashCode() != m_CurrentHashCode) + if (asset.isDirty || asset.GetComponentListHashCode() != m_CurrentHashCode) { RefreshEditors(); - m_CurrentHashCode = asset.GetHashCode(); + m_CurrentHashCode = asset.GetComponentListHashCode(); asset.isDirty = false; } 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.core/Runtime/Volume/VolumeProfile.cs b/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs index 198a44af7ac..a687a86fb4d 100644 --- a/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs +++ b/com.unity.render-pipelines.core/Runtime/Volume/VolumeProfile.cs @@ -297,5 +297,18 @@ public override int GetHashCode() return hash; } } + + internal int GetComponentListHashCode() + { + unchecked + { + int hash = 17; + + for (int i = 0; i < components.Count; i++) + hash = hash * 23 + components[i].GetType().GetHashCode(); + + return hash; + } + } } } diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl index 43280100c26..507635aaffe 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl @@ -1,3 +1,5 @@ +#ifndef SHADOW_SAMPLING_TENT_INCLUDED +#define SHADOW_SAMPLING_TENT_INCLUDED // ------------------------------------------------------------------ // PCF Filtering Tent Functions // ------------------------------------------------------------------ @@ -242,3 +244,4 @@ void SampleShadow_ComputeSamples_Tent_7x7(real4 shadowMapTexture_TexelSize, real fetchesWeights[14] = fetchesWeightsU.z * fetchesWeightsV.w; fetchesWeights[15] = fetchesWeightsU.w * fetchesWeightsV.w; } +#endif diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 93c064ffc97..176dc0804e1 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,14 +6,44 @@ 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 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. - Fixed a cause of NaN when a normal of 0-length is generated (usually via shadergraph). - Fixed a bug where not all entries were generated for the Attributes Struct in Shader Graph shaders. (case 1250275) - VFX: Removed irrelevant queues in render queue selection from HDRP outputs - VFX: Motion Vector are correctly renderered with MSAA [Case 1240754](https://issuetracker.unity3d.com/product/unity/issues/guid/1240754/) +- 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. +- Fixed an issue where manipulating the color wheels in a volume component would reset the cursor every time. +- Fixed an issue where static sky lighting would not be updated for a new scene until it's reloaded at least once. +- Fixed missing include guards in shadow hlsl files. +- Fixed issue with light layers bigger than 8 (and above the supported range). +- Fixed an issue where decals were duplicated in prefab isolation mode. +- Fixed the valid TRS test failing due to variable not being initialized to the identity matrix in RTShadows (1220600). + +### 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. ## [8.1.0] - 2020-04-21 @@ -80,7 +110,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. 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/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index ab124573fa3..28842b8128a 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -254,7 +254,7 @@ void DrawHandles() { // Smoothly update the decal image projected Matrix4x4 sizeOffset = Matrix4x4.Translate(decalProjector.decalOffset) * Matrix4x4.Scale(decalProjector.decalSize); - DecalSystem.instance.UpdateCachedData(decalProjector.position, decalProjector.rotation, sizeOffset, decalProjector.drawDistance, decalProjector.fadeScale, decalProjector.uvScaleBias, decalProjector.affectsTransparency, decalProjector.Handle, decalProjector.gameObject.layer, decalProjector.fadeFactor); + DecalSystem.instance.UpdateCachedData(decalProjector.position, decalProjector.rotation, sizeOffset, decalProjector.drawDistance, decalProjector.fadeScale, decalProjector.uvScaleBias, decalProjector.affectsTransparency, decalProjector.Handle, decalProjector.gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(decalProjector.gameObject), decalProjector.fadeFactor); } } } 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 09c6dc3a7a8..ee58229606c 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, } @@ -485,11 +486,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..53357c92561 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Sky/HDLightingWindowEnvironmentSection.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Sky/HDLightingWindowEnvironmentSection.cs @@ -32,7 +32,6 @@ class SerializedStaticLightingSky { SerializedObject serializedObject; public SerializedProperty skyUniqueID; - public VolumeProfile volumeProfile { get => (serializedObject.targetObject as StaticLightingSky).profile; @@ -177,7 +176,9 @@ void DrawGUI() var profile = m_SerializedActiveSceneLightingSky.volumeProfile; var newProfile = EditorGUILayout.ObjectField(EditorGUIUtility.TrTextContent("Profile"), profile, typeof(VolumeProfile), allowSceneObjects: false) as VolumeProfile; if (profile != newProfile) + { m_SerializedActiveSceneLightingSky.volumeProfile = newProfile; + } using (new EditorGUI.DisabledScope(m_SkyClassNames.Count == 1)) // Only "None" { diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs index 13a317b27d4..b9b8ffe8124 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.cs @@ -1430,7 +1430,7 @@ internal int shadowPrecision Plane[] m_ShadowFrustumPlanes = new Plane[6]; // temporary matrix that stores the previous light data (mainly used to discard history for ray traced screen space shadows) - [System.NonSerialized] internal Matrix4x4 previousTransform = new Matrix4x4(); + [System.NonSerialized] internal Matrix4x4 previousTransform = Matrix4x4.identity; // Temporary index that stores the current shadow index for the light [System.NonSerialized] internal int shadowIndex = -1; 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/Lighting/Shadow/HDShadowAlgorithms.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl index 1aa7a294ab4..188c8dfe876 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAlgorithms.hlsl @@ -1,3 +1,6 @@ +#ifndef HD_SHADOW_ALGORITHMS_INCLUDED +#define HD_SHADOW_ALGORITHMS_INCLUDED + // Various shadow algorithms // There are two variants provided, one takes the texture and sampler explicitly so they can be statically passed in. // The variant without resource parameters dynamically accesses the texture when sampling. @@ -341,3 +344,4 @@ float EvalShadow_SampleClosestDistance_Punctual(HDShadowData sd, Texture2D tex, return distance(occluderPosWS, lightPositionWS); } +#endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSampling.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSampling.hlsl index a89d6292779..3480866c0a9 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSampling.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowSampling.hlsl @@ -1,3 +1,5 @@ +#ifndef HD_SHADOW_SAMPLING_INCLUDED +#define HD_SHADOW_SAMPLING_INCLUDED // Various shadow sampling logic. // Again two versions, one for dynamic resource indexing, one for static resource access. @@ -328,3 +330,4 @@ float SampleShadow_PCSS(float3 tcs, float2 posSS, float2 scale, float2 offset, f // shadowData.shadowFilterParams0.z = shadowRequest.maxDepthBias; // #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDIMS.hlsl" +#endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ShadowMoments.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ShadowMoments.hlsl index d5ded67dc81..bce8d31f69c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ShadowMoments.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ShadowMoments.hlsl @@ -1,3 +1,5 @@ +#ifndef SHADOW_MOMENTS_INCLUDED +#define SHADOW_MOMENTS_INCLUDED // Library header containing various useful functions for doing moment based shadow maps. // Supported flavors are VSM, EVSM and MSM @@ -131,3 +133,4 @@ float ShadowMoments_SolveDelta4MSM( float3 z, float4 b, float lightLeakBias) return saturate( ((1.0 - attenuation) - lightLeakBias) / (1.0 - lightLeakBias) ); } +#endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.Migration.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.Migration.cs index da2070093f2..8c1ef20a3f2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.Migration.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.Migration.cs @@ -37,7 +37,7 @@ enum Version if (decal.m_Handle != null) DecalSystem.instance.RemoveDecal(decal.m_Handle); Matrix4x4 sizeOffset = Matrix4x4.Translate(decal.decalOffset) * Matrix4x4.Scale(decal.decalSize); - decal.m_Handle = DecalSystem.instance.AddDecal(decal.position, decal.rotation, Vector3.one, sizeOffset, decal.m_DrawDistance, decal.m_FadeScale, decal.uvScaleBias, decal.m_AffectsTransparency, decal.m_Material, decal.gameObject.layer, decal.m_FadeFactor); + decal.m_Handle = DecalSystem.instance.AddDecal(decal.position, decal.rotation, Vector3.one, sizeOffset, decal.m_DrawDistance, decal.m_FadeScale, decal.uvScaleBias, decal.m_AffectsTransparency, decal.m_Material, decal.gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(decal.gameObject), decal.m_FadeFactor); }), MigrationStep.New(Version.FixPivotPosition, (DecalProjector decal) => { @@ -69,7 +69,7 @@ enum Version if (decal.m_Handle != null) DecalSystem.instance.RemoveDecal(decal.m_Handle); Matrix4x4 sizeOffset = Matrix4x4.Translate(decal.decalOffset) * Matrix4x4.Scale(decal.decalSize); - decal.m_Handle = DecalSystem.instance.AddDecal(decal.position, decal.rotation, Vector3.one, sizeOffset, decal.m_DrawDistance, decal.m_FadeScale, decal.uvScaleBias, decal.m_AffectsTransparency, decal.m_Material, decal.gameObject.layer, decal.m_FadeFactor); + decal.m_Handle = DecalSystem.instance.AddDecal(decal.position, decal.rotation, Vector3.one, sizeOffset, decal.m_DrawDistance, decal.m_FadeScale, decal.uvScaleBias, decal.m_AffectsTransparency, decal.m_Material, decal.gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(decal.gameObject), decal.m_FadeFactor); }) ); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs index 4f2504252ed..b27590314f4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs @@ -231,7 +231,7 @@ void OnEnable() } Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize); - m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, m_FadeFactor); + m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(gameObject), m_FadeFactor); m_OldMaterial = m_Material; #if UNITY_EDITOR @@ -253,7 +253,7 @@ void UpdateDecalVisibility() else if (m_Handle == null) { Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize); - m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, m_FadeFactor); + m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(gameObject), m_FadeFactor); } } #endif @@ -292,7 +292,7 @@ internal void OnValidate() if (m_Material != null) { - m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, m_FadeFactor); + m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(gameObject), m_FadeFactor); if (!DecalSystem.IsHDRenderPipelineDecal(m_Material.shader)) // non HDRP/decal shaders such as shader graph decal do not affect transparency { @@ -310,7 +310,7 @@ internal void OnValidate() } else // no material change, just update whatever else changed { - DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, m_FadeFactor); + DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(gameObject), m_FadeFactor); } } } @@ -322,7 +322,7 @@ void Update() // only run in editor { Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize); m_Layer = gameObject.layer; - DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, m_FadeFactor); + DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(gameObject), m_FadeFactor); } } #endif @@ -334,7 +334,7 @@ void LateUpdate() if (transform.hasChanged == true) { Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize); - DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, m_FadeFactor); + DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, HDUtils.GetSceneCullingMaskFromGameObject(gameObject), m_FadeFactor); transform.hasChanged = false; } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs index ceeed37afbd..c19d3d507b3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalSystem.cs @@ -422,7 +422,7 @@ private BoundingSphere GetDecalProjectBoundingSphere(Matrix4x4 decalToWorld) return res; } - public void UpdateCachedData(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, float fadeFactor) + public void UpdateCachedData(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, ulong sceneLayerMask, float fadeFactor) { int index = handle.m_Index; m_CachedDecalToWorld[index] = localToWorld * sizeOffset; @@ -448,19 +448,20 @@ public void UpdateCachedData(Matrix4x4 localToWorld, Quaternion rotation, Matrix m_CachedUVScaleBias[index] = uvScaleBias; m_CachedAffectsTransparency[index] = affectsTransparency; m_CachedLayerMask[index] = layerMask; + m_CachedSceneLayerMask[index] = sceneLayerMask; m_CachedFadeFactor[index] = fadeFactor; m_BoundingSpheres[index] = GetDecalProjectBoundingSphere(m_CachedDecalToWorld[index]); } - public void UpdateCachedData(Transform transform, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, float fadeFactor) + public void UpdateCachedData(Transform transform, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, ulong sceneLayerMask, float fadeFactor) { if (m_Material == null) return; - UpdateCachedData(transform.localToWorldMatrix, transform.rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, fadeFactor); + UpdateCachedData(transform.localToWorldMatrix, transform.rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, sceneLayerMask, fadeFactor); } - public DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, int materialID, int layerMask, float fadeFactor) + public DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, int materialID, int layerMask, ulong sceneLayerMask, float fadeFactor) { // increase array size if no space left if (m_DecalsCount == m_Handles.Length) @@ -473,6 +474,7 @@ public DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4 Vector4[] newCachedUVScaleBias = new Vector4[m_DecalsCount + kDecalBlockSize]; bool[] newCachedAffectsTransparency = new bool[m_DecalsCount + kDecalBlockSize]; int[] newCachedLayerMask = new int[m_DecalsCount + kDecalBlockSize]; + ulong[] newCachedSceneLayerMask = new ulong[m_DecalsCount + kDecalBlockSize]; float[] newCachedFadeFactor = new float[m_DecalsCount + kDecalBlockSize]; m_ResultIndices = new int[m_DecalsCount + kDecalBlockSize]; @@ -484,6 +486,7 @@ public DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4 m_CachedUVScaleBias.CopyTo(newCachedUVScaleBias, 0); m_CachedAffectsTransparency.CopyTo(newCachedAffectsTransparency, 0); m_CachedLayerMask.CopyTo(newCachedLayerMask, 0); + m_CachedSceneLayerMask.CopyTo(newCachedSceneLayerMask, 0); m_CachedFadeFactor.CopyTo(newCachedFadeFactor, 0); m_Handles = newHandles; @@ -493,13 +496,13 @@ public DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4 m_CachedDrawDistances = newCachedDrawDistances; m_CachedUVScaleBias = newCachedUVScaleBias; m_CachedAffectsTransparency = newCachedAffectsTransparency; - m_CachedLayerMask = newCachedLayerMask; + m_CachedSceneLayerMask = newCachedSceneLayerMask; m_CachedFadeFactor = newCachedFadeFactor; } DecalHandle decalHandle = new DecalHandle(m_DecalsCount, materialID); m_Handles[m_DecalsCount] = decalHandle; - UpdateCachedData(localToWorld, rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, decalHandle, layerMask, fadeFactor); + UpdateCachedData(localToWorld, rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, decalHandle, layerMask, sceneLayerMask, fadeFactor); m_DecalsCount++; return decalHandle; } @@ -520,6 +523,7 @@ public void RemoveDecal(DecalHandle handle) m_CachedUVScaleBias[removeAtIndex] = m_CachedUVScaleBias[m_DecalsCount - 1]; m_CachedAffectsTransparency[removeAtIndex] = m_CachedAffectsTransparency[m_DecalsCount - 1]; m_CachedLayerMask[removeAtIndex] = m_CachedLayerMask[m_DecalsCount - 1]; + m_CachedSceneLayerMask[removeAtIndex] = m_CachedSceneLayerMask[m_DecalsCount - 1]; m_CachedFadeFactor[removeAtIndex] = m_CachedFadeFactor[m_DecalsCount - 1]; m_DecalsCount--; handle.m_Index = kInvalidIndex; @@ -628,14 +632,23 @@ public void CreateDrawData() AssignCurrentBatches(ref decalToWorldBatch, ref normalToWorldBatch, batchCount); Vector3 cameraPos = instance.CurrentCamera.transform.position; - Matrix4x4 worldToView = HDRenderPipeline.WorldToCamera(instance.CurrentCamera); + var camera = instance.CurrentCamera; + Matrix4x4 worldToView = HDRenderPipeline.WorldToCamera(camera); bool perChannelMask = instance.perChannelMask; + int cullingMask = camera.cullingMask; + ulong sceneCullingMask = HDUtils.GetSceneCullingMaskFromCamera(camera); + for (int resultIndex = 0; resultIndex < m_NumResults; resultIndex++) { int decalIndex = m_ResultIndices[resultIndex]; - int cullingMask = instance.CurrentCamera.cullingMask; int decalMask = 1 << m_CachedLayerMask[decalIndex]; - if ((cullingMask & decalMask) != 0) + ulong decalSceneCullingMask = m_CachedSceneLayerMask[decalIndex]; + bool sceneViewCullingMaskTest = true; +#if UNITY_EDITOR + // In the player, both masks will be zero. Besides we don't want to pay the cost in this case. + sceneViewCullingMaskTest = (sceneCullingMask & decalSceneCullingMask) != 0; +#endif + if ((cullingMask & decalMask) != 0 && sceneViewCullingMaskTest) { // do additional culling based on individual decal draw distances float distanceToDecal = (cameraPos - m_BoundingSpheres[decalIndex].position).magnitude; @@ -817,6 +830,7 @@ public int MaskBlendMode private Vector4[] m_CachedUVScaleBias = new Vector4[kDecalBlockSize]; // xy - scale, zw bias private bool[] m_CachedAffectsTransparency = new bool[kDecalBlockSize]; private int[] m_CachedLayerMask = new int[kDecalBlockSize]; + private ulong[] m_CachedSceneLayerMask = new ulong[kDecalBlockSize]; private float[] m_CachedFadeFactor = new float[kDecalBlockSize]; private Material m_Material; private MaterialPropertyBlock m_PropertyBlock = new MaterialPropertyBlock(); @@ -878,7 +892,7 @@ void SetupMipStreamingSettings(Material material, bool allMips) } } - DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, Material material, int layerMask, float fadeFactor) + DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, Material material, int layerMask, ulong sceneLayerMask, float fadeFactor) { SetupMipStreamingSettings(material, true); @@ -889,18 +903,18 @@ DecalHandle AddDecal(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 size decalSet = new DecalSet(material); m_DecalSets.Add(key, decalSet); } - return decalSet.AddDecal(localToWorld, rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, key, layerMask, fadeFactor); + return decalSet.AddDecal(localToWorld, rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, key, layerMask, sceneLayerMask, fadeFactor); } - public DecalHandle AddDecal(Vector3 position, Quaternion rotation, Vector3 scale, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, Material material, int layerMask, float fadeFactor) + public DecalHandle AddDecal(Vector3 position, Quaternion rotation, Vector3 scale, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, Material material, int layerMask, ulong sceneLayerMask, float fadeFactor) { - return AddDecal(Matrix4x4.TRS(position, rotation, scale), rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, material, layerMask, fadeFactor); + return AddDecal(Matrix4x4.TRS(position, rotation, scale), rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, material, layerMask, sceneLayerMask, fadeFactor); } - public DecalHandle AddDecal(Transform transform, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, Material material, int layerMask, float fadeFactor) + public DecalHandle AddDecal(Transform transform, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, Material material, int layerMask, ulong sceneLayerMask, float fadeFactor) { - return AddDecal(transform.localToWorldMatrix, transform.rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, material, layerMask, fadeFactor); + return AddDecal(transform.localToWorldMatrix, transform.rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, material, layerMask, sceneLayerMask, fadeFactor); } public void RemoveDecal(DecalHandle handle) @@ -922,7 +936,7 @@ public void RemoveDecal(DecalHandle handle) } } - void UpdateCachedData(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, float fadeFactor) + void UpdateCachedData(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, ulong sceneLayerMask, float fadeFactor) { if (!DecalHandle.IsValid(handle)) return; @@ -931,18 +945,18 @@ void UpdateCachedData(Matrix4x4 localToWorld, Quaternion rotation, Matrix4x4 siz int key = handle.m_MaterialID; if (m_DecalSets.TryGetValue(key, out decalSet)) { - decalSet.UpdateCachedData(localToWorld, rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, fadeFactor); + decalSet.UpdateCachedData(localToWorld, rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, sceneLayerMask, fadeFactor); } } - public void UpdateCachedData(Vector3 position, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, float fadeFactor) + public void UpdateCachedData(Vector3 position, Quaternion rotation, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, ulong sceneLayerMask, float fadeFactor) { - UpdateCachedData(Matrix4x4.TRS(position, rotation, Vector3.one), rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, fadeFactor); + UpdateCachedData(Matrix4x4.TRS(position, rotation, Vector3.one), rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, sceneLayerMask, fadeFactor); } - public void UpdateCachedData(Transform transform, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, float fadeFactor) + public void UpdateCachedData(Transform transform, Matrix4x4 sizeOffset, float drawDistance, float fadeScale, Vector4 uvScaleBias, bool affectsTransparency, DecalHandle handle, int layerMask, ulong sceneLayerMask, float fadeFactor) { - UpdateCachedData(Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one)/*transform.localToWorldMatrix*/, transform.rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, fadeFactor); + UpdateCachedData(Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one)/*transform.localToWorldMatrix*/, transform.rotation, sizeOffset, drawDistance, fadeScale, uvScaleBias, affectsTransparency, handle, layerMask, sceneLayerMask, fadeFactor); } public void BeginCull(CullRequest request) { 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/Lit.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl index 64ad119c8fd..1e856c8d89f 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl @@ -643,7 +643,8 @@ void EncodeIntoGBuffer( SurfaceData surfaceData outGBuffer3 *= GetCurrentExposureMultiplier(); #ifdef LIGHT_LAYERS - OUT_GBUFFER_LIGHT_LAYERS = float4(0.0, 0.0, 0.0, builtinData.renderingLayers / 255.0); + // Note: we need to mask out only 8bits of the layer mask before encoding it as otherwise any value > 255 will map to all layers active + OUT_GBUFFER_LIGHT_LAYERS = float4(0.0, 0.0, 0.0, (builtinData.renderingLayers & 0x000000FF) / 255.0); #endif #ifdef SHADOWS_SHADOWMASK 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/RenderPipeline/Utility/HDUtils.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs index 5d6c9c6b7a2..e47e1c84cc7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Utility/HDUtils.cs @@ -938,6 +938,15 @@ internal static UInt64 GetSceneCullingMaskFromCamera(Camera camera) } + internal static ulong GetSceneCullingMaskFromGameObject(GameObject go) + { +#if UNITY_EDITOR + return (go.scene == null) ? ~(ulong)0 : EditorSceneManager.GetSceneCullingMask(go.scene); +#else + return 0; +#endif + } + internal static HDAdditionalCameraData TryGetAdditionalCameraDataOrDefault(Camera camera) { if (camera == null || camera.Equals(null)) 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..63543b12ea4 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,19 +812,17 @@ 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; - UpdateEnvironment(hdCamera, renderContext, m_StaticLightingSky, sunLight, m_StaticSkyUpdateRequired, true, true, SkyAmbientMode.Static, frameIndex, cmd); - m_StaticSkyUpdateRequired = false; - } + m_StaticLightingSky.skySettings = staticLightingSky != null ? staticLightingSky.skySettings : null; + UpdateEnvironment(hdCamera, renderContext, m_StaticLightingSky, sunLight, m_StaticSkyUpdateRequired, true, true, SkyAmbientMode.Static, frameIndex, cmd); + m_StaticSkyUpdateRequired = false; } m_UpdateRequired = false; 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);