diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader index 4e8f14e2b39..ce153c3c74a 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader @@ -1,12 +1,11 @@ -#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal +#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal webgpu #define UNIFIED_RT_GROUP_SIZE_X 64 #define UNIFIED_RT_GROUP_SIZE_Y 1 #include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl" -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl" -#define QRNG_METHOD_SOBOL #include "Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl" @@ -32,7 +31,7 @@ void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) int probeId = dispatchInfo.globalThreadIndex; - QuasiRandomGenerator rngState; + QrngSobol rngState; rngState.Init(uint2((uint)probeId, 0), _SampleId); if (_SampleId==0) diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader.meta b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader.meta index f352a6f2ab2..a7970bc01bd 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader.meta +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/DynamicGI/DynamicGISkyOcclusion.urtshader.meta @@ -7,4 +7,4 @@ ScriptedImporter: userData: assetBundleName: assetBundleVariant: - script: {instanceID: 0} + script: {fileID: 11500000, guid: 42d537a8a4089e448a99fc57a06d74a9, type: 3} diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs index a0be9e1a2b9..d591b4d7011 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs @@ -616,7 +616,7 @@ struct APVRTContext static IRayTracingShader m_ShaderSO = null; static IRayTracingShader m_ShaderRL = null; - const string k_PackageLightTransport = "Packages/com.unity.rendering.light-transport"; + const string k_PackageLightTransport = "Packages/com.unity.render-pipelines.core"; internal AccelStructAdapter CreateAccelerationStructure() { @@ -713,7 +713,7 @@ public void BindSamplingTextures(CommandBuffer cmd) m_SamplingResources.Load(); } - SamplingResources.BindSobolBlueNoiseTextures(cmd, m_SamplingResources); + SamplingResources.Bind(cmd, m_SamplingResources); } public bool TryGetMeshForAccelerationStructure(Renderer renderer, out Mesh mesh) diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs index ef181385c71..593eded049e 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.RenderingLayers.cs @@ -121,14 +121,16 @@ static AccelStructAdapter BuildAccelerationStructure() Array.Fill(matIndices, renderer.component.renderingLayerMask); // repurpose the material id as we don't need it here var perSubMeshMask = new uint[subMeshCount]; Array.Fill(perSubMeshMask, GetInstanceMask(renderer.component.shadowCastingMode)); - accelStruct.AddInstance(renderer.component.GetInstanceID(), renderer.component, perSubMeshMask, matIndices, 1); + var perSubMeshIsOpaque = new bool[subMeshCount]; + Array.Fill(perSubMeshIsOpaque, true); + accelStruct.AddInstance(renderer.component.GetInstanceID(), renderer.component, perSubMeshMask, matIndices, perSubMeshIsOpaque, 1); } foreach (var terrain in contributors.terrains) { uint mask = GetInstanceMask(terrain.component.shadowCastingMode); uint materialID = terrain.component.renderingLayerMask; // repurpose the material id as we don't need it here - accelStruct.AddInstance(terrain.component.GetInstanceID(), terrain.component, new uint[1] { mask }, new uint[1] { materialID }, 1); + accelStruct.AddInstance(terrain.component.GetInstanceID(), terrain.component, new uint[1] { mask }, new uint[1] { materialID }, new bool[1] { true }, 1); } return accelStruct; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs index d9f02557df0..d894c454b5e 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs @@ -217,14 +217,16 @@ static AccelStructAdapter BuildAccelerationStructure() var matIndices = GetMaterialIndices(renderer.component); var perSubMeshMask = new uint[subMeshCount]; Array.Fill(perSubMeshMask, GetInstanceMask(renderer.component.shadowCastingMode)); + var perSubMeshIsOpaque = new bool[subMeshCount]; + Array.Fill(perSubMeshIsOpaque, true); - accelStruct.AddInstance(renderer.component.GetInstanceID(), renderer.component, perSubMeshMask, matIndices, 1); + accelStruct.AddInstance(renderer.component.GetInstanceID(), renderer.component, perSubMeshMask, matIndices, perSubMeshIsOpaque, 1); } foreach (var terrain in contributors.terrains) { uint mask = GetInstanceMask(terrain.component.shadowCastingMode); - accelStruct.AddInstance(terrain.component.GetInstanceID(), terrain.component, new uint[1] { mask }, new uint[1] { 0 }, 1); + accelStruct.AddInstance(terrain.component.GetInstanceID(), terrain.component, new uint[1] { mask }, new uint[1] { 0 }, new bool[1] { true }, 1); } return accelStruct; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs index 9f9204c4e78..b59215ab05c 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs @@ -143,8 +143,10 @@ static AccelStructAdapter BuildAccelerationStructure(int mask) int subMeshCount = mesh.subMeshCount; var maskAndMatDummy = new uint[subMeshCount]; System.Array.Fill(maskAndMatDummy, 0xFFFFFFFF); + var isOpaqueDummy = new bool[subMeshCount]; + System.Array.Fill(isOpaqueDummy, true); - accelStruct.AddInstance(renderer.component.GetInstanceID(), renderer.component, maskAndMatDummy, maskAndMatDummy, 1); + accelStruct.AddInstance(renderer.component.GetInstanceID(), renderer.component, maskAndMatDummy, maskAndMatDummy, isOpaqueDummy, 1); } foreach (var terrain in contributors.terrains) @@ -153,7 +155,7 @@ static AccelStructAdapter BuildAccelerationStructure(int mask) if ((layerMask & mask) == 0) continue; - accelStruct.AddInstance(terrain.component.GetInstanceID(), terrain.component, new uint[1] { 0xFFFFFFFF }, new uint[1] { 0xFFFFFFFF }, 1); + accelStruct.AddInstance(terrain.component.GetInstanceID(), terrain.component, new uint[1] { 0xFFFFFFFF }, new uint[1] { 0xFFFFFFFF }, new bool[1] { true }, 1); } return accelStruct; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader index 9dfeaeea073..f8ff98e3171 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader @@ -5,11 +5,9 @@ #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ShaderVariablesProbeVolumes.cs.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl" -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl" -#define QRNG_METHOD_SOBOL #define SAMPLE_COUNT 32 -#define RAND_SAMPLES_PER_BOUNCE 2 #include "Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl" @@ -27,7 +25,7 @@ void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) ray.tMax = FLT_MAX; ray.tMin = 0.0f; - QuasiRandomGenerator rngState; + QrngSobol rngState; rngState.Init(0, SAMPLE_COUNT); int4 hitCount = 0; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader.meta b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader.meta index c7962b57e64..dd81a66f9e9 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader.meta +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/RenderingLayerMask/TraceRenderingLayerMask.urtshader.meta @@ -7,4 +7,4 @@ ScriptedImporter: userData: assetBundleName: assetBundleVariant: - script: {instanceID: 0} + script: {fileID: 11500000, guid: 42d537a8a4089e448a99fc57a06d74a9, type: 3} diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing.meta b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing.meta new file mode 100644 index 00000000000..d939515bd7e --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0ababd4155f586548894b3dc7e2fd321 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/CreateUnifiedRTShaderMenuItem.cs b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/CreateUnifiedRTShaderMenuItem.cs new file mode 100644 index 00000000000..51d39897a17 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/CreateUnifiedRTShaderMenuItem.cs @@ -0,0 +1,56 @@ +using System.IO; +using UnityEngine; +using UnityEditor; +using UnityEditor.ProjectWindowCallback; + +namespace UnityEditor.Rendering.UnifiedRayTracing +{ + internal class ShaderTemplates + { + [MenuItem("Assets/Create/Shader/Unified Ray Tracing Shader", false, 1)] + internal static void CreateNewUnifiedRayTracingShader() + { + var action = ScriptableObject.CreateInstance(); + ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, action, "NewUnifiedRayTracingShader.urtshader", null, null); + } + + internal class DoCreateUnifiedRayTracingShader : EndNameEditAction + { + public override void Action(int instanceId, string pathName, string resourceFile) + { + string fullPath = Path.GetFullPath(pathName); + File.WriteAllText(fullPath, shaderContent); + + AssetDatabase.ImportAsset(pathName); + var shader = AssetDatabase.LoadAssetAtPath(pathName, typeof(Object)); + + ProjectWindowUtil.ShowCreatedAsset(shader); + } + } + +const string shaderContent = +@"#include ""Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl"" + +UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); + +void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) +{ + // Example code: + UnifiedRT::Ray ray; + ray.origin = 0; + ray.direction = float3(0, 0, 1); + ray.tMin = 0; + ray.tMax = 1000.0f; + UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); + UnifiedRT::Hit hitResult = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, 0xFFFFFFFF, ray, 0); + if (hitResult.IsValid()) + { + // Handle found intersection + } + +} +"; + } +} + + diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/CreateUnifiedRTShaderMenuItem.cs.meta b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/CreateUnifiedRTShaderMenuItem.cs.meta new file mode 100644 index 00000000000..1fc877a8226 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/CreateUnifiedRTShaderMenuItem.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 371b660fd92134146a9c35b3e4221fab \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/UnifiedRTShaderImporter.cs b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/UnifiedRTShaderImporter.cs new file mode 100644 index 00000000000..7c82be5e528 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/UnifiedRTShaderImporter.cs @@ -0,0 +1,32 @@ +using UnityEditor.AssetImporters; +using System.IO; + +namespace UnityEditor.Rendering.UnifiedRayTracing +{ + [ScriptedImporter(1, "urtshader")] + internal class UnifiedRTShaderImporter : ScriptedImporter + { + public override void OnImportAsset(AssetImportContext ctx) + { + string source = File.ReadAllText(ctx.assetPath); + + var com = ShaderUtil.CreateComputeShaderAsset(ctx, computeShaderTemplate.Replace("SHADERCODE", source)); + var rt = ShaderUtil.CreateRayTracingShaderAsset(ctx, + raytracingShaderTemplate.Replace("SHADERCODE", source)); + + ctx.AddObjectToAsset("ComputeShader", com); + ctx.AddObjectToAsset("RayTracingShader", rt); + ctx.SetMainObject(com); + } + + const string computeShaderTemplate = + "#define UNIFIED_RT_BACKEND_COMPUTE\n" + + "SHADERCODE\n" + + "#include_with_pragmas \"Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl\"\n"; + + const string raytracingShaderTemplate = + "#define UNIFIED_RT_BACKEND_HARDWARE\n" + + "SHADERCODE\n" + + "#include_with_pragmas \"Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl\"\n"; + } +} diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/UnifiedRTShaderImporter.cs.meta b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/UnifiedRTShaderImporter.cs.meta new file mode 100644 index 00000000000..15513e14a1f --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/UnifiedRTShaderImporter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 42d537a8a4089e448a99fc57a06d74a9 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.asmdef b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.asmdef new file mode 100644 index 00000000000..4b7df550f80 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "Unity.Rendering.LightTransport.Editor", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.asmdef.meta b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.asmdef.meta new file mode 100644 index 00000000000..26d6f38535b --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 085cb502223da8f46931abfa47535112 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs index 8bf49b24911..1ae793a5f88 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs @@ -5,3 +5,16 @@ [assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Runtime.Tests")] [assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.RPCore.Runtime")] [assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.Universal.Runtime")] // access to internal ProfileIds + +// Access to SamplingResources for the PathTracing package, to be removed when its content will be moved to RP Core +[assembly: InternalsVisibleTo("Unity.Rendering.PathTracing.Runtime.Tests")] +[assembly: InternalsVisibleTo("Unity.PathTracing.Runtime.Tests")] +[assembly: InternalsVisibleTo("Unity.PathTracing.Editor.Tests")] +[assembly: InternalsVisibleTo("Unity.PathTracing.Runtime")] +[assembly: InternalsVisibleTo("Unity.PathTracing.Editor")] + +// Smoke test project visibility +[assembly: InternalsVisibleTo("SRPSmoke.Runtime")] +[assembly: InternalsVisibleTo("SRPSmoke.Runtime.Tests")] +[assembly: InternalsVisibleTo("SRPSmoke.Editor.Tests")] +[assembly: InternalsVisibleTo("Assembly-CSharp-Editor-testable")] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling.meta index e1bab41523e..0f8970d497e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3358847776f217f4fa9d0bf5edc822d6 +guid: b6ee28fd674c77340a2b3b8f7a32e0da folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl index 2506dcd16cb..63f8da86c6b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl @@ -2,9 +2,11 @@ #define _SAMPLING_SAMPLING_COMMON_HLSL_ #ifndef PI -#define PI 3.141592653589f +#define PI 3.14159265358979323846f #endif +#define FLOAT_ONE_MINUS_EPSILON 0.99999994 + // Paper: Building an Orthonormal Basis, Revisited. // Tom Duff, James Burgess, Per Christensen, Christophe Hery, Andrew Kensler, Max Liani, and Ryusuke Villemin (Pixar). // https://graphics.pixar.com/library/OrthonormalB/paper.pdf @@ -111,7 +113,7 @@ float PowerHeuristic(float f, float b) float UintToFloat01(uint x) { - return x * 2.3283064365386963e-10; // (1.f / (1ULL << 32)); + return min(x * 2.3283064365386963e-10, FLOAT_ONE_MINUS_EPSILON); // (1.f / (1ULL << 32)); } int Log2Int(uint v) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl.meta index f8ed37dc6bd..7bd8e56d0ed 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Common.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3439ab1cb0e22d54bb9ce1c5c676045e +guid: 91796a9618276ff42930ee05801207aa ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl index b36c7a416a6..9b9db502575 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl @@ -140,4 +140,9 @@ uint4 Pcg4d(uint4 v) return v; } +uint PixelHash(uint2 pixelCoord, uint seed = 0) +{ + return LowBiasHash32((pixelCoord.x & 0xFFFF) | (pixelCoord.y << 16), seed); +} + #endif // _SAMPLING_HASHES_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl.meta index 3dbb1c49458..90cbecb1dcc 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Hashes.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9d187787267285249aa69304b4588bc4 +guid: ba9242b5d88ccf2489a51d94185a1300 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PathTracingSampler.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PathTracingSampler.hlsl new file mode 100644 index 00000000000..c3fa8b668e5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PathTracingSampler.hlsl @@ -0,0 +1,64 @@ +#ifndef _SAMPLING_PATHTRACINGSAMPLER_HLSL_ +#define _SAMPLING_PATHTRACINGSAMPLER_HLSL_ + +#if defined(QRNG_METHOD_RANDOM_XOR_SHIFT) || defined(QRNG_METHOD_RANDOM_PCG_4D) +#include "PseudoRandom.hlsl" +#else +#include "QuasiRandom.hlsl" +#endif + +// global dimension offset (could be used to alter the noise pattern) +#ifndef QRNG_OFFSET +#define QRNG_OFFSET 0 +#endif + +#ifndef QRNG_SAMPLES_PER_BOUNCE +#define QRNG_SAMPLES_PER_BOUNCE 64 +#endif + +struct PathTracingSampler +{ + #if defined(QRNG_METHOD_SOBOL) + QrngSobol generator; + #elif defined(QRNG_METHOD_SOBOL_BLUE_NOISE) + QrngSobolBlueNoise generator; + #elif defined(QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE) + QrngGlobalSobolBlueNoise generator; + #elif defined(QRNG_METHOD_KRONECKER) + QrngKronecker generator; + #elif defined(QRNG_METHOD_RANDOM_XOR_SHIFT) + QrngXorShift generator; + #elif defined(QRNG_METHOD_RANDOM_PCG_4D) + QrngPcg4D generator; + #endif + int bounceIndex; + + void Init(uint2 pixelCoord, uint startPathIndex, uint perPixelPathCount = 256) + { + #if defined(QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE) + generator.Init(pixelCoord, startPathIndex, perPixelPathCount); + #else + generator.Init(pixelCoord, startPathIndex); + #endif + bounceIndex = 0; + } + + float GetFloatSample(int dimension) + { + uint actualDimension = QRNG_OFFSET + QRNG_SAMPLES_PER_BOUNCE * bounceIndex + dimension; + return generator.GetFloat(actualDimension); + } + + void NextBounce() + { + bounceIndex++; + } + + void NextPath() + { + generator.NextSample(); + bounceIndex = 0; + } +}; + +#endif // _SAMPLING_PATHTRACINGSAMPLER_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PathTracingSampler.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PathTracingSampler.hlsl.meta new file mode 100644 index 00000000000..a95664f9696 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PathTracingSampler.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d330e4a95eccc4eb9bb75e79bc736ce7 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PseudoRandom.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PseudoRandom.hlsl new file mode 100644 index 00000000000..9b1e60b5e5d --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PseudoRandom.hlsl @@ -0,0 +1,61 @@ +#ifndef _SAMPLING_PSEUDORANDOM_HLSL_ +#define _SAMPLING_PSEUDORANDOM_HLSL_ + +#include "Common.hlsl" +#include "Hashes.hlsl" + +// Xor shift PRNG +struct QrngXorShift +{ + uint state; + + void Init(uint2 pixelCoord, uint startSampleIndex) + { + state = PixelHash(pixelCoord, startSampleIndex); + } + + void Init(uint seed, uint startSampleIndex) + { + state = seed; + } + + float GetFloat(uint dimension) + { + state = XorShift32(state); + return UintToFloat01(state); + } + + void NextSample() + { + } +}; + +// From paper: "Hash Functions for GPU Rendering" by Jarzynski & Olano) +struct QrngPcg4D +{ + uint4 state; + + void Init(uint2 pixelCoord, uint startSampleIndex) + { + // Seed for PCG uses a sequential sample number in 4th channel, which increments on every RNG call and starts from 0 + state = uint4(pixelCoord, startSampleIndex, 0); + } + + void Init(uint seed, uint startSampleIndex) + { + state = uint4(seed, 1, startSampleIndex, 0); + } + + float GetFloat(int dimension) + { + state.w++; + return UintToFloat01(Pcg4d(state).x); + } + + void NextSample() + { + state.z++; + } +}; + +#endif // _SAMPLING_PSEUDORANDOM_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PseudoRandom.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PseudoRandom.hlsl.meta new file mode 100644 index 00000000000..99b4f42132c --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/PseudoRandom.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 270be7a3bca5b4e038d7e90c1ca0f18c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl index db0d7d7b680..4f422c65afc 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl @@ -1,65 +1,42 @@ -#ifndef _SAMPLING_RANDOM_HLSL_ -#define _SAMPLING_RANDOM_HLSL_ +#ifndef _SAMPLING_QUASIRANDOM_HLSL_ +#define _SAMPLING_QUASIRANDOM_HLSL_ #include "Common.hlsl" -#include "Hashes.hlsl" - -// Low discrepancy sequence generator with various implementations available - -/* One of the following must be defined by the file that includes QuasiRandom.hlsl to select an implementation: -- QRNG_METHOD_SOBOL (Sobol sampler with Owen scrambling, from paper: Practical Hash-based Owen Scrambling by Burley) - infinite dims, 2097151 max samples, pixel tiling wraps at 65536 - define QRNG_SOBOL_GENERATIVE_DIMS to control how many source dimensions are used, Default value 1024 - -- QRNG_METHOD_SOBOL_BLUE_NOISE (from paper: "A Low-Discrepancy Sampler that Distributes Monte Carlo Errors as a Blue Noise in Screen Space" by Heitz and Belcour) - 256 max dims, 256 max samples (beyond 256, the sequence keeps going with another set of 256 samples belonging to another dim, and so on every 256 samples), pixel tiling wraps at 128 - -- QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE (from paper: "Screen-Space Blue-Noise Diffusion of Monte Carlo Sampling Error via Hierarchical Ordering of Pixels" by Ahmed and Wonka) - infinite dims and samples, pixel tiling depends on target sample count. The more samples, the smaller the tile (ex: for 256 samples, tiling size is 4096) - define QRNG_GLOBAL_SOBOL_ENHANCED_TILING to get tiling to always wrap at 65536 - define QRNG_SOBOL_GENERATIVE_DIMS to control how many source dimensions are used, Default value 1024 - -- QRNG_METHOD_KRONECKER (Kronecker sequence from paper "Optimizing Kronecker Sequences for Multidimensional Sampling") - fast but lower quality than Sobol, infinite dims and samples, pixel tiling wraps at 65536 - define QRNG_KRONECKER_ENHANCED_QUALITY to add small scale jitter - -These last 2 aren't low discrepancy sequences but traditional Pseudorandom number generators -- QRNG_METHOD_RANDOM_XOR_SHIFT Xor shift PRNG -- QRNG_METHOD_RANDOM_PCG_4D (from paper: "Hash Functions for GPU Rendering" by Jarzynski & Olano) -*/ - -#if defined(QRNG_METHOD_SOBOL) || defined(QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE) #include "SobolSampling.hlsl" +#include "SobolBluenoiseSampling.hlsl" -#ifndef QRNG_SOBOL_GENERATIVE_DIMS -#define QRNG_SOBOL_GENERATIVE_DIMS SOBOL_MATRICES_COUNT -#endif -static const uint kMaxSobolDim = QRNG_SOBOL_GENERATIVE_DIMS; -#endif - -uint PixelHash(uint2 pixelCoord, uint seed = 0) -{ - return LowBiasHash32((pixelCoord.x & 0xFFFF) | (pixelCoord.y << 16), seed); -} - -#if defined(QRNG_METHOD_SOBOL) +static const uint kMaxSobolDim = SOBOL_MATRICES_COUNT; -struct QuasiRandomGenerator +// Sobol sampler with Owen scrambling, from paper: Practical Hash-based Owen Scrambling by Burley +// infinite dims, 2097151 max samples, pixel tiling wraps at 65536 +// Define QRNG_SOBOL_02 to only use first 2 sobol dims and rely on scrambling for the others, this +// effectively makes every pair of dims a perfect (0,2) sequence +struct QrngSobol { uint pixelSeed; uint sampleIndex; void Init(uint2 pixelCoord, uint startSampleIndex) { - pixelSeed = PixelHash(pixelCoord); + Init(PixelHash(pixelCoord), startSampleIndex); + } + + void Init(uint seed, uint startSampleIndex) + { + pixelSeed = seed; sampleIndex = startSampleIndex; } float GetFloat(uint dimension) { + #ifdef QRNG_SOBOL_02 + uint index = NestedUniformOwenScramble(sampleIndex, pixelSeed ^ ( dimension / 2)); + return GetOwenScrambledSobolSample(index, dimension & 1, LowBiasHash32(dimension, pixelSeed)); + #else uint scrambleSeed = LowBiasHash32(pixelSeed, dimension); uint shuffleSeed = pixelSeed; return GetOwenScrambledSobolSample(sampleIndex ^ shuffleSeed, dimension % kMaxSobolDim, scrambleSeed); + #endif } void NextSample() @@ -68,10 +45,9 @@ struct QuasiRandomGenerator } }; -#elif defined(QRNG_METHOD_SOBOL_BLUE_NOISE) -#include "SobolBluenoiseSampling.hlsl" - -struct QuasiRandomGenerator +// From paper: "A Low-Discrepancy Sampler that Distributes Monte Carlo Errors as a Blue Noise in Screen Space" by Heitz and Belcour +// 256 max dims, 256 max samples (beyond 256, the sequence keeps going with another set of 256 samples belonging to another dim, and so on every 256 samples), pixel tiling wraps at 128 +struct QrngSobolBlueNoise { uint2 pixelCoord; uint sampleIndex; @@ -82,6 +58,11 @@ struct QuasiRandomGenerator sampleIndex = startSampleIndex; } + void Init(uint seed, uint startSampleIndex) + { + Init(seed / 256, seed % 256); + } + float GetFloat(uint dimension) { // If we go past the number of stored samples per dim, just shift all to the next pair of dimensions @@ -95,9 +76,11 @@ struct QuasiRandomGenerator } }; -#elif defined(QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE) - -struct QuasiRandomGenerator +// From paper: "Screen-Space Blue-Noise Diffusion of Monte Carlo Sampling Error via Hierarchical Ordering of Pixels" by Ahmed and Wonka +// infinite dims and samples, pixel tiling depends on target sample count. The more samples, the smaller the tile (ex: for 256 samples, tiling size is 4096) +// define QRNG_GLOBAL_SOBOL_ENHANCED_TILING to get tiling to always wrap at 65536 +// Define QRNG_SOBOL_02 to only use first 2 sobol dims and rely on scrambling for the others +struct QrngGlobalSobolBlueNoise { uint pixelMortonCode; uint log2SamplesPerPixel; @@ -110,9 +93,19 @@ struct QuasiRandomGenerator sampleIndex = startSampleIndex; } + void Init(uint seed, uint startSampleIndex, uint perPixelSampleCount = 256) + { + Init(uint2(seed & 0xFFFF, seed >> 16), startSampleIndex, perPixelSampleCount); + } + float GetFloat(uint dimension) { + #ifdef QRNG_SOBOL_02 + uint index = NestedUniformOwenScramble(sampleIndex, LowBiasHash32(dimension/2, 0xe0aaaf75)) & ((1U << log2SamplesPerPixel) - 1U); + return GetOwenScrambledZShuffledSobolSample(index, dimension, 2, pixelMortonCode, log2SamplesPerPixel); + #else return GetOwenScrambledZShuffledSobolSample(sampleIndex, dimension, kMaxSobolDim, pixelMortonCode, log2SamplesPerPixel); + #endif } void NextSample() @@ -121,9 +114,10 @@ struct QuasiRandomGenerator } }; -#elif defined(QRNG_METHOD_KRONECKER) - -struct QuasiRandomGenerator +// Kronecker sequence from paper "Optimizing Kronecker Sequences for Multidimensional Sampling" +//fast but lower quality than Sobol, infinite dims and samples, pixel tiling wraps at 65536 +//define QRNG_KRONECKER_ENHANCED_QUALITY to add small scale jitter +struct QrngKronecker { uint cranleyPattersonSeed; uint shuffledSampleIndex; @@ -133,7 +127,12 @@ struct QuasiRandomGenerator void Init(uint2 pixelCoord, uint startSampleIndex) { - uint hash = PixelHash(pixelCoord); + Init(PixelHash(pixelCoord), startSampleIndex); + } + + void Init(uint seed, uint startSampleIndex) + { + uint hash = seed; cranleyPattersonSeed = hash; uint shuffledStartIndex = (startSampleIndex + hash) % (1 << 20); shuffledSampleIndex = shuffledStartIndex; @@ -175,94 +174,5 @@ struct QuasiRandomGenerator } }; -#elif defined(QRNG_METHOD_RANDOM_XOR_SHIFT) - -struct QuasiRandomGenerator -{ - uint state; - - void Init(uint2 pixelCoord, uint startSampleIndex) - { - state = PixelHash(pixelCoord, startSampleIndex); - } - - float GetFloat(uint dimension) - { - state = XorShift32(state); - return UintToFloat01(state); - } - - void NextSample() - { - } -}; - -#elif defined(QRNG_METHOD_RANDOM_PCG_4D) - -struct QuasiRandomGenerator -{ - uint4 state; - - void Init(uint2 pixelCoord, uint startSampleIndex) - { - // Seed for PCG uses a sequential sample number in 4th channel, which increments on every RNG call and starts from 0 - state = uint4(pixelCoord, startSampleIndex, 0); - } - - float GetFloat(int dimension) - { - state.w++; - return UintToFloat01(Pcg4d(state).x); - } - - void NextSample() - { - state.z++; - } -}; -#endif - - -// global dimension offset (could be used to alter the noise pattern) -#ifndef QRNG_OFFSET -#define QRNG_OFFSET 0 -#endif - -#ifndef QRNG_SAMPLES_PER_BOUNCE -#define QRNG_SAMPLES_PER_BOUNCE 64 -#endif - -struct PathTracingSampler -{ - QuasiRandomGenerator generator; - int bounceIndex; - - void Init(uint2 pixelCoord, uint startPathIndex, uint perPixelPathCount = 256) - { - #if defined(QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE) - generator.Init(pixelCoord, startPathIndex, perPixelPathCount); - #else - generator.Init(pixelCoord, startPathIndex); - #endif - bounceIndex = 0; - } - - float GetFloatSample(int dimension) - { - uint actualDimension = QRNG_OFFSET + QRNG_SAMPLES_PER_BOUNCE * bounceIndex + dimension; - return generator.GetFloat(actualDimension); - } - - void NextBounce() - { - bounceIndex++; - } - - void NextPath() - { - generator.NextSample(); - bounceIndex = 0; - } -}; -#endif // _SAMPLING_RANDOM_HLSL_ +#endif // _SAMPLING_QUASIRANDOM_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl.meta index cdf88e32a65..334c195135c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/QuasiRandom.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 42d054f9eda3d4c4abfd3b0e7903cc47 +guid: 6dd45a9bd35347a45b6cb0047cab846f ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs index c6fa077e777..47132816567 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs @@ -29,7 +29,7 @@ public void Load(uint resourceBitmask = (uint)ResourceType.BlueNoiseTextures) { if ((resourceBitmask & (uint)ResourceType.BlueNoiseTextures) != 0) { - const string path = "Packages/com.unity.rendering.light-transport/Runtime/"; + const string path = "Packages/com.unity.render-pipelines.core/Runtime/"; m_SobolScramblingTile = AssetDatabase.LoadAssetAtPath(path + "Sampling/Textures/SobolBlueNoise/ScramblingTile256SPP.png"); m_SobolRankingTile = AssetDatabase.LoadAssetAtPath(path + "Sampling/Textures/SobolBlueNoise/RankingTile256SPP.png"); @@ -45,7 +45,7 @@ public void Load(uint resourceBitmask = (uint)ResourceType.BlueNoiseTextures) } #endif - public static void BindSobolBlueNoiseTextures(CommandBuffer cmd, SamplingResources resources) + public static void Bind(CommandBuffer cmd, SamplingResources resources) { if (resources.m_SobolScramblingTile != null) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs.meta index 6cb440106d7..40a3d63ef49 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: 41bb54c77a08c08438f97423537a16e6 \ No newline at end of file +guid: e664c9077c60b314a80e696796bfcecb \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl index fd1f2e0c912..df8150fdc11 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl @@ -1,14 +1,11 @@ #ifndef _SAMPLING_SAMPLINGRESOURCES_HLSL_ #define _SAMPLING_SAMPLINGRESOURCES_HLSL_ -#ifdef QRNG_METHOD_SOBOL_BLUE_NOISE Texture2D _SobolScramblingTile; Texture2D _SobolRankingTile; Texture2D _SobolOwenScrambledSequence; -#endif -#if defined(QRNG_METHOD_SOBOL) || defined(QRNG_METHOD_GLOBAL_SOBOL_BLUE_NOISE) + StructuredBuffer _SobolMatricesBuffer; -#endif #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl.meta index 4fdf9fdf2b9..0b01a75a140 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SamplingResources.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 87490cc9fe2f28f4890dcdb720bf0c94 +guid: a4f17041120a6f24c8d78d484c813aec ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl index f110d867e9b..a96f8fa8e41 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl @@ -25,7 +25,7 @@ float GetBNDSequenceSample(uint2 pixelCoord, uint sampleIndex, uint sampleDimens value = value ^ uint(scramblingValue * 256.0); // Convert to float (to avoid the same 1/256th quantization everywhere, we jitter by the pixel scramblingValue) - return (max(0.001, scramblingValue) + value) / 256.0; + return min((max(0.001, scramblingValue) + value) / 256.0, FLOAT_ONE_MINUS_EPSILON); } #endif // _SAMPLING_SOBOLBLUENOISESAMPLING_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl.meta index 4d6cb50c678..a8c02bacb18 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolBluenoiseSampling.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b7e54860bc0a3514f9dc1524fde27b07 +guid: 563a0665ce2f07e419c80acd1ad6e1f0 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolData.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolData.cs.meta index 6aadaac4079..73c86370efd 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolData.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolData.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: 4ca8401bf97c614468dbc0101d45d276 \ No newline at end of file +guid: 3855c9e5913bd1e4f84f3bb238dc6c41 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolSampling.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolSampling.hlsl.meta index dc725213798..ee7a6bb3c18 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolSampling.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/SobolSampling.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d0586908835c55944aa8bf3426243186 +guid: 8a9360b3acf7c304cbcb5a54b9b89409 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures.meta index e99a7568f9f..4271d9b67a7 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 317c6ff5b8d44894b8530492822044be +guid: 837c8a5059e05e74f8f9b8cbb40c6fa1 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise.meta index 8b9c7c388b1..bd2cc5e2e7c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5055d486e2e33654a86c88d9238d3de5 +guid: 5cd9d26d95a75804d8f849a19ab998e7 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/RankingTile256SPP.png.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/RankingTile256SPP.png.meta index d021dcb9b77..228f42a5c46 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/RankingTile256SPP.png.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/RankingTile256SPP.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5307d6e84442b0849b7ee235964e578d +guid: adf003e8db5aef64fa57c155f2e599be TextureImporter: internalIDToNameTable: [] externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/ScramblingTile256SPP.png.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/ScramblingTile256SPP.png.meta index e43be668b9d..88909a0dc40 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/ScramblingTile256SPP.png.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/ScramblingTile256SPP.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7cb0041122895034eb8f6692eed6fe14 +guid: 11fcf3c83299e814cbb25c4d74cd045d TextureImporter: internalIDToNameTable: [] externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/SobolOwenScrambled256.png.meta b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/SobolOwenScrambled256.png.meta index 4a1b57b5244..d04224526ca 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/SobolOwenScrambled256.png.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/Sampling/Textures/SobolBlueNoise/SobolOwenScrambled256.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b068695e42b4d4c3ba751c10a7189033 +guid: 8d786511913a2cb4aacb1f9a188652b4 TextureImporter: internalIDToNameTable: [] externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing.meta index f1a60317c32..cef1dd96ccc 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7c966d934bb41f84fb18758ff8dde809 +guid: 5a08d29969661ca449888ba98a48f214 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/AssemblyInfo.cs new file mode 100644 index 00000000000..6c1265bc1d3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System.Runtime.CompilerServices; + +// Make visible to tests +[assembly: InternalsVisibleTo("Unity.PathTracing.Editor.Tests")] +[assembly: InternalsVisibleTo("Unity.PathTracing.Runtime.Tests")] +[assembly: InternalsVisibleTo("Unity.LightTransport.Editor.Tests")] +[assembly: InternalsVisibleTo("Unity.Testing.UnifiedRayTracing.Runtime")] +[assembly: InternalsVisibleTo("Unity.Testing.UnifiedRayTracing.Performance")] +[assembly: InternalsVisibleTo("Unity.UnifiedRayTracing.Editor.Tests")] +[assembly: InternalsVisibleTo("Assembly-CSharp-editor-testable")] + +// Make visible internally to packages using the Unified Raytracing API, TODO: remove when the API is made public +[assembly: InternalsVisibleTo("Unity.PathTracing.Runtime")] +[assembly: InternalsVisibleTo("Unity.PathTracing.Editor")] +[assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Runtime")] +[assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor")] +[assembly: InternalsVisibleTo("Unity.RenderPipelines.HighDefinition.Runtime")] +[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Runtime")] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/AssemblyInfo.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/AssemblyInfo.cs.meta new file mode 100644 index 00000000000..8052e08b2df --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/AssemblyInfo.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 54376717d159ce7499650ad0749a238f \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl index ad6b5420c5f..1a974087244 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl @@ -1,7 +1,11 @@ #ifndef _UNIFIEDRAYTRACING_BINDINGS_HLSL_ #define _UNIFIEDRAYTRACING_BINDINGS_HLSL_ +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl" + #if defined(UNIFIED_RT_BACKEND_COMPUTE) +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/transform.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl" #ifndef UNIFIED_RT_GROUP_SIZE_X #define UNIFIED_RT_GROUP_SIZE_X 16 @@ -15,61 +19,16 @@ #define UNIFIED_RT_GROUP_SIZE_Z 1 #endif -#define GROUP_SIZE (UNIFIED_RT_GROUP_SIZE_X*UNIFIED_RT_GROUP_SIZE_Y) -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/trace_ray.hlsl" #endif - - namespace UnifiedRT { -struct Ray +struct EmptyPayload { - float3 origin; - float tMin; - float3 direction; - float tMax; -}; -struct Hit -{ - uint instanceID; - uint primitiveIndex; - float2 uvBarycentrics; - float hitDistance; - bool isFrontFace; - - bool IsValid() - { - return instanceID != -1; - } - - static Hit Invalid() - { - Hit hit = (Hit)0; - hit.instanceID = -1; - return hit; - } -}; - - -struct InstanceData -{ - float4x4 localToWorld; - float4x4 previousLocalToWorld; - float4x4 localToWorldNormals; - uint renderingLayerMask; - uint instanceMask; - uint userMaterialID; - uint geometryIndex; -}; - -struct DispatchInfo -{ - uint3 dispatchThreadID; - uint localThreadIndex; - uint3 dispatchDimensionsInThreads; - uint globalThreadIndex; }; +#ifndef UNIFIED_RT_PAYLOAD +#define UNIFIED_RT_PAYLOAD EmptyPayload +#endif struct RayTracingAccelStruct { @@ -81,7 +40,6 @@ struct RayTracingAccelStruct StructuredBuffer bottom_bvh_leaves; StructuredBuffer instance_infos; StructuredBuffer vertexBuffer; - int vertexStride; #else #pragma message("Error, you must define either UNIFIED_RT_BACKEND_HARDWARE or UNIFIED_RT_BACKEND_COMPUTE") @@ -106,8 +64,7 @@ RayTracingAccelStruct GetAccelStruct( StructuredBuffer bottomBvhs, StructuredBuffer bottomBvhLeaves, StructuredBuffer instanceInfos, - StructuredBuffer vertexBuffer, - int vertexStride) + StructuredBuffer vertexBuffer) { RayTracingAccelStruct res; res.bvh = bvh; @@ -115,19 +72,15 @@ RayTracingAccelStruct GetAccelStruct( res.bottom_bvh_leaves = bottomBvhLeaves; res.instance_infos = instanceInfos; res.vertexBuffer = vertexBuffer; - res.vertexStride = vertexStride; return res; } -#define UNIFIED_RT_DECLARE_ACCEL_STRUCT(name) StructuredBuffer name##bvh; StructuredBuffer name##bottomBvhs; StructuredBuffer name##bottomBvhLeaves; StructuredBuffer name##instanceInfos; StructuredBuffer name##vertexBuffer; int name##vertexStride -#define UNIFIED_RT_GET_ACCEL_STRUCT(name) UnifiedRT::GetAccelStruct(name##bvh, name##bottomBvhs, name##bottomBvhLeaves, name##instanceInfos, name##vertexBuffer, name##vertexStride) +#define UNIFIED_RT_DECLARE_ACCEL_STRUCT(name) StructuredBuffer name##bvh; StructuredBuffer name##bottomBvhs; StructuredBuffer name##bottomBvhLeaves; StructuredBuffer name##instanceInfos; StructuredBuffer name##vertexBuffer +#define UNIFIED_RT_GET_ACCEL_STRUCT(name) UnifiedRT::GetAccelStruct(name##bvh, name##bottomBvhs, name##bottomBvhLeaves, name##instanceInfos, name##vertexBuffer) #endif } // namespace UnifiedRT -#if defined(UNIFIED_RT_BACKEND_COMPUTE) -RWStructuredBuffer g_stack; -#endif #endif // UNIFIEDRAYTRACING_BINDINGS_HLSL diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl.meta index 1beebe588ec..79c866c1d3a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 612d23a31bb951c48ae167c31ee0f878 +guid: 047623a35563f0e45bbfce747454416c ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl index 74a9f1e52e7..679c5d288f3 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl @@ -8,10 +8,13 @@ #ifndef FLT_EPSILON #define FLT_EPSILON 1.192092896e-07F #endif + #ifndef FLT_MAX #define FLT_MAX 3.402823e+38 #endif +#define K_T_MAX 400000 + float Max3(float3 val) { return max(max(val.x, val.y), val.z); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl.meta index 290a1671bf9..28a4db58cac 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6dd8f4aba68004c88877200e0d8e7ec4 +guid: f1fa02d2f89398244bd06abebd7e1840 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.meta index e6f7f08b402..5bb73a3a647 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: dab83bd6a48c6914e8aa6103773d5bb6 +guid: b9f7ba6849814a54bb551f9491377013 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs index 9c3890d1ee9..a14bccf7ed8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs @@ -57,7 +57,7 @@ public void Dispose() _objectHandleToInstances.Clear(); } - public void AddInstance(int objectHandle, Component meshRendererOrTerrain, Span perSubMeshMask, Span perSubMeshMaterialIDs, uint renderingLayerMask) + public void AddInstance(int objectHandle, Component meshRendererOrTerrain, Span perSubMeshMask, Span perSubMeshMaterialIDs, Span perSubMeshIsOpaque, uint renderingLayerMask) { if (meshRendererOrTerrain is Terrain terrain) { @@ -78,11 +78,11 @@ public void AddInstance(int objectHandle, Component meshRendererOrTerrain, Span< Debug.Assert(meshRenderer.enabled, "Mesh renderers are expected to be enabled."); Debug.Assert(!meshRenderer.isPartOfStaticBatch, "Mesh renderers are expected to not be part of static batch."); var mesh = meshRenderer.GetComponent().sharedMesh; - AddInstance(objectHandle, mesh, meshRenderer.transform.localToWorldMatrix, perSubMeshMask, perSubMeshMaterialIDs, renderingLayerMask); + AddInstance(objectHandle, mesh, meshRenderer.transform.localToWorldMatrix, perSubMeshMask, perSubMeshMaterialIDs, perSubMeshIsOpaque, renderingLayerMask); } } - public void AddInstance(int objectHandle, Mesh mesh, Matrix4x4 localToWorldMatrix, Span perSubMeshMask, Span perSubMeshMaterialIDs, uint renderingLayerMask) + public void AddInstance(int objectHandle, Mesh mesh, Matrix4x4 localToWorldMatrix, Span perSubMeshMask, Span perSubMeshMaterialIDs, Span perSubMeshIsOpaque, uint renderingLayerMask) { int subMeshCount = mesh.subMeshCount; @@ -93,6 +93,7 @@ public void AddInstance(int objectHandle, Mesh mesh, Matrix4x4 localToWorldMatri { localToWorldMatrix = localToWorldMatrix, mask = perSubMeshMask[i], + opaqueGeometry = perSubMeshIsOpaque[i] }; instances[i].InstanceID = _instances.AddInstance(instanceDesc, perSubMeshMaterialIDs[i], renderingLayerMask); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs.meta index 5f0e651bbe5..39df6acc721 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructAdapter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 295102be7cbf62745a566ad91b3e1989 +guid: be387ad7b61cdc84c81dbdd3d936722c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructInstances.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructInstances.cs.meta index e93a2f3b761..f6fab52be35 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructInstances.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/AccelStructInstances.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 655b78989e21c594c92de1023779bc0d +guid: f9b589fa00bef23408b114d1af9b44be MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool.meta index 7a19004ccc2..77a32758844 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 23232b60bf4efdb4abc21f1228d359cc +guid: c92be10cd223d054b8314f7445705554 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs index d537ef33c29..02f6a2d4f4a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs @@ -405,17 +405,12 @@ private bool AllocateGeo(Mesh mesh, out int allocationHandle) newSlot.meshChunkTableAlloc = m_MeshChunkTableAllocator.Allocate(mesh.subMeshCount); if (!newSlot.meshChunkTableAlloc.valid) { - var oldChunkCount = m_MeshChunkTableAllocator.capacity; - var newChunkCount = m_MeshChunkTableAllocator.Grow(m_MeshChunkTableAllocator.capacity + mesh.subMeshCount); - var newChunkTableBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, newChunkCount, GetMeshChunkTableEntryByteSize()); + newSlot.meshChunkTableAlloc = m_MeshChunkTableAllocator.GrowAndAllocate(mesh.subMeshCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / GetMeshChunkTableEntryByteSize(), out int oldCapacity, out int newCapacity); + if (!newSlot.meshChunkTableAlloc.valid) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); - GraphicsHelpers.CopyBuffer(m_CopyShader, m_GlobalMeshChunkTableEntryBuffer, 0, newChunkTableBuffer, 0, DivUp(oldChunkCount * GetMeshChunkTableEntryByteSize(), 4)); - - m_GlobalMeshChunkTableEntryBuffer.Dispose(); - m_GlobalMeshChunkTableEntryBuffer = newChunkTableBuffer; - m_MaxMeshChunkTableEntriesCount = newChunkCount; - newSlot.meshChunkTableAlloc = m_MeshChunkTableAllocator.Allocate(mesh.subMeshCount); - Assert.IsTrue(newSlot.meshChunkTableAlloc.valid); + GraphicsHelpers.ReallocateBuffer(m_CopyShader, oldCapacity, newCapacity, GetMeshChunkTableEntryByteSize(), ref m_GlobalMeshChunkTableEntryBuffer); + m_MaxMeshChunkTableEntriesCount = newCapacity; } newSlot.meshChunks = new NativeArray(mesh.subMeshCount, Allocator.Persistent); @@ -427,33 +422,23 @@ private bool AllocateGeo(Mesh mesh, out int allocationHandle) newMeshChunk.vertexAlloc = m_VertexAllocator.Allocate(submeshDescriptor.vertexCount); if (!newMeshChunk.vertexAlloc.valid) { - var oldVertexCount = m_VertexAllocator.capacity; - var newVertexCount = m_VertexAllocator.Grow(m_VertexAllocator.capacity + submeshDescriptor.vertexCount); - var newVertexBuffer = new GraphicsBuffer(VertexBufferTarget, DivUp(newVertexCount * GetVertexByteSize(), 4), 4); - - GraphicsHelpers.CopyBuffer(m_CopyShader, m_GlobalVertexBuffer, 0, newVertexBuffer, 0, DivUp(oldVertexCount * GetVertexByteSize(), 4)); + newMeshChunk.vertexAlloc = m_VertexAllocator.GrowAndAllocate(submeshDescriptor.vertexCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / GetVertexByteSize(), out int oldCapacity, out int newCapacity); + if (!newMeshChunk.vertexAlloc.valid) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); - m_GlobalVertexBuffer.Dispose(); - m_GlobalVertexBuffer = newVertexBuffer; - m_MaxVertCounts = newVertexCount; - newMeshChunk.vertexAlloc = m_VertexAllocator.Allocate(submeshDescriptor.vertexCount); - Assert.IsTrue(newMeshChunk.vertexAlloc.valid); + GraphicsHelpers.ReallocateBuffer(m_CopyShader, oldCapacity, newCapacity, GetVertexByteSize(), ref m_GlobalVertexBuffer); + m_MaxVertCounts = newCapacity; } newMeshChunk.indexAlloc = m_IndexAllocator.Allocate(submeshDescriptor.indexCount); if (!newMeshChunk.indexAlloc.valid) { - var oldIndexcount = m_IndexAllocator.capacity; - var newIndexCount = m_IndexAllocator.Grow(m_IndexAllocator.capacity + submeshDescriptor.indexCount); - var newIndexBuffer = new GraphicsBuffer(IndexBufferTarget, newIndexCount, 4); - - GraphicsHelpers.CopyBuffer(m_CopyShader, m_GlobalIndexBuffer, 0, newIndexBuffer, 0, oldIndexcount); + newMeshChunk.indexAlloc = m_IndexAllocator.GrowAndAllocate(submeshDescriptor.indexCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / sizeof(int), out int oldCapacity, out int newCapacity); + if (!newMeshChunk.indexAlloc.valid) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); - m_GlobalIndexBuffer.Dispose(); - m_GlobalIndexBuffer = newIndexBuffer; - m_MaxIndexCounts = newIndexCount; - newMeshChunk.indexAlloc = m_IndexAllocator.Allocate(submeshDescriptor.indexCount); - Assert.IsTrue(newMeshChunk.indexAlloc.valid); + GraphicsHelpers.ReallocateBuffer(m_CopyShader, oldCapacity, newCapacity, sizeof(int), ref m_GlobalIndexBuffer); + m_MaxIndexCounts = newCapacity; } newSlot.meshChunks[submeshIndex] = newMeshChunk; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs.meta index 336f628a8ff..6df0de8290c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: df67d0cace6bd8442a1f2d5dcd0ad447 \ No newline at end of file +guid: 352c33fc019547446a50f48d3badcecb \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.hlsl.meta index 4062ef64775..d3dadd360ad 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 48162143dc3e410080eca2efcb84cb58 +guid: 839bff092489da0498be737d665c0665 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.hlsl.meta index 7918be651f6..09975d0ce80 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 60aab5cf6c3946d438e6483635c83a36 +guid: eca78e9f751408043bef5b9d52db9d39 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.meta index 618ba40e934..ae4fc3dcc11 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: ea70f29121a32094584be1fe3cf064dc \ No newline at end of file +guid: 1e9c09a61faef3046bcf416dbb9c9d88 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta index 7d6a836d9d1..cc557f06e82 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: e477e231a2d044e6bc38544c4b746446 +guid: 98e3d58cae7210c4786f67f504c9e899 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/TerrainToMesh.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/TerrainToMesh.cs.meta index 8aa5807fa25..f72f7c358b1 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/TerrainToMesh.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/TerrainToMesh.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8d38ab270d85f584d9dbdc347f8ba6ce +guid: f0cd7c2492f60ae4a9e06a436208c7de MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities.meta index 672d72c6506..3a507c025ce 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 32f64fed9d745e648a6d1e2ca8c73a03 +guid: d87eae04416aa5b4faeeb9dc46c9c6b6 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs index 444161ff9aa..174ea7d5a58 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs @@ -4,7 +4,13 @@ namespace UnityEngine.Rendering.UnifiedRayTracing { internal static class BackendHelpers { - internal static string GetFileNameOfShader(RayTracingBackend backend, string fileName) + /// + /// Builds a file path with the right extension for the given . + /// + /// Backend for which the shader will be loaded. + /// Path to the shader file, without any extension. + /// The file path. + public static string GetFileNameOfShader(RayTracingBackend backend, string fileName) { string postFix = backend switch { @@ -15,7 +21,12 @@ internal static string GetFileNameOfShader(RayTracingBackend backend, string fil return $"{fileName}.{postFix}"; } - internal static Type GetTypeOfShader(RayTracingBackend backend) + /// + /// Returns the of shader used by the given . + /// + /// + /// The Type of the shader. + public static Type GetTypeOfShader(RayTracingBackend backend) { Type shaderType = backend switch { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs.meta index ce52bcd6e0c..4f9797faf57 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BackendHelpers.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: c72e361e62c22e9438d71d51338ed596 \ No newline at end of file +guid: d3167d2685f567343836d6d5ee2e115e \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs index e8b5c83a3bc..d18097f3b94 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs @@ -24,26 +24,27 @@ public struct Allocation public readonly bool valid => handle != -1; } - private int m_freeElementCount; + private int m_FreeElementCount; private int m_MaxElementCount; private NativeList m_freeBlocks; private NativeList m_usedBlocks; private NativeList m_freeSlots; - public int freeElementsCount => m_freeElementCount; + public int freeElementsCount => m_FreeElementCount; public int freeBlocks => m_freeBlocks.Length; public int capacity => m_MaxElementCount; + public int allocatedSize => m_MaxElementCount - m_FreeElementCount; public void Initialize(int maxElementCounts) { m_MaxElementCount = maxElementCounts; - m_freeElementCount = maxElementCounts; + m_FreeElementCount = maxElementCounts; if (!m_freeBlocks.IsCreated) m_freeBlocks = new NativeList(Allocator.Persistent); else m_freeBlocks.Clear(); - m_freeBlocks.Add(new Block() { offset = 0, count = m_freeElementCount }); + m_freeBlocks.Add(new Block() { offset = 0, count = m_FreeElementCount }); if (!m_usedBlocks.IsCreated) m_usedBlocks = new NativeList(Allocator.Persistent); @@ -56,7 +57,7 @@ public void Initialize(int maxElementCounts) m_freeSlots.Clear(); } - private int CalculateGeometricGrowthCapacity(int newMaxElementCount, int maxAllowedNewCapacity) + private int CalculateGeometricGrowthCapacity(int desiredNewCapacity, int maxAllowedNewCapacity) { var oldCapacity = capacity; @@ -67,26 +68,27 @@ private int CalculateGeometricGrowthCapacity(int newMaxElementCount, int maxAllo var geometricNewCapacity = oldCapacity + oldCapacity / 2; - if (geometricNewCapacity < newMaxElementCount) - return newMaxElementCount; // geometric growth would be insufficient + if (geometricNewCapacity < desiredNewCapacity) + return desiredNewCapacity; // geometric growth would be insufficient else return geometricNewCapacity; } - public int Grow(int newDesiredCapacity, int maxAllowedNewCapacity = Int32.MaxValue) + public int Grow(int newDesiredCapacity, int maxAllowedCapacity = Int32.MaxValue) { - newDesiredCapacity = CalculateGeometricGrowthCapacity(newDesiredCapacity, maxAllowedNewCapacity); + Debug.Assert(newDesiredCapacity > 0, "newDesiredCapacity must be positive"); + Debug.Assert(maxAllowedCapacity > 0, "maxAllowedCapacity must be positive"); + Debug.Assert(capacity < newDesiredCapacity, "newDesiredCapacity must be greater than curent capacity"); + Debug.Assert(maxAllowedCapacity >= newDesiredCapacity, "newDesiredCapacity must be smaller than maxAllowedCapacity"); + var newCapacity = CalculateGeometricGrowthCapacity(newDesiredCapacity, maxAllowedCapacity); var oldCapacity = m_MaxElementCount; - var addedElements = newDesiredCapacity - oldCapacity; - if (addedElements <= 0) - return 0; + var addedElements = newCapacity - oldCapacity; + Debug.Assert(addedElements > 0); - Debug.Assert(addedElements > 0, "newMaxElementCount must be greater than current capacity"); - - m_freeElementCount += addedElements; - m_MaxElementCount = newDesiredCapacity; + m_FreeElementCount += addedElements; + m_MaxElementCount = newCapacity; int blockToMerge = m_freeBlocks.Length; m_freeBlocks.Add(new Block() { offset = oldCapacity, count = addedElements }); @@ -97,26 +99,36 @@ public int Grow(int newDesiredCapacity, int maxAllowedNewCapacity = Int32.MaxVal return m_MaxElementCount; } + public bool GetExpectedGrowthToFitAllocation(int elementCounts, int maxAllowedCapacity, out int newCapacity) + { + newCapacity = 0; + + var additionalRequiredElements = m_freeBlocks.IsEmpty ? elementCounts : math.max(elementCounts - m_freeBlocks[m_freeBlocks.Length - 1].count, 0); + if (maxAllowedCapacity < capacity || (maxAllowedCapacity - capacity) < additionalRequiredElements) + return false; + + newCapacity = additionalRequiredElements > 0 ? CalculateGeometricGrowthCapacity(capacity + additionalRequiredElements, maxAllowedCapacity) : capacity; + return true; + } + public Allocation GrowAndAllocate(int elementCounts, out int oldCapacity, out int newCapacity) { return GrowAndAllocate(elementCounts, Int32.MaxValue, out oldCapacity, out newCapacity); } - public Allocation GrowAndAllocate(int elementCounts, int maxAllowedNewCapacity, out int oldCapacity, out int newCapacity) + public Allocation GrowAndAllocate(int elementCounts, int maxAllowedCapacity, out int oldCapacity, out int newCapacity) { - var additionalRequiredElements = m_freeBlocks.IsEmpty ? elementCounts : math.max(elementCounts - m_freeBlocks[m_freeBlocks.Length-1].count, 0); + oldCapacity = capacity; - if (maxAllowedNewCapacity < capacity || (maxAllowedNewCapacity - capacity) < additionalRequiredElements) + var additionalRequiredElements = m_freeBlocks.IsEmpty ? elementCounts : math.max(elementCounts - m_freeBlocks[m_freeBlocks.Length - 1].count, 0); + if (maxAllowedCapacity < capacity || (maxAllowedCapacity - capacity) < additionalRequiredElements) { - oldCapacity = capacity; - newCapacity = 0; + newCapacity = capacity; return Allocation.Invalid; } - oldCapacity = capacity; - newCapacity = Grow(capacity + additionalRequiredElements, maxAllowedNewCapacity); - if (newCapacity == 0) - return Allocation.Invalid; + newCapacity = additionalRequiredElements > 0 ? Grow(capacity + additionalRequiredElements, maxAllowedCapacity) : capacity; + Debug.Assert(newCapacity >= oldCapacity + additionalRequiredElements); var alloc = Allocate(elementCounts); Assert.IsTrue(alloc.valid); @@ -126,7 +138,7 @@ public Allocation GrowAndAllocate(int elementCounts, int maxAllowedNewCapacity, public void Dispose() { m_MaxElementCount = 0; - m_freeElementCount = 0; + m_FreeElementCount = 0; if (m_freeBlocks.IsCreated) m_freeBlocks.Dispose(); if (m_usedBlocks.IsCreated) @@ -137,7 +149,7 @@ public void Dispose() public Allocation Allocate(int elementCounts) { - if (elementCounts > m_freeElementCount || m_freeBlocks.IsEmpty) + if (elementCounts > m_FreeElementCount || m_freeBlocks.IsEmpty) return Allocation.Invalid; int selectedBlock = -1; @@ -182,7 +194,7 @@ public Allocation Allocate(int elementCounts) m_usedBlocks[allocationHandle] = allocationBlock; } - m_freeElementCount -= elementCounts; + m_FreeElementCount -= elementCounts; return new Allocation() { handle = allocationHandle, block = allocationBlock }; } @@ -232,7 +244,7 @@ public void FreeAllocation(in Allocation allocation) while (blockToMerge != -1) blockToMerge = MergeBlockFrontBack(blockToMerge); - m_freeElementCount += allocation.block.count; + m_FreeElementCount += allocation.block.count; } public Allocation[] SplitAllocation(in Allocation allocation, int count) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs.meta index 85130071775..81922fc6b81 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/BlockAllocator.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 664837c6403e79741a4cb05fc58a66ab +guid: 56a7556d9033d1f43b3825829da0505f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta index 2cb58a6a5e0..11d24f17516 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 033e2ad50853a92498e5ca004bf0a68c +guid: 1b95b5dcf48d1914c9e1e7405c7660e3 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs index 36d05527d25..f64c69e4e7c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs @@ -38,6 +38,21 @@ static public void CopyBuffer(ComputeShader copyShader, GraphicsBuffer src, int Graphics.ExecuteCommandBuffer(cmd); } + static public bool ReallocateBuffer(ComputeShader copyShader, int oldCapacity, int newCapacity, int elementSizeInBytes, ref GraphicsBuffer buffer) + { + int bufferStrideInBytes = buffer.stride; + var newBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, newCapacity * elementSizeInBytes / bufferStrideInBytes, bufferStrideInBytes); + if (!newBuffer.IsValid()) + return false; + + CopyBuffer(copyShader, buffer, 0, newBuffer, 0, oldCapacity * elementSizeInBytes / 4); + buffer.Dispose(); + buffer = newBuffer; + + return true; + } + + public const int MaxGraphicsBufferSizeInBytes = int.MaxValue; static public int DivUp(int x, int y) => (x + y - 1) / y; static public int DivUp(int x, uint y) => (x + (int)y - 1) / (int)y; static public uint DivUp(uint x, uint y) => (x + y - 1) / y; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs.meta index 048a4d68365..52877874abb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/GraphicsHelpers.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c86b8c7f5cb48934392704c99b69c9b7 +guid: bfd0ff47a7084174ba1c6b5a11903a1b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/PersistentGPUArray.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/PersistentGPUArray.cs.meta index ee7c9910219..7061f2ca836 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/PersistentGPUArray.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/PersistentGPUArray.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1b3fae1cd111b8f4895b008c99a99803 +guid: a6af8b249ef94724681ddfb4d682f0b7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs index df16ab06859..c608dd51814 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs @@ -1,4 +1,8 @@ +using System; +using System.Diagnostics; +using UnityEngine.UIElements; + namespace UnityEngine.Rendering.UnifiedRayTracing { internal static class Utils @@ -17,6 +21,30 @@ public static void Destroy(UnityEngine.Object obj) #endif } } + + [Conditional("UNITY_ASSERTIONS")] + public static void CheckArgIsNotNull(System.Object obj, string argName) + { + if (obj == null) + throw new ArgumentNullException(argName); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void CheckArg(bool condition, string message) + { + if (!condition) + throw new ArgumentException(message); + } + + [Conditional("UNITY_ASSERTIONS")] + public static void CheckArgRange(T value, T minIncluded, T maxExcluded, string argName) where T: IComparable + { + if (value.CompareTo(minIncluded) < 0 || value.CompareTo(maxExcluded) >= 0) + { + var message = $"{argName}={value}, it must be in the range [{minIncluded}, {maxExcluded}["; + throw new ArgumentOutOfRangeException(argName, message); + } + } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs.meta index 1b8cb5a0f0c..b1c545e20f0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/Utilities/Utils.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: 38870b584486a484b83bf1b5e0e302a9 \ No newline at end of file +guid: 8787039c0fe98374a9815ac59d9878ef \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl new file mode 100644 index 00000000000..289ff19cb8d --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl @@ -0,0 +1,71 @@ +#ifndef _UNIFIEDRAYTRACING_COMMONSTRUCTS_HLSL_ +#define _UNIFIEDRAYTRACING_COMMONSTRUCTS_HLSL_ + +namespace UnifiedRT { + +static const uint kRayFlagNone = 0x0; +static const uint kRayFlagForceOpaque = 0x01; +static const uint kRayFlagForceNonOpaque = 0x02; +static const uint kRayFlagAcceptFirstHitAndEndSearch = 0x04; +static const uint kRayFlagSkipClosestHit = 0x08; +static const uint kRayFlagCullBackFacingTriangles = 0x10; +static const uint kRayFlagCullFrontFacingTriangles = 0x20; +static const uint kRayFlagCullOpaque = 0x40; +static const uint kRayFlagCullNonOpaque = 0x80; + +static const uint kIgnoreHit = 0; +static const uint kAcceptHit = 1; +static const uint kAcceptHitAndEndSearch = 2; + +struct Ray +{ + float3 origin; + float tMin; + float3 direction; + float tMax; +}; + +struct Hit +{ + uint instanceID; + uint primitiveIndex; + float2 uvBarycentrics; + float hitDistance; + bool isFrontFace; + + bool IsValid() + { + return instanceID != -1; + } + + static Hit Invalid() + { + Hit hit = (Hit)0; + hit.instanceID = -1; + return hit; + } +}; + + +struct InstanceData +{ + float4x4 localToWorld; + float4x4 previousLocalToWorld; + float4x4 localToWorldNormals; + uint renderingLayerMask; + uint instanceMask; + uint userMaterialID; + uint geometryIndex; +}; + +struct DispatchInfo +{ + uint3 dispatchThreadID; + uint localThreadIndex; + uint3 dispatchDimensionsInThreads; + uint globalThreadIndex; +}; + +} // namespace UnifiedRT + +#endif // _UNIFIEDRAYTRACING_COMMONSTRUCTS_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl.meta new file mode 100644 index 00000000000..3cb8c001793 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7d31f2834b1e0db45bc5e8596c3908cf diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute.meta index b5b15212e18..66daae419d7 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f242eaea8e7ce454ea303340a67e3743 +guid: 4ecd3fe6796a2ca4aa0c3b180133d9d9 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs index ebb2325f5e4..7be972eebd5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs @@ -1,4 +1,5 @@ using System; +using Unity.Collections.LowLevel.Unsafe; using Unity.Mathematics; using UnityEngine.Assertions; using UnityEngine.Rendering.RadeonRays; @@ -18,7 +19,7 @@ internal sealed class BLASPositionsPool : IDisposable { public BLASPositionsPool(ComputeShader copyPositionsShader, ComputeShader copyShader) { - m_VerticesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, intialVertexCount*3, 4); + m_VerticesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, intialVertexCount * VertexSizeInDwords, 4); m_VerticesAllocator = new BlockAllocator(); m_VerticesAllocator.Initialize(intialVertexCount); @@ -33,15 +34,17 @@ public void Dispose() m_VerticesAllocator.Dispose(); } + public const int VertexSizeInDwords = 3; + public GraphicsBuffer VertexBuffer { get { return m_VerticesBuffer; } } public void Clear() { m_VerticesBuffer.Dispose(); - m_VerticesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, intialVertexCount * 3, 4); + m_VerticesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, intialVertexCount * VertexSizeInDwords, 4); m_VerticesAllocator.Dispose(); m_VerticesAllocator = new BlockAllocator(); - m_VerticesAllocator.Initialize(intialVertexCount*3); + m_VerticesAllocator.Initialize(intialVertexCount); } const int intialVertexCount = 1000; @@ -55,17 +58,19 @@ public void Clear() public void Add(VertexBufferChunk info, out BlockAllocator.Allocation verticesAllocation) { - verticesAllocation = m_VerticesAllocator.Allocate((int)info.vertexCount*3); + verticesAllocation = m_VerticesAllocator.Allocate((int)info.vertexCount); if (!verticesAllocation.valid) { - verticesAllocation = m_VerticesAllocator.GrowAndAllocate((int)info.vertexCount * 3, int.MaxValue/4, out int oldCapacity, out int newCapacity); - if (!verticesAllocation.valid) - throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.OutOfGraphicsBufferMemory); - - var newVertexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, newCapacity, 4); - GraphicsHelpers.CopyBuffer(m_CopyShader, m_VerticesBuffer, 0, newVertexBuffer, 0, oldCapacity); - m_VerticesBuffer.Dispose(); - m_VerticesBuffer = newVertexBuffer; + int oldCapacity = m_VerticesAllocator.capacity; + + if (!m_VerticesAllocator.GetExpectedGrowthToFitAllocation((int)info.vertexCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / UnsafeUtility.SizeOf(), out int newCapacity)) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + if (!GraphicsHelpers.ReallocateBuffer(m_CopyShader, oldCapacity, newCapacity, UnsafeUtility.SizeOf(), ref m_VerticesBuffer)) + throw new UnifiedRayTracingException($"Failed to allocate buffer of size: {newCapacity * UnsafeUtility.SizeOf()} bytes", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + verticesAllocation = m_VerticesAllocator.GrowAndAllocate((int)info.vertexCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / UnsafeUtility.SizeOf(), out oldCapacity, out newCapacity); + Debug.Assert(verticesAllocation.valid); } var cmd = new CommandBuffer(); @@ -73,7 +78,7 @@ public void Add(VertexBufferChunk info, out BlockAllocator.Allocation verticesAl cmd.SetComputeIntParam(m_CopyPositionsShader, "_InputPosBufferOffset", info.verticesStartOffset); cmd.SetComputeIntParam(m_CopyPositionsShader, "_InputBaseVertex", info.baseVertex); cmd.SetComputeIntParam(m_CopyPositionsShader, "_InputPosBufferStride", (int)info.vertexStride); - cmd.SetComputeIntParam(m_CopyPositionsShader, "_OutputPosBufferOffset", verticesAllocation.block.offset); + cmd.SetComputeIntParam(m_CopyPositionsShader, "_OutputPosBufferOffset", verticesAllocation.block.offset * VertexSizeInDwords); cmd.SetComputeBufferParam(m_CopyPositionsShader, m_CopyVerticesKernel, "_InputPosBuffer", info.vertices); cmd.SetComputeBufferParam(m_CopyPositionsShader, m_CopyVerticesKernel, "_OutputPosBuffer", m_VerticesBuffer); cmd.DispatchCompute(m_CopyPositionsShader, m_CopyVerticesKernel, (int)Common.CeilDivide(info.vertexCount, kItemsPerWorkgroup), 1, 1); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs.meta index 4bb02ec152a..e0a61b8d278 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/BLASPositionsPool.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: b53cc1c0c355a50498ab7a4832b90582 \ No newline at end of file +guid: e633faaa7fc13ca42afbbd3359354b1a \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs index f588d123d75..23f8de492fb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs @@ -3,6 +3,10 @@ using Unity.Mathematics; using UnityEngine.Assertions; using UnityEngine.Rendering.RadeonRays; +using UnityEditor; +using System.Data; + + #if UNITY_EDITOR @@ -75,6 +79,10 @@ public void Dispose() public int AddInstance(MeshInstanceDesc meshInstance) { + Utils.CheckArgIsNotNull(meshInstance.mesh, "meshInstance.mesh"); + Utils.CheckArg(meshInstance.mesh.HasVertexAttribute(VertexAttribute.Position), "Cant use a mesh buffer that has no positions."); + Utils.CheckArgRange(meshInstance.subMeshIndex, 0, meshInstance.mesh.subMeshCount, "meshInstance.subMeshIndex"); + var blas = GetOrAllocateMeshBlas(meshInstance.mesh, meshInstance.subMeshIndex); blas.IncRef(); @@ -89,6 +97,7 @@ public int AddInstance(MeshInstanceDesc meshInstance) triangleCullingEnabled = meshInstance.enableTriangleCulling, invertTriangleCulling = meshInstance.frontTriangleCounterClockwise, userInstanceID = meshInstance.instanceID == 0xFFFFFFFF ? (uint)handle : meshInstance.instanceID, + opaqueGeometry = meshInstance.opaqueGeometry, localToWorldTransform = ConvertTranform(meshInstance.localToWorldMatrix) }); @@ -97,6 +106,8 @@ public int AddInstance(MeshInstanceDesc meshInstance) public void RemoveInstance(int instanceHandle) { + CheckInstanceHandleIsValid(instanceHandle); + ReleaseHandle(instanceHandle); m_RadeonInstances.Remove(instanceHandle, out RadeonRaysInstance entry); @@ -134,33 +145,38 @@ public void ClearInstances() public void UpdateInstanceTransform(int instanceHandle, Matrix4x4 localToWorldMatrix) { + CheckInstanceHandleIsValid(instanceHandle); + m_RadeonInstances[instanceHandle].localToWorldTransform = ConvertTranform(localToWorldMatrix); FreeTopLevelAccelStruct(); } public void UpdateInstanceID(int instanceHandle, uint instanceID) { + CheckInstanceHandleIsValid(instanceHandle); + m_RadeonInstances[instanceHandle].userInstanceID = instanceID; FreeTopLevelAccelStruct(); } public void UpdateInstanceMask(int instanceHandle, uint mask) { + CheckInstanceHandleIsValid(instanceHandle); + m_RadeonInstances[instanceHandle].instanceMask = mask; FreeTopLevelAccelStruct(); } - + public void Build(CommandBuffer cmd, GraphicsBuffer scratchBuffer) { - var requiredScratchSize = GetBuildScratchBufferRequiredSizeInBytes(); - if (requiredScratchSize > 0 && (scratchBuffer == null || ((ulong)(scratchBuffer.count * scratchBuffer.stride) < requiredScratchSize))) - { - throw new System.ArgumentException("scratchBuffer size is too small"); - } + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); - if (requiredScratchSize > 0 && scratchBuffer.stride != 4) + var requiredScratchSize = GetBuildScratchBufferRequiredSizeInBytes(); + if (requiredScratchSize > 0) { - throw new System.ArgumentException("scratchBuffer stride must be 4"); + Utils.CheckArgIsNotNull(scratchBuffer, nameof(scratchBuffer)); + Utils.CheckArg((ulong)(scratchBuffer.count * scratchBuffer.stride) >= requiredScratchSize, "scratchBuffer size is too small"); + Utils.CheckArg(scratchBuffer.stride == 4, "scratchBuffer stride must be 4"); } if (m_TopLevelAccelStruct != null) @@ -194,8 +210,13 @@ private MeshBlas GetOrAllocateMeshBlas(Mesh mesh, int subMeshIndex) return blas; } + // throws UnifiedRayTracingException void AllocateBlas(Mesh mesh, int submeshIndex, MeshBlas blas) { + blas.blasVertices = BlockAllocator.Allocation.Invalid; + blas.bvhAlloc = BlockAllocator.Allocation.Invalid; + blas.bvhLeavesAlloc = BlockAllocator.Allocation.Invalid; + var bvhNodeSizeInDwords = RadeonRaysAPI.BvhInternalNodeSizeInDwords(); mesh.indexBufferTarget |= GraphicsBuffer.Target.Raw; @@ -219,10 +240,10 @@ void AllocateBlas(Mesh mesh, int submeshIndex, MeshBlas blas) var meshBuildInfo = new MeshBuildInfo(); meshBuildInfo.vertices = m_BlasPositions.VertexBuffer; - meshBuildInfo.verticesStartOffset = blas.blasVertices.block.offset; + meshBuildInfo.verticesStartOffset = blas.blasVertices.block.offset * BLASPositionsPool.VertexSizeInDwords; meshBuildInfo.baseVertex = 0; meshBuildInfo.triangleIndices = indexBuffer; - meshBuildInfo.vertexCount = (uint)blas.blasVertices.block.count/3; + meshBuildInfo.vertexCount = (uint)blas.blasVertices.block.count; meshBuildInfo.triangleCount = (uint)submeshDescriptor.indexCount / 3; meshBuildInfo.indicesStartOffset = submeshDescriptor.indexStart; meshBuildInfo.baseIndex = -submeshDescriptor.firstVertex; @@ -243,13 +264,29 @@ void AllocateBlas(Mesh mesh, int submeshIndex, MeshBlas blas) else #endif { - var requirements = m_RadeonRaysAPI.GetMeshBuildMemoryRequirements(meshBuildInfo, ConvertFlagsToGpuBuild(m_BuildFlags)); - var allocationNodeCount = (int)(requirements.bvhSizeInDwords / (ulong)bvhNodeSizeInDwords); - blas.bvhAlloc = AllocateBlasInternalNodes(allocationNodeCount); - blas.bvhLeavesAlloc = AllocateBlasLeafNodes((int)meshBuildInfo.triangleCount); - if (!blas.bvhAlloc.valid || !blas.bvhLeavesAlloc.valid) - throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.OutOfGraphicsBufferMemory); + try + { + var requirements = m_RadeonRaysAPI.GetMeshBuildMemoryRequirements(meshBuildInfo, ConvertFlagsToGpuBuild(m_BuildFlags)); + var allocationNodeCount = (ulong)(requirements.bvhSizeInDwords / (ulong)bvhNodeSizeInDwords); + if (allocationNodeCount > int.MaxValue) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + blas.bvhAlloc = AllocateBlasInternalNodes((int)allocationNodeCount); + blas.bvhLeavesAlloc = AllocateBlasLeafNodes((int)meshBuildInfo.triangleCount); + } + catch (UnifiedRayTracingException) + { + if (blas.blasVertices.valid) + m_BlasPositions.Remove(ref blas.blasVertices); + + if (blas.bvhAlloc.valid) + m_BlasAllocator.FreeAllocation(blas.bvhAlloc); + if (blas.bvhLeavesAlloc.valid) + m_BlasAllocator.FreeAllocation(blas.bvhLeavesAlloc); + + throw; + } } } @@ -357,6 +394,7 @@ private void BuildMissingBottomLevelAccelStructs(CommandBuffer cmd, GraphicsBuff } } + private void BuildTopLevelAccelStruct(CommandBuffer cmd, GraphicsBuffer scratchBuffer) { var radeonRaysInstances = new RadeonRays.Instance[m_RadeonInstances.Count]; @@ -366,11 +404,12 @@ private void BuildTopLevelAccelStruct(CommandBuffer cmd, GraphicsBuffer scratchB radeonRaysInstances[i].meshAccelStructOffset = (uint)instance.blas.bvhAlloc.block.offset; radeonRaysInstances[i].localToWorldTransform = instance.localToWorldTransform; radeonRaysInstances[i].instanceMask = instance.instanceMask; - radeonRaysInstances[i].vertexOffset = (uint)instance.blas.blasVertices.block.offset; + radeonRaysInstances[i].vertexOffset = (uint)instance.blas.blasVertices.block.offset * BLASPositionsPool.VertexSizeInDwords; radeonRaysInstances[i].meshAccelStructLeavesOffset = (uint)instance.blas.bvhLeavesAlloc.block.offset; radeonRaysInstances[i].triangleCullingEnabled = instance.triangleCullingEnabled; radeonRaysInstances[i].invertTriangleCulling = instance.invertTriangleCulling; radeonRaysInstances[i].userInstanceID = instance.userInstanceID; + radeonRaysInstances[i].isOpaque = instance.opaqueGeometry; i++; } @@ -416,9 +455,19 @@ void CpuBuildForBottomLevelAccelStruct(CommandBuffer cmd, MeshBlas blas) var bvhSizeInDwords = RadeonRaysAPI.BvhInternalNodeSizeInDwords() * ((int)internalNodeCount + 1); var bvhLeavesSizeInDwords = bvhBlob.Length - bvhSizeInDwords; - blas.bvhAlloc = AllocateBlasInternalNodes((int)internalNodeCount); - blas.bvhLeavesAlloc = AllocateBlasLeafNodes((int)leafNodeCount); + blas.bvhAlloc = BlockAllocator.Allocation.Invalid; + try + { + blas.bvhAlloc = AllocateBlasInternalNodes((int)internalNodeCount + 1); + blas.bvhLeavesAlloc = AllocateBlasLeafNodes((int)leafNodeCount); + } + catch (UnifiedRayTracingException) + { + if (blas.bvhAlloc.valid) + m_BlasAllocator.FreeAllocation(blas.bvhAlloc); + throw; + } // Fill triangle indices in leaf nodes. int leafOffset = bvhSizeInDwords; for (int i = 0; i < leafNodeCount; ++i) @@ -525,7 +574,15 @@ public void Bind(CommandBuffer cmd, string name, IRayTracingShader shader) shader.SetBufferParam(cmd, Shader.PropertyToID(name + "bottomBvhLeaves"), m_BlasLeavesBuffer); shader.SetBufferParam(cmd, Shader.PropertyToID(name + "instanceInfos"), instanceInfoBuffer); shader.SetBufferParam(cmd, Shader.PropertyToID(name + "vertexBuffer"), m_BlasPositions.VertexBuffer); - shader.SetIntParam(cmd, Shader.PropertyToID(name + "vertexStride"), 3); + } + + public void Bind(CommandBuffer cmd, string name, ComputeShader shader, int kernelIndex) + { + cmd.SetComputeBufferParam(shader, kernelIndex, Shader.PropertyToID(name + "bvh"), topLevelBvhBuffer); + cmd.SetComputeBufferParam(shader, kernelIndex, Shader.PropertyToID(name + "bottomBvhs"), bottomLevelBvhBuffer); + cmd.SetComputeBufferParam(shader, kernelIndex, Shader.PropertyToID(name + "bottomBvhLeaves"), m_BlasLeavesBuffer); + cmd.SetComputeBufferParam(shader, kernelIndex, Shader.PropertyToID(name + "instanceInfos"), instanceInfoBuffer); + cmd.SetComputeBufferParam(shader, kernelIndex, Shader.PropertyToID(name + "vertexBuffer"), m_BlasPositions.VertexBuffer); } static private RadeonRays.Transform ConvertTranform(Matrix4x4 input) @@ -577,14 +634,16 @@ BlockAllocator.Allocation AllocateBlasInternalNodes(int allocationNodeCount) var allocation = m_BlasAllocator.Allocate(allocationNodeCount); if (!allocation.valid) { - allocation = m_BlasAllocator.GrowAndAllocate(allocationNodeCount, int.MaxValue / RadeonRaysAPI.BvhInternalNodeSizeInBytes(), out int oldCapacity, out int newCapacity); - if (!allocation.valid) - return allocation; - - var newBlasBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, newCapacity, RadeonRaysAPI.BvhInternalNodeSizeInBytes()); - GraphicsHelpers.CopyBuffer(m_CopyShader, m_BlasBuffer, 0, newBlasBuffer, 0, oldCapacity * RadeonRaysAPI.BvhInternalNodeSizeInDwords()); - m_BlasBuffer.Dispose(); - m_BlasBuffer = newBlasBuffer; + int oldCapacity = m_BlasAllocator.capacity; + + if (!m_BlasAllocator.GetExpectedGrowthToFitAllocation(allocationNodeCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / RadeonRaysAPI.BvhInternalNodeSizeInBytes(), out int newCapacity)) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + if (!GraphicsHelpers.ReallocateBuffer(m_CopyShader, oldCapacity, newCapacity, RadeonRaysAPI.BvhInternalNodeSizeInBytes(), ref m_BlasBuffer)) + throw new UnifiedRayTracingException($"Failed to allocate buffer of size: {newCapacity * RadeonRaysAPI.BvhInternalNodeSizeInBytes()} bytes", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + allocation = m_BlasAllocator.GrowAndAllocate(allocationNodeCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / RadeonRaysAPI.BvhInternalNodeSizeInBytes(), out oldCapacity, out newCapacity); + Debug.Assert(allocation.valid); } return allocation; @@ -595,14 +654,16 @@ BlockAllocator.Allocation AllocateBlasLeafNodes(int allocationNodeCount) var allocation = m_BlasLeavesAllocator.Allocate(allocationNodeCount); if (!allocation.valid) { - allocation = m_BlasLeavesAllocator.GrowAndAllocate(allocationNodeCount, int.MaxValue / RadeonRaysAPI.BvhLeafNodeSizeInBytes(), out int oldCapacity, out int newCapacity); - if (!allocation.valid) - return allocation; - - var newBlasLeavesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, newCapacity, RadeonRaysAPI.BvhLeafNodeSizeInBytes()); - GraphicsHelpers.CopyBuffer(m_CopyShader, m_BlasLeavesBuffer, 0, newBlasLeavesBuffer, 0, oldCapacity * RadeonRaysAPI.BvhLeafNodeSizeInDwords()); - m_BlasLeavesBuffer.Dispose(); - m_BlasLeavesBuffer = newBlasLeavesBuffer; + int oldCapacity = m_BlasLeavesAllocator.capacity; + + if (!m_BlasLeavesAllocator.GetExpectedGrowthToFitAllocation(allocationNodeCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / RadeonRaysAPI.BvhLeafNodeSizeInBytes(), out int newCapacity)) + throw new UnifiedRayTracingException("Can't allocate a GraphicsBuffer bigger than 2GB", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + if (!GraphicsHelpers.ReallocateBuffer(m_CopyShader, oldCapacity, newCapacity, RadeonRaysAPI.BvhLeafNodeSizeInBytes(), ref m_BlasLeavesBuffer)) + throw new UnifiedRayTracingException($"Failed to allocate buffer of size: {newCapacity* RadeonRaysAPI.BvhLeafNodeSizeInBytes()} bytes", UnifiedRayTracingError.GraphicsBufferAllocationFailed); + + allocation = m_BlasLeavesAllocator.GrowAndAllocate(allocationNodeCount, GraphicsHelpers.MaxGraphicsBufferSizeInBytes / RadeonRaysAPI.BvhLeafNodeSizeInBytes(), out oldCapacity, out newCapacity); + Debug.Assert(allocation.valid); } return allocation; @@ -623,6 +684,13 @@ void ReleaseHandle(int handle) m_FreeHandles.Enqueue((uint)handle ^ m_HandleObfuscation); } + [System.Diagnostics.Conditional("UNITY_ASSERTIONS")] + void CheckInstanceHandleIsValid(int instanceHandle) + { + if (!m_RadeonInstances.ContainsKey(instanceHandle)) + throw new System.ArgumentException($"accel struct does not contain instanceHandle {instanceHandle}", "instanceHandle"); + } + readonly RadeonRaysAPI m_RadeonRaysAPI; readonly BuildFlags m_BuildFlags; @@ -632,9 +700,9 @@ void ReleaseHandle(int handle) readonly ReferenceCounter m_Counter; readonly Dictionary<(int mesh, int subMeshIndex), MeshBlas> m_Blases; - BlockAllocator m_BlasAllocator; + internal BlockAllocator m_BlasAllocator; GraphicsBuffer m_BlasBuffer; - BlockAllocator m_BlasLeavesAllocator; + internal BlockAllocator m_BlasLeavesAllocator; GraphicsBuffer m_BlasLeavesBuffer; readonly BLASPositionsPool m_BlasPositions; @@ -652,6 +720,7 @@ sealed class RadeonRaysInstance public bool triangleCullingEnabled; public bool invertTriangleCulling; public uint userInstanceID; + public bool opaqueGeometry; public RadeonRays.Transform localToWorldTransform; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs.meta index 08aeb91bce9..b79a0e82f51 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingAccelStruct.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 47381b95f8bd4f44db5cebb4f2c3cf6d +guid: 13d73738c3312804e8e02a8740df1a8b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingBackend.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingBackend.cs.meta index 6788189e6f3..ca52af558fb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingBackend.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingBackend.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 189c94a74c76e8244a89d8dea501dc60 +guid: 19a80943de97d344f9d78714557048b3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs index 36496c8f792..acf0ff8d9d5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs @@ -21,6 +21,8 @@ internal ComputeRayTracingShader(ComputeShader shader, string dispatchFuncName, m_Shader = shader; m_KernelIndex = m_Shader.FindKernel(dispatchFuncName); m_ComputeIndirectDispatchDimsKernelIndex = m_Shader.FindKernel("ComputeIndirectDispatchDims"); + Debug.Assert(m_Shader.IsSupported(m_KernelIndex), $"Invalid compute shader [{shader.name}], please check that your shader code is compiling."); + m_Shader.GetKernelThreadGroupSizes(m_KernelIndex, out m_ThreadGroupSizes.x, out m_ThreadGroupSizes.y, out m_ThreadGroupSizes.z); m_DispatchBuffer = dispatchBuffer; @@ -33,6 +35,8 @@ public uint3 GetThreadGroupSizes() public void SetAccelerationStructure(CommandBuffer cmd, string name, IRayTracingAccelStruct accelStruct) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + var computeAccelStruct = accelStruct as ComputeRayTracingAccelStruct; Assert.IsNotNull(computeAccelStruct); @@ -41,50 +45,84 @@ public void SetAccelerationStructure(CommandBuffer cmd, string name, IRayTracing public void SetIntParam(CommandBuffer cmd, int nameID, int val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeIntParam(m_Shader, nameID, val); } public void SetFloatParam(CommandBuffer cmd, int nameID, float val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeFloatParam(m_Shader, nameID, val); } public void SetVectorParam(CommandBuffer cmd, int nameID, Vector4 val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeVectorParam(m_Shader, nameID, val); } public void SetMatrixParam(CommandBuffer cmd, int nameID, Matrix4x4 val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeMatrixParam(m_Shader, nameID, val); } public void SetTextureParam(CommandBuffer cmd, int nameID, RenderTargetIdentifier rt) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeTextureParam(m_Shader, m_KernelIndex, nameID, rt); } public void SetBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, nameID, buffer); } + public void SetBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, nameID, buffer); } + public void SetConstantBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer, int offset, int size) + { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(buffer, nameof(buffer)); + + cmd.SetComputeConstantBufferParam(m_Shader, nameID, buffer, offset, size); + } + + public void SetConstantBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer, int offset, int size) + { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(buffer, nameof(buffer)); + + cmd.SetComputeConstantBufferParam(m_Shader, nameID, buffer, offset, size); + } + public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, uint width, uint height, uint depth) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + var requiredScratchSize = GetTraceScratchBufferRequiredSizeInBytes(width, height, depth); if (requiredScratchSize > 0) { - Debug.Assert(scratchBuffer != null && ((ulong)(scratchBuffer.count * scratchBuffer.stride) >= requiredScratchSize), "scratchBuffer size is too small"); - Debug.Assert(scratchBuffer.stride == 4, "scratchBuffer stride must be 4"); + Utils.CheckArg(scratchBuffer != null && ((ulong)(scratchBuffer.count * scratchBuffer.stride) >= requiredScratchSize), "scratchBuffer size is too small"); + Utils.CheckArg(scratchBuffer.stride == 4, "scratchBuffer stride must be 4"); + Utils.CheckArg(scratchBuffer.target == RayTracingHelper.ScratchBufferTarget, "scratchBuffer.target must have Target.Structured set"); } - cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, RadeonRays.SID.g_stack, scratchBuffer); + cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, SID._UnifiedRT_Stack, scratchBuffer); cmd.SetBufferData(m_DispatchBuffer, new uint[] { width, height, depth }); - SetBufferParam(cmd, RadeonRays.SID.g_dispatch_dimensions, m_DispatchBuffer); + SetBufferParam(cmd, SID._UnifiedRT_DispatchDims, m_DispatchBuffer); uint workgroupsX = (uint)GraphicsHelpers.DivUp((int)width, m_ThreadGroupSizes.x); uint workgroupsY = (uint)GraphicsHelpers.DivUp((int)height, m_ThreadGroupSizes.y); @@ -94,21 +132,25 @@ public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, uint width public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, GraphicsBuffer argsBuffer) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + GraphicsBuffer.Target requiredFlags = GraphicsBuffer.Target.IndirectArguments | GraphicsBuffer.Target.Structured; + Utils.CheckArg((argsBuffer.target & requiredFlags) == requiredFlags, "argsBuffer.target must have both Target.IndirectArguments and Target.Structured set"); + SetIndirectDispatchDimensions(cmd, argsBuffer); DispatchIndirect(cmd, scratchBuffer, argsBuffer); } internal void SetIndirectDispatchDimensions(CommandBuffer cmd, GraphicsBuffer argsBuffer) { - cmd.SetComputeBufferParam(m_Shader, m_ComputeIndirectDispatchDimsKernelIndex, RadeonRays.SID.g_dispatch_dimensions, argsBuffer); - cmd.SetComputeBufferParam(m_Shader, m_ComputeIndirectDispatchDimsKernelIndex, RadeonRays.SID.g_dispatch_dims_in_workgroups, m_DispatchBuffer); + cmd.SetComputeBufferParam(m_Shader, m_ComputeIndirectDispatchDimsKernelIndex, SID._UnifiedRT_DispatchDims, argsBuffer); + cmd.SetComputeBufferParam(m_Shader, m_ComputeIndirectDispatchDimsKernelIndex, SID._UnifiedRT_DispatchDimsInWorkgroups, m_DispatchBuffer); cmd.DispatchCompute(m_Shader, m_ComputeIndirectDispatchDimsKernelIndex, 1, 1, 1); } internal void DispatchIndirect(CommandBuffer cmd, GraphicsBuffer scratchBuffer, GraphicsBuffer argsBuffer) { - cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, RadeonRays.SID.g_stack, scratchBuffer); - cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, RadeonRays.SID.g_dispatch_dimensions, argsBuffer); + cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, SID._UnifiedRT_Stack, scratchBuffer); + cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, SID._UnifiedRT_DispatchDims, argsBuffer); cmd.DispatchCompute(m_Shader, m_KernelIndex, m_DispatchBuffer, 0); } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs.meta index e71b5997764..a2fabb108a3 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d2490507baf7aec4d8f25b6e7f7814fa +guid: 7ffb214f1a2621b498faee76b1864c9e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl index 1d52cdf0d2a..6a0ec3a930b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl @@ -1,11 +1,5 @@ -#define WIDTH_OFFSET 0 -#define HEIGHT_OFFSET 1 -#define DEPTH_OFFSET 2 -StructuredBuffer g_Dimensions; -#ifndef UNIFIED_RT_RAYGEN_FUNC_NAME -#define UNIFIED_RT_RAYGEN_FUNC_NAME RayGenExecute -#endif +StructuredBuffer _UnifiedRT_DispatchDims; #pragma kernel MainRayGenShader [numthreads(UNIFIED_RT_GROUP_SIZE_X, UNIFIED_RT_GROUP_SIZE_Y, UNIFIED_RT_GROUP_SIZE_Z)] @@ -13,24 +7,24 @@ void MainRayGenShader( in uint3 gidx: SV_DispatchThreadID, in uint lidx : SV_GroupIndex) { - if (gidx.x >= g_Dimensions[WIDTH_OFFSET] || gidx.y >= g_Dimensions[HEIGHT_OFFSET] || gidx.z >= g_Dimensions[DEPTH_OFFSET]) + if (gidx.x >= _UnifiedRT_DispatchDims[0] || gidx.y >= _UnifiedRT_DispatchDims[1] || gidx.z >= _UnifiedRT_DispatchDims[2]) return; UnifiedRT::DispatchInfo dispatchInfo; dispatchInfo.dispatchThreadID = gidx; - dispatchInfo.dispatchDimensionsInThreads = int3(g_Dimensions[WIDTH_OFFSET], g_Dimensions[HEIGHT_OFFSET], g_Dimensions[DEPTH_OFFSET]); + dispatchInfo.dispatchDimensionsInThreads = int3(_UnifiedRT_DispatchDims[0], _UnifiedRT_DispatchDims[1], _UnifiedRT_DispatchDims[2]); dispatchInfo.localThreadIndex = lidx; - dispatchInfo.globalThreadIndex = gidx.x + gidx.y * g_Dimensions[WIDTH_OFFSET] + gidx.z * (g_Dimensions[WIDTH_OFFSET] * g_Dimensions[HEIGHT_OFFSET]); + dispatchInfo.globalThreadIndex = gidx.x + gidx.y * _UnifiedRT_DispatchDims[0] + gidx.z * (_UnifiedRT_DispatchDims[0] * _UnifiedRT_DispatchDims[1]); - UNIFIED_RT_RAYGEN_FUNC_NAME(dispatchInfo); + UNIFIED_RT_RAYGEN_FUNC(dispatchInfo); } -RWStructuredBuffer g_dispatch_dims_in_workgroups; +RWStructuredBuffer _UnifiedRT_DispatchDimsInWorkgroups; #pragma kernel ComputeIndirectDispatchDims [numthreads(3, 1, 1)] void ComputeIndirectDispatchDims(in uint gidx : SV_DispatchThreadID) { uint3 workgroupSizes = uint3(UNIFIED_RT_GROUP_SIZE_X, UNIFIED_RT_GROUP_SIZE_Y, UNIFIED_RT_GROUP_SIZE_Z); - g_dispatch_dims_in_workgroups[gidx] = (g_Dimensions[gidx] + workgroupSizes[gidx] - 1) / workgroupSizes[gidx]; + _UnifiedRT_DispatchDimsInWorkgroups[gidx] = (_UnifiedRT_DispatchDims[gidx] + workgroupSizes[gidx] - 1) / workgroupSizes[gidx]; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl.meta index ff0ece9263d..e6d978d2636 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/ComputeRaygenShader.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e894eeea9d36e9b4b8d6be81023b7cbe +guid: 7176b7aa19c704f439cdab57ccf4bceb ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays.meta index 87af0342efd..e29dd70411d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7ac9b9b2d31a8ad43adbf58478e79a5f +guid: bc373571d8c974b4c8b11bbc194651eb folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/BvhCheck.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/BvhCheck.cs.meta index 43381e36a90..b1d0590faec 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/BvhCheck.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/BvhCheck.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 948c469ea5274f340a6aaa3e9719c7a1 +guid: fccb64cb1f418b9499235ed8f3ba4624 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Common.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Common.cs.meta index 1af1b5a8ea7..69bf6f28fae 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Common.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Common.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f08443d04942ec5498c71b7961ecbf75 +guid: f0db4ed57f6edee4c885d25ff13937e7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhBuilder.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhBuilder.cs.meta index 6718d31076c..9e12fde28ab 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhBuilder.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhBuilder.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7aeb48182611e8e4898e4bf90c4db57b +guid: 9d053bd99ea2f2c41b6200d1561bc091 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhTopLevelBuilder.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhTopLevelBuilder.cs.meta index 5228cbf759e..a3aa9a1a826 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhTopLevelBuilder.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/HlbvhTopLevelBuilder.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5bfccd437a0363140896a3d2f3bc9492 +guid: 381139c5264bf8f4e81de5c8990ad646 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/README.txt.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/README.txt.meta index a9c7e6ed5bd..ce3eeddbf58 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/README.txt.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/README.txt.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f278ca56cfaafbd43be8c0013c5224f5 +guid: 6ab740f51f5df0244bb3510f143c74ef TextScriptImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs index 0732311eecd..96364bdb9b9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs @@ -173,6 +173,7 @@ internal struct Instance public bool triangleCullingEnabled; public bool invertTriangleCulling; public uint userInstanceID; + public bool isOpaque; public Transform localToWorldTransform; } @@ -183,10 +184,10 @@ internal struct InstanceInfo public int instanceMask; public int vertexOffset; public int indexOffset; - public int triangleCullingEnabled; - public int invertTriangleCulling; + public uint disableTriangleCulling; + public uint invertTriangleCulling; public uint userInstanceID; - public int padding2; + public int isOpaque; public Transform worldToLocalTransform; public Transform localToWorldTransform; } @@ -306,9 +307,10 @@ public TopLevelAccelStruct BuildSceneAccelStruct( vertexOffset = (int)instances[i].vertexOffset, indexOffset = (int)instances[i].meshAccelStructLeavesOffset, localToWorldTransform = instances[i].localToWorldTransform, - triangleCullingEnabled = instances[i].triangleCullingEnabled ? 1 : 0, - invertTriangleCulling = instances[i].invertTriangleCulling ? 1 : 0, - userInstanceID = instances[i].userInstanceID + disableTriangleCulling = instances[i].triangleCullingEnabled ? 0 : (1u << 30), + invertTriangleCulling = instances[i].invertTriangleCulling ? (1u << 31) : 0, + userInstanceID = instances[i].userInstanceID, + isOpaque = instances[i].isOpaque ? 1 : 0 // worldToLocal computed in the shader }; } @@ -344,8 +346,8 @@ public TopLevelAccelStruct CreateSceneAccelStructBuffers( vertexOffset = (int)instances[i].vertexOffset, indexOffset = (int)instances[i].meshAccelStructLeavesOffset, localToWorldTransform = instances[i].localToWorldTransform, - triangleCullingEnabled = instances[i].triangleCullingEnabled ? 1 : 0, - invertTriangleCulling = instances[i].invertTriangleCulling ? 1 : 0, + disableTriangleCulling = instances[i].triangleCullingEnabled ? 0 : (1u << 30), + invertTriangleCulling = instances[i].invertTriangleCulling ? (1u << 31) : 0, userInstanceID = instances[i].userInstanceID, worldToLocalTransform = instances[i].localToWorldTransform.Inverse() }; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs.meta index 53b3476ac04..2902d6783d5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadeonRaysAPI.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0dc179af6af5f1b4b894537809da46fb +guid: 72f2039b19e30244dafbaeed758cb3c6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadixSort.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadixSort.cs.meta index 9b43ccaa4aa..78e073ebb38 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadixSort.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RadixSort.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c3c4a76cdc6a52b4b98967729975ece4 +guid: e8f82bb52f3ef1645959cbcafd7ce168 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs index 16f521dfa68..f03a9296c67 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs @@ -53,7 +53,6 @@ public void Execute( GraphicsBuffer scratch, in BottomLevelLevelAccelStruct result) { var scratchLayout = ScratchBufferLayout.Create(triangleCount); - Common.EnableKeyword(cmd, shader, "TOP_LEVEL", false); cmd.SetComputeIntParam(shader, SID.g_vertices_offset, verticesOffset); cmd.SetComputeIntParam(shader, SID.g_constants_vertex_stride, (int)vertexStride); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs.meta index a3005f3c6cc..7bab6fa59c4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/RestructureBvh.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 63aef885f06315d4894b10ae5704f178 +guid: 9dc191720bcb9a94188d52e5651d86cc MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Scan.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Scan.cs.meta index c29a32a8bfc..0b35bc3f977 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Scan.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/Scan.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f9d5f09f0b8000e40862907f5e6f0c8a +guid: c083b11656047954d8aab3b2b0713f33 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs index ce4ea7c52dc..c342ee3f403 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs @@ -29,7 +29,6 @@ internal static class SID public static readonly int g_ray_count = Shader.PropertyToID("g_ray_count"); public static readonly int g_rays = Shader.PropertyToID("g_rays"); public static readonly int g_hits = Shader.PropertyToID("g_hits"); - public static readonly int g_stack = Shader.PropertyToID("g_stack"); public static readonly int g_constants_min_prims_per_treelet = Shader.PropertyToID("g_constants_min_prims_per_treelet"); public static readonly int g_treelet_count_offset = Shader.PropertyToID("g_treelet_count_offset"); public static readonly int g_treelet_roots_offset = Shader.PropertyToID("g_treelet_roots_offset"); @@ -56,8 +55,6 @@ internal static class SID public static readonly int g_neighbor_offset = Shader.PropertyToID("g_neighbor_offset"); public static readonly int g_cluster_to_node_offset = Shader.PropertyToID("g_cluster_to_node_offset"); public static readonly int g_deltas_offset = Shader.PropertyToID("g_deltas_offset"); - public static readonly int g_dispatch_dimensions = Shader.PropertyToID("g_Dimensions"); - public static readonly int g_dispatch_dims_in_workgroups = Shader.PropertyToID("g_dispatch_dims_in_workgroups"); public static readonly int g_leaf_parents_offset = Shader.PropertyToID("g_leaf_parents_offset"); } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs.meta index 7b303bc3ac3..a4a49ea65c4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/StringIDs.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5e39534370542bd45833909856cf20fc +guid: 5e7ff31e76460b5468d3c45cf9095a6b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels.meta index 323154ab79d..cd2df8a5436 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3181a19f8bf93044398dbf44afdbb548 +guid: 9a4184587b7c760418ee26ca0a32df62 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta index ada36291f0b..c38dc07b130 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/CopyPositions.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: fb6acdefef36af24eab075e3f9e99247 +guid: 1ad53a96b58d3c3488dde4f14db1aaeb ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/aabb.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/aabb.hlsl.meta index 266a8383e2a..0600a849a87 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/aabb.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/aabb.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fb66710642858974cac36e578244cf81 +guid: 6065e50fcb17cf247938a4f5ed300176 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta index 69f3c9f6654..70fdcec3673 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: f2122e5e16c5caa42ba34450bc5ab14b -ShaderIncludeImporter: +guid: 8670f7ce4b60cef43bed36148aa1b0a2 +ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta index cae2da0ed40..b100a6c36fe 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: ae6c1838a70d96043b73ec2993509e8c -ShaderIncludeImporter: +guid: 4e034cc8ea2635c4e9f063e5ddc7ea7a +ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta index 4fe999f6559..4d5a4a0920b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: c453356d08264cd419c13dd2ae8d1147 -ShaderIncludeImporter: +guid: 4d6d5de35fa45ef4a92119397a045cc9 +ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta index 1bc53720be3..971d99892e2 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 599a7ad58d01b8142b554e0a0625b451 +guid: 2d70cd6be91bd7843a39a54b51c15b13 ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl index 370b943e386..c0c6ee8859f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl @@ -93,10 +93,10 @@ struct InstanceInfo int instance_mask; int vertex_offset; int index_offset; - int triangle_culling_enabled; - int invert_triangle_culling; + uint disable_triangle_culling; + uint invert_triangle_culling; uint user_instance_id; - int padding2; + int is_opaque; Transform world_to_local_transform; Transform local_to_world_transform; }; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl.meta index c6e098acb78..565be46c6bf 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bvh2il.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f88febca88c99324284882a13ba3eb2d +guid: 4541f1bb75b10ac4597809e3016f3026 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersect_structures.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersect_structures.hlsl.meta index 487292fb3cd..5c15c5f5a4b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersect_structures.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersect_structures.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7e674948dec058a4cb862db7aaf5b7ca +guid: f20cb86c2d6c414d9ff78df5fc04cd1d ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl index db005f1a70a..a7b04ab5e24 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl @@ -92,15 +92,15 @@ struct InstanceInfo int instance_mask; int vertex_offset; int blas_leaves_offset; - int triangle_culling_enabled; // int instead of a bool because the shader compiler refuses to play ball - int invert_triangle_culling; //same + uint disable_triangle_culling; + uint invert_triangle_culling; uint user_instance_id; - int padding2; + int is_opaque; Transform world_to_local_transform; Transform local_to_world_transform; }; -bool fast_intersect_triangle(in int cull_mode, +bool fast_intersect_triangle(in uint cull_mode, in float3 ray_origin, in float3 ray_direction, in float3 v1, @@ -129,7 +129,7 @@ bool fast_intersect_triangle(in int cull_mode, // Barycentric coordinate U is outside range bool hit = false; - if (!((u < 0.f) || (u > 1.f) || sign(determinant) == cull_mode)) + if (!((u < 0.f) || (u > 1.f) || determinant == 0.0f || (asuint(determinant) & 0x80000000) == cull_mode)) { const float3 s2 = cross(d, e1); const float v = dot(ray_direction, s2) * invd; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl.meta index f91a8a3980c..fb1b4f57dbf 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/intersector_common.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 540173dbad43bd34fb2d7ce3c6b8f2a8 +guid: 1d3d4991676b46b4dbcffa10bf77e786 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/math.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/math.hlsl.meta index 5771733f252..b77d3e9cab6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/math.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/math.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ed6467937cd80e546b619d28b398f738 +guid: 8a988affc98dd434aadd71fe6be1061f ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute index 29960d23885..30d2ee4e138 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute @@ -38,8 +38,6 @@ THE SOFTWARE. // WebGPU has extremely strict uniformity requirements that are incompatible with the current implementation of this shader. #pragma exclude_renderers webgpu -#pragma multi_compile __ TOP_LEVEL - #if !(TOP_LEVEL) RWStructuredBuffer g_vertices; int g_vertices_offset; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta index e3af1e5128d..fb35c9df3bb 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: f68e907366e14894aa16f412af90f520 -ShaderIncludeImporter: +guid: 56641cb88dcb31a4398a4997ef7a7a8c +ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta index f0d927bac80..0e873b73394 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute.meta @@ -1,7 +1,7 @@ fileFormatVersion: 2 -guid: 28dba68663251c347b548c8ea7405650 -ShaderIncludeImporter: +guid: a2eaeefdac4637a44b734e85b7be9186 +ComputeShaderImporter: externalObjects: {} userData: - assetBundleName: + assetBundleName: unifiedraytracing assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/trace_ray.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/trace_ray.hlsl.meta index 99cb4cf93ec..8a6cb3c3b73 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/trace_ray.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/trace_ray.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9a77ac57745a52840820366eafde51cd +guid: ab8d793352dffca4f9b91b50e2421b57 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/transform.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/transform.hlsl.meta index 8d2c1fd02cd..2440a731c64 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/transform.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/transform.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 01fd8d94264d9074eadc5f788a3b3c82 +guid: 7b4dd253adea58d49a8347c5bcc08904 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/triangle_mesh.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/triangle_mesh.hlsl.meta index 12f9d506f91..21c23bf6fd1 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/triangle_mesh.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/triangle_mesh.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a5214fa82098469499d8d6b321cffd64 +guid: 76757b5514dd6404dafc9fbe2566522d ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl new file mode 100644 index 00000000000..3dca1b65c30 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl @@ -0,0 +1,434 @@ +#ifndef _UNIFIEDRAYTRACING_RAYQUERYSOFTWARE_HLSL_ +#define _UNIFIEDRAYTRACING_RAYQUERYSOFTWARE_HLSL_ + +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl" + +#pragma warning(disable : 4008) // fast_intersect_bbox is designed to handle inf and nans, so we disable the `floating point division by zero` warning + +#ifndef UNIFIED_RT_LDS_STACK_SIZE +#define UNIFIED_RT_LDS_STACK_SIZE 8 +#endif + +#ifndef UNIFIED_RT_STACK_SIZE +#define UNIFIED_RT_STACK_SIZE 64 +#endif + +RWStructuredBuffer _UnifiedRT_Stack; + +namespace UnifiedRT { + +groupshared uint lds_stack[UNIFIED_RT_LDS_STACK_SIZE * (UNIFIED_RT_GROUP_SIZE_X*UNIFIED_RT_GROUP_SIZE_Y*UNIFIED_RT_GROUP_SIZE_Z)]; + +static const uint kTopLevelSentinel = 0xFFFFFFFE; +static const uint kCommittedNothing = 0; +static const uint kCommittedTriangleHit = 1; + +static const uint kNonOpaqueInstanceBit = (1 << 29); +static const uint kCandidateHitCommittedBit = (1 << 28); + +struct RayTraversalStack +{ + void Init(uint globalThreadIndex, uint localThreadIndex) + { + sbegin = UNIFIED_RT_STACK_SIZE * globalThreadIndex; + sptr = sbegin; + lds_sbegin = localThreadIndex * UNIFIED_RT_LDS_STACK_SIZE; + lds_sptr = lds_sbegin; + lds_stack[lds_sptr++] = INVALID_NODE; + } + + void Push(uint addr) + { + if (lds_sptr - lds_sbegin >= UNIFIED_RT_LDS_STACK_SIZE) + { + for (int i = 1; i < UNIFIED_RT_LDS_STACK_SIZE; ++i) + { + _UnifiedRT_Stack[sptr + i] = lds_stack[lds_sbegin + i]; + } + + sptr += UNIFIED_RT_LDS_STACK_SIZE; + lds_sptr = lds_sbegin + 1; + } + lds_stack[lds_sptr++] = addr; + } + + uint Pop() + { + uint addr = lds_stack[--lds_sptr]; + if (addr == INVALID_NODE && sptr > sbegin) + { + sptr -= UNIFIED_RT_LDS_STACK_SIZE; + for (int i = 1; i < UNIFIED_RT_LDS_STACK_SIZE; ++i) + { + lds_stack[lds_sbegin + i] = _UnifiedRT_Stack[sptr + i]; + } + lds_sptr = lds_sbegin + UNIFIED_RT_LDS_STACK_SIZE; + addr = lds_stack[--lds_sptr]; + } + return addr; + } + + uint lds_sptr; + uint lds_sbegin; + uint sptr; + uint sbegin; +}; + +uint GetCullMode(uint rayFlags) +{ + uint cullMode = 0; + cullMode |= (rayFlags & kRayFlagCullBackFacingTriangles) << 27; + + if ((rayFlags & (kRayFlagCullFrontFacingTriangles | kRayFlagCullBackFacingTriangles)) == 0) + cullMode |= (1 << 30); + + return cullMode; +} + +struct ClosestHit +{ + uint instanceIndex; + uint isFrontFace_primitiveIndex; + float2 uv; +}; + +struct CandidateHit +{ + uint isFrontFace_primitiveIndex; + float2 uv; + float hitT; +}; + +struct CurrentInstance +{ + uint cullMode_isNonOpaque_candidateCommitted; + uint bvhOffset; + int bvhLeavesOffset; + int vertexOffset; +}; + +CurrentInstance GetCurrentInstance(InstanceInfo instanceInfo, uint rayCullMode, bool transparentInstance) +{ + CurrentInstance currentInstance; + currentInstance.bvhOffset = instanceInfo.blas_offset; + currentInstance.vertexOffset = instanceInfo.vertex_offset; + currentInstance.bvhLeavesOffset = instanceInfo.blas_leaves_offset; + + uint instanceCullMode = (rayCullMode ^ instanceInfo.invert_triangle_culling) | instanceInfo.disable_triangle_culling; + + currentInstance.cullMode_isNonOpaque_candidateCommitted = instanceCullMode; + if (transparentInstance) + currentInstance.cullMode_isNonOpaque_candidateCommitted |= kNonOpaqueInstanceBit; + + return currentInstance; +} + +bool IsInstanceNonOpaque(RayTracingAccelStruct accelStruct, uint instanceIndex, uint rayFlags) +{ + bool isTransparent = !accelStruct.instance_infos[instanceIndex].is_opaque; + if (rayFlags & kRayFlagForceNonOpaque) + isTransparent = true; + if (rayFlags & kRayFlagForceOpaque) + isTransparent = false; + + return isTransparent; +} + +float4x3 ConvertToFloat4x3(Transform t) +{ + float4x3 m; + m[0] = float3(t.row0.x, t.row1.x, t.row2.x); + m[1] = float3(t.row0.y, t.row1.y, t.row2.y); + m[2] = float3(t.row0.z, t.row1.z, t.row2.z); + m[3] = float3(t.row0.w, t.row1.w, t.row2.w); + return m; +} + +float3x4 ConvertToFloat3x4(Transform t) +{ + float3x4 m; + m[0] = float4(t.row0.x, t.row0.y, t.row0.z, t.row0.w); + m[1] = float4(t.row1.x, t.row1.y, t.row1.z, t.row1.w); + m[2] = float4(t.row2.x, t.row2.y, t.row2.z, t.row2.w); + return m; +} + +bool IntersectLeafTriangle( + StructuredBuffer vertexBuffer, int vertexOffset, uint4 leafNode, uint triangleCullMode, + float3 rayDirection, float3 rayOrigin, float tmin, float tmax, + out CandidateHit hitInfo) +{ + hitInfo = (CandidateHit)0; + uint3 triangleIndices = leafNode.xyz; + float3 v1 = FetchVertex(vertexBuffer, 3, vertexOffset, triangleIndices.x); + float3 v2 = FetchVertex(vertexBuffer, 3, vertexOffset, triangleIndices.y); + float3 v3 = FetchVertex(vertexBuffer, 3, vertexOffset, triangleIndices.z); + + // Determine edge vectors for clockwise triangle vertices + const float3 e1 = v2 - v1; + const float3 e2 = v3 - v1; + + const float3 s1 = cross(rayDirection, e2); + const float determinant = dot(s1, e1); + const float invd = rcp(determinant); + + const float3 d = rayOrigin - v1; + const float u = dot(d, s1) * invd; + + const uint detSignBit = asuint(determinant) & 0x80000000; + // Barycentric coordinate U is outside range or triangle front/backface culled + bool hit = false; + if (!((u < 0.f) || (u > 1.f) || determinant == 0.0f || detSignBit == triangleCullMode)) + { + const float3 s2 = cross(d, e1); + const float v = dot(rayDirection, s2) * invd; + // Barycentric coordinate V is outside range + if (!((v < 0.f) || (u + v > 1.f))) + { + // Check parametric distance + const float t = dot(e2, s2) * invd; + if (!(t < tmin || t > tmax)) + { + // Accept hit + hitInfo.isFrontFace_primitiveIndex = (detSignBit ^ 0x80000000) | leafNode.w; + hitInfo.uv = float2(u, v); + hitInfo.hitT = t; + hit = true; + } + } + } + return hit; +} + +struct RayQuery +{ + void Init(uint globalThreadIndex, uint localThreadIndex, RayTracingAccelStruct accelStruct_, uint rayFlags_, uint instanceMask_, Ray ray_) + { + accelStruct = accelStruct_; + rayCullMode_Mask = instanceMask_ & 0x000000FF; + rayCullMode_Mask |= GetCullMode(rayFlags_); + rayFlags = rayFlags_; + rayOriginInWorld = ray_.origin; + rayDirectionInWorld = ray_.direction; + tMin = ray_.tMin; + tMax = ray_.tMax; + rayOrigin = ray_.origin; + rayDirection = ray_.direction; + rayInvDir = 1.0 / ray_.direction; + + stack.Init(globalThreadIndex, localThreadIndex); + + candidateHit = (CandidateHit)0; + closestHit = (ClosestHit)0; + closestHit.instanceIndex = INVALID_NODE; + currentInstance = (CurrentInstance)0; + + currentNodeIndex = accelStruct.bvh[0].parent; // get root node index from bvh header + currentInstanceIndex = INVALID_NODE; + currentLeafTriangleIndex = -1; + } + + bool Proceed() + { + bool transparencyEnabled = !(rayFlags & (UnifiedRT::kRayFlagForceOpaque | UnifiedRT::kRayFlagCullNonOpaque)); + + if ((currentInstance.cullMode_isNonOpaque_candidateCommitted & kCandidateHitCommittedBit) && transparencyEnabled) + { + currentInstance.cullMode_isNonOpaque_candidateCommitted &= ~kCandidateHitCommittedBit; + + _CommitCandidateHit(); + + if (rayFlags & kRayFlagAcceptFirstHitAndEndSearch) + { + Abort(); + return false; + } + } + + currentLeafTriangleIndex++; + + while (currentNodeIndex != INVALID_NODE) + { + bool isLeaf = IS_LEAF_NODE(currentNodeIndex); + bool skipPopStack = false; + + // internal node (Bounding boxes) + if (!isLeaf) + { + BvhNode node; + if (currentInstanceIndex == INVALID_NODE) + node = accelStruct.bvh[1 + currentNodeIndex]; + else + node = accelStruct.bottom_bvhs[currentInstance.bvhOffset + 1 + currentNodeIndex]; + + uint2 result = IntersectInternalNode(node, rayInvDir, rayOrigin, tMin, tMax); + if (result.y != INVALID_NODE) + { + stack.Push(result.y); + } + + if (result.x != INVALID_NODE) + { + currentNodeIndex = result.x; + skipPopStack = true; + } + } + // top-level leaf: adjust ray respecively to transforms + else if (currentInstanceIndex == INVALID_NODE) + { + uint currentInstanceIndex_ = GET_LEAF_NODE_FIRST_PRIM(currentNodeIndex); + uint instanceMask = accelStruct.instance_infos[currentInstanceIndex_].instance_mask; + bool instanceIsTransparent = IsInstanceNonOpaque(accelStruct, currentInstanceIndex_, rayFlags); + + bool instanceCulled = (instanceMask & rayCullMode_Mask & 0x000000FF) == 0 || + (instanceIsTransparent && (rayFlags & kRayFlagCullNonOpaque)) || + (!instanceIsTransparent && (rayFlags & kRayFlagCullOpaque)); + + if (!instanceCulled) + { + // push sentinel + stack.Push(kTopLevelSentinel); + + currentInstanceIndex = currentInstanceIndex_; + currentInstance = GetCurrentInstance(accelStruct.instance_infos[currentInstanceIndex_], rayCullMode_Mask & 0xC0000000, instanceIsTransparent); + currentNodeIndex = accelStruct.bottom_bvhs[currentInstance.bvhOffset + 0].parent; + + // transform ray into Bottom level space + Transform transform = accelStruct.instance_infos[currentInstanceIndex].world_to_local_transform; + rayOrigin = TransformPointT(rayOriginInWorld, transform); + rayDirection = TransformDirection(rayDirectionInWorld, transform); + rayInvDir = 1.0 / rayDirection; + + skipPopStack = true; + } + } + // bottom-level leaf (triangles) + else + { + int firstTriangle = GET_LEAF_NODE_FIRST_PRIM(currentNodeIndex); + int nodeTriangleCount = GET_LEAF_NODE_PRIM_COUNT(currentNodeIndex); + + while (currentLeafTriangleIndex < nodeTriangleCount) + { + uint4 leafNode = accelStruct.bottom_bvh_leaves[currentInstance.bvhLeavesOffset + (firstTriangle + currentLeafTriangleIndex)]; + uint triangleCullMode = (currentInstance.cullMode_isNonOpaque_candidateCommitted & 0xC0000000); + bool nonOpaqueInstance = (currentInstance.cullMode_isNonOpaque_candidateCommitted & kNonOpaqueInstanceBit); + + if (IntersectLeafTriangle( + accelStruct.vertexBuffer, currentInstance.vertexOffset, leafNode, triangleCullMode, + rayDirection, rayOrigin, tMin, tMax, + candidateHit)) + { + if (nonOpaqueInstance && transparencyEnabled) + return true; + + _CommitCandidateHit(); + + if (rayFlags & kRayFlagAcceptFirstHitAndEndSearch) + { + Abort(); + return false; + } + } + + currentLeafTriangleIndex++; + } + + currentLeafTriangleIndex = 0; + } + + if (skipPopStack) + continue; + + currentNodeIndex = stack.Pop(); + + // check if need to go back to the top-level + if (currentNodeIndex == kTopLevelSentinel) + { + currentNodeIndex = stack.Pop(); + currentInstanceIndex = INVALID_NODE; + + // restore ray + rayOrigin = rayOriginInWorld; + rayDirection= rayDirectionInWorld; + rayInvDir = 1.0 / rayDirectionInWorld; + } + } + + return false; + } + + void Abort() + { + currentNodeIndex = INVALID_NODE; + } + + void CommitNonOpaqueTriangleHit() + { + currentInstance.cullMode_isNonOpaque_candidateCommitted |= kCandidateHitCommittedBit; + } + + void _CommitCandidateHit() + { + closestHit.instanceIndex = currentInstanceIndex; + closestHit.isFrontFace_primitiveIndex = candidateHit.isFrontFace_primitiveIndex; + closestHit.uv = candidateHit.uv; + tMax = candidateHit.hitT; + } + + uint RayFlags() { return rayFlags; } + float3 WorldRayOrigin() { return rayOriginInWorld; } + float3 WorldRayDirection() { return rayDirectionInWorld; } + float RayTMin() { return tMin; } + + float CandidateTriangleRayT() { return candidateHit.hitT; } + uint CandidateInstanceID() { return accelStruct.instance_infos[currentInstanceIndex].user_instance_id; } + uint CandidatePrimitiveIndex() { return candidateHit.isFrontFace_primitiveIndex & 0x7FFFFFFF; } + float2 CandidateTriangleBarycentrics() { return candidateHit.uv; } + bool CandidateTriangleFrontFace() { return candidateHit.isFrontFace_primitiveIndex & 0x80000000; } + float3 CandidateLocalRayOrigin() { return rayOrigin; } + float3 CandidateLocalRayDirection() { return rayDirection; } + float3x4 CandidateWorldToLocal3x4() { return ConvertToFloat3x4(accelStruct.instance_infos[currentInstanceIndex].world_to_local_transform); } + float4x3 CandidateWorldToLocal4x3() { return ConvertToFloat4x3(accelStruct.instance_infos[currentInstanceIndex].world_to_local_transform); } + float3x4 CandidateLocalToWorld3x4() { return ConvertToFloat3x4(accelStruct.instance_infos[currentInstanceIndex].local_to_world_transform); } + float4x3 CandidateLocalToWorld4x3() { return ConvertToFloat4x3(accelStruct.instance_infos[currentInstanceIndex].local_to_world_transform); } + + uint CommittedStatus() { return closestHit.instanceIndex == -1 ? kCommittedNothing : kCommittedTriangleHit; } + float CommittedRayT() { return tMax; } + uint CommittedInstanceID() { return accelStruct.instance_infos[closestHit.instanceIndex].user_instance_id; } + uint CommittedPrimitiveIndex() { return closestHit.isFrontFace_primitiveIndex & 0x7FFFFFFF; } + float2 CommittedTriangleBarycentrics() { return closestHit.uv; } + bool CommittedTriangleFrontFace() { return closestHit.isFrontFace_primitiveIndex & 0x80000000; } + float3 CommittedLocalRayOrigin() { return TransformPointT(rayOriginInWorld, accelStruct.instance_infos[closestHit.instanceIndex].world_to_local_transform); } + float3 CommittedLocalRayDirection() { return TransformDirection(rayDirectionInWorld, accelStruct.instance_infos[closestHit.instanceIndex].world_to_local_transform); } + float3x4 CommittedWorldToLocal3x4() { return ConvertToFloat3x4(accelStruct.instance_infos[closestHit.instanceIndex].world_to_local_transform); } + float4x3 CommittedWorldToLocal4x3() { return ConvertToFloat4x3(accelStruct.instance_infos[closestHit.instanceIndex].world_to_local_transform); } + float3x4 CommittedLocalToWorld3x4() { return ConvertToFloat3x4(accelStruct.instance_infos[closestHit.instanceIndex].local_to_world_transform); } + float4x3 CommittedLocalToWorld4x3() { return ConvertToFloat4x3(accelStruct.instance_infos[closestHit.instanceIndex].local_to_world_transform); } + + // read only data + uint rayFlags; + uint rayCullMode_Mask; + float3 rayOriginInWorld; + float3 rayDirectionInWorld; + float tMin; + RayTracingAccelStruct accelStruct; + + // traversal state + float tMax; + float3 rayOrigin; + float3 rayDirection; + float3 rayInvDir; + ClosestHit closestHit; + CandidateHit candidateHit; + RayTraversalStack stack; + CurrentInstance currentInstance; + uint currentNodeIndex; + uint currentInstanceIndex; + int currentLeafTriangleIndex; +}; + + +} // namespace UnifiedRT + +#endif // _UNIFIEDRAYTRACING_RAYQUERYSOFTWARE_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl.meta new file mode 100644 index 00000000000..78963bef32c --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3cae67c457a2ad24495f86529619c102 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl index 81416de234c..55c6cead9b5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl @@ -4,7 +4,7 @@ #include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolDefs.cs.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.hlsl" -#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/CommonStructs.hlsl" #define INTERPOLATE_ATTRIBUTE(attr, barCoords) v.attr = v0.attr * (1.0 - barCoords.x - barCoords.y) + v1.attr * barCoords.x + v2.attr * barCoords.y diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl.meta index ab30ee4e538..2d6194e23a9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 53817fed7d916d74c9584d60774a899f +guid: 8089a70b4819c714295530d5e01d5d36 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware.meta index a107ed30db0..58426d2b3d7 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e45cf32b126e2e346b778e07438405e4 +guid: de0ed5319362ff5418fb5d16977e9463 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs index 2fea619132e..2196e0613de 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs @@ -1,5 +1,5 @@ - using System.Collections.Generic; +using System.Diagnostics; namespace UnityEngine.Rendering.UnifiedRayTracing { @@ -7,24 +7,25 @@ internal sealed class HardwareRayTracingAccelStruct : IRayTracingAccelStruct { public RayTracingAccelerationStructure accelStruct { get; } - readonly Shader m_HWMaterialShader; - Material m_RayTracingMaterial; readonly RayTracingAccelerationStructureBuildFlags m_BuildFlags; + // keep a reference to Meshes because RayTracingAccelerationStructure impl is to automatically // remove instances when the mesh is disposed readonly Dictionary m_Meshes = new(); readonly ReferenceCounter m_Counter; - internal HardwareRayTracingAccelStruct(AccelerationStructureOptions options, Shader hwMaterialShader, ReferenceCounter counter, bool enableCompaction) + #if UNITY_ASSERTIONS + readonly HashSet m_InstanceHandles = new(); + #endif + + internal HardwareRayTracingAccelStruct(AccelerationStructureOptions options, ReferenceCounter counter) { - m_HWMaterialShader = hwMaterialShader; - LoadRayTracingMaterial(); m_BuildFlags = (RayTracingAccelerationStructureBuildFlags)options.buildFlags; RayTracingAccelerationStructure.Settings settings = new RayTracingAccelerationStructure.Settings(); settings.rayTracingModeMask = RayTracingAccelerationStructure.RayTracingModeMask.Everything; settings.managementMode = RayTracingAccelerationStructure.ManagementMode.Manual; - settings.enableCompaction = enableCompaction; + settings.enableCompaction = false; settings.layerMask = 255; settings.buildFlagsStaticGeometries = m_BuildFlags; @@ -37,55 +38,81 @@ internal HardwareRayTracingAccelStruct(AccelerationStructureOptions options, Sha public void Dispose() { m_Counter.Dec(); - accelStruct?.Dispose(); - - if (m_RayTracingMaterial != null) - Utils.Destroy(m_RayTracingMaterial); } public int AddInstance(MeshInstanceDesc meshInstance) { - LoadRayTracingMaterial(); + Utils.CheckArgIsNotNull(meshInstance.mesh, "meshInstance.mesh"); + Utils.CheckArg(meshInstance.mesh.HasVertexAttribute(VertexAttribute.Position), "Cant use a mesh buffer that has no positions."); + Utils.CheckArgRange(meshInstance.subMeshIndex, 0, meshInstance.mesh.subMeshCount, "meshInstance.subMeshIndex"); - var instanceDesc = new RayTracingMeshInstanceConfig(meshInstance.mesh, (uint)meshInstance.subMeshIndex, m_RayTracingMaterial); + var instanceDesc = new RayTracingMeshInstanceConfig(meshInstance.mesh, (uint)meshInstance.subMeshIndex, null); instanceDesc.mask = meshInstance.mask; instanceDesc.enableTriangleCulling = meshInstance.enableTriangleCulling; instanceDesc.frontTriangleCounterClockwise = meshInstance.frontTriangleCounterClockwise; + instanceDesc.subMeshFlags = meshInstance.opaqueGeometry ? RayTracingSubMeshFlags.Enabled | RayTracingSubMeshFlags.ClosestHitOnly : RayTracingSubMeshFlags.Enabled | RayTracingSubMeshFlags.UniqueAnyHitCalls; int instanceHandle = accelStruct.AddInstance(instanceDesc, meshInstance.localToWorldMatrix, null, meshInstance.instanceID); + + // If instanceID is auto assigned, set it in the same way as ComputeRaytracingAccelStruct + if (meshInstance.instanceID == 0xFFFFFFFF) + accelStruct.UpdateInstanceID(instanceHandle, (uint)instanceHandle); + m_Meshes.Add(instanceHandle, meshInstance.mesh); + + #if UNITY_ASSERTIONS + m_InstanceHandles.Add(instanceHandle); + #endif + return instanceHandle; } public void RemoveInstance(int instanceHandle) { + #if UNITY_ASSERTIONS + if (!m_InstanceHandles.Remove(instanceHandle)) + throw new System.ArgumentException($"accel struct does not contain instanceHandle {instanceHandle}", "instanceHandle"); + #endif + m_Meshes.Remove(instanceHandle); accelStruct.RemoveInstance(instanceHandle); } public void ClearInstances() { + #if UNITY_ASSERTIONS + m_InstanceHandles.Clear(); + #endif + m_Meshes.Clear(); accelStruct.ClearInstances(); } public void UpdateInstanceTransform(int instanceHandle, Matrix4x4 localToWorldMatrix) { + CheckInstanceHandleIsValid(instanceHandle); + accelStruct.UpdateInstanceTransform(instanceHandle, localToWorldMatrix); } public void UpdateInstanceID(int instanceHandle, uint instanceID) { + CheckInstanceHandleIsValid(instanceHandle); + accelStruct.UpdateInstanceID(instanceHandle, instanceID); } public void UpdateInstanceMask(int instanceHandle, uint mask) { + CheckInstanceHandleIsValid(instanceHandle); + accelStruct.UpdateInstanceMask(instanceHandle, mask); } public void Build(CommandBuffer cmd, GraphicsBuffer scratchBuffer) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + var buildSettings = new RayTracingAccelerationStructure.BuildSettings() { buildFlags = m_BuildFlags, @@ -101,10 +128,13 @@ public ulong GetBuildScratchBufferRequiredSizeInBytes() return 0; } - private void LoadRayTracingMaterial() + [Conditional("UNITY_ASSERTIONS")] + void CheckInstanceHandleIsValid(int instanceHandle) { - if (m_RayTracingMaterial == null) - m_RayTracingMaterial = new Material(m_HWMaterialShader); +#if UNITY_ASSERTIONS + if (!m_InstanceHandles.Contains(instanceHandle)) + throw new System.ArgumentException($"accel struct does not contain instanceHandle {instanceHandle}", "instanceHandle"); +#endif } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs.meta index 3e65808be6f..fda1dfbf295 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingAccelStruct.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ede69b5a79e72a747867137b76de8f1c +guid: 6170611547c16f24cb5d5878364fc42d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs index 787bb0b5eeb..6b9463eaa68 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs @@ -15,8 +15,8 @@ public IRayTracingShader CreateRayTracingShader(Object shader, string kernelName public IRayTracingAccelStruct CreateAccelerationStructure(AccelerationStructureOptions options, ReferenceCounter counter) { - return new HardwareRayTracingAccelStruct(options, m_Resources.hardwareRayTracingMaterial, counter, options.enableCompaction); - } + return new HardwareRayTracingAccelStruct(options, counter); + } public ulong GetRequiredTraceScratchBufferSizeInBytes(uint width, uint height, uint depth) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs.meta index 45196539f93..a6980d5e487 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingBackend.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 751ba810c80121f4b813b7064a994252 +guid: 5b5b3e229e218a448ae4b7fa04df3b32 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs index d234eeb2c7b..19492291460 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs @@ -21,59 +21,99 @@ public uint3 GetThreadGroupSizes() public void SetAccelerationStructure(CommandBuffer cmd, string name, IRayTracingAccelStruct accelStruct) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(accelStruct, nameof(accelStruct)); + cmd.SetRayTracingShaderPass(m_Shader, "RayTracing"); var hwAccelStruct = accelStruct as HardwareRayTracingAccelStruct; - Assert.IsNotNull(hwAccelStruct); + Debug.Assert(hwAccelStruct != null); + cmd.SetRayTracingAccelerationStructure(m_Shader, Shader.PropertyToID(name+"accelStruct"), hwAccelStruct.accelStruct); } public void SetIntParam(CommandBuffer cmd, int nameID, int val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetRayTracingIntParam(m_Shader, nameID, val); } public void SetFloatParam(CommandBuffer cmd, int nameID, float val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetRayTracingFloatParam(m_Shader, nameID, val); } public void SetVectorParam(CommandBuffer cmd, int nameID, Vector4 val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetRayTracingVectorParam(m_Shader, nameID, val); } public void SetMatrixParam(CommandBuffer cmd, int nameID, Matrix4x4 val) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetRayTracingMatrixParam(m_Shader, nameID, val); } public void SetTextureParam(CommandBuffer cmd, int nameID, RenderTargetIdentifier rt) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.SetRayTracingTextureParam(m_Shader, nameID, rt); } public void SetBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(buffer, nameof(buffer)); + cmd.SetRayTracingBufferParam(m_Shader, nameID, buffer); } public void SetBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(buffer, nameof(buffer)); + cmd.SetRayTracingBufferParam(m_Shader, nameID, buffer); } + public void SetConstantBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer, int offset, int size) + { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(buffer, nameof(buffer)); + + cmd.SetRayTracingConstantBufferParam(m_Shader, nameID, buffer, offset, size); + } + + public void SetConstantBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer, int offset, int size) + { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(buffer, nameof(buffer)); + + cmd.SetRayTracingConstantBufferParam(m_Shader, nameID, buffer, offset, size); + } + public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, uint width, uint height, uint depth) { + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + cmd.DispatchRays(m_Shader, m_ShaderDispatchFuncName, width, height, depth, null); } public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, GraphicsBuffer argsBuffer) { - Assert.IsTrue((argsBuffer.target & GraphicsBuffer.Target.IndirectArguments) != 0); - Assert.IsTrue((argsBuffer.target & GraphicsBuffer.Target.Structured) != 0); - Assert.IsTrue(argsBuffer.count * argsBuffer.stride == 24); - cmd.DispatchRays(m_Shader, m_ShaderDispatchFuncName, argsBuffer, RayTracingHelper.k_DimensionByteOffset); + Utils.CheckArgIsNotNull(cmd, nameof(cmd)); + Utils.CheckArgIsNotNull(argsBuffer, nameof(argsBuffer)); + GraphicsBuffer.Target requiredFlags = GraphicsBuffer.Target.IndirectArguments | GraphicsBuffer.Target.Structured; + Utils.CheckArg((argsBuffer.target & requiredFlags) == requiredFlags, "argsBuffer.target must have both Target.IndirectArguments and Target.Structured set"); + + cmd.DispatchRays(m_Shader, m_ShaderDispatchFuncName, argsBuffer, 0); } public ulong GetTraceScratchBufferRequiredSizeInBytes(uint width, uint height, uint depth) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs.meta index 2d124d727ac..c5f0b239e9f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRayTracingShader.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0425f6fa23e7cf34ea4251c1fd0ab415 +guid: 5fe1af5fce30d364abd00e843878a7ad MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl index 7f69c305b1d..145da92322d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl @@ -1,9 +1,5 @@ #pragma max_recursion_depth 1 -#ifndef UNIFIED_RT_RAYGEN_FUNC_NAME -#define UNIFIED_RT_RAYGEN_FUNC_NAME RayGenExecute -#endif - [shader("raygeneration")] void MainRayGenShader() { @@ -13,11 +9,53 @@ void MainRayGenShader() dispatchInfo.localThreadIndex = 0; dispatchInfo.globalThreadIndex = DispatchRaysIndex().x + DispatchRaysIndex().y * DispatchRaysDimensions().x + DispatchRaysIndex().z * (DispatchRaysDimensions().x * DispatchRaysDimensions().y); - UNIFIED_RT_RAYGEN_FUNC_NAME(dispatchInfo); + UNIFIED_RT_RAYGEN_FUNC(dispatchInfo); } +// miss shader needs to be always defined [shader("miss")] -void MainMissShader0(inout UnifiedRT::Hit hit : SV_RayPayload) +void MissShader(inout UNIFIED_RT_PAYLOAD payload : SV_RayPayload) +{ +#ifdef UNIFIED_RT_MISS_FUNC + UnifiedRT::HitContext hitContext = (UnifiedRT::HitContext)0; + UNIFIED_RT_MISS_FUNC(hitContext, payload); +#endif +} + +namespace UnifiedRT { - hit.instanceID = -1; + struct AttributeData + { + float2 barycentrics; + }; +} + +#ifdef UNIFIED_RT_CLOSESTHIT_FUNC +[shader("closesthit")] +void ClosestHitShader(inout UNIFIED_RT_PAYLOAD payload : SV_RayPayload, UnifiedRT::AttributeData attribs : SV_IntersectionAttributes) +{ + UnifiedRT::HitContext hitContext; + hitContext.barycentrics = attribs.barycentrics; + + UNIFIED_RT_CLOSESTHIT_FUNC(hitContext, payload); } +#endif + +#ifdef UNIFIED_RT_ANYHIT_FUNC +[shader("anyhit")] +void AnyHitShader(inout UNIFIED_RT_PAYLOAD payload : SV_RayPayload, UnifiedRT::AttributeData attribs : SV_IntersectionAttributes) +{ + UnifiedRT::HitContext hitContext; + hitContext.barycentrics = attribs.barycentrics; + + uint res = UNIFIED_RT_ANYHIT_FUNC(hitContext, payload); + + if (res == UnifiedRT::kIgnoreHit) + IgnoreHit(); + + if (res == UnifiedRT::kAcceptHitAndEndSearch) + AcceptHitAndEndSearch(); + + // UnifiedRT::kAcceptHit: As specified in DXR, simply exiting means the hit is accepted. +} +#endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl.meta index 45488d7dc18..da2155884ff 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Hardware/HardwareRaygenShader.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e698d98f89f906548ba85b47757d94a7 +guid: 1ad0a9c8f99bbe642b782fd45551c0a1 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs index 22899cc6345..f648907dac6 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs @@ -2,16 +2,67 @@ namespace UnityEngine.Rendering.UnifiedRayTracing { + /// + /// Parameters used to configure the creation of instances that are part of a . + /// internal struct MeshInstanceDesc { + /// + /// The Mesh used to build this instance's geometry. + /// public Mesh mesh; + + /// + /// The index of the sub-mesh (MeshInstanceDesc references a single sub-mesh). + /// public int subMeshIndex; + + /// + /// The transformation matrix of the instance. + /// public Matrix4x4 localToWorldMatrix; + + /// + /// The instance mask. + /// + /// + /// Instances in the acceleration structure contain an 8-bit user defined instance mask. + /// The TraceRayClosestHit/TraceRayAnyHit HLSL functions have an 8-bit input parameter, InstanceInclusionMask which gets ANDed with the instance mask from + /// any instance that is a candidate for intersection during acceleration structure traversal on the GPU. + /// If the result of the AND operation is zero, the GPU ignores the intersection. + /// public uint mask; + + /// + /// Instance identifier. Can be accessed in the HLSL via the instanceID member of Hit (Hit is returned by the TraceRayClosestHit/TraceRayAnyHit HLSL functions). + /// public uint instanceID; + + /// + /// Whether front/back face culling for this ray tracing instance is enabled. Default value: true. + /// public bool enableTriangleCulling; + + /// + /// Whether to flip the way triangles face in this ray tracing instance. Default value: false. + /// public bool frontTriangleCounterClockwise; + /// + /// Whether the geometry is considered opaque. Default value: true. + /// + /// + /// When an instance's opaqueGeometry field is set to false, the AnyHitExecute shader function will be invoked during the ray traversal when a hit is found. + /// This alows the user to programmatically decide whether to reject or accept the candidate hit. This feature can, for example, be used to implement alpha cutout transparency. + /// For best performance, prefer to set this parameter to false for as many geometries as possibe. + /// + public bool opaqueGeometry; + + /// + /// Creates a MeshInstanceDesc. + /// + /// The Mesh used to build this instance's geometry. + /// The index of the sub-mesh (MeshInstanceDesc references a single sub-mesh). public MeshInstanceDesc(Mesh mesh, int subMeshIndex = 0) { this.mesh = mesh; @@ -21,18 +72,78 @@ public MeshInstanceDesc(Mesh mesh, int subMeshIndex = 0) instanceID = 0xFFFFFFFF; enableTriangleCulling = true; frontTriangleCounterClockwise = false; + opaqueGeometry = true; } } + /// + /// A data structure used to represent a collection of instances and geometries that are used for GPU ray tracing. + /// It can be created by calling . + /// internal interface IRayTracingAccelStruct : IDisposable { + /// + /// Adds an instance to the RayTracingAccelerationStructure. + /// + /// The parameters describing this instance. + /// A value representing a handle that you can use to perform later actions (e.g. RemoveInstance...) + /// int AddInstance(MeshInstanceDesc meshInstance); + + /// + /// Removes an instance. + /// + /// The handle associated with an instance. void RemoveInstance(int instanceHandle); + + /// + /// Removes all ray tracing instances from the acceleration structure. + /// void ClearInstances(); + + /// + /// Updates the transformation of an instance. + /// + /// The handle associated with an instance. + /// The new transformation matrix of the instance. void UpdateInstanceTransform(int instanceHandle, Matrix4x4 localToWorldMatrix); + + /// + /// Updates the instance ID of an instance. + /// + /// The handle associated with an instance. + /// The new instance ID. void UpdateInstanceID(int instanceHandle, uint instanceID); + + /// + /// Updates the instance mask of an instance. + /// + /// + /// Ray tracing instances in the acceleration structure contain an 8-bit user defined instance mask. + /// The TraceRay() HLSL function has an 8-bit input parameter, InstanceInclusionMask which gets ANDed with the instance mask from + /// any ray tracing instance that is a candidate for intersection during acceleration structure traversal on the GPU. + /// If the result of the AND operation is zero, the GPU ignores the intersection. + /// + /// The handle associated with an instance. + /// The new mask. void UpdateInstanceMask(int instanceHandle, uint mask); + + /// + /// Adds a command in cmd to build this acceleration structure on the GPU. + /// + /// + /// Depending on the backend, the GPU build algorithm can require additional GPU storage that is supplied through the scratchBuffer parameter. + /// Its required size can be queried by calling . + /// + /// + /// + /// void Build(CommandBuffer cmd, GraphicsBuffer scratchBuffer); + + /// + /// Returns the minimum buffer size that is required by the scratchBuffer parameter of . + /// + /// The minimum size in bytes. ulong GetBuildScratchBufferRequiredSizeInBytes(); } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs.meta index 89635ef5d48..d0884b84a32 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingAccelStruct.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 14ac07feee17a6442bb0e201c19b57cc +guid: d7dc1089d206d5b41896750a9934e1aa MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingBackend.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingBackend.cs.meta index 3203dc3b06d..969ab9a5a84 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingBackend.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingBackend.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3b3d24f8be576794388110967274b3e0 +guid: c55c8d58ea467a449b38deeb15c16906 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs index ea6b8a97531..bcdde58c82c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs @@ -2,20 +2,145 @@ namespace UnityEngine.Rendering.UnifiedRayTracing { + /// + /// Shader abstraction that is used to bind resources and execute a unified ray tracing shader (.urtshader) on the GPU. + /// + /// + /// It can be created by calling , or . + /// Depending on the backend that was selected when creating the , this class either wraps + /// a RayTracing or a Compute shader. + /// internal interface IRayTracingShader { - uint3 GetThreadGroupSizes(); + /// + /// Adds a command in cmd to set an IRayTracingAccelStruct on this shader. + /// + /// CommandBuffer to register the command to. + /// Name of the variable in shader code. + /// The IRayTracingAccelStruct to be used. void SetAccelerationStructure(CommandBuffer cmd, string name, IRayTracingAccelStruct accelStruct); + + /// + /// Adds a command in cmd to set an integer parameter on this shader. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Value to set. void SetIntParam(CommandBuffer cmd, int nameID, int val); + + /// + /// Adds a command in cmd to set a float parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Value to set. void SetFloatParam(CommandBuffer cmd, int nameID, float val); + + /// + /// Adds a command in cmd to set a vector parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Value to set. void SetVectorParam(CommandBuffer cmd, int nameID, Vector4 val); + + /// + /// Adds a command in cmd to set a matrix parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Value to set. void SetMatrixParam(CommandBuffer cmd, int nameID, Matrix4x4 val); + + /// + /// Adds a command in cmd to set a texture parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Texture to set. void SetTextureParam(CommandBuffer cmd, int nameID, RenderTargetIdentifier rt); + + /// + /// Adds a command in cmd to set a buffer parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Buffer to set. void SetBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer); + + /// + /// Adds a command in cmd to set a buffer parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// Buffer to set. void SetBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer); + + /// + /// Adds a command in cmd to dispatch this IRayTracingShader. + /// + /// + /// Dispatches to the GPU this shader to be executed on a grid of width*height*depth threads. + /// Depending on the backend, the GPU ray traversal algorithm can require additional GPU storage that is supplied through the scratchBuffer parameter. + /// Its required size can be queried by calling . + /// + /// CommandBuffer to register the command to. + /// Temporary buffer used during the shader's ray tracing calls. + /// Number of threads in the X dimension. + /// Number of threads in the Y dimension. + /// Number of threads in the Z dimension. void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, uint width, uint height, uint depth); + + /// + /// Adds a command in cmd to dispatch this IRayTracingShader. + /// + /// + /// Dispatches to the GPU this shader to be executed on a grid of width*height*depth threads. The grid dimensions are read directly from the argsBuffer parameter. It needs + /// to contain 3 integers: number of threads in X dimension, number of threads in Y dimension, number of threads in Z dimension. + /// Typical use case is writing to argsBuffer from another shader and then dispatching this shader, without requiring a readback to the CPU. + /// Depending on the backend, the GPU ray traversal algorithm can require additional GPU storage that is supplied through the scratchBuffer parameter. + /// Its required size can be queried by calling . + /// + /// CommandBuffer to register the command to. + /// Temporary buffer used during the shader's ray tracing calls. + /// Buffer with work grid dimensions. void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, GraphicsBuffer argsBuffer); + + /// + /// Adds a command in cmd to set a constant buffer parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// The buffer to bind as constant buffer. + /// The offset in bytes from the beginning of the buffer to bind. Must be a multiple of SystemInfo.constantBufferOffsetAlignment, or 0 if that value is 0. + /// The number of bytes to bind. + void SetConstantBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer, int offset, int size); + + /// + /// Adds a command in cmd to set a constant buffer parameter. + /// + /// CommandBuffer to register the command to. + /// Property name ID. Use Shader.PropertyToID to get this ID. + /// The buffer to bind as constant buffer. + /// The offset in bytes from the beginning of the buffer to bind. Must be a multiple of SystemInfo.constantBufferOffsetAlignment, or 0 if that value is 0. + /// The number of bytes to bind. + void SetConstantBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer, int offset, int size); + + /// + /// Returns the minimum buffer size that is required by the scratchBuffer parameter of . + /// This size depends on the specific values for width,height and depth that will be passed to Dispatch(). + /// + /// Number of threads in the X dimension. + /// Number of threads in the Y dimension. + /// Number of threads in the Z dimension. + /// The minimum size in bytes. ulong GetTraceScratchBufferRequiredSizeInBytes(uint width, uint height, uint depth); + + /// + /// Get the thread group sizes of this shader. + /// + /// Thread group size in the X,Y and Z directions. + uint3 GetThreadGroupSizes(); } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs.meta index dda8da1812e..5782bee6b72 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/IRayTracingShader.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: eb8cc55328de6e24797ca17b24e18acf +guid: 049128a5d2439f641b23508bb67e181c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs index 0c18a296128..fb24e678968 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs @@ -7,12 +7,46 @@ namespace UnityEngine.Rendering.UnifiedRayTracing { - internal enum RayTracingBackend { Hardware = 0, Compute = 1} + /// + /// Specifies what backend to use when creating a . + /// + internal enum RayTracingBackend + { + /// + /// Requires a GPU supporting hardware accelerated ray tracing. + /// + Hardware = 0, + + /// + /// Software implementation of ray tracing that requires the GPU to support compute shaders. + /// + Compute = 1 + } + /// + /// Entry point for the UnifiedRayTracing API. + /// + /// + /// It provides functionality to: + /// + /// load shader code (CreateRayTracingShader) + /// create an acceleration structure (CreateAccelerationStructure) that represents the geometry to be ray traced against. + /// + /// Once these objects have been created, the shader code can be executed by calling IRayTracingShader.Dispatch + /// Before calling Dispose() on a RayTracingContext, all that have been created by a RayTracingContext must be disposed as well. + /// internal sealed class RayTracingContext : IDisposable { + /// + /// Creates a RayTracingContext. + /// + /// The chosen backend. + /// The resources (provides the various shaders the context needs to operate). + /// public RayTracingContext(RayTracingBackend backend, RayTracingResources resources) { + Utils.CheckArgIsNotNull(resources, nameof(resources)); + if (!IsBackendSupported(backend)) throw new System.InvalidOperationException("Unsupported backend: " + backend.ToString()); @@ -23,8 +57,24 @@ public RayTracingContext(RayTracingBackend backend, RayTracingResources resource m_Backend = new ComputeRayTracingBackend(resources); Resources = resources; - m_DispatchBuffer = RayTracingHelper.CreateDispatchDimensionBuffer(); + m_DispatchBuffer = RayTracingHelper.CreateDispatchIndirectBuffer(); } + + /// + /// Creates a RayTracingContext. + /// + /// The resources (provides the various shaders the context needs to operate). + /// + public RayTracingContext(RayTracingResources resources) : this(IsBackendSupported(RayTracingBackend.Hardware) ? RayTracingBackend.Hardware : RayTracingBackend.Compute, resources) + { + } + + /// + /// Disposes the RaytracingContext. + /// + /// + /// Before calling this, all that have been created with this RayTracingContext must be disposed as well. + /// public void Dispose() { if (m_AccelStructCounter.value != 0) @@ -35,8 +85,16 @@ public void Dispose() m_DispatchBuffer?.Release(); } - public RayTracingResources Resources; + /// + /// object this context has been created with. + /// + public RayTracingResources Resources { get; private set; } + /// + /// Checks if the specified backend is supported on the current GPU. + /// + /// The backend. + /// Whether the specified bakend is supported. static public bool IsBackendSupported(RayTracingBackend backend) { if (backend == RayTracingBackend.Hardware) @@ -47,23 +105,29 @@ static public bool IsBackendSupported(RayTracingBackend backend) return false; } + /// + /// Creates a IRayTracingShader. + /// + /// + /// Depending on the chosen backend, the shader parameter + /// needs to be either a ComputeShader or RayTracingShader. + /// + /// The ComputeShader or RayTracingShader asset. + /// The unified ray tracing shader. public IRayTracingShader CreateRayTracingShader(Object shader) => m_Backend.CreateRayTracingShader(shader, "MainRayGenShader", m_DispatchBuffer); - public static uint GetScratchBufferStrideInBytes() => 4; - - public IRayTracingShader CreateRayTracingShader(RayTracingShader rtShader) - { - var shader = m_Backend.CreateRayTracingShader(rtShader, "MainRayGenShader", m_DispatchBuffer); - return shader; - } - public IRayTracingShader CreateRayTracingShader(ComputeShader computeShader) - { - var shader = m_Backend.CreateRayTracingShader(computeShader, "MainRayGenShader", m_DispatchBuffer); - return shader; - } - #if UNITY_EDITOR + /// + /// Creates a unified ray tracing shader from .urtshader asset file. + /// + /// + /// - This API works only in the Unity Editor, not at runtime. + /// - The path must be relative to the project folder, for example: "Assets/Stuff/myshader.urtshader". + /// - A .urtshader asset file is imported in the Editor as 2 shaders: a ComputeShader and a RayTracingShader. LoadRayTracingShader loads the one relevant one depending on the RayTracingContext's backend. + /// + /// Path to the .urtshader shader asset file to load. + /// The unified ray tracing shader. public IRayTracingShader LoadRayTracingShader(string fileName) { Type shaderType = BackendHelpers.GetTypeOfShader(BackendType); @@ -71,17 +135,55 @@ public IRayTracingShader LoadRayTracingShader(string fileName) return CreateRayTracingShader(asset); } #endif +#if ENABLE_ASSET_BUNDLE + /// + /// Creates a unified ray tracing shader from an AssetBundle. + /// + /// The AssetBundle. + /// The asset name with the .urtshader extension included. + /// The unified ray tracing shader. + public IRayTracingShader LoadRayTracingShaderFromAssetBundle(AssetBundle assetBundle, string name) + { + Utils.CheckArgIsNotNull(assetBundle, nameof(assetBundle)); + Object asset = assetBundle.LoadAsset(name, BackendHelpers.GetTypeOfShader(BackendType)); + return CreateRayTracingShader(asset); + } +#endif + /// + /// Creates a IRayTracingAccelStruct. + /// + /// Options for quality/performance trade-offs for the returned acceleration structure + /// The acceleration structure. public IRayTracingAccelStruct CreateAccelerationStructure(AccelerationStructureOptions options) { + Utils.CheckArgIsNotNull(options, nameof(options)); + var accelStruct = m_Backend.CreateAccelerationStructure(options, m_AccelStructCounter); return accelStruct; } + + /// + /// Returns the minimum size that is required by the scratchBuffer parameter of . + /// + /// Number of threads in the X dimension. + /// Number of threads in the Y dimension. + /// Number of threads in the Z dimension. + /// The size in bytes. public ulong GetRequiredTraceScratchBufferSizeInBytes(uint width, uint height, uint depth) { return m_Backend.GetRequiredTraceScratchBufferSizeInBytes(width, height, depth); } + /// + /// Required stride for the creation of the scratchBuffers used by and . + /// + /// The required stride. + public static uint GetScratchBufferStrideInBytes() => 4; + + /// + /// The this context was created with. + /// public RayTracingBackend BackendType { get; private set; } readonly IRayTracingBackend m_Backend; @@ -89,22 +191,52 @@ public ulong GetRequiredTraceScratchBufferSizeInBytes(uint width, uint height, u readonly GraphicsBuffer m_DispatchBuffer; } + /// + /// Specifies how Unity builds the acceleration structure on the GPU. + /// [System.Flags] internal enum BuildFlags { + /// + /// Specify no options for the acceleration structure build. Provides a trade-off between good ray tracing performance and fast build times. + /// None = 0, + + /// + /// Build a high quality acceleration structure, increasing build time but maximizing ray tracing performance. + /// PreferFastTrace = 1 << 0, + + /// + /// Build a lower quality acceleration structure, minimizing build time but decreasing ray tracing performance. + /// PreferFastBuild = 1 << 1, + + /// + /// Minimize the amount of temporary memory Unity uses when building the acceleration structure, and minimize the size of the result. + /// MinimizeMemory = 1 << 2 } + /// + /// Options used to configure the creation of a . + /// internal class AccelerationStructureOptions { + /// + /// Option for the quality of the built . + /// public BuildFlags buildFlags = 0; - public bool enableCompaction = false; - #if UNITY_EDITOR +#if UNITY_EDITOR + /// + /// Enables building the acceleration structure on the CPU instead of the GPU. + /// Enabling this option combined with the use of the PreferFastBuild flag provides the best possible ray tracing performance. + /// + /// + /// This field works only in the Unity Editor, not at runtime. + /// public bool useCPUBuild = false; - #endif +#endif } internal class ReferenceCounter @@ -115,21 +247,44 @@ internal class ReferenceCounter public void Dec() { value--; } } + /// + /// Helper functions that can be used to create a scratch buffer. + /// + /// + /// A scratch buffer is a GraphicsBuffer that Unity uses during the acceleration structure build or the ray tracing dispatch to store temporary data. + /// internal static class RayTracingHelper { + /// + /// suitable for scratch buffers used in for both and . + /// public const GraphicsBuffer.Target ScratchBufferTarget = GraphicsBuffer.Target.Structured; - static public readonly uint k_DimensionByteOffset = 0; // offset into the DispatchDimensionBuffer where the dimensions reside - static public readonly uint k_GroupSizeByteOffset = 12; // offset into the DispatchDimensionBuffer where the group sizes reside - static public GraphicsBuffer CreateDispatchDimensionBuffer() + /// + /// Creates an indirect args buffer suitable for . + /// + /// The scratch buffer. + static public GraphicsBuffer CreateDispatchIndirectBuffer() { - return new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments | GraphicsBuffer.Target.Structured | GraphicsBuffer.Target.CopySource, 6, sizeof(uint)); + return new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments | GraphicsBuffer.Target.Structured | GraphicsBuffer.Target.CopySource, 3, sizeof(uint)); } + /// + /// Creates a scratch buffer suitable for both and . + /// + /// The acceleration structure that will be passed to . + /// The shader that will be passed to . + /// Number of threads in the X dimension that will be passed to . + /// Number of threads in the Y dimension that will be passed to . + /// Number of threads in the Z dimension that will be passed to . + /// The scratch buffer. static public GraphicsBuffer CreateScratchBufferForBuildAndDispatch( IRayTracingAccelStruct accelStruct, IRayTracingShader shader, uint dispatchWidth, uint dispatchHeight, uint dispatchDepth) { + Utils.CheckArgIsNotNull(accelStruct, nameof(accelStruct)); + Utils.CheckArgIsNotNull(shader, nameof(shader)); + var sizeInBytes = System.Math.Max(accelStruct.GetBuildScratchBufferRequiredSizeInBytes(), shader.GetTraceScratchBufferRequiredSizeInBytes(dispatchWidth, dispatchHeight, dispatchDepth)); if (sizeInBytes == 0) return null; @@ -137,21 +292,64 @@ static public GraphicsBuffer CreateScratchBufferForBuildAndDispatch( return new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)(sizeInBytes / 4), 4); } + /// + /// Creates a scratch buffer suitable for . + /// + /// The acceleration structure that will be passed to . + /// The scratch buffer. static public GraphicsBuffer CreateScratchBufferForBuild( IRayTracingAccelStruct accelStruct) { + Utils.CheckArgIsNotNull(accelStruct, nameof(accelStruct)); + var sizeInBytes = accelStruct.GetBuildScratchBufferRequiredSizeInBytes(); + if (sizeInBytes == 0) + return null; + return new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)(sizeInBytes / 4), 4); } + /// + /// Creates a scratch buffer suitable for . + /// + /// The shader that will be passed to . + /// Number of threads in the X dimension that will be passed to . + /// Number of threads in the Y dimension that will be passed to . + /// Number of threads in the Z dimension that will be passed to . + /// The scratch buffer. + static public GraphicsBuffer CreateScratchBufferForTrace(IRayTracingShader shader, uint dispatchWidth, uint dispatchHeight, uint dispatchDepth) + { + Utils.CheckArgIsNotNull(shader, nameof(shader)); + + var sizeInBytes = shader.GetTraceScratchBufferRequiredSizeInBytes(dispatchWidth, dispatchHeight, dispatchDepth); + if (sizeInBytes == 0) + return null; + + return new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)(sizeInBytes / 4), 4); + } + + /// + /// Resizes a scratch buffer if its size doesn't fit the requirement of . + /// + /// + /// The resize is accomplished by disposing of the GraphicsBuffer and instanciating a new one at the proper size. + /// + /// The shader that will be passed to . + /// Number of threads in the X dimension that will be passed to . + /// Number of threads in the Y dimension that will be passed to . + /// Number of threads in the Z dimension that will be passed to . + /// The scratch buffer. static public void ResizeScratchBufferForTrace( IRayTracingShader shader, uint dispatchWidth, uint dispatchHeight, uint dispatchDepth, ref GraphicsBuffer scratchBuffer) { + Utils.CheckArgIsNotNull(shader, nameof(shader)); + var sizeInBytes = shader.GetTraceScratchBufferRequiredSizeInBytes(dispatchWidth, dispatchHeight, dispatchDepth); if (sizeInBytes == 0) return; - Debug.Assert(scratchBuffer == null || scratchBuffer.target == ScratchBufferTarget); + if (scratchBuffer != null) + Utils.CheckArg(scratchBuffer.target == ScratchBufferTarget, "scratchBuffer.target must have Target.Structured set"); if (scratchBuffer == null || (ulong)(scratchBuffer.count*scratchBuffer.stride) < sizeInBytes) { @@ -160,14 +358,25 @@ static public void ResizeScratchBufferForTrace( } } + /// + /// Resizes a scratch buffer if its size doesn't fit the requirement of . + /// + /// + /// The resize is accomplished by disposing of the GraphicsBuffer and instanciating a new one at the proper size. + /// + /// The acceleration structure that will be passed to . + /// The scratch buffer. static public void ResizeScratchBufferForBuild( IRayTracingAccelStruct accelStruct, ref GraphicsBuffer scratchBuffer) { + Utils.CheckArgIsNotNull(accelStruct, nameof(accelStruct)); + var sizeInBytes = accelStruct.GetBuildScratchBufferRequiredSizeInBytes(); if (sizeInBytes == 0) return; - Debug.Assert(scratchBuffer == null || scratchBuffer.target == ScratchBufferTarget); + if (scratchBuffer != null) + Utils.CheckArg(scratchBuffer.target == ScratchBufferTarget, "scratchBuffer.target must have Target.Structured set"); if (scratchBuffer == null || (ulong)(scratchBuffer.count * scratchBuffer.stride) < sizeInBytes) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs.meta index 102c807759a..d2d46fb5f11 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingContext.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 78b3c8adbce74bd408b9732aa59d50bd +guid: bf5115231aebe5d459b1b57b8a3cd703 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs index 89cbd6b06a4..ac5e5d35a89 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs @@ -1,32 +1,132 @@ - +using System; #if UNITY_EDITOR using UnityEditor; #endif namespace UnityEngine.Rendering.UnifiedRayTracing { + [Serializable] + [SupportedOnRenderPipeline()] + [Categorization.CategoryInfo(Name = "R: Unified Ray Tracing", Order = 1000), HideInInspector] + internal class RayTracingRenderPipelineResources : IRenderPipelineResources + { + [SerializeField, HideInInspector] int m_Version = 1; + + public int version + { + get => m_Version; + } + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute")] + ComputeShader m_GeometryPoolKernels; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Common/Utilities/CopyBuffer.compute")] + ComputeShader m_CopyBuffer; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/copyPositions.compute")] + ComputeShader m_CopyPositions; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute")] + ComputeShader m_BitHistogram; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute")] + ComputeShader m_BlockReducePart; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute")] + ComputeShader m_BlockScan; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute")] + ComputeShader m_BuildHlbvh; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute")] + ComputeShader m_RestructureBvh; + + [SerializeField, ResourcePath("Runtime/UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute")] + ComputeShader m_Scatter; + + public ComputeShader GeometryPoolKernels + { + get => m_GeometryPoolKernels; + set => this.SetValueAndNotify(ref m_GeometryPoolKernels, value, nameof(m_GeometryPoolKernels)); + } + + public ComputeShader CopyBuffer + { + get => m_CopyBuffer; + set => this.SetValueAndNotify(ref m_CopyBuffer, value, nameof(m_CopyBuffer)); + } + + public ComputeShader CopyPositions + { + get => m_CopyPositions; + set => this.SetValueAndNotify(ref m_CopyPositions, value, nameof(m_CopyPositions)); + } + + public ComputeShader BitHistogram + { + get => m_BitHistogram; + set => this.SetValueAndNotify(ref m_BitHistogram, value, nameof(m_BitHistogram)); + } + + public ComputeShader BlockReducePart + { + get => m_BlockReducePart; + set => this.SetValueAndNotify(ref m_BlockReducePart, value, nameof(m_BlockReducePart)); + } + + public ComputeShader BlockScan + { + get => m_BlockScan; + set => this.SetValueAndNotify(ref m_BlockScan, value, nameof(m_BlockScan)); + } + + public ComputeShader BuildHlbvh + { + get => m_BuildHlbvh; + set => this.SetValueAndNotify(ref m_BuildHlbvh, value, nameof(m_BuildHlbvh)); + } + + public ComputeShader RestructureBvh + { + get => m_RestructureBvh; + set => this.SetValueAndNotify(ref m_RestructureBvh, value, nameof(m_RestructureBvh)); + } + + public ComputeShader Scatter + { + get => m_Scatter; + set => this.SetValueAndNotify(ref m_Scatter, value, nameof(m_Scatter)); + } + } + + /// + /// Utility shaders needed by a to operate. + /// internal class RayTracingResources { - public ComputeShader geometryPoolKernels; - public ComputeShader copyBuffer; - public Shader hardwareRayTracingMaterial; - - public ComputeShader copyPositions; - public ComputeShader bitHistogram; - public ComputeShader blockReducePart; - public ComputeShader blockScan; - public ComputeShader buildHlbvh; - public ComputeShader restructureBvh; - public ComputeShader scatter; + public ComputeShader geometryPoolKernels { get; set; } + public ComputeShader copyBuffer { get; set; } + public ComputeShader copyPositions { get; set; } + public ComputeShader bitHistogram { get; set; } + public ComputeShader blockReducePart { get; set; } + public ComputeShader blockScan { get; set; } + public ComputeShader buildHlbvh { get; set; } + public ComputeShader restructureBvh { get; set; } + public ComputeShader scatter { get; set; } #if UNITY_EDITOR + /// + /// Intializes the RayTracingResources. + /// + /// + /// This API works only in the Unity Editor, not at runtime. + /// public void Load() { - const string path = "Packages/com.unity.rendering.light-transport/Runtime/"; + const string path = "Packages/com.unity.render-pipelines.core/Runtime/"; geometryPoolKernels = AssetDatabase.LoadAssetAtPath(path + "UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute"); copyBuffer = AssetDatabase.LoadAssetAtPath(path + "UnifiedRayTracing/Common/Utilities/CopyBuffer.compute"); - hardwareRayTracingMaterial = AssetDatabase.LoadAssetAtPath(path + "UnifiedRayTracing/Hardware/HWRayTracingMaterial.shader"); copyPositions = AssetDatabase.LoadAssetAtPath(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/copyPositions.compute"); bitHistogram = AssetDatabase.LoadAssetAtPath(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute"); @@ -38,7 +138,72 @@ public void Load() } #endif +#if ENABLE_ASSET_BUNDLE + /// + /// Intializes the RayTracingResources by loading its utility shaders from an AssetBundle. + /// + /// + /// The necessary shaders are configured to belong to the unifiedraytracing AssetBundle which can be built by calling + /// + /// The AssetBundle to load the shaders from. + public void LoadFromAssetBundle(AssetBundle assetBundle) + { + const string path = "Packages/com.unity.render-pipelines.core/Runtime/"; + + geometryPoolKernels = assetBundle.LoadAsset(path + "UnifiedRayTracing/Common/GeometryPool/GeometryPoolKernels.compute"); + copyBuffer = assetBundle.LoadAsset(path + "UnifiedRayTracing/Common/Utilities/CopyBuffer.compute"); + + copyPositions = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/copyPositions.compute"); + bitHistogram = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/bit_histogram.compute"); + blockReducePart = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/block_reduce_part.compute"); + blockScan = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/block_scan.compute"); + buildHlbvh = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/build_hlbvh.compute"); + restructureBvh = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/restructure_bvh.compute"); + scatter = assetBundle.LoadAsset(path + "UnifiedRayTracing/Compute/RadeonRays/kernels/scatter.compute"); + } +#endif + + /// + /// Intializes the RayTracingResources by loading its utility shaders via GraphicsSettings. + /// + /// + /// This method only works in projects that use Scriptable Render Pipeline. + /// + /// Whether the resources were successfully loaded. + public bool LoadFromRenderPipelineResources() + { + if (GraphicsSettings.TryGetRenderPipelineSettings(out var rpResources)) + { + Debug.Assert(rpResources.GeometryPoolKernels != null); + Debug.Assert(rpResources.CopyBuffer != null); + Debug.Assert(rpResources.CopyPositions != null); + Debug.Assert(rpResources.BitHistogram != null); + Debug.Assert(rpResources.BlockReducePart != null); + Debug.Assert(rpResources.BlockScan != null); + Debug.Assert(rpResources.BuildHlbvh != null); + Debug.Assert(rpResources.RestructureBvh != null); + Debug.Assert(rpResources.Scatter != null); + + geometryPoolKernels = rpResources.GeometryPoolKernels; + copyBuffer = rpResources.CopyBuffer; + + copyPositions = rpResources.CopyPositions; + bitHistogram = rpResources.BitHistogram; + blockReducePart = rpResources.BlockReducePart; + blockScan = rpResources.BlockScan; + buildHlbvh = rpResources.BuildHlbvh; + restructureBvh = rpResources.RestructureBvh; + scatter = rpResources.Scatter; + + return true; + } + else + { + return false; + } + } } + } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs.meta index f75ded008cf..62970a469b0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/RayTracingResources.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c618c6f8634d800438912f2bc089721a +guid: e9a999e2bb7021640b7d79411f755090 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/StringIDs.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/StringIDs.cs new file mode 100644 index 00000000000..0900806fda4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/StringIDs.cs @@ -0,0 +1,10 @@ + +namespace UnityEngine.Rendering.UnifiedRayTracing +{ + internal static class SID + { + public static readonly int _UnifiedRT_Stack = Shader.PropertyToID("_UnifiedRT_Stack"); + public static readonly int _UnifiedRT_DispatchDims = Shader.PropertyToID("_UnifiedRT_DispatchDims"); + public static readonly int _UnifiedRT_DispatchDimsInWorkgroups = Shader.PropertyToID("_UnifiedRT_DispatchDimsInWorkgroups"); + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/StringIDs.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/StringIDs.cs.meta new file mode 100644 index 00000000000..2b384b793e8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/StringIDs.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8f66ec818466aff4c96e8f911679ffe5 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl index 8fa5ade5056..8e8a5de180c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl @@ -2,30 +2,74 @@ #define _UNIFIEDRAYTRACING_TRACERAY_HLSL_ #include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Bindings.hlsl" +#if defined(UNIFIED_RT_BACKEND_COMPUTE) +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Compute/RayQuerySoftware.hlsl" +#endif -namespace UnifiedRT { - -static const uint kRayFlagNone = 0x0; -static const uint kRayFlagCullBackFacingTriangles = 0x10; -static const uint kRayFlagCullFrontFacingTriangles = 0x20; - -#if defined(UNIFIED_RT_BACKEND_HARDWARE) - -Hit TraceRayClosestHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags) +namespace UnifiedRT { - RayDesc rayDesc; - rayDesc.Origin = ray.origin; - rayDesc.TMin = ray.tMin; - rayDesc.Direction = ray.direction; - rayDesc.TMax = ray.tMax; - Hit payload; - TraceRay(accelStruct.accelStruct, RAY_FLAG_FORCE_OPAQUE | rayFlags, instanceMask, 0, 1, 0, rayDesc, payload); +#if defined(UNIFIED_RT_BACKEND_HARDWARE) - return payload; -} +float3 _WorldRayOrigin() { return WorldRayOrigin(); } +float3 _WorldRayDirection() { return WorldRayDirection(); } +float _RayTMin() { return RayTMin(); } +float _RayTCurrent() { return RayTCurrent(); } +uint _InstanceID() { return InstanceID(); } +uint _InstanceIndex() { return InstanceIndex(); } +uint _PrimitiveIndex() { return PrimitiveIndex(); } -bool TraceRayAnyHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags) +struct HitContext +{ + float2 barycentrics; + + float3 WorldRayOrigin() + { + return _WorldRayOrigin(); + } + + float3 WorldRayDirection() + { + return _WorldRayDirection(); + } + + float RayTMin() + { + return _RayTMin(); + } + + float RayTCurrent() + { + return _RayTCurrent(); + } + + uint InstanceIndex() + { + return _InstanceIndex(); + } + + uint InstanceID() + { + return _InstanceID(); + } + + uint PrimitiveIndex() + { + return _PrimitiveIndex(); + } + + float2 UvBarycentrics() + { + return barycentrics; + } + + bool IsFrontFace() + { + return (HitKind() == HIT_KIND_TRIANGLE_FRONT_FACE); + } +}; + +void TraceRay(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags, inout UNIFIED_RT_PAYLOAD payload) { RayDesc rayDesc; rayDesc.Origin = ray.origin; @@ -33,72 +77,142 @@ bool TraceRayAnyHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct rayDesc.Direction = ray.direction; rayDesc.TMax = ray.tMax; - Hit payLoadShadow = (Hit)0; - TraceRay(accelStruct.accelStruct, RAY_FLAG_SKIP_CLOSEST_HIT_SHADER | RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | rayFlags, instanceMask, 0, 1, 0, rayDesc, payLoadShadow); - - return payLoadShadow.IsValid(); + TraceRay(accelStruct.accelStruct, rayFlags, instanceMask, 0, 1, 0, rayDesc, payload); } #elif defined(UNIFIED_RT_BACKEND_COMPUTE) -int GetCullMode(uint rayFlags) +struct HitContext { - int cullMode = CULL_MODE_NONE; + float3 worldRayOrigin; + float3 worldRayDirection; + float tmin; + float tcurrent; + uint instanceID; + uint primitiveIndex; + float2 barycentrics; + bool isFrontFace; + + float3 WorldRayOrigin() + { + return worldRayOrigin; + } + + float3 WorldRayDirection() + { + return worldRayDirection; + } + + float RayTMin() + { + return tmin; + } + + float RayTCurrent() + { + return tcurrent; + } + + uint InstanceID() + { + return instanceID; + } + + uint PrimitiveIndex() + { + return primitiveIndex; + } + + float2 UvBarycentrics() + { + return barycentrics; + } + + bool IsFrontFace() + { + return isFrontFace; + } +}; - if (rayFlags & kRayFlagCullFrontFacingTriangles) - cullMode = CULL_MODE_FRONTFACE; +} // namespace UnifiedRT - if (rayFlags & kRayFlagCullBackFacingTriangles) - cullMode = CULL_MODE_BACKFACE; +#ifdef UNIFIED_RT_ANYHIT_FUNC + uint UNIFIED_RT_ANYHIT_FUNC(UnifiedRT::HitContext hitContext, inout UNIFIED_RT_PAYLOAD payload); +#endif - return cullMode; -} +#ifdef UNIFIED_RT_CLOSESTHIT_FUNC + void UNIFIED_RT_CLOSESTHIT_FUNC(UnifiedRT::HitContext hitContext, inout UNIFIED_RT_PAYLOAD payload); +#endif -Hit TraceRayClosestHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags) -{ - TraceParams traceParams; - traceParams.bvh = accelStruct.bvh; - traceParams.bottom_bvhs = accelStruct.bottom_bvhs; - traceParams.bottom_bvh_leaves = accelStruct.bottom_bvh_leaves; - traceParams.stack = g_stack; - traceParams.instance_infos = accelStruct.instance_infos; - traceParams.globalThreadIndex = dispatchInfo.globalThreadIndex; - traceParams.localThreadIndex = dispatchInfo.localThreadIndex; - traceParams.bottom_bvhs_vertices = accelStruct.vertexBuffer; - traceParams.bottom_bvhs_vertex_stride = accelStruct.vertexStride; - - int cull_mode = GetCullMode(rayFlags); - - TraceHitResult hitData = TraceRaySoftware(traceParams, ray.origin, ray.tMin, ray.direction, ray.tMax, instanceMask, cull_mode, true); - - Hit res; - res.instanceID = hitData.inst_id != -1 ? GetUserInstanceID(traceParams, hitData.inst_id) : -1; - res.primitiveIndex = hitData.prim_id; - res.uvBarycentrics = hitData.uv; - res.hitDistance = hitData.hit_distance; - res.isFrontFace = hitData.front_face; - - return res; -} +namespace UnifiedRT { + +#pragma warning(disable : 3557) // prevent warning when the "while (rayQuery.Proceed())" loop is unrolled -bool TraceRayAnyHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags) +void TraceRay(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags, inout UNIFIED_RT_PAYLOAD payload) { - TraceParams traceParams; - traceParams.bvh = accelStruct.bvh; - traceParams.bottom_bvhs = accelStruct.bottom_bvhs; - traceParams.bottom_bvh_leaves = accelStruct.bottom_bvh_leaves; - traceParams.stack = g_stack; - traceParams.instance_infos = accelStruct.instance_infos; - traceParams.globalThreadIndex = dispatchInfo.globalThreadIndex; - traceParams.localThreadIndex = dispatchInfo.localThreadIndex; - traceParams.bottom_bvhs_vertices = accelStruct.vertexBuffer; - traceParams.bottom_bvhs_vertex_stride = accelStruct.vertexStride; - - int cull_mode = GetCullMode(rayFlags); - - TraceHitResult hit = TraceRaySoftware(traceParams, ray.origin, ray.tMin, ray.direction, ray.tMax, instanceMask, cull_mode, false); - - return hit.inst_id != INVALID_NODE; + #ifdef UNIFIED_RT_ANYHIT_FUNC + RayQuery rayQuery; + rayQuery.Init(dispatchInfo.globalThreadIndex, dispatchInfo.localThreadIndex, accelStruct, rayFlags, instanceMask, ray); + while (rayQuery.Proceed()) + { + // not necessary but makes sure the compiler optimizes the loop out when one of these flags is set + if (rayFlags & (UnifiedRT::kRayFlagForceOpaque | UnifiedRT::kRayFlagCullNonOpaque)) + break; + + HitContext hitContext; + hitContext.worldRayOrigin = rayQuery.WorldRayOrigin(); + hitContext.worldRayDirection = rayQuery.WorldRayDirection(); + hitContext.tmin = rayQuery.RayTMin(); + hitContext.tcurrent = rayQuery.CandidateTriangleRayT(); + hitContext.instanceID = rayQuery.CandidateInstanceID(); + hitContext.primitiveIndex = rayQuery.CandidatePrimitiveIndex(); + hitContext.barycentrics = rayQuery.CandidateTriangleBarycentrics(); + hitContext.isFrontFace = rayQuery.CandidateTriangleFrontFace(); + + uint res = UNIFIED_RT_ANYHIT_FUNC(hitContext, payload); + + if (res != UnifiedRT::kIgnoreHit) + rayQuery.CommitNonOpaqueTriangleHit(); + + if (res == UnifiedRT::kAcceptHitAndEndSearch) + rayQuery.Abort(); + + } + #else + RayQuery rayQuery; + rayQuery.Init(dispatchInfo.globalThreadIndex, dispatchInfo.localThreadIndex, accelStruct, rayFlags | UnifiedRT::kRayFlagForceOpaque, instanceMask, ray); + rayQuery.Proceed(); + #endif + +#ifdef UNIFIED_RT_CLOSESTHIT_FUNC + if (!(rayFlags & kRayFlagSkipClosestHit) && rayQuery.CommittedStatus() == kCommittedTriangleHit) + { + HitContext hitContext; + hitContext.worldRayOrigin = rayQuery.WorldRayOrigin(); + hitContext.worldRayDirection = rayQuery.WorldRayDirection(); + hitContext.tmin = rayQuery.RayTMin(); + hitContext.tcurrent = rayQuery.CommittedRayT(); + hitContext.instanceID = rayQuery.CommittedInstanceID(); + hitContext.primitiveIndex = rayQuery.CommittedPrimitiveIndex(); + hitContext.barycentrics = rayQuery.CommittedTriangleBarycentrics(); + hitContext.isFrontFace = rayQuery.CommittedTriangleFrontFace(); + + UNIFIED_RT_CLOSESTHIT_FUNC(hitContext, payload); + } +#endif + +#ifdef UNIFIED_RT_MISS_FUNC + if (rayQuery.CommittedStatus() == kCommittedNothing) + { + HitContext hitContext = (HitContext)0; + hitContext.worldRayOrigin = rayQuery.WorldRayOrigin(); + hitContext.worldRayDirection = rayQuery.WorldRayDirection(); + hitContext.tmin = rayQuery.RayTMin(); + + UNIFIED_RT_MISS_FUNC(hitContext, payload); + } +#endif + } #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl.meta index 9bf607b2cfa..84f8016696b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2a499812089c5144288ca9403af818d2 +guid: d89584fc78a387b4b89d50da624e2695 ShaderIncludeImporter: externalObjects: {} userData: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl new file mode 100644 index 00000000000..afdfa0b5b8f --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl @@ -0,0 +1,45 @@ +#ifndef _UNIFIEDRAYTRACING_TRACERAYANDQUERYHIT_HLSL_ +#define _UNIFIEDRAYTRACING_TRACERAYANDQUERYHIT_HLSL_ + +#define UNIFIED_RT_PAYLOAD UnifiedRT::Hit +#ifndef UNIFIED_RT_RAYGEN_FUNC +#define UNIFIED_RT_RAYGEN_FUNC RayGenExecute +#endif +#define UNIFIED_RT_CLOSESTHIT_FUNC ClosestHitExecute +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl" + +void ClosestHitExecute(UnifiedRT::HitContext hitContext, inout UnifiedRT::Hit payload) +{ + payload.instanceID = hitContext.InstanceID(); + payload.primitiveIndex = hitContext.PrimitiveIndex(); + payload.uvBarycentrics = hitContext.UvBarycentrics(); + payload.hitDistance = hitContext.RayTCurrent(); + payload.isFrontFace = hitContext.IsFrontFace(); +} + +namespace UnifiedRT +{ + +Hit TraceRayClosestHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags) +{ + Hit payload= (Hit)0; + payload.instanceID = -1; + + TraceRay(dispatchInfo, accelStruct, instanceMask, ray, rayFlags | kRayFlagForceOpaque, payload); + + return payload; +} + +bool TraceRayAnyHit(DispatchInfo dispatchInfo, RayTracingAccelStruct accelStruct, uint instanceMask, Ray ray, uint rayFlags) +{ + Hit payLoadShadow = (Hit)0; + payLoadShadow.instanceID = -1; + + TraceRay(dispatchInfo, accelStruct, instanceMask, ray, rayFlags | kRayFlagForceOpaque | kRayFlagAcceptFirstHitAndEndSearch, payLoadShadow); + + return payLoadShadow.IsValid(); +} + +} // namespace UnifiedRT + +#endif // _UNIFIEDRAYTRACING_TRACERAYANDQUERYHIT_HLSL_ diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl.meta new file mode 100644 index 00000000000..164358d2686 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ff541650e0d7c3146a62582a0bd48d30 diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs index 653157dee79..f49f90f71d0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs @@ -7,7 +7,7 @@ namespace UnityEngine.Rendering.UnifiedRayTracing internal enum UnifiedRayTracingError { Unknown, - OutOfGraphicsBufferMemory, + GraphicsBufferAllocationFailed } internal class UnifiedRayTracingException : Exception diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs.meta index 4ee6400d017..af2556b5299 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs.meta +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/UnifiedRayTracingException.cs.meta @@ -1,2 +1,2 @@ fileFormatVersion: 2 -guid: 269e5f1f89a81184190bcab4e306675b \ No newline at end of file +guid: 9eb26d0567d9108418c5bf72b7b62682 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Unity.UnifiedRayTracing.Runtime.asmdef b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Unity.UnifiedRayTracing.Runtime.asmdef new file mode 100644 index 00000000000..6202ece7e69 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Unity.UnifiedRayTracing.Runtime.asmdef @@ -0,0 +1,26 @@ +{ + "name": "Unity.UnifiedRayTracing.Runtime", + "rootNamespace": "", + "references": [ + "Unity.Mathematics", + "Unity.Collections", + "Unity.Burst" + ], + "includePlatforms": [], + "excludePlatforms": [ + "WebGL" + ], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.assetbundle", + "expression": "1.0.0", + "define": "ENABLE_ASSET_BUNDLE" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Unity.UnifiedRayTracing.Runtime.asmdef.meta b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Unity.UnifiedRayTracing.Runtime.asmdef.meta new file mode 100644 index 00000000000..16aef1075eb --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/Unity.UnifiedRayTracing.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 214c0945bb158c940aada223f3223ee8 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/THIRD PARTY NOTICES.md b/Packages/com.unity.render-pipelines.core/THIRD PARTY NOTICES.md new file mode 100644 index 00000000000..d5211d3d0d2 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/THIRD PARTY NOTICES.md @@ -0,0 +1,77 @@ +This package contains third-party software components governed by the license(s) indicated below: +--------- + +Component Name: RadeonRays 4.1 + +License Type: MIT License + +https://github.com/GPUOpen-LibrariesAndSDKs/RadeonRays_SDK + +Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--------- + +Component Name: Bullet Physics SDK + +License Type: zlib License + +The files in this repository are licensed under the zlib license, except for the files under 'Extras' and examples/ThirdPartyLibs. + +Bullet Continuous Collision Detection and Physics Library +http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +--------- + +Component Name: Sobol sampler + +License Type: MIT License + +https://github.com/lgruen/sobol + +Copyright (c) 2023 Leonhard Gruenschloss + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Packages/com.unity.render-pipelines.core/THIRD PARTY NOTICES.md.meta b/Packages/com.unity.render-pipelines.core/THIRD PARTY NOTICES.md.meta new file mode 100644 index 00000000000..f9d632373ee --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/THIRD PARTY NOTICES.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: eefc64b67f7aad040905b2000990f5f3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing.meta new file mode 100644 index 00000000000..db331f17432 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4e4c297047ea96a49826f1570cf7db07 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs new file mode 100644 index 00000000000..8b56cef9e54 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs @@ -0,0 +1,62 @@ +using NUnit.Framework; +using System; +using UnityEditor; +using System.Runtime.InteropServices; +using Unity.Mathematics; +using Unity.Collections.LowLevel.Unsafe; + +namespace UnityEngine.Rendering.UnifiedRayTracing.Tests +{ + [TestFixture("Compute")] + [TestFixture("Hardware")] + internal class IRayTracingBackendTests + { + readonly RayTracingBackend m_BackendType; + RayTracingResources m_Resources; + IRayTracingBackend m_Backend; + + public IRayTracingBackendTests(string backendAsString) + { + m_BackendType = Enum.Parse(backendAsString); + } + + [SetUp] + public void SetUp() + { + if (!SystemInfo.supportsRayTracing && m_BackendType == RayTracingBackend.Hardware) + { + Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); + } + + if (!SystemInfo.supportsComputeShaders && m_BackendType == RayTracingBackend.Compute) + { + Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); + } + + m_Resources = new RayTracingResources(); + m_Resources.Load(); + + if (m_BackendType == RayTracingBackend.Hardware) + m_Backend = new HardwareRayTracingBackend(m_Resources); + else if (m_BackendType == RayTracingBackend.Compute) + m_Backend = new ComputeRayTracingBackend(m_Resources); + else + Assert.Fail("Invalid backend type"); + } + + [Test] + public void IRayTracingBackend_QueryScratchBufferStride_ShouldGenerateCorrectResult() + { + Assert.AreEqual(4, RayTracingContext.GetScratchBufferStrideInBytes()); + } + + [Test] + public void IRayTracingBackend_QueryScratchBufferSize_ShouldGenerateCorrectResult() + { + if (m_BackendType == RayTracingBackend.Hardware) + Assert.AreEqual(0, m_Backend.GetRequiredTraceScratchBufferSizeInBytes(1, 2, 3)); + else if (m_BackendType == RayTracingBackend.Compute) + Assert.AreEqual(1536, m_Backend.GetRequiredTraceScratchBufferSizeInBytes(1, 2, 3)); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta new file mode 100644 index 00000000000..fcb17d986f7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/APITests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1cee6a301a2297f4aa8e064f8504abc8 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs new file mode 100644 index 00000000000..44bdeb1bed9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs @@ -0,0 +1,263 @@ +using NUnit.Framework; +using System; +using UnityEditor; +using System.Runtime.InteropServices; +using Unity.Mathematics; +using Unity.Collections.LowLevel.Unsafe; + +namespace UnityEngine.Rendering.UnifiedRayTracing.Tests +{ + + [TestFixture("Compute")] + [TestFixture("Hardware")] + internal class AccelStructAdapterTests + { + readonly RayTracingBackend m_Backend; + RayTracingContext m_Context; + AccelStructAdapter m_AccelStruct; + IRayTracingShader m_Shader; + + public AccelStructAdapterTests(string backendAsString) + { + m_Backend = Enum.Parse(backendAsString); + } + + [SetUp] + public void SetUp() + { + if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware) + { + Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); + } + + if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute) + { + Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); + } + + if (SystemInfo.graphicsDeviceName.Contains("llvmpipe")) + { + Assert.Ignore("Cannot run test on this device (Renderer: llvmpipe (LLVM 10.0.0, 128 bits)). Tests are disabled because they fail on some platforms (that do not support 11 SSBOs). Once we do not run Ubuntu 18.04 try removing this"); + } + + CreateRayTracingResources(); + } + + [TearDown] + public void TearDown() + { + DisposeRayTracingResources(); + } + + void RayTraceAndCheckUVs(Mesh mesh, float2 expected, int uvChannel, float tolerance = 0.01f) + { + const int instanceCount = 4; + CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); + + for (int i = 0; i < instanceCount; ++i) + { + m_AccelStruct.AddInstance(i, instanceDescs[i].mesh, instanceDescs[i].localToWorldMatrix, new uint[]{ 0xFFFFFFFF }, new uint[]{ 0xFFFFFFFF }, new bool[] { true }, 1); + } + + HitGeomAttributes[] hitAttributes = null; + var hits = TraceRays(rays, out hitAttributes); + for (int i = 0; i < rays.Length; ++i) + { + Assert.IsTrue(hits[i].Valid(), "Expected ray to hit the mesh."); + float2 uv = uvChannel == 1 ? hitAttributes[i].uv1 : hitAttributes[i].uv0; + Assert.AreEqual(expected.x, uv.x, tolerance, $"Expected x (from uv{uvChannel}) to be fetched correctly in the ray tracing shader."); + Assert.AreEqual(expected.y, uv.y, tolerance, $"Expected y (from uv{uvChannel}) to be fetched correctly in the ray tracing shader."); + } + } + + [Test] + [TestCase(0)] + [TestCase(1)] + public void GeometryPool_MeshWithTwoWideUVs_UVsAreFetchedCorrectly(int uvChannel) + { + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + float x = 100.2f; + float y = -9.3f; + var uvs = new Vector2[] { new Vector2(x, y), new Vector2(x, y), new Vector2(x, y) }; + // Here we use the Vector2 version for setting the UVs on the mesh + mesh.SetUVs(uvChannel, uvs); + RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel); + } + + [Test] + [TestCase(0)] + [TestCase(1)] + public void GeometryPool_MeshWithThreeWideUVs_UVsAreFetchedCorrectly(int uvChannel) + { + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + float x = 100.2f; + float y = -9.3f; + float z = 32.4f; + var uvs = new Vector3[] { new Vector3(x, y, z), new Vector3(x, y, z), new Vector3(x, y, z) }; + // Here we use the Vector3 version for setting the UVs on the mesh + mesh.SetUVs(uvChannel, uvs); + RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel); + } + + [Test] + [TestCase(0)] + [TestCase(1)] + public void GeometryPool_MeshWithFourWideUVs_UVsAreFetchedCorrectly(int uvChannel) + { + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + float x = 100.2f; + float y = -9.3f; + float z = 32.4f; + float w = -12.5f; + var uvs = new Vector4[] { new Vector4(x, y, z, w), new Vector4(x, y, z, w), new Vector4(x, y, z, w) }; + // Here we use the Vector4 version for setting the UVs on the mesh + mesh.SetUVs(uvChannel, uvs); + RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel); + } + + [Test] + [TestCase(0)] + [TestCase(1)] + public void GeometryPool_MeshWithLargeUVValues_UVsAreFetchedCorrectly(int uvChannel) + { + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + float x = 100000.2f; + float y = -900000.3f; + float z = 32000.4f; + float w = -1200000.5f; + var uvs = new Vector4[] { new Vector4(x, y, z, w), new Vector4(x, y, z, w), new Vector4(x, y, z, w) }; + // Here we use the Vector4 version for setting the UVs on the mesh + mesh.SetUVs(uvChannel, uvs); + RayTraceAndCheckUVs(mesh, new float2(x, y), uvChannel, 0.2f); + } + + [Test] + [TestCase(0)] + [TestCase(1)] + public void GeometryPool_MeshWithDifferentVertexUVs_UVsAreInterpolatedCorrectly(int uvChannel) + { + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + float x = 1.0f; + float y = 5.0f; + float z = 7.0f; + var uvs = new Vector4[] { new Vector4(x, x, x, x), new Vector4(y, y, y, y), new Vector4(z, z, z, z) }; + // Here we use the Vector4 version for setting the UVs on the mesh + mesh.SetUVs(uvChannel, uvs); + RayTraceAndCheckUVs(mesh, new float2(4.333f, 4.333f), uvChannel, 0.001f); + } + + void CreateMatchingRaysAndInstanceDescs(uint instanceCount, Mesh mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs) + { + instanceDescs = new MeshInstanceDesc[instanceCount]; + rays = new RayWithFlags[instanceCount]; + var ray = new RayWithFlags(new float3(0.0f, 0.0f, 1.0f), new float3(0.0f, 0.0f, -1.0f)); + float3 step = new float3(2.0f, 0.0f, 0.0f); + + for (int i = 0; i < instanceCount; ++i) + { + instanceDescs[i] = new MeshInstanceDesc(mesh); + instanceDescs[i].localToWorldMatrix = float4x4.Translate(step * i); + + rays[i] = ray; + rays[i].origin += step * i; + } + } + + Hit[] TraceRays(RayWithFlags[] rays, out HitGeomAttributes[] hitAttributes) + { + var bufferTarget = GraphicsBuffer.Target.Structured; + var rayCount = rays.Length; + using var raysBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); + raysBuffer.SetData(rays); + using var hitsBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); + using var attributesBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); + + var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuildAndDispatch(m_AccelStruct.GetAccelerationStructure(), m_Shader, (uint)rayCount, 1, 1); + + var cmd = new CommandBuffer(); + m_AccelStruct.Build(cmd, ref scratchBuffer); + m_AccelStruct.Bind(cmd, "_AccelStruct", m_Shader); + m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Rays"), raysBuffer); + m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Hits"), hitsBuffer); + m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_HitAttributes"), attributesBuffer); + m_Shader.Dispatch(cmd, scratchBuffer, (uint)rayCount, 1, 1); + Graphics.ExecuteCommandBuffer(cmd); + + var hits = new Hit[rayCount]; + hitsBuffer.GetData(hits); + + hitAttributes = new HitGeomAttributes[rayCount]; + attributesBuffer.GetData(hitAttributes); + + scratchBuffer?.Dispose(); + + return hits; + } + + void CreateRayTracingResources() + { + var resources = new RayTracingResources(); + resources.Load(); + + m_Context = new RayTracingContext(m_Backend, resources); + m_AccelStruct = new AccelStructAdapter(m_Context.CreateAccelerationStructure(new AccelerationStructureOptions()), resources); + m_Shader = m_Context.LoadRayTracingShader("Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader"); + } + + void DisposeRayTracingResources() + { + m_AccelStruct?.Dispose(); + m_Context?.Dispose(); + } + + [StructLayout(LayoutKind.Sequential)] + public struct RayWithFlags + { + public float3 origin; + public float minT; + public float3 direction; + public float maxT; + public uint culling; + public uint instanceMask; + uint padding; + uint padding2; + + public RayWithFlags(float3 origin, float3 direction) + { + this.origin = origin; + this.direction = direction; + minT = 0.0f; + maxT = float.MaxValue; + instanceMask = 0xFFFFFFFF; + culling = 0; + padding = 0; + padding2 = 0; + } + } + + [System.Flags] + enum RayCulling { None = 0, CullFrontFace = 0x10, CullBackFace = 0x20 } + + [StructLayout(LayoutKind.Sequential)] + public struct Hit + { + public uint instanceID; + public uint primitiveIndex; + public float2 uvBarycentrics; + public float hitDistance; + public uint isFrontFace; + + public bool Valid() { return instanceID != 0xFFFFFFFF; } + } + + [StructLayout(LayoutKind.Sequential)] + public struct HitGeomAttributes + { + public float3 position; + public float3 normal; + public float3 faceNormal; + public float2 uv0; + public float2 uv1; + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta new file mode 100644 index 00000000000..23d0990967c --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructAdapterTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 355495db5b95855439b77dcb5868f8f7 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs new file mode 100644 index 00000000000..23a6676b844 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs @@ -0,0 +1,722 @@ +using NUnit.Framework; +using System; +using UnityEditor; +using System.Runtime.InteropServices; +using Unity.Mathematics; +using Unity.Collections.LowLevel.Unsafe; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.TestTools; +using UnityEngine.Rendering.RadeonRays; + +namespace UnityEngine.Rendering.UnifiedRayTracing.Tests +{ + internal static class MeshUtil + { + static internal Mesh CreateSingleTriangleMesh(float2 scaling, float3 translation) + { + Mesh mesh = new Mesh(); + + Vector3[] vertices = new Vector3[] + { + (Vector3)translation + new Vector3(0.0f, 0.0f, 0), + (Vector3)translation + new Vector3(1.0f * scaling.x, 0.0f, 0), + (Vector3)translation + new Vector3(0.0f, 1.0f * scaling.y, 0) + }; + mesh.vertices = vertices; + + Vector3[] normals = new Vector3[] + { + -Vector3.forward, + -Vector3.forward, + -Vector3.forward + }; + mesh.normals = normals; + + Vector2[] uv = new Vector2[] + { + new Vector2(0, 1), + new Vector2(1, 1), + new Vector2(0, 0) + }; + mesh.uv = uv; + + int[] tris = new int[3] + { + 0, 2, 1 + }; + mesh.triangles = tris; + + return mesh; + } + + static internal Mesh CreateQuadMesh() + { + Mesh mesh = new Mesh(); + + Vector3[] vertices = new Vector3[] + { + new Vector3(-0.5f, -0.5f, 0.0f), + new Vector3(0.5f, -0.5f, 0.0f), + new Vector3(-0.5f, 0.5f, 0.0f), + new Vector3(0.5f, 0.5f, 0.0f) + }; + mesh.vertices = vertices; + + Vector3[] normals = new Vector3[] + { + -Vector3.forward, + -Vector3.forward, + -Vector3.forward, + -Vector3.forward + }; + mesh.normals = normals; + + Vector2[] uv = new Vector2[] + { + new Vector2(0, 0), + new Vector2(1, 0), + new Vector2(0, 1), + new Vector2(1, 1) + }; + mesh.uv = uv; + + int[] tris = new int[6] + { + 0, 2, 1, + 2, 3, 1 + }; + mesh.triangles = tris; + + return mesh; + } + } + + internal class ComputeRayTracingAccelStructTests + { + static private void AssertFloat3sAreEqual(float3 expected, float3 actual, float tolerance) + { + Assert.AreEqual(expected.x, actual.x, tolerance); + Assert.AreEqual(expected.y, actual.y, tolerance); + Assert.AreEqual(expected.z, actual.z, tolerance); + } + + static private void AssertAABBsAreEqual(float3 expectedMin, float3 expectedMax, float3 actualMin, float3 actualMax, float tolerance) + { + AssertFloat3sAreEqual(expectedMin, actualMin, tolerance); + AssertFloat3sAreEqual(expectedMax, actualMax, tolerance); + } + + [Test] + public void Build_TwoInstancesOfASingleTriangleMesh_ShouldGenerateCorrectResult() + { + var resources = new RayTracingResources(); + resources.Load(); + + using var accelStruct = new ComputeRayTracingAccelStruct( + new AccelerationStructureOptions() { buildFlags = BuildFlags.PreferFastBuild }, + resources, + new ReferenceCounter()); + + uint instanceCount = 2; + + { + var mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.0f, 1.0f), float3.zero); + var globalTranslation = new float3(1.0f, 1.0f, 0.0f); + for (uint i = 0; i < instanceCount; i++) + { + var instanceDesc = new MeshInstanceDesc(mesh); + instanceDesc.localToWorldMatrix = Matrix4x4.Translate(globalTranslation + new float3(2.0f * i, 0.0f, 0.0f)); + accelStruct.AddInstance(instanceDesc); + } + + using var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuild(accelStruct); + using var cmd = new CommandBuffer(); + accelStruct.Build(cmd, scratchBuffer); + Graphics.ExecuteCommandBuffer(cmd); + Object.DestroyImmediate(mesh); + } + + var tolerance = 0.001f; + { + // Verify bottom level BVH. + uint expectedTotalNodeCount = 1; + var bottomLevelNodes = new BvhNode[(int)expectedTotalNodeCount + 1]; // plus one for header + accelStruct.bottomLevelBvhBuffer.GetData(bottomLevelNodes); + + var header = UnsafeUtility.As(ref bottomLevelNodes[0]); + Assert.AreEqual(expectedTotalNodeCount, header.internalNodeCount + header.leafNodeCount); + Assert.AreEqual(1, header.leafNodeCount); + Assert.AreEqual(expectedTotalNodeCount, header.internalNodeCount + header.leafNodeCount); + AssertAABBsAreEqual(new float3(0.0f, 0.0f, 0.0f), new float3(1.0f, 1.0f, 0.0f), header.globalAabbMin, header.globalAabbMax, tolerance); + } + + { + // Verify top level BVH. + uint expectedInternalNodeCount = instanceCount - 1; + uint expectedLeafNodeCount = instanceCount; + var topLevelNodes = new BvhNode[(int)expectedInternalNodeCount + 1]; // plus one for header + accelStruct.topLevelBvhBuffer.GetData(topLevelNodes); + + var header = UnsafeUtility.As(ref topLevelNodes[0]); + Assert.AreEqual(expectedInternalNodeCount, header.internalNodeCount); + Assert.AreEqual(expectedLeafNodeCount, header.leafNodeCount); + + AssertAABBsAreEqual(new float3(1.0f, 1.0f, 0.0f), new float3(4.0f, 2.0f, 0.0f), header.globalAabbMin, header.globalAabbMax, tolerance); + + var instanceBvhRoot = topLevelNodes[1]; + Assert.AreEqual(0u | (1u << 31), instanceBvhRoot.child0); // MSB is set for leaf node indices + Assert.AreEqual(1u | (1u << 31), instanceBvhRoot.child1); + AssertAABBsAreEqual(new float3(1.0f, 1.0f, 0.0f), new float3(2.0f, 2.0f, 0.0f), instanceBvhRoot.aabb0_min, instanceBvhRoot.aabb0_max, tolerance); + AssertAABBsAreEqual(new float3(3.0f, 1.0f, 0.0f), new float3(4.0f, 2.0f, 0.0f), instanceBvhRoot.aabb1_min, instanceBvhRoot.aabb1_max, tolerance); + } + } + + [Test] + [Ignore("Test too unstable on Yamato (UUM-95662, UUM-67382)")] + public void AddInstance_MeshWith2GBWorthOfVertices_Throws() + { + var resources = new RayTracingResources(); + resources.Load(); + + using var accelStruct = new ComputeRayTracingAccelStruct( + new AccelerationStructureOptions() { buildFlags = BuildFlags.PreferFastBuild }, + resources, + new ReferenceCounter()); + + Random.InitState(1987); + + int vertexCount = 200000001; // 200 millions + int indexCount = vertexCount; // must be a multiple of 3 + + Mesh mesh = new Mesh(); + mesh.indexFormat = IndexFormat.UInt32; + + Vector3[] vertices = new Vector3[vertexCount]; + for (int i = 0; i < vertexCount; ++i) + { + vertices[i] = new Vector3(0.0f, 0.0f, Random.Range(0.0f, 1.0f)); + } + mesh.SetVertices(vertices); + + Vector3[] normals = new Vector3[vertexCount]; + mesh.SetNormals(normals); + + Vector2[] uv = new Vector2[vertexCount]; + mesh.SetUVs(0, uv); + + int[] tris = new int[indexCount]; + for (int i = 0; i < indexCount; ++i) + tris[i] = i; + + mesh.SetIndices(tris, MeshTopology.Triangles, 0); + + MeshInstanceDesc instanceDesc = new MeshInstanceDesc(mesh); + Assert.Throws(() => accelStruct.AddInstance(instanceDesc)); + + Assert.That(accelStruct.m_BlasAllocator.allocatedSize, Is.Zero); + Assert.That(accelStruct.m_BlasLeavesAllocator.allocatedSize, Is.Zero); + } + } + + + internal class AccelStructTestsBase + { + readonly protected RayTracingBackend m_Backend; + protected RayTracingContext m_Context; + protected RayTracingResources m_Resources; + protected IRayTracingAccelStruct m_AccelStruct; + protected IRayTracingShader m_Shader; + + public AccelStructTestsBase(string backendAsString) + { + m_Backend = Enum.Parse(backendAsString); + } + + protected void CreateRayTracingResources(string shaderFilename) + { + if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware) + { + Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); + } + + if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute) + { + Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); + } + + if (SystemInfo.graphicsDeviceName.Contains("llvmpipe")) + { + Assert.Ignore("Cannot run test on this device (Renderer: llvmpipe (LLVM 10.0.0, 128 bits)). Tests are disabled because they fail on some platforms (that do not support 11 SSBOs). Once we do not run Ubuntu 18.04 try removing this"); + } + + m_Resources = new RayTracingResources(); + m_Resources.Load(); + + m_Context = new RayTracingContext(m_Backend, m_Resources); + m_AccelStruct = m_Context.CreateAccelerationStructure(new AccelerationStructureOptions()); + m_Shader = m_Context.LoadRayTracingShader("Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/" + shaderFilename); + } + + protected void DisposeRayTracingResources() + { + m_AccelStruct?.Dispose(); + m_Context?.Dispose(); + } + + protected THit[] TraceRays(RayWithFlags[] rays, AnyHitDecision anyHitDecision = AnyHitDecision.Invalid) + { + var bufferTarget = GraphicsBuffer.Target.Structured; + var rayCount = rays.Length; + using var raysBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); + raysBuffer.SetData(rays); + using var hitsBuffer = new GraphicsBuffer(bufferTarget, rayCount, Marshal.SizeOf()); + + using var scratchBuffer = RayTracingHelper.CreateScratchBufferForBuildAndDispatch(m_AccelStruct, m_Shader, (uint)rayCount, 1, 1); + + var cmd = new CommandBuffer(); + m_AccelStruct.Build(cmd, scratchBuffer); + + if (anyHitDecision != AnyHitDecision.Invalid) + m_Shader.SetIntParam(cmd, Shader.PropertyToID("_AnyHitDecision"), (int)anyHitDecision); + + m_Shader.SetAccelerationStructure(cmd, "_AccelStruct", m_AccelStruct); + m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Rays"), raysBuffer); + m_Shader.SetBufferParam(cmd, Shader.PropertyToID("_Hits"), hitsBuffer); + m_Shader.Dispatch(cmd, scratchBuffer, (uint)rayCount, 1, 1); + Graphics.ExecuteCommandBuffer(cmd); + + var hits = new THit[rayCount]; + hitsBuffer.GetData(hits); + + return hits; + } + + [StructLayout(LayoutKind.Sequential)] + public struct RayWithFlags + { + public float3 origin; + public float minT; + public float3 direction; + public float maxT; + public uint culling; + public uint instanceMask; + uint padding; + uint padding2; + + public RayWithFlags(float3 origin, float3 direction) + { + this.origin = origin; + this.direction = direction; + minT = 0.0f; + maxT = float.MaxValue; + instanceMask = 0xFFFFFFFF; + culling = 0; + padding = 0; + padding2 = 0; + } + } + + protected enum AnyHitDecision { Invalid = -1, IgnoreHit = 0, AcceptHit = 1, AcceptHitAndEndSearch = 2 }; + + [System.Flags] + protected enum RayFlags { None = 0, ForceOpaque = 0x01, ForceNonOpaque = 0x02, AcceptFirstHitAndEndSearch = 0x04, SkipClosestHit = 0x08, CullBackFace = 0x10, CullFrontFace = 0x20, CullOpaque = 0x40, CullNonOpaque = 0x80 } + } + + + [TestFixture("Compute")] + [TestFixture("Hardware")] + internal class AccelStructTests : AccelStructTestsBase + { + public AccelStructTests(string backendAsString) : base(backendAsString) + { + } + + [SetUp] + public void SetUp() + { + CreateRayTracingResources("TraceRays.urtshader"); + } + + [TearDown] + public void TearDown() + { + DisposeRayTracingResources(); + } + + [Test] + public void RayTracePixelsInUnitQuad([Values(1, 10, 100)] int rayResolution, [Values(0, 1, 2, 3)] int buildFlagsAsInteger) + { + var buildFlags = (BuildFlags)buildFlagsAsInteger; // We do this ugly but simple cast hack because the BuildFlags type is not public as time of this writing (test methods must be public and so must their argument types). + + // re-create the acceleration structure with suitable options + m_AccelStruct?.Dispose(); + var options = new AccelerationStructureOptions() { buildFlags = buildFlags }; + m_AccelStruct = m_Context.CreateAccelerationStructure(options); + + Mesh mesh = MeshUtil.CreateQuadMesh(); + + var instanceDesc = new MeshInstanceDesc(mesh); + instanceDesc.localToWorldMatrix = Matrix4x4.identity; + instanceDesc.localToWorldMatrix.SetTRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.identity, new Vector3(1.0f, 1.0f, 1.0f)); + instanceDesc.enableTriangleCulling = false; + instanceDesc.frontTriangleCounterClockwise = true; + m_AccelStruct.AddInstance(instanceDesc); + + // trace N*N rays towards the quad and expect to hit it + int N = rayResolution; + var rays = new RayWithFlags[N * N]; + int rayI = 0; + for (int v = 0; v < N; ++v) + { + for (int u = 0; u < N; ++u) + { + float2 uv = new float2((float)u, (float)v); + uv += 0.5f; + uv /= N; + float3 origin = new float3(uv.x, uv.y, 1.0f); + float3 direction = new float3(0.0f, 0.0f, -1.0f); + rays[rayI] = new RayWithFlags(origin, direction); + rays[rayI].culling = (uint)RayFlags.None; + rayI++; + } + } + + var hits = TraceRays(rays); + for (int i = 0; i < hits.Length; ++i) + { + Assert.IsTrue(hits[i].Valid(), $"Expected all rays to hit the quad but ray {i} missed."); + } + } + + [Test] + public void FrontOrBackFaceCulling() + { + const int instanceCount = 4; + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); + + var raysDuplicated = new RayWithFlags[instanceCount * 3]; + Array.Copy(rays, 0, raysDuplicated, 0, instanceCount); + Array.Copy(rays, 0, raysDuplicated, instanceCount, instanceCount); + Array.Copy(rays, 0, raysDuplicated, 2 * instanceCount, instanceCount); + + for (int i = 0; i < instanceCount; ++i) + { + raysDuplicated[i].culling = (uint)RayFlags.None; + raysDuplicated[i + instanceCount].culling = (uint)RayFlags.CullBackFace; + raysDuplicated[i + instanceCount * 2].culling = (uint)RayFlags.CullFrontFace; + } + + instanceDescs[0].enableTriangleCulling = false; + instanceDescs[0].frontTriangleCounterClockwise = true; + + instanceDescs[1].enableTriangleCulling = false; + instanceDescs[1].frontTriangleCounterClockwise = false; + + instanceDescs[2].enableTriangleCulling = true; + instanceDescs[2].frontTriangleCounterClockwise = true; + + instanceDescs[3].enableTriangleCulling = true; + instanceDescs[3].frontTriangleCounterClockwise = false; + + for (int i = 0; i < instanceCount; ++i) + { + m_AccelStruct.AddInstance(instanceDescs[i]); + } + + var hits = TraceRays(raysDuplicated); + // No culling + Assert.IsTrue(hits[0].Valid()); + Assert.IsTrue(hits[1].Valid()); + Assert.IsTrue(hits[2].Valid()); + Assert.IsTrue(hits[3].Valid()); + + // FrontFace culling + Assert.IsTrue(hits[4].Valid()); + Assert.IsTrue(hits[5].Valid()); + Assert.IsTrue(hits[6].Valid()); + Assert.IsTrue(!hits[7].Valid()); + + // BackFace culling + Assert.IsTrue(hits[8].Valid()); + Assert.IsTrue(hits[9].Valid()); + Assert.IsTrue(!hits[10].Valid()); + Assert.IsTrue(hits[11].Valid()); + + + } + + + [Test] + public void InstanceAndRayMask() + { + const int instanceCount = 8; + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); + + var rayAndInstanceMasks = new (uint instanceMask, uint rayMask)[] + { + (0, 0), + (0xFFFFFFFF, 0xFFFFFFFF), + (0, 0xFFFFFFFF), + (0xFFFFFFFF, 0), + (0x0F, 0x01), + (0x0F, 0xF0), + (0x90, 0xF0), + (0xF0, 0x10), + }; + + for (int i = 0; i < instanceCount; ++i) + { + instanceDescs[i].mask = rayAndInstanceMasks[i].instanceMask; + rays[i].instanceMask = rayAndInstanceMasks[i].rayMask; + } + + for (int i = 0; i < instanceCount; ++i) + { + m_AccelStruct.AddInstance(instanceDescs[i]); + } + + var hits = TraceRays(rays); + + for (int i = 0; i < instanceCount; ++i) + { + bool rayShouldHit = ((rayAndInstanceMasks[i].instanceMask & rayAndInstanceMasks[i].rayMask) != 0); + bool rayHit = hits[i].Valid(); + + var message = String.Format("Ray {0} hit for InstanceMask: 0x{1:X} & RayMask: 0x{2:X}", + rayShouldHit ? "should" : "shouldn't", + rayAndInstanceMasks[i].instanceMask, + rayAndInstanceMasks[i].rayMask); + + Assert.AreEqual(rayShouldHit, rayHit, message); + } + } + + [Test] + public void AddAndRemoveInstances() + { + const int instanceCount = 4; + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + CreateMatchingRaysAndInstanceDescs(instanceCount, mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs); + + var instanceHandles = new int[instanceCount]; + var expectedVisibleInstances = new bool[instanceCount]; + + for (int i = 0; i < instanceCount; ++i) + { + instanceHandles[i] = m_AccelStruct.AddInstance(instanceDescs[i]); + expectedVisibleInstances[i] = true; + } + + CheckVisibleInstances(rays, expectedVisibleInstances); + + m_AccelStruct.RemoveInstance(instanceHandles[0]); expectedVisibleInstances[0] = false; + m_AccelStruct.RemoveInstance(instanceHandles[2]); expectedVisibleInstances[2] = false; + + CheckVisibleInstances(rays, expectedVisibleInstances); + + m_AccelStruct.ClearInstances(); + + Array.Fill(expectedVisibleInstances, false); + + CheckVisibleInstances(rays, expectedVisibleInstances); + + m_AccelStruct.AddInstance(instanceDescs[3]); + expectedVisibleInstances[3] = true; + + CheckVisibleInstances(rays, expectedVisibleInstances); + } + + private void AddTerrainToAccelerationStructure(int heightmapResolution) + { + Terrain.CreateTerrainGameObject(new TerrainData()); + Terrain terrain = GameObject.FindFirstObjectByType(); + Assert.NotNull(terrain); + + // Set terrain texture resolution on terrain data. + terrain.terrainData.heightmapResolution = heightmapResolution; + + // Convert to mesh. + AsyncTerrainToMeshRequest request = TerrainToMesh.ConvertAsync(terrain); + request.WaitForCompletion(); + + // Add the terrain to the acceleration structure. + MeshInstanceDesc instanceDesc = new MeshInstanceDesc(request.GetMesh()); + instanceDesc.localToWorldMatrix = float4x4.identity; + m_AccelStruct.AddInstance(instanceDesc); + } + + [Test] + public void Add_1KTerrain_Works() + { + AddTerrainToAccelerationStructure(1025); + } + + [Test] + [Ignore("This test is disabled because of the allocation limitation of 2 GB in GraphicsBuffer.")] + public void Add_4KTerrain_Works() + { + AddTerrainToAccelerationStructure(4097); + } + + void CheckVisibleInstances(RayWithFlags[] rays, bool[] expectedVisibleInstances) + { + var hits = TraceRays(rays); + for (int i = 0; i < rays.Length; ++i) + { + Assert.AreEqual(expectedVisibleInstances[i], hits[i].Valid(), $"Unexpected state of intersection with instance {i}"); + } + } + + void CreateMatchingRaysAndInstanceDescs(uint instanceCount, Mesh mesh, out RayWithFlags[] rays, out MeshInstanceDesc[] instanceDescs) + { + instanceDescs = new MeshInstanceDesc[instanceCount]; + rays = new RayWithFlags[instanceCount]; + var ray = new RayWithFlags(new float3(0.0f, 0.0f, 1.0f), new float3(0.0f, 0.0f, -1.0f)); + float3 step = new float3(2.0f, 0.0f, 0.0f); + + for (int i = 0; i < instanceCount; ++i) + { + instanceDescs[i] = new MeshInstanceDesc(mesh); + instanceDescs[i].localToWorldMatrix = float4x4.Translate(step * i); + + rays[i] = ray; + rays[i].origin += step * i; + } + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Hit + { + public uint instanceID; + public uint primitiveIndex; + public float2 uvBarycentrics; + public float hitDistance; + public uint isFrontFace; + + public bool Valid() { return instanceID != 0xFFFFFFFF; } + } + + } + + [TestFixture("Compute")] + [TestFixture("Hardware")] + internal class AccelStructTransparencyTests : AccelStructTestsBase + { + public AccelStructTransparencyTests(string backendAsString) : base(backendAsString) + { + } + + [SetUp] + public void SetUp() + { + CreateRayTracingResources("TraceTransparentRays.urtshader"); + } + + [TearDown] + public void TearDown() + { + DisposeRayTracingResources(); + } + + + [Test] + public void WithTransparentInstances_ClosestAndAnyHitsFuncsAreCalled() + { + Mesh mesh = MeshUtil.CreateSingleTriangleMesh(new float2(1.5f, 1.5f), new float3(-0.5f, -0.5f, 0.0f)); + + var isOpaque = new bool[] { false, false, true, false, false, false, true, false }; + for (int i = 0; i < isOpaque.Length; ++i) + { + var instanceDesc = new MeshInstanceDesc(mesh); + instanceDesc.localToWorldMatrix = float4x4.Translate(new float3(0.0f, 0.0f, 2.0f) * i); + instanceDesc.opaqueGeometry = isOpaque[i]; + instanceDesc.instanceID = (uint)i; + + m_AccelStruct.AddInstance(instanceDesc); + } + + { + var testCases = new TransparencyTestCase[] { + new(RayFlags.None, 2, new int[] { 0, 1 }), + new(RayFlags.ForceOpaque, 0, new int[] { }), + new(RayFlags.ForceNonOpaque, -1, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }), + new(RayFlags.CullOpaque, -1, new int[] { 0, 1, 3, 4, 5, 7 }), + new(RayFlags.CullNonOpaque, 2, new int[] { }), + new(RayFlags.CullOpaque | RayFlags.SkipClosestHit, -1, new int[] { 0, 1, 3, 4, 5, 7 }), + new(RayFlags.AcceptFirstHitAndEndSearch, 2, new int[] { 0, 1 }), + new(RayFlags.ForceNonOpaque | RayFlags.AcceptFirstHitAndEndSearch, -1, new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }), + }; + + TestTransparentInstances(testCases, AnyHitDecision.IgnoreHit); + } + + { + var testCases = new TransparencyTestCase[] { + new(RayFlags.None, 0, new int[] { 0 }), + new(RayFlags.ForceOpaque, 0, new int[] { }), + new(RayFlags.ForceNonOpaque, 0, new int[] { 0 }), + new(RayFlags.CullOpaque, 0, new int[] { 0 }), + new(RayFlags.CullNonOpaque, 2, new int[] { }), + new(RayFlags.CullOpaque | RayFlags.SkipClosestHit, -1, new int[] { 0 }), + new(RayFlags.AcceptFirstHitAndEndSearch, 0, new int[] { 0 }), + new(RayFlags.ForceNonOpaque | RayFlags.AcceptFirstHitAndEndSearch, 0, new int[] { 0 }), + }; + + TestTransparentInstances(testCases, AnyHitDecision.AcceptHit); + TestTransparentInstances(testCases, AnyHitDecision.AcceptHitAndEndSearch); + } + } + + void TestTransparentInstances(TransparencyTestCase[] testCases, AnyHitDecision anyHitDecision) + { + var expectedResults = new List(); + var rayWithFlags = new List(); + + foreach (var testCase in testCases) + { + var ray = new RayWithFlags(new float3(0.0f, 0.0f, -1.0f), new float3(0.0f, 0.0f, 1.0f)); + ray.culling = (uint)testCase.rayFlags; + rayWithFlags.Add(ray); + + expectedResults.Add(testCase.expectedResult); + } + + var hits = TraceRays(rayWithFlags.ToArray(), anyHitDecision); + + for (int i = 0; i < testCases.Length; ++i) + { + Assert.AreEqual(testCases[i].expectedResult.closestHit, hits[i].closestHit, $"Unexpected closestHit with RayFlags=[{(RayFlags)rayWithFlags[i].culling}] and AnyHitDecision=[{anyHitDecision}]"); + Assert.AreEqual(testCases[i].expectedResult.anyHits, hits[i].anyHits, $"Unexpected anyHits with RayFlags=[{(RayFlags)rayWithFlags[i].culling}] and AnyHitDecision=[{anyHitDecision}]"); + } + } + + + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct TransparentRayResult + { + public uint anyHits; + public int closestHit; + } + + struct TransparencyTestCase + { + public TransparencyTestCase(RayFlags flags, int expectedClosestHit, int[] expectedAnyHitInvocations) + { + rayFlags = flags; + + expectedResult.closestHit = expectedClosestHit; + expectedResult.anyHits = 0; + for (int i = 0; i < expectedAnyHitInvocations.Length; ++i) + expectedResult.anyHits |= (1u << expectedAnyHitInvocations[i]); + } + + public RayFlags rayFlags; + public TransparentRayResult expectedResult; + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta new file mode 100644 index 00000000000..686c2868621 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/AccelStructTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 907dea72c9efc834499557d581dbc45a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/BlockAllocatorTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/BlockAllocatorTests.cs new file mode 100644 index 00000000000..465169c0563 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/BlockAllocatorTests.cs @@ -0,0 +1,54 @@ +using NUnit.Framework; +using System; +using UnityEditor; +using System.Runtime.InteropServices; +using Unity.Mathematics; +using Unity.Collections.LowLevel.Unsafe; +using UnityEngine.Rendering.RadeonRays; + +namespace UnityEngine.Rendering.UnifiedRayTracing.Tests +{ + internal class BlockAllocatorTests + { + [Test] + public void GrowAndAllocate_NotEnoughSpace_ShouldFail() + { + var allocator = new BlockAllocator(); + allocator.Initialize(500); + for (int i = 0; i < 50; i++) + { + var a = allocator.Allocate(2); + Assert.IsTrue(a.valid); + } + + int oldCapacity; + int newCapacity; + + var alloc = allocator.GrowAndAllocate(500, 300, out oldCapacity, out newCapacity); + Assert.IsFalse(alloc.valid); + + alloc = allocator.GrowAndAllocate(500, 600, out oldCapacity, out newCapacity); + Assert.IsTrue(alloc.valid); + + alloc = allocator.GrowAndAllocate(2, 600, out oldCapacity, out newCapacity); + Assert.IsFalse(alloc.valid); + } + + [Test] + public void GrowAndAllocate_NotEnoughSpaceMaxInt_ShouldFail() + { + var allocator = new BlockAllocator(); + allocator.Initialize(int.MaxValue); + var a = allocator.Allocate(int.MaxValue / 2); + + int oldCapacity; + int newCapacity; + + var alloc = allocator.GrowAndAllocate(3, int.MaxValue, out oldCapacity, out newCapacity); + Assert.IsTrue(alloc.valid); + + alloc = allocator.GrowAndAllocate(int.MaxValue / 2, int.MaxValue, out oldCapacity, out newCapacity); + Assert.IsFalse(alloc.valid); + } +} +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/BlockAllocatorTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/BlockAllocatorTests.cs.meta new file mode 100644 index 00000000000..948a39bd745 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/BlockAllocatorTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6e0bf59629e30a243ba9535c7ed91f54 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs new file mode 100644 index 00000000000..f7a8bf6055a --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs @@ -0,0 +1,175 @@ +using System; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace UnityEngine.Rendering.UnifiedRayTracing.Tests +{ + [TestFixture("Compute")] + [TestFixture("Hardware")] + internal class InvalidInputsTests + { + readonly RayTracingBackend m_Backend; + RayTracingContext m_Context; + RayTracingResources m_Resources; + IRayTracingAccelStruct m_AccelStruct; + IRayTracingShader m_Shader; + + [Flags] + enum MeshField { Positions=1, Normals=2, Uvs=4, Indices=8 } + + static Mesh CreateSingleTriangleMesh(MeshField fields) + { + Mesh mesh = new Mesh(); + + if ((fields & MeshField.Positions) != 0) + { + Vector3[] vertices = new Vector3[] + { + new Vector3(1.0f, 0.0f, 0), + new Vector3(0.0f, 0.0f, 0), + new Vector3(0.0f, 0.0f, 0) + }; + mesh.vertices = vertices; + } + + + if ((fields & MeshField.Normals) != 0) + { + Vector3[] normals = new Vector3[] + { + -Vector3.forward, + -Vector3.forward, + -Vector3.forward + }; + mesh.normals = normals; + } + + if ((fields & MeshField.Uvs) != 0) + { + Vector2[] uv = new Vector2[] + { + new Vector2(0, 1), + new Vector2(1, 1), + new Vector2(0, 0) + }; + mesh.uv = uv; + } + + if ((fields & MeshField.Indices) != 0) + { + int[] tris = new int[3] + { + 0, 2, 1 + }; + mesh.triangles = tris; + } + + return mesh; + } + + public InvalidInputsTests(string backendAsString) + { + m_Backend = Enum.Parse(backendAsString); + } + + [SetUp] + public void SetUp() + { + if (!SystemInfo.supportsRayTracing && m_Backend == RayTracingBackend.Hardware) + Assert.Ignore("Cannot run test on this Graphics API. Hardware RayTracing is not supported"); + + + if (!SystemInfo.supportsComputeShaders && m_Backend == RayTracingBackend.Compute) + Assert.Ignore("Cannot run test on this Graphics API. Compute shaders are not supported"); + + m_Resources = new RayTracingResources(); + m_Resources.Load(); + + m_Context = new RayTracingContext(m_Backend, m_Resources); + m_AccelStruct = m_Context.CreateAccelerationStructure(new AccelerationStructureOptions() { useCPUBuild = false }); + m_Shader = m_Context.LoadRayTracingShader("Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader"); + } + + [TearDown] + public void TearDown() + { + m_AccelStruct?.Dispose(); + m_Context?.Dispose(); + } + + + [Test] + public void AccelStruct_AddInstance_ThrowOnNullMesh() + { + var instanceDesc = new MeshInstanceDesc(null); + Assert.Throws(() => m_AccelStruct.AddInstance(instanceDesc)); + } + + [Test] + public void AccelStruct_AddInstance_ThrowOnMeshWithNoPositions() + { + var mesh = new Mesh(); + var instanceDesc = new MeshInstanceDesc(mesh); + Assert.Throws(() => m_AccelStruct.AddInstance(instanceDesc)); + } + + [Test] + public void AccelStruct_AddInstance_ThrowOnInvalidSubmeshIndex() + { + var mesh = CreateSingleTriangleMesh(MeshField.Positions | MeshField.Indices | MeshField.Normals | MeshField.Uvs); + var instanceDesc = new MeshInstanceDesc(mesh); + instanceDesc.subMeshIndex = -1; + Assert.Throws(() => m_AccelStruct.AddInstance(instanceDesc)); + } + + [Test] + public void AccelStruct_AddInstance_ThrowOnInvalidInstanceHandle() + { + var mesh = CreateSingleTriangleMesh(MeshField.Positions | MeshField.Indices | MeshField.Normals | MeshField.Uvs); + var instanceDesc = new MeshInstanceDesc(mesh); + var handle = m_AccelStruct.AddInstance(instanceDesc); + Assert.Throws(() => m_AccelStruct.RemoveInstance(handle + 1)); + + m_AccelStruct.ClearInstances(); + Assert.Throws(() => m_AccelStruct.RemoveInstance(handle)); + } + + [Test] + public void RayTracingShader_SetFloatParam_ThrowOnNullCmdBuffer() + { + Assert.Throws(() => m_Shader.SetFloatParam(null, 0, 1.0f)); + } + + [Test] + public void RayTracingShader_Dispatch_ThrowOnSmallScratchBuffer() + { + if (m_Backend == RayTracingBackend.Hardware) + { + Assert.Ignore("scratch buffer is lawfully null with hardware backend"); + return; + } + + using GraphicsBuffer scratch = new GraphicsBuffer(GraphicsBuffer.Target.Structured, 10, 4); + using CommandBuffer cmd = new CommandBuffer(); + var except = Assert.Throws(() => m_Shader.Dispatch(cmd, scratch, 20, 20, 20)); + Assert.That(except.Message, Does.Contain("scratch")); + } + + [Test] + public void RayTracingShader_Dispatch_ThrowOnScratchBufferWithInvalidTarget() + { + if (m_Backend == RayTracingBackend.Hardware) + { + Assert.Ignore("scratch buffer is lawfully null with hardware backend"); + return; + } + + using GraphicsBuffer scratch = new GraphicsBuffer(GraphicsBuffer.Target.Raw, 20*20*20*100, 4); + using CommandBuffer cmd = new CommandBuffer(); + var except = Assert.Throws(() => m_Shader.Dispatch(cmd, scratch, 20, 20, 20)); + Assert.That(except.Message, Does.Contain("target")); + } + + } +} + diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta new file mode 100644 index 00000000000..fae7e4e9083 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/InvalidInputsTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: dd65df3631672c9449ce603e84743fd9 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader new file mode 100644 index 00000000000..3db863cbcf5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader @@ -0,0 +1,38 @@ +#define UNIFIED_RT_GROUP_SIZE_X 16 +#define UNIFIED_RT_GROUP_SIZE_Y 8 +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl" + +UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); + +struct RayWithFlags +{ + float3 origin; + float tMin; + float3 direction; + float tMax; + uint culling; + uint instanceMask; + uint padding; + uint padding2; +}; + + + +StructuredBuffer _Rays; +RWStructuredBuffer _Hits; + + +void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) +{ + RayWithFlags rayWithFlags = _Rays[dispatchInfo.globalThreadIndex]; + UnifiedRT::Ray ray; + ray.origin = rayWithFlags.origin; + ray.direction = rayWithFlags.direction; + ray.tMin = rayWithFlags.tMin; + ray.tMax = rayWithFlags.tMax; + + UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); + UnifiedRT::Hit hitResult = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, rayWithFlags.instanceMask, ray, rayWithFlags.culling); + + _Hits[dispatchInfo.globalThreadIndex] = hitResult; +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta new file mode 100644 index 00000000000..1b9e032ae42 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRays.urtshader.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1142bbad8b9e8c44c83a9775ff120d37 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader new file mode 100644 index 00000000000..f02b22e9f87 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader @@ -0,0 +1,48 @@ +#define UNIFIED_RT_GROUP_SIZE_X 16 +#define UNIFIED_RT_GROUP_SIZE_Y 8 +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/FetchGeometry.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRayAndQueryHit.hlsl" + +UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); + +struct RayWithFlags +{ + float3 origin; + float tMin; + float3 direction; + float tMax; + uint culling; + uint instanceMask; + uint padding; + uint padding2; +}; + +StructuredBuffer _Rays; +RWStructuredBuffer _Hits; +RWStructuredBuffer _HitAttributes; + +void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) +{ + + RayWithFlags rayWithFlags = _Rays[dispatchInfo.globalThreadIndex]; + UnifiedRT::Ray ray; + ray.origin = rayWithFlags.origin; + ray.direction = rayWithFlags.direction; + ray.tMin = rayWithFlags.tMin; + ray.tMax = rayWithFlags.tMax; + + UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); + UnifiedRT::Hit hitResult = UnifiedRT::TraceRayClosestHit(dispatchInfo, accelStruct, rayWithFlags.instanceMask, ray, rayWithFlags.culling); + if (hitResult.IsValid()) + { + UnifiedRT::HitGeomAttributes hitAttribs = UnifiedRT::FetchHitGeomAttributes(hitResult); + _HitAttributes[dispatchInfo.globalThreadIndex] = hitAttribs; + } + else + { + _HitAttributes[dispatchInfo.globalThreadIndex] = (UnifiedRT::HitGeomAttributes)0; + } + + + _Hits[dispatchInfo.globalThreadIndex] = hitResult; +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta new file mode 100644 index 00000000000..8ab85f8e486 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceRaysAndFetchAttributes.urtshader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fbc59f55df2416344b008dc23753cae2 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 42d537a8a4089e448a99fc57a06d74a9, type: 3} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader new file mode 100644 index 00000000000..03686c9de4d --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader @@ -0,0 +1,65 @@ +#define UNIFIED_RT_GROUP_SIZE_X 16 +#define UNIFIED_RT_GROUP_SIZE_Y 8 +#define UNIFIED_RT_PAYLOAD RayPayload +#define UNIFIED_RT_RAYGEN_FUNC RayGenExecute +#define UNIFIED_RT_CLOSESTHIT_FUNC ClosestHitExecute +#define UNIFIED_RT_ANYHIT_FUNC AnyHitExecute + +struct RayPayload +{ + uint anyHits; + int closestHit; +}; + +#include "Packages/com.unity.render-pipelines.core/Runtime/UnifiedRayTracing/TraceRay.hlsl" + +int _AnyHitDecision; + +uint AnyHitExecute(UnifiedRT::HitContext hitContext, inout RayPayload payload) +{ + payload.anyHits |= (1 << hitContext.InstanceID()); + + return _AnyHitDecision; +} + +void ClosestHitExecute(UnifiedRT::HitContext hitContext, inout RayPayload payload) +{ + payload.closestHit = hitContext.InstanceID(); +} + +UNIFIED_RT_DECLARE_ACCEL_STRUCT(_AccelStruct); + +struct RayWithFlags +{ + float3 origin; + float tMin; + float3 direction; + float tMax; + uint culling; + uint instanceMask; + uint padding; + uint padding2; +}; + +StructuredBuffer _Rays; +RWStructuredBuffer _Hits; + + +void RayGenExecute(UnifiedRT::DispatchInfo dispatchInfo) +{ + RayWithFlags rayWithFlags = _Rays[dispatchInfo.globalThreadIndex]; + UnifiedRT::Ray ray; + ray.origin = rayWithFlags.origin; + ray.direction = rayWithFlags.direction; + ray.tMin = rayWithFlags.tMin; + ray.tMax = rayWithFlags.tMax; + + UnifiedRT::RayTracingAccelStruct accelStruct = UNIFIED_RT_GET_ACCEL_STRUCT(_AccelStruct); + + RayPayload rayPayload = (RayPayload)0; + rayPayload.closestHit = -1; + UnifiedRT::TraceRay(dispatchInfo, accelStruct, 0xFFFFFFFF, ray, rayWithFlags.culling, rayPayload); + + _Hits[dispatchInfo.globalThreadIndex] = rayPayload; +} + diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta new file mode 100644 index 00000000000..f90fde8a674 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/TraceTransparentRays.urtshader.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6513c3b892e933c4f8d00c19d5c47532 diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.Tests.asmdef b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.Tests.asmdef new file mode 100644 index 00000000000..8c170851b27 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.Tests.asmdef @@ -0,0 +1,24 @@ +{ + "name": "Unity.UnifiedRayTracing.Editor.Tests", + "rootNamespace": "", + "references": [ + "GUID:d8b63aba1907145bea998dd612889d6b", + "GUID:df380645f10b7bc4b97d4f5eb6303d95", + "GUID:214c0945bb158c940aada223f3223ee8" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.Tests.asmdef.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.Tests.asmdef.meta new file mode 100644 index 00000000000..6e56e53fc0c --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/UnifiedRayTracing/Unity.UnifiedRayTracing.Editor.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cb16ddcad9e86c047a91282ca9c48140 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json b/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json index 11617591923..33ab7fed88e 100644 --- a/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BatchRendererGroup_HDRP/Packages/manifest.json @@ -13,7 +13,6 @@ "com.unity.ide.visualstudio": "2.0.1", "com.unity.mathematics": "1.2.1", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", "com.unity.render-pipelines.high-definition-config": "file:../../../../../Packages/com.unity.render-pipelines.high-definition-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", diff --git a/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json b/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json index d87a15c9561..a2046f5e69d 100644 --- a/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BatchRendererGroup_URP/Packages/manifest.json @@ -13,7 +13,6 @@ "com.unity.ide.visualstudio": "2.0.17", "com.unity.mathematics": "1.2.1", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json index c9dee4a4a98..a749ae707a5 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Foundation/Packages/manifest.json @@ -9,7 +9,6 @@ "com.unity.ide.vscode": "1.1.3", "com.unity.nuget.newtonsoft-json": "2.0.1-preview.1", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", diff --git a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json index c9dee4a4a98..a749ae707a5 100644 --- a/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/BuiltInGraphicsTest_Lighting/Packages/manifest.json @@ -9,7 +9,6 @@ "com.unity.ide.vscode": "1.1.3", "com.unity.nuget.newtonsoft-json": "2.0.1-preview.1", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", diff --git a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json index edf49babc7f..f13108f4c75 100644 --- a/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_DXR_Tests/Packages/manifest.json @@ -4,7 +4,6 @@ "dependencies": { "com.unity.ide.visualstudio": "2.0.0", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", "com.unity.render-pipelines.high-definition-config": "file:../../../../../Packages/com.unity.render-pipelines.high-definition-config", "com.unity.rendering.denoising": "1.0.5", diff --git a/Tests/SRPTests/Projects/HDRP_PerformanceTests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_PerformanceTests/Packages/manifest.json index 76c368f4d6c..3dbd531f2f7 100644 --- a/Tests/SRPTests/Projects/HDRP_PerformanceTests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_PerformanceTests/Packages/manifest.json @@ -4,7 +4,6 @@ "com.unity.ide.visualstudio": "2.0.0", "com.unity.ide.vscode": "1.2.0", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", "com.unity.render-pipelines.high-definition-config": "file:../../../../../Packages/com.unity.render-pipelines.high-definition-config", "com.unity.shaderanalysis": "file:../../../../../Packages/com.unity.shaderanalysis", diff --git a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json index 9d96adc60ab..fab19e9b9a4 100644 --- a/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/HDRP_RuntimeTests/Packages/manifest.json @@ -3,7 +3,6 @@ "dependencies": { "com.unity.ide.visualstudio": "2.0.22", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.render-pipelines.high-definition": "file:../../../../../Packages/com.unity.render-pipelines.high-definition", "com.unity.render-pipelines.high-definition-config": "file:../../../../../Packages/com.unity.render-pipelines.high-definition-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", diff --git a/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json b/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json index b0c940abe23..006f053b012 100644 --- a/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/MultipleSRP_Tests/Packages/manifest.json @@ -9,7 +9,6 @@ "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "local.utf.references": "file:../../../Packages/local.utf.references", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", "com.unity.timeline": "1.8.0", diff --git a/Tests/SRPTests/Projects/RPCore_PerformanceTests/Packages/manifest.json b/Tests/SRPTests/Projects/RPCore_PerformanceTests/Packages/manifest.json index 84ba611c8c1..ef1773c01d2 100644 --- a/Tests/SRPTests/Projects/RPCore_PerformanceTests/Packages/manifest.json +++ b/Tests/SRPTests/Projects/RPCore_PerformanceTests/Packages/manifest.json @@ -4,7 +4,6 @@ "dependencies": { "com.unity.feature.development": "1.0.2", "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.test-framework.performance": "3.0.2", "com.unity.ugui": "2.0.0", "local.utf.references": "file:../../../Packages/local.utf.references", diff --git a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json index 1367086b61c..e7ba46fcb22 100644 --- a/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json +++ b/Tests/SRPTests/Projects/SRP_SmokeTest/Packages/manifest.json @@ -10,7 +10,6 @@ "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "local.utf.references": "file:../../../Packages/local.utf.references", "com.unity.visualeffectgraph": "file:../../../../../Packages/com.unity.visualeffectgraph", "local.code.coverage.references": "file:../../../Packages/local.code.coverage.references" @@ -20,7 +19,6 @@ "com.unity.render-pipelines.universal", "com.unity.render-pipelines.high-definition", "com.unity.shadergraph", - "com.unity.rendering.light-transport", "com.unity.visualeffectgraph" ] } diff --git a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json index 21209001c0e..3e361935dfa 100644 --- a/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraph/Packages/manifest.json @@ -5,7 +5,6 @@ "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", "com.unity.testtools.codecoverage": "1.1.0", diff --git a/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json b/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json index 1d11f12c7b5..78bacaae172 100644 --- a/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json +++ b/Tests/SRPTests/Projects/ShaderGraphUniversalStereo/Packages/manifest.json @@ -7,7 +7,6 @@ "com.unity.render-pipelines.core": "file:../../../../../Packages/com.unity.render-pipelines.core", "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", "com.unity.ugui": "2.0.0", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json index 1113b4e34fb..5b7e2260f45 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_2D/Packages/manifest.json @@ -13,7 +13,6 @@ "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.testing.urp": "file:../../../Packages/com.unity.testing.urp", "com.unity.visualeffectgraph": "file:../../../../../Packages/com.unity.visualeffectgraph", "local.code.coverage.references": "file:../../../Packages/local.code.coverage.references", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json index ee727725908..beca389a124 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Packages/manifest.json @@ -13,7 +13,6 @@ "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "local.code.coverage.references": "file:../../../Packages/local.code.coverage.references", "local.utf.references": "file:../../../Packages/local.utf.references", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json index 896aacb2e64..50f2c039f02 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Lighting/Packages/manifest.json @@ -12,7 +12,6 @@ "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "local.code.coverage.references": "file:../../../Packages/local.code.coverage.references", "local.utf.references": "file:../../../Packages/local.utf.references", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json index 4bf1eaca36e..7b2e0d61c3a 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_PostPro/Packages/manifest.json @@ -13,7 +13,6 @@ "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.testing.hdr-faking": "file:../../../Packages/com.unity.testing.hdr-faking", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "local.code.coverage.references": "file:../../../Packages/local.code.coverage.references", "local.utf.references": "file:../../../Packages/local.utf.references", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", diff --git a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json index eeea03ca6f8..6609658ca50 100644 --- a/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json +++ b/Tests/SRPTests/Projects/UniversalGraphicsTest_Terrain/Packages/manifest.json @@ -12,7 +12,6 @@ "com.unity.render-pipelines.universal": "file:../../../../../Packages/com.unity.render-pipelines.universal", "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "local.code.coverage.references": "file:../../../Packages/local.code.coverage.references", "local.utf.references": "file:../../../Packages/local.utf.references", "com.unity.testframework.graphics": "file:../../../Packages/com.unity.testframework.graphics", diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json index f68604d8432..162d642a128 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/VisualEffectGraph_HDRP/Packages/manifest.json @@ -11,7 +11,6 @@ "com.unity.render-pipelines.high-definition-config": "file:../../../../../Packages/com.unity.render-pipelines.high-definition-config", "com.unity.shaderanalysis": "file:../../../../../Packages/com.unity.shaderanalysis", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.test-framework.graphics.performance": "file:../../../Packages/com.unity.test-framework.graphics.performance", "com.unity.testing.visualeffectgraph": "file:../../../Packages/com.unity.testing.visualeffectgraph", "com.unity.testing.xr": "file:../../../Packages/com.unity.testing.xr", diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json b/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json index 858ab5e9dca..af9b145128a 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json +++ b/Tests/SRPTests/Projects/VisualEffectGraph_URP/Packages/manifest.json @@ -10,7 +10,6 @@ "com.unity.render-pipelines.universal-config": "file:../../../../../Packages/com.unity.render-pipelines.universal-config", "com.unity.shaderanalysis": "file:../../../../../Packages/com.unity.shaderanalysis", "com.unity.shadergraph": "file:../../../../../Packages/com.unity.shadergraph", - "com.unity.rendering.light-transport": "file:../../../../../Packages/com.unity.rendering.light-transport", "com.unity.test-framework.graphics.performance": "file:../../../Packages/com.unity.test-framework.graphics.performance", "com.unity.testing.visualeffectgraph": "file:../../../Packages/com.unity.testing.visualeffectgraph", "com.unity.testing.xr": "file:../../../Packages/com.unity.testing.xr",