diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 4ec1d2eb670..79107569998 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -131,6 +131,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - LOD meshes are now properly stripped based on the maximum lod value parameters contained in the HDRP asset. - Fixed an inconsistency in the LOD group UI where LOD bias was not the right one. - Fixed outlines in transitions between post-processed and plain regions in the graphics compositor (case 1278775). +- Fix decal being applied twice with LOD Crossfade. ### Changed - Preparation pass for RTSSShadows to be supported by render graph. diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Master-Node-Decal.md b/com.unity.render-pipelines.high-definition/Documentation~/Master-Node-Decal.md index 89ed5c4dc0e..ee210a1d055 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Master-Node-Decal.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Master-Node-Decal.md @@ -55,8 +55,9 @@ To view these properties, click the gear in the top right of the Master Node. | **Affects Ambient Occlusion** | Enable or disable the effect of the **Ambient Occlusion** property. | | **Affects Smoothness** | Enable or disable the effect of the **Smoothness** property. | | **Affects Emission** | Enable or disable the effect of the **Emission** property. | +| **Support LOD CrossFace** | Indicates whether dithering occurs when moving from one LOD level of the receiving Mesh to another when sampling Textures. Only use with Decal Mesh. | | **Override ShaderGUI** | Lets you override the [ShaderGUI](https://docs.unity3d.com/ScriptReference/ShaderGUI.html) that this Shader Graph uses. If `true`, the **ShaderGUI** property appears, which lets you specify the ShaderGUI to use. | -| **- ShaderGUI** | The full name of the ShaderGUI class to use, including the class path. | +| **- ShaderGUI** | The full name of the ShaderGUI class to use, including the class path. | diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalData.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalData.cs index 1e68dcbfcfc..1dbc32acb52 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalData.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalData.cs @@ -62,6 +62,14 @@ public int drawOrder set => m_DrawOrder = value; } + [SerializeField] + bool m_SupportLodCrossFade; + public bool supportLodCrossFade + { + get => m_SupportLodCrossFade; + set => m_SupportLodCrossFade = value; + } + public bool affectsMaskmap => affectsSmoothness || affectsMetal || affectsAO; } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPass.template b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPass.template index 0804a8cd692..75f9485c2e1 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPass.template +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPass.template @@ -97,6 +97,10 @@ Pass fragInputs.tangentToWorld[2].xyz = TransformObjectToWorldDir(float3(0, 1, 0)); fragInputs.tangentToWorld[1].xyz = TransformObjectToWorldDir(float3(0, 0, 1)); #else + #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group + LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x); + #endif + float fadeFactor = 1.0; #endif diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPropertyBlock.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPropertyBlock.cs index 25d5b64f758..8ac81ea3154 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPropertyBlock.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalPropertyBlock.cs @@ -29,6 +29,7 @@ protected override void CreatePropertyGUI() AddProperty(affectAmbientOcclusionText, () => decalData.affectsAO, (newValue) => decalData.affectsAO = newValue); AddProperty(affectSmoothnessText, () => decalData.affectsSmoothness, (newValue) => decalData.affectsSmoothness = newValue); AddProperty(affectEmissionText, () => decalData.affectsEmission, (newValue) => decalData.affectsEmission = newValue); + AddProperty(supportLodCrossFadeText, () => decalData.supportLodCrossFade, (newValue) => decalData.supportLodCrossFade = newValue); } } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalSubTarget.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalSubTarget.cs index f1a52a975ba..b8c619b31f6 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalSubTarget.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ShaderGraph/DecalSubTarget.cs @@ -70,6 +70,12 @@ protected override void CollectPassKeywords(ref PassDescriptor pass) if (decalData.affectsMaskmap) pass.keywords.Add(DecalDefines.Maskmap); } + + if (pass.lightMode == DecalSystem.s_MaterialDecalPassNames[(int)DecalSystem.MaterialDecalPass.DecalMeshForwardEmissive] || + pass.lightMode == DecalSystem.s_MaterialDecalPassNames[(int)DecalSystem.MaterialDecalPass.DBufferMesh]) + { + pass.keywords.Add(CoreKeywordDescriptors.LodFadeCrossfade, new FieldCondition(Fields.LodCrossFade, true)); + } } public static FieldDescriptor AffectsAlbedo = new FieldDescriptor(kMaterial, "AffectsAlbedo", ""); @@ -93,6 +99,7 @@ public override void GetFields(ref TargetFieldContext context) context.AddField(AffectsMaskMap, decalData.affectsMaskmap); context.AddField(DecalDefault, decalData.affectsAlbedo || decalData.affectsNormal || decalData.affectsMetal || decalData.affectsAO || decalData.affectsSmoothness ); + context.AddField(Fields.LodCrossFade, decalData.supportLodCrossFade); } public override void GetActiveBlocks(ref TargetActiveBlockContext context) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceOptionsUIBlock.cs b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceOptionsUIBlock.cs index 03c33a12fce..86aca5c42ce 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceOptionsUIBlock.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/DecalSurfaceOptionsUIBlock.cs @@ -22,6 +22,7 @@ public class Styles public static GUIContent affectAmbientOcclusionText = new GUIContent("Affect Ambient Occlusion", "When enabled, this decal uses the smoothness channel of its Mask Map. When disabled, the decal has no smoothness effect."); public static GUIContent affectSmoothnessText = new GUIContent("Affect Smoothness", "When enabled, this decal uses the ambient occlusion channel of its Mask Map. When disabled, the decal has no ambient occlusion effect."); public static GUIContent affectEmissionText = new GUIContent("Affect Emission", "When enabled, this decal becomes emissive and appears self-illuminated. Affect Emission does not support Affects Transparents option on Decal Projector."); + public static GUIContent supportLodCrossFadeText = new GUIContent("Support LOD CrossFade", "When enabled, this decal material supports LOD Cross fade if use on a Mesh."); } Expandable m_ExpandableBit; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.shader index 9fa8c422cf5..b8327d6f1fd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.shader @@ -207,6 +207,9 @@ Shader "HDRP/Decal" HLSLPROGRAM #pragma multi_compile DECALS_3RT DECALS_4RT + // enable dithering LOD crossfade + #pragma multi_compile _ LOD_FADE_CROSSFADE + #define SHADERPASS SHADERPASS_DBUFFER_MESH #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProperties.hlsl" @@ -238,6 +241,8 @@ Shader "HDRP/Decal" Blend 0 SrcAlpha One HLSLPROGRAM + // enable dithering LOD crossfade + #pragma multi_compile _ LOD_FADE_CROSSFADE #define _MATERIAL_AFFECTS_EMISSION #define SHADERPASS SHADERPASS_FORWARD_EMISSIVE_MESH diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl index bea55bd6254..a99f0586b26 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl @@ -14,6 +14,11 @@ void GetSurfaceData(FragInputs input, float3 V, PositionInputs posInput, out Dec float2 offset = float2(normalToWorld[3][2], normalToWorld[3][3]); float2 texCoords = input.texCoord0.xy * scale + offset; #elif (SHADERPASS == SHADERPASS_DBUFFER_MESH) || (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_MESH) + + #ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group + LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x); + #endif + float fadeFactor = _DecalBlend; float2 texCoords = input.texCoord0.xy; #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl index 3c08ecd5dc9..8e776624000 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl @@ -125,37 +125,6 @@ void DoAlphaTest(float alpha, float alphaCutoff, out bool alphaTestResult) { alphaTestResult = alpha >= alphaCutoff; } -//----------------------------------------------------------------------------- -// LoD Fade -//----------------------------------------------------------------------------- - -// Helper for LODDitheringTransition. -uint2 ComputeFadeMaskSeed(float3 V, uint2 positionSS) -{ - uint2 fadeMaskSeed; - - if (IsPerspectiveProjection()) - { - // Start with the world-space direction V. It is independent from the orientation of the camera, - // and only depends on the position of the camera and the position of the fragment. - // Now, project and transform it into [-1, 1]. - float2 pv = PackNormalOctQuadEncode(V); - // Rescale it to account for the resolution of the screen. - pv *= _ScreenSize.xy; - // The camera only sees a small portion of the sphere, limited by hFoV and vFoV. - // Therefore, we must rescale again (before quantization), roughly, by 1/tan(FoV/2). - pv *= UNITY_MATRIX_P._m00_m11; - // Truncate and quantize. - fadeMaskSeed = asuint((int2)pv); - } - else - { - // Can't use the view direction, it is the same across the entire screen. - fadeMaskSeed = positionSS; - } - - return fadeMaskSeed; -} //----------------------------------------------------------------------------- // Reflection / Refraction hierarchy handling diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesFunctions.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesFunctions.hlsl index ab9a3831ff1..990e9e25c42 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesFunctions.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesFunctions.hlsl @@ -2,6 +2,7 @@ #define UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" // Helper function for Rendering Layers #define DEFAULT_LIGHT_LAYERS (RENDERING_LIGHT_LAYERS_MASK >> RENDERING_LIGHT_LAYERS_MASK_SHIFT) @@ -206,5 +207,36 @@ uint ScalarizeElementIndex(uint v_elementIdx, bool fastPath) return s_elementIdx; } +//----------------------------------------------------------------------------- +// LoD Fade +//----------------------------------------------------------------------------- + +// Helper for LODDitheringTransition. +uint2 ComputeFadeMaskSeed(float3 V, uint2 positionSS) +{ + uint2 fadeMaskSeed; + + if (IsPerspectiveProjection()) + { + // Start with the world-space direction V. It is independent from the orientation of the camera, + // and only depends on the position of the camera and the position of the fragment. + // Now, project and transform it into [-1, 1]. + float2 pv = PackNormalOctQuadEncode(V); + // Rescale it to account for the resolution of the screen. + pv *= _ScreenSize.xy; + // The camera only sees a small portion of the sphere, limited by hFoV and vFoV. + // Therefore, we must rescale again (before quantization), roughly, by 1/tan(FoV/2). + pv *= UNITY_MATRIX_P._m00_m11; + // Truncate and quantize. + fadeMaskSeed = asuint((int2)pv); + } + else + { + // Can't use the view direction, it is the same across the entire screen. + fadeMaskSeed = positionSS; + } + + return fadeMaskSeed; +} #endif // UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED