diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl index c1c6827ac77..917ac268bad 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl @@ -692,6 +692,46 @@ real Pow4(real x) TEMPLATE_3_FLT(RangeRemap, min, max, t, return saturate((t - min) / (max - min))) +float4x4 Inverse(float4x4 m) +{ + float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0]; + float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1]; + float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2], n34 = m[3][2]; + float n41 = m[0][3], n42 = m[1][3], n43 = m[2][3], n44 = m[3][3]; + + float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; + float t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44; + float t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44; + float t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + + float det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; + float idet = 1.0f / det; + + float4x4 ret; + + ret[0][0] = t11 * idet; + ret[0][1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * idet; + ret[0][2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * idet; + ret[0][3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * idet; + + ret[1][0] = t12 * idet; + ret[1][1] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * idet; + ret[1][2] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * idet; + ret[1][3] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * idet; + + ret[2][0] = t13 * idet; + ret[2][1] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * idet; + ret[2][2] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * idet; + ret[2][3] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * idet; + + ret[3][0] = t14 * idet; + ret[3][1] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * idet; + ret[3][2] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * idet; + ret[3][3] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * idet; + + return ret; +} + // ---------------------------------------------------------------------------- // Texture utilities // ---------------------------------------------------------------------------- diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 8eb57f62742..ceb79e23e54 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -52,6 +52,7 @@ The version number for this package has increased due to a version update of a r - Fixed issue when null parameters in a volume component would spam null reference errors. Produce a warning instead. - Fix volument component creation via script. - Fixed GC allocs in render graph. +- Fixed scene picking passes. ### Changed - Combined occlusion meshes into one to reduce draw calls and state changes with XR single-pass. diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2020.1-to-2020.2.md b/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2020.1-to-2020.2.md index 1cff036d47f..d3d2deef62c 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2020.1-to-2020.2.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2020.1-to-2020.2.md @@ -192,6 +192,8 @@ From 10.x, HDRP uses range remapping for the metallic property when using a mask In the Lit, LitTessellation, LayeredLit and LayeredLitTesselation shaders, two new properties have been added: `_MetallicRemapMin` and `_MetallicRemapMax`. In the Decal shader, the property `_MetallicRemapMin` have been added, and `_MetallicScale` has been renamed as `_MetallicRemapMax`. +From 10.x, a new pass ScenePickingPass have been added to all the shader and master node to allow the editor to correctly handle the picking with tesselated objects and backfaced objects. + ## Raytracing From Unity 2020.2, the Raytracing Node in shader graph now apply the raytraced path (previously low path) to all raytraced effects but path tracing. diff --git a/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs b/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs index a3f07b5fbc2..b82ee87e056 100644 --- a/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs +++ b/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs @@ -24,7 +24,8 @@ protected override bool DoShadersStripper(HDRenderPipelineAsset hdrpAsset, Shade // Remove editor only pass bool isSceneSelectionPass = snippet.passName == "SceneSelectionPass"; - if (isSceneSelectionPass) + bool isScenePickingPass = snippet.passName == "ScenePickingPass"; + if (isSceneSelectionPass || isScenePickingPass) return true; // CAUTION: We can't identify transparent material in the stripped in a general way. 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 219fb8de831..7307c1b135a 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 @@ -48,6 +48,11 @@ Pass $splice(HybridV1InjectedBuiltinProperties) + // -- Properties used by ScenePickingPass + #ifdef SCENEPICKINGPASS + float4 _SelectionID; + #endif + // Includes $splice(PreGraphIncludes) 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 6a123e4a542..92fa4e2f24a 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 @@ -197,6 +197,7 @@ void AddColorMaskProperty(string referenceName) #region SubShaders static class SubShaders { + // Relies on the order shader passes are declared in DecalSystem.cs public static SubShaderDescriptor Decal = new SubShaderDescriptor() { generatesPreview = true, @@ -206,6 +207,7 @@ static class SubShaders { DecalPasses.DecalProjectorForwardEmissive, new FieldCondition(AffectsEmission, true) }, { DecalPasses.DBufferMesh, new FieldCondition(DecalDefault, true) }, { DecalPasses.DecalMeshForwardEmissive, new FieldCondition(AffectsEmission, true) }, + { DecalPasses.ScenePicking, new FieldCondition(DecalDefault, true) }, { DecalPasses.Preview, new FieldCondition(Fields.IsPreview, true) }, }, }; @@ -215,8 +217,23 @@ static class SubShaders #region Passes public static class DecalPasses { - // CAUTION: c# code relies on the order in which the passes are declared, any change will need to be reflected in Decalsystem.cs - s_MaterialDecalNames array - // and DecalSet.InitializeMaterialValues() + // CAUTION: c# code relies on the order in which the passes are declared, any change will need to be reflected in Decalsystem.cs - enum MaterialDecalPass + + public static PassDescriptor ScenePicking = new PassDescriptor() + { + // Definition + displayName = "ScenePickingPass", + referenceName = "SHADERPASS_DEPTH_ONLY", + lightMode = "Picking", + useInPreview = false, + + // Collections + renderStates = DecalRenderStates.ScenePicking, + pragmas = DecalPragmas.Instanced, + defines = CoreDefines.ScenePicking, + includes = DecalIncludes.ScenePicking, + }; + public static PassDescriptor DBufferProjector = new PassDescriptor() { // Definition @@ -385,6 +402,11 @@ static class DecalRenderStates readonly static string s_DecalColorMask = "ColorMask [_DecalColorMask0]\n\tColorMask [_DecalColorMask1] 1\n\tColorMask [_DecalColorMask2] 2\n\tColorMask [_DecalColorMask3] 3"; readonly static string s_DecalBlend = "Blend 0 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha \n\tBlend 1 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha \n\tBlend 2 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha \n\tBlend 3 Zero OneMinusSrcColor"; + public static RenderStateCollection ScenePicking = new RenderStateCollection + { + { RenderState.Cull(Cull.Back) }, + }; + public static RenderStateCollection DBufferProjector = new RenderStateCollection { { RenderState.Blend(s_DecalBlend) }, @@ -536,6 +558,17 @@ static class DecalIncludes { kDecal, IncludeLocation.Pregraph }, { kPassDecal, IncludeLocation.Postgraph }, }; + + public static IncludeCollection ScenePicking = new IncludeCollection + { + { kPacking, IncludeLocation.Pregraph }, + { kColor, IncludeLocation.Pregraph }, + { kFunctions, IncludeLocation.Pregraph }, + { CoreIncludes.MinimalCorePregraph }, + { kDecal, IncludeLocation.Pregraph }, + { CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph }, + { kPassDecal, IncludeLocation.Postgraph }, + }; } #endregion } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs index 82dd14c24c5..ecf7578f8f0 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs @@ -74,6 +74,42 @@ IncludeCollection GenerateIncludes() #endregion +#region Scene Picking Pass + + public static PassDescriptor GenerateScenePicking() + { + return new PassDescriptor + { + // Definition + displayName = "ScenePickingPass", + referenceName = "SHADERPASS_DEPTH_ONLY", + lightMode = "Picking", + useInPreview = false, + + // Collections + renderStates = CoreRenderStates.ScenePicking, + pragmas = CorePragmas.DotsInstancedInV1AndV2EditorSync, + defines = CoreDefines.ScenePicking, + includes = GenerateIncludes(), + }; + + IncludeCollection GenerateIncludes() + { + var includes = new IncludeCollection(); + + includes.Add(CoreIncludes.CorePregraph); + includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); + includes.Add(CoreIncludes.CoreUtility); + includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); + includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph); + includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); + + return includes; + } + } + +#endregion + #region Scene Selection Pass public static PassDescriptor GenerateSceneSelection(bool supportLighting) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs index c8681682202..a12715dc036 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs @@ -594,6 +594,11 @@ public static class Uniforms { RenderState.ColorMask("ColorMask 0") }, }; + public static RenderStateCollection ScenePicking = new RenderStateCollection + { + { RenderState.Cull(Uniforms.cullMode) }, + }; + public static RenderStateCollection SceneSelection = new RenderStateCollection { { RenderState.Cull(Cull.Off) }, @@ -800,6 +805,11 @@ static class CoreKeywords #region Defines static class CoreDefines { + public static DefineCollection ScenePicking = new DefineCollection + { + { CoreKeywordDescriptors.ScenePickingPass, 1 }, + }; + public static DefineCollection SceneSelection = new DefineCollection { { RayTracingQualityNode.GetRayTracingQualityKeyword(), 0 }, @@ -860,6 +870,7 @@ static class CoreIncludes public const string kFragInputs = "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/FragInputs.hlsl"; public const string kMaterial = "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl"; public const string kDebugDisplay = "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl"; + public const string kPickingSpaceTransforms = "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl"; // CoreUtility public const string kBuiltInUtilities = "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinUtilities.hlsl"; @@ -1160,6 +1171,15 @@ static class CoreKeywordDescriptors scope = KeywordScope.Local, }; + public static KeywordDescriptor ScenePickingPass = new KeywordDescriptor() + { + displayName = "Scene Picking Pass", + referenceName = "SCENEPICKINGPASS", + type = KeywordType.Boolean, + definition = KeywordDefinition.ShaderFeature, + scope = KeywordScope.Local, + }; + public static KeywordDescriptor SceneSelectionPass = new KeywordDescriptor() { displayName = "Scene Selection Pass", diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/SurfaceSubTarget.cs b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/SurfaceSubTarget.cs index 06f807865bb..4d5d56b0604 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/SurfaceSubTarget.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/SurfaceSubTarget.cs @@ -79,6 +79,7 @@ PassCollection GetPasses() // Common "surface" passes HDShaderPasses.GenerateShadowCaster(supportLighting), HDShaderPasses.GenerateMETA(supportLighting), + HDShaderPasses.GenerateScenePicking(), HDShaderPasses.GenerateSceneSelection(supportLighting), HDShaderPasses.GenerateMotionVectors(supportLighting, supportForward), { HDShaderPasses.GenerateBackThenFront(supportLighting), new FieldCondition(HDFields.TransparentBackFace, true)}, diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template index 47395cd3201..fe45a75b2ba 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template +++ b/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template @@ -119,6 +119,11 @@ Pass // -- Graph Properties $splice(GraphProperties) + // -- Property used by ScenePickingPass + #ifdef SCENEPICKINGPASS + float4 _SelectionID; + #endif + // -- Properties used by SceneSelectionPass #ifdef SCENESELECTIONPASS int _ObjectId; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader index 09f6f58da52..aca2ba0c00a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader @@ -216,6 +216,35 @@ Shader "HDRP/AxF" // This tags allow to use the shader replacement features Tags{ "RenderPipeline" = "HDRenderPipeline" "RenderType" = "HDLitShader" } + Pass + { + Name "ScenePickingPass" + Tags { "LightMode" = "Picking" } + + Cull [_CullMode] + + HLSLPROGRAM + + // Note: Require _SelectionID variable + + // We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation + #define SHADERPASS SHADERPASS_DEPTH_ONLY + #define SCENEPICKINGPASS + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/ShaderPass/AxFDepthPass.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFData.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl" + + #pragma vertex Vert + #pragma fragment Frag + + #pragma editor_sync_compilation + + ENDHLSL + } + Pass { Name "SceneSelectionPass" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFProperties.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFProperties.hlsl index 7cced1b697f..f454df5ff4c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFProperties.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxFProperties.hlsl @@ -133,8 +133,9 @@ float _SpecularAAThreshold; // TODO: Fix the code in legacy unity so we can customize the behavior for GI float3 _EmissionColor; -// Following two variables are feeded by the C++ Editor for Scene selection +// Following three variables are feeded by the C++ Editor for Scene selection int _ObjectId; int _PassValue; +float4 _SelectionID; CBUFFER_END 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 7b4cdb919d2..1bf513b3060 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 @@ -98,8 +98,10 @@ Shader "HDRP/Decal" { Tags{ "RenderPipeline" = "HDRenderPipeline"} - // c# code relies on the order in which the passes are declared, any change will need to be reflected in Decalsystem.cs - s_MaterialDecalNames and s_MaterialDecalSGNames array - // and DecalSet.InitializeMaterialValues() + // c# code relies on the order in which the passes are declared, any change will need to be reflected in + // DecalSystem.cs - enum MaterialDecalPass + // DecalSubTarget.cs - class SubShaders + // Caution: passes stripped in builds (like the scene picking pass) need to be put last to have consistent indices Pass // 0 { @@ -257,6 +259,40 @@ Shader "HDRP/Decal" ENDHLSL } + Pass // 4 + { + Name "ScenePickingPass" + Tags { "LightMode" = "Picking" } + + Cull Back + + HLSLPROGRAM + + #pragma only_renderers d3d11 playstation xboxone vulkan metal switch + + //enable GPU instancing support + #pragma instancing_options renderinglayer + #pragma multi_compile _ DOTS_INSTANCING_ON + // enable dithering LOD crossfade + #pragma multi_compile _ LOD_FADE_CROSSFADE + + // Note: Require _SelectionID variable + + // We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation + #define SHADERPASS SHADERPASS_DEPTH_ONLY + #define SCENEPICKINGPASS + #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" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/Decal.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/ShaderPass/DecalSharePass.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDecal.hlsl" + + #pragma editor_sync_compilation + + ENDHLSL + } + } CustomEditor "Rendering.HighDefinition.DecalUI" } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProperties.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProperties.hlsl index b0d43c243ac..305b999ce0c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProperties.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProperties.hlsl @@ -29,4 +29,8 @@ float _Smoothness; float _AO; float _Metallic; +#ifdef SCENEPICKINGPASS + float4 _SelectionID; +#endif + #endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader index 52c29075102..102e820144b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader @@ -533,6 +533,42 @@ Shader "HDRP/LayeredLit" // This tags allow to use the shader replacement features Tags{ "RenderPipeline" = "HDRenderPipeline" "RenderType" = "HDLitShader" } + Pass + { + Name "ScenePickingPass" + Tags { "LightMode" = "Picking" } + + Cull [_CullMode] + + HLSLPROGRAM + + #pragma only_renderers d3d11 playstation xboxone vulkan metal switch + //enable GPU instancing support + #pragma multi_compile_instancing + #pragma multi_compile _ DOTS_INSTANCING_ON + #pragma instancing_options renderinglayer + #pragma multi_compile _ LOD_FADE_CROSSFADE + + // Note: Require _SelectionID variable + + // We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation + #define SHADERPASS SHADERPASS_DEPTH_ONLY + #define SCENEPICKINGPASS + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl" + + #pragma vertex Vert + #pragma fragment Frag + + #pragma editor_sync_compilation + + ENDHLSL + } + Pass { Name "SceneSelectionPass" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader index 936a14e9f6b..5214a71ca2e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader @@ -551,6 +551,37 @@ Shader "HDRP/LayeredLitTessellation" // This tags allow to use the shader replacement features Tags{ "RenderPipeline" = "HDRenderPipeline" "RenderType" = "HDLitShader" } + Pass + { + Name "ScenePickingPass" + Tags { "LightMode" = "Picking" } + + Cull [_CullMode] + + HLSLPROGRAM + + // Note: Require _SelectionID variable + + // We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation + #define SHADERPASS SHADERPASS_DEPTH_ONLY + #define SCENEPICKINGPASS + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl" + + #pragma vertex Vert + #pragma fragment Frag + #pragma hull Hull + #pragma domain Domain + + #pragma editor_sync_compilation + + ENDHLSL + } + Pass { Name "SceneSelectionPass" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader index a502d716f12..9a06b61358a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader @@ -352,6 +352,44 @@ Shader "HDRP/Lit" // This tags allow to use the shader replacement features Tags{ "RenderPipeline"="HDRenderPipeline" "RenderType" = "HDLitShader" } + Pass + { + Name "ScenePickingPass" + Tags { "LightMode" = "Picking" } + + Cull [_CullMode] + + HLSLPROGRAM + + #pragma only_renderers d3d11 playstation xboxone vulkan metal switch + + //enable GPU instancing support + #pragma multi_compile_instancing + #pragma instancing_options renderinglayer + #pragma multi_compile _ DOTS_INSTANCING_ON + // enable dithering LOD crossfade + #pragma multi_compile _ LOD_FADE_CROSSFADE + + // Note: Require _SelectionID variable + + // We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation + #define SHADERPASS SHADERPASS_DEPTH_ONLY + #define SCENEPICKINGPASS + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl" + + #pragma vertex Vert + #pragma fragment Frag + + #pragma editor_sync_compilation + + ENDHLSL + } + Pass { Name "SceneSelectionPass" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataMeshModification.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataMeshModification.hlsl index a3ce2ef3aec..7ea5f75fe58 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataMeshModification.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataMeshModification.hlsl @@ -58,10 +58,15 @@ float4 GetTessellationFactors(float3 p0, float3 p1, float3 p2, float3 n0, float3 // Thus the following code play with both. float frustumEps = -maxDisplacement; // "-" Expected parameter for CullTriangleEdgesFrustum +#ifndef SCENEPICKINGPASS // TODO: the only reason I test the near plane here is that I am not sure that the product of other tessellation factors // (such as screen-space/distance-based) results in the tessellation factor of 1 for the geometry behind the near plane. // If that is the case (and, IMHO, it should be), we shouldn't have to test the near plane here. bool3 frustumCullEdgesMainView = CullTriangleEdgesFrustum(p0, p1, p2, frustumEps, _FrustumPlanes, 5); // Do not test the far plane +#else + // During the scene picking pass, we have no access to camera frustum planes + bool3 frustumCullEdgesMainView = false; +#endif #if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS) bool frustumCullCurrView = all(frustumCullEdgesMainView); @@ -71,7 +76,7 @@ float4 GetTessellationFactors(float3 p0, float3 p1, float3 p2, float3 n0, float3 bool faceCull = false; -#ifndef _DOUBLESIDED_ON +#if !defined(_DOUBLESIDED_ON) && !defined(SCENESELECTIONPASS) && !defined(SCENEPICKINGPASS) if (_TessellationBackFaceCullEpsilon > -1.0) // Is back-face culling enabled ? { // Handle transform mirroring (like negative scaling) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl index 6e033288230..4f1d667e328 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitProperties.hlsl @@ -290,9 +290,10 @@ float _TessellationObjectScale; float _TessellationTilingScale; #endif -// Following two variables are feeded by the C++ Editor for Scene selection +// Following three variables are feeded by the C++ Editor for Scene selection int _ObjectId; int _PassValue; +float4 _SelectionID; CBUFFER_END diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader index 1d1b25b1451..7f0cf2012cf 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader @@ -366,6 +366,37 @@ Shader "HDRP/LitTessellation" // This tags allow to use the shader replacement features Tags{ "RenderPipeline"="HDRenderPipeline" "RenderType" = "HDLitShader" } + Pass + { + Name "ScenePickingPass" + Tags { "LightMode" = "Picking" } + + Cull [_CullMode] + + HLSLPROGRAM + + // Note: Require _SelectionID variable + + // We reuse depth prepass for the scene selection, allow to handle alpha correctly as well as tessellation and vertex animation + #define SHADERPASS SHADERPASS_DEPTH_ONLY + #define SCENEPICKINGPASS + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitData.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" + #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl" + + #pragma vertex Vert + #pragma fragment Frag + #pragma hull Hull + #pragma domain Domain + + #pragma editor_sync_compilation + + ENDHLSL + } + Pass { Name "SceneSelectionPass" diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDecal.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDecal.hlsl index 95de6d1ad0b..2288049bd7a 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDecal.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDecal.hlsl @@ -1,4 +1,4 @@ -#if (SHADERPASS != SHADERPASS_DBUFFER_PROJECTOR) && (SHADERPASS != SHADERPASS_DBUFFER_MESH) && (SHADERPASS != SHADERPASS_FORWARD_EMISSIVE_PROJECTOR) && (SHADERPASS != SHADERPASS_FORWARD_EMISSIVE_MESH) && (SHADERPASS != SHADERPASS_FORWARD_PREVIEW) +#if (SHADERPASS != SHADERPASS_DEPTH_ONLY) && (SHADERPASS != SHADERPASS_DBUFFER_PROJECTOR) && (SHADERPASS != SHADERPASS_DBUFFER_MESH) && (SHADERPASS != SHADERPASS_FORWARD_EMISSIVE_PROJECTOR) && (SHADERPASS != SHADERPASS_FORWARD_EMISSIVE_MESH) && (SHADERPASS != SHADERPASS_FORWARD_PREVIEW) #error SHADERPASS_is_not_correctly_define #endif @@ -27,13 +27,16 @@ PackedVaryingsType Vert(AttributesMesh inputMesh) void Frag( PackedVaryingsToPS packedInput, #if (SHADERPASS == SHADERPASS_DBUFFER_PROJECTOR) || (SHADERPASS == SHADERPASS_DBUFFER_MESH) OUTPUT_DBUFFER(outDBuffer) -#elif (SHADERPASS == SHADERPASS_FORWARD_PREVIEW) // Only used for preview in shader graph +#elif defined(SCENEPICKINGPASS) || (SHADERPASS == SHADERPASS_FORWARD_PREVIEW) // Only used for preview in shader graph and scene picking out float4 outColor : SV_Target0 #else out float4 outEmissive : SV_Target0 #endif ) { +#ifdef SCENEPICKINGPASS + outColor = _SelectionID; +#else UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput); FragInputs input = UnpackVaryingsToFragInputs(packedInput); DecalSurfaceData surfaceData; @@ -147,4 +150,5 @@ void Frag( PackedVaryingsToPS packedInput, outEmissive.rgb = surfaceData.emissive * GetCurrentExposureMultiplier(); outEmissive.a = 1.0; #endif +#endif } diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl index b3d5b0aa701..342f1500fde 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/ShaderPassDepthOnly.hlsl @@ -11,7 +11,7 @@ PackedVaryingsType Vert(AttributesMesh inputMesh) { VaryingsType varyingsType; -#if (SHADERPASS == SHADERPASS_DEPTH_ONLY) && defined(HAVE_RECURSIVE_RENDERING) && !defined(SCENESELECTIONPASS) +#if (SHADERPASS == SHADERPASS_DEPTH_ONLY) && defined(HAVE_RECURSIVE_RENDERING) && !defined(SCENESELECTIONPASS) && !defined(SCENEPICKINGPASS) // If we have a recursive raytrace object, we will not render it. // As we don't want to rely on renderqueue to exclude the object from the list, // we cull it by settings position to NaN value. @@ -51,7 +51,7 @@ PackedVaryingsToPS VertTesselation(VaryingsToDS input) #endif void Frag( PackedVaryingsToPS packedInput - #if defined(SCENESELECTIONPASS) + #if defined(SCENESELECTIONPASS) || defined(SCENEPICKINGPASS) , out float4 outColor : SV_Target0 #else #ifdef WRITE_MSAA_DEPTH @@ -101,6 +101,8 @@ void Frag( PackedVaryingsToPS packedInput #ifdef SCENESELECTIONPASS // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly outColor = float4(_ObjectId, _PassValue, 1.0, 1.0); +#elif defined(SCENEPICKINGPASS) + outColor = _SelectionID; #else // Depth and Alpha to coverage diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl new file mode 100644 index 00000000000..0b3be72d754 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl @@ -0,0 +1,68 @@ +#ifndef UNITY_PICKING_SPACE_TRANSFORMS_INCLUDED +#define UNITY_PICKING_SPACE_TRANSFORMS_INCLUDED + +#ifdef SCENEPICKINGPASS + +// The picking pass uses custom matrices defined directly from the c++ +// So we have to redefine the space transform functions to overwrite the used matrices + +#undef SHADEROPTIONS_CAMERA_RELATIVE_RENDERING + +// Define the correct matrices +#undef unity_ObjectToWorld +#undef unity_MatrixVP +float4x4 unity_MatrixV; +float4x4 unity_MatrixVP; +float4x4 glstate_matrix_projection; + +#undef UNITY_MATRIX_M +#define UNITY_MATRIX_M unity_ObjectToWorld + +#undef UNITY_MATRIX_I_M +#define UNITY_MATRIX_I_M Inverse(unity_ObjectToWorld) + +#undef UNITY_MATRIX_V +#define UNITY_MATRIX_V unity_MatrixV + +#undef UNITY_MATRIX_VP +#define UNITY_MATRIX_VP unity_MatrixVP + +#undef UNITY_MATRIX_P +#define UNITY_MATRIX_P glstate_matrix_projection + + +// Overwrite the SpaceTransforms functions +#define GetObjectToWorldMatrix GetObjectToWorldMatrix_Picking +#define GetWorldToObjectMatrix GetWorldToObjectMatrix_Picking +#define GetWorldToViewMatrix GetWorldToViewMatrix_Picking +#define GetWorldToHClipMatrix GetWorldToHClipMatrix_Picking +#define GetViewToHClipMatrix GetViewToHClipMatrix_Picking +#define GetAbsolutePositionWS GetAbsolutePositionWS_Picking +#define GetCameraRelativePositionWS GetCameraRelativePositionWS_Picking +#define GetOddNegativeScale GetOddNegativeScale_Picking +#define TransformObjectToWorld TransformObjectToWorld_Picking +#define TransformWorldToObject TransformWorldToObject_Picking +#define TransformWorldToView TransformWorldToView_Picking +#define TransformObjectToHClip TransformObjectToHClip_Picking +#define TransformWorldToHClip TransformWorldToHClip_Picking +#define TransformWViewToHClip TransformWViewToHClip_Picking +#define TransformObjectToWorldDir TransformObjectToWorldDir_Picking +#define TransformWorldToObjectDir TransformWorldToObjectDir_Picking +#define TransformWorldToViewDir TransformWorldToViewDir_Picking +#define TransformWorldToHClipDir TransformWorldToHClipDir_Picking +#define TransformObjectToWorldNormal TransformObjectToWorldNormal_Picking +#define TransformWorldToObjectNormal TransformWorldToObjectNormal_Picking +#define CreateTangentToWorld CreateTangentToWorld_Picking +#define TransformTangentToWorld TransformTangentToWorld_Picking +#define TransformWorldToTangent TransformWorldToTangent_Picking +#define TransformTangentToObject TransformTangentToObject_Picking +#define TransformObjectToTangent TransformObjectToTangent_Picking + + +// Redefine the functions using the new macros +#undef UNITY_SPACE_TRANSFORMS_INCLUDED +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl" + + +#endif +#endif diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl.meta b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl.meta new file mode 100644 index 00000000000..6af1b1fc268 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 07878c52127f8a248be207c0fb1b6e77 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: