diff --git a/%USERPROFILE/VSTelem.Out/201910252250_D15.9_15.9.28307.105_23124_3db3c980-6baf-4c9c-86f3-c09da6e80f99.tcdb b/%USERPROFILE/VSTelem.Out/201910252250_D15.9_15.9.28307.105_23124_3db3c980-6baf-4c9c-86f3-c09da6e80f99.tcdb new file mode 100644 index 0000000..91d4aa4 Binary files /dev/null and b/%USERPROFILE/VSTelem.Out/201910252250_D15.9_15.9.28307.105_23124_3db3c980-6baf-4c9c-86f3-c09da6e80f99.tcdb differ diff --git a/%USERPROFILE/VSTelem.Out/dabcb5e4888f49e290393defbd7886a423124/dabcb5e4888f49e290393defbd7886a423124.jfm b/%USERPROFILE/VSTelem.Out/dabcb5e4888f49e290393defbd7886a423124/dabcb5e4888f49e290393defbd7886a423124.jfm new file mode 100644 index 0000000..5f39ddf Binary files /dev/null and b/%USERPROFILE/VSTelem.Out/dabcb5e4888f49e290393defbd7886a423124/dabcb5e4888f49e290393defbd7886a423124.jfm differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.commonide.ni.pdb/9b27896dfe227b44cc60549c3f8eb47f1/Microsoft.VisualStudio.CommonIDE.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.commonide.ni.pdb/9b27896dfe227b44cc60549c3f8eb47f1/Microsoft.VisualStudio.CommonIDE.ni.pdb new file mode 100644 index 0000000..67d99d9 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.commonide.ni.pdb/9b27896dfe227b44cc60549c3f8eb47f1/Microsoft.VisualStudio.CommonIDE.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.editor.implementation.ni.pdb/8a9562f3ee0e30bd3a5f5f08e0272cc71/Microsoft.VisualStudio.Editor.Implementation.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.editor.implementation.ni.pdb/8a9562f3ee0e30bd3a5f5f08e0272cc71/Microsoft.VisualStudio.Editor.Implementation.ni.pdb new file mode 100644 index 0000000..689a586 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.editor.implementation.ni.pdb/8a9562f3ee0e30bd3a5f5f08e0272cc71/Microsoft.VisualStudio.Editor.Implementation.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.platform.vseditor.ni.pdb/66c69e67b13bf0fedfba05329b98e69b1/Microsoft.VisualStudio.Platform.VSEditor.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.platform.vseditor.ni.pdb/66c69e67b13bf0fedfba05329b98e69b1/Microsoft.VisualStudio.Platform.VSEditor.ni.pdb new file mode 100644 index 0000000..c660292 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.platform.vseditor.ni.pdb/66c69e67b13bf0fedfba05329b98e69b1/Microsoft.VisualStudio.Platform.VSEditor.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.platform.windowmanagement.ni.pdb/7720b27c7add449d877b86f4443286db1/Microsoft.VisualStudio.Platform.WindowManagement.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.platform.windowmanagement.ni.pdb/7720b27c7add449d877b86f4443286db1/Microsoft.VisualStudio.Platform.WindowManagement.ni.pdb new file mode 100644 index 0000000..5950653 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.platform.windowmanagement.ni.pdb/7720b27c7add449d877b86f4443286db1/Microsoft.VisualStudio.Platform.WindowManagement.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.progression.native.codeprovider.ni.pdb/8198029fc2e3bf2843ba06dbca65283c1/Microsoft.VisualStudio.Progression.Native.CodeProvider.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.progression.native.codeprovider.ni.pdb/8198029fc2e3bf2843ba06dbca65283c1/Microsoft.VisualStudio.Progression.Native.CodeProvider.ni.pdb new file mode 100644 index 0000000..aad4ba6 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.progression.native.codeprovider.ni.pdb/8198029fc2e3bf2843ba06dbca65283c1/Microsoft.VisualStudio.Progression.Native.CodeProvider.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.project.visualc.vcprojectengine.ni.pdb/fb6f915245107d22404eb1b2ae0f56421/Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.project.visualc.vcprojectengine.ni.pdb/fb6f915245107d22404eb1b2ae0f56421/Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.ni.pdb new file mode 100644 index 0000000..118004d Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.project.visualc.vcprojectengine.ni.pdb/fb6f915245107d22404eb1b2ae0f56421/Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.projectsystem.vs.implementation.ni.pdb/ff7d8a4ac8a5c47f7ddcb35c899a2daa1/Microsoft.VisualStudio.ProjectSystem.VS.Implementation.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.projectsystem.vs.implementation.ni.pdb/ff7d8a4ac8a5c47f7ddcb35c899a2daa1/Microsoft.VisualStudio.ProjectSystem.VS.Implementation.ni.pdb new file mode 100644 index 0000000..d52dd27 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.projectsystem.vs.implementation.ni.pdb/ff7d8a4ac8a5c47f7ddcb35c899a2daa1/Microsoft.VisualStudio.ProjectSystem.VS.Implementation.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.15.0.ni.pdb/fb34a23b5321e3fa36184235712d678e1/Microsoft.VisualStudio.Shell.15.0.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.15.0.ni.pdb/fb34a23b5321e3fa36184235712d678e1/Microsoft.VisualStudio.Shell.15.0.ni.pdb new file mode 100644 index 0000000..4a110e1 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.15.0.ni.pdb/fb34a23b5321e3fa36184235712d678e1/Microsoft.VisualStudio.Shell.15.0.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.treenavigation.graphprovider.ni.pdb/220222c36b2d06e638d6aaf075eb2c6c1/Microsoft.VisualStudio.Shell.TreeNavigation.GraphProvider.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.treenavigation.graphprovider.ni.pdb/220222c36b2d06e638d6aaf075eb2c6c1/Microsoft.VisualStudio.Shell.TreeNavigation.GraphProvider.ni.pdb new file mode 100644 index 0000000..d2677fb Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.treenavigation.graphprovider.ni.pdb/220222c36b2d06e638d6aaf075eb2c6c1/Microsoft.VisualStudio.Shell.TreeNavigation.GraphProvider.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.treenavigation.hierarchyprovider.ni.pdb/491ffed74a638be83f77c70de44844ab1/Microsoft.VisualStudio.Shell.TreeNavigation.HierarchyProvider.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.treenavigation.hierarchyprovider.ni.pdb/491ffed74a638be83f77c70de44844ab1/Microsoft.VisualStudio.Shell.TreeNavigation.HierarchyProvider.ni.pdb new file mode 100644 index 0000000..b46a8ae Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.treenavigation.hierarchyprovider.ni.pdb/491ffed74a638be83f77c70de44844ab1/Microsoft.VisualStudio.Shell.TreeNavigation.HierarchyProvider.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.ui.internal.ni.pdb/03f18a6779edeaa727c3a86dfe63f9c21/Microsoft.VisualStudio.Shell.UI.Internal.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.ui.internal.ni.pdb/03f18a6779edeaa727c3a86dfe63f9c21/Microsoft.VisualStudio.Shell.UI.Internal.ni.pdb new file mode 100644 index 0000000..ab94f69 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.ui.internal.ni.pdb/03f18a6779edeaa727c3a86dfe63f9c21/Microsoft.VisualStudio.Shell.UI.Internal.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.viewmanager.ni.pdb/ab567f610d9609fa845fd0e89b1a5ea01/Microsoft.VisualStudio.Shell.ViewManager.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.viewmanager.ni.pdb/ab567f610d9609fa845fd0e89b1a5ea01/Microsoft.VisualStudio.Shell.ViewManager.ni.pdb new file mode 100644 index 0000000..04782fa Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.shell.viewmanager.ni.pdb/ab567f610d9609fa845fd0e89b1a5ea01/Microsoft.VisualStudio.Shell.ViewManager.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.threading.ni.pdb/3af46be52314bf1ba5362b208bf9fdbe1/Microsoft.VisualStudio.Threading.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.threading.ni.pdb/3af46be52314bf1ba5362b208bf9fdbe1/Microsoft.VisualStudio.Threading.ni.pdb new file mode 100644 index 0000000..b36c4c7 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.threading.ni.pdb/3af46be52314bf1ba5362b208bf9fdbe1/Microsoft.VisualStudio.Threading.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.utilities.ni.pdb/7e53c375de01fea1ea679c29b98377af1/Microsoft.VisualStudio.Utilities.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.utilities.ni.pdb/7e53c375de01fea1ea679c29b98377af1/Microsoft.VisualStudio.Utilities.ni.pdb new file mode 100644 index 0000000..8498dcb Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/microsoft.visualstudio.utilities.ni.pdb/7e53c375de01fea1ea679c29b98377af1/Microsoft.VisualStudio.Utilities.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/mscorlib.ni.pdb/bf92dcc11e428fd5adf02632b5d4414f1/mscorlib.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/mscorlib.ni.pdb/bf92dcc11e428fd5adf02632b5d4414f1/mscorlib.ni.pdb new file mode 100644 index 0000000..888b270 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/mscorlib.ni.pdb/bf92dcc11e428fd5adf02632b5d4414f1/mscorlib.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/presentationcore.ni.pdb/431135a1fa749be763773e77963c87b41/PresentationCore.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/presentationcore.ni.pdb/431135a1fa749be763773e77963c87b41/PresentationCore.ni.pdb new file mode 100644 index 0000000..e5aec23 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/presentationcore.ni.pdb/431135a1fa749be763773e77963c87b41/PresentationCore.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/presentationframework.ni.pdb/7a5c6b618e732e2851e884ec96b555cf1/PresentationFramework.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/presentationframework.ni.pdb/7a5c6b618e732e2851e884ec96b555cf1/PresentationFramework.ni.pdb new file mode 100644 index 0000000..e2e8d57 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/presentationframework.ni.pdb/7a5c6b618e732e2851e884ec96b555cf1/PresentationFramework.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/system.core.ni.pdb/54f8d9f69d63e6a7d4c9d10d07264dc31/System.Core.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/system.core.ni.pdb/54f8d9f69d63e6a7d4c9d10d07264dc31/System.Core.ni.pdb new file mode 100644 index 0000000..42a85ea Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/system.core.ni.pdb/54f8d9f69d63e6a7d4c9d10d07264dc31/System.Core.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/system.windows.forms.ni.pdb/cb7d5a26ece74684906e4981d4f1228d1/System.Windows.Forms.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/system.windows.forms.ni.pdb/cb7d5a26ece74684906e4981d4f1228d1/System.Windows.Forms.ni.pdb new file mode 100644 index 0000000..0183850 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/system.windows.forms.ni.pdb/cb7d5a26ece74684906e4981d4f1228d1/System.Windows.Forms.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/system.xaml.ni.pdb/17a1a95614aa2b130ba0227d6f60b7bd1/System.Xaml.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/system.xaml.ni.pdb/17a1a95614aa2b130ba0227d6f60b7bd1/System.Xaml.ni.pdb new file mode 100644 index 0000000..89a7037 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/system.xaml.ni.pdb/17a1a95614aa2b130ba0227d6f60b7bd1/System.Xaml.ni.pdb differ diff --git a/%USERPROFILE/VSTelem/NgenPdb/windowsbase.ni.pdb/d2014403854680ecc973f75e73a71b241/WindowsBase.ni.pdb b/%USERPROFILE/VSTelem/NgenPdb/windowsbase.ni.pdb/d2014403854680ecc973f75e73a71b241/WindowsBase.ni.pdb new file mode 100644 index 0000000..ccefea5 Binary files /dev/null and b/%USERPROFILE/VSTelem/NgenPdb/windowsbase.ni.pdb/d2014403854680ecc973f75e73a71b241/WindowsBase.ni.pdb differ diff --git a/README.md b/README.md index b0189d0..a4d604a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,27 @@ +

