diff --git a/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl index 3c8729f513d..397e2ff537b 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl @@ -62,9 +62,9 @@ real PerceptualSmoothnessToPerceptualRoughness(real perceptualSmoothness) // but chopping the far tails of GGX and keeping 94% of the mass yields a distribution with a defined variance where // we can then relate the roughness of GGX to a variance (see Ray Tracing Gems p153 - the reference is wrong though, // the Conty paper doesn't mention this at all, but it can be found in stats using quantiles): -// +// // roughnessGGX^2 = variance / 2 -// +// // From the two previous, if we want roughly comparable variances of slopes between a Beckmann and a GGX NDF, we can // equate the variances and get a conversion of their roughnesses: // diff --git a/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl new file mode 100644 index 00000000000..0c3f4c633b9 --- /dev/null +++ b/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl @@ -0,0 +1,56 @@ +#ifndef UNITY_DATA_EXTRACTION_INCLUDED +#define UNITY_DATA_EXTRACTION_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" + +// These correspond to UnityEngine.Camera.RenderRequestMode enum values +#define RENDER_OBJECT_ID 1 +#define RENDER_DEPTH 2 +#define RENDER_WORLD_NORMALS_FACE_RGB 3 +#define RENDER_WORLD_POSITION_RGB 4 +#define RENDER_ENTITY_ID 5 +#define RENDER_BASE_COLOR_RGBA 6 +#define RENDER_SPECULAR_RGB 7 +#define RENDER_METALLIC_R 8 +#define RENDER_EMISSION_RGB 9 +#define RENDER_WORLD_NORMALS_PIXEL_RGB 10 +#define RENDER_SMOOTHNESS_R 11 +#define RENDER_OCCLUSION_R 12 +#define RENDER_DIFFUSE_COLOR_RGBA 13 +#define RENDER_OUTLINE_MASK 14 + +float4 ComputeEntityPickingValue(uint entityID) +{ + // Add 1 to the ID, so the entity ID 0 gets a value that is not equal + // to the clear value. + uint pickingValue = entityID + 1; + return PackId32ToRGBA8888(pickingValue); +} + +float4 ComputeSelectionMask(float objectGroupId, float3 ndcWithZ, TEXTURE2D_PARAM(depthBuffer, sampler_depthBuffer)) +{ + // float sceneZ = SAMPLE_TEXTURE2D(depthBuffer, sampler_depthBuffer, ndcWithZ.xy).r; + // Use LOAD so this is compatible with MSAA. Original SAMPLE kept here for reference. + float2 depthBufferSize; + depthBuffer.GetDimensions(depthBufferSize.x, depthBufferSize.y); + float2 unnormalizedUV = depthBufferSize * ndcWithZ.xy; + float sceneZ = LOAD_TEXTURE2D(depthBuffer, unnormalizedUV).r; + + // Use a small multiplicative Z bias to make it less likely for objects to self occlude in the outline buffer + static const float zBias = 0.02; +#if UNITY_REVERSED_Z + float pixelZ = ndcWithZ.z * (1 + zBias); + bool occluded = pixelZ < sceneZ; +#else + float pixelZ = ndcWithZ.z * (1 - zBias); + bool occluded = pixelZ > sceneZ; +#endif + // Red channel = unique identifier, can be used to separate groups of objects from each other + // to get outlines between them. + // Green channel = occluded behind depth buffer (0) or not occluded (1) + // Blue channel = always 1 = not cleared to zero = there's an outlined object at this pixel + return float4(objectGroupId, occluded ? 0 : 1, 1, 1); +} + +#endif + diff --git a/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl.meta b/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl.meta new file mode 100644 index 00000000000..570e8777432 --- /dev/null +++ b/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2457427cd93a466db488bb565b0624b0 +timeCreated: 1617987396 \ No newline at end of file diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl index b9577abb684..f7a0741f519 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl @@ -177,6 +177,13 @@ real3 UnpackNormalRGBNoScale(real4 packedNormal) return packedNormal.rgb * 2.0 - 1.0; } +real3 PackNormalRGB(real3 normal, real scale = 1.0) +{ + normal = normal * 0.5 + 0.5; + normal.xy *= scale; + return normal; +} + real3 UnpackNormalAG(real4 packedNormal, real scale = 1.0) { real3 normal; @@ -552,7 +559,7 @@ float3 PackFloat2To888(float2 f) // Unpack 2 float of 12bit packed into a 888 float2 Unpack888ToFloat2(float3 x) { - uint3 i = (uint3)(x * 255.5); // +0.5 to fix precision error on iOS + uint3 i = (uint3)(x * 255.5); // +0.5 to fix precision error on iOS // 8 bit in lo, 4 bit in hi uint hi = i.z >> 4; uint lo = i.z & 15; @@ -560,6 +567,22 @@ float2 Unpack888ToFloat2(float3 x) return cb / 4095.0; } + +// Pack a 32-bit integer into four 8-bit color channels such that the integer can be +// exactly reconstructed afterwards. +float4 PackId32ToRGBA8888(uint id32) +{ + uint b0 = (id32 >> 0) & 0xff; + uint b1 = (id32 >> 8) & 0xff; + uint b2 = (id32 >> 16) & 0xff; + uint b3 = (id32 >> 24) & 0xff; + float f0 = (float)b0 / 255.0f; + float f1 = (float)b1 / 255.0f; + float f2 = (float)b2 / 255.0f; + float f3 = (float)b3 / 255.0f; + return float4(f0, f1, f2, f3); +} + #endif // SHADER_API_GLES // Pack 2 float values from the [0, 1] range, to an 8 bits float from the [0, 1] range @@ -571,7 +594,7 @@ float PackFloat2To8(float2 f) return x_y_expanded / 255.0; // above 4 lines equivalent to: - //return (16.0 * f.x + f.y) / 17.0; + //return (16.0 * f.x + f.y) / 17.0; } // Unpack 2 float values from the [0, 1] range, packed in an 8 bits float from the [0, 1] range diff --git a/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl index 52903b13e55..57678da7158 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl @@ -5,8 +5,6 @@ #pragma warning (disable : 3205) // conversion of larger type to smaller #endif -// Caution: For HDRP, adding a function in this file requires adding the appropriate #define in PickingSpaceTransforms.hlsl - // Return the PreTranslated ObjectToWorld Matrix (i.e matrix with _WorldSpaceCameraPos apply to it if we use camera relative rendering) float4x4 GetObjectToWorldMatrix() { 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 9e89cf00caf..321dea70b46 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 @@ -585,7 +585,6 @@ static class DecalIncludes { kColor, IncludeLocation.Pregraph }, { kFunctions, IncludeLocation.Pregraph }, { CoreIncludes.MinimalCorePregraph }, - { CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph }, { kDecal, IncludeLocation.Pregraph }, { kPassDecal, IncludeLocation.Postgraph }, }; 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 0448d8d514f..d0ad061a86a 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 @@ -97,7 +97,6 @@ IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); - includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CorePregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); @@ -133,7 +132,6 @@ IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); - includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); 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 453c67fe165..419b13f7be0 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 @@ -879,7 +879,6 @@ 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"; 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 b92a005ee9f..4ea61399d76 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 @@ -134,6 +134,8 @@ Pass #ifdef SCENESELECTIONPASS int _ObjectId; int _PassValue; + TEXTURE2D(unity_EditorViz_DepthBuffer); + SAMPLER(sampler_unity_EditorViz_DepthBuffer); #endif // Includes diff --git a/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Sphere/PassDepthOrMV.template b/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Sphere/PassDepthOrMV.template index d682634471f..f638bc2c4cd 100644 --- a/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Sphere/PassDepthOrMV.template +++ b/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Sphere/PassDepthOrMV.template @@ -34,6 +34,8 @@ ${VFXIncludeRP("VFXLit.template")} #if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION int _ObjectId; int _PassValue; +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); #endif #pragma fragment frag diff --git a/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template b/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template index 66b5144b32b..6ec629ad01a 100644 --- a/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template +++ b/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template @@ -40,6 +40,8 @@ ${SHADERGRAPH_PIXEL_CODE_DEPTHONLY} #if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION int _ObjectId; int _PassValue; +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); #endif #pragma fragment frag diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index 35c75c1afa6..2bec3b2da1c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -42,7 +42,7 @@ unsafe struct ShaderVariablesDebugDisplay public int _DebugProbeVolumeMode; public int _DebugAOVOutput; public int _DebugDisplayPad0; - public int _DebugDisplayPad1; + public int _DebugDisplayPad1; } /// @@ -73,6 +73,7 @@ public enum FullScreenDebugMode PreRefractionColorPyramid, /// Display the Depth Pyramid. DepthPyramid, + WorldSpacePosition, /// Display the final color pyramid for the frame. FinalColorPyramid, @@ -1402,7 +1403,7 @@ void RegisterLightingDebug() { var container = new DebugUI.Container { - children = + children = { new DebugUI.EnumField { displayName = "Light Volume Debug Type", getter = () => (int)data.lightingDebugSettings.lightVolumeDebugByCategory, setter = value => data.lightingDebugSettings.lightVolumeDebugByCategory = (LightVolumeDebug)value, autoEnum = typeof(LightVolumeDebug), getIndex = () => data.lightVolumeDebugTypeEnumIndex, setIndex = value => data.lightVolumeDebugTypeEnumIndex = value, onValueChanged = RefreshLightingDebug } } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl index 01f7a9a59ca..c69d82d464b 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs.hlsl @@ -17,28 +17,29 @@ #define FULLSCREENDEBUGMODE_SCREEN_SPACE_SHADOWS (7) #define FULLSCREENDEBUGMODE_PRE_REFRACTION_COLOR_PYRAMID (8) #define FULLSCREENDEBUGMODE_DEPTH_PYRAMID (9) -#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (10) -#define FULLSCREENDEBUGMODE_LIGHT_CLUSTER (11) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_GLOBAL_ILLUMINATION (12) -#define FULLSCREENDEBUGMODE_RECURSIVE_RAY_TRACING (13) -#define FULLSCREENDEBUGMODE_RAY_TRACED_SUB_SURFACE (14) -#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (15) -#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (16) -#define FULLSCREENDEBUGMODE_MOTION_VECTORS (17) -#define FULLSCREENDEBUGMODE_NAN_TRACKER (18) -#define FULLSCREENDEBUGMODE_COLOR_LOG (19) -#define FULLSCREENDEBUGMODE_DEPTH_OF_FIELD_COC (20) -#define FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW (21) -#define FULLSCREENDEBUGMODE_QUAD_OVERDRAW (22) -#define FULLSCREENDEBUGMODE_VERTEX_DENSITY (23) -#define FULLSCREENDEBUGMODE_REQUESTED_VIRTUAL_TEXTURE_TILES (24) -#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (25) -#define FULLSCREENDEBUGMODE_MIN_MATERIAL_FULL_SCREEN_DEBUG (26) -#define FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR (27) -#define FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR (28) -#define FULLSCREENDEBUGMODE_MAX_MATERIAL_FULL_SCREEN_DEBUG (29) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV (30) -#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM (31) +#define FULLSCREENDEBUGMODE_WORLD_SPACE_POSITION (10) +#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (11) +#define FULLSCREENDEBUGMODE_LIGHT_CLUSTER (12) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_GLOBAL_ILLUMINATION (13) +#define FULLSCREENDEBUGMODE_RECURSIVE_RAY_TRACING (14) +#define FULLSCREENDEBUGMODE_RAY_TRACED_SUB_SURFACE (15) +#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (16) +#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (17) +#define FULLSCREENDEBUGMODE_MOTION_VECTORS (18) +#define FULLSCREENDEBUGMODE_NAN_TRACKER (19) +#define FULLSCREENDEBUGMODE_COLOR_LOG (20) +#define FULLSCREENDEBUGMODE_DEPTH_OF_FIELD_COC (21) +#define FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW (22) +#define FULLSCREENDEBUGMODE_QUAD_OVERDRAW (23) +#define FULLSCREENDEBUGMODE_VERTEX_DENSITY (24) +#define FULLSCREENDEBUGMODE_REQUESTED_VIRTUAL_TEXTURE_TILES (25) +#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (26) +#define FULLSCREENDEBUGMODE_MIN_MATERIAL_FULL_SCREEN_DEBUG (27) +#define FULLSCREENDEBUGMODE_VALIDATE_DIFFUSE_COLOR (28) +#define FULLSCREENDEBUGMODE_VALIDATE_SPECULAR_COLOR (29) +#define FULLSCREENDEBUGMODE_MAX_MATERIAL_FULL_SCREEN_DEBUG (30) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_PREV (31) +#define FULLSCREENDEBUGMODE_SCREEN_SPACE_REFLECTIONS_ACCUM (32) // Generated from UnityEngine.Rendering.HighDefinition.ShaderVariablesDebugDisplay // PackingRules = Exact diff --git a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader index 47ea37b3110..f17369da92d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader @@ -332,6 +332,17 @@ Shader "Hidden/HDRP/DebugFullScreen" return float4(linearDepth.xxx, 1.0); } + if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_WORLD_SPACE_POSITION) + { + float depth = LoadCameraDepth(input.positionCS.xy); + PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V); + float3 positionWS = GetAbsolutePositionWS(posInput.positionWS); + + if (depth != 0) + return float4(positionWS.xyz, 1.0); + return float4(0.0, 0.0, 0.0, 0.0); + } + if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW) { float4 color = (float4)0; 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 9284d85b0c0..eae5f5b006a 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 @@ -232,7 +232,6 @@ Shader "HDRP/AxF" // 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/PickingSpaceTransforms.hlsl" #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" @@ -261,7 +260,6 @@ Shader "HDRP/AxF" // 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 SCENESELECTIONPASS // This will drive the output of the scene selection shader - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #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" 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 aab094c1a09..76fdd29d0e4 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 @@ -138,5 +138,7 @@ float3 _EmissionColor; int _ObjectId; int _PassValue; float4 _SelectionID; +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); 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 92a13774962..8bbd63f0954 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 @@ -286,12 +286,11 @@ Shader "HDRP/Decal" #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/ShaderLibrary/PickingSpaceTransforms.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/RenderPipeline/ShaderPass/ShaderPassDecal.hlsl" - + #pragma editor_sync_compilation ENDHLSL 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 e0bca14b812..1c77e117b10 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 @@ -528,6 +528,7 @@ public DecalHandle AddDecal(int materialID, in DecalProjector.CachedDecalData da ulong[] newCachedSceneLayerMask = new ulong[m_DecalsCount + kDecalBlockSize]; var cachedDecalLayerMask = new DecalLayerEnum[m_DecalsCount + kDecalBlockSize]; float[] newCachedFadeFactor = new float[m_DecalsCount + kDecalBlockSize]; + m_ResultIndices = new int[m_DecalsCount + kDecalBlockSize]; m_Handles.CopyTo(newHandles, 0); 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 d29e27051c9..3d3a01ce4cb 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 @@ -555,7 +555,6 @@ Shader "HDRP/LayeredLit" // 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/PickingSpaceTransforms.hlsl" #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" @@ -590,7 +589,6 @@ Shader "HDRP/LayeredLit" #define SHADERPASS SHADERPASS_DEPTH_ONLY #define SCENESELECTIONPASS // This will drive the output of the scene selection shader - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #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" 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 d98b1aad6bc..66ebb280e02 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 @@ -572,7 +572,6 @@ Shader "HDRP/LayeredLitTessellation" // 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/PickingSpaceTransforms.hlsl" #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" @@ -609,7 +608,6 @@ Shader "HDRP/LayeredLitTessellation" #define SHADERPASS SHADERPASS_DEPTH_ONLY #define SCENESELECTIONPASS // This will drive the output of the scene selection shader - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #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" 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 4820fe557d7..c6f9b9879f7 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 @@ -356,7 +356,6 @@ Shader "HDRP/Lit" // 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/PickingSpaceTransforms.hlsl" #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" @@ -394,7 +393,6 @@ Shader "HDRP/Lit" // 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 SCENESELECTIONPASS // This will drive the output of the scene selection shader - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #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" 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 b5b7aeb9e6b..e7f2394a349 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 @@ -291,12 +291,15 @@ float _TessellationObjectScale; float _TessellationTilingScale; #endif -// Following three variables are feeded by the C++ Editor for Scene selection +CBUFFER_END + +// Following variables and textures are fed by the C++ Editor for Scene selection +// These are global on purpose so they don't go in the main constant buffer. int _ObjectId; int _PassValue; float4 _SelectionID; - -CBUFFER_END +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); #if defined(UNITY_DOTS_INSTANCING_ENABLED) #if defined(LAYERED_LIT_SHADER) 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 613601c7ec0..3e8bdf731ef 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 @@ -374,7 +374,6 @@ Shader "HDRP/LitTessellation" // 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/PickingSpaceTransforms.hlsl" #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" @@ -414,7 +413,6 @@ Shader "HDRP/LitTessellation" // 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 SCENESELECTIONPASS // This will drive the output of the scene selection shader - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #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" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitData.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitData.hlsl index f1fe7796afb..2265a021edd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitData.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitData.hlsl @@ -32,6 +32,8 @@ CBUFFER_START(UnityTerrain) #ifdef SCENESELECTIONPASS int _ObjectId; int _PassValue; + TEXTURE2D(unity_EditorViz_DepthBuffer); + SAMPLER(sampler_unity_EditorViz_DepthBuffer); #endif CBUFFER_END diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl index 1a2ea16d0bf..992f80ecda5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLitTemplate.hlsl @@ -26,7 +26,6 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl" #endif #ifdef SCENESELECTIONPASS - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #endif #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader b/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader index e0eb3c46d3d..280ca84a4f5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.shader @@ -165,7 +165,6 @@ Shader "HDRP/Unlit" #define SHADERPASS SHADERPASS_DEPTH_ONLY #define SCENESELECTIONPASS // This will drive the output of the scene selection shader - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/Unlit.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/ShaderPass/UnlitDepthPass.hlsl" diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/UnlitProperties.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/UnlitProperties.hlsl index d259d3ae6df..66ac1c7a075 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/UnlitProperties.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Unlit/UnlitProperties.hlsl @@ -37,11 +37,15 @@ float3 _EmissionColor; // By default, the emissive is contributing float _IncludeIndirectLighting; -// Following two variables are feeded by the C++ Editor for Scene selection +CBUFFER_END + +// Following variables and textures are fed by the C++ Editor for Scene selection +// These are global on purpose so they don't go in the main constant buffer. int _ObjectId; int _PassValue; - -CBUFFER_END +float4 _SelectionID; +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); #ifdef UNITY_DOTS_INSTANCING_ENABLED diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs index 86b5f85d8df..e3b626fc6df 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs @@ -239,6 +239,8 @@ internal enum HDProfileId BuildGPULightListProbeVolumes, PushProbeVolumeLightListGlobalParameters, + RenderSceneSelection, + AOVExecute, // Enum AOVBuffers AOVOutput, 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 1a7dc920606..3dd89888313 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.Linq; +using Unity.Collections; using UnityEngine.Experimental.GlobalIllumination; using UnityEngine.Experimental.Rendering; using UnityEngine.Experimental.Rendering.RenderGraphModule; @@ -304,6 +305,11 @@ internal int GetMaxScreenSpaceShadows() RTHandle m_DebugFullScreenTempBuffer; // This target is only used in Dev builds as an intermediate destination for post process and where debug rendering will be done. RTHandle m_IntermediateAfterPostProcessBuffer; + RTHandle m_IntermediateAfterPostProcessBufferFloat; + // These are used to pass scene selection settings to the method that renders it + Camera.RenderRequestMode m_SceneSelectionMode; + RenderTexture m_SceneSelectionTarget; + // We need this flag because otherwise if no full screen debug is pushed (like for example if the corresponding pass is disabled), when we render the result in RenderDebug m_DebugFullScreenTempBuffer will contain potential garbage bool m_FullScreenDebugPushed; bool m_ValidAPI; // False by default mean we render normally, true mean we don't render anything @@ -852,9 +858,11 @@ void DestroyRenderTextures() RTHandles.Release(m_DebugColorPickerBuffer); RTHandles.Release(m_DebugFullScreenTempBuffer); RTHandles.Release(m_IntermediateAfterPostProcessBuffer); + RTHandles.Release(m_IntermediateAfterPostProcessBufferFloat); m_DebugColorPickerBuffer = null; m_DebugFullScreenTempBuffer = null; m_IntermediateAfterPostProcessBuffer = null; + m_IntermediateAfterPostProcessBufferFloat = null; if (m_RayTracingSupported) { @@ -966,7 +974,7 @@ bool IsSupportedPlatformAndDevice(out GraphicsDeviceType unsupportedGraphicDevic { HDUtils.DisplayMessageNotification("Unable to compile Default Material based on Lit.shader. Either there is a compile error in Lit.shader or the current platform / API isn't compatible."); return false; - } + } #if UNITY_EDITOR UnityEditor.BuildTarget activeBuildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget; @@ -3208,6 +3216,184 @@ static void BlitFinalCameraTexture(BlitFinalCameraTextureParameters parameters, HDUtils.DrawFullScreen(cmd, parameters.viewport, parameters.blitMaterial, destination, propertyBlock, 0, parameters.dstTexArraySlice); } + private bool IsSceneSelectionRequest(Camera.RenderRequest renderRequest) + { + switch (renderRequest.mode) + { + case Camera.RenderRequestMode.EntityId: + case Camera.RenderRequestMode.ObjectId: + case Camera.RenderRequestMode.SelectionMask: + return true; + default: + return false; + } + } + + protected override void ProcessRenderRequests(ScriptableRenderContext renderContext, Camera camera, List renderRequests) + { + var previousRT = RenderTexture.active; + RenderTexture.active = null; + + if (m_IntermediateAfterPostProcessBufferFloat == null) + m_IntermediateAfterPostProcessBufferFloat = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R32G32B32A32_SFloat, useDynamicScale: true, name: "AfterPostProcessFloat"); + + var previousPostprocessBuffer = m_IntermediateAfterPostProcessBuffer; + m_IntermediateAfterPostProcessBuffer = m_IntermediateAfterPostProcessBufferFloat; + + // Process RenderRequests in two batches. First, process every SceneSelection request, which + // is handled using a special codepath. Then, process every other request, which will go through + // the AOV system. + try + { + foreach (var request in renderRequests) + { + if (!IsSceneSelectionRequest(request)) + continue; + + var additionalCameraData = camera.GetComponent(); + if (additionalCameraData == null) + { + camera.gameObject.AddComponent(); + additionalCameraData = camera.GetComponent(); + } + + try + { + additionalCameraData.customRender += RenderSceneSelectionRequest; + m_SceneSelectionMode = request.mode; + m_SceneSelectionTarget = request.result; + Render(renderContext, new[] {camera}); + // Clear the target field to make sure we're not leaking a reference to it + m_SceneSelectionTarget = null; + } + finally + { + additionalCameraData.customRender -= RenderSceneSelectionRequest; + } + } + + bool haveAOVRequests = false; + var requests = new AOVRequestBuilder(); + foreach (var request in renderRequests) + { + if (IsSceneSelectionRequest(request)) + continue; + + var aovRequest = AOVRequest.NewDefault().SetRenderRequestMode(request.mode); + var aovBuffers = AOVBuffers.Color; + if (request.mode == Camera.RenderRequestMode.Depth || + request.mode == Camera.RenderRequestMode.WorldPosition) + aovBuffers = AOVBuffers.Output; + + requests.Add( + aovRequest, + // NOTE: RTHandles.Alloc is never allocated because the texture is passed in explicitly. + (AOVBuffers aovBufferId) => RTHandles.Alloc(request.result), + null, + new[] {aovBuffers}, + (cmd, textures, properties) => + { + //if (request.result != null) + // cmd.Blit(textures[0], request.result); + }); + haveAOVRequests = true; + } + + if (haveAOVRequests) + { + var additionaCameraData = camera.GetComponent(); + if (additionaCameraData == null) + { + camera.gameObject.AddComponent(); + additionaCameraData = camera.GetComponent(); + } + + additionaCameraData.SetAOVRequests(requests.Build()); + + Render(renderContext, new[] {camera}); + + additionaCameraData.SetAOVRequests(null); + } + } + finally + { + m_IntermediateAfterPostProcessBuffer = previousPostprocessBuffer; + RenderTexture.active = previousRT; + } + } + + void RenderSceneSelectionRequest(ScriptableRenderContext context, HDCamera hdCamera) + { + var cmd = CommandBufferPool.Get("RenderSceneSelectionRequest"); + + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RenderSceneSelection))) + { + cmd.SetRenderTarget(m_SceneSelectionTarget); + cmd.ClearRenderTarget(true, true, Color.clear); + cmd.SetGlobalInt("_ObjectId", 0); + cmd.SetGlobalInt("_PassValue", 1); + cmd.SetGlobalVector("_SelectionID", new Vector4((float)(int)m_SceneSelectionMode, 0, 0, 0)); + + hdCamera.UpdateShaderVariablesGlobalCB(ref m_ShaderVariablesGlobalCB, 0); + ConstantBuffer.PushGlobal(cmd, m_ShaderVariablesGlobalCB, HDShaderIDs._ShaderVariablesGlobal); + + var camera = hdCamera.camera; + camera.TryGetCullingParameters(out var cullingParameters); + var cullingResults = context.Cull(ref cullingParameters); + + var renderState = new RenderStateBlock(RenderStateMask.Nothing); + + ShaderTagId shaderTagId; + switch (m_SceneSelectionMode) + { + case Camera.RenderRequestMode.ObjectId: + case Camera.RenderRequestMode.EntityId: + shaderTagId = new ShaderTagId("Picking"); + // Turn backface culling off. HDRP Picking passes set "Cull Off" regardless, but things + // don't seem to always work properly unless it's done here as well. + renderState.rasterState = new RasterState(CullMode.Off); + renderState.mask = RenderStateMask.Raster; + break; + case Camera.RenderRequestMode.SelectionMask: + shaderTagId = new ShaderTagId("SceneSelectionPass"); + renderState.rasterState = new RasterState(CullMode.Back, 0, -0.02f); + // There is no Z buffer for selection mask, use blending to make sure "unoccluded" (G = 1) values + // always remain on top. + renderState.blendState = new BlendState + { + blendState0 = new RenderTargetBlendState + { + colorBlendOperation = BlendOp.Max, + sourceColorBlendMode = BlendMode.One, + destinationColorBlendMode = BlendMode.One, + alphaBlendOperation = BlendOp.Max, + sourceAlphaBlendMode = BlendMode.One, + destinationAlphaBlendMode = BlendMode.One, + writeMask = ColorWriteMask.Green | ColorWriteMask.Blue | ColorWriteMask.Alpha, + } + }; + renderState.depthState = new DepthState {compareFunction = CompareFunction.Always, writeEnabled = false}; + renderState.mask = RenderStateMask.Everything; + break; + default: + return; + } + + var drawingSettings = new DrawingSettings( + shaderTagId, + new SortingSettings(camera) { criteria = SortingCriteria.None}); + + var filteringSettings = FilteringSettings.defaultValue; + + context.ExecuteCommandBuffer(cmd); + context.DrawRenderers( + cullingResults, + ref drawingSettings, + ref filteringSettings, + ref renderState); + } + } + void SetupCameraProperties(HDCamera hdCamera, ScriptableRenderContext renderContext, CommandBuffer cmd) { // The next 2 functions are required to flush the command buffer before calling functions directly on the render context. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/AOV/AOVRequest.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/AOV/AOVRequest.cs index 7a810c3fd9b..cf74fcbf8d5 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/AOV/AOVRequest.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/AOV/AOVRequest.cs @@ -52,9 +52,13 @@ public unsafe struct AOVRequest m_MaterialProperty = MaterialSharedProperty.None, m_LightingProperty = LightingProperty.None, m_DebugFullScreen = DebugFullScreen.None, - m_LightFilterProperty = DebugLightFilterMode.None + m_LightFilterProperty = DebugLightFilterMode.None, + m_RequestMode = Camera.RenderRequestMode.None }; + + + Camera.RenderRequestMode m_RequestMode; MaterialSharedProperty m_MaterialProperty; LightingProperty m_LightingProperty; DebugLightFilterMode m_LightFilterProperty; @@ -77,6 +81,7 @@ public AOVRequest(AOVRequest other) m_LightingProperty = other.m_LightingProperty; m_DebugFullScreen = other.m_DebugFullScreen; m_LightFilterProperty = other.m_LightFilterProperty; + m_RequestMode = other.m_RequestMode; } /// State the property to render. In case of several SetFullscreenOutput chained call, only last will be used. @@ -115,6 +120,12 @@ public ref AOVRequest SetLightFilter(DebugLightFilterMode filter) return ref *thisPtr; } + public ref AOVRequest SetRenderRequestMode(Camera.RenderRequestMode mode) + { + m_RequestMode = mode; + return ref *thisPtr; + } + /// /// Populate the debug display settings with the AOV data. /// @@ -175,6 +186,50 @@ public void FillDebugData(DebugDisplaySettings debug) default: throw new ArgumentException("Unknown DebugFullScreen"); } + + if (m_RequestMode != Camera.RenderRequestMode.None) + { + switch (m_RequestMode) + { + case Camera.RenderRequestMode.Depth: + debug.SetFullScreenDebugMode(FullScreenDebugMode.DepthPyramid); + break; + case Camera.RenderRequestMode.VertexNormal: + debug.SetDebugViewVarying(DebugViewVarying.VertexNormalWS); + break; + case Camera.RenderRequestMode.WorldPosition: + debug.SetFullScreenDebugMode(FullScreenDebugMode.WorldSpacePosition); + break; + case Camera.RenderRequestMode.BaseColor: + //@TODO: This should perform metallic / specular conversion + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.Albedo); + break; + case Camera.RenderRequestMode.SpecularColor: + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.Specular); + break; + case Camera.RenderRequestMode.Metallic: + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.Metal); + break; + case Camera.RenderRequestMode.Emission: + debug.SetDebugLightingMode(DebugLightingMode.EmissiveLighting); + break; + case Camera.RenderRequestMode.Normal: + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.Normal); + break; + case Camera.RenderRequestMode.Smoothness: + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.Smoothness); + break; + case Camera.RenderRequestMode.Occlusion: + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.AmbientOcclusion); + break; + case Camera.RenderRequestMode.DiffuseColor: + //@TODO: This should perform metallic / specular conversion + debug.SetDebugViewCommonMaterialProperty(MaterialSharedProperty.Albedo); + break; + default: + throw new ArgumentOutOfRangeException(nameof(m_RequestMode), m_RequestMode, null); + } + } } /// 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 06f2851687a..4f5d8f62bfb 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 @@ -6,6 +6,7 @@ #if defined(WRITE_DECAL_BUFFER) && !defined(_DISABLE_DECALS) #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalPrepassBuffer.hlsl" #endif +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl" PackedVaryingsType Vert(AttributesMesh inputMesh) { @@ -100,9 +101,26 @@ 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); + // outColor = float4(_ObjectId, _PassValue, 1.0, 1.0); + outColor = ComputeSelectionMask( + _ObjectId, + float3(posInput.positionNDC, posInput.deviceDepth), + TEXTURE2D_ARGS(unity_EditorViz_DepthBuffer, sampler_unity_EditorViz_DepthBuffer)); #elif defined(SCENEPICKINGPASS) - outColor = _SelectionID; + #ifdef UNITY_DOTS_INSTANCING_ENABLED + // When rendering EntityIds, GameObjects output EntityId = 0 + if (_SelectionID.x == RENDER_ENTITY_ID) + outColor = ComputeEntityPickingValue(unity_EntityId.x); + else + outColor = float4(0, 0, 0, 0); + #else + // When rendering ObjectIds, Entities output ObjectId = 0 + if (_SelectionID.x == RENDER_OBJECT_ID) + outColor = PackId32ToRGBA8888(asuint(unity_LODFade.z)); + else + outColor = float4(0, 0, 0, 0); + #endif + //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 deleted file mode 100644 index 7623688cfc2..00000000000 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef UNITY_PICKING_SPACE_TRANSFORMS_INCLUDED -#define UNITY_PICKING_SPACE_TRANSFORMS_INCLUDED - -#if defined(SCENEPICKINGPASS) || defined(SCENESELECTIONPASS) - -// 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 -// For the selection pass, we want to use the non jittered projection matrix to avoid object outline flickering - -#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 - -float4x4 ScenePickingGetCameraViewProjMatrix() -{ - float4x4 translationMatrix = { - { 1.0 ,0.0 , 0.0, -_WorldSpaceCameraPos.x }, - { 0.0 ,1.0 , 0.0, -_WorldSpaceCameraPos.y }, - { 0.0 ,0.0 , 1.0, -_WorldSpaceCameraPos.z }, - { 0.0 ,0.0 , 0.0, 1.0} }; - - return mul(_CameraViewProjMatrix, translationMatrix); -} - -#define _CameraViewProjMatrix ScenePickingGetCameraViewProjMatrix() - - -// 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/ShaderVariables.hlsl b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl index 6f35c90e717..b59153a5779 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl @@ -372,6 +372,7 @@ UNITY_DOTS_INSTANCING_START(BuiltinPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(float4, unity_ProbesOcclusion) UNITY_DOTS_INSTANCED_PROP(float3x4, unity_MatrixPreviousM) UNITY_DOTS_INSTANCED_PROP(float3x4, unity_MatrixPreviousMI) + UNITY_DOTS_INSTANCED_PROP(uint2, unity_EntityId) UNITY_DOTS_INSTANCING_END(BuiltinPropertyMetadata) // Note: Macros for unity_ObjectToWorld and unity_WorldToObject are declared elsewhere @@ -389,6 +390,7 @@ UNITY_DOTS_INSTANCING_END(BuiltinPropertyMetadata) #define unity_SHBb UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4, Metadata_unity_SHBb) #define unity_SHC UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4, Metadata_unity_SHC) #define unity_ProbesOcclusion UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4, Metadata_unity_ProbesOcclusion) +#define unity_EntityId UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(uint2, Metadata_unity_EntityId) #define unity_MatrixPreviousM LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_MatrixPreviousM)) #define unity_MatrixPreviousMI LoadDOTSInstancedData_float4x4_from_float3x4(UNITY_DOTS_INSTANCED_METADATA_NAME_FROM_MACRO(float3x4, Metadata_unity_MatrixPreviousMI)) diff --git a/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl b/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl index e551f2a269e..c2c427b1acd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLitPixelOutput.hlsl @@ -48,7 +48,7 @@ float4 VFXCalcPixelOutputForward(const SurfaceData surfaceData, const BuiltinDat { float3 result = float3(1.0, 0.0, 1.0); bool needLinearToSRGB = false; - + // Loop through the whole buffer // Works because GetSurfaceDataDebug will do nothing if the index is not a known one for (int index = 1; index <= bufferSize; index++) @@ -63,7 +63,7 @@ float4 VFXCalcPixelOutputForward(const SurfaceData surfaceData, const BuiltinDat GetBSDFDataDebug(indexMaterialProperty, bsdfData, result, needLinearToSRGB); } } - + // TEMP! // For now, the final blit in the backbuffer performs an sRGB write // So in the meantime we apply the inverse transform to linear data to compensate, unless we output to AOVs. diff --git a/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl b/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl index a884b754e73..adc9a65a8c3 100644 --- a/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl +++ b/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl @@ -1,3 +1,5 @@ +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl" + void BuildInputData(Varyings input, SurfaceDescription surfaceDescription, out InputData inputData) { inputData.positionWS = input.positionWS; @@ -93,3 +95,74 @@ half4 frag(PackedVaryings packedInput) : SV_TARGET color.rgb = MixFog(color.rgb, inputData.fogCoord); return color; } + +PackedVaryings vertExtraction( + Attributes input) +{ + Varyings output = (Varyings)0; + output = BuildVaryings(input); + PackedVaryings packedOutput = (PackedVaryings)0; + packedOutput = PackVaryings(output); + +/* Not yet supported. + if (UNITY_DataExtraction_Space == 0) + packedOutput.positionCS = float4(uv0, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 1) + packedOutput.positionCS = float4(uv1, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 2) + packedOutput.positionCS = float4(uv2, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 3) + packedOutput.positionCS = float4(uv3, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 4) + packedOutput.positionCS = float4(uv4, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 5) + packedOutput.positionCS = float4(uv5, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 6) + packedOutput.positionCS = float4(uv6, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 7) + packedOutput.positionCS = float4(uv7, 0.0F, 1.0f); +*/ + return packedOutput; +} + +half4 fragExtraction(PackedVaryings packedInput) : SV_TARGET +{ + Varyings unpacked = UnpackVaryings(packedInput); + UNITY_SETUP_INSTANCE_ID(unpacked); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(unpacked); + + SurfaceDescriptionInputs surfaceDescriptionInputs = BuildSurfaceDescriptionInputs(unpacked); + SurfaceDescription surfaceDescription = SurfaceDescriptionFunction(surfaceDescriptionInputs); + + #if _AlphaClip + half alpha = surfaceDescription.Alpha; + clip(alpha - surfaceDescription.AlphaClipThreshold); + #elif _SURFACE_TYPE_TRANSPARENT + half alpha = surfaceDescription.Alpha; + #else + half alpha = 1; + #endif + + InputData inputData; + BuildInputData(unpacked, surfaceDescription, inputData); + + ExtractionInputs extraction; + extraction.vertexNormalWS = unpacked.normalWS; + extraction.pixelNormalWS = inputData.normalWS; + extraction.positionWS = inputData.positionWS; + extraction.baseColor = surfaceDescription.BaseColor; + extraction.alpha = alpha; + #ifdef _SPECULAR_SETUP + extraction.specular = surfaceDescription.Specular; + #else + extraction.metallic = surfaceDescription.Metallic; + #endif + extraction.smoothness = surfaceDescription.Smoothness; + extraction.occlusion = surfaceDescription.Occlusion; + extraction.emission = surfaceDescription.Emission.xyz; + + // half precision will not preserve things like IDs which require exact results. + return half4(OutputExtraction(extraction)); +} + + diff --git a/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs b/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs index 2855f110f0f..dc2ef87fab5 100644 --- a/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs +++ b/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs @@ -290,6 +290,7 @@ private static PassDescriptor PassVariant( in PassDescriptor source, BlockFieldD passes = new PassCollection { { PassVariant(LitPasses.Forward, CorePragmas.DOTSForward) }, + { PassVariant(LitPasses.DataExtraction, CorePragmas.DOTSDataExtraction) }, { LitPasses.GBuffer }, { PassVariant(CorePasses.ShadowCaster, CorePragmas.DOTSInstanced) }, { PassVariant(CorePasses.DepthOnly, CorePragmas.DOTSInstanced) }, @@ -345,6 +346,7 @@ private static PassDescriptor PassVariant( in PassDescriptor source, BlockFieldD passes = new PassCollection { { LitPasses.ForwardOnly }, + { LitPasses.DataExtraction }, { CorePasses.ShadowCaster }, { CorePasses.DepthOnly }, { LitPasses.DepthNormalOnly }, @@ -385,6 +387,34 @@ static class LitPasses keywords = LitKeywords.Forward, includes = LitIncludes.Forward, }; + + public static PassDescriptor DataExtraction = new PassDescriptor + { + // Definition + displayName = "Data Extraction", + referenceName = "DATA_EXTRACTION", + lightMode = "DataExtraction", + useInPreview = false, + + // Template + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + + // Port Mask + validVertexBlocks = CoreBlockMasks.Vertex, + validPixelBlocks = LitBlockMasks.FragmentLit, + + // Fields + structs = CoreStructCollections.Default, + requiredFields = LitRequiredFields.Forward, + fieldDependencies = CoreFieldDependencies.Default, + + // Conditional State + renderStates = CoreRenderStates.Default, + pragmas = CorePragmas.DataExtraction, + keywords = LitKeywords.DataExtraction, + includes = LitIncludes.Forward, + }; public static PassDescriptor ForwardOnly = new PassDescriptor { @@ -674,6 +704,56 @@ static class LitKeywords { CoreKeywordDescriptors.LightmapShadowMixing }, { CoreKeywordDescriptors.ShadowsShadowmask }, }; + + public static KeywordCollection DataExtraction = new KeywordCollection + { + new KeywordDescriptor() + { + displayName = "Extraction Modes", + referenceName = "", + type = KeywordType.MultiCompile, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global, + value = 0, + entries = new[] + { + new KeywordEntry("None", "_"), + new KeywordEntry("Object Id", "RENDER_OBJECT_ID"), + new KeywordEntry("Depth", "RENDER_DEPTH"), + new KeywordEntry("World Normals (face)", "RENDER_WORLD_NORMALS_FACE"), + new KeywordEntry("World Normals (pixel)", "RENDER_WORLD_NORMALS_PIXEL"), + new KeywordEntry("World Position", "RENDER_WORLD_POSITION"), + new KeywordEntry("Base Color + Alpha", "RENDER_BASE_COLOR_ALPHA"), + new KeywordEntry("Specular(RGB) Metallic(A)", "RENDER_SPECULAR_METALLIC"), + new KeywordEntry("Emission(RGB)", "RENDER_EMISSION"), + new KeywordEntry("Smoothness(r) + Occlusion (g)", "RENDER_SMOOTHNESS_OCCLUSION"), + new KeywordEntry("EntityId", "RENDER_ENTITY_ID"), + }, + }, + new KeywordDescriptor() + { + displayName = "Extraction Output Space", + referenceName = "", + type = KeywordType.MultiCompile, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global, + value = 0, + entries = new[] + { + new KeywordEntry("Mesh", "_"), + new KeywordEntry("UV0", "RENDER_SPACE_UV0"), + new KeywordEntry("UV1", "RENDER_SPACE_UV1"), + new KeywordEntry("UV2", "RENDER_SPACE_UV2"), + new KeywordEntry("UV3", "RENDER_SPACE_UV3"), + new KeywordEntry("UV4", "RENDER_SPACE_UV4"), + new KeywordEntry("UV5", "RENDER_SPACE_UV5"), + new KeywordEntry("UV6", "RENDER_SPACE_UV6"), + new KeywordEntry("UV7", "RENDER_SPACE_UV7"), + new KeywordEntry("UV8", "RENDER_SPACE_UV8"), + }, + } + }; + public static readonly KeywordCollection GBuffer = new KeywordCollection { diff --git a/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs b/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs index 23d074cf5d9..4cf99761e06 100644 --- a/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs +++ b/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs @@ -545,6 +545,15 @@ static class CorePragmas { Pragma.Fragment("frag") }, }; + public static readonly PragmaCollection DataExtraction = new PragmaCollection + { + { Pragma.Target(ShaderModel.Target20) }, + { Pragma.OnlyRenderers(new[]{ Platform.GLES, Platform.GLES3, Platform.GLCore }) }, + { Pragma.MultiCompileInstancing }, + { Pragma.Vertex("vertExtraction") }, + { Pragma.Fragment("fragExtraction") }, + }; + public static readonly PragmaCollection _2DDefault = new PragmaCollection { { Pragma.Target(ShaderModel.Target20) }, @@ -582,6 +591,16 @@ static class CorePragmas { Pragma.Fragment("frag") }, }; + public static readonly PragmaCollection DOTSDataExtraction = new PragmaCollection + { + { Pragma.Target(ShaderModel.Target45) }, + { Pragma.ExcludeRenderers(new[]{ Platform.GLES, Platform.GLES3, Platform.GLCore }) }, + { Pragma.MultiCompileFog }, + { Pragma.DOTSInstancing }, + { Pragma.Vertex("vertExtraction") }, + { Pragma.Fragment("fragExtraction") }, + }; + public static readonly PragmaCollection DOTSGBuffer = new PragmaCollection { { Pragma.Target(ShaderModel.Target45) }, diff --git a/com.unity.render-pipelines.universal/Runtime/Passes/DrawObjectsPass.cs b/com.unity.render-pipelines.universal/Runtime/Passes/DrawObjectsPass.cs index d04ba87033f..813f2736338 100644 --- a/com.unity.render-pipelines.universal/Runtime/Passes/DrawObjectsPass.cs +++ b/com.unity.render-pipelines.universal/Runtime/Passes/DrawObjectsPass.cs @@ -18,9 +18,35 @@ public class DrawObjectsPass : ScriptableRenderPass string m_ProfilerTag; ProfilingSampler m_ProfilingSampler; bool m_IsOpaque; + + List m_AdditionalShaderKeywords = new List(); + Dictionary m_AdditionalValues = new Dictionary(); static readonly int s_DrawObjectPassDataPropID = Shader.PropertyToID("_DrawObjectPassData"); + public RenderStateBlock RenderStateBlock + { + get => m_RenderStateBlock; + set => m_RenderStateBlock = value; + } + public void SetAdditionalKeywords(IEnumerable words) + { + m_AdditionalShaderKeywords.Clear(); + foreach (var word in words) + { + m_AdditionalShaderKeywords.Add(word); + } + } + + public void SetAdditionalValues(List> values) + { + m_AdditionalValues.Clear(); + foreach (var word in values) + { + m_AdditionalValues.Add(word.Item1, word.Item2); + } + } + public DrawObjectsPass(string profilerTag, ShaderTagId[] shaderTagIds, bool opaque, RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, StencilState stencilState, int stencilReference) { base.profilingSampler = new ProfilingSampler(nameof(DrawObjectsPass)); @@ -68,6 +94,11 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData Vector4 drawObjectPassData = new Vector4(0.0f, 0.0f, 0.0f, (m_IsOpaque) ? 1.0f : 0.0f); cmd.SetGlobalVector(s_DrawObjectPassDataPropID, drawObjectPassData); + foreach (var word in m_AdditionalShaderKeywords) + cmd.EnableShaderKeyword(word); + foreach (var value in m_AdditionalValues) + cmd.SetGlobalInt(value.Key, value.Value); + // scaleBias.x = flipSign // scaleBias.y = scale // scaleBias.z = bias @@ -96,6 +127,11 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref filterSettings, ref m_RenderStateBlock); + foreach (var word in m_AdditionalShaderKeywords) + cmd.DisableShaderKeyword(word); + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + // Render objects that did not match any shader pass with error shader RenderingUtils.RenderObjectsWithError(context, ref renderingData.cullResults, camera, filterSettings, SortingCriteria.None); } diff --git a/com.unity.render-pipelines.universal/Runtime/RenderRequests.cs b/com.unity.render-pipelines.universal/Runtime/RenderRequests.cs new file mode 100644 index 00000000000..97a39e81a8c --- /dev/null +++ b/com.unity.render-pipelines.universal/Runtime/RenderRequests.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Rendering.Universal.Internal; + +namespace UnityEngine.Rendering.Universal +{ + internal class RenderRequestRendererData : ScriptableRendererData + { + protected override ScriptableRenderer Create() + { + switch (request.mode) + { + case Camera.RenderRequestMode.SelectionMask: + return new RenderRequestSelectionMaskRenderer(this); + default: + return new RenderRequestRenderer(this); + } + } + + public Camera.RenderRequest request { get; set; } + } + + internal class RenderRequestRenderer : ScriptableRenderer + { + DrawObjectsPass m_RenderOpaqueForwardPass; + DrawObjectsPass m_RenderTransparentForwardPass; + + LayerMask m_OpaqueLayerMask = -1; + LayerMask m_TransparentLayerMask = -1; + StencilState m_DefaultStencilState = StencilState.defaultValue; + + public RenderRequestRenderer(RenderRequestRendererData data) : base(data) + { + var shaderTags = new[] {new ShaderTagId("DataExtraction")}; + + m_RenderOpaqueForwardPass = new DrawObjectsPass("Render Opaques", shaderTags, true, RenderPassEvent.BeforeRenderingOpaques, RenderQueueRange.opaque, m_OpaqueLayerMask, m_DefaultStencilState, 0 ); + m_RenderTransparentForwardPass = new DrawObjectsPass("Render Transparents", shaderTags, false, RenderPassEvent.BeforeRenderingTransparents, RenderQueueRange.transparent, m_TransparentLayerMask, m_DefaultStencilState, 0); + + List> values = new List> + { + new Tuple("UNITY_DataExtraction_Mode", (int)data.request.mode), + new Tuple("UNITY_DataExtraction_Space", (int)data.request.outputSpace), + }; + + m_RenderOpaqueForwardPass.SetAdditionalValues(values); + m_RenderTransparentForwardPass.SetAdditionalValues(values); + } + + /// + public override void Setup(ScriptableRenderContext context, ref RenderingData renderingData) + { + EnqueuePass(m_RenderOpaqueForwardPass); + EnqueuePass(m_RenderTransparentForwardPass); + } + + public override void FinishRendering(CommandBuffer cmd) + { + base.FinishRendering(cmd); + cmd.SetGlobalInt("UNITY_DataExtraction_Mode", 0); + cmd.SetGlobalInt("UNITY_DataExtraction_Space", 0); + } + } + + internal class RenderRequestSelectionMaskRenderer : ScriptableRenderer + { + DrawObjectsPass m_RenderOpaqueForwardPassZDisabled; + DrawObjectsPass m_RenderTransparentForwardPassZDisabled; + + LayerMask m_OpaqueLayerMask = -1; + LayerMask m_TransparentLayerMask = -1; + StencilState m_DefaultStencilState = StencilState.defaultValue; + + private const float kSelectionZFudgeFactor = -0.02f; + + public RenderRequestSelectionMaskRenderer(RenderRequestRendererData data) : base(data) + { + Debug.Assert(data.request.mode == Camera.RenderRequestMode.SelectionMask, "RenderRequestSelectionMaskRenderer should only be used with RenderRequestMode.SelectionMask"); + + var shaderTags = new[] {new ShaderTagId("DataExtraction")}; + + // There is no Z buffer for selection mask, use blending to make sure "unoccluded" (G = 1) values + // always remain on top when both occluded and unoccluded objects overlap. + + m_RenderOpaqueForwardPassZDisabled = new DrawObjectsPass("Render Opaques (Z disabled)", shaderTags, true, RenderPassEvent.BeforeRenderingOpaques, RenderQueueRange.opaque, m_OpaqueLayerMask, m_DefaultStencilState, 0 ); + m_RenderTransparentForwardPassZDisabled = new DrawObjectsPass("Render Transparents (Z disabled)", shaderTags, false, RenderPassEvent.BeforeRenderingTransparents, RenderQueueRange.transparent, m_TransparentLayerMask, m_DefaultStencilState, 0); + + var state = m_RenderOpaqueForwardPassZDisabled.RenderStateBlock; + state.rasterState = new RasterState(CullMode.Back, 0, kSelectionZFudgeFactor); + state.blendState = new BlendState + { + blendState0 = new RenderTargetBlendState + { + colorBlendOperation = BlendOp.Max, + sourceColorBlendMode = BlendMode.One, + destinationColorBlendMode = BlendMode.One, + alphaBlendOperation = BlendOp.Max, + sourceAlphaBlendMode = BlendMode.One, + destinationAlphaBlendMode = BlendMode.One, + writeMask = ColorWriteMask.Green | ColorWriteMask.Blue | ColorWriteMask.Alpha, + } + }; + state.depthState = new DepthState {compareFunction = CompareFunction.Always, writeEnabled = false}; + state.mask = RenderStateMask.Everything; + m_RenderOpaqueForwardPassZDisabled.RenderStateBlock = state; + m_RenderTransparentForwardPassZDisabled.RenderStateBlock = state; + + List> values = new List> + { + new Tuple("UNITY_DataExtraction_Mode", (int)data.request.mode), + new Tuple("UNITY_DataExtraction_Space", (int)data.request.outputSpace), + }; + + m_RenderOpaqueForwardPassZDisabled.SetAdditionalValues(values); + m_RenderTransparentForwardPassZDisabled.SetAdditionalValues(values); + } + + /// + public override void Setup(ScriptableRenderContext context, ref RenderingData renderingData) + { + EnqueuePass(m_RenderOpaqueForwardPassZDisabled); + EnqueuePass(m_RenderTransparentForwardPassZDisabled); + } + + public override void FinishRendering(CommandBuffer cmd) + { + base.FinishRendering(cmd); + cmd.SetGlobalInt("UNITY_DataExtraction_Mode", 0); + cmd.SetGlobalInt("UNITY_DataExtraction_Space", 0); + } + } +} diff --git a/com.unity.render-pipelines.universal/Runtime/RenderRequests.cs.meta b/com.unity.render-pipelines.universal/Runtime/RenderRequests.cs.meta new file mode 100644 index 00000000000..d77995d370c --- /dev/null +++ b/com.unity.render-pipelines.universal/Runtime/RenderRequests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 043b52e37a9f484eb91eaccca2f853f3 +timeCreated: 1620303141 \ No newline at end of file diff --git a/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index 7376bc8138f..7286777a0f3 100644 --- a/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -562,7 +562,8 @@ public void Execute(ScriptableRenderContext context, ref RenderingData rendering } // Draw Gizmos... - DrawGizmos(context, camera, GizmoSubset.PreImageEffects); + if (cameraData.renderRequestMode == Camera.RenderRequestMode.None) + DrawGizmos(context, camera, GizmoSubset.PreImageEffects); // In this block after rendering drawing happens, e.g, post processing, video player capture. if (renderBlocks.GetLength(RenderPassBlock.AfterRendering) > 0) @@ -573,9 +574,15 @@ public void Execute(ScriptableRenderContext context, ref RenderingData rendering EndXRRendering(cmd, context, ref renderingData.cameraData); - DrawWireOverlay(context, camera); - DrawGizmos(context, camera, GizmoSubset.PostImageEffects); - + if (cameraData.renderRequestMode == Camera.RenderRequestMode.None) + { + DrawWireOverlay(context, camera); + DrawGizmos(context, camera, GizmoSubset.PostImageEffects); + } + + if (cameraData.renderRequestMode == Camera.RenderRequestMode.ObjectId) + DrawGizmos(context, camera, GizmoSubset.RenderRequestInstanceID); + InternalFinishRendering(context, cameraData.resolveFinalTarget); } diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 5c6101eb8b1..206a739c4eb 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -9,6 +9,7 @@ using Lightmapping = UnityEngine.Experimental.GlobalIllumination.Lightmapping; using UnityEngine.Experimental.Rendering; using UnityEngine.Profiling; +using UnityEngine.Rendering.Universal.Internal; namespace UnityEngine.Rendering.LWRP { @@ -136,7 +137,7 @@ public static int maxVisibleAdditionalLights // GLES can be selected as platform on Windows (not a mobile platform) but uniform buffer size so we must use a low light count. return (isMobile || SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore || SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES2 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3) - ? k_MaxVisibleAdditionalLightsMobile : k_MaxVisibleAdditionalLightsNonMobile; + ? k_MaxVisibleAdditionalLightsMobile : k_MaxVisibleAdditionalLightsNonMobile; } } @@ -190,6 +191,62 @@ protected override void Dispose(bool disposing) CameraCaptureBridge.enabled = false; } + protected override void ProcessRenderRequests(ScriptableRenderContext renderContext, Camera camera, List renderRequests) + { + var cameras = new [] {camera}; + BeginFrameRendering(renderContext, cameras); + + GraphicsSettings.lightsUseLinearIntensity = (QualitySettings.activeColorSpace == ColorSpace.Linear); + GraphicsSettings.useScriptableRenderPipelineBatching = asset.useSRPBatcher; + SetupPerFrameShaderConstants(); + + BeginCameraRendering(renderContext, camera); +#if VISUAL_EFFECT_GRAPH_0_0_1_OR_NEWER + //It should be called before culling to prepare material. When there isn't any VisualEffect component, this method has no effect. + VFX.VFXManager.PrepareCamera(camera); +#endif + UpdateVolumeFramework(camera, null); + + + var cameraTarget = camera.targetTexture; + + foreach (var renderRequest in renderRequests) + { + + if (!renderRequest.isValid) + continue; + RenderWithMode(renderContext, camera, renderRequest); + } + + EndCameraRendering(renderContext, camera); + EndFrameRendering(renderContext, cameras); + camera.targetTexture = cameraTarget; + } + + private static void RenderWithMode(ScriptableRenderContext renderContext, Camera camera, Camera.RenderRequest renderRequest) + { + camera.targetTexture = renderRequest.result; + + UniversalAdditionalCameraData additionalCameraData = null; + if (IsGameCamera(camera)) + camera.gameObject.TryGetComponent(out additionalCameraData); + + if (additionalCameraData != null && additionalCameraData.renderType != CameraRenderType.Base) + { + Debug.LogWarning("Only Base cameras can be rendered with standalone RenderSingleCamera. Camera will be skipped."); + return; + } + + //@TODO: What crazy sauce is this? Perhaps this should be stored in a member and not recreated each time? + var data = ScriptableObject.CreateInstance(); + data.request = renderRequest; + InitializeCameraData(camera, additionalCameraData, true, out var cameraData); + cameraData.renderRequestMode = renderRequest.mode; + cameraData.renderer = data.InternalCreateRenderer(); + RenderSingleCamera(renderContext, cameraData, false); + Object.DestroyImmediate(data); + } + #if UNITY_2021_1_OR_NEWER protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras) { diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 790855af5d0..42e94b184b8 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -108,6 +108,7 @@ public Matrix4x4 GetGPUProjectionMatrix(int viewIndex = 0) public bool isHdrEnabled; public bool requiresDepthTexture; public bool requiresOpaqueTexture; + public Camera.RenderRequestMode renderRequestMode; #if ENABLE_VR && ENABLE_XR_MODULE public bool xrRendering; #endif diff --git a/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl b/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl new file mode 100644 index 00000000000..223d56b0997 --- /dev/null +++ b/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl @@ -0,0 +1,118 @@ +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Debug.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DataExtraction.hlsl" + +int UNITY_DataExtraction_Mode; +int UNITY_DataExtraction_Space; +TEXTURE2D(unity_EditorViz_DepthBuffer); SAMPLER(sampler_unity_EditorViz_DepthBuffer); + +struct ExtractionInputs +{ + float3 vertexNormalWS; + float3 pixelNormalWS; + float3 positionWS; + + float3 baseColor; + float alpha; + +#ifdef _SPECULAR_SETUP + float3 specular; +#else + float metallic; +#endif + float smoothness; + float occlusion; + float3 emission; +}; + +// These used to be in CommonMaterial.hlsl but no longer are. They are still +// needed for DataExtraction, so we have them here now. +void ConvertSpecularToMetallic(float3 diffuseColor, float3 specularColor, out float3 baseColor, out float metallic) +{ + metallic = saturate( (Max3(specularColor.r, specularColor.g, specularColor.b) - 0.1F) / 0.45F); + baseColor = lerp(diffuseColor, specularColor, metallic); +} + +void ConvertMetallicToSpecular(float3 baseColor, float metallic, out float3 diffuseColor, out float3 specularColor) +{ + diffuseColor = ComputeDiffuseColor(baseColor, metallic); + specularColor = ComputeFresnel0(baseColor, metallic, DEFAULT_SPECULAR_VALUE); +} + +float4 OutputExtraction(ExtractionInputs inputs) +{ + float3 specular, diffuse, baseColor; + float metallic; + + // Outline mask is the most performance sensitive (rendered each frame when selection is active), + // so it is tested first. + // For some weird reason, using a direct return inside the branch causes a warning about + // a potentially uninitialized variable, so use an explicitly initialized return value variable + // to avoid it. + float4 selectionMask = 0; + if (UNITY_DataExtraction_Mode == RENDER_OUTLINE_MASK) + { + // Red channel = unique identifier, can be used to separate groups of objects from each other + // to get outlines between them. + // Green channel = occluded behind depth buffer (0) or not occluded (1) + // Blue channel = always 1 = not cleared to zero = there's an outlined object at this pixel + selectionMask = ComputeSelectionMask( + 0, // Object unique identifier currently unused + ComputeNormalizedDeviceCoordinatesWithZ(inputs.positionWS, UNITY_MATRIX_VP), + TEXTURE2D_ARGS(unity_EditorViz_DepthBuffer, sampler_unity_EditorViz_DepthBuffer)); + } + + if (UNITY_DataExtraction_Mode == RENDER_OUTLINE_MASK) + return selectionMask; + + #ifdef _SPECULAR_SETUP + specular = inputs.specular; + diffuse = inputs.baseColor; + ConvertSpecularToMetallic(inputs.baseColor, inputs.specular, baseColor, metallic); + #else + baseColor = inputs.baseColor; + metallic = inputs.metallic; + ConvertMetallicToSpecular(inputs.baseColor, inputs.metallic, diffuse, specular); + #endif + +#ifdef UNITY_DOTS_INSTANCING_ENABLED + // Entities always have zero ObjectId + if (UNITY_DataExtraction_Mode == RENDER_OBJECT_ID) + return 0; +#else + if (UNITY_DataExtraction_Mode == RENDER_OBJECT_ID) + return PackId32ToRGBA8888(asuint(unity_LODFade.z)); +#endif + //@TODO + if (UNITY_DataExtraction_Mode == RENDER_DEPTH) + return 0; + if (UNITY_DataExtraction_Mode == RENDER_WORLD_NORMALS_FACE_RGB) + return float4(PackNormalRGB(inputs.vertexNormalWS), 1.0f); + if (UNITY_DataExtraction_Mode == RENDER_WORLD_POSITION_RGB) + return float4(inputs.positionWS, 1.0); +#ifdef UNITY_DOTS_INSTANCING_ENABLED + if (UNITY_DataExtraction_Mode == RENDER_ENTITY_ID) + return ComputeEntityPickingValue(unity_EntityId.x); +#else + // GameObjects always have zero EntityId + if (UNITY_DataExtraction_Mode == RENDER_ENTITY_ID) + return 0; +#endif + if (UNITY_DataExtraction_Mode == RENDER_BASE_COLOR_RGBA) + return float4(baseColor, inputs.alpha); + if (UNITY_DataExtraction_Mode == RENDER_SPECULAR_RGB) + return float4(specular.xxx, 1); + if (UNITY_DataExtraction_Mode == RENDER_METALLIC_R) + return float4(metallic.xxx, 1.0); + if (UNITY_DataExtraction_Mode == RENDER_EMISSION_RGB) + return float4(inputs.emission, 1.0); + if (UNITY_DataExtraction_Mode == RENDER_WORLD_NORMALS_PIXEL_RGB) + return float4(PackNormalRGB(inputs.pixelNormalWS), 1.0f); + if (UNITY_DataExtraction_Mode == RENDER_SMOOTHNESS_R) + return float4(inputs.smoothness.xxx, 1.0); + if (UNITY_DataExtraction_Mode == RENDER_OCCLUSION_R) + return float4(inputs.occlusion.xxx, 1.0); + if (UNITY_DataExtraction_Mode == RENDER_DIFFUSE_COLOR_RGBA) + return float4(diffuse, inputs.alpha); + + return 0; +} diff --git a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl.meta b/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl.meta similarity index 83% rename from com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl.meta rename to com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl.meta index 6af1b1fc268..f828fe827db 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/PickingSpaceTransforms.hlsl.meta +++ b/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 07878c52127f8a248be207c0fb1b6e77 +guid: 996764835d9cb402689335d7811b93e8 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/com.unity.render-pipelines.universal/ShaderLibrary/UniversalDOTSInstancing.hlsl b/com.unity.render-pipelines.universal/ShaderLibrary/UniversalDOTSInstancing.hlsl index 202173d5b18..34c5755fe23 100644 --- a/com.unity.render-pipelines.universal/ShaderLibrary/UniversalDOTSInstancing.hlsl +++ b/com.unity.render-pipelines.universal/ShaderLibrary/UniversalDOTSInstancing.hlsl @@ -25,6 +25,7 @@ UNITY_DOTS_INSTANCING_START(BuiltinPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(float4, unity_SHBg) UNITY_DOTS_INSTANCED_PROP(float4, unity_SHBb) UNITY_DOTS_INSTANCED_PROP(float4, unity_SHC) + UNITY_DOTS_INSTANCED_PROP(uint2, unity_EntityId) UNITY_DOTS_INSTANCING_END(BuiltinPropertyMetadata) // Note: Macros for unity_ObjectToWorld and unity_WorldToObject are declared in UnityInstancing.hlsl @@ -45,6 +46,7 @@ UNITY_DOTS_INSTANCING_END(BuiltinPropertyMetadata) #define unity_SHBg UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4, Metadata_unity_SHBg) #define unity_SHBb UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4, Metadata_unity_SHBb) #define unity_SHC UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4, Metadata_unity_SHC) +#define unity_EntityId UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(uint2, Metadata_unity_EntityId) #endif #endif diff --git a/com.unity.render-pipelines.universal/Shaders/Lit.shader b/com.unity.render-pipelines.universal/Shaders/Lit.shader index d69331217a7..b33195a4d8c 100644 --- a/com.unity.render-pipelines.universal/Shaders/Lit.shader +++ b/com.unity.render-pipelines.universal/Shaders/Lit.shader @@ -141,6 +141,7 @@ Shader "Universal Render Pipeline/Lit" ENDHLSL } + Pass { Name "ShadowCaster" @@ -325,6 +326,51 @@ Shader "Universal Render Pipeline/Lit" ENDHLSL } + + Pass + { + Name "Data Extraction" + Tags{"LightMode" = "DataExtraction"} + + Blend[_SrcBlend][_DstBlend] + ZWrite[_ZWrite] + Cull[_Cull] + + HLSLPROGRAM + #pragma exclude_renderers d3d11_9x gles + #pragma target 4.5 + + // ------------------------------------- + // Material Keywords + #pragma shader_feature_local _NORMALMAP + #pragma shader_feature_local_fragment _ALPHATEST_ON + #pragma shader_feature_local_fragment _ALPHAPREMULTIPLY_ON + #pragma shader_feature_local_fragment _EMISSION + #pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP + #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #pragma shader_feature_local_fragment _OCCLUSIONMAP + + #pragma shader_feature_local_fragment _ _CLEARCOAT _CLEARCOATMAP + + #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF + #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF + #pragma shader_feature_local_fragment _SPECULAR_SETUP + #pragma shader_feature_local _RECEIVE_SHADOWS_OFF + + //-------------------------------------- + // GPU Instancing + #pragma multi_compile_instancing + #pragma multi_compile _ DOTS_INSTANCING_ON + + #pragma vertex ExtractionVertex + #pragma fragment ExtractionFragment + + #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" + #include "Packages/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl" + + ENDHLSL + } + Pass { Name "Universal2D" diff --git a/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl b/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl new file mode 100644 index 00000000000..81eca962835 --- /dev/null +++ b/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl @@ -0,0 +1,127 @@ +#ifndef UNIVERSAL_LIT_EXTRACTION_PASS_INCLUDED +#define UNIVERSAL_LIT_EXTRACTION_PASS_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DataExtraction.hlsl" + +struct Attributes +{ + float4 positionOS : POSITION; + float3 normalOS : NORMAL; + float4 tangentOS : TANGENT; + float2 texcoord : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float2 uv2 : TEXCOORD2; + float2 uv3 : TEXCOORD3; + float2 uv4 : TEXCOORD4; + float2 uv5 : TEXCOORD5; + float2 uv6 : TEXCOORD6; + float2 uv7 : TEXCOORD7; + + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct Varyings +{ + float2 uv : TEXCOORD0; + float3 positionWS : TEXCOORD1; + float3 normalWS : TEXCOORD3; + float4 tangentWS : TEXCOORD4; // xyz: tangent, w: sign + float4 positionCS : SV_POSITION; + UNITY_VERTEX_INPUT_INSTANCE_ID + UNITY_VERTEX_OUTPUT_STEREO +}; + +void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData) +{ + inputData = (InputData)0; + + inputData.positionWS = input.positionWS; + +#ifdef _NORMALMAP + float sgn = input.tangentWS.w; // should be either +1 or -1 + float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz); + inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz)); +#else + inputData.normalWS = input.normalWS; +#endif + + inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); + inputData.normalizedScreenSpaceUV = input.positionCS.xy; +} + +Varyings ExtractionVertex(Attributes input) +{ + Varyings output = (Varyings)0; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_TRANSFER_INSTANCE_ID(input, output); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); + + // normalWS and tangentWS already normalize. + // this is required to avoid skewing the direction during interpolation + // also required for per-vertex lighting and SH evaluation + VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); + + output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); + + // already normalized from normal transform to WS. + output.normalWS = normalInput.normalWS; + real sign = input.tangentOS.w * GetOddNegativeScale(); + output.tangentWS = half4(normalInput.tangentWS.xyz, sign); + + output.positionWS = vertexInput.positionWS; + output.positionCS = vertexInput.positionCS; + + if (UNITY_DataExtraction_Space == 0) + output.positionCS = float4(input.texcoord, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 1) + output.positionCS = float4(input.uv1.xy, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 2) + output.positionCS = float4(input.uv2, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 3) + output.positionCS = float4(input.uv3, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 4) + output.positionCS = float4(input.uv4, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 5) + output.positionCS = float4(input.uv5, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 6) + output.positionCS = float4(input.uv6, 0.0F, 1.0f); + else if (UNITY_DataExtraction_Space == 7) + output.positionCS = float4(input.uv7, 0.0F, 1.0f); + + return output; +} + +float4 ExtractionFragment(Varyings input) : SV_Target +{ + UNITY_SETUP_INSTANCE_ID(input); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + SurfaceData surfaceData; + InitializeStandardLitSurfaceData(input.uv, surfaceData); + + InputData inputData; + InitializeInputData(input, surfaceData.normalTS, inputData); + + ExtractionInputs extraction; + extraction.vertexNormalWS = input.normalWS; + extraction.pixelNormalWS = inputData.normalWS; + extraction.positionWS = inputData.positionWS; + extraction.baseColor = surfaceData.albedo; + extraction.alpha = OutputAlpha(UniversalFragmentPBR(inputData, surfaceData).a); + #ifdef _SPECULAR_SETUP + extraction.specular = surfaceData.specular; + #else + extraction.metallic = surfaceData.metallic; + #endif + extraction.smoothness = surfaceData.smoothness; + extraction.occlusion = surfaceData.occlusion; + extraction.emission = surfaceData.emission; + + return OutputExtraction(extraction); +} + +#endif diff --git a/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl.meta b/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl.meta new file mode 100644 index 00000000000..c3553f11953 --- /dev/null +++ b/com.unity.render-pipelines.universal/Shaders/LitExtractionPass.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 22ccac106383e4c4f823f473865d5971 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl b/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl index 02f97fc041d..af1ffea5df3 100644 --- a/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl +++ b/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl @@ -149,6 +149,7 @@ Varyings LitPassVertex(Attributes input) return output; } + // Used in Standard (Physically Based) shader half4 LitPassFragment(Varyings input) : SV_Target { @@ -171,11 +172,11 @@ half4 LitPassFragment(Varyings input) : SV_Target InitializeInputData(input, surfaceData.normalTS, inputData); half4 color = UniversalFragmentPBR(inputData, surfaceData); - color.rgb = MixFog(color.rgb, inputData.fogCoord); color.a = OutputAlpha(color.a, _Surface); return color; } + #endif diff --git a/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs b/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs index 150b790e7de..b1675bb518e 100644 --- a/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs +++ b/com.unity.shadergraph/Editor/Data/Util/KeywordUtil.cs @@ -79,6 +79,10 @@ public static string ToDeclarationString(this KeywordDescriptor keyword) var enumEntryDefinitions = keyword.entries.Select(x => $"{keyword.referenceName}_{x.referenceName}"); string enumEntriesString = string.Join(" ", enumEntryDefinitions); return $"#pragma {definitionString} {enumEntriesString}"; + case KeywordType.MultiCompile: + var multiCompileEntryDefinitions = keyword.entries.Select(x => $"{x.referenceName}"); + string multiCompileEntriesString = string.Join(" ", multiCompileEntryDefinitions); + return $"#pragma {definitionString} {multiCompileEntriesString}"; default: throw new ArgumentOutOfRangeException(); } diff --git a/com.unity.shadergraph/Editor/Generation/Enumerations/KeywordType.cs b/com.unity.shadergraph/Editor/Generation/Enumerations/KeywordType.cs index 1a896f570da..36951a4835d 100644 --- a/com.unity.shadergraph/Editor/Generation/Enumerations/KeywordType.cs +++ b/com.unity.shadergraph/Editor/Generation/Enumerations/KeywordType.cs @@ -4,6 +4,7 @@ internal enum KeywordType { Boolean, - Enum + Enum, + MultiCompile } } diff --git a/com.unity.visualeffectgraph/Shaders/ParticleDecals/Pass.template b/com.unity.visualeffectgraph/Shaders/ParticleDecals/Pass.template index 99be7d009b2..bc236b8ced5 100644 --- a/com.unity.visualeffectgraph/Shaders/ParticleDecals/Pass.template +++ b/com.unity.visualeffectgraph/Shaders/ParticleDecals/Pass.template @@ -91,6 +91,8 @@ ${VFXInclude("Shaders/ParticleHexahedron/Pass.template")} #if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION int _ObjectId; int _PassValue; +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); #endif #pragma fragment frag diff --git a/com.unity.visualeffectgraph/Shaders/VFXParticleCommon.template b/com.unity.visualeffectgraph/Shaders/VFXParticleCommon.template index d4147bf1c7e..507725d77bd 100644 --- a/com.unity.visualeffectgraph/Shaders/VFXParticleCommon.template +++ b/com.unity.visualeffectgraph/Shaders/VFXParticleCommon.template @@ -169,6 +169,8 @@ ${SHADERGRAPH_PIXEL_CODE_DEPTHONLY} #if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION int _ObjectId; int _PassValue; +TEXTURE2D(unity_EditorViz_DepthBuffer); +SAMPLER(sampler_unity_EditorViz_DepthBuffer); #endif #pragma fragment frag