+ +

+ **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 5 - DirectX Procedural Raytracing** -* (TODO) YOUR NAME HERE - * (TODO) [LinkedIn](), [personal website](), [twitter](), etc. -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +* Jiangping Xu + * [LinkedIn](https://www.linkedin.com/in/jiangping-xu-365b19134/) +* Tested on: Windows 10, i9-8950HK @ 2.90GHz 32GB, GTX 1070 8G +__________ +[Introduction](#Stream-Compaction) - [Performance Analysis](#performance-analysis) +__________ +## Introduction + +This is a directX raytracing project using the recently released DirectX Raytracing API. There is one `Top Level Acceleration Structures` (TLAS), which has one instance of a Triangle `Bottom Level Acceleration Structures` (BLAS), and one instance of an `Axis-Aligned Bounding Box` (AABB) BLAS. The Triangle BLAS holds triangle data that will be used to render a horizontal plane. The AABB BLAS holds procedural geometry data, including a box, three balls, and a meta ball. + +

+ +

-### (TODO: Your README) +## Performance Analysis +

+ +

-Include screenshots, analysis, etc. (Remember, this is public, so don't put -anything here that you don't want to share with the world.) +The figure above shows the frame rate changes as increasing maximum raytracing depth. FPS goes down as expected when tracing depth increases. \ No newline at end of file diff --git a/images/FPS.png b/images/FPS.png new file mode 100644 index 0000000..074c739 Binary files /dev/null and b/images/FPS.png differ diff --git a/images/demo.gif b/images/demo.gif new file mode 100644 index 0000000..a8d93f5 Binary files /dev/null and b/images/demo.gif differ diff --git a/src/D3D12RaytracingProceduralGeometry/AnalyticPrimitives.hlsli b/src/D3D12RaytracingProceduralGeometry/AnalyticPrimitives.hlsli index c6ccebb..9852ba6 100644 --- a/src/D3D12RaytracingProceduralGeometry/AnalyticPrimitives.hlsli +++ b/src/D3D12RaytracingProceduralGeometry/AnalyticPrimitives.hlsli @@ -165,19 +165,48 @@ bool RaySolidSphereIntersectionTest(in Ray ray, out float thit, out float tmax, // You can hardcode the local centers/radii of the spheres, just try to maintain them between 1 and -1 (and > 0 for the radii). bool RayMultipleSpheresIntersectionTest(in Ray ray, out float thit, out ProceduralPrimitiveAttributes attr) { + //wtf // Define the spheres in local space (within the aabb) - float3 center = float3(-0.2, 0, -0.2); - float radius = 0.7f; - - thit = RayTCurrent(); - + float3 center1 = float3(-0.2, 0, -0.2); + float radius1 = 0.7f; + + float3 center2 = float3(0.4, 0, 0.5); + float radius2 = 0.3f; + + float3 center3 = float3(0.6, 0, 0.8); + float radius3 = 0.1f; + float ttmp = RayTCurrent(); + thit = ttmp; + ProceduralPrimitiveAttributes attrtmp; + bool flag = false; float tmax; - if (RaySphereIntersectionTest(ray, thit, tmax, attr, center, radius)) + if (RaySphereIntersectionTest(ray, ttmp, tmax, attrtmp, center1, radius1)) { - return true; + if (thit > ttmp) { + thit = ttmp; + attr = attrtmp; + flag = true; + } } - - return false; + if (RaySphereIntersectionTest(ray, ttmp, tmax, attrtmp, center2, radius2)) + { + if (thit > ttmp) { + thit = ttmp; + attr = attrtmp; + flag = true; + } + } + if (RaySphereIntersectionTest(ray, ttmp, tmax, attrtmp, center3, radius3)) + { + if (thit > ttmp) { + thit = ttmp; + attr = attrtmp; + flag = true; + } + } + if(flag) + return is_a_valid_hit(ray, thit, attr.normal); + return false; } #endif // ANALYTICPRIMITIVES_H \ No newline at end of file diff --git a/src/D3D12RaytracingProceduralGeometry/D3D12RaytracingProceduralGeometry.vcxproj b/src/D3D12RaytracingProceduralGeometry/D3D12RaytracingProceduralGeometry.vcxproj index 4a8b9ab..d655e5a 100644 --- a/src/D3D12RaytracingProceduralGeometry/D3D12RaytracingProceduralGeometry.vcxproj +++ b/src/D3D12RaytracingProceduralGeometry/D3D12RaytracingProceduralGeometry.vcxproj @@ -121,7 +121,7 @@ PrebuildCheck.bat true WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true - util;..\..\Libraries\D3D12RaytracingFallback\Include;$(IntDir);%(AdditionalIncludeDirectories) + C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;util;..\..\Libraries\D3D12RaytracingFallback\Include;$(IntDir);%(AdditionalIncludeDirectories) false @@ -129,8 +129,9 @@ PrebuildCheck.bat true true true - d3d12.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + atls.lib;d3d12.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) d3d12.dll + C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\lib\amd64\;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\lib\;%(AdditionalLibraryDirectories) true diff --git a/src/D3D12RaytracingProceduralGeometry/DXProceduralProject.h b/src/D3D12RaytracingProceduralGeometry/DXProceduralProject.h index 10498fc..28a2014 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXProceduralProject.h +++ b/src/D3D12RaytracingProceduralGeometry/DXProceduralProject.h @@ -152,6 +152,7 @@ class DXProceduralProject : public DXProject void BuildGeometryDescsForBottomLevelAS(std::array, BottomLevelASType::Count>& geometryDescs); AccelerationStructureBuffers BuildBottomLevelAS(const std::vector& geometryDesc, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS buildFlags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE); template + void BuildBottomLevelASInstanceDescs(BLASPtrType *bottomLevelASaddresses, ComPtr* instanceDescsResource); AccelerationStructureBuffers BuildTopLevelAS(AccelerationStructureBuffers bottomLevelAS[BottomLevelASType::Count], D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS buildFlags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE); void BuildAccelerationStructures(); diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-AccelerationStructure.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-AccelerationStructure.cpp index 084077a..3883b9a 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-AccelerationStructure.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-AccelerationStructure.cpp @@ -31,7 +31,15 @@ void DXProceduralProject::BuildGeometryDescsForBottomLevelAS(arrayGetDesc().Width) auto& geometryDesc = geometryDescs[BottomLevelASType::Triangle][0]; geometryDesc = {}; - + geometryDesc.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; + geometryDesc.Triangles.IndexBuffer = m_indexBuffer.resource->GetGPUVirtualAddress(); + geometryDesc.Triangles.VertexBuffer.StartAddress = m_vertexBuffer.resource->GetGPUVirtualAddress(); + geometryDesc.Triangles.VertexBuffer.StrideInBytes = sizeof(Vertex); + geometryDesc.Triangles.IndexFormat = DXGI_FORMAT_R16_UINT; + geometryDesc.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT; + geometryDesc.Triangles.IndexCount = m_indexBuffer.resource->GetDesc().Width / sizeof(Index); + geometryDesc.Triangles.VertexCount = m_vertexBuffer.resource->GetDesc().Width / sizeof(Vertex); + geometryDesc.Flags = geometryFlags; } { @@ -49,7 +57,11 @@ void DXProceduralProject::BuildGeometryDescsForBottomLevelAS(arrayGetGPUVirtualAddress() + i * sizeof(D3D12_RAYTRACING_AABB); + //geometryDescs[BottomLevelASType::AABB][i].AABBs.AABBs.StrideInBytes = sizeof(D3D12_RAYTRACING_AABB); + } } } @@ -68,6 +80,12 @@ AccelerationStructureBuffers DXProceduralProject::BuildBottomLevelAS(const vecto // Again, these tell the AS where the actual geometry data is and how it is laid out. // TODO-2.6: fill the bottom-level inputs. Consider using D3D12_ELEMENTS_LAYOUT_ARRAY as the DescsLayout. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS &bottomLevelInputs = bottomLevelBuildDesc.Inputs; + bottomLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + //wtf + bottomLevelInputs.pGeometryDescs = geometryDescs.data(); + bottomLevelInputs.Flags = buildFlags; + bottomLevelInputs.NumDescs = geometryDescs.size(); + bottomLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; // Query the driver for resource requirements to build an acceleration structure. We've done this for you. @@ -108,7 +126,8 @@ AccelerationStructureBuffers DXProceduralProject::BuildBottomLevelAS(const vecto // TODO-2.6: Now that you have the scratch and actual bottom-level AS desc, pass their GPU addresses to the bottomLevelBuildDesc. // Consider reading about D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC. // This should be as easy as passing the GPU addresses to the struct using GetGPUVirtualAddress() calls. - + bottomLevelBuildDesc.ScratchAccelerationStructureData = scratch->GetGPUVirtualAddress(); + bottomLevelBuildDesc.DestAccelerationStructureData = bottomLevelAS->GetGPUVirtualAddress(); // Fill up the command list with a command that tells the GPU how to build the bottom-level AS. if (m_raytracingAPI == RaytracingAPI::FallbackLayer) @@ -127,7 +146,8 @@ AccelerationStructureBuffers DXProceduralProject::BuildBottomLevelAS(const vecto // the AccelerationStructureBuffers struct so the top-level AS can use it! // Don't forget that this is the return value. // Consider looking into the AccelerationStructureBuffers struct in DXR-Structs.h - return AccelerationStructureBuffers{}; + + return AccelerationStructureBuffers{scratch, bottomLevelAS, nullptr, bottomLevelPrebuildInfo.ResultDataMaxSizeInBytes}; } // TODO-2.6: Build the instance descriptor for each bottom-level AS you built before. @@ -179,7 +199,38 @@ void DXProceduralProject::BuildBottomLevelASInstanceDescs(BLASPtrType *bottomLev // Where do you think procedural shader records would start then? Hint: right after. // * Make each instance hover above the ground by ~ half its width { + /* + const XMUINT3 NUM_AABB = XMUINT3(1, 1, 1); + const XMFLOAT3 fWidth = XMFLOAT3( + NUM_AABB.x * c_aabbWidth + (NUM_AABB.x - 1) * c_aabbDistance, + NUM_AABB.y * c_aabbWidth + (NUM_AABB.y - 1) * c_aabbDistance, + NUM_AABB.z * c_aabbWidth + (NUM_AABB.z - 1) * c_aabbDistance); + const XMVECTOR vWidth = XMLoadFloat3(&fWidth); + */ + + auto& instanceDesc = instanceDescs[BottomLevelASType::AABB]; + instanceDesc = {}; + instanceDesc.InstanceMask = 1; + instanceDesc.InstanceContributionToHitGroupIndex = 2;// GeometryType::Enum::Count * RayType::Count; + instanceDesc.AccelerationStructure = bottomLevelASaddresses[BottomLevelASType::AABB]; + /* + const XMVECTOR vBasePosition = vWidth * XMLoadFloat3(&XMFLOAT3(-0.5f, 0.5f, -0.5f)); + + // Scale in XZ dimensions. + XMMATRIX mScale = XMMatrixScaling(fWidth.x, fWidth.y, fWidth.z); + XMMATRIX mTranslation = XMMatrixTranslationFromVector(vBasePosition); + XMMATRIX mTransform = mScale * mTranslation; + // Store the transform in the instanceDesc. + XMStoreFloat3x4(reinterpret_cast(instanceDesc.Transform), mTransform); + */ + const XMVECTOR vBasePosition = c_aabbWidth * XMLoadFloat3(&XMFLOAT3(0.0f, 0.5f, 0.0f)); + + // To see about the scaling later on + //XMMATRIX mScale = XMMatrixScaling(fWidth.x, fWidth.y, fWidth.z); + XMMATRIX mTranslation = XMMatrixTranslationFromVector(vBasePosition); + XMMATRIX mTransform = mTranslation; + XMStoreFloat3x4(reinterpret_cast(instanceDesc.Transform), mTransform); } // Upload all these instances to the GPU, and make sure the resouce is set to instanceDescsResource. @@ -202,7 +253,11 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt // TODO-2.6: fill in the topLevelInputs, read about D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS. // Consider using D3D12_ELEMENTS_LAYOUT_ARRAY as a DescsLayout since we are using an array of bottom-level AS. D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS &topLevelInputs = topLevelBuildDesc.Inputs; - + topLevelInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + topLevelInputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + topLevelInputs.NumDescs = 2; + topLevelInputs.Flags = buildFlags; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO topLevelPrebuildInfo = {}; if (m_raytracingAPI == RaytracingAPI::FallbackLayer) @@ -216,7 +271,7 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt ThrowIfFalse(topLevelPrebuildInfo.ResultDataMaxSizeInBytes > 0); // TODO-2.6: Allocate a UAV buffer for the scracth/temporary top-level AS data. - + AllocateUAVBuffer(device, topLevelPrebuildInfo.ScratchDataSizeInBytes, &scratch, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, L"ScratchResource"); // Allocate space for the top-level AS. { @@ -231,7 +286,7 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt } // TODO-2.6: Allocate a UAV buffer for the actual top-level AS. - + AllocateUAVBuffer(device, topLevelPrebuildInfo.ResultDataMaxSizeInBytes, &topLevelAS, initialResourceState, L"TopLevelAccelerationStructure"); } // Note on Emulated GPU pointers (AKA Wrapped pointers) requirement in Fallback Layer: @@ -259,7 +314,7 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt }; // TODO-2.6: Call the fallback-templated version of BuildBottomLevelASInstanceDescs() you completed above. - + BuildBottomLevelASInstanceDescs(bottomLevelASaddresses, &instanceDescsResource); } else // DirectX Raytracing { @@ -271,7 +326,7 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt }; // TODO-2.6: Call the DXR-templated version of BuildBottomLevelASInstanceDescs() you completed above. - + BuildBottomLevelASInstanceDescs(bottomLevelASaddresses, &instanceDescsResource); } // Create a wrapped pointer to the acceleration structure. @@ -283,7 +338,9 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt // TODO-2.6: fill in the topLevelBuildDesc. Read about D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC. // This should be as easy as passing the GPU addresses to the struct using GetGPUVirtualAddress() calls. - + topLevelBuildDesc.ScratchAccelerationStructureData = scratch->GetGPUVirtualAddress(); + topLevelInputs.InstanceDescs = instanceDescsResource->GetGPUVirtualAddress(); + topLevelBuildDesc.DestAccelerationStructureData = topLevelAS->GetGPUVirtualAddress(); // Build acceleration structure. if (m_raytracingAPI == RaytracingAPI::FallbackLayer) @@ -302,7 +359,7 @@ AccelerationStructureBuffers DXProceduralProject::BuildTopLevelAS(AccelerationSt // Very similar to how you did this in BuildBottomLevelAS() except now you have to worry about topLevelASBuffers.instanceDesc. // Consider looking into the AccelerationStructureBuffers struct in DXR-Structs.h. // Make sure to return the topLevelASBuffers before you exit the function. - return AccelerationStructureBuffers{}; + return AccelerationStructureBuffers{scratch, topLevelAS, instanceDescsResource, topLevelPrebuildInfo.ResultDataMaxSizeInBytes}; } // TODO-2.6: This will wrap building the Acceleration Structure! This is what we will call when building our scene. @@ -318,12 +375,13 @@ void DXProceduralProject::BuildAccelerationStructures() // TODO-2.6: Build the geometry descriptors. Hint: you filled in a function that does this. array, BottomLevelASType::Count> geometryDescs; - + BuildGeometryDescsForBottomLevelAS(geometryDescs); // TODO-2.6: For each bottom-level object (triangle, procedural), build a bottom-level AS. // Hint: you filled in a function that does this. AccelerationStructureBuffers bottomLevelAS[BottomLevelASType::Count]; - + bottomLevelAS[0] = BuildBottomLevelAS(geometryDescs[0], D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE); + bottomLevelAS[1] = BuildBottomLevelAS(geometryDescs[1], D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE); // Batch all resource barriers for bottom-level AS builds. // This will Notifies the driver that it needs to synchronize multiple accesses to resources. @@ -336,7 +394,7 @@ void DXProceduralProject::BuildAccelerationStructures() // TODO-2.6: Build top-level AS. Hint, you already made a function that does this. AccelerationStructureBuffers topLevelAS; - + topLevelAS = BuildTopLevelAS(bottomLevelAS, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE); // Kick off acceleration structure construction. m_deviceResources->ExecuteCommandList(); @@ -347,5 +405,7 @@ void DXProceduralProject::BuildAccelerationStructures() // TODO-2.6: Store the AS buffers. The rest of the buffers will be released once we exit the function. // Do this for both the bottom-level and the top-level AS. Consider re-reading the DXProceduralProject class // to find what member variables should be set. - + m_bottomLevelAS[0] = bottomLevelAS[0].accelerationStructure; + m_bottomLevelAS[1] = bottomLevelAS[1].accelerationStructure; + m_topLevelAS = topLevelAS.accelerationStructure; } \ No newline at end of file diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-DoRaytracing.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-DoRaytracing.cpp index 03a8c58..21fe85a 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-DoRaytracing.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-DoRaytracing.cpp @@ -22,7 +22,8 @@ void DXProceduralProject::DoRaytracing() commandList->SetComputeRootConstantBufferView(GlobalRootSignature::Slot::SceneConstant, m_sceneCB.GpuVirtualAddress(frameIndex)); // TODO-2.8: do a very similar operation for the m_aabbPrimitiveAttributeBuffer - + m_aabbPrimitiveAttributeBuffer.CopyStagingToGpu(frameIndex); + commandList->SetComputeRootShaderResourceView(GlobalRootSignature::Slot::AABBattributeBuffer, m_aabbPrimitiveAttributeBuffer.GpuVirtualAddress(frameIndex)); // Bind the descriptor heaps. if (m_raytracingAPI == RaytracingAPI::FallbackLayer) @@ -50,9 +51,10 @@ void DXProceduralProject::DoRaytracing() // Example: in the case of GlobalRootSignature::Slot::SceneConstant above, we used SetComputeRootConstantBufferView() // Hint: look at CreateRootSignatures() in DXR-Pipeline.cpp. + commandList->SetComputeRootDescriptorTable(GlobalRootSignature::Slot::VertexBuffers, m_indexBuffer.gpuDescriptorHandle); // TODO-2.8: Bind the OutputView (basically m_raytracingOutputResourceUAVGpuDescriptor). Very similar to the Index/Vertex buffer. - + commandList->SetComputeRootDescriptorTable(GlobalRootSignature::Slot::OutputView, m_raytracingOutputResourceUAVGpuDescriptor); // This will define a `DispatchRays` function that takes in a command list, a pipeline state, and a descriptor // This will set the hooks using the shader tables built before and call DispatchRays on the command list @@ -60,13 +62,19 @@ void DXProceduralProject::DoRaytracing() { // You will fill in a D3D12_DISPATCH_RAYS_DESC (which is dispatchDesc). // TODO-2.8: fill in dispatchDesc->HitGroupTable. Look up the struct D3D12_GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE - - + dispatchDesc->HitGroupTable.StartAddress = m_hitGroupShaderTable->GetGPUVirtualAddress(); + dispatchDesc->HitGroupTable.StrideInBytes = m_hitGroupShaderTableStrideInBytes; + dispatchDesc->HitGroupTable.SizeInBytes = m_hitGroupShaderTable->GetDesc().Width; // TODO-2.8: now fill in dispatchDesc->MissShaderTable - - + //m_missShaderTable + dispatchDesc->MissShaderTable.StartAddress = m_missShaderTable->GetGPUVirtualAddress(); + dispatchDesc->MissShaderTable.StrideInBytes = m_missShaderTableStrideInBytes; + dispatchDesc->MissShaderTable.SizeInBytes = m_missShaderTable->GetDesc().Width; // TODO-2.8: now fill in dispatchDesc->RayGenerationShaderRecord - + //m_RayGenerationShaderTable + //only start address and size + dispatchDesc->RayGenerationShaderRecord.StartAddress = m_rayGenShaderTable->GetGPUVirtualAddress(); + dispatchDesc->RayGenerationShaderRecord.SizeInBytes = m_rayGenShaderTable->GetDesc().Width; // We do this for you. This will define how many threads will be dispatched. Basically like a blockDims in CUDA! dispatchDesc->Width = m_width; diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-DynamicBuffers.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-DynamicBuffers.cpp index e3ff63c..d5baa43 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-DynamicBuffers.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-DynamicBuffers.cpp @@ -111,7 +111,10 @@ void DXProceduralProject::CreateConstantBuffers() // structured buffers are for structs that have dynamic data (e.g lights in a scene, or AABBs in this case) void DXProceduralProject::CreateAABBPrimitiveAttributesBuffers() { + auto device = m_deviceResources->GetD3DDevice(); + auto frameCount = m_deviceResources->GetBackBufferCount(); + m_aabbPrimitiveAttributeBuffer.Create(device, IntersectionShaderType::TotalPrimitiveCount, frameCount, L"aabb Primitive Attribute Buffer"); } // LOOKAT-2.1: Update camera matrices stored in m_sceneCB. @@ -164,6 +167,12 @@ void DXProceduralProject::UpdateAABBPrimitiveAttributes(float animationTime) // You can infer what the bottom level AS space to local space transform should be. // The intersection shader tests in this project work with local space, but the geometries are provided in bottom level // AS space. So this data will be used to convert back and forth from these spaces. + + //wtf + m_aabbPrimitiveAttributeBuffer[primitiveIndex].localSpaceToBottomLevelAS = + XMMatrixMultiply(XMMatrixMultiply(mScale, mRotation), mTranslation); + m_aabbPrimitiveAttributeBuffer[primitiveIndex].bottomLevelASToLocalSpace = + XMMatrixInverse(nullptr, m_aabbPrimitiveAttributeBuffer[primitiveIndex].localSpaceToBottomLevelAS); }; UINT offset = 0; diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-Geometry.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-Geometry.cpp index 9d93504..ff8944d 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-Geometry.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-Geometry.cpp @@ -87,6 +87,12 @@ void DXProceduralProject::BuildProceduralGeometryAABBs() auto InitializeAABB = [&](auto& offsetIndex, auto& size) { D3D12_RAYTRACING_AABB aabb{}; + aabb.MinX = basePosition.x + offsetIndex.x * stride.x; + aabb.MinY = basePosition.y + offsetIndex.y * stride.y; + aabb.MinZ = basePosition.z + offsetIndex.z * stride.z; + aabb.MaxX = aabb.MinX + size.x; + aabb.MaxY = aabb.MinY + size.y; + aabb.MaxZ = aabb.MinZ + size.z; return aabb; }; m_aabbs.resize(IntersectionShaderType::TotalPrimitiveCount); @@ -110,12 +116,13 @@ void DXProceduralProject::BuildProceduralGeometryAABBs() // TODO-2.5: Allocate an upload buffer for this AABB data. // The base data lives in m_aabbs.data() (the stuff you filled in!), but the allocationg should be pointed // towards m_aabbBuffer.resource (the actual D3D12 resource that will hold all of our AABB data as a contiguous buffer). - + AllocateUploadBuffer(device, m_aabbs.data(), m_aabbs.size() * sizeof(m_aabbs[0]), &m_aabbBuffer.resource); } } // TODO-2.5: Build geometry used in the project. As easy as calling both functions above :) void DXProceduralProject::BuildGeometry() { - + BuildPlaneGeometry(); + BuildProceduralGeometryAABBs(); } \ No newline at end of file diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-HitGroup.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-HitGroup.cpp index 33899bd..3b1260c 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-HitGroup.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-HitGroup.cpp @@ -21,6 +21,7 @@ void DXProceduralProject::CreateHitGroupSubobjects(CD3D12_STATE_OBJECT_DESC* ray hitGroup->SetClosestHitShaderImport(c_closestHitShaderNames[GeometryType::Triangle]); } + // We tell the hitgroup that it should export into the correct shader hit group name, with the correct type hitGroup->SetHitGroupExport(c_hitGroupNames_TriangleGeometry[rayType]); hitGroup->SetHitGroupType(D3D12_HIT_GROUP_TYPE_TRIANGLES); @@ -30,6 +31,25 @@ void DXProceduralProject::CreateHitGroupSubobjects(CD3D12_STATE_OBJECT_DESC* ray // TODO-2.3: AABB geometry hit groups. Very similar to triangles, except now you have to *also* loop over the primitive types. { + for (UINT rayType = 0; rayType < RayType::Count; rayType++) + { + for (UINT primitiveType = 0; primitiveType < IntersectionShaderType::Count; primitiveType++) + { + auto hitGroup = raytracingPipeline->CreateSubobject(); + if (rayType == RayType::Radiance) + { + // We import the closest hit shader name + hitGroup->SetClosestHitShaderImport(c_closestHitShaderNames[GeometryType::AABB]); + } + + // Intersection shader mandatory for the AABB geometries + hitGroup->SetIntersectionShaderImport(c_intersectionShaderNames[primitiveType]); + // We tell the hitgroup that it should export into the correct shader hit group name, with the correct type + hitGroup->SetHitGroupExport(c_hitGroupNames_AABBGeometry[primitiveType][rayType]); + hitGroup->SetHitGroupType(D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE); + } + + } } } @@ -37,7 +57,7 @@ void DXProceduralProject::CreateHitGroupSubobjects(CD3D12_STATE_OBJECT_DESC* ray void DXProceduralProject::CreateLocalRootSignatureSubobjects(CD3D12_STATE_OBJECT_DESC* raytracingPipeline) { // Ray gen and miss shaders in this project are not using a local root signature and thus one is not associated with them. - + // Triangle geometry { auto localRootSignature = raytracingPipeline->CreateSubobject(); @@ -54,6 +74,19 @@ void DXProceduralProject::CreateLocalRootSignatureSubobjects(CD3D12_STATE_OBJECT // TODO-2.3: AABB geometry hitgroup/local root signature association. // Very similar to triangles, except now one for each primitive type. { - + auto localRootSignature = raytracingPipeline->CreateSubobject(); + + // This is the AABB geometry local root signature you already filled in before. + localRootSignature->SetRootSignature(m_raytracingLocalRootSignature[LocalRootSignature::Type::AABB].Get()); + + // Shader association + auto rootSignatureAssociation = raytracingPipeline->CreateSubobject(); + rootSignatureAssociation->SetSubobjectToAssociate(*localRootSignature); + + for (UINT primitiveType = 0; primitiveType < IntersectionShaderType::Count; primitiveType++) + { + rootSignatureAssociation->AddExports(c_hitGroupNames_AABBGeometry[primitiveType]); + } + } } \ No newline at end of file diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-RootSignature.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-RootSignature.cpp index 2dff8b5..f08c599 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-RootSignature.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-RootSignature.cpp @@ -21,7 +21,7 @@ void DXProceduralProject::CreateRootSignatures() // TODO-2.2: In range index 1 (the second range), initialize 2 SRV resources at register 1: indices and vertices of triangle data. // This will effectively put the indices at register 1, and the vertices at register 2. - + ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 1); // TODO-2.2: Initialize all the parameters of the GlobalRootSignature in their appropriate slots. // * See GlobalRootSignature in RaytracingSceneDefines.h to understand what they are. @@ -39,6 +39,11 @@ void DXProceduralProject::CreateRootSignatures() // t registers --> SRV // b registers --> CBV CD3DX12_ROOT_PARAMETER rootParameters[GlobalRootSignature::Slot::Count]; + rootParameters[GlobalRootSignature::Slot::OutputView].InitAsDescriptorTable(1, &ranges[0]); + rootParameters[GlobalRootSignature::Slot::VertexBuffers].InitAsDescriptorTable(1, &ranges[1]); + rootParameters[GlobalRootSignature::Slot::AccelerationStructure].InitAsShaderResourceView(0); + rootParameters[GlobalRootSignature::Slot::SceneConstant].InitAsConstantBufferView(0); + rootParameters[GlobalRootSignature::Slot::AABBattributeBuffer].InitAsShaderResourceView(3); // Finally, we bundle up all the descriptors you filled up and tell the device to create this global root signature! CD3DX12_ROOT_SIGNATURE_DESC globalRootSignatureDesc(ARRAYSIZE(rootParameters), rootParameters); @@ -67,7 +72,15 @@ void DXProceduralProject::CreateRootSignatures() // to register 1, this overlap is allowed since we are talking about *local* root signatures // --> the values they hold will depend on the shader function the local signature is bound to! { - + namespace RootSignatureSlots = LocalRootSignature::AABB::Slot; + CD3DX12_ROOT_PARAMETER rootParameters[RootSignatureSlots::Count]; + rootParameters[RootSignatureSlots::MaterialConstant].InitAsConstants(SizeOfInUint32(PrimitiveConstantBuffer), 1); + //wtf + rootParameters[RootSignatureSlots::GeometryIndex].InitAsConstants(SizeOfInUint32(PrimitiveConstantBuffer), 2); + + CD3DX12_ROOT_SIGNATURE_DESC localRootSignatureDesc(ARRAYSIZE(rootParameters), rootParameters); + localRootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE; + SerializeAndCreateRaytracingRootSignature(localRootSignatureDesc, &m_raytracingLocalRootSignature[LocalRootSignature::Type::AABB]); } } } diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-ShaderNames.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-ShaderNames.cpp index abc1f1e..de25bda 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-ShaderNames.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-ShaderNames.cpp @@ -16,7 +16,7 @@ using namespace DX; // LOOKAT-2.3, LOOKAT-2.7: Shader entry points. const wchar_t* DXProceduralProject::c_raygenShaderName = L"MyRaygenShader"; -const wchar_t* DXProceduralProject::c_intersectionShaderNames[] = +const wchar_t* DXProceduralProject::c_intersectionShaderNames[] = { L"MyIntersectionShader_AnalyticPrimitive", L"MyIntersectionShader_VolumetricPrimitive", diff --git a/src/D3D12RaytracingProceduralGeometry/DXR-ShaderTable.cpp b/src/D3D12RaytracingProceduralGeometry/DXR-ShaderTable.cpp index 150e92d..50f7128 100644 --- a/src/D3D12RaytracingProceduralGeometry/DXR-ShaderTable.cpp +++ b/src/D3D12RaytracingProceduralGeometry/DXR-ShaderTable.cpp @@ -32,8 +32,10 @@ void DXProceduralProject::BuildShaderTables() // TODO-2.7: Miss shaders. // Similar to the raygen shader, but now we have 1 for each ray type (radiance, shadow) // Don't forget to update shaderIdToStringMap. - missShaderIDs[0] = nullptr; - missShaderIDs[1] = nullptr; + missShaderIDs[0] = stateObjectProperties->GetShaderIdentifier(c_missShaderNames[0]); + shaderIdToStringMap[missShaderIDs[0]] = c_missShaderNames[0]; + missShaderIDs[1] = stateObjectProperties->GetShaderIdentifier(c_missShaderNames[1]); + shaderIdToStringMap[missShaderIDs[1]] = c_missShaderNames[1]; // Hitgroup shaders for the Triangle. We have 2: one for radiance ray, and another for the shadow ray. for (UINT i = 0; i < RayType::Count; i++) @@ -43,7 +45,13 @@ void DXProceduralProject::BuildShaderTables() } // TODO-2.7: Hitgroup shaders for the AABBs. We have 2 for each AABB. - + for (UINT i = 0; i < RayType::Count; i++) + { + for (UINT j = 0; j < IntersectionShaderType::Count; j++) { + hitGroupShaderIDs_AABBGeometry[j][i] = stateObjectProperties->GetShaderIdentifier(c_hitGroupNames_AABBGeometry[j][i]); + shaderIdToStringMap[hitGroupShaderIDs_AABBGeometry[j][i]] = c_hitGroupNames_AABBGeometry[j][i]; + } + } }; // Get shader identifiers using the lambda function defined above. @@ -95,7 +103,20 @@ void DXProceduralProject::BuildShaderTables() // TODO-2.7: Miss shader table. Very similar to the RayGen table except now we push_back() 2 shader records // 1 for the radiance ray, 1 for the shadow ray. Don't forget to call DebugPrint() on the table for your sanity! { - + UINT numShaderRecords = 2; + UINT shaderRecordSize = shaderIDSize; // No root arguments + + // The RayGen shader table contains a single ShaderRecord: the one single raygen shader! + ShaderTable missShaderTable(device, numShaderRecords, shaderRecordSize, L"MissShaderTable"); + + // Push back the shader record, which does not need any root signatures. + missShaderTable.push_back(ShaderRecord(missShaderIDs[0], shaderRecordSize, nullptr, 0)); + missShaderTable.push_back(ShaderRecord(missShaderIDs[1], shaderRecordSize, nullptr, 0)); + + // Save the uploaded resource (remember that the uploaded resource is created when we call Allocate() on a GpuUploadBuffer + missShaderTable.DebugPrint(shaderIdToStringMap); + m_missShaderTable = missShaderTable.GetResource(); + m_missShaderTableStrideInBytes = missShaderTable.GetShaderRecordSize(); } // Hit group shader table. This one is slightly different given that a hit group requires its own custom root signature. diff --git a/src/D3D12RaytracingProceduralGeometry/Main.cpp b/src/D3D12RaytracingProceduralGeometry/Main.cpp index 7f70bc6..6bbb443 100644 --- a/src/D3D12RaytracingProceduralGeometry/Main.cpp +++ b/src/D3D12RaytracingProceduralGeometry/Main.cpp @@ -16,7 +16,7 @@ #include "stdafx.h" #include "DXProceduralProject.h" -#define CPU_CODE_COMPLETE 0 +#define CPU_CODE_COMPLETE 1 _Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) diff --git a/src/D3D12RaytracingProceduralGeometry/Raytracing.hlsl b/src/D3D12RaytracingProceduralGeometry/Raytracing.hlsl index d066933..a5817fe 100644 --- a/src/D3D12RaytracingProceduralGeometry/Raytracing.hlsl +++ b/src/D3D12RaytracingProceduralGeometry/Raytracing.hlsl @@ -41,7 +41,7 @@ ConstantBuffer l_aabbCB: register(b2); // other // Remember to clamp the dot product term! float CalculateDiffuseCoefficient(in float3 incidentLightRay, in float3 normal) { - return 0.0f; + return 1.0f; } // TODO-3.6: Phong lighting specular component. @@ -51,7 +51,7 @@ float CalculateDiffuseCoefficient(in float3 incidentLightRay, in float3 normal) // Remember to normalize the reflected ray, and to clamp the dot product term float4 CalculateSpecularCoefficient(in float3 incidentLightRay, in float3 normal, in float specularPower) { - return float4(0.0f, 0.0f, 0.0f, 0.0f); + return float4(1.0f, 1.0f, 1.0f, 1.0f); } // TODO-3.6: Phong lighting model = ambient + diffuse + specular components. @@ -70,13 +70,27 @@ float4 CalculatePhongLighting(in float4 albedo, in float3 normal, in bool isInSh { // Ambient component // Fake AO: Darken faces with normal facing downwards/away from the sky a little bit + //wtf float4 ambientColor = g_sceneCB.lightAmbientColor; float4 ambientColorMin = g_sceneCB.lightAmbientColor - 0.1; float4 ambientColorMax = g_sceneCB.lightAmbientColor; float a = 1 - saturate(dot(normal, float3(0, -1, 0))); ambientColor = albedo * lerp(ambientColorMin, ambientColorMax, a); - return ambientColor; + float4 diffuseColor = g_sceneCB.lightDiffuseColor; + float3 lightDir = normalize(g_sceneCB.lightPosition.xyz - HitWorldPosition()); + diffuseColor = albedo * diffuseCoef * diffuseColor * clamp(dot(normal, lightDir), 0.0, 1.0); + + float4 specularColor = float4(g_sceneCB.reflectance, g_sceneCB.reflectance, g_sceneCB.reflectance, 1.0f); + specularColor = specularColor * specularCoef * pow(abs(dot(normalize(-WorldRayDirection()), reflect(-lightDir, normal))), specularPower); + float4 finalColor; + if(isInShadow) { + finalColor = ambientColor + diffuseColor * InShadowRadiance; + } else { + finalColor = ambientColor + diffuseColor + specularColor; + } + finalColor.w = 1.0f; + return finalColor; } //*************************************************************************** @@ -135,7 +149,31 @@ float4 TraceRadianceRay(in Ray ray, in UINT currentRayRecursionDepth) // Hint 2: remember what the ShadowRay payload looks like. See RaytracingHlslCompat.h bool TraceShadowRayAndReportIfHit(in Ray ray, in UINT currentRayRecursionDepth) { - return false; + + if (currentRayRecursionDepth >= MAX_RAY_RECURSION_DEPTH) + { + return false; + } + + //wtf + RayDesc rayDesc; + rayDesc.Origin = ray.origin; + rayDesc.Direction = ray.direction; + // Set TMin to a zero value to avoid aliasing artifacts along contact areas. + // Note: make sure to enable face culling so as to avoid surface face fighting. + rayDesc.TMin = 0; + rayDesc.TMax = 10000; + + ShadowRayPayload rayPayload = {true}; + + TraceRay(g_scene, + RAY_FLAG_CULL_BACK_FACING_TRIANGLES | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, + TraceRayParameters::InstanceMask, + TraceRayParameters::HitGroup::Offset[RayType::Shadow], + TraceRayParameters::HitGroup::GeometryStride, + TraceRayParameters::MissShader::Offset[RayType::Shadow], + rayDesc, rayPayload); + return rayPayload.hit; } //*************************************************************************** @@ -149,9 +187,9 @@ bool TraceShadowRayAndReportIfHit(in Ray ray, in UINT currentRayRecursionDepth) [shader("raygeneration")] void MyRaygenShader() { - + Ray r = GenerateCameraRay(DispatchRaysIndex().xy, g_sceneCB.cameraPosition.xyz, g_sceneCB.projectionToWorld); // Write the color to the render target - g_renderTarget[DispatchRaysIndex().xy] = float4(0.0f, 0.0f, 0.0f, 0.0f); + g_renderTarget[DispatchRaysIndex().xy] = TraceRadianceRay(r, 0); } //*************************************************************************** @@ -209,7 +247,8 @@ void MyClosestHitShader_Triangle(inout RayPayload rayPayload, in BuiltInTriangle // Hint 1: look at the intrinsic function RayTCurrent() that returns how "far away" your ray is. // Hint 2: use the built-in function lerp() to linearly interpolate between the computed color and the Background color. // When t is big, we want the background color to be more pronounced. - + float t = RayTCurrent(); + color = lerp(color, float4(0.05f, 0.5f, 0.55f, 1.0f), 1 - exp(-0.00001*pow(t, 2.0f))); rayPayload.color = color; } @@ -227,7 +266,42 @@ void MyClosestHitShader_Triangle(inout RayPayload rayPayload, in BuiltInTriangle [shader("closesthit")] void MyClosestHitShader_AABB(inout RayPayload rayPayload, in ProceduralPrimitiveAttributes attr) { + // Retrieve corresponding vertex normals for the triangle vertices. + float3 normal = attr.normal; + + // This is the intersection point on the triangle. + float3 hitPosition = HitWorldPosition(); + // Trace a ray from the hit position towards the single light source we have. If on our way to the light we hit something, then we have a shadow! + Ray shadowRay = { hitPosition, normalize(g_sceneCB.lightPosition.xyz - hitPosition) }; + bool shadowRayHit = TraceShadowRayAndReportIfHit(shadowRay, rayPayload.recursionDepth); + + // Reflected component ray. + float4 reflectedColor = float4(0, 0, 0, 0); + if (l_materialCB.reflectanceCoef > 0.001 ) + { + // Trace a reflection ray from the intersection points using Snell's law. The reflect() HLSL built-in function does this for you! + // See https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-intrinsic-functions + Ray reflectionRay = { hitPosition, reflect(WorldRayDirection(), normal) }; + float4 reflectionColor = TraceRadianceRay(reflectionRay, rayPayload.recursionDepth); + + float3 fresnelR = FresnelReflectanceSchlick(WorldRayDirection(), normal, l_materialCB.albedo.xyz); + reflectedColor = l_materialCB.reflectanceCoef * float4(fresnelR, 1) * reflectionColor; + } + + // Calculate final color. + float4 phongColor = CalculatePhongLighting(l_materialCB.albedo, normal, shadowRayHit, l_materialCB.diffuseCoef, l_materialCB.specularCoef, l_materialCB.specularPower); + float4 color = (phongColor + reflectedColor); + + // TODO: Apply a visibility falloff. + // If the ray is very very very far away, tends to sample the background color rather than the color you computed. + // This is to mimic some form of distance fog where farther objects appear to blend with the background. + // Hint 1: look at the intrinsic function RayTCurrent() that returns how "far away" your ray is. + // Hint 2: use the built-in function lerp() to linearly interpolate between the computed color and the Background color. + // When t is big, we want the background color to be more pronounced. + float t = RayTCurrent(); + color = lerp(color, float4(0.05f, 0.5f, 0.55f, 1.0f), 1 - exp(-0.00001*pow(t, 2.0f))); + rayPayload.color = color; } //*************************************************************************** @@ -240,14 +314,16 @@ void MyClosestHitShader_AABB(inout RayPayload rayPayload, in ProceduralPrimitive [shader("miss")] void MyMissShader(inout RayPayload rayPayload) { - + //wtf + rayPayload.color = float4(0.05f, 0.5f, 0.55f, 1.0f); } // TODO-3.3: Complete the Shadow ray miss shader. Is this ray a shadow ray if it hit nothing? [shader("miss")] void MyMissShader_ShadowRay(inout ShadowRayPayload rayPayload) { - + //wtf + rayPayload.hit = false; } //*************************************************************************** @@ -299,6 +375,23 @@ void MyIntersectionShader_AnalyticPrimitive() [shader("intersection")] void MyIntersectionShader_VolumetricPrimitive() { + //wtf + Ray localRay = GetRayInAABBPrimitiveLocalSpace(); + VolumetricPrimitive::Enum primitiveType = (VolumetricPrimitive::Enum) l_aabbCB.primitiveType; + + float thit; + ProceduralPrimitiveAttributes attr; + if (RayVolumetricGeometryIntersectionTest(localRay, primitiveType, thit, attr, g_sceneCB.elapsedTime)) + { + PrimitiveInstancePerFrameBuffer aabbAttribute = g_AABBPrimitiveAttributes[l_aabbCB.instanceIndex]; + // Make sure the normals are stored in BLAS space and not the local space + attr.normal = mul(attr.normal, (float3x3) aabbAttribute.localSpaceToBottomLevelAS); + attr.normal = normalize(mul((float3x3) ObjectToWorld3x4(), attr.normal)); + + // thit is invariant to the space transformation + ReportHit(thit, /*hitKind*/ 0, attr); + } + } #endif // RAYTRACING_HLSL \ No newline at end of file diff --git a/src/D3D12RaytracingProceduralGeometry/RaytracingHlslCompat.h b/src/D3D12RaytracingProceduralGeometry/RaytracingHlslCompat.h index 6e10f0d..4b4d664 100644 --- a/src/D3D12RaytracingProceduralGeometry/RaytracingHlslCompat.h +++ b/src/D3D12RaytracingProceduralGeometry/RaytracingHlslCompat.h @@ -28,7 +28,7 @@ typedef UINT16 Index; #define N_FRACTAL_ITERATIONS 5 // = <1,...> -#define MAX_RAY_RECURSION_DEPTH 3 // ~ primary rays + reflections + shadow rays from reflected geometry. +#define MAX_RAY_RECURSION_DEPTH 10 // ~ primary rays + reflections + shadow rays from reflected geometry. /**************** Scene *****************/ static const XMFLOAT4 ChromiumReflectance = XMFLOAT4(0.549f, 0.556f, 0.554f, 1.0f); diff --git a/src/D3D12RaytracingProceduralGeometry/RaytracingShaderHelper.hlsli b/src/D3D12RaytracingProceduralGeometry/RaytracingShaderHelper.hlsli index 94bf5cc..84fafd3 100644 --- a/src/D3D12RaytracingProceduralGeometry/RaytracingShaderHelper.hlsli +++ b/src/D3D12RaytracingProceduralGeometry/RaytracingShaderHelper.hlsli @@ -5,6 +5,7 @@ #define RAYTRACINGSHADERHELPER_H #include "RayTracingHlslCompat.h" +//#include "corecrt_math.h" #define INFINITY (1.0/0.0) @@ -68,7 +69,11 @@ bool is_a_valid_hit(in Ray ray, in float thit, in float3 hitSurfaceNormal) // (3) Call the hlsl built-in function smoothstep() on this interpolant to smooth it out so it doesn't change abruptly. float CalculateAnimationInterpolant(in float elapsedTime, in float cycleDuration) { - return smoothstep(0, 1, 0); + float cur = fmod(elapsedTime, cycleDuration) / cycleDuration; + if (cur <= 0.5f) { + return smoothstep(0.0f, 1.0f, 2.0f * cur); + } + return smoothstep(1.0f, 0.0f, 2.0f * cur - 1.0f); } // Load three 2-byte indices from a ByteAddressBuffer. @@ -130,8 +135,11 @@ float3 HitAttribute(float3 vertexAttribute[3], float2 barycentrics) inline Ray GenerateCameraRay(uint2 index, in float3 cameraPosition, in float4x4 projectionToWorld) { Ray ray; - ray.origin = float3(0.0f, 0.0f, 0.0f); - ray.direction = normalize(float3(0.0f, 0.0f, 0.0f)); + uint3 screensize = DispatchRaysDimensions(); + ray.origin = cameraPosition; + float4 p_ndc = float4(125.0f*(2.0f * index[0] / screensize.x - 1.0f), 125.0f*(1.0f - 2.0f * index[1] / screensize.y), 125.0f*1.0f, 125.0f*1.0f); + p_ndc = mul(p_ndc, projectionToWorld); + ray.direction = normalize(float3(p_ndc.x, p_ndc.y, p_ndc.z) - cameraPosition); return ray; } @@ -141,7 +149,7 @@ inline Ray GenerateCameraRay(uint2 index, in float3 cameraPosition, in float4x4 // f0 is usually the albedo of the material assuming the outside environment is air. float3 FresnelReflectanceSchlick(in float3 I, in float3 N, in float3 f0) { - return f0; + return f0 + (float3(1.0f, 1.0f, 1.0f) - f0) * pow(1.0f - abs(dot(N, I)), 5.0f); } #endif // RAYTRACINGSHADERHELPER_H \ No newline at end of file diff --git a/src/D3D12RaytracingProceduralGeometry/VolumetricPrimitives.hlsli b/src/D3D12RaytracingProceduralGeometry/VolumetricPrimitives.hlsli index 31a9444..bd28e4d 100644 --- a/src/D3D12RaytracingProceduralGeometry/VolumetricPrimitives.hlsli +++ b/src/D3D12RaytracingProceduralGeometry/VolumetricPrimitives.hlsli @@ -5,6 +5,7 @@ #define VOLUMETRICPRIMITIVESLIBRARY_H #include "RaytracingShaderHelper.hlsli" +#include "AnalyticPrimitives.hlsli" // LOOKAT-1.9.4: Shockingly, a metaball is just a sphere! struct Metaball @@ -22,7 +23,9 @@ struct Metaball // of the distance from the center to the radius. float CalculateMetaballPotential(in float3 position, in Metaball blob) { - return 0.0f; + float dis = distance(position, blob.center); + dis = max((1.0f - dis / blob.radius), 0.0f); + return 6.0f * pow(dis, 5.0f) - 15.0f * pow(dis, 4.0f) + 10.0f * pow(dis, 3.0f); } // LOOKAT-1.9.4: Calculates field potential from all active metaballs. This is just the sum of all potentials. @@ -81,8 +84,26 @@ void InitializeAnimatedMetaballs(out Metaball blobs[N_METABALLS], in float elaps // Remember that a metaball is just a solid sphere. Didn't we already do this somewhere else? void TestMetaballsIntersection(in Ray ray, out float tmin, out float tmax, inout Metaball blobs[N_METABALLS]) { + //wtf tmin = INFINITY; tmax = -INFINITY; + + float ttmp1; + float ttmp2; + for (int i = 0; i < N_METABALLS; i++) { + if (RaySolidSphereIntersectionTest(ray, ttmp1, ttmp2, blobs[i].center, blobs[i].radius)) + { + if (tmin > ttmp1) { + tmin = ttmp1; + } + if (tmax < ttmp2) { + tmax = ttmp2; + } + } + } + tmin = max(tmin, RayTMin()); + tmax = min(tmax, RayTCurrent()); + return; } // TODO-3.4.2: Test if a ray with RayFlags and segment intersects metaball field. @@ -100,8 +121,23 @@ void TestMetaballsIntersection(in Ray ray, out float tmin, out float tmax, inout // If this condition fails, keep raymarching! bool RayMetaballsIntersectionTest(in Ray ray, out float thit, out ProceduralPrimitiveAttributes attr, in float elapsedTime) { - thit = 0.0f; - attr.normal = float3(0.0f, 0.0f, 0.0f); + //wtf + + Metaball blobs[N_METABALLS]; + InitializeAnimatedMetaballs(blobs, elapsedTime, 10.0f); + float tmin, tmax; + TestMetaballsIntersection(ray, tmin, tmax, blobs); + float step = (tmax - tmin) / 128.0f; + for (int i = 1; i <= 128; i++) { + float3 position = ray.origin + (tmin + i * step) * ray.direction; + if (CalculateMetaballsPotential(position, blobs) > 0.15f) { + attr.normal = CalculateMetaballsNormal(position, blobs); + thit = tmin + i * step; + if (is_a_valid_hit(ray, thit, attr.normal)) + return true; + } + } + return false; }