diff --git a/.gitignore b/.gitignore index dc4bed0..573923e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ *.sublime-workspace compile-shaders.bat /tests +/external/dxc diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 78a1ab4..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,120 +0,0 @@ -stages: - - build - - test - -variables: - GIT_SUBMODULE_STRATEGY: none - TEST_REPO_BRANCH: main - -# Variables that should be specified from the project settings: -# - TEST_REPO_URL : URL of the repository with tests, including the username and token parts if necessary -# - ENABLE_JOBS : list of jobs to run, such as "build-linux,test-linux" - -# The script assumes that the following software is installed on the runner: -# - GCC or Clang (Linux) -# - Visual Studio 2019 (Windows) -# - CMake 3.10+ -# - Ninja build system -# - Python 3.8+ and scikit-image - - -# Clone the tests repository -.clone-tests: &clone-tests - - git clone -b ${TEST_REPO_BRANCH} ${TEST_REPO_URL} tests - - -build-linux: - stage: build - tags: - - linux - rules: - - if: '$ENABLE_JOBS =~ /build-linux/' - before_script: - - ./update_dependencies.sh - script: - - mkdir build && cd build - - cmake .. -GNinja - - ninja - artifacts: - name: "rtxdi-linux-${CI_COMMIT_SHORT_SHA}" - paths: - - build/bin/ - -build-windows: - stage: build - tags: - - windows - rules: - - if: '$ENABLE_JOBS =~ /build-windows/' - before_script: - - ./update_dependencies.bat - script: - - ./set_vs_vars.ps1 - - mkdir build - - cd build - - cmake .. -GNinja -DRTXDI_CONSOLE_APP=ON - - cmake --build . - artifacts: - name: "rtxdi-windows-${CI_COMMIT_SHORT_SHA}" - paths: - - build/bin/ - -test-linux: - stage: test - tags: - - linux - rules: - - if: '$ENABLE_JOBS =~ /test-linux/' - dependencies: - - build-linux - before_script: - - ./update_dependencies.sh - - *clone-tests - script: - - cd tests - - python test.py - artifacts: - name: "rtxdi-linux-test-outputs-${CI_COMMIT_SHORT_SHA}" - when: on_failure - paths: - - tests/outputs/ - -test-windows-dx12: - stage: test - tags: - - windows - rules: - - if: '$ENABLE_JOBS =~ /test-windows-dx12/' - dependencies: - - build-windows - before_script: - - ./update_dependencies.bat - - *clone-tests - script: - - cd tests - - python test.py - artifacts: - name: "rtxdi-windows-test-outputs-dx12-${CI_COMMIT_SHORT_SHA}" - when: on_failure - paths: - - tests/outputs/ - -test-windows-vulkan: - stage: test - tags: - - windows - rules: - - if: '$ENABLE_JOBS =~ /test-windows-vulkan/' - dependencies: - - build-windows - before_script: - - ./update_dependencies.bat - - *clone-tests - script: - - cd tests - - python test.py --vulkan - artifacts: - name: "rtxdi-windows-test-outputs-vulkan-${CI_COMMIT_SHORT_SHA}" - when: on_failure - paths: - - tests/outputs/ diff --git a/.gitmodules b/.gitmodules index fcd5685..851ccab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,18 +1,18 @@ [submodule "donut"] - path = donut - url = https://github.com/NVIDIAGameWorks/donut.git + path = External/donut + url = https://github.com/NVIDIA-RTX/Donut.git [submodule "NRD"] - path = NRD - url = https://github.com/NVIDIAGameWorks/RayTracingDenoiser.git + path = External/NRD + url = https://github.com/NVIDIA-RTX/NRD.git [submodule "DLSS"] - path = DLSS + path = External/DLSS url = https://github.com/NVIDIA/DLSS.git [submodule "rtxdi-runtime"] - path = rtxdi-runtime - url = https://github.com/NVIDIAGameWorks/rtxdi-runtime.git -[submodule "rtxdi-assets"] - path = rtxdi-assets - url = https://github.com/NVIDIAGameWorks/rtxdi-assets.git + path = Libraries/Rtxdi + url = https://github.com/NVIDIA-RTX/RTXDI-Library.git [submodule "thirdparty/cxxopts"] - path = thirdparty/cxxopts + path = External/cxxopts url = https://github.com/jarro2783/cxxopts.git +[submodule "Assets/Media"] + path = Assets/Media + url = https://github.com/NVIDIA-RTX/RTXDI-Assets.git diff --git a/rtxdi-assets b/Assets/Media similarity index 100% rename from rtxdi-assets rename to Assets/Media diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ee30fe..914189c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,13 +60,13 @@ endfunction() # Download DXC if (WIN32) - CheckAndDownloadPackage("DXC" "v1.7.2212.1" ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/dxc https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.7.2212.1/dxc_2023_03_01.zip) - set(REDIST_DXC "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/dxc/bin/x64/dxc.exe") + CheckAndDownloadPackage("DXC" "v1.7.2212.1" ${CMAKE_CURRENT_SOURCE_DIR}/External/dxc https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.7.2212.1/dxc_2023_03_01.zip) + set(REDIST_DXC "${CMAKE_CURRENT_SOURCE_DIR}/External/dxc/bin/x64/dxc.exe") else() - CheckAndDownloadPackage("DXC" "v1.7.2212.1" ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/dxc https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.7.2212.1/linux_dxc_2023_03_01.x86_64.tar.gz) + CheckAndDownloadPackage("DXC" "v1.7.2212.1" ${CMAKE_CURRENT_SOURCE_DIR}/External/dxc https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.7.2212.1/linux_dxc_2023_03_01.x86_64.tar.gz) # Add execute permissions - file(CHMOD ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/dxc/bin/dxc PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) - set(REDIST_DXC "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/dxc/bin/dxc") + file(CHMOD ${CMAKE_CURRENT_SOURCE_DIR}/External/dxc/bin/dxc PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) + set(REDIST_DXC "${CMAKE_CURRENT_SOURCE_DIR}/External/dxc/bin/dxc") endif() if (EXISTS "${REDIST_DXC}") if (WIN32 AND NOT DXC_PATH) @@ -89,14 +89,21 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") set(DONUT_SHADERS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin/shaders/framework") -add_subdirectory(donut) -set(DONUT_PATH "${CMAKE_CURRENT_LIST_DIR}/donut") +# Put the ShaderMake binary with the other build outputs +set(SHADERMAKE_BIN_OUTPUT_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" CACHE STRING "") -include(NRD.cmake) -include(DLSS.cmake) -include(rtxdi-runtime.cmake) +add_subdirectory(External/donut) +set(DONUT_PATH "${CMAKE_CURRENT_LIST_DIR}/External/donut") -set(RTXDI_RUNTIME_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/rtxdi-runtime/include") +include(External/NRD.cmake) +include(External/DLSS.cmake) + +if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/Libraries/Rtxdi/CMakeLists.txt") + + add_subdirectory(Libraries/Rtxdi) + set(RTXDI_RUNTIME_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Libraries/Rtxdi/Include") + +endif() set(GLSLANG_PATH "" CACHE STRING "Path to glslangValidator for GLSL header verification (optional)") @@ -104,15 +111,15 @@ if (NOT TARGET cxxopts) option(CXXOPTS_BUILD_EXAMPLES OFF) option(CXXOPTS_BUILD_TESTS OFF) option(CXXOPTS_ENABLE_INSTALL OFF) - add_subdirectory(thirdparty/cxxopts) + add_subdirectory(External/cxxopts) endif() -add_subdirectory(shaders) -add_subdirectory(src) -add_subdirectory(minimal/src) -add_subdirectory(minimal/shaders) -add_subdirectory(rtxdi-runtime-shader-tests) +add_subdirectory(Samples/FullSample/Shaders) +add_subdirectory(Samples/FullSample/Source) +add_subdirectory(Samples/MinimalSample/Shaders) +add_subdirectory(Samples/MinimalSample/Source) +add_subdirectory(Support/Tests/RtxdiRuntimeShaderTests) if (MSVC) - set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT rtxdi-sample) + set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT FullSample) endif() diff --git a/ChangeLog.md b/ChangeLog.md index 1ca78ed..9a6e590 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,22 @@ # RTXDI SDK Change Log +## 2.3.0 + +**Release highlights:** + +- Better folder organization: The samples now live in `Samples/`, external libraries now live in `External/`, and the test suite lives in `External/Tests/`. +- All folders and files now use the PascalCase naming convention. +- `RtxdiApplicationBridge.hlsli` broken down into constituent files based on functionality. +- `DIResamplingFunctions.hlsli` and `GIResamplingFunctions.hlsli` broken down into constituent files based on functionality. + +**Breaking changes:** + +- rtxdi-runtime folder moved to Libraries/Rtxdi, which is now organized into folders based on algorithm. +- File breakdowns mentioned above. + +**Misc improvements:** + +- Donut updated to latest version to include Blackwell support. ## 2.2.0 diff --git a/doc/Confidence.md b/Doc/Confidence.md similarity index 82% rename from doc/Confidence.md rename to Doc/Confidence.md index fed6b50..265dc62 100644 --- a/doc/Confidence.md +++ b/Doc/Confidence.md @@ -12,13 +12,13 @@ The confidence solution in RTXDI is inspired by the A-SVGF algorithm published i Notable open source implementations of A-SVGF can be found in the [Q2VKPT](http://brechpunkt.de/q2vkpt) project and its successor, [Quake II RTX](https://github.com/NVIDIA/Q2RTX). Q2VKPT implements the "vanilla" A-SVGF with forward projection of the surfaces from the previous frame into the current frame using the V-buffer; Q2RTX has switched to a different approach that is based on backward projection and G-buffer patching because the forward projection approach doesn't work for objects seen through reflections and refractions. -While A-SVGF worked well in these projects, it is not very practical for more complex renderers due to the fragility that comes from reusing random number sequences. Great care must be taken to avoid computing false positive gradients based on unrelated changes in the scene. For example, a change in the total light _count_ makes the light sampling logic select different lights using the same RNG sequence even though the surface being shaded may be unaffected by the change at all. In the case of RTXDI, reusing the RNG sequence doesn't look sufficient at all because the shading results depend on persistent state that is different from frame to frame, specifically the light reservoirs. Good news is, we can reuse the reservoirs instead of random numbers. +While A-SVGF worked well in these projects, it is not very practical for more complex renderers due to the fragility that comes from reusing random number sequences. Great care must be taken to avoid computing false positive gradients based on unrelated changes in the scene. For example, a change in the total light _count_ makes the light sampling logic select different lights using the same RNG sequence even though the surface being shaded may be unaffected by the change at all. In the case of RTXDI, reusing the RNG sequence doesn't look sufficient at all because the shading results depend on persistent state that is different from frame to frame, specifically the light reservoirs. The good news is that we can reuse the reservoirs instead of random numbers. ## Temporal Gradients in RTXDI -Similar to A-SVGF, we define a temporal gradient as difference between the shading results of the same surface using the same light sample on two consecutive frames. Gradients defined like this capture the changes in the surface's lighting environment, such as lights moving relative to the surface, lights changing their intensity, or lights becoming shadowed or un-shadowed. They may capture the difference in shading results due to the view vector changing because of camera motion, or not capture that, depending on the implementation; when using the NRD denoisers, capturing the view vector changes is not necessary. Gradients should **not** capture any changes due to the subpixel camera jitter that results in slight material variation in the same pixel when the camera is static. +Similar to A-SVGF, we define a temporal gradient as the difference between the shading results of the same surface using the same light sample on two consecutive frames. Gradients defined like this capture the changes in the surface's lighting environment, such as lights moving relative to the surface, lights changing their intensity, or lights becoming shadowed or un-shadowed. They may capture the difference in shading results due to the view vector changing because of camera motion, or not capture that, depending on the implementation; when using the NRD denoisers, capturing the view vector changes is not necessary. Gradients should **not** capture any changes due to the subpixel camera jitter that results in slight material variation in the same pixel when the camera is static. -Temporal gradients are computed using a separate compute or ray tracing pass that runs after final shading, [`ComputeGradients.hlsl`](../shaders/LightingPasses/ComputeGradients.hlsl). As a pre-requisite, the temporal resampling pass or the fused kernel saves the screen-space position of the pixel whose reservoir was used as the temporal light sample. Also, the luminance of the final shading results from the current and the previous frames needs to be available. Luminance can be computed from the diffuse and specular lighting textures if they store unmodified colors, but the RTXDI sample app may add BRDF ray tracing results into the same textures, so the sampled lighting luminance values are stored separately in the textures called `RestirLuminance`. +Temporal gradients are computed using a separate compute or ray tracing pass that runs after final shading, [`ComputeGradients.hlsl`](../shaders/DenoisingPasses/ComputeGradients.hlsl). As a prerequisite, the temporal resampling pass or the fused kernel saves the screen-space position of the pixel whose reservoir was used as the temporal light sample. Also, the luminance of the final shading results from the current and the previous frames need to be available. Luminance can be computed from the diffuse and specular lighting textures if they store unmodified colors, but the RTXDI sample app may add BRDF ray tracing results into the same textures, so the sampled lighting luminance values are stored separately in the textures called `RestirLuminance`. The gradient pass has two phases of execution: @@ -32,15 +32,15 @@ For more details on the gradient pass implementation, please refer to the commen The gradients pass produces a sparse and low-resolution signal, normally at 1/3 the screen resolution, that stores luminance differences and absolute values. Feeding that signal into the denoiser as confidence just wouldn't work, and the signal needs to be filtered and converted first. -First, the gradients are filtered spatially using a wide blur. The blur size and exact parameters may vary; the RTXDI sample app uses a 4-pass A-trous filter with a 3x3 kernel, which results in a 31 pixel kernel radius (in gradient space). The blur could be bilateral and take surface normals and positions into account, if desired. Our implementation is very straightforward and can be found in [`FilterGradientsPass.hlsl`](../shaders/FilterGradientsPass.hlsl). Note that the luminance differences and absolute values are filtered independently, which means that a small local change in a bright region is unlikely to result in history invalidation. +First, the gradients are filtered spatially using a wide blur. The blur size and exact parameters may vary; the RTXDI sample app uses a 4-pass A-trous filter with a 3x3 kernel, which results in a 31 pixel kernel radius (in gradient space). The blur could be bilateral and take surface normals and positions into account, if desired. Our implementation is very straightforward and can be found in [`FilterGradientsPass.hlsl`](../shaders/DenoisingPasses/FilterGradientsPass.hlsl). Note that the luminance differences and absolute values are filtered independently, which means that a small local change in a bright region is unlikely to result in history invalidation. Second, the filtered gradients are normalized, i.e. luminance differences are divided by the absolute luminance values, and then converted into (0-1) confidence using a simple function. This signal can already be fed into the confidence input of the denoiser, but there is one extra trick. The gradients are often noisy even after the spatial filtering, which sometimes results in patchy history invalidation. More importantly, singular events like a light turning on or off only create nonzero gradients on one frame. The spatiotemporal nature of ReSTIR leads to noisy and locally biased lighting on that first frame after a significant change. If the denoiser history is reset momentarily and then accumulation starts from scratch, that local bias has a significant weight in the history, resulting for example in a "black dip" effect around a light that has turned off. -The solution to both noisy confidence and local bias is simple: we can apply a short-history temporal filter to the confidence input of the denoiser. When the temporal filter is tuned right, deoniser history invalidations happen smoothly over a few frames and not abruptly. The temporal filter can be very simple; refer to [`ConfidencePass.hlsl`](../shaders/ConfidencePass.hlsl) for a reference implementation. +The solution to both noisy confidence and local bias is simple: we can apply a short-history temporal filter to the confidence input of the denoiser. When the temporal filter is tuned right, deoniser history invalidations happen smoothly over a few frames and not abruptly. The temporal filter can be very simple; refer to [`ConfidencePass.hlsl`](../shaders/DenoisingPasses/ConfidencePass.hlsl) for a reference implementation. -![Unfiltered and Filtered Confidence](images/Confidence.png) +![Unfiltered and Filtered Confidence](Images/Confidence.png) The images above illustrate the confidence channel computed from unfiltered gradients (top-left) and after spatial and temporal filtering (top-right) resulting from light coming through a rotating sphere with holes. The confidence is shown using a reverse heat map to highlight the regions where the history should be invalidated. diff --git a/doc/images/BiasCorrection.png b/Doc/Images/BiasCorrection.png similarity index 100% rename from doc/images/BiasCorrection.png rename to Doc/Images/BiasCorrection.png diff --git a/doc/images/Boiling.gif b/Doc/Images/Boiling.gif similarity index 100% rename from doc/images/Boiling.gif rename to Doc/Images/Boiling.gif diff --git a/doc/images/Checkerboard.gif b/Doc/Images/Checkerboard.gif similarity index 100% rename from doc/images/Checkerboard.gif rename to Doc/Images/Checkerboard.gif diff --git a/doc/images/Confidence.png b/Doc/Images/Confidence.png similarity index 100% rename from doc/images/Confidence.png rename to Doc/Images/Confidence.png diff --git a/doc/images/DataFlow.png b/Doc/Images/DataFlow.png similarity index 100% rename from doc/images/DataFlow.png rename to Doc/Images/DataFlow.png diff --git a/doc/images/DisocclusionBoost.png b/Doc/Images/DisocclusionBoost.png similarity index 100% rename from doc/images/DisocclusionBoost.png rename to Doc/Images/DisocclusionBoost.png diff --git a/doc/images/LightBufferLayout.png b/Doc/Images/LightBufferLayout.png similarity index 100% rename from doc/images/LightBufferLayout.png rename to Doc/Images/LightBufferLayout.png diff --git a/doc/images/LocalLightPdf.png b/Doc/Images/LocalLightPdf.png similarity index 100% rename from doc/images/LocalLightPdf.png rename to Doc/Images/LocalLightPdf.png diff --git a/doc/images/MeshLightProcessing.png b/Doc/Images/MeshLightProcessing.png similarity index 100% rename from doc/images/MeshLightProcessing.png rename to Doc/Images/MeshLightProcessing.png diff --git a/doc/images/PipelineFused.png b/Doc/Images/PipelineFused.png similarity index 100% rename from doc/images/PipelineFused.png rename to Doc/Images/PipelineFused.png diff --git a/doc/images/PipelineSeparated.png b/Doc/Images/PipelineSeparated.png similarity index 100% rename from doc/images/PipelineSeparated.png rename to Doc/Images/PipelineSeparated.png diff --git a/doc/images/ReGIRCellStructures.png b/Doc/Images/ReGIRCellStructures.png similarity index 100% rename from doc/images/ReGIRCellStructures.png rename to Doc/Images/ReGIRCellStructures.png diff --git a/doc/images/ReSTIRGI.png b/Doc/Images/ReSTIRGI.png similarity index 100% rename from doc/images/ReSTIRGI.png rename to Doc/Images/ReSTIRGI.png diff --git a/doc/images/TargetPDF.png b/Doc/Images/TargetPDF.png similarity index 100% rename from doc/images/TargetPDF.png rename to Doc/Images/TargetPDF.png diff --git a/doc/images/TemporalNoise.gif b/Doc/Images/TemporalNoise.gif similarity index 100% rename from doc/images/TemporalNoise.gif rename to Doc/Images/TemporalNoise.gif diff --git a/doc/Integration.md b/Doc/Integration.md similarity index 89% rename from doc/Integration.md rename to Doc/Integration.md index 7f385df..09fd8ff 100644 --- a/doc/Integration.md +++ b/Doc/Integration.md @@ -1,12 +1,12 @@ # Three Algorithms in One SDK -The RTXDI SDK originally contained a single algorithm, ReSTIR DI. Over time, however, the SDK has been expanded to include the ReGIR and ReSTIR GI algorithms. These three algorithms are grouped together because they all deal with importance sampling for path tracing. While something like "RTX IS" might therefore be a clearer name today, RTXDI is kept for historical continuity. Here is a summary of the three algorithms: +The RTXDI SDK originally contained a single algorithm, ReSTIR DI. Over time, however, the SDK has been expanded to include the ReGIR and ReSTIR GI algorithms. These three algorithms are grouped together because they all deal with importance sampling for path tracing. While something like "RTX IS" might therefore be a clearer name today, RTXDI is kept for historical continuity, and the DI now stands for Dynamic Illumination. Here is a summary of the three algorithms: - ReSTIR DI, short for **Re**servoir **S**patio**T**emporal **I**mportance **R**esampling for **D**irect **I**llumination, is a screen space light sampling technique used for illuminating primary surfaces during path tracing. It cheaply selects several lights from an initial distribution, such as a uniform or power-based one, then selects one light of that group based on a more expensive distribution, such as one including geometry, BRDF, and visibility terms, and uses that one for illumination. These samples are then resampled over time and across neighboring pixels to increase effective sample count. - ReGIR, short for Reservoir-based Grid Importance Sampling, is a world space light sampling technique that can be used for illuminating primary or subsequent surfaces. It samples lights from an initial distribution, such as a uniform or power-based one, for each grid cell. Other algorithms, such as ReSTIR DI and ReSTIR GI, can sample lights from this grid if the surface they are illuminating falls in a grid cell. -- ReSTIR GI, short for **Re**servoir **S**patio**T**emporal **I**mportance **R**esampling for **G**lobal **I**llumination, is a screen space light sampling technique used for illuminating secondary surfaces during path tracing. ReSTIR GI requires an initial light sampling technique be implemented by the path tracer for the secondary surface. In the `rtxdi-sample` project, this method is the initial sampling pass from ReSTIR DI, although any technique may be used. This secondary surface sample is then resampled across other pixels in space and time. +- ReSTIR GI, short for **Re**servoir **S**patio**T**emporal **I**mportance **R**esampling for **G**lobal **I**llumination, is a screen space light sampling technique used for illuminating secondary surfaces during path tracing. ReSTIR GI requires an initial light sampling technique be implemented by the path tracer for the secondary surface. In the `full-sample` project, this method is the initial sampling pass from ReSTIR DI, although any technique may be used. This secondary surface sample is then resampled across other pixels in space and time. -The algorithms in the SDK are implemented largely independent from one another, and the C++-side of each is centered around an accordingly named context class (`ReSTIRDIContext`, `ReGIRContext`, and `ReSTIRGIContext`). However, ReSTIR DI has a close integration of ReGIR for initial sampling. Likewise, the `rtxdi-sample` project uses ReSTIR DI's light sampling functions to illuminate secondary surfaces during multi-bounce path tracing. +The algorithms in the SDK are implemented largely independent from one another, and the C++-side of each is centered around an accordingly named context class (`ReSTIRDIContext`, `ReGIRContext`, and `ReSTIRGIContext`). However, ReSTIR DI has a close integration of ReGIR for initial sampling. Likewise, the `full-sample` project uses ReSTIR DI's light sampling functions to illuminate secondary surfaces during multi-bounce path tracing. The SDK also provides structs and functions that are shared between multiple algorithms. For example, the `RtxdiParameters.h` header provides structs relating to the light buffer and global runtime parameters. Likewise, the `PresamplingFunctions.hlsli` file provides presampling functions for creating PDF-textures for both local and environment lights, which can, in turn, be sampled from in the initial sampling passes of ReSTIR DI, ReGIR, and ReSTIR GI for improved sampling quality. @@ -24,7 +24,7 @@ The algorithms in the RTXDI SDK require a deep integration into the renderer. Th To avoid making overcomplicated abstractions or restrictive requirements, the RTXDI SDK follows an approach where the application is responsible for all of the above functionality, and RTXDI only provides the light sampling and resampling math that ties into pieces of that functionality through shader callback functions. This makes the integration process fairly involved, but the developers have complete control over the lighting system of their engines and do not have to ship any extra closed-source libraries with it. -The functionality provided by RTXDI can be separated into shader-side and host-side. Shader-side functionality for ReSTIR DI is provided through the [`DIResamplingFunctions.hlsli`](../rtxdi-sdk/include/rtxdi/DIResamplingFunctions.hlsli) include file and documented in [Shader API Reference](ShaderAPI.md). Host-side functionality is provided through the [`ReSTIRDI.h`](../rtxdi-sdk/include/rtxdi/ReSTIRDI.h) include file and the [`ReSTIRDI.cpp`](../rtxdi-sdk/src/ReSTIRDI.cpp) source file, which together form the `ReSTIRDIContext` class. ReGIR's context lives in [`ReGIR.h`](../rtxdi-sdk/include/rtxdi/ReGIR.h), and ReSTIR GI's context lives in [`ReSTIRGI.h`](../rtxdi-sdk/include/rtxdi/ReSTIRGI.h) Functionality that is shared between these algorithms is located in [`RtxdiUtils.h`](../rtxdi-sdk/include/rtxdi/RtxdiUtils.h). +The functionality provided by RTXDI can be separated into shader-side and host-side. Shader-side functionality for ReSTIR DI is provided through the [`DI/`](../Libraries/Rtxdi/Include/Rtxdi/DI/) include folder and documented in [Shader API Reference](ShaderAPI.md). Host-side functionality is provided through the [`ReSTIRDI.h`](../Libraries/Rtxdi/Include/Rtxdi/DI/ReSTIRDI.h) include file and the [`ReSTIRDI.cpp`](../Libraries/Rtxdi/Source/DI/ReSTIRDI.cpp) source file, which together form the `ReSTIRDIContext` class. ReGIR's context lives in [`ReGIR.h`](../Libraries/Rtxdi/Include/Rtxdi/ReGIR/ReGIR.h), and ReSTIR GI's context lives in [`ReSTIRGI.h`](../Libraries/Rtxdi/Include/Rtxdi/GI/ReSTIRGI.h). Functionality that is shared between these algorithms is located in [`RtxdiUtils.h`](../Libraries/Rtxdi/Include/Rtxdi/RtxdiUtils.h). The application also needs to provide shader-side and host-side functionality for RTXDI to work. Most importantly, it needs to provide the bridge structures functions, or callbacks, that are used by the RTXDI resampling functions. Those functions' and structures' names start with `RAB_` (for "**R**TXDI-**A**pplication **B**ridge"). For the complete list of functions and structures that need to be implemented, see the [Bridge Reference](RtxdiApplicationBridge.md). Then the application needs to assemble the resampling functions into complete shaders to build the desired pipeline and compile those shaders. Finally, at run time, the application needs to collect the light information, create the necessary buffers, and execute the compiled shaders. @@ -35,7 +35,7 @@ For additional considerations about the necessary passes and functions, and to l The data flow of a renderer using RTXDI is shown on the diagram below. -![Data Flow Diagram](images/DataFlow.png) +![Data Flow Diagram](Images/DataFlow.png) The rendering process includes the following steps. @@ -70,7 +70,7 @@ Collect information about all lights in the scene into a buffer. That includes m The layout of the light buffer used in the sample application is shown here: -![Light Buffer Layout](images/LightBufferLayout.png) +![Light Buffer Layout](Images/LightBufferLayout.png) Note that there are two groups of lights here, one for the odd frames and one for the even frames. This ensures that temporal resampling can access light information from the previous frame, which is necessary to compute the correct normalization factors for unbiased resampling. Another necessary thing is the mapping between light indices on the current and previous frames, which is provided through the [`RAB_TranslateLightIndex`](RtxdiApplicationBridge.md#rab_translatelightindex) bridge function. @@ -82,7 +82,7 @@ In order to use importance sampling for local lights and the environment map, th The local light PDF texture might look like this image: -![Local Light PDF](images/LocalLightPdf.png) +![Local Light PDF](Images/LocalLightPdf.png) The PDF texture also needs to have a full mip chain, up to 1x1 pixels. Any mipmap generation code can be used, as long as it does exactly 4:1 pixel downsampling in each step using a box filter: *output = sum(inputs) / 4*. @@ -90,13 +90,13 @@ In the sample application, the first pass of PDF texture build for local lights ### 4. Fill the constant buffer structure -Each pass of the ReSTIR DI algorithm requires settings from a correspondingly named `ReSTIRDI_*Parameters` struct. Fetch these from the ReSTIRDI context by calling the appropriate `rtxdi::ReSTIRDIContext::get*()` functions and place them into a constant buffer. Additionally, some settings are shared between stages and are stored in the `rtxdi::ReSTIRDIContext::getRuntimeParams()`, `rtxdi::ReSTIRDIContext::getBufferIndices()`, and `rtxdi::ReSTIRDIContext::getReservoirBufferParameters()` functions; these, too, must be stored in the constant buffer for each pass of the algorithm and passed to the shader functions accordingly. +Each pass of the ReSTIR DI algorithm requires settings from a correspondingly named `ReSTIRDI_*Parameters` struct. Fetch these from the ReSTIRDI context by calling the appropriate `rtxdi::ReSTIRDIContext::get*()` functions and place them into a constant buffer. Additionally, some settings are shared between stages and are stored in the `rtxdi::ReSTIRDIContext::getBufferIndices()`,and `rtxdi::ReSTIRDIContext::getReservoirBufferParameters()` functions; these, too, must be stored in the constant buffer for each pass of the algorithm and passed to the shader functions accordingly. The ReGIR and ReSTIR GI contexts likewise provide `get*()` functions for data that needs to be placed in the constant buffer for their respective shader passes. Note that ReSTIR DI and ReSTIR GI can both make use of ReGIR, so you should make sure to keep the ReGIR constants set for both the ReSTIR DI shader passes and the ReSTIR GI shader passes. ### 5. Pre-sample local lights and environment map (Optional) -Local ligths are pre-sampled into the RIS buffer to accelerate the initial sampling pass. This is necessary if local light importance sampling is used. The presampling pass is effectively doing CDF (Cumulative Distribution Function) inversion through mipmap descent and is implemented in the [`RTXDI_PresampleLocalLights`](ShaderAPI.md#rtxdi_presamplelocallights) function. +Local lights are pre-sampled into the RIS buffer to accelerate the initial sampling pass. This is necessary if local light importance sampling is used. The presampling pass is effectively doing CDF (Cumulative Distribution Function) inversion through mipmap descent and is implemented in the [`RTXDI_PresampleLocalLights`](ShaderAPI.md#rtxdi_presamplelocallights) function. The environment map is pre-sampled into a different part of the RIS buffer. This is implemented in the [`RTXDI_PresampleEnvironmentMap`](ShaderAPI.md#rtxdi_presampleenvironmentmap) function. @@ -106,11 +106,11 @@ Build the world-space light sampling structure for [ReGIR](#regir) (Reservoir-ba ### 7. Perform light sampling and resampling -Perform light sampling and resampling in screen space using shaders that call the following functions: `[RTXDI_SampleLightsForSurface`](ShaderAPI.md#rtxdi_samplelightsforsurface), [`RTXDI_TemporalResampling`](ShaderAPI.md#rtxdi_temporalresampling), [`RTXDI_SpatialResampling`](ShaderAPI.md#rtxdi_spatialresampling), [`RTXDI_SpatioTemporalResampling`](ShaderAPI.md#RTXDI_SpatioTemporalResampling). See e.g. [`GenerateInitialSamples.hlsl`](../shaders/LightingPasses/GenerateInitialSamples.hlsl) for a shader example, and [`LightingPasses.cpp`](../src/LightingPasses.cpp) for host-side code example. Examples of resampled pipelines are provided [below](#examples). +Perform light sampling and resampling in screen space using shaders that call the following functions: `[RTXDI_SampleLightsForSurface`](ShaderAPI.md#rtxdi_samplelightsforsurface), [`RTXDI_TemporalResampling`](ShaderAPI.md#rtxdi_temporalresampling), [`RTXDI_SpatialResampling`](ShaderAPI.md#rtxdi_spatialresampling), [`RTXDI_SpatioTemporalResampling`](ShaderAPI.md#RTXDI_SpatioTemporalResampling). See e.g. [`GenerateInitialSamples.hlsl`](../shaders/LightingPasses/DI/GenerateInitialSamples.hlsl) for a shader example, and [`LightingPasses.cpp`](../src/LightingPasses.cpp) for host-side code example. Examples of resampled pipelines are provided [below](#examples). ### 8. Shade -Shade the final selected light samples using your final material BRDF. Load the sample from the reservoir buffer, trace a visibility ray, store the visibility in the reservoir if desired, and evaluate the BRDF. See [`ShadeSamples.hlsl`](../shaders/LightingPasses/ShadeSamples.hlsl) for an example. +Shade the final selected light samples using your final material BRDF. Load the sample from the reservoir buffer, trace a visibility ray, store the visibility in the reservoir if desired, and evaluate the BRDF. See [`ShadeSamples.hlsl`](../shaders/LightingPasses/DI/ShadeSamples.hlsl) for an example. ### 9. Compute the denoiser confidence inputs (Optional) @@ -124,11 +124,11 @@ Apply denoising and composite the denoised lighting with other effects. The resampling functions can be assembled into various pipelines to fit the application's needs. A complete resampling pipeline with two spatial passes is shown on the image below. The sample application uses a pipeline like this, except with one spatial pass instead of two. -![Separated Pipeline](images/PipelineSeparated.png) +![Separated Pipeline](Images/PipelineSeparated.png) Some applications might find it useful to implement a fused resampling pipeline, one that combines all light sampling passes into one shader, which could be also tracing primary rays. Such fused pipeline is shown below. -![Fused Pipeline](images/PipelineFused.png) +![Fused Pipeline](Images/PipelineFused.png) ## Mesh light processing @@ -138,7 +138,7 @@ The sample application implements a basic mesh light processing pipeline with st The mesh light processing compute shader, [`PrepareLights.hlsl`](../shaders/PrepareLights.hlsl),starts by identifying which mesh and triangle the current thread should be processing. This is done by doing a binary search on the task list and matching the thread index to the index ranges occupied by each mesh instance; those indices are allocated on the host before launching the shader. Then the shader loads the triangle information: vertex positions and texture coordinates. Vertex positions are transformed with the instance matrix, and they become the vertices of the created mesh light. For materials which have an emissive texture, the texture is approximately integrated over the area of the triangle using a single anisotropic texture sample, as shown below. -![Mesh Light Processing Diagram](images/MeshLightProcessing.png) +![Mesh Light Processing Diagram](Images/MeshLightProcessing.png) In practice, extracting emissive triangle information from meshes can be problematic for a number of reasons. The following discussion assumes that the processing is happening on the GPU, similar to the way the sample application does it. @@ -159,11 +159,11 @@ The simplest solution for world-space sampling is to apply RIS to a number of sa RTXDI SDK includes a solution for world-space sampling called ReGIR, for *Reservoir-based Grid Importance Resampling*. ReGIR constructs a spatial structure with cells distributed around a given location, typically around the camera. There are two available structures: `Grid`, which is just a regular 3D grid; and `Onion`, which is a spherical space partitioning that fills the space with cells whose size gradually increases with distance from the center. The type of structure can be selected with the `ReGIRContextParameters::Mode` field when creating the RTXDI context. -![ReGIR Spatial Structures](images/ReGIRCellStructures.png) +![ReGIR Spatial Structures](Images/ReGIRCellStructures.png) The spatial structure is rebuilt every frame. Every cell is populated with a number of lights, typically on the order of hundreds to thousands. Each light in the cell is selected from the local light pool using RIS, with the target distribution function being average irradiance from the light to any surface within the cell. Therefore, the cells are not very selective, i.e. if there are many lights in or around the cell, the cells will not help choose a relevant light from those. But they will help filter out the lights that are too far away and will therefore significantly reduce the noise in large scenes. -To build the ReGIR spatial structure, run a compute shader that calls the `RTXDI_PresampleLocalLightsForReGIR` function. That shader should execute between the local light presampling pass (if importance sampling is enabled; it should be) and any uses of the structure. To sample from the structure only, call the `RTXDI_SampleLocalLightsFromReGIR` function that returns a reservoir with the selected light. Shadowing is not evaluated by that function. To combine the ReGIR results with sampling from unordered light pools outside of the ReGIR structure, call `RTXDI_SampleLightsForSurface`. +To build the ReGIR spatial structure, run a compute shader that calls the `RTXDI_PresampleLocalLightsForReGIR` function. That shader should execute between the local light presampling pass (if importance sampling is enabled; it should be) and any uses of the structure. To sample from the structure only, call the `RTXDI_SampleLocalLights` function that returns a reservoir with the selected light. Shadowing is not evaluated by that function. To combine the ReGIR results with sampling from unordered light pools outside of the ReGIR structure, call `RTXDI_SampleLightsForSurface`. Note that ReGIR can also be used as the initial sample generator for screen-space resampling, or ReSTIR. This leads to reduced noise in the initial samples, and in case of large and distributed scenes, can make the difference between a usable output signal and an output signal that has a lot of boiling. This "ReGIR feeds ReSTIR" mode is the default behavior of the sample application. @@ -178,4 +178,4 @@ Checkerboard rendering must be enabled at RTXDI context creation time, through t An example frame sequence rendered in checkerboard mode is shown below. -![Checkerboard](images/Checkerboard.gif) \ No newline at end of file +![Checkerboard](Images/Checkerboard.gif) \ No newline at end of file diff --git a/doc/NoiseAndBias.md b/Doc/NoiseAndBias.md similarity index 97% rename from doc/NoiseAndBias.md rename to Doc/NoiseAndBias.md index 6d347e5..37a9a78 100644 --- a/doc/NoiseAndBias.md +++ b/Doc/NoiseAndBias.md @@ -1,6 +1,6 @@ # Dealing with Noise and Bias -Reducing the noise that comes with sampled lighting is the entire point of ReSTIR and RTXDI. There are many parameters in the resampling passes that affect the noise levels and performance, and there are a few critical pieces of functionality that must be implemented right in order to ensure adequate ReSTIR performance. +Reducing the noise that comes with sampled lighting is the entire point of ReSTIR and RTXDI. There are many parameters in the resampling passes that affect the noise levels and performance, and there are a few critical pieces of functionality that must be implemented correctly in order to ensure adequate ReSTIR performance. ## Target PDF @@ -10,7 +10,7 @@ The target PDF is defined as `RAB_GetLightSampleTargetPdfForSurface` in the brid An illustration for the effect that the target PDF makes on the final sampled image is shown below. -![Target PDF Errors](images/TargetPDF.png) +![Target PDF Errors](Images/TargetPDF.png) Image (a) shows a rendering of the Bistro scene with the correct target PDF proportional to the actual BRDF. Image (b) shows the same scene with a PDF that is constant 1.0, meaning it is equally likely to select the sun light as it is to select a tiny emissive triangle far away. Image (c) shows the scene with a PDF that assumes that every material is fully metallic and has a roughness of 0.2, which makes the renderer prefer lights that are somewhere around the reflected direction, instead of anywhere around a diffuse surface. Image (d) shows the scene that actually has all materials replaced by metals with a roughness of 0.2, to illustrate what ReSTIR is trying to render on image (c). @@ -24,13 +24,13 @@ The two main use cases for importance resampling in RTXDI are when the *target P The initial sampling pass has a straightforward way to control the output noise: specify the number of samples taken from each strategy. There are separate sample counts for local lights (either importance sampled or not), for infinite lights, for the environment map, and for ReGIR where it's available. The more samples are taken, the better the results, but the noise reduction is linear, which means the initial sampling pass alone won't produce a good enough picture for a large number of lights in real-time constraints. It's important, however, to have enough initial samples to avoid boiling that appears when spatiotemporal reuse is applied to a very noisy, sparse signal. Using ReGIR can help with the boiling situation in large scenes with multiple rooms or similarly separated locations. An example of this boiling is shown on the animation below, which was rendered by applying uniform sampling to an environment map with a very bright sun. -![Boiling example](images/Boiling.gif) +![Boiling example](Images/Boiling.gif) The temporal and spatial resampling passes, or a combined version of those - the spatiotemporal pass, are crucial to noise reduction. Using temporal resampling makes the number of light samples evaluated per pixel increase linearly over time, and adding spatial resampling on top changes that sample count function to an exponential one. The more spatial samples you use, the higher is the base of the exponent, and the faster the noise will fade. But increasing the number of spatial samples also results in reduced performance, and using many samples is not necessary in converged areas - typically, 1-3 samples are sufficient. Many spatial samples are useful mostly in areas of disocclusion, and the process of increasing their count is called "disocclusion boost". The `numDisocclusionBoostSamples` parameter of the spatial and spatiotemporal resampling passes controls how many samples to take in areas that do not have sufficient history length, to help those areas converge faster. The effectiveness of disocclusion boost is illustrated on the image below. It shows the same scene location captured when the camera is strafing from right to left, making a portion of the ground appear from behind the pole on every frame. -![Disocclusion boost comparison](images/DisocclusionBoost.png) +![Disocclusion boost comparison](Images/DisocclusionBoost.png) ## Denoiser friendliness @@ -38,7 +38,7 @@ Modern spatiotemporal denoisers expect the input noisy signal to have certain pr If a single temporal resampling pass is applied, the output noisy signal will appear fairly stable. Too stable, in fact, and a temporal denoiser will not have enough temporal variation to operate effectively. The denoiser will see that the signal in each pixel has low temporal variance, and decide that it doesn't need to be blurred, so the result will be blotchy. The blotches will also fade in and out slowly, together with the noisy signal. Using a shorter history in ReSTIR helps increase temporal variation, but also increases noise. Another problem with using a single temporal pass is that in motion, the light samples tend to stick together and form clusters of bright pixels, which is even more confusing for the denoiser. These situations are illustrated on the animation below. -![Temporal resampling noise](images/TemporalNoise.gif) +![Temporal resampling noise](Images/TemporalNoise.gif) Adding a spatial resampling pass after temporal resampling improves the noise patterns significantly. One spatial sample helps break up the stable patterns and bright clusters, add enough variation for the denoiser to be effective. Two spatial samples improve the signal even more and reduce noise. @@ -58,7 +58,7 @@ One important aspect of bias correction is using correct temporal data. Since th The other two sources of bias - discarding invisible samples and visibility reuse - cannot be corrected, but these features are still useful when completely unbiased results are not necessary, for example, in games. Discarding invisible samples after the final shading pass is useful because it can significantly reduce noise in areas that are near the edge of the shadow cast by a powerful light. Note that a similar effect can be achieved by using ray traced bias correction, which is unbiased but more expensive. See the image below for a comparison of these techniques. -![Bias correction comparison](images/BiasCorrection.png) +![Bias correction comparison](Images/BiasCorrection.png) Final visibility reuse is an optimization that significantly reduces the number of rays traced for final shading. The renderer stores the final visibility as color in the reservoir, and that visibility is copied around when the reservoir is reused. When the final visibility is copied, the reservoir tracks the distance between the original location of the surface that generated the visibility term and the reservoir's current location, and the age of the visibility term, in frames. During final shading, the renderer can query if the reservoir has stored visibility and if it hasn't moved too far, and if everything is good, the stored visibility can be used instead of tracing a new ray. In our tests, this type of reuse has been shown to reduce the number of final visibility rays to 30% of its original value, with negligible visual difference. diff --git a/doc/RestirGI.md b/Doc/RestirGI.md similarity index 81% rename from doc/RestirGI.md rename to Doc/RestirGI.md index 09f919b..e1c79fb 100644 --- a/doc/RestirGI.md +++ b/Doc/RestirGI.md @@ -4,13 +4,13 @@ ReSTIR GI is a spatiotemporal resampling algorithm that is applied to samples of surfaces that produce indirect lighting. For comparison, regular ReSTIR DI operates on samples of lights that affect primary surfaces; ReSTIR GI converts every surface found by tracing BRDF-sampled rays from the primary surface into a light sample. -![ReSTIR GI](images/ReSTIRGI.png) +![ReSTIR GI](Images/ReSTIRGI.png) ## Integration model The RTXDI SDK's implementation of ReSTIR GI follows the same integration model as ReSTIR DI, with the resampling math encapsulated in a number of high-level functions that call various functions in the bridge for application interoperability. The application is expected to call these high-level functions from its own shaders. -The functions and structures necessary for ReSTIR GI implementation are defined in two header files: [`GIResamplingFunctions.hlsli`](../rtxdi-sdk/include/RTXDI/GIResamplingFunctions.hlsli) and [`GIReservoir.hlsli`](../rtxdi-sdk/include/RTXDI/GIReservoir.hlsli). See the [API reference](ShaderAPI-RestirGI.md) for more information on the ReSTIR GI functions and structures. +The functions and structures necessary for ReSTIR GI implementation are defined in the header files stored in the [`GI/`](../Libraries/Rtxdi/Include/RTXDI/GI/): See the [API reference](ShaderAPI-RestirGI.md) for more information on the ReSTIR GI functions and structures. The application needs to implement the various bridge functions necessary for ReSTIR GI in order to compile the shaders. ReSTIR GI and DI share the same bridge interface, and the sets of functions necessary for them intersect. The following shared bridge structures and functions are needed for ReSTIR GI and must be implemented: @@ -49,12 +49,12 @@ Note that the radiance of secondary surfaces is non-directional, which means tha Once the secondary surfaces or paths have been traced and shaded, the application should create a ReSTIR GI reservoir from it using the `RTXDI_MakeGIReservoir` function. That reservoir can be stored in a reservoir buffer for further resampling, or passed directly into a temporal or a spatiotemporal resampling function. See [ShadeSecondarySurfaces.hlsl](../shaders/LightingPasses/ShadeSecondarySurfaces.hlsl) for an example. -GI reservoirs created after path tracing can be immediately used for shading, without any resampling. This is a useful mode to verify that the math is correct, that no throughput or visibility term is left behind when ReSTIR GI is inserted into the pipeline. In the basic version (no MIS), the application should take the final GI reservoir for the current pixel and shade the primary surface using that reservoir as a regular emissive surface sample, multiplying the results with `weightSum` from the reservoir. The shading result replaces the original radiance produced by the path tracer. See [GIFinalShading.hlsl](../shaders/LightingPasses/GIFinalShading.hlsl) for an example. +GI reservoirs created after path tracing can be immediately used for shading, without any resampling. This is a useful mode to verify that the math is correct, that no throughput or visibility term is left behind when ReSTIR GI is inserted into the pipeline. In the basic version (no MIS), the application should take the final GI reservoir for the current pixel and shade the primary surface using that reservoir as a regular emissive surface sample, multiplying the results with `weightSum` from the reservoir. The shading result replaces the original radiance produced by the path tracer. See [FinalShading.hlsl](../shaders/LightingPasses/GI/FinalShading.hlsl) for an example. LightVector = normalize(reservoir.position - primarySurface.position) PrimaryReflectedIndirectRadiance = primarySurface.BRDF(LightVector, ViewVector) * reservoir.radiance * reservoir.weightSum -Once the GI reservoir creation and shading are working correctly, resampling passes can be inserted between these two stages. It can be a combination of temporal and spatial passes, or a fused spatiotemporal pass. In the former case, the [temporal pass](../shaders/LightingPasses/GITemporalResampling.hlsl) can be performed in the same shader that does path tracing and/or initial shading, and the [spatial pass](../shaders/LightingPasses/GISpatialResampling.hlsl) can be performed in the same shader that does final shading - or they can be separate shaders, whichever works faster. The sample application uses the separate approach. In the case of fused [spatiotemporal resampling](../shaders/LightingPasses/GIFusedResampling.hlsl), all passes can be done in the same shader, which is probably the easiest way to integrate ReSTIR GI into a path tracer, but it's likely not great for performance. +Once the GI reservoir creation and shading are working correctly, resampling passes can be inserted between these two stages. It can be a combination of temporal and spatial passes, or a fused spatiotemporal pass. In the former case, the [temporal pass](../shaders/LightingPasses/GI/TemporalResampling.hlsl) can be performed in the same shader that does path tracing and/or initial shading, and the [spatial pass](../shaders/LightingPasses/GI/SpatialResampling.hlsl) can be performed in the same shader that does final shading - or they can be separate shaders, whichever works faster. The sample application uses the separate approach. In the case of fused [spatiotemporal resampling](../shaders/LightingPasses/GI/FusedResampling.hlsl), all passes can be done in the same shader, which is probably the easiest way to integrate ReSTIR GI into a path tracer, but it's likely not great for performance. -In the final shading pass, multiple importance sampling (MIS) can be applied to recover some image quality lost on shiny surfaces. ReSTIR doesn't work well on specular surfaces with low roughness: the results may look like a more stable, but sparser noise pattern than the original signal, and that's bad for denoising. It's better to combine the ReSTIR GI output with its input in a MIS fashion and use the input signal on surfaces with low roughness. An example of such MIS scheme can be found in the sample application, in the [GIFinalShading.hlsl](../shaders/LightingPasses/GIFinalShading.hlsl) file - see the `GetMISWeight` function and its uses. \ No newline at end of file +In the final shading pass, multiple importance sampling (MIS) can be applied to recover some image quality lost on shiny surfaces. ReSTIR doesn't work well on specular surfaces with low roughness: the results may look like a more stable, but sparser noise pattern than the original signal, and that's bad for denoising. It's better to combine the ReSTIR GI output with its input in a MIS fashion and use the input signal on surfaces with low roughness. An example of such MIS scheme can be found in the sample application, in the [FinalShading.hlsl](../shaders/LightingPasses/GI/FinalShading.hlsl) file - see the `GetMISWeight` function and its uses. \ No newline at end of file diff --git a/doc/RtxdiApplicationBridge.md b/Doc/RtxdiApplicationBridge.md similarity index 91% rename from doc/RtxdiApplicationBridge.md rename to Doc/RtxdiApplicationBridge.md index 3e38933..229c9d6 100644 --- a/doc/RtxdiApplicationBridge.md +++ b/Doc/RtxdiApplicationBridge.md @@ -1,9 +1,9 @@ # RTXDI Application Bridge -The application must implement a number of structures and functions on the shader side that are necessary for the RTXDI resampling functions to operate. These structures and functions must be declared before including the main RTXDI header file, [`DIResamplingFunctions.hlsli`](../rtxdi-sdk/include/rtxdi/DIResamplingFunctions.hlsli). +The application must implement a number of structures and functions on the shader side that are necessary for the RTXDI resampling functions to operate. These structures and functions must be declared before including the main RTXDI header files. -A reference implementation of the bridge functions and structures with support for multiple light types and fractional visibility (translucency) can be found in [`RtxdiApplicationBridge.hlsli`](../shaders/LightingPasses/RtxdiApplicationBridge.hlsli). This implementation uses some functionality defined in other header files, most notably, polymorphic lights are implemented in [`PolymorphicLight.hlsli`](../shaders/PolymorphicLight.hlsli). +A reference implementation of the bridge functions and structures with support for multiple light types and fractional visibility (translucency) can be found in [`RtxdiApplicationBridge.hlsli`](../shaders/LightingPasses/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli). This implementation uses some functionality defined in other header files, most notably, polymorphic lights are implemented in [`PolymorphicLight.hlsli`](../shaders/PolymorphicLight.hlsli). The main application bridge file is itself a list of includes of other files, each of which handles a specific piece of the implementation. Below is a list of structures and functions that need to be implemented by the application, by category. @@ -13,10 +13,14 @@ All these structures are opaque, i.e. the library code makes no assumption about ### `RAB_Surface` -Stores information about a surface, including its position, orientation, and material parameters. In addition to that, a view direction should also be a part of the `RAB_Surface` structure. This structure must contain everything that is necessary to compute a material BRDF using the `RAB_GetLightSampleTargetPdfForSurface` function. +Stores information about a surface, including its position, orientation, and material parameters, the last of which must be accessible as an `RAB_Material` via the `RAB_GetMaterial` function. Additionally, a view direction should also be a part of the `RAB_Surface` structure. This structure must contain everything that is necessary to compute a material BRDF using the `RAB_GetLightSampleTargetPdfForSurface` function. Instances of `RAB_Surface` are constructed in the `RAB_GetGBufferSurface` function, which loads the surface information from either the current or the previous G-buffer given a pixel position, and is called from the temporal and spatial resampling functions. Alternatively, these instances can be produced directly in the primary rays shader, for example, and passed into the resampling functions as the current surface being shaded. +### `RAB_Material` + +Stores the material information for a surface. + ### `RAB_LightInfo` Stores information about a polymorphic light, i.e. a light of any type. Typically, this structure would contain a field encoding the light type, another field storing the light radiance, and other fields like position and orientation, whose interpretation depends on the specific light type. It's not a requirement however, and an implementation could choose to store lights of different types in different arrays, and keep only the light type and array index in the `RAB_LightInfo` structure, loading the specific light information only when sampling or weighing the light is performed. @@ -56,6 +60,11 @@ Returns an empty `RAB_LightInfo` object. Returns an empty `RAB_LightSample` object. +### `RAB_EmptyMaterial` + +`RAB_Material RAB_EmptyMaterial()` + +Returns an empty `RAB_Material` object. ## G-buffer Input and Accessor Functions @@ -63,7 +72,13 @@ Returns an empty `RAB_LightSample` object. `RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame)` -Loads a surface from the current or previous G-buffer at the specified pixel position. Pixel positions may be out-of-bounds or negative, in which case the function is supposed to return an invalid surface. Invalid surfaces are identified by `RAB_IsSurfaceValid` returning `false`. +Loads a surface from the current or previous G-buffer at the specified pixel position. Pixel positions may be out-of-bounds or negative, in which case the function is supposed to return an invalid surface. Invalid surfaces are identified by `RAB_IsSurfaceValid` returning `false`. Should call RAB_GetGBufferMaterial to fill in its RAB_Material data. + +### `RAB_GetGBufferMaterial` + +`RAB_Material RAB_GetGBufferMaterial(int2 pixelPosition, bool previousFrame)` + +Loads the material data from the current or previous G-buffer at the specified pixel position. Pixel positions may be out-of-bounds or negative, in which case the function is supposed to return an invalid surface. ### `RAB_IsSurfaceValid` @@ -101,11 +116,7 @@ This function is called in the spatial resampling passes to make sure that the s `RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame)` -Loads the information about a polymorphic light based on its index, on the current or previous frame. See [`RAB_LightInfo`](#rab_lightinfo) for the description of what information is required. The indices passed to this function will be in one of the three ranges provided to `rtxdi::Context::FillRuntimeParameters(...)`: - -- `firstLocalLight` ... `firstLocalLight + numLocalLights - 1`: local lights; -- `firstInfiniteLight` ... `firstInfiniteLight + numInfiniteLights - 1` : infinite lights; -- `environmentLightIndex`: importance sampled environment light, if `environmentLightPresent` is `true`. +Loads the information about a polymorphic light based on its index, on the current or previous frame. See [`RAB_LightInfo`](#rab_lightinfo) for the description of what information is required. The indices passed to this function will be in one of the three ranges provided to `RTXDI_LightBufferParameters`. These ranges do not have to be continuously packed in one buffer or start at zero. The application can choose to use some higher bits in the light index to store information. The lower 31 bit of the light index are available; the highest bit is reserved for internal use. diff --git a/doc/ShaderAPI-RestirGI.md b/Doc/ShaderAPI-RestirGI.md similarity index 100% rename from doc/ShaderAPI-RestirGI.md rename to Doc/ShaderAPI-RestirGI.md diff --git a/doc/ShaderAPI.md b/Doc/ShaderAPI.md similarity index 98% rename from doc/ShaderAPI.md rename to Doc/ShaderAPI.md index 1d58d7c..a94fb16 100644 --- a/doc/ShaderAPI.md +++ b/Doc/ShaderAPI.md @@ -1,6 +1,6 @@ # RTXDI Shader API -Most of the RTXDI functionality is implemented in shaders. To use this functionality, include the [`DIResamplingFunctions.hlsli`](../rtxdi-sdk/include/rtxdi/DIResamplingFunctions.hlsli) file into your shader source code, after defining (or at least declaring) the [bridge functions](RtxdiApplicationBridge.md). +Most of the RTXDI functionality is implemented in shaders. To use this functionality, include the appropriate header file(s) from the [`DI/`](../Libaries/Rtxdi/Include/Rtxdi/DI/) folder into your shader source code, after defining (or at least declaring) the [bridge functions](RtxdiApplicationBridge.md). Below is the list of shader structures and functions provided by RTXDI that can be useful to applications. Some internal functions are not shown. @@ -39,6 +39,7 @@ Define this macro to one of the `RTXDI_REGIR_DISABLED`, `RTXDI_REGIR_GRID`, `RTX Define this macro to a resource name for the RIS buffer, which should have HLSL type `RWBuffer`. Not necessary when `RTXDI_ENABLE_PRESAMPLING` is `0`. + ## Structures ### `RTXDI_PackedDIReservoir` @@ -187,6 +188,7 @@ Adds `newReservoir` into `reservoir`, returns true if the new reservoir's sample This is a very general form, allowing input parameters to specify normalization and `targetPdf` rather than computing them from `newReservoir`. + ## Low-Level Sampling Functions ### `RTXDI_SamplePdfMipmap` @@ -202,7 +204,6 @@ Performs importance sampling of a set of items with their PDF values stored in a The function returns the position of the final selected texel in the `position` parameter, and its normalized selection PDF in the `pdf` parameter. If the PDF texture is empty or malformed (i.e. has four adjacent zeros in one mip level and a nonzero corresponding texel in the next mip level), the returned PDF will be zero. - ### `RTXDI_PresampleLocalLights` void RTXDI_PresampleLocalLights( @@ -345,7 +346,6 @@ Called to finish the process of doing pairwise MIS. This function must be calle compensates for this overweighting, but it can only happen after all neighbors have been processed. - ## High-Level Sampling and Resampling Functions ### `RTXDI_SampleLightsForSurface` @@ -465,13 +465,12 @@ Applies a boiling filter over all threads in the compute shader thread group. Th ``` RTXDI_SampleParameters RTXDI_InitSampleParameters( - uint numRegirSamples, uint numLocalLightSamples, uint numInfiniteLightSamples, uint numEnvironmentMapSamples, uint numBrdfSamples, - float brdfCutoff = 0.0, - float brdfRayMinT = 0.001 + float brdfCutoff RTXDI_DEFAULT(0.0f), + float brdfRayMinT RTXDI_DEFAULT(0.001f)) ``` Initializes the [`RTXDI_SampleParameters`](#rtxdi_sampleparameters) structure from the sample counts and BRDF sampling parameters. The structure should be the same when passed to various resampling functions to ensure correct MIS application. diff --git a/DLSS b/External/DLSS similarity index 100% rename from DLSS rename to External/DLSS diff --git a/DLSS.cmake b/External/DLSS.cmake similarity index 95% rename from DLSS.cmake rename to External/DLSS.cmake index f48028d..591c6c4 100644 --- a/DLSS.cmake +++ b/External/DLSS.cmake @@ -1,5 +1,5 @@ -set(dlss_sdk "${CMAKE_CURRENT_SOURCE_DIR}/DLSS") +set(dlss_sdk "${CMAKE_CURRENT_SOURCE_DIR}/external/DLSS") if (WIN32) add_library(DLSS SHARED IMPORTED) diff --git a/NRD b/External/NRD similarity index 100% rename from NRD rename to External/NRD diff --git a/NRD.cmake b/External/NRD.cmake similarity index 94% rename from NRD.cmake rename to External/NRD.cmake index b009227..35d6c84 100644 --- a/NRD.cmake +++ b/External/NRD.cmake @@ -8,7 +8,7 @@ if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/NRD/CMakeLists.txt") set (NRD_SHADERS_PATH "${CMAKE_CURRENT_BINARY_DIR}/NRD_Shaders" CACHE STRING "") option(NRD_STATIC_LIBRARY "" ON) - add_subdirectory(NRD) + add_subdirectory(external/NRD) set_target_properties(NRD PROPERTIES FOLDER NRD) set_target_properties(NRD_Shaders PROPERTIES FOLDER NRD) diff --git a/thirdparty/cxxopts b/External/cxxopts similarity index 100% rename from thirdparty/cxxopts rename to External/cxxopts diff --git a/External/donut b/External/donut new file mode 160000 index 0000000..04c9b20 --- /dev/null +++ b/External/donut @@ -0,0 +1 @@ +Subproject commit 04c9b20189ea59629c888f260cd3a3cef0119010 diff --git a/Libraries/Rtxdi b/Libraries/Rtxdi new file mode 160000 index 0000000..e5c953c --- /dev/null +++ b/Libraries/Rtxdi @@ -0,0 +1 @@ +Subproject commit e5c953c275b17c9a2fbaa12dab8b3805d87440f7 diff --git a/README.md b/README.md index c172749..66b1508 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # RTXDI SDK and Sample Applications -Version 2.2.0. +Version 2.3.0. [Change Log](ChangeLog.md) @@ -15,31 +15,30 @@ For more information about RTXDI, see the [NVIDIA Developer Page](https://develo ## Package Contents -[`rtxdi-runtime`](https://github.com/NVIDIAGameWorks/rtxdi-runtime) is a submodule that contains the integrable runtime sources that are meant to be included in the application build: +[`Libraries/Rtxdi`](https://github.com/NVIDIAGameWorks/rtxdi-runtime) is a submodule that contains the integrable runtime sources that are meant to be included in the application build: -- [`rtxdi-runtime/include/rtxdi`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/include/rtxdi) has the include files, both for host code and for shaders -- [`rtxdi-runtime/include/rtxdi/DIResamplingFunctions.hlsli`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/include/rtxdi/DIResamplingFunctions.hlsli) and [`rtxdi-runtime/include/rtxdi/GIResamplingFunctions.hlsli`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/include/rtxdi/GIResamplingFunctions.hlsli) are the main shader includes that contain the resampling implementations -- [`rtxdi-runtime/src`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/src) has the host code with various utility functions for setting up the parameters and resources for resampling +- [`Rtxdi/Include/Rtxdi`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/include/rtxdi) has the include files, both for host code and for shaders. +- [`Rtxdi/Include/Rtxdi/DI/`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/Include/Rtxdi/DI/) and [`Rtxdi/Include/Rtxdi/GI/`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/Include/Rtxdi/GI/) are the main shader include folders that contain the resampling implementations for their respective algorithms. +- [`Rtxdi/Source`](https://github.com/NVIDIAGameWorks/rtxdi-runtime/tree/main/Source) has the host code with various utility functions for setting up the parameters and resources for resampling. -[`src`](src) contains the sample application host code. +[`Samples`](Samples) contains two sample projects, [`MinimalSample`](Samples/MinimalSample) and [`FullSample`](Samples/FullSample). The [`MinimalSample/Source`](Samples/MinimalSample/Source) project implements ReSTIR DI in a single combined pass to show a minimum viable implementation. The [`FullSample/Source`](Samples/FullSample/Source) project implements ReSTIR DI in several passes integrated into a broader rendering pipeline to show a more standard implementation. The shaders for each project live in their respective [`MinimalSample/Shaders`](Samples/MinimalSample/Shaders) and [`FullSample/Shaders`](Samples/FullSample/Shaders) folders. -[`shaders`](shaders) contains the sample application shaders. +[`External`](External) contains project dependencies both from Nvidia and third parties: -[`donut`](donut) is a submodule structure with the ["Donut" rendering framework](https://github.com/NVIDIAGameWorks/donut) used to build the sample apps. +- [`External/donut`](External/donut) is a Git submodule structure with the ["Donut" rendering framework](https://github.com/NVIDIAGameWorks/donut) used to build the sample apps. -[`NRD`](NRD) is a submodule with the ["NRD" denoiser library](https://github.com/NVIDIAGameWorks/RayTracingDenoiser). +- [`External/NRD`](External/NRD) is a Git submodule with the ["NRD" denoiser library](https://github.com/NVIDIAGameWorks/RayTracingDenoiser). -[`DLSS`](DLSS) is a submodule with the [Deep Learning Super-Sampling SDK](https://github.com/NVIDIA/DLSS). +- [`External/DLSS`](External/DLSS) is a Git submodule with the [Deep Learning Super-Sampling SDK](https://github.com/NVIDIA/DLSS). -[`rtxdi-assets`](https://github.com/NVIDIAGameWorks/rtxdi-assets) is a submodule containing the [RTXDI SDK Sample Assets](https://github.com/NVIDIAGameWorks/rtxdi-assets). +- `External/dxc` is a recent version of DirectX Shader Compiler. However, unlike the other dependencies, it is not a Git submodule but is instead fetched by CMake at project configuration time. -Additional content delivered during CMake configuration: +[`Assets/Media`](https://github.com/NVIDIAGameWorks/rtxdi-assets) is a Git submodule containing the [RTXDI SDK Sample Assets](https://github.com/NVIDIAGameWorks/rtxdi-assets). -`thirdparty/dxc` is a recent version of DirectX Shader Compiler. ## Building and Running the Sample Apps -**Note** that because the [`rtxdi-assets`](https://github.com/NVIDIAGameWorks/rtxdi-assets) submodule uses LFS. Cloning it without [LFS](https://git-lfs.com) installed will result in files containing LFS pointers instead of the actual assets. +**Note** that because the [`rtxdi-assets`](https://github.com/NVIDIAGameWorks/rtxdi-assets) submodule that is cloned into `Assets/Media` uses LFS, cloning it without [LFS](https://git-lfs.com) installed will result in files containing LFS pointers instead of the actual assets. ### Windows @@ -64,7 +63,7 @@ Additional content delivered during CMake configuration: 7. Build the solution with Visual Studio -8. Run the `rtxdi-sample` or `minimal-sample` projects. +8. Run the `FullSample` or `MinimalSample` projects. ### Linux @@ -91,7 +90,7 @@ Additional content delivered during CMake configuration: - `make -j8` (example for an 8-core CPU, or use [Ninja](https://ninja-build.org) instead) 7. Run: - - `bin/rtxdi-sample` or `bin/minimal-sample` + - `bin/FullSample` or `bin/MinimalSample` ### Vulkan support diff --git a/shaders/AccumulationPass.hlsl b/Samples/FullSample/Shaders/AccumulationPass.hlsl similarity index 97% rename from shaders/AccumulationPass.hlsl rename to Samples/FullSample/Shaders/AccumulationPass.hlsl index 3e28796..cfbd01a 100644 --- a/shaders/AccumulationPass.hlsl +++ b/Samples/FullSample/Shaders/AccumulationPass.hlsl @@ -12,7 +12,7 @@ #include "ShaderParameters.h" #include "HelperFunctions.hlsli" -#include +#include VK_PUSH_CONSTANT ConstantBuffer g_Const : register(b0); diff --git a/shaders/BRDFPTParameters.h b/Samples/FullSample/Shaders/BRDFPTParameters.h similarity index 97% rename from shaders/BRDFPTParameters.h rename to Samples/FullSample/Shaders/BRDFPTParameters.h index 309ed9d..fe7eab8 100644 --- a/shaders/BRDFPTParameters.h +++ b/Samples/FullSample/Shaders/BRDFPTParameters.h @@ -11,7 +11,7 @@ #ifndef RTXDI_BRDFPT_PARAMETERS_H #define RTXDI_BRDFPT_PARAMETERS_H -#include +#include struct BRDFPathTracing_MaterialOverrideParameters { diff --git a/Samples/FullSample/Shaders/CMakeLists.txt b/Samples/FullSample/Shaders/CMakeLists.txt new file mode 100644 index 0000000..ad93179 --- /dev/null +++ b/Samples/FullSample/Shaders/CMakeLists.txt @@ -0,0 +1,133 @@ + +include("${DONUT_PATH}/compileshaders.cmake") + +set(shaders + DebugViz/NDirOctUNorm32Viz.hlsl + DebugViz/PackedR11G11B10UFloatViz.hlsl + DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl + DenoisingPasses/ComputeGradients.hlsl + DenoisingPasses/ConfidencePass.hlsl + DenoisingPasses/FilterGradientsPass.hlsl + LightingPasses/DI/FusedResampling.hlsl + LightingPasses/DI/GenerateInitialSamples.hlsl + LightingPasses/DI/ShadeSamples.hlsl + LightingPasses/DI/SpatialResampling.hlsl + LightingPasses/DI/TemporalResampling.hlsl + LightingPasses/GI/FinalShading.hlsl + LightingPasses/GI/FusedResampling.hlsl + LightingPasses/GI/SpatialResampling.hlsl + LightingPasses/GI/TemporalResampling.hlsl + LightingPasses/Presampling/PresampleEnvironmentMap.hlsl + LightingPasses/Presampling/PresampleLights.hlsl + LightingPasses/Presampling/PresampleReGIR.hlsl + LightingPasses/BrdfRayTracing.hlsl + LightingPasses/RtxdiApplicationBridge/RAB_Buffers.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_LightInfo.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_LightSample.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_LightSampling.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_Material.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_RayPayload.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_RTShaders.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_Surface.hlsli + LightingPasses/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli + LightingPasses/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli + LightingPasses/ShadeSecondarySurfaces.hlsl + LightingPasses/ShadingHelpers.hlsli + AccumulationPass.hlsl + BRDFPTParameters.h + CompositingPass.hlsl + DlssExposure.hlsl + GBufferHelpers.hlsli + GlassPass.hlsl + HelperFunctions.hlsli + GlassPass.hlsl + Helperfunctions.hlsli + LightShaping.hlsli + PolymorphicLight.hlsli + PostprocessGBuffer.hlsl + PrepareLights.hlsl + PreprocessEnvironmentMap.hlsl + RasterizedGBuffer.hlsl + RaytracedGBuffer.hlsl + RenderEnvironmentMap.hlsl + SceneGeometry.hlsli + ShaderParameters.h + VisualizeConfidence.hlsl + VisualizeHdrSignals.hlsl) + +# Organize MSVS filters (the little folders in the solution explorer) to match the folder structure +foreach(source IN LISTS shaders) + get_filename_component(source_path "${source}" PATH) + string(REPLACE "/" "\\" source_path_msvc "${source_path}") + source_group("${source_path_msvc}" FILES "${source}") +endforeach() + +set(project FullSample) +set(folder "RTXDI SDK") +set(shaders_target FullSampleShaders) + +add_custom_target(${shaders_target} + DEPENDS ShaderMake + SOURCES ${shaders} Shaders.cfg) + +if(TARGET NRD) + set(NRD_OPTIONS -I "${CMAKE_CURRENT_SOURCE_DIR}/../../../external/NRD/Shaders/Include" -D WITH_NRD -D NRD_USE_OCT_NORMAL_ENCODING=0 -D NRD_USE_MATERIAL_ID=0) +else() + set(NRD_OPTIONS --relaxedInclude NRD.hlsli) +endif() + +set (OUTPUT_PATH_BASE "${CMAKE_BINARY_DIR}/bin/shaders/full-sample") + + if (WIN32) + set (USE_API_OPTION --useAPI) + else() + set (USE_API_OPTION "") + endif() + +if (DONUT_WITH_DX12) + set(DX12_COMPILER_OPTIONS + --platform DXIL + --shaderModel 6_5 + --binaryBlob + --outputExt .bin + -I ${DONUT_SHADER_INCLUDE_DIR} + -I ${RTXDI_RUNTIME_INCLUDE_PATH} + --relaxedInclude "../Types.h" + ${NRD_OPTIONS} + ${USE_API_OPTION} + --compiler ${DXC_PATH}) + + add_custom_command(TARGET ${shaders_target} PRE_BUILD + COMMAND ShaderMake + --config ${CMAKE_CURRENT_SOURCE_DIR}/Shaders.cfg + --out ${OUTPUT_PATH_BASE}/dxil + ${DX12_COMPILER_OPTIONS}) +endif() + +if (DONUT_WITH_VULKAN) + set(VULKAN_COMPILER_OPTIONS + --platform SPIRV + --shaderModel 6_5 + --vulkanVersion 1.2 + --binaryBlob + --outputExt .bin + -I ${DONUT_SHADER_INCLUDE_DIR} + -I ${RTXDI_RUNTIME_INCLUDE_PATH} + --relaxedInclude "../Types.h" + ${NRD_OPTIONS} + ${USE_API_OPTION} + ${NVRHI_DEFAULT_VK_REGISTER_OFFSETS} + -D SPIRV + --compiler ${DXC_SPIRV_PATH}) + + add_custom_command(TARGET ${shaders_target} PRE_BUILD + COMMAND ShaderMake + --config ${CMAKE_CURRENT_SOURCE_DIR}/Shaders.cfg + --out ${OUTPUT_PATH_BASE}/spirv + ${VULKAN_COMPILER_OPTIONS}) +endif() + +set_target_properties(${shaders_target} PROPERTIES FOLDER ${folder}) +set_source_files_properties(${shaders} PROPERTIES VS_TOOL_OVERRIDE "None") diff --git a/shaders/CompositingPass.hlsl b/Samples/FullSample/Shaders/CompositingPass.hlsl similarity index 100% rename from shaders/CompositingPass.hlsl rename to Samples/FullSample/Shaders/CompositingPass.hlsl diff --git a/shaders/DebugViz/NDirOctUNorm32Viz.hlsl b/Samples/FullSample/Shaders/DebugViz/NDirOctUNorm32Viz.hlsl similarity index 100% rename from shaders/DebugViz/NDirOctUNorm32Viz.hlsl rename to Samples/FullSample/Shaders/DebugViz/NDirOctUNorm32Viz.hlsl diff --git a/shaders/DebugViz/PackedR11G11B10UFloatViz.hlsl b/Samples/FullSample/Shaders/DebugViz/PackedR11G11B10UFloatViz.hlsl similarity index 100% rename from shaders/DebugViz/PackedR11G11B10UFloatViz.hlsl rename to Samples/FullSample/Shaders/DebugViz/PackedR11G11B10UFloatViz.hlsl diff --git a/shaders/DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl b/Samples/FullSample/Shaders/DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl similarity index 100% rename from shaders/DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl rename to Samples/FullSample/Shaders/DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl diff --git a/shaders/LightingPasses/DIComputeGradients.hlsl b/Samples/FullSample/Shaders/DenoisingPasses/ComputeGradients.hlsl similarity index 97% rename from shaders/LightingPasses/DIComputeGradients.hlsl rename to Samples/FullSample/Shaders/DenoisingPasses/ComputeGradients.hlsl index febd534..da891b1 100644 --- a/shaders/LightingPasses/DIComputeGradients.hlsl +++ b/Samples/FullSample/Shaders/DenoisingPasses/ComputeGradients.hlsl @@ -10,15 +10,15 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "../LightingPasses/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include "Rtxdi/DI/Reservoir.hlsli" #ifdef WITH_NRD #undef WITH_NRD #endif -#include "ShadingHelpers.hlsli" +#include "../LightingPasses/ShadingHelpers.hlsli" #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] @@ -152,7 +152,7 @@ void RayGen() /* previousFrameTLAS = */ !usePrevSample, /* enableVisibilityReuse = */ false, diffuse, specular, lightDistance); // Calculate the sampled lighting luminance for the other surface - float2 newDiffSpecLum = float2(calcLuminance(diffuse * surface.diffuseAlbedo), calcLuminance(specular)); + float2 newDiffSpecLum = float2(calcLuminance(diffuse * surface.material.diffuseAlbedo), calcLuminance(specular)); // Convert to FP16 and back to avoid false-positive gradients due to precision loss in the // u_RestirLuminance and t_PrevRestirLuminance textures where selectedDiffSpecLum comes from. diff --git a/shaders/ConfidencePass.hlsl b/Samples/FullSample/Shaders/DenoisingPasses/ConfidencePass.hlsl similarity index 98% rename from shaders/ConfidencePass.hlsl rename to Samples/FullSample/Shaders/DenoisingPasses/ConfidencePass.hlsl index 1549245..8b75042 100644 --- a/shaders/ConfidencePass.hlsl +++ b/Samples/FullSample/Shaders/DenoisingPasses/ConfidencePass.hlsl @@ -10,8 +10,8 @@ #pragma pack_matrix(row_major) -#include "ShaderParameters.h" -#include +#include "../ShaderParameters.h" +#include VK_PUSH_CONSTANT ConstantBuffer g_Const : register(b0); diff --git a/shaders/FilterGradientsPass.hlsl b/Samples/FullSample/Shaders/DenoisingPasses/FilterGradientsPass.hlsl similarity index 96% rename from shaders/FilterGradientsPass.hlsl rename to Samples/FullSample/Shaders/DenoisingPasses/FilterGradientsPass.hlsl index 8d675f3..4b3eab4 100644 --- a/shaders/FilterGradientsPass.hlsl +++ b/Samples/FullSample/Shaders/DenoisingPasses/FilterGradientsPass.hlsl @@ -10,8 +10,8 @@ #pragma pack_matrix(row_major) -#include "ShaderParameters.h" -#include +#include "../ShaderParameters.h" +#include VK_PUSH_CONSTANT ConstantBuffer g_Const : register(b0); diff --git a/shaders/DlssExposure.hlsl b/Samples/FullSample/Shaders/DlssExposure.hlsl similarity index 96% rename from shaders/DlssExposure.hlsl rename to Samples/FullSample/Shaders/DlssExposure.hlsl index 627c76f..8edb210 100644 --- a/shaders/DlssExposure.hlsl +++ b/Samples/FullSample/Shaders/DlssExposure.hlsl @@ -8,7 +8,7 @@ # license agreement from NVIDIA CORPORATION is strictly prohibited. **************************************************************************/ -#include +#include Buffer t_Source : register(t0); RWTexture2D u_Dest : register(u0); diff --git a/shaders/GBufferHelpers.hlsli b/Samples/FullSample/Shaders/GBufferHelpers.hlsli similarity index 100% rename from shaders/GBufferHelpers.hlsli rename to Samples/FullSample/Shaders/GBufferHelpers.hlsli diff --git a/shaders/GlassPass.hlsl b/Samples/FullSample/Shaders/GlassPass.hlsl similarity index 100% rename from shaders/GlassPass.hlsl rename to Samples/FullSample/Shaders/GlassPass.hlsl diff --git a/shaders/HelperFunctions.hlsli b/Samples/FullSample/Shaders/HelperFunctions.hlsli similarity index 99% rename from shaders/HelperFunctions.hlsli rename to Samples/FullSample/Shaders/HelperFunctions.hlsli index 0fc8ee1..2679c1a 100644 --- a/shaders/HelperFunctions.hlsli +++ b/Samples/FullSample/Shaders/HelperFunctions.hlsli @@ -12,7 +12,7 @@ #define HELPER_FUNCTIONS_HLSLI #include -#include +#include static const float c_pi = 3.1415926535; diff --git a/shaders/LightShaping.hlsli b/Samples/FullSample/Shaders/LightShaping.hlsli similarity index 100% rename from shaders/LightShaping.hlsli rename to Samples/FullSample/Shaders/LightShaping.hlsli diff --git a/shaders/LightingPasses/BrdfRayTracing.hlsl b/Samples/FullSample/Shaders/LightingPasses/BrdfRayTracing.hlsl similarity index 94% rename from shaders/LightingPasses/BrdfRayTracing.hlsl rename to Samples/FullSample/Shaders/LightingPasses/BrdfRayTracing.hlsl index a0f49de..e130567 100644 --- a/shaders/LightingPasses/BrdfRayTracing.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/BrdfRayTracing.hlsl @@ -10,9 +10,9 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include #ifdef WITH_NRD #define NRD_HEADER_ONLY @@ -60,7 +60,7 @@ void RayGen() float3 V = normalize(g_Const.view.cameraDirectionOrPosition.xyz - surface.worldPos); bool isSpecularRay = false; - bool isDeltaSurface = surface.roughness == 0; + bool isDeltaSurface = surface.material.roughness == 0; float specular_PDF; float3 BRDF_over_PDF; float overall_PDF; @@ -70,14 +70,14 @@ void RayGen() float3 specular_BRDF_over_PDF; { float3 Ve = float3(dot(V, tangent), dot(V, bitangent), dot(V, surface.normal)); - float3 He = sampleGGX_VNDF(Ve, surface.roughness, Rand); + float3 He = sampleGGX_VNDF(Ve, surface.material.roughness, Rand); float3 H = isDeltaSurface ? surface.normal : normalize(He.x * tangent + He.y * bitangent + He.z * surface.normal); specularDirection = reflect(-V, H); float HoV = saturate(dot(H, V)); float NoV = saturate(dot(surface.normal, V)); - float3 F = Schlick_Fresnel(surface.specularF0, HoV); - float G1 = isDeltaSurface ? 1.0 : (NoV > 0) ? G1_Smith(surface.roughness, NoV) : 0; + float3 F = Schlick_Fresnel(surface.material.specularF0, HoV); + float G1 = isDeltaSurface ? 1.0 : (NoV > 0) ? G1_Smith(surface.material.roughness, NoV) : 0; specular_BRDF_over_PDF = F * G1; } @@ -91,7 +91,7 @@ void RayGen() } specular_PDF = saturate(calcLuminance(specular_BRDF_over_PDF) / - calcLuminance(specular_BRDF_over_PDF + diffuse_BRDF_over_PDF * surface.diffuseAlbedo)); + calcLuminance(specular_BRDF_over_PDF + diffuse_BRDF_over_PDF * surface.material.diffuseAlbedo)); isSpecularRay = RAB_GetNextRandom(rng) < specular_PDF; @@ -106,7 +106,7 @@ void RayGen() BRDF_over_PDF = diffuse_BRDF_over_PDF / (1.0 - specular_PDF); } - const float specularLobe_PDF = ImportanceSampleGGX_VNDF_PDF(surface.roughness, surface.normal, V, ray.Direction); + const float specularLobe_PDF = ImportanceSampleGGX_VNDF_PDF(surface.material.roughness, surface.normal, V, ray.Direction); const float diffuseLobe_PDF = saturate(dot(ray.Direction, surface.normal)) / c_pi; // For delta surfaces, we only pass the diffuse lobe to ReSTIR GI, and this pdf is for that. @@ -295,10 +295,10 @@ void RayGen() float diffuseHitT = payload.committedRayT; float specularHitT = payload.committedRayT; - specular = DemodulateSpecular(surface.specularF0, specular); + specular = DemodulateSpecular(surface.material.specularF0, specular); StoreShadingOutput(GlobalIndex, pixelPosition, - surface.viewDepth, surface.roughness, diffuse, specular, payload.committedRayT, !g_Const.enableBrdfAdditiveBlend, !g_Const.enableBrdfIndirect); + surface.viewDepth, surface.material.roughness, diffuse, specular, payload.committedRayT, !g_Const.enableBrdfAdditiveBlend, !g_Const.enableBrdfIndirect); } } diff --git a/shaders/LightingPasses/DIFusedResampling.hlsl b/Samples/FullSample/Shaders/LightingPasses/DI/FusedResampling.hlsl similarity index 90% rename from shaders/LightingPasses/DIFusedResampling.hlsl rename to Samples/FullSample/Shaders/LightingPasses/DI/FusedResampling.hlsl index a56140b..7d7b673 100644 --- a/shaders/LightingPasses/DIFusedResampling.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/DI/FusedResampling.hlsl @@ -15,12 +15,13 @@ #define RTXDI_BOILING_FILTER_GROUP_SIZE RTXDI_SCREEN_SPACE_GROUP_SIZE #endif -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include -#include +#include +#include +#include #if RTXDI_REGIR_MODE != RTXDI_REGIR_DISABLED -#include "rtxdi/ReGIRSampling.hlsli" +#include "Rtxdi/ReGIR/ReGIRSampling.hlsli" #endif #ifdef WITH_NRD @@ -29,7 +30,7 @@ #include #endif -#include "ShadingHelpers.hlsli" +#include "../ShadingHelpers.hlsli" #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] @@ -130,9 +131,9 @@ void RayGen() ShadeSurfaceWithLightSample(reservoir, surface, lightSample, /* previousFrameTLAS = */ false, /* enableVisibilityReuse = */ true, diffuse, specular, lightDistance); - currLuminance = float2(calcLuminance(diffuse * surface.diffuseAlbedo), calcLuminance(specular)); + currLuminance = float2(calcLuminance(diffuse * surface.material.diffuseAlbedo), calcLuminance(specular)); - specular = DemodulateSpecular(surface.specularF0, specular); + specular = DemodulateSpecular(surface.material.specularF0, specular); } // Store the sampled lighting luminance for the gradient pass. @@ -149,5 +150,5 @@ void RayGen() #endif StoreShadingOutput(GlobalIndex, pixelPosition, - surface.viewDepth, surface.roughness, diffuse, specular, lightDistance, true, g_Const.restirDI.shadingParams.enableDenoiserInputPacking); + surface.viewDepth, surface.material.roughness, diffuse, specular, lightDistance, true, g_Const.restirDI.shadingParams.enableDenoiserInputPacking); } \ No newline at end of file diff --git a/shaders/LightingPasses/DIGenerateInitialSamples.hlsl b/Samples/FullSample/Shaders/LightingPasses/DI/GenerateInitialSamples.hlsl similarity index 96% rename from shaders/LightingPasses/DIGenerateInitialSamples.hlsl rename to Samples/FullSample/Shaders/LightingPasses/DI/GenerateInitialSamples.hlsl index fa2ca70..15e690e 100644 --- a/shaders/LightingPasses/DIGenerateInitialSamples.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/DI/GenerateInitialSamples.hlsl @@ -10,9 +10,9 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] diff --git a/shaders/LightingPasses/DIShadeSamples.hlsl b/Samples/FullSample/Shaders/LightingPasses/DI/ShadeSamples.hlsl similarity index 84% rename from shaders/LightingPasses/DIShadeSamples.hlsl rename to Samples/FullSample/Shaders/LightingPasses/DI/ShadeSamples.hlsl index c4db00c..db23e7b 100644 --- a/shaders/LightingPasses/DIShadeSamples.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/DI/ShadeSamples.hlsl @@ -10,11 +10,12 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" + +#include "Rtxdi/DI/Reservoir.hlsli" -#include #if RTXDI_REGIR_MODE != RTXDI_REGIR_DISABLED -#include "rtxdi/ReGIRSampling.hlsli" +#include "Rtxdi/ReGIR/ReGIRSampling.hlsli" #endif #ifdef WITH_NRD @@ -23,7 +24,7 @@ #include #endif -#include "ShadingHelpers.hlsli" +#include "../ShadingHelpers.hlsli" #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] @@ -60,9 +61,9 @@ void RayGen() bool needToStore = ShadeSurfaceWithLightSample(reservoir, surface, lightSample, /* previousFrameTLAS = */ false, /* enableVisibilityReuse = */ true, diffuse, specular, lightDistance); - currLuminance = float2(calcLuminance(diffuse * surface.diffuseAlbedo), calcLuminance(specular)); + currLuminance = float2(calcLuminance(diffuse * surface.material.diffuseAlbedo), calcLuminance(specular)); - specular = DemodulateSpecular(surface.specularF0, specular); + specular = DemodulateSpecular(surface.material.specularF0, specular); if (needToStore) { @@ -82,5 +83,5 @@ void RayGen() #endif StoreShadingOutput(GlobalIndex, pixelPosition, - surface.viewDepth, surface.roughness, diffuse, specular, lightDistance, true, g_Const.restirDI.shadingParams.enableDenoiserInputPacking); + surface.viewDepth, surface.material.roughness, diffuse, specular, lightDistance, true, g_Const.restirDI.shadingParams.enableDenoiserInputPacking); } diff --git a/shaders/LightingPasses/DISpatialResampling.hlsl b/Samples/FullSample/Shaders/LightingPasses/DI/SpatialResampling.hlsl similarity index 96% rename from shaders/LightingPasses/DISpatialResampling.hlsl rename to Samples/FullSample/Shaders/LightingPasses/DI/SpatialResampling.hlsl index 8d9d375..48fdfb4 100644 --- a/shaders/LightingPasses/DISpatialResampling.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/DI/SpatialResampling.hlsl @@ -10,9 +10,9 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] diff --git a/shaders/LightingPasses/DITemporalResampling.hlsl b/Samples/FullSample/Shaders/LightingPasses/DI/TemporalResampling.hlsl similarity index 96% rename from shaders/LightingPasses/DITemporalResampling.hlsl rename to Samples/FullSample/Shaders/LightingPasses/DI/TemporalResampling.hlsl index 7eff199..d018874 100644 --- a/shaders/LightingPasses/DITemporalResampling.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/DI/TemporalResampling.hlsl @@ -16,9 +16,10 @@ #define RTXDI_BOILING_FILTER_GROUP_SIZE RTXDI_SCREEN_SPACE_GROUP_SIZE #endif -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include +#include #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] diff --git a/shaders/LightingPasses/GIFinalShading.hlsl b/Samples/FullSample/Shaders/LightingPasses/GI/FinalShading.hlsl similarity index 88% rename from shaders/LightingPasses/GIFinalShading.hlsl rename to Samples/FullSample/Shaders/LightingPasses/GI/FinalShading.hlsl index cf452bf..bde6d5a 100644 --- a/shaders/LightingPasses/GIFinalShading.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/GI/FinalShading.hlsl @@ -10,9 +10,11 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" +#include "../ShadingHelpers.hlsli" -#include +#include +#include #ifdef WITH_NRD #define NRD_HEADER_ONLY @@ -20,7 +22,7 @@ #include #endif -#include "ShadingHelpers.hlsli" +#include "../ShadingHelpers.hlsli" static const float kMaxBrdfValue = 1e4; static const float kMISRoughness = 0.3; @@ -94,13 +96,13 @@ void RayGen() const SplitBrdf brdf0 = EvaluateBrdf(primarySurface, initialReservoir.position); RAB_Surface roughenedSurface = primarySurface; - roughenedSurface.roughness = max(roughenedSurface.roughness, kMISRoughness); + roughenedSurface.material.roughness = max(roughenedSurface.material.roughness, kMISRoughness); const SplitBrdf roughBrdf = EvaluateBrdf(roughenedSurface, reservoir.position); const SplitBrdf roughBrdf0 = EvaluateBrdf(roughenedSurface, initialReservoir.position); - const float finalWeight = 1.0 - GetMISWeight(roughBrdf, brdf, primarySurface.diffuseAlbedo); - const float initialWeight = GetMISWeight(roughBrdf0, brdf0, primarySurface.diffuseAlbedo); + const float finalWeight = 1.0 - GetMISWeight(roughBrdf, brdf, primarySurface.material.diffuseAlbedo); + const float initialWeight = GetMISWeight(roughBrdf0, brdf0, primarySurface.material.diffuseAlbedo); const float3 initialRadiance = initialReservoir.radiance * initialReservoir.weightSum; @@ -117,9 +119,9 @@ void RayGen() } - specular = DemodulateSpecular(primarySurface.specularF0, specular); + specular = DemodulateSpecular(primarySurface.material.specularF0, specular); } StoreShadingOutput(GlobalIndex, pixelPosition, - primarySurface.viewDepth, primarySurface.roughness, diffuse, specular, 0, false, true); + primarySurface.viewDepth, primarySurface.material.roughness, diffuse, specular, 0, false, true); } diff --git a/shaders/LightingPasses/GIFusedResampling.hlsl b/Samples/FullSample/Shaders/LightingPasses/GI/FusedResampling.hlsl similarity index 96% rename from shaders/LightingPasses/GIFusedResampling.hlsl rename to Samples/FullSample/Shaders/LightingPasses/GI/FusedResampling.hlsl index 3485997..2cc470c 100644 --- a/shaders/LightingPasses/GIFusedResampling.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/GI/FusedResampling.hlsl @@ -15,9 +15,10 @@ #define RTXDI_BOILING_FILTER_GROUP_SIZE RTXDI_SCREEN_SPACE_GROUP_SIZE #endif -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include +#include #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] diff --git a/shaders/LightingPasses/GISpatialResampling.hlsl b/Samples/FullSample/Shaders/LightingPasses/GI/SpatialResampling.hlsl similarity index 95% rename from shaders/LightingPasses/GISpatialResampling.hlsl rename to Samples/FullSample/Shaders/LightingPasses/GI/SpatialResampling.hlsl index a1f55d5..eb2a26b 100644 --- a/shaders/LightingPasses/GISpatialResampling.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/GI/SpatialResampling.hlsl @@ -10,10 +10,9 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" - -#include +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" +#include #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] diff --git a/shaders/LightingPasses/GITemporalResampling.hlsl b/Samples/FullSample/Shaders/LightingPasses/GI/TemporalResampling.hlsl similarity index 94% rename from shaders/LightingPasses/GITemporalResampling.hlsl rename to Samples/FullSample/Shaders/LightingPasses/GI/TemporalResampling.hlsl index 4f09d59..fcb4601 100644 --- a/shaders/LightingPasses/GITemporalResampling.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/GI/TemporalResampling.hlsl @@ -1,5 +1,5 @@ /*************************************************************************** - # Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. + # Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. # # NVIDIA CORPORATION and its licensors retain all intellectual property # and proprietary rights in and to this software, related documentation @@ -15,9 +15,10 @@ #define RTXDI_BOILING_FILTER_GROUP_SIZE RTXDI_SCREEN_SPACE_GROUP_SIZE #endif -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include +#include #if USE_RAY_QUERY [numthreads(RTXDI_SCREEN_SPACE_GROUP_SIZE, RTXDI_SCREEN_SPACE_GROUP_SIZE, 1)] diff --git a/shaders/LightingPasses/PresampleEnvironmentMap.hlsl b/Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleEnvironmentMap.hlsl similarity index 89% rename from shaders/LightingPasses/PresampleEnvironmentMap.hlsl rename to Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleEnvironmentMap.hlsl index 46f65f7..57be42c 100644 --- a/shaders/LightingPasses/PresampleEnvironmentMap.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleEnvironmentMap.hlsl @@ -8,9 +8,9 @@ # license agreement from NVIDIA CORPORATION is strictly prohibited. **************************************************************************/ -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include [numthreads(RTXDI_PRESAMPLING_GROUP_SIZE, 1, 1)] void main(uint2 GlobalIndex : SV_DispatchThreadID) diff --git a/shaders/LightingPasses/PresampleLights.hlsl b/Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleLights.hlsl similarity index 89% rename from shaders/LightingPasses/PresampleLights.hlsl rename to Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleLights.hlsl index 79ddd8c..1ca9e94 100644 --- a/shaders/LightingPasses/PresampleLights.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleLights.hlsl @@ -8,9 +8,9 @@ # license agreement from NVIDIA CORPORATION is strictly prohibited. **************************************************************************/ -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include [numthreads(RTXDI_PRESAMPLING_GROUP_SIZE, 1, 1)] void main(uint2 GlobalIndex : SV_DispatchThreadID) diff --git a/shaders/LightingPasses/PresampleReGIR.hlsl b/Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleReGIR.hlsl similarity index 89% rename from shaders/LightingPasses/PresampleReGIR.hlsl rename to Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleReGIR.hlsl index 65f2e99..cfbedc7 100644 --- a/shaders/LightingPasses/PresampleReGIR.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/Presampling/PresampleReGIR.hlsl @@ -10,9 +10,9 @@ #pragma pack_matrix(row_major) -#include "RtxdiApplicationBridge.hlsli" +#include "../RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include +#include [numthreads(256, 1, 1)] void main(uint GlobalIndex : SV_DispatchThreadID) diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Buffers.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Buffers.hlsli new file mode 100644 index 0000000..1892eb0 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Buffers.hlsli @@ -0,0 +1,77 @@ +#ifndef RAB_BUFFER_HLSLI +#define RAB_BUFFER_HLSLI + +// G-buffer resources +Texture2D t_GBufferDepth : register(t0); +Texture2D t_GBufferNormals : register(t1); +Texture2D t_GBufferGeoNormals : register(t2); +Texture2D t_GBufferDiffuseAlbedo : register(t3); +Texture2D t_GBufferSpecularRough : register(t4); +Texture2D t_PrevGBufferDepth : register(t5); +Texture2D t_PrevGBufferNormals : register(t6); +Texture2D t_PrevGBufferGeoNormals : register(t7); +Texture2D t_PrevGBufferDiffuseAlbedo : register(t8); +Texture2D t_PrevGBufferSpecularRough : register(t9); +Texture2D t_PrevRestirLuminance : register(t10); +Texture2D t_MotionVectors : register(t11); +Texture2D t_DenoiserNormalRoughness : register(t12); + +// Scene resources +RaytracingAccelerationStructure SceneBVH : register(t30); +RaytracingAccelerationStructure PrevSceneBVH : register(t31); +StructuredBuffer t_InstanceData : register(t32); +StructuredBuffer t_GeometryData : register(t33); +StructuredBuffer t_MaterialConstants : register(t34); + +// RTXDI resources +StructuredBuffer t_LightDataBuffer : register(t20); +Buffer t_NeighborOffsets : register(t21); +Buffer t_LightIndexMappingBuffer : register(t22); +Texture2D t_EnvironmentPdfTexture : register(t23); +Texture2D t_LocalLightPdfTexture : register(t24); +StructuredBuffer t_GeometryInstanceToLight : register(t25); + +// Screen-sized UAVs +RWStructuredBuffer u_LightReservoirs : register(u0); +RWTexture2D u_DiffuseLighting : register(u1); +RWTexture2D u_SpecularLighting : register(u2); +RWTexture2D u_TemporalSamplePositions : register(u3); +RWTexture2DArray u_Gradients : register(u4); +RWTexture2D u_RestirLuminance : register(u5); +RWStructuredBuffer u_GIReservoirs : register(u6); + +// RTXDI UAVs +RWBuffer u_RisBuffer : register(u10); +RWBuffer u_RisLightDataBuffer : register(u11); +RWBuffer u_RayCountBuffer : register(u12); +RWStructuredBuffer u_SecondaryGBuffer : register(u13); + +// Other +ConstantBuffer g_Const : register(b0); +VK_PUSH_CONSTANT ConstantBuffer g_PerPassConstants : register(b1); +SamplerState s_MaterialSampler : register(s0); +SamplerState s_EnvironmentSampler : register(s1); + +#define RTXDI_RIS_BUFFER u_RisBuffer +#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs +#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets +#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs + +#define IES_SAMPLER s_EnvironmentSampler + +// Translates the light index from the current frame to the previous frame (if currentToPrevious = true) +// or from the previous frame to the current frame (if currentToPrevious = false). +// Returns the new index, or a negative number if the light does not exist in the other frame. +int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) +{ + // In this implementation, the mapping buffer contains both forward and reverse mappings, + // stored at different offsets, so we don't care about the currentToPrevious parameter. + uint mappedIndexPlusOne = t_LightIndexMappingBuffer[lightIndex]; + + // The mappings are stored offset by 1 to differentiate between valid and invalid mappings. + // The buffer is cleared with zeros which indicate an invalid mapping. + // Subtract that one to make this function return expected values. + return int(mappedIndexPlusOne) - 1; +} + +#endif // RAB_BUFFER_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightInfo.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightInfo.hlsli new file mode 100644 index 0000000..e78ac11 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightInfo.hlsli @@ -0,0 +1,73 @@ +#ifndef RAB_LIGHT_INFO_HLSLI +#define RAB_LIGHT_INFO_HLSLI + +#include "../../PolymorphicLight.hlsli" +#include "RAB_Surface.hlsli" +#include "RAB_LightSample.hlsli" + +typedef PolymorphicLightInfo RAB_LightInfo; + +RAB_LightInfo RAB_EmptyLightInfo() +{ + return (RAB_LightInfo)0; +} + +// Loads polymorphic light data from the global light buffer. +RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) +{ + return t_LightDataBuffer[index]; +} + +// Loads triangle light data from a tile produced by the presampling pass. +RAB_LightInfo RAB_LoadCompactLightInfo(uint linearIndex) +{ + uint4 packedData1, packedData2; + packedData1 = u_RisLightDataBuffer[linearIndex * 2 + 0]; + packedData2 = u_RisLightDataBuffer[linearIndex * 2 + 1]; + return unpackCompactLightInfo(packedData1, packedData2); +} + +// Stores triangle light data into a tile. +// Returns true if this light can be stored in a tile (i.e. compacted). +// If it cannot, for example it's a shaped light, this function returns false and doesn't store. +// A basic implementation can ignore this feature and always return false, which is just slower. +bool RAB_StoreCompactLightInfo(uint linearIndex, RAB_LightInfo lightInfo) +{ + uint4 data1, data2; + if (!packCompactLightInfo(lightInfo, data1, data2)) + return false; + + u_RisLightDataBuffer[linearIndex * 2 + 0] = data1; + u_RisLightDataBuffer[linearIndex * 2 + 1] = data2; + + return true; +} + +// Computes the weight of the given light for arbitrary surfaces located inside +// the specified volume. Used for world-space light grid construction. +float RAB_GetLightTargetPdfForVolume(RAB_LightInfo light, float3 volumeCenter, float volumeRadius) +{ + return PolymorphicLight::getWeightForVolume(light, volumeCenter, volumeRadius); +} + +// Samples a polymorphic light relative to the given receiver surface. +// For most light types, the "uv" parameter is just a pair of uniform random numbers, originally +// produced by the RAB_GetNextRandom function and then stored in light reservoirs. +// For importance sampled environment lights, the "uv" parameter has the texture coordinates +// in the PDF texture, normalized to the (0..1) range. +RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) +{ + PolymorphicLightSample pls = PolymorphicLight::calcSample(lightInfo, uv, surface.worldPos); + + RAB_LightSample lightSample; + lightSample.position = pls.position; + lightSample.normal = pls.normal; + lightSample.radiance = pls.radiance; + lightSample.solidAnglePdf = pls.solidAnglePdf; + lightSample.lightType = getLightType(lightInfo); + return lightSample; +} + + + +#endif // RAB_LIGHT_INFO_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightSample.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightSample.hlsli new file mode 100644 index 0000000..59c471d --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightSample.hlsli @@ -0,0 +1,29 @@ +#ifndef RTXDI_RAB_LIGHT_INFO_HLSLI +#define RTXDI_RAB_LIGHT_INFO_HLSLI + +struct RAB_LightSample +{ + float3 position; + float3 normal; + float3 radiance; + float solidAnglePdf; + PolymorphicLightType lightType; +}; + +RAB_LightSample RAB_EmptyLightSample() +{ + return (RAB_LightSample)0; +} + +bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) +{ + return lightSample.lightType != PolymorphicLightType::kTriangle && + lightSample.lightType != PolymorphicLightType::kEnvironment; +} + +float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) +{ + return lightSample.solidAnglePdf; +} + +#endif // RTXDI_RAB_LIGHT_INFO_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightSampling.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightSampling.hlsli new file mode 100644 index 0000000..49fb841 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_LightSampling.hlsli @@ -0,0 +1,211 @@ +#ifndef RAB_LIGHT_SAMPLING_HLSLI +#define RAB_LIGHT_SAMPLING_HLSLI + +#include "RAB_RayPayload.hlsli" + +float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) +{ + float2 uv = directionToEquirectUV(worldDir); + uv.x -= g_Const.sceneConstants.environmentRotation; + uv = frac(uv); + return uv; +} + +// Computes the probability of a particular direction being sampled from the environment map +// relative to all the other possible directions, based on the environment map pdf texture. +float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) +{ + if (!g_Const.restirDI.initialSamplingParams.environmentMapImportanceSampling) + return 1.0; + + float2 uv = RAB_GetEnvironmentMapRandXYFromDir(L); + + uint2 pdfTextureSize = g_Const.environmentPdfTextureSize.xy; + uint2 texelPosition = uint2(pdfTextureSize * uv); + float texelValue = t_EnvironmentPdfTexture[texelPosition].r; + + int lastMipLevel = max(0, int(floor(log2(max(pdfTextureSize.x, pdfTextureSize.y))))); + float averageValue = t_EnvironmentPdfTexture.mips[lastMipLevel][uint2(0, 0)].x; + + // The single texel in the last mip level is effectively the average of all texels in mip 0, + // padded to a square shape with zeros. So, in case the PDF texture has a 2:1 aspect ratio, + // that texel's value is only half of the true average of the rectangular input texture. + // Compensate for that by assuming that the input texture is square. + float sum = averageValue * square(1u << lastMipLevel); + + return texelValue / sum; +} + +// Evaluates pdf for a particular light +float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) +{ + uint2 pdfTextureSize = g_Const.localLightPdfTextureSize.xy; + uint2 texelPosition = RTXDI_LinearIndexToZCurve(lightIndex); + float texelValue = t_LocalLightPdfTexture[texelPosition].r; + + int lastMipLevel = max(0, int(floor(log2(max(pdfTextureSize.x, pdfTextureSize.y))))); + float averageValue = t_LocalLightPdfTexture.mips[lastMipLevel][uint2(0, 0)].x; + + // See the comment at 'sum' in RAB_EvaluateEnvironmentMapSamplingPdf. + // The same texture shape considerations apply to local lights. + float sum = averageValue * square(1u << lastMipLevel); + + return texelValue / sum; +} + +float3 RAB_GetReflectedRadianceForSurface(float3 incomingRadianceLocation, float3 incomingRadiance, RAB_Surface surface) +{ + float3 L = normalize(incomingRadianceLocation - surface.worldPos); + float3 N = surface.normal; + float3 V = surface.viewDir; + + if (dot(L, surface.geoNormal) <= 0) + return 0; + + float d = Lambert(N, -L); + float3 s; + if (surface.material.roughness == 0) + s = 0; + else + s = GGX_times_NdotL(V, L, N, max(surface.material.roughness, kMinRoughness), surface.material.specularF0); + + return incomingRadiance * (d * surface.material.diffuseAlbedo + s); +} + +float RAB_GetReflectedLuminanceForSurface(float3 incomingRadianceLocation, float3 incomingRadiance, RAB_Surface surface) +{ + return RTXDI_Luminance(RAB_GetReflectedRadianceForSurface(incomingRadianceLocation, incomingRadiance, surface)); +} + +// Computes the weight of the given light samples when the given surface is +// shaded using that light sample. Exact or approximate BRDF evaluation can be +// used to compute the weight. ReSTIR will converge to a correct lighting result +// even if all samples have a fixed weight of 1.0, but that will be very noisy. +// Scaling of the weights can be arbitrary, as long as it's consistent +// between all lights and surfaces. +float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) +{ + if (lightSample.solidAnglePdf <= 0) + return 0; + + return RAB_GetReflectedLuminanceForSurface(lightSample.position, lightSample.radiance, surface) / lightSample.solidAnglePdf; +} + +// Computes the weight of the given GI sample when the given surface is shaded using that GI sample. +float RAB_GetGISampleTargetPdfForSurface(float3 samplePosition, float3 sampleRadiance, RAB_Surface surface) +{ + float3 reflectedRadiance = RAB_GetReflectedRadianceForSurface(samplePosition, sampleRadiance, surface); + + return RTXDI_Luminance(reflectedRadiance); +} + +void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, + out float3 o_lightDir, + out float o_lightDistance) +{ + if (lightSample.lightType == PolymorphicLightType::kEnvironment) + { + o_lightDir = -lightSample.normal; + o_lightDistance = DISTANT_LIGHT_DISTANCE; + } + else + { + float3 toLight = lightSample.position - surface.worldPos; + o_lightDistance = length(toLight); + o_lightDir = toLight / o_lightDistance; + } +} + +// Forward declare the SDK function that's used in RAB_AreMaterialsSimilar +bool RTXDI_CompareRelativeDifference(float reference, float candidate, float threshold); + +float3 GetEnvironmentRadiance(float3 direction) +{ + if (!g_Const.sceneConstants.enableEnvironmentMap) + return 0; + + Texture2D environmentLatLongMap = t_BindlessTextures[g_Const.sceneConstants.environmentMapTextureIndex]; + + float2 uv = directionToEquirectUV(direction); + uv.x -= g_Const.sceneConstants.environmentRotation; + + float3 environmentRadiance = environmentLatLongMap.SampleLevel(s_EnvironmentSampler, uv, 0).rgb; + environmentRadiance *= g_Const.sceneConstants.environmentScale; + + return environmentRadiance; +} + +bool IsComplexSurface(int2 pixelPosition, RAB_Surface surface) +{ + // Use a simple classification of surfaces into simple and complex based on the roughness. + // The PostprocessGBuffer pass modifies the surface roughness and writes the DenoiserNormalRoughness + // channel where the roughness is preserved. The roughness stored in the regular G-buffer is modified + // based on the surface curvature around the current pixel. If the surface is curved, roughness increases. + // Detect that increase here and disable permutation sampling based on a threshold. + // Other classification methods can be employed for better quality. + float originalRoughness = t_DenoiserNormalRoughness[pixelPosition].a; + return originalRoughness < (surface.material.roughness * g_Const.restirDI.temporalResamplingParams.permutationSamplingThreshold); +} + +uint getLightIndex(uint instanceID, uint geometryIndex, uint primitiveIndex) +{ + uint lightIndex = RTXDI_InvalidLightIndex; + InstanceData hitInstance = t_InstanceData[instanceID]; + uint geometryInstanceIndex = hitInstance.firstGeometryInstanceIndex + geometryIndex; + lightIndex = t_GeometryInstanceToLight[geometryInstanceIndex]; + if (lightIndex != RTXDI_InvalidLightIndex) + lightIndex += primitiveIndex; + return lightIndex; +} + +// Return true if anything was hit. If false, RTXDI will do environment map sampling +// o_lightIndex: If hit, must be a valid light index for RAB_LoadLightInfo, if no local light was hit, must be RTXDI_InvalidLightIndex +// randXY: The randXY that corresponds to the hit location and is the same used for RAB_SamplePolymorphicLight +bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, + out uint o_lightIndex, out float2 o_randXY) +{ + o_lightIndex = RTXDI_InvalidLightIndex; + o_randXY = 0; + + RayDesc ray; + ray.Origin = origin; + ray.Direction = direction; + ray.TMin = tMin; + ray.TMax = tMax; + + float2 hitUV; + bool hitAnything; +#if USE_RAY_QUERY + RayQuery rayQuery; + rayQuery.TraceRayInline(SceneBVH, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); + rayQuery.Proceed(); + + hitAnything = rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT; + if (hitAnything) + { + o_lightIndex = getLightIndex(rayQuery.CommittedInstanceID(), rayQuery.CommittedGeometryIndex(), rayQuery.CommittedPrimitiveIndex()); + hitUV = rayQuery.CommittedTriangleBarycentrics(); + } +#else + RayPayload payload = (RayPayload)0; + payload.instanceID = ~0u; + payload.throughput = 1.0; + + TraceRay(SceneBVH, RAY_FLAG_CULL_NON_OPAQUE | RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES, INSTANCE_MASK_OPAQUE, 0, 0, 0, ray, payload); + hitAnything = payload.instanceID != ~0u; + if (hitAnything) + { + o_lightIndex = getLightIndex(payload.instanceID, payload.geometryIndex, payload.primitiveIndex); + hitUV = payload.barycentrics; + } +#endif + + if (o_lightIndex != RTXDI_InvalidLightIndex) + { + o_randXY = randomFromBarycentric(hitUVToBarycentric(hitUV)); + } + + return hitAnything; +} + +#endif // RAB_LIGHT_SAMPLING_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Material.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Material.hlsli new file mode 100644 index 0000000..524a7d5 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Material.hlsli @@ -0,0 +1,97 @@ +#ifndef RAB_MATERIAL_HLSLI +#define RAB_MATERIAL_HLSLI + +static const float kMinRoughness = 0.05f; + +struct RAB_Material +{ + float3 diffuseAlbedo; + float3 specularF0; + float roughness; +}; + +RAB_Material RAB_EmptyMaterial() +{ + RAB_Material material = (RAB_Material)0; + + return material; +} + +float3 GetDiffuseAlbedo(RAB_Material material) +{ + return material.diffuseAlbedo; +} + +float3 GetSpecularF0(RAB_Material material) +{ + return material.specularF0; +} + +float GetRoughness(RAB_Material material) +{ + return material.roughness; +} + +RAB_Material GetGBufferMaterial( + int2 pixelPosition, + PlanarViewConstants view, + Texture2D diffuseAlbedoTexture, + Texture2D specularRoughTexture) +{ + RAB_Material material = RAB_EmptyMaterial(); + + if (any(pixelPosition >= view.viewportSize)) + return material; + + material.diffuseAlbedo = Unpack_R11G11B10_UFLOAT(diffuseAlbedoTexture[pixelPosition]).rgb; + float4 specularRough = Unpack_R8G8B8A8_Gamma_UFLOAT(specularRoughTexture[pixelPosition]); + material.roughness = specularRough.a; + material.specularF0 = specularRough.rgb; + + return material; +} + +RAB_Material RAB_GetGBufferMaterial( + int2 pixelPosition, + bool previousFrame) +{ + if(previousFrame) + { + return GetGBufferMaterial( + pixelPosition, + g_Const.prevView, + t_PrevGBufferDiffuseAlbedo, + t_PrevGBufferSpecularRough); + } + else + { + return GetGBufferMaterial( + pixelPosition, + g_Const.view, + t_GBufferDiffuseAlbedo, + t_GBufferSpecularRough); + } +} + +// Compares the materials of two surfaces, returns true if the surfaces +// are similar enough that we can share the light reservoirs between them. +// If unsure, just return true. +bool RAB_AreMaterialsSimilar(RAB_Material a, RAB_Material b) +{ + const float roughnessThreshold = 0.5; + const float reflectivityThreshold = 0.25; + const float albedoThreshold = 0.25; + + if (!RTXDI_CompareRelativeDifference(a.roughness, b.roughness, roughnessThreshold)) + return false; + + if (abs(calcLuminance(a.specularF0) - calcLuminance(b.specularF0)) > reflectivityThreshold) + return false; + + if (abs(calcLuminance(a.diffuseAlbedo) - calcLuminance(b.diffuseAlbedo)) > albedoThreshold) + return false; + + return true; +} + +#endif // RAB_MATERIAL_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RTShaders.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RTShaders.hlsli new file mode 100644 index 0000000..a089ec2 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RTShaders.hlsli @@ -0,0 +1,76 @@ +#ifndef RAB_RT_SHADERS_HLSLI +#define RAB_RT_SHADERS_HLSLI + +bool considerTransparentMaterial(uint instanceIndex, uint geometryIndex, uint triangleIndex, float2 rayBarycentrics, inout float3 throughput) +{ + GeometrySample gs = getGeometryFromHit( + instanceIndex, + geometryIndex, + triangleIndex, + rayBarycentrics, + GeomAttr_TexCoord, + t_InstanceData, t_GeometryData, t_MaterialConstants); + + MaterialSample ms = sampleGeometryMaterial(gs, 0, 0, 0, + MatAttr_BaseColor | MatAttr_Transmission, s_MaterialSampler); + + bool alphaMask = ms.opacity >= gs.material.alphaCutoff; + + if (gs.material.domain == MaterialDomain_AlphaTested) + return alphaMask; + + if (gs.material.domain == MaterialDomain_AlphaBlended) + { + throughput *= (1.0 - ms.opacity); + return false; + } + + if (gs.material.domain == MaterialDomain_Transmissive || + (gs.material.domain == MaterialDomain_TransmissiveAlphaTested && alphaMask) || + gs.material.domain == MaterialDomain_TransmissiveAlphaBlended) + { + throughput *= ms.transmission; + + if (ms.hasMetalRoughParams) + throughput *= (1.0 - ms.metalness) * ms.baseColor; + + if (gs.material.domain == MaterialDomain_TransmissiveAlphaBlended) + throughput *= (1.0 - ms.opacity); + + return all(throughput == 0); + } + + return false; +} + +#if !USE_RAY_QUERY +struct RayAttributes +{ + float2 uv; +}; + +[shader("miss")] +void Miss(inout RayPayload payload : SV_RayPayload) +{ +} + +[shader("closesthit")] +void ClosestHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) +{ + payload.committedRayT = RayTCurrent(); + payload.instanceID = InstanceID(); + payload.geometryIndex = GeometryIndex(); + payload.primitiveIndex = PrimitiveIndex(); + payload.frontFace = HitKind() == HIT_KIND_TRIANGLE_FRONT_FACE; + payload.barycentrics = attrib.uv; +} + +[shader("anyhit")] +void AnyHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) +{ + if (!considerTransparentMaterial(InstanceID(), GeometryIndex(), PrimitiveIndex(), attrib.uv, payload.throughput)) + IgnoreHit(); +} +#endif + +#endif // RAB_RT_SHADERS_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli new file mode 100644 index 0000000..c0eebb2 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli @@ -0,0 +1,24 @@ +#ifndef RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI +#define RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI + +#include "../../HelperFunctions.hlsli" + +typedef RandomSamplerState RAB_RandomSamplerState; + +// Initialized the random sampler for a given pixel or tile index. +// The pass parameter is provided to help generate different RNG sequences +// for different resampling passes, which is important for image quality. +// In general, a high quality RNG is critical to get good results from ReSTIR. +// A table-based blue noise RNG dose not provide enough entropy, for example. +RAB_RandomSamplerState RAB_InitRandomSampler(uint2 index, uint pass) +{ + return initRandomSampler(index, g_Const.frameIndex + pass * 13); +} + +// Draws a random number X from the sampler, so that (0 <= X < 1). +float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) +{ + return sampleUniformRng(rng); +} + +#endif // RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RayPayload.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RayPayload.hlsli new file mode 100644 index 0000000..9389dfd --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_RayPayload.hlsli @@ -0,0 +1,15 @@ +#ifndef RAB_RAY_PAYLOAD_HLSLI +#define RAB_RAY_PAYLOAD_HLSLI + +struct RayPayload +{ + float3 throughput; + float committedRayT; + uint instanceID; + uint geometryIndex; + uint primitiveIndex; + bool frontFace; + float2 barycentrics; +}; + +#endif // RAB_RAY_PAYLOAD_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli new file mode 100644 index 0000000..68c1245 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli @@ -0,0 +1,38 @@ +#ifndef RAB_SPATIAL_HELPERS_HLSLI +#define RAB_SPATIAL_HELPERS_HLSLI + +// This function is called in the spatial resampling passes to make sure that +// the samples actually land on the screen and not outside of its boundaries. +// It can clamp the position or reflect it across the nearest screen edge. +// The simplest implementation will just return the input pixelPosition. +int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) +{ + int width = int(g_Const.view.viewportSize.x); + int height = int(g_Const.view.viewportSize.y); + + // Reflect the position across the screen edges. + // Compared to simple clamping, this prevents the spread of colorful blobs from screen edges. + if (pixelPosition.x < 0) pixelPosition.x = -pixelPosition.x; + if (pixelPosition.y < 0) pixelPosition.y = -pixelPosition.y; + if (pixelPosition.x >= width) pixelPosition.x = 2 * width - pixelPosition.x - 1; + if (pixelPosition.y >= height) pixelPosition.y = 2 * height - pixelPosition.y - 1; + + return pixelPosition; +} + +// Check if the sample is fine to be used as a valid spatial sample. +// This function also be able to clamp the value of the Jacobian. +bool RAB_ValidateGISampleWithJacobian(inout float jacobian) +{ + // Sold angle ratio is too different. Discard the sample. + if (jacobian > 10.0 || jacobian < 1 / 10.0) { + return false; + } + + // clamp Jacobian. + jacobian = clamp(jacobian, 1 / 3.0, 3.0); + + return true; +} + +#endif // RAB_SPATIAL_HELPERS_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Surface.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Surface.hlsli new file mode 100644 index 0000000..7aaca62 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_Surface.hlsli @@ -0,0 +1,187 @@ +#ifndef RTXDI_RAB_SURFACE_HLSLI +#define RTXDI_RAB_SURFACE_HLSLI + +#include "../../GBufferHelpers.hlsli" +#include "../../SceneGeometry.hlsli" +#include "../../ShaderParameters.h" + +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_Material.hlsli" + +static const bool kSpecularOnly = false; + +struct RAB_Surface +{ + float3 worldPos; + float3 viewDir; + float3 normal; + float3 geoNormal; + float viewDepth; + float diffuseProbability; + RAB_Material material; +}; + +RAB_Surface RAB_EmptySurface() +{ + RAB_Surface surface = (RAB_Surface)0; + surface.viewDepth = BACKGROUND_DEPTH; + return surface; +} + +// Checks if the given surface is valid, see RAB_GetGBufferSurface. +bool RAB_IsSurfaceValid(RAB_Surface surface) +{ + return surface.viewDepth != BACKGROUND_DEPTH; +} + +// Returns the world position of the given surface +float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) +{ + return surface.worldPos; +} + +RAB_Material RAB_GetMaterial(RAB_Surface surface) +{ + return surface.material; +} + +// Returns the world shading normal of the given surface +float3 RAB_GetSurfaceNormal(RAB_Surface surface) +{ + return surface.normal; +} + +// Returns the linear depth of the given surface. +// It doesn't have to be linear depth in a strict sense (i.e. viewPos.z), +// and can be distance to the camera or primary path length instead. +// Just make sure that the motion vectors' .z component follows the same logic. +float RAB_GetSurfaceLinearDepth(RAB_Surface surface) +{ + return surface.viewDepth; +} + +float getSurfaceDiffuseProbability(RAB_Surface surface) +{ + float diffuseWeight = calcLuminance(surface.material.diffuseAlbedo); + float specularWeight = calcLuminance(Schlick_Fresnel(surface.material.specularF0, dot(surface.viewDir, surface.normal))); + float sumWeights = diffuseWeight + specularWeight; + return sumWeights < 1e-7f ? 1.f : (diffuseWeight / sumWeights); +} + +RAB_Surface GetGBufferSurface( + int2 pixelPosition, + bool previousFrame, + PlanarViewConstants view, + Texture2D depthTexture, + Texture2D normalsTexture, + Texture2D geoNormalsTexture) +{ + RAB_Surface surface = RAB_EmptySurface(); + + if (any(pixelPosition >= view.viewportSize)) + return surface; + + surface.viewDepth = depthTexture[pixelPosition]; + + if(surface.viewDepth == BACKGROUND_DEPTH) + return surface; + + surface.material = RAB_GetGBufferMaterial(pixelPosition, previousFrame); + + surface.geoNormal = octToNdirUnorm32(geoNormalsTexture[pixelPosition]); + surface.normal = octToNdirUnorm32(normalsTexture[pixelPosition]); + surface.worldPos = viewDepthToWorldPos(view, pixelPosition, surface.viewDepth); + surface.viewDir = normalize(view.cameraDirectionOrPosition.xyz - surface.worldPos); + surface.diffuseProbability = getSurfaceDiffuseProbability(surface); + + return surface; +} + + +// Reads the G-buffer, either the current one or the previous one, and returns a surface. +// If the provided pixel position is outside of the viewport bounds, the surface +// should indicate that it's invalid when RAB_IsSurfaceValid is called on it. +RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) +{ + if(previousFrame) + { + return GetGBufferSurface( + pixelPosition, + previousFrame, + g_Const.prevView, + t_PrevGBufferDepth, + t_PrevGBufferNormals, + t_PrevGBufferGeoNormals); + } + else + { + return GetGBufferSurface( + pixelPosition, + previousFrame, + g_Const.view, + t_GBufferDepth, + t_GBufferNormals, + t_GBufferGeoNormals); + } +} + +float3 worldToTangent(RAB_Surface surface, float3 w) +{ + // reconstruct tangent frame based off worldspace normal + // this is ok for isotropic BRDFs + // for anisotropic BRDFs, we need a user defined tangent + float3 tangent; + float3 bitangent; + ConstructONB(surface.normal, tangent, bitangent); + + return float3(dot(bitangent, w), dot(tangent, w), dot(surface.normal, w)); +} + +float3 tangentToWorld(RAB_Surface surface, float3 h) +{ + // reconstruct tangent frame based off worldspace normal + // this is ok for isotropic BRDFs + // for anisotropic BRDFs, we need a user defined tangent + float3 tangent; + float3 bitangent; + ConstructONB(surface.normal, tangent, bitangent); + + return bitangent * h.x + tangent * h.y + surface.normal * h.z; +} + +bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) +{ + float3 rand; + rand.x = RAB_GetNextRandom(rng); + rand.y = RAB_GetNextRandom(rng); + rand.z = RAB_GetNextRandom(rng); + if (rand.x < surface.diffuseProbability) + { + if (kSpecularOnly) + return false; + + float pdf; + float3 h = SampleCosHemisphere(rand.yz, pdf); + dir = tangentToWorld(surface, h); + } + else + { + float3 Ve = normalize(worldToTangent(surface, surface.viewDir)); + float3 h = ImportanceSampleGGX_VNDF(rand.yz, max(surface.material.roughness, kMinRoughness), Ve, 1.0); + h = normalize(h); + dir = reflect(-surface.viewDir, tangentToWorld(surface, h)); + } + + return dot(surface.normal, dir) > 0.f; +} + +float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) +{ + float cosTheta = saturate(dot(surface.normal, dir)); + float diffusePdf = kSpecularOnly ? 0.f : (cosTheta / M_PI); + float specularPdf = ImportanceSampleGGX_VNDF_PDF(max(surface.material.roughness, kMinRoughness), surface.normal, surface.viewDir, dir); + float pdf = cosTheta > 0.f ? lerp(specularPdf, diffusePdf, surface.diffuseProbability) : 0.f; + return pdf; +} + +#endif // RTXDI_RAB_SURFACE_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli new file mode 100644 index 0000000..c872be4 --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli @@ -0,0 +1,151 @@ +#ifndef RAB_VISIBILITY_TEST_HLSLI +#define RAB_VISIBILITY_TEST_HLSLI + +#include "../../SceneGeometry.hlsli" + +RayDesc setupVisibilityRay(RAB_Surface surface, float3 samplePosition, float offset = 0.001) +{ + float3 L = samplePosition - surface.worldPos; + + RayDesc ray; + ray.TMin = offset; + ray.TMax = max(offset, length(L) - offset * 2); + ray.Direction = normalize(L); + ray.Origin = surface.worldPos; + + return ray; +} + +bool GetConservativeVisibility(RaytracingAccelerationStructure accelStruct, RAB_Surface surface, float3 samplePosition) +{ + RayDesc ray = setupVisibilityRay(surface, samplePosition); + +#if USE_RAY_QUERY + RayQuery rayQuery; + + rayQuery.TraceRayInline(accelStruct, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); + + rayQuery.Proceed(); + + bool visible = (rayQuery.CommittedStatus() == COMMITTED_NOTHING); +#else + RayPayload payload = (RayPayload)0; + payload.instanceID = ~0u; + payload.throughput = 1.0; + + TraceRay(accelStruct, RAY_FLAG_CULL_NON_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, INSTANCE_MASK_OPAQUE, 0, 0, 0, ray, payload); + + bool visible = (payload.instanceID == ~0u); +#endif + + REPORT_RAY(!visible); + + return visible; +} + +// Traces a cheap visibility ray that returns approximate, conservative visibility +// between the surface and the light sample. Conservative means if unsure, assume the light is visible. +// Significant differences between this conservative visibility and the final one will result in more noise. +// This function is used in the spatial resampling functions for ray traced bias correction. +bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) +{ + return GetConservativeVisibility(SceneBVH, surface, lightSample.position); +} + +// Same as RAB_GetConservativeVisibility but for temporal resampling. +// When the previous frame TLAS and BLAS are available, the implementation should use the previous position and the previous AS. +// When they are not available, use the current AS. That will result in transient bias. +bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, RAB_LightSample lightSample) +{ + if (g_Const.enablePreviousTLAS) + return GetConservativeVisibility(PrevSceneBVH, previousSurface, lightSample.position); + else + return GetConservativeVisibility(SceneBVH, currentSurface, lightSample.position); +} + +// Traces an expensive visibility ray that considers all alpha tested and transparent geometry along the way. +// Only used for final shading. +// Not a required bridge function. +float3 GetFinalVisibility(RaytracingAccelerationStructure accelStruct, RAB_Surface surface, float3 samplePosition) +{ + RayDesc ray = setupVisibilityRay(surface, samplePosition, 0.01); + + uint instanceMask = INSTANCE_MASK_OPAQUE; + uint rayFlags = RAY_FLAG_NONE; + + if (g_Const.sceneConstants.enableAlphaTestedGeometry) + instanceMask |= INSTANCE_MASK_ALPHA_TESTED; + + if (g_Const.sceneConstants.enableTransparentGeometry) + instanceMask |= INSTANCE_MASK_TRANSPARENT; + + if (!g_Const.sceneConstants.enableTransparentGeometry && !g_Const.sceneConstants.enableAlphaTestedGeometry) + rayFlags |= RAY_FLAG_CULL_NON_OPAQUE; + + RayPayload payload = (RayPayload)0; + payload.instanceID = ~0u; + payload.throughput = 1.0; + +#if USE_RAY_QUERY + RayQuery rayQuery; + + rayQuery.TraceRayInline(accelStruct, rayFlags, instanceMask, ray); + + while (rayQuery.Proceed()) + { + if (rayQuery.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE) + { + if (considerTransparentMaterial( + rayQuery.CandidateInstanceID(), + rayQuery.CandidateGeometryIndex(), + rayQuery.CandidatePrimitiveIndex(), + rayQuery.CandidateTriangleBarycentrics(), + payload.throughput)) + { + rayQuery.CommitNonOpaqueTriangleHit(); + } + } + } + + if (rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT) + { + payload.instanceID = rayQuery.CommittedInstanceID(); + payload.primitiveIndex = rayQuery.CommittedPrimitiveIndex(); + payload.geometryIndex = rayQuery.CommittedGeometryIndex(); + payload.barycentrics = rayQuery.CommittedTriangleBarycentrics(); + payload.committedRayT = rayQuery.CommittedRayT(); + payload.frontFace = rayQuery.CommittedTriangleFrontFace(); + } +#else + TraceRay(accelStruct, rayFlags, instanceMask, 0, 0, 0, ray, payload); +#endif + + REPORT_RAY(payload.instanceID != ~0u); + + if(payload.instanceID == ~0u) + return payload.throughput.rgb; + else + return 0; +} + +// Traces a cheap visibility ray that returns approximate, conservative visibility +// between the surface and the light sample. Conservative means if unsure, assume the light is visible. +// Significant differences between this conservative visibility and the final one will result in more noise. +// This function is used in the spatial resampling functions for ray traced bias correction. +bool RAB_GetConservativeVisibility(RAB_Surface surface, float3 samplePosition) +{ + return GetConservativeVisibility(SceneBVH, surface, samplePosition); +} + +// Same as RAB_GetConservativeVisibility but for temporal resampling. +// When the previous frame TLAS and BLAS are available, the implementation should use the previous position and the previous AS. +// When they are not available, use the current AS. That will result in transient bias. +bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, float3 samplePosition) +{ + if (g_Const.enablePreviousTLAS) + return GetConservativeVisibility(PrevSceneBVH, previousSurface, samplePosition); + else + return GetConservativeVisibility(SceneBVH, currentSurface, samplePosition); +} + +#endif // RAB_VISIBILITY_TEST_HLSLI \ No newline at end of file diff --git a/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli new file mode 100644 index 0000000..35a4c8c --- /dev/null +++ b/Samples/FullSample/Shaders/LightingPasses/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli @@ -0,0 +1,48 @@ +/*************************************************************************** + # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + # + # NVIDIA CORPORATION and its licensors retain all intellectual property + # and proprietary rights in and to this software, related documentation + # and any modifications thereto. Any use, reproduction, disclosure or + # distribution of this software and related documentation without an express + # license agreement from NVIDIA CORPORATION is strictly prohibited. + **************************************************************************/ + +/* +This header file is the bridge between the RTXDI resampling functions +and the application resources and parts of shader functionality. + +The RTXDI SDK provides the resampling logic, and the application provides +other necessary aspects: + - Material BRDF evaluation; + - Ray tracing and transparent/alpha-tested material processing; + - Light sampling functions and emission profiles. + +The structures and functions that are necessary for SDK operation +start with the RAB_ prefix (for RTXDI-Application Bridge). + +All structures defined here are opaque for the SDK, meaning that +it makes no assumptions about their contents, they are just passed +between the bridge functions. +*/ + +#ifndef RTXDI_APPLICATION_BRIDGE_HLSLI +#define RTXDI_APPLICATION_BRIDGE_HLSLI + +#include "../../ShaderParameters.h" +#include "../../SceneGeometry.hlsli" + +#include "RAB_Buffers.hlsli" + +#include "RAB_LightInfo.hlsli" +#include "RAB_LightSample.hlsli" +#include "RAB_LightSampling.hlsli" +#include "RAB_Material.hlsli" +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_RayPayload.hlsli" +#include "RAB_RTShaders.hlsli" +#include "RAB_SpatialHelpers.hlsli" +#include "RAB_Surface.hlsli" +#include "RAB_VisibilityTest.hlsli" + +#endif // RTXDI_APPLICATION_BRIDGE_HLSLI diff --git a/shaders/LightingPasses/ShadeSecondarySurfaces.hlsl b/Samples/FullSample/Shaders/LightingPasses/ShadeSecondarySurfaces.hlsl similarity index 92% rename from shaders/LightingPasses/ShadeSecondarySurfaces.hlsl rename to Samples/FullSample/Shaders/LightingPasses/ShadeSecondarySurfaces.hlsl index 5056209..8f3e944 100644 --- a/shaders/LightingPasses/ShadeSecondarySurfaces.hlsl +++ b/Samples/FullSample/Shaders/LightingPasses/ShadeSecondarySurfaces.hlsl @@ -14,11 +14,11 @@ // because we do not trace the BRDF rays further. #define RAB_ENABLE_SPECULAR_MIS 0 -#include "RtxdiApplicationBridge.hlsli" +#include "RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include -#include -#include +#include +#include +#include #ifdef WITH_NRD #define NRD_HEADER_ONLY @@ -71,10 +71,10 @@ void RayGen() secondarySurface.viewDepth = 1.0; // doesn't matter secondarySurface.normal = octToNdirUnorm32(secondaryGBufferData.normal); secondarySurface.geoNormal = secondarySurface.normal; - secondarySurface.diffuseAlbedo = Unpack_R11G11B10_UFLOAT(secondaryGBufferData.diffuseAlbedo); + secondarySurface.material.diffuseAlbedo = Unpack_R11G11B10_UFLOAT(secondaryGBufferData.diffuseAlbedo); float4 specularRough = Unpack_R8G8B8A8_Gamma_UFLOAT(secondaryGBufferData.specularAndRoughness); - secondarySurface.specularF0 = specularRough.rgb; - secondarySurface.roughness = specularRough.a; + secondarySurface.material.specularF0 = specularRough.rgb; + secondarySurface.material.roughness = specularRough.a; secondarySurface.diffuseProbability = getSurfaceDiffuseProbability(secondarySurface); secondarySurface.viewDir = normalize(primarySurface.worldPos - secondarySurface.worldPos); @@ -136,7 +136,7 @@ void RayGen() ShadeSurfaceWithLightSample(reservoir, secondarySurface, lightSample, /* previousFrameTLAS = */ false, /* enableVisibilityReuse = */ false, indirectDiffuse, indirectSpecular, lightDistance); - radiance += indirectDiffuse * secondarySurface.diffuseAlbedo + indirectSpecular; + radiance += indirectDiffuse * secondarySurface.material.diffuseAlbedo + indirectSpecular; // Firefly suppression float indirectLuminance = calcLuminance(radiance); @@ -172,9 +172,9 @@ void RayGen() float3 diffuse = isSpecularRay ? 0.0 : radiance * throughput.rgb; float3 specular = isSpecularRay ? radiance * throughput.rgb : 0.0; - specular = DemodulateSpecular(primarySurface.specularF0, specular); + specular = DemodulateSpecular(primarySurface.material.specularF0, specular); StoreShadingOutput(GlobalIndex, pixelPosition, - primarySurface.viewDepth, primarySurface.roughness, diffuse, specular, 0, false, true); + primarySurface.viewDepth, primarySurface.material.roughness, diffuse, specular, 0, false, true); } } diff --git a/shaders/LightingPasses/ShadingHelpers.hlsli b/Samples/FullSample/Shaders/LightingPasses/ShadingHelpers.hlsli similarity index 90% rename from shaders/LightingPasses/ShadingHelpers.hlsli rename to Samples/FullSample/Shaders/LightingPasses/ShadingHelpers.hlsli index 43bd59e..1e26fd1 100644 --- a/shaders/LightingPasses/ShadingHelpers.hlsli +++ b/Samples/FullSample/Shaders/LightingPasses/ShadingHelpers.hlsli @@ -11,6 +11,30 @@ #ifndef SHADING_HELPERS_HLSLI #define SHADING_HELPERS_HLSLI +#include "NRDEncoding.hlsli" +#include "NRD.hlsli" + +struct SplitBrdf +{ + float demodulatedDiffuse; + float3 specular; +}; + +SplitBrdf EvaluateBrdf(RAB_Surface surface, float3 samplePosition) +{ + float3 N = surface.normal; + float3 V = surface.viewDir; + float3 L = normalize(samplePosition - surface.worldPos); + + SplitBrdf brdf; + brdf.demodulatedDiffuse = Lambert(surface.normal, -L); + if (surface.material.roughness == 0) + brdf.specular = 0; + else + brdf.specular = GGX_times_NdotL(V, L, surface.normal, max(surface.material.roughness, kMinRoughness), surface.material.specularF0); + return brdf; +} + #ifdef RTXDI_DIRESERVOIR_HLSLI bool ShadeSurfaceWithLightSample( diff --git a/shaders/PolymorphicLight.hlsli b/Samples/FullSample/Shaders/PolymorphicLight.hlsli similarity index 99% rename from shaders/PolymorphicLight.hlsli rename to Samples/FullSample/Shaders/PolymorphicLight.hlsli index 1ce072c..c069dbc 100644 --- a/shaders/PolymorphicLight.hlsli +++ b/Samples/FullSample/Shaders/PolymorphicLight.hlsli @@ -13,7 +13,6 @@ #include "HelperFunctions.hlsli" #include "LightShaping.hlsli" -#include #define LIGHT_SAMPING_EPSILON 1e-10 #define DISTANT_LIGHT_DISTANCE 10000.0 diff --git a/shaders/PostprocessGBuffer.hlsl b/Samples/FullSample/Shaders/PostprocessGBuffer.hlsl similarity index 100% rename from shaders/PostprocessGBuffer.hlsl rename to Samples/FullSample/Shaders/PostprocessGBuffer.hlsl diff --git a/shaders/PrepareLights.hlsl b/Samples/FullSample/Shaders/PrepareLights.hlsl similarity index 99% rename from shaders/PrepareLights.hlsl rename to Samples/FullSample/Shaders/PrepareLights.hlsl index f93a446..625f6ec 100644 --- a/shaders/PrepareLights.hlsl +++ b/Samples/FullSample/Shaders/PrepareLights.hlsl @@ -11,9 +11,9 @@ #pragma pack_matrix(row_major) #include -#include +#include #include -#include +#include #include "ShaderParameters.h" VK_PUSH_CONSTANT ConstantBuffer g_Const : register(b0); diff --git a/shaders/PreprocessEnvironmentMap.hlsl b/Samples/FullSample/Shaders/PreprocessEnvironmentMap.hlsl similarity index 98% rename from shaders/PreprocessEnvironmentMap.hlsl rename to Samples/FullSample/Shaders/PreprocessEnvironmentMap.hlsl index 70c563a..d4d5b3c 100644 --- a/shaders/PreprocessEnvironmentMap.hlsl +++ b/Samples/FullSample/Shaders/PreprocessEnvironmentMap.hlsl @@ -10,8 +10,8 @@ #include "ShaderParameters.h" #include "HelperFunctions.hlsli" -#include -#include +#include +#include RWTexture2D u_IntegratedMips[] : register(u0); diff --git a/shaders/RasterizedGBuffer.hlsl b/Samples/FullSample/Shaders/RasterizedGBuffer.hlsl similarity index 100% rename from shaders/RasterizedGBuffer.hlsl rename to Samples/FullSample/Shaders/RasterizedGBuffer.hlsl diff --git a/shaders/RaytracedGBuffer.hlsl b/Samples/FullSample/Shaders/RaytracedGBuffer.hlsl similarity index 100% rename from shaders/RaytracedGBuffer.hlsl rename to Samples/FullSample/Shaders/RaytracedGBuffer.hlsl diff --git a/shaders/RenderEnvironmentMap.hlsl b/Samples/FullSample/Shaders/RenderEnvironmentMap.hlsl similarity index 95% rename from shaders/RenderEnvironmentMap.hlsl rename to Samples/FullSample/Shaders/RenderEnvironmentMap.hlsl index dc5fdf5..e023591 100644 --- a/shaders/RenderEnvironmentMap.hlsl +++ b/Samples/FullSample/Shaders/RenderEnvironmentMap.hlsl @@ -11,7 +11,7 @@ #include "ShaderParameters.h" #include "HelperFunctions.hlsli" #include -#include +#include VK_PUSH_CONSTANT ConstantBuffer g_Const : register(b0); diff --git a/minimal/shaders/SceneGeometry.hlsli b/Samples/FullSample/Shaders/SceneGeometry.hlsli similarity index 99% rename from minimal/shaders/SceneGeometry.hlsli rename to Samples/FullSample/Shaders/SceneGeometry.hlsli index f910659..29a0ab3 100644 --- a/minimal/shaders/SceneGeometry.hlsli +++ b/Samples/FullSample/Shaders/SceneGeometry.hlsli @@ -13,7 +13,7 @@ #include -#include +#include #include #include diff --git a/shaders/ShaderParameters.h b/Samples/FullSample/Shaders/ShaderParameters.h similarity index 98% rename from shaders/ShaderParameters.h rename to Samples/FullSample/Shaders/ShaderParameters.h index 549153c..e029771 100644 --- a/shaders/ShaderParameters.h +++ b/Samples/FullSample/Shaders/ShaderParameters.h @@ -14,9 +14,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include "BRDFPTParameters.h" diff --git a/Samples/FullSample/Shaders/Shaders.cfg b/Samples/FullSample/Shaders/Shaders.cfg new file mode 100644 index 0000000..ef6266e --- /dev/null +++ b/Samples/FullSample/Shaders/Shaders.cfg @@ -0,0 +1,51 @@ +RasterizedGBuffer.hlsl -T vs -E vs_main +RasterizedGBuffer.hlsl -T ps -E ps_main -D ALPHA_TESTED={0,1} +RaytracedGBuffer.hlsl -T cs -E main -D USE_RAY_QUERY=1 +RaytracedGBuffer.hlsl -T lib -D USE_RAY_QUERY=0 +CompositingPass.hlsl -T cs -E main +GlassPass.hlsl -T cs -E main -D USE_RAY_QUERY=1 +GlassPass.hlsl -T lib -D USE_RAY_QUERY=0 +AccumulationPass.hlsl -T cs -E main +RenderEnvironmentMap.hlsl -T cs -E main +PreprocessEnvironmentMap.hlsl -T cs -E main -D INPUT_ENVIRONMENT_MAP={0,1} +VisualizeHdrSignals.hlsl -T ps -E main +VisualizeConfidence.hlsl -T ps -E main +DlssExposure.hlsl -T cs -E main +PostprocessGBuffer.hlsl -T cs -E main +DebugViz/NDirOctUNorm32Viz.hlsl -T cs -E main +DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl -T cs -E main +DebugViz/PackedR11G11B10UFloatViz.hlsl -T cs -E main + +PrepareLights.hlsl -T cs -E main +LightingPasses/Presampling/PresampleLights.hlsl -T cs -E main +LightingPasses/Presampling/PresampleEnvironmentMap.hlsl -T cs -E main +LightingPasses/Presampling/PresampleReGIR.hlsl -T cs -E main -D RTXDI_REGIR_MODE={RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/DI/GenerateInitialSamples.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/DI/GenerateInitialSamples.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/DI/TemporalResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/DI/TemporalResampling.hlsl -T lib -D USE_RAY_QUERY=0 +LightingPasses/DI/SpatialResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/DI/SpatialResampling.hlsl -T lib -D USE_RAY_QUERY=0 +LightingPasses/DI/FusedResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/DI/FusedResampling.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/DI/ShadeSamples.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/DI/ShadeSamples.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} + +LightingPasses/BrdfRayTracing.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/BrdfRayTracing.hlsl -T lib -D USE_RAY_QUERY=0 +LightingPasses/ShadeSecondarySurfaces.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} +LightingPasses/ShadeSecondarySurfaces.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} + +DenoisingPasses/ComputeGradients.hlsl -T cs -E main -D USE_RAY_QUERY=1 +DenoisingPasses/ComputeGradients.hlsl -T lib -D USE_RAY_QUERY=0 +DenoisingPasses/FilterGradientsPass.hlsl -T cs -E main +DenoisingPasses/ConfidencePass.hlsl -T cs -E main + +LightingPasses/GI/TemporalResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/GI/TemporalResampling.hlsl -T lib -E main -D USE_RAY_QUERY=0 +LightingPasses/GI/SpatialResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/GI/SpatialResampling.hlsl -T lib -E main -D USE_RAY_QUERY=0 +LightingPasses/GI/FusedResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/GI/FusedResampling.hlsl -T lib -E main -D USE_RAY_QUERY=0 +LightingPasses/GI/FinalShading.hlsl -T cs -E main -D USE_RAY_QUERY=1 +LightingPasses/GI/FinalShading.hlsl -T lib -E main -D USE_RAY_QUERY=0 diff --git a/shaders/VisualizeConfidence.hlsl b/Samples/FullSample/Shaders/VisualizeConfidence.hlsl similarity index 100% rename from shaders/VisualizeConfidence.hlsl rename to Samples/FullSample/Shaders/VisualizeConfidence.hlsl diff --git a/shaders/VisualizeHdrSignals.hlsl b/Samples/FullSample/Shaders/VisualizeHdrSignals.hlsl similarity index 97% rename from shaders/VisualizeHdrSignals.hlsl rename to Samples/FullSample/Shaders/VisualizeHdrSignals.hlsl index 2092235..c3ea521 100644 --- a/shaders/VisualizeHdrSignals.hlsl +++ b/Samples/FullSample/Shaders/VisualizeHdrSignals.hlsl @@ -13,8 +13,7 @@ #include "ShaderParameters.h" #include "HelperFunctions.hlsli" -#include -#include +#include ConstantBuffer g_Const : register(b0); Texture2D t_CompositedColor : register(t0); @@ -31,8 +30,8 @@ StructuredBuffer t_GIReservoirs : register(t9); #define RTXDI_LIGHT_RESERVOIR_BUFFER t_Reservoirs #define RTXDI_GI_RESERVOIR_BUFFER t_GIReservoirs #define RTXDI_ENABLE_STORE_RESERVOIR 0 -#include -#include +#include +#include float4 blend(float4 top, float4 bottom) { diff --git a/src/AppDefines.h b/Samples/FullSample/Source/AppDefines.h similarity index 100% rename from src/AppDefines.h rename to Samples/FullSample/Source/AppDefines.h diff --git a/Samples/FullSample/Source/CMakeLists.txt b/Samples/FullSample/Source/CMakeLists.txt new file mode 100644 index 0000000..9522ea6 --- /dev/null +++ b/Samples/FullSample/Source/CMakeLists.txt @@ -0,0 +1,93 @@ +set(project FullSample) +set(folder "RTXDI SDK") + +set(sources + "DebugViz/DebugVizPasses.cpp" + "DebugViz/DebugVizPasses.h" + "DebugViz/PackedDataVizPass.cpp" + "DebugViz/PackedDataVizPass.h" + "RenderPasses/AccumulationPass.cpp" + "RenderPasses/AccumulationPass.h" + "RenderPasses/CompositingPass.cpp" + "RenderPasses/CompositingPass.h" + "RenderPasses/ConfidencePass.cpp" + "RenderPasses/ConfidencePass.h" + "RenderPasses/FilterGradientsPass.cpp" + "RenderPasses/FilterGradientsPass.h" + "RenderPasses/GBufferPass.cpp" + "RenderPasses/GBufferPass.h" + "RenderPasses/GenerateMipsPass.cpp" + "RenderPasses/GenerateMipsPass.h" + "RenderPasses/GlassPass.cpp" + "RenderPasses/GlassPass.h" + "RenderPasses/LightingPasses.cpp" + "RenderPasses/LightingPasses.h" + "RenderPasses/PrepareLightsPass.cpp" + "RenderPasses/PrepareLightsPass.h" + "RenderPasses/RaytracingPass.cpp" + "RenderPasses/RaytracingPass.h" + "RenderPasses/RenderEnvironmentMapPass.cpp" + "RenderPasses/RenderEnvironmentMapPass.h" + "RenderPasses/VisualizationPass.cpp" + "RenderPasses/VisualizationPass.h" + "AppDefines.h" + "DLSS-DX12.cpp" + "DLSS-VK.cpp" + "DLSS.cpp" + "DLSS.h" + "main.cpp" + "NrdIntegration.cpp" + "NrdIntegration.h" + "Profiler.cpp" + "Profiler.h" + "ProfilerSections.h" + "RenderTargets.cpp" + "RenderTargets.h" + "RtxdiResources.cpp" + "RtxdiResources.h" + "SampleScene.cpp" + "SampleScene.h" + "Testing.cpp" + "Testing.h" + "UserInterface.cpp" + "UserInterface.h") + +# Organize MSVS filters (the little folders in the solution explorer) to match the folder structure +foreach(source IN LISTS sources) + get_filename_component(source_path "${source}" PATH) + string(REPLACE "/" "\\" source_path_msvc "${source_path}") + source_group("${source_path_msvc}" FILES "${source}") +endforeach() + + +include(CMakeDependentOption) + +cmake_dependent_option(RTXDI_CONSOLE_APP "Build the sample as a console application" OFF WIN32 OFF) + +if (RTXDI_CONSOLE_APP) + add_executable(${project} ${sources}) + target_compile_definitions(${project} PRIVATE IS_CONSOLE_APP=1) +else() + add_executable(${project} WIN32 ${sources}) +endif() + +target_link_libraries(${project} donut_core donut_engine donut_app donut_render Rtxdi cxxopts) +add_dependencies(${project} FullSampleShaders) +set_target_properties(${project} PROPERTIES FOLDER ${folder}) + +if (TARGET NRD) + target_compile_definitions(${project} PRIVATE WITH_NRD=1) + target_link_libraries(${project} NRD) + + # NRD doesn't add a public include path at this time, work around that + target_include_directories(${project} PRIVATE "${CMAKE_SOURCE_DIR}/NRD/Include") +endif() + +if (TARGET DLSS) + target_compile_definitions(${project} PRIVATE WITH_DLSS=1) + target_link_libraries(${project} DLSS) + add_custom_command(TARGET ${project} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${DLSS_SHARED_LIBRARY_PATH}" + "$/") +endif() diff --git a/src/DLSS-DX12.cpp b/Samples/FullSample/Source/DLSS-DX12.cpp similarity index 81% rename from src/DLSS-DX12.cpp rename to Samples/FullSample/Source/DLSS-DX12.cpp index 17a5154..9dec599 100644 --- a/src/DLSS-DX12.cpp +++ b/Samples/FullSample/Source/DLSS-DX12.cpp @@ -43,7 +43,7 @@ class DLSS_DX12 : public DLSS featureCommonInfo.LoggingInfo.MinimumLoggingLevel = NVSDK_NGX_LOGGING_LEVEL_OFF; featureCommonInfo.LoggingInfo.DisableOtherLoggingSinks = true; - NVSDK_NGX_Result result = NVSDK_NGX_D3D12_Init(c_ApplicationID, executablePathW.c_str(), d3ddevice, &featureCommonInfo); + NVSDK_NGX_Result result = NVSDK_NGX_D3D12_Init(c_applicationID, executablePathW.c_str(), d3ddevice, &featureCommonInfo); if (result != NVSDK_NGX_Result_Success) { @@ -51,44 +51,44 @@ class DLSS_DX12 : public DLSS return; } - result = NVSDK_NGX_D3D12_GetCapabilityParameters(&m_Parameters); + result = NVSDK_NGX_D3D12_GetCapabilityParameters(&m_parameters); if (result != NVSDK_NGX_Result_Success) return; int dlssAvailable = 0; - result = m_Parameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable); + result = m_parameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable); if (result != NVSDK_NGX_Result_Success || !dlssAvailable) { result = NVSDK_NGX_Result_Fail; - NVSDK_NGX_Parameter_GetI(m_Parameters, NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult, (int*)&result); + NVSDK_NGX_Parameter_GetI(m_parameters, NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult, (int*)&result); log::warning("NVIDIA DLSS is not available on this system, FeatureInitResult = 0x%08x (%ls)", result, GetNGXResultAsString(result)); return; } - m_FeatureSupported = true; + m_featureSupported = true; } void SetRenderSize( uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight) override { - if (!m_FeatureSupported) + if (!m_featureSupported) return; - if (m_InputWidth == inputWidth && m_InputHeight == inputHeight && m_OutputWidth == outputWidth && m_OutputHeight == outputHeight) + if (m_inputWidth == inputWidth && m_inputHeight == inputHeight && m_outputWidth == outputWidth && m_outputHeight == outputHeight) return; - if (m_DlssHandle) + if (m_dlssHandle) { - m_Device->waitForIdle(); - NVSDK_NGX_D3D12_ReleaseFeature(m_DlssHandle); - m_DlssHandle = nullptr; + m_device->waitForIdle(); + NVSDK_NGX_D3D12_ReleaseFeature(m_dlssHandle); + m_dlssHandle = nullptr; } - m_FeatureCommandList->open(); - ID3D12GraphicsCommandList* d3dcmdlist = m_FeatureCommandList->getNativeObject(nvrhi::ObjectTypes::D3D12_GraphicsCommandList); + m_featureCommandList->open(); + ID3D12GraphicsCommandList* d3dcmdlist = m_featureCommandList->getNativeObject(nvrhi::ObjectTypes::D3D12_GraphicsCommandList); NVSDK_NGX_DLSS_Create_Params dlssParams = {}; dlssParams.Feature.InWidth = inputWidth; @@ -101,10 +101,10 @@ class DLSS_DX12 : public DLSS NVSDK_NGX_DLSS_Feature_Flags_DepthInverted | NVSDK_NGX_DLSS_Feature_Flags_MVLowRes; - NVSDK_NGX_Result result = NGX_D3D12_CREATE_DLSS_EXT(d3dcmdlist, 1, 1, &m_DlssHandle, m_Parameters, &dlssParams); + NVSDK_NGX_Result result = NGX_D3D12_CREATE_DLSS_EXT(d3dcmdlist, 1, 1, &m_dlssHandle, m_parameters, &dlssParams); - m_FeatureCommandList->close(); - m_Device->executeCommandList(m_FeatureCommandList); + m_featureCommandList->close(); + m_device->executeCommandList(m_featureCommandList); if (result != NVSDK_NGX_Result_Success) { @@ -112,12 +112,12 @@ class DLSS_DX12 : public DLSS return; } - m_IsAvailable = true; + m_isAvailable = true; - m_InputWidth = inputWidth; - m_InputHeight = inputHeight; - m_OutputWidth = outputWidth; - m_OutputHeight = outputHeight; + m_inputWidth = inputWidth; + m_inputHeight = inputHeight; + m_outputWidth = outputWidth; + m_outputHeight = outputHeight; } void Render( @@ -131,7 +131,7 @@ class DLSS_DX12 : public DLSS const donut::engine::PlanarView& view, const donut::engine::PlanarView& viewPrev) override { - if (!m_IsAvailable) + if (!m_isAvailable) return; commandList->beginMarker("DLSS"); @@ -146,7 +146,7 @@ class DLSS_DX12 : public DLSS commandList->setTextureState(renderTargets.ResolvedColor, nvrhi::AllSubresources, nvrhi::ResourceStates::UnorderedAccess); commandList->setTextureState(depthTexture, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); commandList->setTextureState(renderTargets.MotionVectors, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); - commandList->setTextureState(m_ExposureTexture, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); + commandList->setTextureState(m_exposureTexture, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); commandList->commitBarriers(); NVSDK_NGX_D3D12_DLSS_Eval_Params evalParams = {}; @@ -155,14 +155,14 @@ class DLSS_DX12 : public DLSS evalParams.Feature.InSharpness = sharpness; evalParams.pInDepth = depthTexture->getNativeObject(nvrhi::ObjectTypes::D3D12_Resource); evalParams.pInMotionVectors = renderTargets.MotionVectors->getNativeObject(nvrhi::ObjectTypes::D3D12_Resource); - evalParams.pInExposureTexture = m_ExposureTexture->getNativeObject(nvrhi::ObjectTypes::D3D12_Resource); + evalParams.pInExposureTexture = m_exposureTexture->getNativeObject(nvrhi::ObjectTypes::D3D12_Resource); evalParams.InReset = resetHistory; evalParams.InJitterOffsetX = view.GetPixelOffset().x; evalParams.InJitterOffsetY = view.GetPixelOffset().y; evalParams.InRenderSubrectDimensions.Width = view.GetViewExtent().width(); evalParams.InRenderSubrectDimensions.Height = view.GetViewExtent().height(); - NVSDK_NGX_Result result = NGX_D3D12_EVALUATE_DLSS_EXT(d3dcmdlist, m_DlssHandle, m_Parameters, &evalParams); + NVSDK_NGX_Result result = NGX_D3D12_EVALUATE_DLSS_EXT(d3dcmdlist, m_dlssHandle, m_parameters, &evalParams); commandList->clearState(); @@ -177,16 +177,16 @@ class DLSS_DX12 : public DLSS ~DLSS_DX12() override { - if (m_DlssHandle) + if (m_dlssHandle) { - NVSDK_NGX_D3D12_ReleaseFeature(m_DlssHandle); - m_DlssHandle = nullptr; + NVSDK_NGX_D3D12_ReleaseFeature(m_dlssHandle); + m_dlssHandle = nullptr; } - if (m_Parameters) + if (m_parameters) { - NVSDK_NGX_D3D12_DestroyParameters(m_Parameters); - m_Parameters = nullptr; + NVSDK_NGX_D3D12_DestroyParameters(m_parameters); + m_parameters = nullptr; } NVSDK_NGX_D3D12_Shutdown(); diff --git a/src/DLSS-VK.cpp b/Samples/FullSample/Source/DLSS-VK.cpp similarity index 85% rename from src/DLSS-VK.cpp rename to Samples/FullSample/Source/DLSS-VK.cpp index 6ff5bbe..2de8cc9 100644 --- a/src/DLSS-VK.cpp +++ b/Samples/FullSample/Source/DLSS-VK.cpp @@ -47,7 +47,7 @@ class DLSS_VK : public DLSS featureCommonInfo.LoggingInfo.MinimumLoggingLevel = NVSDK_NGX_LOGGING_LEVEL_OFF; featureCommonInfo.LoggingInfo.DisableOtherLoggingSinks = true; - NVSDK_NGX_Result result = NVSDK_NGX_VULKAN_Init(c_ApplicationID, + NVSDK_NGX_Result result = NVSDK_NGX_VULKAN_Init(c_applicationID, executablePathW.c_str(), vkInstance, vkPhysicalDevice, vkDevice, &featureCommonInfo); if (result != NVSDK_NGX_Result_Success) @@ -56,44 +56,44 @@ class DLSS_VK : public DLSS return; } - result = NVSDK_NGX_VULKAN_GetCapabilityParameters(&m_Parameters); + result = NVSDK_NGX_VULKAN_GetCapabilityParameters(&m_parameters); if (result != NVSDK_NGX_Result_Success) return; int dlssAvailable = 0; - result = m_Parameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable); + result = m_parameters->Get(NVSDK_NGX_Parameter_SuperSampling_Available, &dlssAvailable); if (result != NVSDK_NGX_Result_Success || !dlssAvailable) { result = NVSDK_NGX_Result_Fail; - NVSDK_NGX_Parameter_GetI(m_Parameters, NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult, (int*)&result); + NVSDK_NGX_Parameter_GetI(m_parameters, NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult, (int*)&result); log::warning("NVIDIA DLSS is not available on this system, FeatureInitResult = 0x%08x (%ls)", result, GetNGXResultAsString(result)); return; } - m_FeatureSupported = true; + m_featureSupported = true; } void SetRenderSize( uint32_t inputWidth, uint32_t inputHeight, uint32_t outputWidth, uint32_t outputHeight) override { - if (!m_FeatureSupported) + if (!m_featureSupported) return; - if (m_InputWidth == inputWidth && m_InputHeight == inputHeight && m_OutputWidth == outputWidth && m_OutputHeight == outputHeight) + if (m_inputWidth == inputWidth && m_inputHeight == inputHeight && m_outputWidth == outputWidth && m_outputHeight == outputHeight) return; - if (m_DlssHandle) + if (m_dlssHandle) { - m_Device->waitForIdle(); - NVSDK_NGX_VULKAN_ReleaseFeature(m_DlssHandle); - m_DlssHandle = nullptr; + m_device->waitForIdle(); + NVSDK_NGX_VULKAN_ReleaseFeature(m_dlssHandle); + m_dlssHandle = nullptr; } - m_FeatureCommandList->open(); - VkCommandBuffer vkCmdBuf = m_FeatureCommandList->getNativeObject(nvrhi::ObjectTypes::VK_CommandBuffer); + m_featureCommandList->open(); + VkCommandBuffer vkCmdBuf = m_featureCommandList->getNativeObject(nvrhi::ObjectTypes::VK_CommandBuffer); NVSDK_NGX_DLSS_Create_Params dlssParams = {}; dlssParams.Feature.InWidth = inputWidth; @@ -106,10 +106,10 @@ class DLSS_VK : public DLSS NVSDK_NGX_DLSS_Feature_Flags_DepthInverted | NVSDK_NGX_DLSS_Feature_Flags_MVLowRes; - NVSDK_NGX_Result result = NGX_VULKAN_CREATE_DLSS_EXT(vkCmdBuf, 1, 1, &m_DlssHandle, m_Parameters, &dlssParams); + NVSDK_NGX_Result result = NGX_VULKAN_CREATE_DLSS_EXT(vkCmdBuf, 1, 1, &m_dlssHandle, m_parameters, &dlssParams); - m_FeatureCommandList->close(); - m_Device->executeCommandList(m_FeatureCommandList); + m_featureCommandList->close(); + m_device->executeCommandList(m_featureCommandList); if (result != NVSDK_NGX_Result_Success) { @@ -117,12 +117,12 @@ class DLSS_VK : public DLSS return; } - m_IsAvailable = true; + m_isAvailable = true; - m_InputWidth = inputWidth; - m_InputHeight = inputHeight; - m_OutputWidth = outputWidth; - m_OutputHeight = outputHeight; + m_inputWidth = inputWidth; + m_inputHeight = inputHeight; + m_outputWidth = outputWidth; + m_outputHeight = outputHeight; } static void FillTextureResource(NVSDK_NGX_Resource_VK& resource, nvrhi::ITexture* texture) @@ -155,7 +155,7 @@ class DLSS_VK : public DLSS const donut::engine::PlanarView& view, const donut::engine::PlanarView& viewPrev) override { - if (!m_IsAvailable) + if (!m_isAvailable) return; ComputeExposure(commandList, toneMapperExposureBuffer, exposureScale); @@ -173,13 +173,13 @@ class DLSS_VK : public DLSS FillTextureResource(outColorResource, renderTargets.ResolvedColor); FillTextureResource(depthResource, depthTexture); FillTextureResource(motionVectorResource, renderTargets.MotionVectors); - FillTextureResource(exposureResource, m_ExposureTexture); + FillTextureResource(exposureResource, m_exposureTexture); commandList->setTextureState(renderTargets.HdrColor, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); commandList->setTextureState(renderTargets.ResolvedColor, nvrhi::AllSubresources, nvrhi::ResourceStates::UnorderedAccess); commandList->setTextureState(depthTexture, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); commandList->setTextureState(renderTargets.MotionVectors, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); - commandList->setTextureState(m_ExposureTexture, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); + commandList->setTextureState(m_exposureTexture, nvrhi::AllSubresources, nvrhi::ResourceStates::ShaderResource); commandList->commitBarriers(); NVSDK_NGX_VK_DLSS_Eval_Params evalParams = {}; @@ -195,7 +195,7 @@ class DLSS_VK : public DLSS evalParams.InRenderSubrectDimensions.Width = view.GetViewExtent().width(); evalParams.InRenderSubrectDimensions.Height = view.GetViewExtent().height(); - NVSDK_NGX_Result result = NGX_VULKAN_EVALUATE_DLSS_EXT(vkCmdBuf, m_DlssHandle, m_Parameters, &evalParams); + NVSDK_NGX_Result result = NGX_VULKAN_EVALUATE_DLSS_EXT(vkCmdBuf, m_dlssHandle, m_parameters, &evalParams); commandList->clearState(); @@ -208,16 +208,16 @@ class DLSS_VK : public DLSS ~DLSS_VK() override { - if (m_DlssHandle) + if (m_dlssHandle) { - NVSDK_NGX_VULKAN_ReleaseFeature(m_DlssHandle); - m_DlssHandle = nullptr; + NVSDK_NGX_VULKAN_ReleaseFeature(m_dlssHandle); + m_dlssHandle = nullptr; } - if (m_Parameters) + if (m_parameters) { - NVSDK_NGX_VULKAN_DestroyParameters(m_Parameters); - m_Parameters = nullptr; + NVSDK_NGX_VULKAN_DestroyParameters(m_parameters); + m_parameters = nullptr; } NVSDK_NGX_VULKAN_Shutdown(); diff --git a/src/DLSS.cpp b/Samples/FullSample/Source/DLSS.cpp similarity index 63% rename from src/DLSS.cpp rename to Samples/FullSample/Source/DLSS.cpp index 1b081cc..5580189 100644 --- a/src/DLSS.cpp +++ b/Samples/FullSample/Source/DLSS.cpp @@ -16,10 +16,18 @@ using namespace donut; -DLSS::DLSS(nvrhi::IDevice* device, donut::engine::ShaderFactory& shaderFactory) - : m_Device(device) +DLSS::DLSS(nvrhi::IDevice* device, donut::engine::ShaderFactory& shaderFactory) : + m_featureSupported(false), + m_isAvailable(false), + m_dlssHandle(nullptr), + m_parameters(nullptr), + m_inputWidth(0), + m_inputHeight(0), + m_outputWidth(0), + m_outputHeight(0), + m_device(device) { - m_ExposureShader = shaderFactory.CreateShader("app/DlssExposure.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_exposureShader = shaderFactory.CreateShader("app/DlssExposure.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); auto layoutDesc = nvrhi::BindingLayoutDesc() .setVisibility(nvrhi::ShaderType::Compute) @@ -27,13 +35,13 @@ DLSS::DLSS(nvrhi::IDevice* device, donut::engine::ShaderFactory& shaderFactory) .addItem(nvrhi::BindingLayoutItem::Texture_UAV(0)) .addItem(nvrhi::BindingLayoutItem::PushConstants(0, sizeof(float))); - m_ExposureBindingLayout = device->createBindingLayout(layoutDesc); + m_exposureBindingLayout = device->createBindingLayout(layoutDesc); auto pipelineDesc = nvrhi::ComputePipelineDesc() - .addBindingLayout(m_ExposureBindingLayout) - .setComputeShader(m_ExposureShader); + .addBindingLayout(m_exposureBindingLayout) + .setComputeShader(m_exposureShader); - m_ExposurePipeline = device->createComputePipeline(pipelineDesc); + m_exposurePipeline = device->createComputePipeline(pipelineDesc); auto textureDesc = nvrhi::TextureDesc() .setWidth(1) @@ -45,32 +53,42 @@ DLSS::DLSS(nvrhi::IDevice* device, donut::engine::ShaderFactory& shaderFactory) .setDimension(nvrhi::TextureDimension::Texture2D) .setIsUAV(true); - m_ExposureTexture = device->createTexture(textureDesc); + m_exposureTexture = device->createTexture(textureDesc); - m_FeatureCommandList = device->createCommandList(); + m_featureCommandList = device->createCommandList(); +} + +bool DLSS::IsSupported() const +{ + return m_featureSupported; +} + +bool DLSS::IsAvailable() const +{ + return m_featureSupported && m_isAvailable; } void DLSS::ComputeExposure(nvrhi::ICommandList* commandList, nvrhi::IBuffer* toneMapperExposureBuffer, float exposureScale) { - if (m_ExposureSourceBuffer != toneMapperExposureBuffer) + if (m_exposureSourceBuffer != toneMapperExposureBuffer) { - m_ExposureSourceBuffer = nullptr; - m_ExposureBindingSet = nullptr; + m_exposureSourceBuffer = nullptr; + m_exposureBindingSet = nullptr; } - if (!m_ExposureBindingSet) + if (!m_exposureBindingSet) { auto setDesc = nvrhi::BindingSetDesc() .addItem(nvrhi::BindingSetItem::TypedBuffer_SRV(0, toneMapperExposureBuffer)) - .addItem(nvrhi::BindingSetItem::Texture_UAV(0, m_ExposureTexture)) + .addItem(nvrhi::BindingSetItem::Texture_UAV(0, m_exposureTexture)) .addItem(nvrhi::BindingSetItem::PushConstants(0, sizeof(float))); - m_ExposureBindingSet = m_Device->createBindingSet(setDesc, m_ExposureBindingLayout); + m_exposureBindingSet = m_device->createBindingSet(setDesc, m_exposureBindingLayout); } auto state = nvrhi::ComputeState() - .setPipeline(m_ExposurePipeline) - .addBindingSet(m_ExposureBindingSet); + .setPipeline(m_exposurePipeline) + .addBindingSet(m_exposureBindingSet); commandList->setComputeState(state); commandList->setPushConstants(&exposureScale, sizeof(float)); diff --git a/src/DLSS.h b/Samples/FullSample/Source/DLSS.h similarity index 70% rename from src/DLSS.h rename to Samples/FullSample/Source/DLSS.h index 1d4115e..f706de2 100644 --- a/src/DLSS.h +++ b/Samples/FullSample/Source/DLSS.h @@ -28,38 +28,11 @@ struct NVSDK_NGX_Parameter; class DLSS { -protected: - bool m_FeatureSupported = false; - bool m_IsAvailable = false; - - NVSDK_NGX_Handle* m_DlssHandle = nullptr; - NVSDK_NGX_Parameter* m_Parameters = nullptr; - - // Use the AppID from the DLSS sample app until we get a separate one for RTXDI... wait, is it random? - static const uint32_t c_ApplicationID = 231313132; - - uint32_t m_InputWidth = 0; - uint32_t m_InputHeight = 0; - uint32_t m_OutputWidth = 0; - uint32_t m_OutputHeight = 0; - - nvrhi::DeviceHandle m_Device; - nvrhi::ShaderHandle m_ExposureShader; - nvrhi::ComputePipelineHandle m_ExposurePipeline; - nvrhi::TextureHandle m_ExposureTexture; - nvrhi::BufferHandle m_ExposureSourceBuffer; - nvrhi::BindingLayoutHandle m_ExposureBindingLayout; - nvrhi::BindingSetHandle m_ExposureBindingSet; - nvrhi::CommandListHandle m_FeatureCommandList; - - void ComputeExposure(nvrhi::ICommandList* commandList, nvrhi::IBuffer* toneMapperExposureBuffer, float exposureScale); - public: - DLSS(nvrhi::IDevice* device, donut::engine::ShaderFactory& shaderFactory); - [[nodiscard]] bool IsSupported() const { return m_FeatureSupported; } - [[nodiscard]] bool IsAvailable() const { return m_FeatureSupported && m_IsAvailable; } + [[nodiscard]] bool IsSupported() const; + [[nodiscard]] bool IsAvailable() const; virtual void SetRenderSize( uint32_t inputWidth, uint32_t inputHeight, @@ -85,6 +58,32 @@ class DLSS static std::unique_ptr CreateVK(nvrhi::IDevice* device, donut::engine::ShaderFactory& shaderFactory); #endif static void GetRequiredVulkanExtensions(std::vector& instanceExtensions, std::vector& deviceExtensions); + +protected: + bool m_featureSupported; + bool m_isAvailable; + + NVSDK_NGX_Handle* m_dlssHandle; + NVSDK_NGX_Parameter* m_parameters; + + // Use the AppID from the DLSS sample app until we get a separate one for RTXDI... wait, is it random? + static const uint32_t c_applicationID = 231313132; + + uint32_t m_inputWidth; + uint32_t m_inputHeight; + uint32_t m_outputWidth; + uint32_t m_outputHeight; + + nvrhi::DeviceHandle m_device; + nvrhi::ShaderHandle m_exposureShader; + nvrhi::ComputePipelineHandle m_exposurePipeline; + nvrhi::TextureHandle m_exposureTexture; + nvrhi::BufferHandle m_exposureSourceBuffer; + nvrhi::BindingLayoutHandle m_exposureBindingLayout; + nvrhi::BindingSetHandle m_exposureBindingSet; + nvrhi::CommandListHandle m_featureCommandList; + + void ComputeExposure(nvrhi::ICommandList* commandList, nvrhi::IBuffer* toneMapperExposureBuffer, float exposureScale); }; #endif diff --git a/src/DebugViz/DebugVizPasses.cpp b/Samples/FullSample/Source/DebugViz/DebugVizPasses.cpp similarity index 64% rename from src/DebugViz/DebugVizPasses.cpp rename to Samples/FullSample/Source/DebugViz/DebugVizPasses.cpp index a9ccaca..1b18643 100644 --- a/src/DebugViz/DebugVizPasses.cpp +++ b/Samples/FullSample/Source/DebugViz/DebugVizPasses.cpp @@ -17,54 +17,54 @@ DebugVizPasses::DebugVizPasses( std::shared_ptr shaderFactory, std::shared_ptr scene, nvrhi::IBindingLayout* bindlessLayout) : - m_GBufferNormalsViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)), - m_GBufferGeoNormalsViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)), - m_GBufferDiffuseAlbedoViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)), - m_GBufferSpecularRoughnessViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)) + m_gBufferNormalsViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)), + m_gBufferGeoNormalsViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)), + m_gBufferDiffuseAlbedoViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)), + m_gBufferSpecularRoughnessViz(std::make_unique(device, shaderFactory, scene, bindlessLayout)) { } void DebugVizPasses::CreatePipelines() { - m_GBufferNormalsViz->CreatePipeline("app/DebugViz/NDirOctUNorm32Viz.hlsl"); - m_GBufferGeoNormalsViz->CreatePipeline("app/DebugViz/NDirOctUNorm32Viz.hlsl"); - m_GBufferDiffuseAlbedoViz->CreatePipeline("app/DebugViz/PackedR11G11B10UFloatViz.hlsl"); - m_GBufferSpecularRoughnessViz->CreatePipeline("app/DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl"); + m_gBufferNormalsViz->CreatePipeline("app/DebugViz/NDirOctUNorm32Viz.hlsl"); + m_gBufferGeoNormalsViz->CreatePipeline("app/DebugViz/NDirOctUNorm32Viz.hlsl"); + m_gBufferDiffuseAlbedoViz->CreatePipeline("app/DebugViz/PackedR11G11B10UFloatViz.hlsl"); + m_gBufferSpecularRoughnessViz->CreatePipeline("app/DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl"); } void DebugVizPasses::CreateBindingSets(RenderTargets& renderTargets, nvrhi::TextureHandle dst) { - m_GBufferNormalsViz->CreateBindingSet(renderTargets.GBufferNormals, renderTargets.PrevGBufferNormals, renderTargets.DebugColor); - m_GBufferGeoNormalsViz->CreateBindingSet(renderTargets.GBufferGeoNormals, renderTargets.PrevGBufferGeoNormals, renderTargets.DebugColor); - m_GBufferDiffuseAlbedoViz->CreateBindingSet(renderTargets.GBufferDiffuseAlbedo, renderTargets.PrevGBufferDiffuseAlbedo, renderTargets.DebugColor); - m_GBufferSpecularRoughnessViz->CreateBindingSet(renderTargets.GBufferSpecularRough, renderTargets.PrevGBufferSpecularRough, renderTargets.DebugColor); + m_gBufferNormalsViz->CreateBindingSet(renderTargets.GBufferNormals, renderTargets.PrevGBufferNormals, renderTargets.DebugColor); + m_gBufferGeoNormalsViz->CreateBindingSet(renderTargets.GBufferGeoNormals, renderTargets.PrevGBufferGeoNormals, renderTargets.DebugColor); + m_gBufferDiffuseAlbedoViz->CreateBindingSet(renderTargets.GBufferDiffuseAlbedo, renderTargets.PrevGBufferDiffuseAlbedo, renderTargets.DebugColor); + m_gBufferSpecularRoughnessViz->CreateBindingSet(renderTargets.GBufferSpecularRough, renderTargets.PrevGBufferSpecularRough, renderTargets.DebugColor); } void DebugVizPasses::RenderUnpackedNormals(nvrhi::ICommandList* commandList, const donut::engine::IView& view) { - m_GBufferNormalsViz->Render(commandList, view); + m_gBufferNormalsViz->Render(commandList, view); } void DebugVizPasses::RenderUnpackedGeoNormals(nvrhi::ICommandList* commandList, const donut::engine::IView& view) { - m_GBufferGeoNormalsViz->Render(commandList, view); + m_gBufferGeoNormalsViz->Render(commandList, view); } void DebugVizPasses::RenderUnpackedDiffuseAlbeo(nvrhi::ICommandList* commandList, const donut::engine::IView& view) { - m_GBufferDiffuseAlbedoViz->Render(commandList, view); + m_gBufferDiffuseAlbedoViz->Render(commandList, view); } void DebugVizPasses::RenderUnpackedSpecularRoughness(nvrhi::ICommandList* commandList, const donut::engine::IView& view) { - m_GBufferSpecularRoughnessViz->Render(commandList, view); + m_gBufferSpecularRoughnessViz->Render(commandList, view); } void DebugVizPasses::NextFrame() { - m_GBufferNormalsViz->NextFrame(); - m_GBufferGeoNormalsViz->NextFrame(); - m_GBufferDiffuseAlbedoViz->NextFrame(); - m_GBufferSpecularRoughnessViz->NextFrame(); + m_gBufferNormalsViz->NextFrame(); + m_gBufferGeoNormalsViz->NextFrame(); + m_gBufferDiffuseAlbedoViz->NextFrame(); + m_gBufferSpecularRoughnessViz->NextFrame(); } \ No newline at end of file diff --git a/src/DebugViz/DebugVizPasses.h b/Samples/FullSample/Source/DebugViz/DebugVizPasses.h similarity index 85% rename from src/DebugViz/DebugVizPasses.h rename to Samples/FullSample/Source/DebugViz/DebugVizPasses.h index 9f54c9b..255d948 100644 --- a/src/DebugViz/DebugVizPasses.h +++ b/Samples/FullSample/Source/DebugViz/DebugVizPasses.h @@ -35,9 +35,8 @@ class DebugVizPasses void NextFrame(); private: - std::unique_ptr m_GBufferNormalsViz; - std::unique_ptr m_GBufferGeoNormalsViz; - std::unique_ptr m_GBufferDiffuseAlbedoViz; - std::unique_ptr m_GBufferSpecularRoughnessViz; + std::unique_ptr m_gBufferNormalsViz; + std::unique_ptr m_gBufferGeoNormalsViz; + std::unique_ptr m_gBufferDiffuseAlbedoViz; + std::unique_ptr m_gBufferSpecularRoughnessViz; }; - diff --git a/src/DebugViz/PackedDataVizPass.cpp b/Samples/FullSample/Source/DebugViz/PackedDataVizPass.cpp similarity index 75% rename from src/DebugViz/PackedDataVizPass.cpp rename to Samples/FullSample/Source/DebugViz/PackedDataVizPass.cpp index 003c715..2276b85 100644 --- a/src/DebugViz/PackedDataVizPass.cpp +++ b/Samples/FullSample/Source/DebugViz/PackedDataVizPass.cpp @@ -31,10 +31,10 @@ PackedDataVizPass::PackedDataVizPass( std::shared_ptr shaderFactory, std::shared_ptr scene, nvrhi::IBindingLayout* bindlessLayout) : - m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_Scene(std::move(scene)) + m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_scene(std::move(scene)) { nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -43,21 +43,21 @@ PackedDataVizPass::PackedDataVizPass( nvrhi::BindingLayoutItem::Texture_UAV(0), }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); } void PackedDataVizPass::CreatePipeline(const std::string& shaderPath) { std::string debugMsg = "Initializing PackedDataVizPass with " + shaderPath + "..."; donut::log::debug(debugMsg.c_str()); - gpuPerfMarker = "Packed Data Viz Pass:" + shaderPath; + m_gpuPerfMarker = "Packed Data Viz Pass:" + shaderPath; - m_ComputeShader = m_ShaderFactory->CreateShader(shaderPath.c_str(), "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader(shaderPath.c_str(), "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void PackedDataVizPass::CreateBindingSet(nvrhi::TextureHandle src, nvrhi::TextureHandle prevSrc, nvrhi::TextureHandle dst) @@ -70,22 +70,22 @@ void PackedDataVizPass::CreateBindingSet(nvrhi::TextureHandle src, nvrhi::Textur nvrhi::BindingSetItem::Texture_UAV(0, dst) }; - m_BindingSetEven = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSetEven = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); bindingSetDesc.bindings[0].resourceHandle = prevSrc; - m_BindingSetOdd = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSetOdd = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); } void PackedDataVizPass::Render( nvrhi::ICommandList* commandList, const donut::engine::IView& view) { - commandList->beginMarker(gpuPerfMarker.c_str()); + commandList->beginMarker(m_gpuPerfMarker.c_str()); nvrhi::ComputeState state; - state.bindings = { m_BindingSetEven, m_Scene->GetDescriptorTable() }; - state.pipeline = m_ComputePipeline; + state.bindings = { m_bindingSetEven, m_scene->GetDescriptorTable() }; + state.pipeline = m_computePipeline; commandList->setComputeState(state); commandList->dispatch( @@ -98,5 +98,5 @@ void PackedDataVizPass::Render( void PackedDataVizPass::NextFrame() { - std::swap(m_BindingSetEven, m_BindingSetOdd); + std::swap(m_bindingSetEven, m_bindingSetOdd); } \ No newline at end of file diff --git a/src/DebugViz/PackedDataVizPass.h b/Samples/FullSample/Source/DebugViz/PackedDataVizPass.h similarity index 73% rename from src/DebugViz/PackedDataVizPass.h rename to Samples/FullSample/Source/DebugViz/PackedDataVizPass.h index 2c528a2..c47b7b6 100644 --- a/src/DebugViz/PackedDataVizPass.h +++ b/Samples/FullSample/Source/DebugViz/PackedDataVizPass.h @@ -27,22 +27,6 @@ struct UIData; class PackedDataVizPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSetEven; - nvrhi::BindingSetHandle m_BindingSetOdd; - - nvrhi::BufferHandle m_ConstantBuffer; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_Scene; - std::string gpuPerfMarker; - public: PackedDataVizPass( nvrhi::IDevice* device, @@ -59,4 +43,20 @@ class PackedDataVizPass const donut::engine::IView& view); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSetEven; + nvrhi::BindingSetHandle m_bindingSetOdd; + + nvrhi::BufferHandle m_constantBuffer; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_scene; + std::string m_gpuPerfMarker; }; diff --git a/src/NrdIntegration.cpp b/Samples/FullSample/Source/NrdIntegration.cpp similarity index 91% rename from src/NrdIntegration.cpp rename to Samples/FullSample/Source/NrdIntegration.cpp index 340dea3..96d9529 100644 --- a/src/NrdIntegration.cpp +++ b/Samples/FullSample/Source/NrdIntegration.cpp @@ -92,12 +92,12 @@ static nvrhi::Format GetNvrhiFormat(nrd::Format format) } NrdIntegration::NrdIntegration(nvrhi::IDevice* device, nrd::Denoiser denoiser) - : m_Device(device) - , m_Initialized(false) - , m_Instance(nullptr) - , m_Denoiser(denoiser) - , m_BindingCache(device) - , m_PixelOffsetPrev(0.0f, 0.0f) + : m_device(device) + , m_initialized(false) + , m_instance(nullptr) + , m_denoiser(denoiser) + , m_bindingCache(device) + , m_pixelOffsetPrev(0.0f, 0.0f) { } @@ -106,7 +106,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) const nrd::LibraryDesc& libraryDesc = nrd::GetLibraryDesc(); const nrd::DenoiserDesc denoisers[] = { - { ID, m_Denoiser } + { ID, m_denoiser } }; nrd::InstanceCreationDesc instanceCreationDesc; @@ -116,13 +116,13 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) instanceCreationDesc.denoisersNum = dim(denoisers); instanceCreationDesc.denoisers = denoisers; - nrd::Result res = nrd::CreateInstance(instanceCreationDesc, m_Instance); + nrd::Result res = nrd::CreateInstance(instanceCreationDesc, m_instance); if (res != nrd::Result::SUCCESS) return false; - const nrd::InstanceDesc& instanceDesc = nrd::GetInstanceDesc(*m_Instance); - const bool isVulkan = m_Device->getGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN; + const nrd::InstanceDesc& instanceDesc = nrd::GetInstanceDesc(*m_instance); + const bool isVulkan = m_device->getGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN; const nvrhi::BufferDesc constantBufferDesc = nvrhi::utils::CreateVolatileConstantBufferDesc( @@ -130,7 +130,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) "NrdConstantBuffer", instanceDesc.descriptorPoolDesc.constantBuffersMaxNum * 4); - m_ConstantBuffer = m_Device->createBuffer(constantBufferDesc); + m_constantBuffer = m_device->createBuffer(constantBufferDesc); for (uint32_t samplerIndex = 0; samplerIndex < instanceDesc.samplersNum; samplerIndex++) @@ -159,7 +159,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) .setAllAddressModes(addressMode) .setAllFilters(filter); - const nvrhi::SamplerHandle sampler = m_Device->createSampler(samplerDesc); + const nvrhi::SamplerHandle sampler = m_device->createSampler(samplerDesc); if (!sampler) { @@ -167,7 +167,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) return false; } - m_Samplers.push_back(sampler); + m_samplers.push_back(sampler); } nvrhi::VulkanBindingOffsets bindingOffsets; @@ -182,7 +182,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) const nrd::ComputeShaderDesc& nrdComputeShader = isVulkan ? nrdPipelineDesc.computeShaderSPIRV : nrdPipelineDesc.computeShaderDXIL; NrdPipeline pipeline; - pipeline.Shader = m_Device->createShader(nvrhi::ShaderDesc(nvrhi::ShaderType::Compute), nrdComputeShader.bytecode, nrdComputeShader.size); + pipeline.Shader = m_device->createShader(nvrhi::ShaderDesc(nvrhi::ShaderType::Compute), nrdComputeShader.bytecode, nrdComputeShader.size); if (!pipeline.Shader) { @@ -235,7 +235,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) } } - pipeline.BindingLayout = m_Device->createBindingLayout(layoutDesc); + pipeline.BindingLayout = m_device->createBindingLayout(layoutDesc); if (!pipeline.BindingLayout) { @@ -246,7 +246,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) nvrhi::ComputePipelineDesc pipelineDesc; pipelineDesc.bindingLayouts = { pipeline.BindingLayout }; pipelineDesc.CS = pipeline.Shader; - pipeline.Pipeline = m_Device->createComputePipeline(pipelineDesc); + pipeline.Pipeline = m_device->createComputePipeline(pipelineDesc); if (!pipeline.Pipeline) { @@ -254,7 +254,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) return false; } - m_Pipelines.push_back(pipeline); + m_pipelines.push_back(pipeline); } @@ -290,7 +290,7 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) textureDesc.isUAV = true; textureDesc.debugName = ss.str(); - const nvrhi::TextureHandle texture = m_Device->createTexture(textureDesc); + const nvrhi::TextureHandle texture = m_device->createTexture(textureDesc); if (!texture) { @@ -299,18 +299,18 @@ bool NrdIntegration::Initialize(uint32_t width, uint32_t height) } if (isPermanent) - m_PermanentTextures.push_back(texture); + m_permanentTextures.push_back(texture); else - m_TransientTextures.push_back(texture); + m_transientTextures.push_back(texture); } - m_Initialized = true; + m_initialized = true; return true; } bool NrdIntegration::IsAvailable() const { - return m_Initialized; + return m_initialized; } static inline void MatrixToNrd(float* dest, const dm::float4x4& m) @@ -331,7 +331,7 @@ void NrdIntegration::RunDenoiserPasses( { if (denoiserSettings) { - nrd::SetDenoiserSettings(*m_Instance, ID, denoiserSettings); + nrd::SetDenoiserSettings(*m_instance, ID, denoiserSettings); } nrd::CommonSettings commonSettings = {}; @@ -349,9 +349,9 @@ void NrdIntegration::RunDenoiserPasses( commonSettings.cameraJitter[0] = pixelOffset.x; commonSettings.cameraJitter[1] = pixelOffset.y; - commonSettings.cameraJitterPrev[0] = m_PixelOffsetPrev.x; - commonSettings.cameraJitterPrev[1] = m_PixelOffsetPrev.y; - m_PixelOffsetPrev = pixelOffset; + commonSettings.cameraJitterPrev[0] = m_pixelOffsetPrev.x; + commonSettings.cameraJitterPrev[1] = m_pixelOffsetPrev.y; + m_pixelOffsetPrev = pixelOffset; commonSettings.resourceSize[0] = motionVectorDesc.width; commonSettings.resourceSize[1] = motionVectorDesc.height; @@ -382,13 +382,13 @@ void NrdIntegration::RunDenoiserPasses( commonSettings.isBaseColorMetalnessAvailable = false; commonSettings.enableValidation = false; - nrd::SetCommonSettings(*m_Instance, commonSettings); + nrd::SetCommonSettings(*m_instance, commonSettings); const nrd::DispatchDesc* dispatchDescs = nullptr; uint32_t dispatchDescNum = 0; - nrd::GetComputeDispatches(*m_Instance, &ID, 1, dispatchDescs, dispatchDescNum); + nrd::GetComputeDispatches(*m_instance, &ID, 1, dispatchDescs, dispatchDescNum); - const nrd::InstanceDesc& instanceDesc = nrd::GetInstanceDesc(*m_Instance); + const nrd::InstanceDesc& instanceDesc = nrd::GetInstanceDesc(*m_instance); for (uint32_t dispatchIndex = 0; dispatchIndex < dispatchDescNum; dispatchIndex++) { @@ -399,16 +399,16 @@ void NrdIntegration::RunDenoiserPasses( commandList->beginMarker(dispatchDesc.name); } - assert(m_ConstantBuffer); - commandList->writeBuffer(m_ConstantBuffer, dispatchDesc.constantBufferData, dispatchDesc.constantBufferDataSize); + assert(m_constantBuffer); + commandList->writeBuffer(m_constantBuffer, dispatchDesc.constantBufferData, dispatchDesc.constantBufferDataSize); nvrhi::BindingSetDesc setDesc; - setDesc.bindings.push_back(nvrhi::BindingSetItem::ConstantBuffer(instanceDesc.constantBufferRegisterIndex, m_ConstantBuffer)); + setDesc.bindings.push_back(nvrhi::BindingSetItem::ConstantBuffer(instanceDesc.constantBufferRegisterIndex, m_constantBuffer)); for (uint32_t samplerIndex = 0; samplerIndex < instanceDesc.samplersNum; samplerIndex++) { - assert(m_Samplers[samplerIndex]); - setDesc.bindings.push_back(nvrhi::BindingSetItem::Sampler(instanceDesc.samplersBaseRegisterIndex + samplerIndex, m_Samplers[samplerIndex])); + assert(m_samplers[samplerIndex]); + setDesc.bindings.push_back(nvrhi::BindingSetItem::Sampler(instanceDesc.samplersBaseRegisterIndex + samplerIndex, m_samplers[samplerIndex])); } const nrd::PipelineDesc& nrdPipelineDesc = instanceDesc.pipelines[dispatchDesc.pipelineIndex]; @@ -456,10 +456,10 @@ void NrdIntegration::RunDenoiserPasses( texture = renderTargets.DenoisedSpecularLighting; break; case nrd::ResourceType::TRANSIENT_POOL: - texture = m_TransientTextures[resource.indexInPool]; + texture = m_transientTextures[resource.indexInPool]; break; case nrd::ResourceType::PERMANENT_POOL: - texture = m_PermanentTextures[resource.indexInPool]; + texture = m_permanentTextures[resource.indexInPool]; break; default: assert(!"Unavailable resource type"); @@ -488,9 +488,9 @@ void NrdIntegration::RunDenoiserPasses( assert(resourceIndex == dispatchDesc.resourcesNum); - const NrdPipeline& pipeline = m_Pipelines[dispatchDesc.pipelineIndex]; + const NrdPipeline& pipeline = m_pipelines[dispatchDesc.pipelineIndex]; - nvrhi::BindingSetHandle bindingSet = m_BindingCache.GetOrCreateBindingSet(setDesc, pipeline.BindingLayout); + nvrhi::BindingSetHandle bindingSet = m_bindingCache.GetOrCreateBindingSet(setDesc, pipeline.BindingLayout); nvrhi::ComputeState state; state.bindings = { bindingSet }; @@ -506,4 +506,9 @@ void NrdIntegration::RunDenoiserPasses( } } +const nrd::Denoiser NrdIntegration::GetDenoiser() const +{ + return m_denoiser; +} + #endif diff --git a/src/NrdIntegration.h b/Samples/FullSample/Source/NrdIntegration.h similarity index 74% rename from src/NrdIntegration.h rename to Samples/FullSample/Source/NrdIntegration.h index 9d20b2f..3a934ab 100644 --- a/src/NrdIntegration.h +++ b/Samples/FullSample/Source/NrdIntegration.h @@ -27,27 +27,6 @@ namespace donut::engine class NrdIntegration { -private: - nvrhi::DeviceHandle m_Device; - bool m_Initialized; - nrd::Instance* m_Instance; - nrd::Denoiser m_Denoiser; - - struct NrdPipeline - { - nvrhi::ShaderHandle Shader; - nvrhi::BindingLayoutHandle BindingLayout; - nvrhi::ComputePipelineHandle Pipeline; - }; - - nvrhi::BufferHandle m_ConstantBuffer; - std::vector m_Pipelines; - std::vector m_Samplers; - std::vector m_PermanentTextures; - std::vector m_TransientTextures; - donut::engine::BindingCache m_BindingCache; - dm::float2 m_PixelOffsetPrev; - public: NrdIntegration(nvrhi::IDevice* device, nrd::Denoiser denoiser); @@ -64,7 +43,28 @@ class NrdIntegration const void* denoiserSettings, float debug); - const nrd::Denoiser GetDenoiser() const { return m_Denoiser; } + const nrd::Denoiser GetDenoiser() const; + +private: + nvrhi::DeviceHandle m_device; + bool m_initialized; + nrd::Instance* m_instance; + nrd::Denoiser m_denoiser; + + struct NrdPipeline + { + nvrhi::ShaderHandle Shader; + nvrhi::BindingLayoutHandle BindingLayout; + nvrhi::ComputePipelineHandle Pipeline; + }; + + nvrhi::BufferHandle m_constantBuffer; + std::vector m_pipelines; + std::vector m_samplers; + std::vector m_permanentTextures; + std::vector m_transientTextures; + donut::engine::BindingCache m_bindingCache; + dm::float2 m_pixelOffsetPrev; }; #endif diff --git a/src/Profiler.cpp b/Samples/FullSample/Source/Profiler.cpp similarity index 75% rename from src/Profiler.cpp rename to Samples/FullSample/Source/Profiler.cpp index af8d700..7e5551d 100644 --- a/src/Profiler.cpp +++ b/Samples/FullSample/Source/Profiler.cpp @@ -44,11 +44,11 @@ static const char* g_SectionNames[ProfilerSection::Count] = { }; Profiler::Profiler(donut::app::DeviceManager& deviceManager) - : m_DeviceManager(deviceManager) - , m_Device(deviceManager.GetDevice()) + : m_deviceManager(deviceManager) + , m_device(deviceManager.GetDevice()) { - for (auto& query : m_TimerQueries) - query = m_Device->createTimerQuery(); + for (auto& query : m_timerQueries) + query = m_device->createTimerQuery(); nvrhi::BufferDesc rayCountBufferDesc; rayCountBufferDesc.byteSize = sizeof(uint32_t) * 2 * ProfilerSection::Count; @@ -58,7 +58,7 @@ Profiler::Profiler(donut::app::DeviceManager& deviceManager) rayCountBufferDesc.debugName = "RayCount"; rayCountBufferDesc.initialState = nvrhi::ResourceStates::UnorderedAccess; rayCountBufferDesc.keepInitialState = true; - m_RayCountBuffer = m_Device->createBuffer(rayCountBufferDesc); + m_rayCountBuffer = m_device->createBuffer(rayCountBufferDesc); rayCountBufferDesc.canHaveUAVs = false; rayCountBufferDesc.cpuAccess = nvrhi::CpuAccessMode::Read; @@ -66,36 +66,41 @@ Profiler::Profiler(donut::app::DeviceManager& deviceManager) rayCountBufferDesc.debugName = "RayCountReadback"; for (size_t bank = 0; bank < 2; bank++) { - m_RayCountReadback[bank] = m_Device->createBuffer(rayCountBufferDesc); + m_rayCountReadback[bank] = m_device->createBuffer(rayCountBufferDesc); } } +bool Profiler::IsEnabled() const +{ + return m_enabled; +} + void Profiler::EnableProfiler(bool enable) { - m_Enabled = enable; + m_enabled = enable; } void Profiler::EnableAccumulation(bool enable) { - m_IsAccumulating = enable; + m_isAccumulating = enable; } void Profiler::ResetAccumulation() { - m_AccumulatedFrames = 0; - m_TimerValues.fill(0.0); - m_RayCounts.fill(0); - m_HitCounts.fill(0); + m_accumulatedFrames = 0; + m_timerValues.fill(0.0); + m_rayCounts.fill(0); + m_hitCounts.fill(0); } void Profiler::ResolvePreviousFrame() { - m_ActiveBank = !m_ActiveBank; + m_activeBank = !m_activeBank; - if (!m_Enabled) + if (!m_enabled) return; - const uint32_t* rayCountData = static_cast(m_Device->mapBuffer(m_RayCountReadback[m_ActiveBank], nvrhi::CpuAccessMode::Read)); + const uint32_t* rayCountData = static_cast(m_device->mapBuffer(m_rayCountReadback[m_activeBank], nvrhi::CpuAccessMode::Read)); for (uint32_t section = 0; section < ProfilerSection::MaterialReadback; section++) { @@ -103,11 +108,11 @@ void Profiler::ResolvePreviousFrame() uint32_t rayCount = 0; uint32_t hitCount = 0; - uint32_t timerIndex = section + m_ActiveBank * ProfilerSection::Count; + uint32_t timerIndex = section + m_activeBank * ProfilerSection::Count; - if (m_TimersUsed[timerIndex]) + if (m_timersUsed[timerIndex]) { - time = double(m_Device->getTimerQueryTime(m_TimerQueries[timerIndex])); + time = double(m_device->getTimerQueryTime(m_timerQueries[timerIndex])); time *= 1000.0; // seconds -> milliseconds if (rayCountData) @@ -117,44 +122,44 @@ void Profiler::ResolvePreviousFrame() } } - m_TimersUsed[timerIndex] = false; + m_timersUsed[timerIndex] = false; - if (m_IsAccumulating) + if (m_isAccumulating) { - m_TimerValues[section] += time; - m_RayCounts[section] += rayCount; - m_HitCounts[section] += hitCount; + m_timerValues[section] += time; + m_rayCounts[section] += rayCount; + m_hitCounts[section] += hitCount; } else { - m_TimerValues[section] = time; - m_RayCounts[section] = rayCount; - m_HitCounts[section] = hitCount; + m_timerValues[section] = time; + m_rayCounts[section] = rayCount; + m_hitCounts[section] = hitCount; } } if (rayCountData) - m_RayCounts[ProfilerSection::MaterialReadback] = rayCountData[ProfilerSection::MaterialReadback * 2]; + m_rayCounts[ProfilerSection::MaterialReadback] = rayCountData[ProfilerSection::MaterialReadback * 2]; else - m_RayCounts[ProfilerSection::MaterialReadback] = 0; + m_rayCounts[ProfilerSection::MaterialReadback] = 0; if (rayCountData) { - m_Device->unmapBuffer(m_RayCountReadback[m_ActiveBank]); + m_device->unmapBuffer(m_rayCountReadback[m_activeBank]); } - if (m_IsAccumulating) - m_AccumulatedFrames += 1; + if (m_isAccumulating) + m_accumulatedFrames += 1; else - m_AccumulatedFrames = 1; + m_accumulatedFrames = 1; } void Profiler::BeginFrame(nvrhi::ICommandList* commandList) { - if (!m_Enabled) + if (!m_enabled) return; - commandList->clearBufferUInt(m_RayCountBuffer, 0); + commandList->clearBufferUInt(m_rayCountBuffer, 0); BeginSection(commandList, ProfilerSection::Frame); } @@ -163,12 +168,12 @@ void Profiler::EndFrame(nvrhi::ICommandList* commandList) { EndSection(commandList, ProfilerSection::Frame); - if (m_Enabled) + if (m_enabled) { commandList->copyBuffer( - m_RayCountReadback[m_ActiveBank], + m_rayCountReadback[m_activeBank], 0, - m_RayCountBuffer, + m_rayCountBuffer, 0, ProfilerSection::Count * sizeof(uint32_t) * 2); } @@ -176,55 +181,60 @@ void Profiler::EndFrame(nvrhi::ICommandList* commandList) void Profiler::BeginSection(nvrhi::ICommandList* commandList, const ProfilerSection::Enum section) { - if (!m_Enabled) + if (!m_enabled) return; - uint32_t timerIndex = section + m_ActiveBank * ProfilerSection::Count; - commandList->beginTimerQuery(m_TimerQueries[timerIndex]); - m_TimersUsed[timerIndex] = true; + uint32_t timerIndex = section + m_activeBank * ProfilerSection::Count; + commandList->beginTimerQuery(m_timerQueries[timerIndex]); + m_timersUsed[timerIndex] = true; } void Profiler::EndSection(nvrhi::ICommandList* commandList, const ProfilerSection::Enum section) { - if (!m_Enabled) + if (!m_enabled) return; - uint32_t timerIndex = section + m_ActiveBank * ProfilerSection::Count; - commandList->endTimerQuery(m_TimerQueries[timerIndex]); + uint32_t timerIndex = section + m_activeBank * ProfilerSection::Count; + commandList->endTimerQuery(m_timerQueries[timerIndex]); +} + +void Profiler::SetRenderTargets(const std::shared_ptr& renderTargets) +{ + m_renderTargets = renderTargets; } double Profiler::GetTimer(ProfilerSection::Enum section) { - if (m_AccumulatedFrames == 0) + if (m_accumulatedFrames == 0) return 0.0; - return m_TimerValues[section] / double(m_AccumulatedFrames); + return m_timerValues[section] / double(m_accumulatedFrames); } double Profiler::GetRayCount(ProfilerSection::Enum section) { - if (m_AccumulatedFrames == 0) + if (m_accumulatedFrames == 0) return 0.0; - return double(m_RayCounts[section]) / double(m_AccumulatedFrames); + return double(m_rayCounts[section]) / double(m_accumulatedFrames); } double Profiler::GetHitCount(ProfilerSection::Enum section) { - if (m_AccumulatedFrames == 0) + if (m_accumulatedFrames == 0) return 0.0; - return double(m_HitCounts[section]) / double(m_AccumulatedFrames); + return double(m_hitCounts[section]) / double(m_accumulatedFrames); } int Profiler::GetMaterialReadback() { - return int(m_RayCounts[ProfilerSection::MaterialReadback]) - 1; + return int(m_rayCounts[ProfilerSection::MaterialReadback]) - 1; } void Profiler::BuildUI(const bool enableRayCounts) { - auto renderTargets = m_RenderTargets.lock(); + auto renderTargets = m_renderTargets.lock(); if (!renderTargets) return; @@ -294,14 +304,14 @@ void Profiler::BuildUI(const bool enableRayCounts) std::string Profiler::GetAsText() { - auto renderTargets = m_RenderTargets.lock(); + auto renderTargets = m_renderTargets.lock(); if (!renderTargets) return ""; const int renderPixels = renderTargets->Size.x * renderTargets->Size.y; std::stringstream text; - text << "Renderer: " << m_DeviceManager.GetRendererString() << std::endl; + text << "Renderer: " << m_deviceManager.GetRendererString() << std::endl; text << "Resolution: " << renderTargets->Size.x << " x " << renderTargets->Size.y << std::endl; for (uint32_t section = 0; section < ProfilerSection::MaterialReadback; section++) @@ -340,6 +350,11 @@ std::string Profiler::GetAsText() return text.str(); } +nvrhi::IBuffer* Profiler::GetRayCountBuffer() const +{ + return m_rayCountBuffer; +} + ProfilerScope::ProfilerScope(Profiler& profiler, nvrhi::ICommandList* commandList, ProfilerSection::Enum section) : m_Profiler(profiler) , m_CommandList(commandList) diff --git a/src/Profiler.h b/Samples/FullSample/Source/Profiler.h similarity index 72% rename from src/Profiler.h rename to Samples/FullSample/Source/Profiler.h index cd6ce68..360ae67 100644 --- a/src/Profiler.h +++ b/Samples/FullSample/Source/Profiler.h @@ -25,28 +25,10 @@ namespace donut::app class Profiler { -private: - bool m_Enabled = true; - bool m_IsAccumulating = false; - uint32_t m_AccumulatedFrames = 0; - uint32_t m_ActiveBank = 0; - - std::array m_TimerQueries; - std::array m_TimerValues{}; - std::array m_RayCounts{}; - std::array m_HitCounts{}; - std::array m_TimersUsed{}; - - donut::app::DeviceManager& m_DeviceManager; - nvrhi::DeviceHandle m_Device; - nvrhi::BufferHandle m_RayCountBuffer; - std::array m_RayCountReadback; - std::weak_ptr m_RenderTargets; - public: explicit Profiler(donut::app::DeviceManager& deviceManager); - bool IsEnabled() const { return m_Enabled; } + bool IsEnabled() const; void EnableProfiler(bool enable); void EnableAccumulation(bool enable); void ResetAccumulation(); @@ -55,7 +37,7 @@ class Profiler void EndFrame(nvrhi::ICommandList* commandList); void BeginSection(nvrhi::ICommandList* commandList, ProfilerSection::Enum section); void EndSection(nvrhi::ICommandList* commandList, ProfilerSection::Enum section); - void SetRenderTargets(const std::shared_ptr& renderTargets) { m_RenderTargets = renderTargets; } + void SetRenderTargets(const std::shared_ptr& renderTargets); double GetTimer(ProfilerSection::Enum section); double GetRayCount(ProfilerSection::Enum section); @@ -65,16 +47,29 @@ class Profiler void BuildUI(bool enableRayCounts); std::string GetAsText(); - [[nodiscard]] nvrhi::IBuffer* GetRayCountBuffer() const { return m_RayCountBuffer; } + [[nodiscard]] nvrhi::IBuffer* GetRayCountBuffer() const; + +private: + bool m_enabled = true; + bool m_isAccumulating = false; + uint32_t m_accumulatedFrames = 0; + uint32_t m_activeBank = 0; + + std::array m_timerQueries; + std::array m_timerValues{}; + std::array m_rayCounts{}; + std::array m_hitCounts{}; + std::array m_timersUsed{}; + + donut::app::DeviceManager& m_deviceManager; + nvrhi::DeviceHandle m_device; + nvrhi::BufferHandle m_rayCountBuffer; + std::array m_rayCountReadback; + std::weak_ptr m_renderTargets; }; class ProfilerScope { -private: - Profiler& m_Profiler; - nvrhi::ICommandList* m_CommandList; - ProfilerSection::Enum m_Section; - public: ProfilerScope(Profiler& profiler, nvrhi::ICommandList* commandList, ProfilerSection::Enum section); ~ProfilerScope(); @@ -84,4 +79,9 @@ class ProfilerScope ProfilerScope(const ProfilerScope&&) = delete; ProfilerScope& operator=(const ProfilerScope&) = delete; ProfilerScope& operator=(const ProfilerScope&&) = delete; + +private: + Profiler& m_Profiler; + nvrhi::ICommandList* m_CommandList; + ProfilerSection::Enum m_Section; }; diff --git a/src/ProfilerSections.h b/Samples/FullSample/Source/ProfilerSections.h similarity index 100% rename from src/ProfilerSections.h rename to Samples/FullSample/Source/ProfilerSections.h diff --git a/src/AccumulationPass.cpp b/Samples/FullSample/Source/RenderPasses/AccumulationPass.cpp similarity index 80% rename from src/AccumulationPass.cpp rename to Samples/FullSample/Source/RenderPasses/AccumulationPass.cpp index ac96911..4ca4b28 100644 --- a/src/AccumulationPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/AccumulationPass.cpp @@ -9,7 +9,7 @@ **************************************************************************/ #include "AccumulationPass.h" -#include "RenderTargets.h" +#include "../RenderTargets.h" #include #include @@ -17,7 +17,7 @@ #include using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -25,8 +25,8 @@ using namespace donut::engine; AccumulationPass::AccumulationPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory) - : m_Device(device) - , m_ShaderFactory(shaderFactory) + : m_device(device) + , m_shaderFactory(shaderFactory) { nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -37,24 +37,24 @@ AccumulationPass::AccumulationPass( nvrhi::BindingLayoutItem::PushConstants(0, sizeof(AccumulationConstants)) }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); auto samplerDesc = nvrhi::SamplerDesc() .setAllFilters(true); - m_Sampler = m_Device->createSampler(samplerDesc); + m_sampler = m_device->createSampler(samplerDesc); } void AccumulationPass::CreatePipeline() { donut::log::debug("Initializing AccumulationPass..."); - m_ComputeShader = m_ShaderFactory->CreateShader("app/AccumulationPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/AccumulationPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void AccumulationPass::CreateBindingSet(const RenderTargets& renderTargets) @@ -64,13 +64,13 @@ void AccumulationPass::CreateBindingSet(const RenderTargets& renderTargets) bindingSetDesc.bindings = { nvrhi::BindingSetItem::Texture_SRV(0, renderTargets.HdrColor), nvrhi::BindingSetItem::Texture_UAV(0, renderTargets.AccumulatedColor), - nvrhi::BindingSetItem::Sampler(0, m_Sampler), + nvrhi::BindingSetItem::Sampler(0, m_sampler), nvrhi::BindingSetItem::PushConstants(0, sizeof(AccumulationConstants)) }; - m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); - m_CompositedColor = renderTargets.HdrColor; + m_compositedColor = renderTargets.HdrColor; } void AccumulationPass::Render( @@ -84,7 +84,7 @@ void AccumulationPass::Render( const auto sourceViewport = sourceView.GetViewportState().viewports[0]; const auto upscaledViewport = upscaledView.GetViewportState().viewports[0]; - const auto& inputDesc = m_CompositedColor->getDesc(); + const auto& inputDesc = m_compositedColor->getDesc(); AccumulationConstants constants = {}; constants.inputSize = float2(sourceViewport.width(), sourceViewport.height()); @@ -94,8 +94,8 @@ void AccumulationPass::Render( constants.blendFactor = accumulationWeight; nvrhi::ComputeState state; - state.bindings = { m_BindingSet }; - state.pipeline = m_ComputePipeline; + state.bindings = { m_bindingSet }; + state.pipeline = m_computePipeline; commandList->setComputeState(state); commandList->setPushConstants(&constants, sizeof(constants)); diff --git a/src/AccumulationPass.h b/Samples/FullSample/Source/RenderPasses/AccumulationPass.h similarity index 76% rename from src/AccumulationPass.h rename to Samples/FullSample/Source/RenderPasses/AccumulationPass.h index d295b68..aa3f0c4 100644 --- a/src/AccumulationPass.h +++ b/Samples/FullSample/Source/RenderPasses/AccumulationPass.h @@ -23,18 +23,6 @@ class RenderTargets; class AccumulationPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::SamplerHandle m_Sampler; - nvrhi::TextureHandle m_CompositedColor; - - std::shared_ptr m_ShaderFactory; - public: AccumulationPass( nvrhi::IDevice* device, @@ -49,4 +37,16 @@ class AccumulationPass const donut::engine::IView& sourceView, const donut::engine::IView& upscaledView, float accumulationWeight); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::SamplerHandle m_sampler; + nvrhi::TextureHandle m_compositedColor; + + std::shared_ptr m_shaderFactory; }; diff --git a/src/CompositingPass.cpp b/Samples/FullSample/Source/RenderPasses/CompositingPass.cpp similarity index 81% rename from src/CompositingPass.cpp rename to Samples/FullSample/Source/RenderPasses/CompositingPass.cpp index f516841..cf62570 100644 --- a/src/CompositingPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/CompositingPass.cpp @@ -9,9 +9,9 @@ **************************************************************************/ #include "CompositingPass.h" -#include "RenderTargets.h" -#include "SampleScene.h" -#include "UserInterface.h" +#include "../RenderTargets.h" +#include "../SampleScene.h" +#include "../UserInterface.h" #include #include @@ -23,7 +23,7 @@ #include using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -34,13 +34,13 @@ CompositingPass::CompositingPass( std::shared_ptr commonPasses, std::shared_ptr scene, nvrhi::IBindingLayout* bindlessLayout) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) { - m_ConstantBuffer = m_Device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(CompositingConstants), "CompositingConstants", 16)); + m_constantBuffer = m_device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(CompositingConstants), "CompositingConstants", 16)); nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -60,19 +60,19 @@ CompositingPass::CompositingPass( nvrhi::BindingLayoutItem::VolatileConstantBuffer(0) }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); } void CompositingPass::CreatePipeline() { donut::log::debug("Initializing CompositingPass..."); - m_ComputeShader = m_ShaderFactory->CreateShader("app/CompositingPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/CompositingPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void CompositingPass::CreateBindingSet(const RenderTargets& renderTargets) @@ -93,18 +93,18 @@ void CompositingPass::CreateBindingSet(const RenderTargets& renderTargets) nvrhi::BindingSetItem::Texture_SRV(8, renderTargets.DenoisedSpecularLighting), nvrhi::BindingSetItem::Texture_UAV(0, renderTargets.HdrColor), nvrhi::BindingSetItem::Texture_UAV(1, renderTargets.MotionVectors), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_LinearWrapSampler), - nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer) + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_LinearWrapSampler), + nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer) }; - m_BindingSetEven = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSetEven = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); bindingSetDesc.bindings[0].resourceHandle = renderTargets.PrevDepth; bindingSetDesc.bindings[1].resourceHandle = renderTargets.PrevGBufferNormals; bindingSetDesc.bindings[2].resourceHandle = renderTargets.PrevGBufferDiffuseAlbedo; bindingSetDesc.bindings[3].resourceHandle = renderTargets.PrevGBufferSpecularRough; - m_BindingSetOdd = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSetOdd = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); } void CompositingPass::Render( @@ -131,11 +131,11 @@ void CompositingPass::Render( constants.noiseMix = ui.noiseMix; constants.noiseClampLow = ui.noiseClampLow; constants.noiseClampHigh = ui.noiseClampHigh; - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); nvrhi::ComputeState state; - state.bindings = { m_BindingSetEven, m_Scene->GetDescriptorTable() }; - state.pipeline = m_ComputePipeline; + state.bindings = { m_bindingSetEven, m_scene->GetDescriptorTable() }; + state.pipeline = m_computePipeline; commandList->setComputeState(state); commandList->dispatch( @@ -148,5 +148,5 @@ void CompositingPass::Render( void CompositingPass::NextFrame() { - std::swap(m_BindingSetEven, m_BindingSetOdd); + std::swap(m_bindingSetEven, m_bindingSetOdd); } diff --git a/src/CompositingPass.h b/Samples/FullSample/Source/RenderPasses/CompositingPass.h similarity index 74% rename from src/CompositingPass.h rename to Samples/FullSample/Source/RenderPasses/CompositingPass.h index f9e7b2e..ce7a380 100644 --- a/src/CompositingPass.h +++ b/Samples/FullSample/Source/RenderPasses/CompositingPass.h @@ -27,22 +27,6 @@ struct UIData; class CompositingPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSetEven; - nvrhi::BindingSetHandle m_BindingSetOdd; - - nvrhi::BufferHandle m_ConstantBuffer; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - public: CompositingPass( nvrhi::IDevice* device, @@ -65,4 +49,20 @@ class CompositingPass const EnvironmentLight& environmentLight); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSetEven; + nvrhi::BindingSetHandle m_bindingSetOdd; + + nvrhi::BufferHandle m_constantBuffer; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; }; diff --git a/src/ConfidencePass.cpp b/Samples/FullSample/Source/RenderPasses/ConfidencePass.cpp similarity index 80% rename from src/ConfidencePass.cpp rename to Samples/FullSample/Source/RenderPasses/ConfidencePass.cpp index b281d3a..cb0e268 100644 --- a/src/ConfidencePass.cpp +++ b/Samples/FullSample/Source/RenderPasses/ConfidencePass.cpp @@ -10,7 +10,7 @@ #include "ConfidencePass.h" #include "FilterGradientsPass.h" -#include "RenderTargets.h" +#include "../RenderTargets.h" #include #include @@ -19,15 +19,15 @@ using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; ConfidencePass::ConfidencePass( nvrhi::IDevice* device, std::shared_ptr shaderFactory) - : m_Device(device) - , m_ShaderFactory(shaderFactory) + : m_device(device) + , m_shaderFactory(shaderFactory) { nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -42,26 +42,26 @@ ConfidencePass::ConfidencePass( nvrhi::BindingLayoutItem::PushConstants(0, sizeof(ConfidenceConstants)) }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); auto samplerDesc = nvrhi::SamplerDesc() .setAllFilters(true) .setAllAddressModes(nvrhi::SamplerAddressMode::ClampToBorder) .setBorderColor(nvrhi::Color(0.f)); - m_Sampler = device->createSampler(samplerDesc); + m_sampler = device->createSampler(samplerDesc); } void ConfidencePass::CreatePipeline() { donut::log::debug("Initializing ConfidencePass..."); - m_ComputeShader = m_ShaderFactory->CreateShader("app/ConfidencePass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/DenoisingPasses/ConfidencePass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void ConfidencePass::CreateBindingSet(const RenderTargets& renderTargets) @@ -77,18 +77,18 @@ void ConfidencePass::CreateBindingSet(const RenderTargets& renderTargets) nvrhi::BindingSetItem::Texture_SRV(3, currentFrame ? renderTargets.PrevSpecularConfidence : renderTargets.SpecularConfidence), nvrhi::BindingSetItem::Texture_UAV(0, currentFrame ? renderTargets.DiffuseConfidence : renderTargets.PrevDiffuseConfidence), nvrhi::BindingSetItem::Texture_UAV(1, currentFrame ? renderTargets.SpecularConfidence : renderTargets.PrevSpecularConfidence), - nvrhi::BindingSetItem::Sampler(0, m_Sampler), + nvrhi::BindingSetItem::Sampler(0, m_sampler), nvrhi::BindingSetItem::PushConstants(0, sizeof(ConfidenceConstants)) }; - nvrhi::BindingSetHandle bindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + nvrhi::BindingSetHandle bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); if (currentFrame) - m_BindingSet = bindingSet; + m_bindingSet = bindingSet; else - m_PrevBindingSet = bindingSet; + m_prevBindingSet = bindingSet; } - m_GradientsTexture = renderTargets.Gradients; + m_gradientsTexture = renderTargets.Gradients; } void ConfidencePass::Render( @@ -101,7 +101,7 @@ void ConfidencePass::Render( { commandList->beginMarker("Confidence"); - const auto& gradientsDesc = m_GradientsTexture->getDesc(); + const auto& gradientsDesc = m_gradientsTexture->getDesc(); ConfidenceConstants constants = {}; constants.viewportSize = dm::uint2(view.GetViewExtent().width(), view.GetViewExtent().height()); @@ -114,8 +114,8 @@ void ConfidencePass::Render( constants.inputBufferIndex = FilterGradientsPass::GetOutputBufferIndex(); nvrhi::ComputeState state; - state.bindings = { m_BindingSet }; - state.pipeline = m_ComputePipeline; + state.bindings = { m_bindingSet }; + state.pipeline = m_computePipeline; commandList->setComputeState(state); commandList->setPushConstants(&constants, sizeof(constants)); @@ -130,5 +130,5 @@ void ConfidencePass::Render( void ConfidencePass::NextFrame() { - std::swap(m_BindingSet, m_PrevBindingSet); + std::swap(m_bindingSet, m_prevBindingSet); } diff --git a/src/ConfidencePass.h b/Samples/FullSample/Source/RenderPasses/ConfidencePass.h similarity index 75% rename from src/ConfidencePass.h rename to Samples/FullSample/Source/RenderPasses/ConfidencePass.h index 4f06a91..91e6000 100644 --- a/src/ConfidencePass.h +++ b/Samples/FullSample/Source/RenderPasses/ConfidencePass.h @@ -23,19 +23,6 @@ class RenderTargets; class ConfidencePass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingSetHandle m_PrevBindingSet; - nvrhi::TextureHandle m_GradientsTexture; - nvrhi::SamplerHandle m_Sampler; - - std::shared_ptr m_ShaderFactory; - public: ConfidencePass( nvrhi::IDevice* device, @@ -54,4 +41,17 @@ class ConfidencePass bool checkerboard); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingSetHandle m_prevBindingSet; + nvrhi::TextureHandle m_gradientsTexture; + nvrhi::SamplerHandle m_sampler; + + std::shared_ptr m_shaderFactory; }; diff --git a/src/FilterGradientsPass.cpp b/Samples/FullSample/Source/RenderPasses/FilterGradientsPass.cpp similarity index 78% rename from src/FilterGradientsPass.cpp rename to Samples/FullSample/Source/RenderPasses/FilterGradientsPass.cpp index 9ace989..b93f979 100644 --- a/src/FilterGradientsPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/FilterGradientsPass.cpp @@ -9,7 +9,7 @@ **************************************************************************/ #include "FilterGradientsPass.h" -#include "RenderTargets.h" +#include "../RenderTargets.h" #include #include @@ -17,7 +17,7 @@ #include using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -26,8 +26,8 @@ static const int c_NumFilterPasses = 4; FilterGradientsPass::FilterGradientsPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory) - : m_Device(device) - , m_ShaderFactory(shaderFactory) + : m_device(device) + , m_shaderFactory(shaderFactory) { nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -36,19 +36,19 @@ FilterGradientsPass::FilterGradientsPass( nvrhi::BindingLayoutItem::PushConstants(0, sizeof(FilterGradientsConstants)) }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); } void FilterGradientsPass::CreatePipeline() { donut::log::debug("Initializing FilterGradientsPass..."); - m_ComputeShader = m_ShaderFactory->CreateShader("app/FilterGradientsPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/DenoisingPasses/FilterGradientsPass.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void FilterGradientsPass::CreateBindingSet(const RenderTargets& renderTargets) @@ -60,9 +60,9 @@ void FilterGradientsPass::CreateBindingSet(const RenderTargets& renderTargets) nvrhi::BindingSetItem::PushConstants(0, sizeof(FilterGradientsConstants)) }; - m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); - m_GradientsTexture = renderTargets.Gradients; + m_gradientsTexture = renderTargets.Gradients; } void FilterGradientsPass::Render( @@ -78,8 +78,8 @@ void FilterGradientsPass::Render( constants.checkerboard = checkerboard; nvrhi::ComputeState state; - state.bindings = { m_BindingSet }; - state.pipeline = m_ComputePipeline; + state.bindings = { m_bindingSet }; + state.pipeline = m_computePipeline; commandList->setComputeState(state); for (int passIndex = 0; passIndex < c_NumFilterPasses; passIndex++) @@ -92,7 +92,7 @@ void FilterGradientsPass::Render( dm::div_ceil(view.GetViewExtent().height(), 8), 1); - nvrhi::utils::TextureUavBarrier(commandList, m_GradientsTexture); + nvrhi::utils::TextureUavBarrier(commandList, m_gradientsTexture); commandList->commitBarriers(); } diff --git a/src/FilterGradientsPass.h b/Samples/FullSample/Source/RenderPasses/FilterGradientsPass.h similarity index 78% rename from src/FilterGradientsPass.h rename to Samples/FullSample/Source/RenderPasses/FilterGradientsPass.h index 290fe18..ebd0634 100644 --- a/src/FilterGradientsPass.h +++ b/Samples/FullSample/Source/RenderPasses/FilterGradientsPass.h @@ -23,17 +23,6 @@ class RenderTargets; class FilterGradientsPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::TextureHandle m_GradientsTexture; - - std::shared_ptr m_ShaderFactory; - public: FilterGradientsPass( nvrhi::IDevice* device, @@ -49,4 +38,15 @@ class FilterGradientsPass bool checkerboard); static int GetOutputBufferIndex(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::TextureHandle m_gradientsTexture; + + std::shared_ptr m_shaderFactory; }; diff --git a/src/GBufferPass.cpp b/Samples/FullSample/Source/RenderPasses/GBufferPass.cpp similarity index 78% rename from src/GBufferPass.cpp rename to Samples/FullSample/Source/RenderPasses/GBufferPass.cpp index e47f82f..587f132 100644 --- a/src/GBufferPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/GBufferPass.cpp @@ -9,9 +9,9 @@ **************************************************************************/ #include "GBufferPass.h" -#include "RenderTargets.h" -#include "Profiler.h" -#include "SampleScene.h" +#include "../RenderTargets.h" +#include "../Profiler.h" +#include "../SampleScene.h" #include #include @@ -24,7 +24,7 @@ #include using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -36,14 +36,14 @@ RaytracedGBufferPass::RaytracedGBufferPass( std::shared_ptr scene, std::shared_ptr profiler, nvrhi::IBindingLayout* bindlessLayout) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) - , m_Profiler(std::move(profiler)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) + , m_profiler(std::move(profiler)) { - m_ConstantBuffer = m_Device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(GBufferConstants), "GBufferPassConstants", 16)); + m_constantBuffer = m_device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(GBufferConstants), "GBufferPassConstants", 16)); nvrhi::BindingLayoutDesc globalBindingLayoutDesc; globalBindingLayoutDesc.visibility = nvrhi::ShaderType::Compute | nvrhi::ShaderType::AllRayTracing; @@ -67,12 +67,12 @@ RaytracedGBufferPass::RaytracedGBufferPass( nvrhi::BindingLayoutItem::Sampler(0) }; - m_BindingLayout = m_Device->createBindingLayout(globalBindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(globalBindingLayoutDesc); } void RaytracedGBufferPass::CreatePipeline(bool useRayQuery) { - m_Pass.Init(m_Device, *m_ShaderFactory, "app/RaytracedGBuffer.hlsl", {}, useRayQuery, 16, m_BindingLayout, nullptr, m_BindlessLayout); + m_pass.Init(m_device, *m_shaderFactory, "app/RaytracedGBuffer.hlsl", {}, useRayQuery, 16, m_bindingLayout, nullptr, m_bindlessLayout); } void RaytracedGBufferPass::CreateBindingSet( @@ -92,23 +92,23 @@ void RaytracedGBufferPass::CreateBindingSet( nvrhi::BindingSetItem::Texture_UAV(5, renderTargets.GBufferEmissive), nvrhi::BindingSetItem::Texture_UAV(6, renderTargets.MotionVectors), nvrhi::BindingSetItem::Texture_UAV(7, renderTargets.DeviceDepthUAV), - nvrhi::BindingSetItem::TypedBuffer_UAV(8, m_Profiler->GetRayCountBuffer()), + nvrhi::BindingSetItem::TypedBuffer_UAV(8, m_profiler->GetRayCountBuffer()), - nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer), + nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer), nvrhi::BindingSetItem::PushConstants(1, sizeof(PerPassConstants)), nvrhi::BindingSetItem::RayTracingAccelStruct(0, currentFrame ? topLevelAS : prevTopLevelAS), - nvrhi::BindingSetItem::StructuredBuffer_SRV(1, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_Scene->GetMaterialBuffer()), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_AnisotropicWrapSampler) + nvrhi::BindingSetItem::StructuredBuffer_SRV(1, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_AnisotropicWrapSampler) }; - const nvrhi::BindingSetHandle bindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + const nvrhi::BindingSetHandle bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); if (currentFrame) - m_BindingSet = bindingSet; + m_bindingSet = bindingSet; else - m_PrevBindingSet = bindingSet; + m_prevBindingSet = bindingSet; } } @@ -132,18 +132,18 @@ void RaytracedGBufferPass::Render( constants.materialReadbackPosition = (settings.enableMaterialReadback) ? settings.materialReadbackPosition : int2(-1, -1); constants.textureLodBias = settings.textureLodBias; constants.textureGradientScale = powf(2.f, settings.textureLodBias); - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); PerPassConstants pushConstants{}; pushConstants.rayCountBufferIndex = ProfilerSection::GBufferFill; - m_Pass.Execute( + m_pass.Execute( commandList, view.GetViewExtent().width(), view.GetViewExtent().height(), - m_BindingSet, + m_bindingSet, nullptr, - m_Scene->GetDescriptorTable(), + m_scene->GetDescriptorTable(), &pushConstants, sizeof(pushConstants)); @@ -152,7 +152,7 @@ void RaytracedGBufferPass::Render( void RaytracedGBufferPass::NextFrame() { - std::swap(m_BindingSet, m_PrevBindingSet); + std::swap(m_bindingSet, m_prevBindingSet); } RasterizedGBufferPass::RasterizedGBufferPass( @@ -162,14 +162,14 @@ RasterizedGBufferPass::RasterizedGBufferPass( std::shared_ptr scene, std::shared_ptr profiler, nvrhi::IBindingLayout* bindlessLayout) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) - , m_Profiler(std::move(profiler)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) + , m_profiler(std::move(profiler)) { - m_ConstantBuffer = m_Device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(GBufferConstants), "GBufferPassConstants", 16)); + m_constantBuffer = m_device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(GBufferConstants), "GBufferPassConstants", 16)); nvrhi::BindingLayoutDesc globalBindingLayoutDesc; globalBindingLayoutDesc.visibility = nvrhi::ShaderType::Vertex | nvrhi::ShaderType::Pixel; @@ -183,7 +183,7 @@ RasterizedGBufferPass::RasterizedGBufferPass( nvrhi::BindingLayoutItem::TypedBuffer_UAV(0) }; - m_BindingLayout = m_Device->createBindingLayout(globalBindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(globalBindingLayoutDesc); } @@ -192,16 +192,16 @@ void RasterizedGBufferPass::CreateBindingSet() nvrhi::BindingSetDesc bindingSetDesc; bindingSetDesc.bindings = { - nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer), + nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer), nvrhi::BindingSetItem::PushConstants(1, sizeof(uint2)), - nvrhi::BindingSetItem::StructuredBuffer_SRV(0, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(1, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_Scene->GetMaterialBuffer()), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_AnisotropicWrapSampler), - nvrhi::BindingSetItem::TypedBuffer_UAV(0, m_Profiler->GetRayCountBuffer()) + nvrhi::BindingSetItem::StructuredBuffer_SRV(0, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(1, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_AnisotropicWrapSampler), + nvrhi::BindingSetItem::TypedBuffer_UAV(0, m_profiler->GetRayCountBuffer()) }; - m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + m_bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); } void RasterizedGBufferPass::CreatePipeline(const RenderTargets& renderTargets) @@ -212,9 +212,9 @@ void RasterizedGBufferPass::CreatePipeline(const RenderTargets& renderTargets) nvrhi::GraphicsPipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; - pipelineDesc.VS = m_ShaderFactory->CreateShader("app/RasterizedGBuffer.hlsl", "vs_main", nullptr, nvrhi::ShaderType::Vertex); - pipelineDesc.PS = m_ShaderFactory->CreateShader("app/RasterizedGBuffer.hlsl", "ps_main", ¯os, nvrhi::ShaderType::Pixel); + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; + pipelineDesc.VS = m_shaderFactory->CreateShader("app/RasterizedGBuffer.hlsl", "vs_main", nullptr, nvrhi::ShaderType::Vertex); + pipelineDesc.PS = m_shaderFactory->CreateShader("app/RasterizedGBuffer.hlsl", "ps_main", ¯os, nvrhi::ShaderType::Pixel); pipelineDesc.primType = nvrhi::PrimitiveType::TriangleList; pipelineDesc.renderState.rasterState.frontCounterClockwise = true; pipelineDesc.renderState.rasterState.cullMode = nvrhi::RasterCullMode::Back; @@ -223,13 +223,13 @@ void RasterizedGBufferPass::CreatePipeline(const RenderTargets& renderTargets) auto* framebuffer = renderTargets.GBufferFramebuffer->GetFramebuffer(nvrhi::AllSubresources); - m_OpaquePipeline = m_Device->createGraphicsPipeline(pipelineDesc, framebuffer); + m_opaquePipeline = m_device->createGraphicsPipeline(pipelineDesc, framebuffer); macros[0].definition = "1"; // ALPHA_TESTED - pipelineDesc.PS = m_ShaderFactory->CreateShader("app/RasterizedGBuffer.hlsl", "ps_main", ¯os, nvrhi::ShaderType::Pixel); + pipelineDesc.PS = m_shaderFactory->CreateShader("app/RasterizedGBuffer.hlsl", "ps_main", ¯os, nvrhi::ShaderType::Pixel); pipelineDesc.renderState.rasterState.cullMode = nvrhi::RasterCullMode::None; - m_AlphaTestedPipeline = m_Device->createGraphicsPipeline(pipelineDesc, framebuffer); + m_alphaTestedPipeline = m_device->createGraphicsPipeline(pipelineDesc, framebuffer); } void RasterizedGBufferPass::Render( @@ -255,7 +255,7 @@ void RasterizedGBufferPass::Render( constants.textureGradientScale = powf(2.f, settings.textureLodBias); constants.materialReadbackBufferIndex = ProfilerSection::MaterialReadback * 2; constants.materialReadbackPosition = (settings.enableMaterialReadback) ? settings.materialReadbackPosition : int2(-1, -1); - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); nvrhi::IFramebuffer* framebuffer = renderTargets.GBufferFramebuffer->GetFramebuffer(nvrhi::AllSubresources); @@ -263,7 +263,7 @@ void RasterizedGBufferPass::Render( commandList->setResourceStatesForFramebuffer(framebuffer); commandList->commitBarriers(); - const auto& instances = m_Scene->GetSceneGraph()->GetMeshInstances(); + const auto& instances = m_scene->GetSceneGraph()->GetMeshInstances(); const auto viewFrustum = view.GetViewFrustum(); @@ -273,8 +273,8 @@ void RasterizedGBufferPass::Render( break; nvrhi::GraphicsState state; - state.pipeline = alphaTested ? m_AlphaTestedPipeline : m_OpaquePipeline; - state.bindings = { m_BindingSet, m_Scene->GetDescriptorTable() }; + state.pipeline = alphaTested ? m_alphaTestedPipeline : m_opaquePipeline; + state.bindings = { m_bindingSet, m_scene->GetDescriptorTable() }; state.framebuffer = framebuffer; state.viewport = view.GetViewportState(); commandList->setGraphicsState(state); @@ -317,8 +317,8 @@ void RasterizedGBufferPass::Render( } PostprocessGBufferPass::PostprocessGBufferPass(nvrhi::IDevice* device, std::shared_ptr shaderFactory) - : m_Device(device) - , m_ShaderFactory(std::move(shaderFactory)) + : m_device(device) + , m_shaderFactory(std::move(shaderFactory)) { nvrhi::BindingLayoutDesc globalBindingLayoutDesc; globalBindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -330,18 +330,18 @@ PostprocessGBufferPass::PostprocessGBufferPass(nvrhi::IDevice* device, std::shar nvrhi::BindingLayoutItem::Texture_SRV(1) }; - m_BindingLayout = m_Device->createBindingLayout(globalBindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(globalBindingLayoutDesc); } void PostprocessGBufferPass::CreatePipeline() { - m_ComputeShader = m_ShaderFactory->CreateShader("app/PostprocessGBuffer.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/PostprocessGBuffer.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); auto pipelineDesc = nvrhi::ComputePipelineDesc() - .setComputeShader(m_ComputeShader) - .addBindingLayout(m_BindingLayout); + .setComputeShader(m_computeShader) + .addBindingLayout(m_bindingLayout); - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void PostprocessGBufferPass::CreateBindingSet(const RenderTargets& renderTargets) @@ -357,20 +357,20 @@ void PostprocessGBufferPass::CreateBindingSet(const RenderTargets& renderTargets nvrhi::BindingSetItem::Texture_SRV(1, currentFrame ? renderTargets.Depth : renderTargets.PrevDepth) }; - const nvrhi::BindingSetHandle bindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + const nvrhi::BindingSetHandle bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); if (currentFrame) - m_BindingSet = bindingSet; + m_bindingSet = bindingSet; else - m_PrevBindingSet = bindingSet; + m_prevBindingSet = bindingSet; } } void PostprocessGBufferPass::Render(nvrhi::ICommandList* commandList, const donut::engine::IView& view) { auto state = nvrhi::ComputeState() - .setPipeline(m_ComputePipeline) - .addBindingSet(m_BindingSet); + .setPipeline(m_computePipeline) + .addBindingSet(m_bindingSet); commandList->setComputeState(state); commandList->dispatch( @@ -380,5 +380,5 @@ void PostprocessGBufferPass::Render(nvrhi::ICommandList* commandList, const donu void PostprocessGBufferPass::NextFrame() { - std::swap(m_BindingSet, m_PrevBindingSet); + std::swap(m_bindingSet, m_prevBindingSet); } diff --git a/src/GBufferPass.h b/Samples/FullSample/Source/RenderPasses/GBufferPass.h similarity index 69% rename from src/GBufferPass.h rename to Samples/FullSample/Source/RenderPasses/GBufferPass.h index c480188..87ef5f7 100644 --- a/src/GBufferPass.h +++ b/Samples/FullSample/Source/RenderPasses/GBufferPass.h @@ -47,24 +47,7 @@ struct GBufferSettings class RaytracedGBufferPass { -private: - nvrhi::DeviceHandle m_Device; - - RayTracingPass m_Pass; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingSetHandle m_PrevBindingSet; - - nvrhi::BufferHandle m_ConstantBuffer; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - std::shared_ptr m_Profiler; - public: - RaytracedGBufferPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory, @@ -87,25 +70,26 @@ class RaytracedGBufferPass const GBufferSettings& settings); void NextFrame(); -}; -class RasterizedGBufferPass -{ private: - nvrhi::DeviceHandle m_Device; + nvrhi::DeviceHandle m_device; + + RayTracingPass m_pass; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingSetHandle m_prevBindingSet; - nvrhi::GraphicsPipelineHandle m_OpaquePipeline; - nvrhi::GraphicsPipelineHandle m_AlphaTestedPipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSet; + nvrhi::BufferHandle m_constantBuffer; - nvrhi::BufferHandle m_ConstantBuffer; + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; + std::shared_ptr m_profiler; +}; - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - std::shared_ptr m_Profiler; +class RasterizedGBufferPass +{ public: RasterizedGBufferPass( nvrhi::IDevice* device, @@ -125,24 +109,27 @@ class RasterizedGBufferPass const donut::engine::IView& viewPrev, const RenderTargets& renderTargets, const GBufferSettings& settings); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::GraphicsPipelineHandle m_opaquePipeline; + nvrhi::GraphicsPipelineHandle m_alphaTestedPipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSet; + + nvrhi::BufferHandle m_constantBuffer; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; + std::shared_ptr m_profiler; }; class PostprocessGBufferPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingSetHandle m_PrevBindingSet; - - std::shared_ptr m_ShaderFactory; - public: - PostprocessGBufferPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory); @@ -157,4 +144,16 @@ class PostprocessGBufferPass const donut::engine::IView& view); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingSetHandle m_prevBindingSet; + + std::shared_ptr m_shaderFactory; }; \ No newline at end of file diff --git a/src/GenerateMipsPass.cpp b/Samples/FullSample/Source/RenderPasses/GenerateMipsPass.cpp similarity index 86% rename from src/GenerateMipsPass.cpp rename to Samples/FullSample/Source/RenderPasses/GenerateMipsPass.cpp index b362b8c..7c4c56c 100644 --- a/src/GenerateMipsPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/GenerateMipsPass.cpp @@ -17,19 +17,19 @@ using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" GenerateMipsPass::GenerateMipsPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory, nvrhi::ITexture* sourceEnvironmentMap, nvrhi::ITexture* destinationTexture) - : m_SourceTexture(sourceEnvironmentMap) - , m_DestinationTexture(destinationTexture) + : m_sourceTexture(sourceEnvironmentMap) + , m_destinationTexture(destinationTexture) { donut::log::debug("Initializing GenerateMipsPass..."); - const auto& destinationDesc = m_DestinationTexture->getDesc(); + const auto& destinationDesc = m_destinationTexture->getDesc(); nvrhi::BindingSetDesc bindingSetDesc; bindingSetDesc.bindings = { @@ -45,14 +45,14 @@ GenerateMipsPass::GenerateMipsPass( { bindingSetDesc.bindings.push_back(nvrhi::BindingSetItem::Texture_UAV( mipLevel, - m_DestinationTexture, + m_destinationTexture, nvrhi::Format::UNKNOWN, nvrhi::TextureSubresourceSet(mipLevel, 1, 0, 1))); } nvrhi::BindingLayoutHandle bindingLayout; nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::Compute, 0, - bindingSetDesc, bindingLayout, m_BindingSet); + bindingSetDesc, bindingLayout, m_bindingSet); std::vector macros = { { "INPUT_ENVIRONMENT_MAP", sourceEnvironmentMap ? "1" : "0" } }; @@ -61,14 +61,14 @@ GenerateMipsPass::GenerateMipsPass( nvrhi::ComputePipelineDesc pipelineDesc; pipelineDesc.bindingLayouts = { bindingLayout }; pipelineDesc.CS = shader; - m_Pipeline = device->createComputePipeline(pipelineDesc); + m_pipeline = device->createComputePipeline(pipelineDesc); } void GenerateMipsPass::Process(nvrhi::ICommandList* commandList) { commandList->beginMarker("GenerateMips"); - const auto& destDesc = m_DestinationTexture->getDesc(); + const auto& destDesc = m_destinationTexture->getDesc(); constexpr uint32_t mipLevelsPerPass = 5; uint32_t width = destDesc.width; @@ -77,8 +77,8 @@ void GenerateMipsPass::Process(nvrhi::ICommandList* commandList) for (uint32_t sourceMipLevel = 0; sourceMipLevel < destDesc.mipLevels; sourceMipLevel += mipLevelsPerPass) { nvrhi::ComputeState state; - state.pipeline = m_Pipeline; - state.bindings = { m_BindingSet }; + state.pipeline = m_pipeline; + state.bindings = { m_bindingSet }; commandList->setComputeState(state); PreprocessEnvironmentMapConstants constants{}; diff --git a/src/GenerateMipsPass.h b/Samples/FullSample/Source/RenderPasses/GenerateMipsPass.h similarity index 84% rename from src/GenerateMipsPass.h rename to Samples/FullSample/Source/RenderPasses/GenerateMipsPass.h index 3e50584..1b8172c 100644 --- a/src/GenerateMipsPass.h +++ b/Samples/FullSample/Source/RenderPasses/GenerateMipsPass.h @@ -20,12 +20,6 @@ namespace donut::engine class GenerateMipsPass { -private: - nvrhi::ComputePipelineHandle m_Pipeline; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::TextureHandle m_SourceTexture; - nvrhi::TextureHandle m_DestinationTexture; - public: GenerateMipsPass( nvrhi::IDevice* device, @@ -34,4 +28,10 @@ class GenerateMipsPass nvrhi::ITexture* destinationTexture); void Process(nvrhi::ICommandList* commandList); + +private: + nvrhi::ComputePipelineHandle m_pipeline; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::TextureHandle m_sourceTexture; + nvrhi::TextureHandle m_destinationTexture; }; diff --git a/src/GlassPass.cpp b/Samples/FullSample/Source/RenderPasses/GlassPass.cpp similarity index 74% rename from src/GlassPass.cpp rename to Samples/FullSample/Source/RenderPasses/GlassPass.cpp index cf859b0..8d40876 100644 --- a/src/GlassPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/GlassPass.cpp @@ -9,18 +9,18 @@ **************************************************************************/ #include "GlassPass.h" -#include "RenderTargets.h" -#include "SampleScene.h" +#include "../RenderTargets.h" +#include "../SampleScene.h" #include #include #include #include -#include "Profiler.h" +#include "../Profiler.h" using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -32,14 +32,14 @@ GlassPass::GlassPass( std::shared_ptr scene, std::shared_ptr profiler, nvrhi::IBindingLayout* bindlessLayout) - : m_Device(device) - , m_ShaderFactory(shaderFactory) - , m_CommonPasses(commonPasses) - , m_Scene(scene) - , m_BindlessLayout(bindlessLayout) - , m_Profiler(profiler) + : m_device(device) + , m_shaderFactory(shaderFactory) + , m_commonPasses(commonPasses) + , m_scene(scene) + , m_bindlessLayout(bindlessLayout) + , m_profiler(profiler) { - m_ConstantBuffer = m_Device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(GlassConstants), "GlassConstants", 16)); + m_constantBuffer = m_device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(GlassConstants), "GlassConstants", 16)); nvrhi::BindingLayoutDesc globalBindingLayoutDesc; globalBindingLayoutDesc.visibility = nvrhi::ShaderType::Compute | nvrhi::ShaderType::AllRayTracing; @@ -57,12 +57,12 @@ GlassPass::GlassPass( nvrhi::BindingLayoutItem::PushConstants(1, sizeof(PerPassConstants)), }; - m_BindingLayout = m_Device->createBindingLayout(globalBindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(globalBindingLayoutDesc); } void GlassPass::CreatePipeline(bool useRayQuery) { - m_Pass.Init(m_Device, *m_ShaderFactory, "app/GlassPass.hlsl", {}, useRayQuery, 16, m_BindingLayout, nullptr, m_BindlessLayout); + m_pass.Init(m_device, *m_shaderFactory, "app/GlassPass.hlsl", {}, useRayQuery, 16, m_bindingLayout, nullptr, m_bindlessLayout); } void GlassPass::CreateBindingSet( @@ -75,24 +75,24 @@ void GlassPass::CreateBindingSet( nvrhi::BindingSetDesc bindingSetDesc; bindingSetDesc.bindings = { nvrhi::BindingSetItem::RayTracingAccelStruct(0, currentFrame ? topLevelAS : prevTopLevelAS), - nvrhi::BindingSetItem::StructuredBuffer_SRV(1, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_Scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(1, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_scene->GetMaterialBuffer()), nvrhi::BindingSetItem::Texture_SRV(4, renderTargets.GBufferEmissive), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_LinearWrapSampler), - nvrhi::BindingSetItem::Sampler(1, m_CommonPasses->m_LinearWrapSampler), + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_LinearWrapSampler), + nvrhi::BindingSetItem::Sampler(1, m_commonPasses->m_LinearWrapSampler), nvrhi::BindingSetItem::Texture_UAV(0, renderTargets.HdrColor), - nvrhi::BindingSetItem::TypedBuffer_UAV(1, m_Profiler->GetRayCountBuffer()), - nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer), + nvrhi::BindingSetItem::TypedBuffer_UAV(1, m_profiler->GetRayCountBuffer()), + nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer), nvrhi::BindingSetItem::PushConstants(1, sizeof(PerPassConstants)), }; - const nvrhi::BindingSetHandle bindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + const nvrhi::BindingSetHandle bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); if (currentFrame) - m_BindingSet = bindingSet; + m_bindingSet = bindingSet; else - m_PrevBindingSet = bindingSet; + m_prevBindingSet = bindingSet; } } @@ -115,18 +115,18 @@ void GlassPass::Render( constants.normalMapScale = normalMapScale; constants.materialReadbackBufferIndex = ProfilerSection::MaterialReadback * 2; constants.materialReadbackPosition = enableMaterialReadback ? materialReadbackPosition : int2(-1, -1); - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); PerPassConstants pushConstants{}; pushConstants.rayCountBufferIndex = ProfilerSection::Glass; - m_Pass.Execute(commandList, view.GetViewExtent().width(), view.GetViewExtent().height(), - m_BindingSet, nullptr, m_Scene->GetDescriptorTable(), &pushConstants, sizeof(pushConstants)); + m_pass.Execute(commandList, view.GetViewExtent().width(), view.GetViewExtent().height(), + m_bindingSet, nullptr, m_scene->GetDescriptorTable(), &pushConstants, sizeof(pushConstants)); commandList->endMarker(); } void GlassPass::NextFrame() { - std::swap(m_BindingSet, m_PrevBindingSet); + std::swap(m_bindingSet, m_prevBindingSet); } diff --git a/src/GlassPass.h b/Samples/FullSample/Source/RenderPasses/GlassPass.h similarity index 77% rename from src/GlassPass.h rename to Samples/FullSample/Source/RenderPasses/GlassPass.h index 5a1fba0..1f786c8 100644 --- a/src/GlassPass.h +++ b/Samples/FullSample/Source/RenderPasses/GlassPass.h @@ -30,22 +30,6 @@ class EnvironmentLight; class GlassPass { -private: - nvrhi::DeviceHandle m_Device; - - RayTracingPass m_Pass; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingSetHandle m_PrevBindingSet; - - nvrhi::BufferHandle m_ConstantBuffer; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - std::shared_ptr m_Profiler; - public: GlassPass( @@ -72,4 +56,20 @@ class GlassPass dm::int2 materialReadbackPosition); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + RayTracingPass m_pass; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingSetHandle m_prevBindingSet; + + nvrhi::BufferHandle m_constantBuffer; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; + std::shared_ptr m_profiler; }; diff --git a/src/LightingPasses.cpp b/Samples/FullSample/Source/RenderPasses/LightingPasses.cpp similarity index 70% rename from src/LightingPasses.cpp rename to Samples/FullSample/Source/RenderPasses/LightingPasses.cpp index f5f82e2..48672cf 100644 --- a/src/LightingPasses.cpp +++ b/Samples/FullSample/Source/RenderPasses/LightingPasses.cpp @@ -9,10 +9,10 @@ **************************************************************************/ #include "LightingPasses.h" -#include "RenderTargets.h" -#include "RtxdiResources.h" -#include "Profiler.h" -#include "SampleScene.h" +#include "../RenderTargets.h" +#include "../RtxdiResources.h" +#include "../Profiler.h" +#include "../SampleScene.h" #include "GBufferPass.h" #include @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include @@ -30,11 +30,11 @@ #endif using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; -BRDFPathTracing_MaterialOverrideParameters getDefaultBRDFPathTracingMaterialOverrideParams() +BRDFPathTracing_MaterialOverrideParameters GetDefaultBRDFPathTracingMaterialOverrideParams() { BRDFPathTracing_MaterialOverrideParameters params = {}; params.metalnessOverride = 0.5; @@ -43,7 +43,7 @@ BRDFPathTracing_MaterialOverrideParameters getDefaultBRDFPathTracingMaterialOver return params; } -BRDFPathTracing_SecondarySurfaceReSTIRDIParameters getDefaultBRDFPathTracingSecondarySurfaceReSTIRDIParams() +BRDFPathTracing_SecondarySurfaceReSTIRDIParameters GetDefaultBRDFPathTracingSecondarySurfaceReSTIRDIParams() { BRDFPathTracing_SecondarySurfaceReSTIRDIParameters params = {}; @@ -65,13 +65,13 @@ BRDFPathTracing_SecondarySurfaceReSTIRDIParameters getDefaultBRDFPathTracingSeco return params; } -BRDFPathTracing_Parameters getDefaultBRDFPathTracingParams() +BRDFPathTracing_Parameters GetDefaultBRDFPathTracingParams() { BRDFPathTracing_Parameters params; params.enableIndirectEmissiveSurfaces = false; params.enableReSTIRGI = false; - params.materialOverrideParams = getDefaultBRDFPathTracingMaterialOverrideParams(); - params.secondarySurfaceReSTIRDIParams = getDefaultBRDFPathTracingSecondarySurfaceReSTIRDIParams(); + params.materialOverrideParams = GetDefaultBRDFPathTracingMaterialOverrideParams(); + params.secondarySurfaceReSTIRDIParams = GetDefaultBRDFPathTracingSecondarySurfaceReSTIRDIParams(); return params; } @@ -83,12 +83,12 @@ LightingPasses::LightingPasses( std::shared_ptr profiler, nvrhi::IBindingLayout* bindlessLayout ) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) - , m_Profiler(std::move(profiler)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) + , m_profiler(std::move(profiler)) { // The binding layout descriptor must match the binding set descriptor defined in CreateBindingSet(...) below @@ -141,9 +141,9 @@ LightingPasses::LightingPasses( nvrhi::BindingLayoutItem::Sampler(1), }; - m_BindingLayout = m_Device->createBindingLayout(globalBindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(globalBindingLayoutDesc); - m_ConstantBuffer = m_Device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(ResamplingConstants), "ResamplingConstants", 16)); + m_constantBuffer = m_device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(ResamplingConstants), "ResamplingConstants", 16)); } void LightingPasses::CreateBindingSet( @@ -177,9 +177,9 @@ void LightingPasses::CreateBindingSet( nvrhi::BindingSetItem::RayTracingAccelStruct(30, currentFrame ? topLevelAS : prevTopLevelAS), nvrhi::BindingSetItem::RayTracingAccelStruct(31, currentFrame ? prevTopLevelAS : topLevelAS), - nvrhi::BindingSetItem::StructuredBuffer_SRV(32, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(33, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(34, m_Scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(32, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(33, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(34, m_scene->GetMaterialBuffer()), nvrhi::BindingSetItem::StructuredBuffer_SRV(20, resources.LightDataBuffer), nvrhi::BindingSetItem::TypedBuffer_SRV(21, resources.NeighborOffsetsBuffer), @@ -198,33 +198,33 @@ void LightingPasses::CreateBindingSet( nvrhi::BindingSetItem::TypedBuffer_UAV(10, resources.RisBuffer), nvrhi::BindingSetItem::TypedBuffer_UAV(11, resources.RisLightDataBuffer), - nvrhi::BindingSetItem::TypedBuffer_UAV(12, m_Profiler->GetRayCountBuffer()), + nvrhi::BindingSetItem::TypedBuffer_UAV(12, m_profiler->GetRayCountBuffer()), nvrhi::BindingSetItem::StructuredBuffer_UAV(13, resources.SecondaryGBuffer), - nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer), + nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer), nvrhi::BindingSetItem::PushConstants(1, sizeof(PerPassConstants)), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_LinearWrapSampler), - nvrhi::BindingSetItem::Sampler(1, m_CommonPasses->m_LinearWrapSampler) + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_LinearWrapSampler), + nvrhi::BindingSetItem::Sampler(1, m_commonPasses->m_LinearWrapSampler) }; - const nvrhi::BindingSetHandle bindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + const nvrhi::BindingSetHandle bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); if (currentFrame) - m_BindingSet = bindingSet; + m_bindingSet = bindingSet; else - m_PrevBindingSet = bindingSet; + m_prevBindingSet = bindingSet; } const auto& environmentPdfDesc = resources.EnvironmentPdfTexture->getDesc(); - m_EnvironmentPdfTextureSize.x = environmentPdfDesc.width; - m_EnvironmentPdfTextureSize.y = environmentPdfDesc.height; + m_environmentPdfTextureSize.x = environmentPdfDesc.width; + m_environmentPdfTextureSize.y = environmentPdfDesc.height; const auto& localLightPdfDesc = resources.LocalLightPdfTexture->getDesc(); - m_LocalLightPdfTextureSize.x = localLightPdfDesc.width; - m_LocalLightPdfTextureSize.y = localLightPdfDesc.height; + m_localLightPdfTextureSize.x = localLightPdfDesc.width; + m_localLightPdfTextureSize.y = localLightPdfDesc.height; - m_LightReservoirBuffer = resources.LightReservoirBuffer; - m_SecondarySurfaceBuffer = resources.SecondaryGBuffer; + m_lightReservoirBuffer = resources.LightReservoirBuffer; + m_secondarySurfaceBuffer = resources.SecondaryGBuffer; m_GIReservoirBuffer = resources.GIReservoirBuffer; } @@ -232,21 +232,21 @@ void LightingPasses::CreateComputePass(ComputePass& pass, const char* shaderName { donut::log::debug("Initializing ComputePass %s...", shaderName); - pass.Shader = m_ShaderFactory->CreateShader(shaderName, "main", ¯os, nvrhi::ShaderType::Compute); + pass.Shader = m_shaderFactory->CreateShader(shaderName, "main", ¯os, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; pipelineDesc.CS = pass.Shader; - pass.Pipeline = m_Device->createComputePipeline(pipelineDesc); + pass.Pipeline = m_device->createComputePipeline(pipelineDesc); } void LightingPasses::ExecuteComputePass(nvrhi::ICommandList* commandList, ComputePass& pass, const char* passName, dm::int2 dispatchSize, ProfilerSection::Enum profilerSection) { commandList->beginMarker(passName); - m_Profiler->BeginSection(commandList, profilerSection); + m_profiler->BeginSection(commandList, profilerSection); nvrhi::ComputeState state; - state.bindings = { m_BindingSet, m_Scene->GetDescriptorTable() }; + state.bindings = { m_bindingSet, m_scene->GetDescriptorTable() }; state.pipeline = pass.Pipeline; commandList->setComputeState(state); @@ -256,21 +256,21 @@ void LightingPasses::ExecuteComputePass(nvrhi::ICommandList* commandList, Comput commandList->dispatch(dispatchSize.x, dispatchSize.y, 1); - m_Profiler->EndSection(commandList, profilerSection); + m_profiler->EndSection(commandList, profilerSection); commandList->endMarker(); } void LightingPasses::ExecuteRayTracingPass(nvrhi::ICommandList* commandList, RayTracingPass& pass, bool enableRayCounts, const char* passName, dm::int2 dispatchSize, ProfilerSection::Enum profilerSection, nvrhi::IBindingSet* extraBindingSet) { commandList->beginMarker(passName); - m_Profiler->BeginSection(commandList, profilerSection); + m_profiler->BeginSection(commandList, profilerSection); PerPassConstants pushConstants{}; pushConstants.rayCountBufferIndex = enableRayCounts ? profilerSection : -1; - pass.Execute(commandList, dispatchSize.x, dispatchSize.y, m_BindingSet, extraBindingSet, m_Scene->GetDescriptorTable(), &pushConstants, sizeof(pushConstants)); + pass.Execute(commandList, dispatchSize.x, dispatchSize.y, m_bindingSet, extraBindingSet, m_scene->GetDescriptorTable(), &pushConstants, sizeof(pushConstants)); - m_Profiler->EndSection(commandList, profilerSection); + m_profiler->EndSection(commandList, profilerSection); commandList->endMarker(); } @@ -294,38 +294,38 @@ donut::engine::ShaderMacro LightingPasses::GetRegirMacro(const rtxdi::ReGIRStati return { "RTXDI_REGIR_MODE", regirMode }; } -void LightingPasses::createPresamplingPipelines() +void LightingPasses::CreatePresamplingPipelines() { - CreateComputePass(m_PresampleLightsPass, "app/LightingPasses/PresampleLights.hlsl", {}); - CreateComputePass(m_PresampleEnvironmentMapPass, "app/LightingPasses/PresampleEnvironmentMap.hlsl", {}); + CreateComputePass(m_presampleLightsPass, "app/LightingPasses/Presampling/PresampleLights.hlsl", {}); + CreateComputePass(m_presampleEnvironmentMapPass, "app/LightingPasses/Presampling/PresampleEnvironmentMap.hlsl", {}); } -void LightingPasses::createReGIRPipeline(const rtxdi::ReGIRStaticParameters& regirStaticParams, const std::vector& regirMacros) +void LightingPasses::CreateReGIRPipeline(const rtxdi::ReGIRStaticParameters& regirStaticParams, const std::vector& regirMacros) { if (regirStaticParams.Mode != rtxdi::ReGIRMode::Disabled) { - CreateComputePass(m_PresampleReGIR, "app/LightingPasses/PresampleReGIR.hlsl", regirMacros); + CreateComputePass(m_presampleReGIR, "app/LightingPasses/Presampling/PresampleReGIR.hlsl", regirMacros); } } -void LightingPasses::createReSTIRDIPipelines(const std::vector& regirMacros, bool useRayQuery) +void LightingPasses::CreateReSTIRDIPipelines(const std::vector& regirMacros, bool useRayQuery) { - m_GenerateInitialSamplesPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/DIGenerateInitialSamples.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_TemporalResamplingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/DITemporalResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_SpatialResamplingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/DISpatialResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_ShadeSamplesPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/DIShadeSamples.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_BrdfRayTracingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/BrdfRayTracing.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_ShadeSecondarySurfacesPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/ShadeSecondarySurfaces.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_FusedResamplingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/DIFusedResampling.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_GradientsPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/DIComputeGradients.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); + m_generateInitialSamplesPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/DI/GenerateInitialSamples.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_temporalResamplingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/DI/TemporalResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_spatialResamplingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/DI/SpatialResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_shadeSamplesPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/DI/ShadeSamples.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_brdfRayTracingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/BrdfRayTracing.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_shadeSecondarySurfacesPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/ShadeSecondarySurfaces.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_fusedResamplingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/DI/FusedResampling.hlsl", regirMacros, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_gradientsPass.Init(m_device, *m_shaderFactory, "app/DenoisingPasses/ComputeGradients.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); } -void LightingPasses::createReSTIRGIPipelines(bool useRayQuery) +void LightingPasses::CreateReSTIRGIPipelines(bool useRayQuery) { - m_GITemporalResamplingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/GITemporalResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_GISpatialResamplingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/GISpatialResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_GIFusedResamplingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/GIFusedResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); - m_GIFinalShadingPass.Init(m_Device, *m_ShaderFactory, "app/LightingPasses/GIFinalShading.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_BindingLayout, nullptr, m_BindlessLayout); + m_GITemporalResamplingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/GI/TemporalResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_GISpatialResamplingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/GI/SpatialResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_GIFusedResamplingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/GI/FusedResampling.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); + m_GIFinalShadingPass.Init(m_device, *m_shaderFactory, "app/LightingPasses/GI/FinalShading.hlsl", {}, useRayQuery, RTXDI_SCREEN_SPACE_GROUP_SIZE, m_bindingLayout, nullptr, m_bindlessLayout); } void LightingPasses::CreatePipelines(const rtxdi::ReGIRStaticParameters& regirStaticParams, bool useRayQuery) @@ -334,10 +334,10 @@ void LightingPasses::CreatePipelines(const rtxdi::ReGIRStaticParameters& regirSt GetRegirMacro(regirStaticParams) }; - createPresamplingPipelines(); - createReGIRPipeline(regirStaticParams, regirMacros); - createReSTIRDIPipelines(regirMacros, useRayQuery); - createReSTIRGIPipelines(useRayQuery); + CreatePresamplingPipelines(); + CreateReGIRPipeline(regirStaticParams, regirMacros); + CreateReSTIRDIPipelines(regirMacros, useRayQuery); + CreateReSTIRGIPipelines(useRayQuery); } #if WITH_NRD @@ -353,30 +353,30 @@ static void NrdHitDistanceParamsToFloat4(const nrd::HitDistanceParameters* param void FillReSTIRDIConstants(ReSTIRDI_Parameters& params, const rtxdi::ReSTIRDIContext& restirDIContext, const RTXDI_LightBufferParameters& lightBufferParameters) { - params.reservoirBufferParams = restirDIContext.getReservoirBufferParameters(); - params.bufferIndices = restirDIContext.getBufferIndices(); - params.initialSamplingParams = restirDIContext.getInitialSamplingParameters(); + params.reservoirBufferParams = restirDIContext.GetReservoirBufferParameters(); + params.bufferIndices = restirDIContext.GetBufferIndices(); + params.initialSamplingParams = restirDIContext.GetInitialSamplingParameters(); params.initialSamplingParams.environmentMapImportanceSampling = lightBufferParameters.environmentLightParams.lightPresent; if (!params.initialSamplingParams.environmentMapImportanceSampling) params.initialSamplingParams.numPrimaryEnvironmentSamples = 0; - params.temporalResamplingParams = restirDIContext.getTemporalResamplingParameters(); - params.spatialResamplingParams = restirDIContext.getSpatialResamplingParameters(); - params.shadingParams = restirDIContext.getShadingParameters(); + params.temporalResamplingParams = restirDIContext.GetTemporalResamplingParameters(); + params.spatialResamplingParams = restirDIContext.GetSpatialResamplingParameters(); + params.shadingParams = restirDIContext.GetShadingParameters(); } void FillReGIRConstants(ReGIR_Parameters& params, const rtxdi::ReGIRContext& regirContext) { - auto staticParams = regirContext.getReGIRStaticParameters(); - auto dynamicParams = regirContext.getReGIRDynamicParameters(); - auto gridParams = regirContext.getReGIRGridCalculatedParameters(); - auto onionParams = regirContext.getReGIROnionCalculatedParameters(); + auto staticParams = regirContext.GetReGIRStaticParameters(); + auto dynamicParams = regirContext.GetReGIRDynamicParameters(); + auto gridParams = regirContext.GetReGIRGridCalculatedParameters(); + auto onionParams = regirContext.GetReGIROnionCalculatedParameters(); params.gridParams.cellsX = staticParams.gridParameters.GridSize.x; params.gridParams.cellsY = staticParams.gridParameters.GridSize.y; params.gridParams.cellsZ = staticParams.gridParameters.GridSize.z; params.commonParams.numRegirBuildSamples = dynamicParams.regirNumBuildSamples; - params.commonParams.risBufferOffset = regirContext.getReGIRCellOffset(); + params.commonParams.risBufferOffset = regirContext.GetReGIRCellOffset(); params.commonParams.lightsPerCell = staticParams.LightsPerCell; params.commonParams.centerX = dynamicParams.center.x; params.commonParams.centerY = dynamicParams.center.y; @@ -405,16 +405,16 @@ void FillReGIRConstants(ReGIR_Parameters& params, const rtxdi::ReGIRContext& reg params.onionParams.rings[n] = onionParams.regirOnionRings[n]; } - params.onionParams.cubicRootFactor = regirContext.getReGIROnionCalculatedParameters().regirOnionCubicRootFactor; + params.onionParams.cubicRootFactor = regirContext.GetReGIROnionCalculatedParameters().regirOnionCubicRootFactor; } void FillReSTIRGIConstants(ReSTIRGI_Parameters& constants, const rtxdi::ReSTIRGIContext& restirGIContext) { - constants.reservoirBufferParams = restirGIContext.getReservoirBufferParameters(); - constants.bufferIndices = restirGIContext.getBufferIndices(); - constants.temporalResamplingParams = restirGIContext.getTemporalResamplingParameters(); - constants.spatialResamplingParams = restirGIContext.getSpatialResamplingParameters(); - constants.finalShadingParams = restirGIContext.getFinalShadingParameters(); + constants.reservoirBufferParams = restirGIContext.GetReservoirBufferParameters(); + constants.bufferIndices = restirGIContext.GetBufferIndices(); + constants.temporalResamplingParams = restirGIContext.GetTemporalResamplingParameters(); + constants.spatialResamplingParams = restirGIContext.GetSpatialResamplingParameters(); + constants.finalShadingParams = restirGIContext.GetFinalShadingParameters(); } void FillBRDFPTConstants(BRDFPathTracing_Parameters& constants, const GBufferSettings& gbufferSettings, const LightingPasses::RenderSettings& lightingSettings, const RTXDI_LightBufferParameters& lightBufferParameters) @@ -433,7 +433,7 @@ void LightingPasses::FillResamplingConstants( const RenderSettings& lightingSettings, const rtxdi::ImportanceSamplingContext& isContext) { - const RTXDI_LightBufferParameters& lightBufferParameters = isContext.getLightBufferParameters(); + const RTXDI_LightBufferParameters& lightBufferParameters = isContext.GetLightBufferParameters(); constants.enablePreviousTLAS = lightingSettings.enablePreviousTLAS; constants.denoiserMode = lightingSettings.denoiserMode; @@ -448,22 +448,22 @@ void LightingPasses::FillResamplingConstants( } #endif - constants.lightBufferParams = isContext.getLightBufferParameters(); - constants.localLightsRISBufferSegmentParams = isContext.getLocalLightRISBufferSegmentParams(); - constants.environmentLightRISBufferSegmentParams = isContext.getEnvironmentLightRISBufferSegmentParams(); - constants.runtimeParams = isContext.getReSTIRDIContext().getRuntimeParams(); - FillReSTIRDIConstants(constants.restirDI, isContext.getReSTIRDIContext(), isContext.getLightBufferParameters()); - FillReGIRConstants(constants.regir, isContext.getReGIRContext()); - FillReSTIRGIConstants(constants.restirGI, isContext.getReSTIRGIContext()); + constants.lightBufferParams = isContext.GetLightBufferParameters(); + constants.localLightsRISBufferSegmentParams = isContext.GetLocalLightRISBufferSegmentParams(); + constants.environmentLightRISBufferSegmentParams = isContext.GetEnvironmentLightRISBufferSegmentParams(); + constants.runtimeParams = isContext.GetReSTIRDIContext().GetRuntimeParams(); + FillReSTIRDIConstants(constants.restirDI, isContext.GetReSTIRDIContext(), isContext.GetLightBufferParameters()); + FillReGIRConstants(constants.regir, isContext.GetReGIRContext()); + FillReSTIRGIConstants(constants.restirGI, isContext.GetReSTIRGIContext()); - constants.localLightPdfTextureSize = m_LocalLightPdfTextureSize; + constants.localLightPdfTextureSize = m_localLightPdfTextureSize; if (lightBufferParameters.environmentLightParams.lightPresent) { - constants.environmentPdfTextureSize = m_EnvironmentPdfTextureSize; + constants.environmentPdfTextureSize = m_environmentPdfTextureSize; } - m_CurrentFrameOutputReservoir = isContext.getReSTIRDIContext().getBufferIndices().shadingInputBufferIndex; + m_currentFrameOutputReservoir = isContext.GetReSTIRDIContext().GetBufferIndices().shadingInputBufferIndex; } void LightingPasses::PrepareForLightSampling( @@ -474,50 +474,50 @@ void LightingPasses::PrepareForLightSampling( const RenderSettings& localSettings, bool enableAccumulation) { - rtxdi::ReSTIRDIContext& restirDIContext = isContext.getReSTIRDIContext(); - rtxdi::ReGIRContext& regirContext = isContext.getReGIRContext(); + rtxdi::ReSTIRDIContext& restirDIContext = isContext.GetReSTIRDIContext(); + rtxdi::ReGIRContext& regirContext = isContext.GetReGIRContext(); ResamplingConstants constants = {}; - constants.frameIndex = restirDIContext.getFrameIndex(); + constants.frameIndex = restirDIContext.GetFrameIndex(); view.FillPlanarViewConstants(constants.view); previousView.FillPlanarViewConstants(constants.prevView); FillResamplingConstants(constants, localSettings, isContext); constants.enableAccumulation = enableAccumulation; - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); - auto& lightBufferParams = isContext.getLightBufferParameters(); + auto& lightBufferParams = isContext.GetLightBufferParameters(); - if (isContext.isLocalLightPowerRISEnabled() && + if (isContext.IsLocalLightPowerRISEnabled() && lightBufferParams.localLightBufferRegion.numLights > 0) { dm::int2 presampleDispatchSize = { - dm::div_ceil(isContext.getLocalLightRISBufferSegmentParams().tileSize, RTXDI_PRESAMPLING_GROUP_SIZE), - int(isContext.getLocalLightRISBufferSegmentParams().tileCount) + dm::div_ceil(isContext.GetLocalLightRISBufferSegmentParams().tileSize, RTXDI_PRESAMPLING_GROUP_SIZE), + int(isContext.GetLocalLightRISBufferSegmentParams().tileCount) }; - ExecuteComputePass(commandList, m_PresampleLightsPass, "PresampleLights", presampleDispatchSize, ProfilerSection::PresampleLights); + ExecuteComputePass(commandList, m_presampleLightsPass, "PresampleLights", presampleDispatchSize, ProfilerSection::PresampleLights); } if (lightBufferParams.environmentLightParams.lightPresent) { dm::int2 presampleDispatchSize = { - dm::div_ceil(isContext.getEnvironmentLightRISBufferSegmentParams().tileSize, RTXDI_PRESAMPLING_GROUP_SIZE), - int(isContext.getEnvironmentLightRISBufferSegmentParams().tileCount) + dm::div_ceil(isContext.GetEnvironmentLightRISBufferSegmentParams().tileSize, RTXDI_PRESAMPLING_GROUP_SIZE), + int(isContext.GetEnvironmentLightRISBufferSegmentParams().tileCount) }; - ExecuteComputePass(commandList, m_PresampleEnvironmentMapPass, "PresampleEnvironmentMap", presampleDispatchSize, ProfilerSection::PresampleEnvMap); + ExecuteComputePass(commandList, m_presampleEnvironmentMapPass, "PresampleEnvironmentMap", presampleDispatchSize, ProfilerSection::PresampleEnvMap); } - if (isContext.isReGIREnabled() && + if (isContext.IsReGIREnabled() && lightBufferParams.localLightBufferRegion.numLights > 0) { dm::int2 worldGridDispatchSize = { - dm::div_ceil(regirContext.getReGIRLightSlotCount(), RTXDI_GRID_BUILD_GROUP_SIZE), + dm::div_ceil(regirContext.GetReGIRLightSlotCount(), RTXDI_GRID_BUILD_GROUP_SIZE), 1 }; - ExecuteComputePass(commandList, m_PresampleReGIR, "PresampleReGIR", worldGridDispatchSize, ProfilerSection::PresampleReGIR); + ExecuteComputePass(commandList, m_presampleReGIR, "PresampleReGIR", worldGridDispatchSize, ProfilerSection::PresampleReGIR); } } @@ -532,7 +532,7 @@ void LightingPasses::RenderDirectLighting( view.GetViewExtent().height() }; - if (context.getStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) + if (context.GetStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) dispatchSize.x /= 2; // Run the lighting passes in the necessary sequence: one fused kernel or multiple separate passes. @@ -541,40 +541,40 @@ void LightingPasses::RenderDirectLighting( // because NVRHI misses them, as the binding sets are exactly the same between these passes. // That equality makes NVRHI take a shortcut for performance and it doesn't look at bindings at all. - if (context.getResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::FusedSpatiotemporal) + if (context.GetResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::FusedSpatiotemporal) { - nvrhi::utils::BufferUavBarrier(commandList, m_LightReservoirBuffer); + nvrhi::utils::BufferUavBarrier(commandList, m_lightReservoirBuffer); - ExecuteRayTracingPass(commandList, m_FusedResamplingPass, localSettings.enableRayCounts, "DIFusedResampling", dispatchSize, ProfilerSection::Shading); + ExecuteRayTracingPass(commandList, m_fusedResamplingPass, localSettings.enableRayCounts, "DIFusedResampling", dispatchSize, ProfilerSection::Shading); } else { - ExecuteRayTracingPass(commandList, m_GenerateInitialSamplesPass, localSettings.enableRayCounts, "DIGenerateInitialSamples", dispatchSize, ProfilerSection::InitialSamples); + ExecuteRayTracingPass(commandList, m_generateInitialSamplesPass, localSettings.enableRayCounts, "DIGenerateInitialSamples", dispatchSize, ProfilerSection::InitialSamples); - if (context.getResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::Temporal || context.getResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::TemporalAndSpatial) + if (context.GetResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::Temporal || context.GetResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::TemporalAndSpatial) { - nvrhi::utils::BufferUavBarrier(commandList, m_LightReservoirBuffer); + nvrhi::utils::BufferUavBarrier(commandList, m_lightReservoirBuffer); - ExecuteRayTracingPass(commandList, m_TemporalResamplingPass, localSettings.enableRayCounts, "DITemporalResampling", dispatchSize, ProfilerSection::TemporalResampling); + ExecuteRayTracingPass(commandList, m_temporalResamplingPass, localSettings.enableRayCounts, "DITemporalResampling", dispatchSize, ProfilerSection::TemporalResampling); } - if (context.getResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::Spatial || context.getResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::TemporalAndSpatial) + if (context.GetResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::Spatial || context.GetResamplingMode() == rtxdi::ReSTIRDI_ResamplingMode::TemporalAndSpatial) { - nvrhi::utils::BufferUavBarrier(commandList, m_LightReservoirBuffer); + nvrhi::utils::BufferUavBarrier(commandList, m_lightReservoirBuffer); - ExecuteRayTracingPass(commandList, m_SpatialResamplingPass, localSettings.enableRayCounts, "DISpatialResampling", dispatchSize, ProfilerSection::SpatialResampling); + ExecuteRayTracingPass(commandList, m_spatialResamplingPass, localSettings.enableRayCounts, "DISpatialResampling", dispatchSize, ProfilerSection::SpatialResampling); } - nvrhi::utils::BufferUavBarrier(commandList, m_LightReservoirBuffer); + nvrhi::utils::BufferUavBarrier(commandList, m_lightReservoirBuffer); - ExecuteRayTracingPass(commandList, m_ShadeSamplesPass, localSettings.enableRayCounts, "DIShadeSamples", dispatchSize, ProfilerSection::Shading); + ExecuteRayTracingPass(commandList, m_shadeSamplesPass, localSettings.enableRayCounts, "DIShadeSamples", dispatchSize, ProfilerSection::Shading); } if (localSettings.enableGradients) { - nvrhi::utils::BufferUavBarrier(commandList, m_LightReservoirBuffer); + nvrhi::utils::BufferUavBarrier(commandList, m_lightReservoirBuffer); - ExecuteRayTracingPass(commandList, m_GradientsPass, localSettings.enableRayCounts, "DIGradients", (dispatchSize + RTXDI_GRAD_FACTOR - 1) / RTXDI_GRAD_FACTOR, ProfilerSection::Gradients); + ExecuteRayTracingPass(commandList, m_gradientsPass, localSettings.enableRayCounts, "DIGradients", (dispatchSize + RTXDI_GRAD_FACTOR - 1) / RTXDI_GRAD_FACTOR, ProfilerSection::Gradients); } } @@ -597,10 +597,10 @@ void LightingPasses::RenderBrdfRays( view.FillPlanarViewConstants(constants.view); previousView.FillPlanarViewConstants(constants.prevView); - rtxdi::ReSTIRDIContext& restirDIContext = isContext.getReSTIRDIContext(); - rtxdi::ReSTIRGIContext& restirGIContext = isContext.getReSTIRGIContext(); + rtxdi::ReSTIRDIContext& restirDIContext = isContext.GetReSTIRDIContext(); + rtxdi::ReSTIRGIContext& restirGIContext = isContext.GetReSTIRGIContext(); - constants.frameIndex = restirDIContext.getFrameIndex(); + constants.frameIndex = restirDIContext.GetFrameIndex(); constants.denoiserMode = localSettings.denoiserMode; constants.enableBrdfIndirect = enableIndirect; constants.enableBrdfAdditiveBlend = enableAdditiveBlend; @@ -610,35 +610,35 @@ void LightingPasses::RenderBrdfRays( constants.sceneConstants.environmentScale = environmentLight.radianceScale.x; constants.sceneConstants.environmentRotation = environmentLight.rotation; FillResamplingConstants(constants, localSettings, isContext); - FillBRDFPTConstants(constants.brdfPT, gbufferSettings, localSettings, isContext.getLightBufferParameters()); + FillBRDFPTConstants(constants.brdfPT, gbufferSettings, localSettings, isContext.GetLightBufferParameters()); constants.brdfPT.enableIndirectEmissiveSurfaces = enableEmissiveSurfaces; constants.brdfPT.enableReSTIRGI = enableReSTIRGI; - ReSTIRGI_BufferIndices restirGIBufferIndices = restirGIContext.getBufferIndices(); - m_CurrentFrameGIOutputReservoir = restirGIBufferIndices.finalShadingInputBufferIndex; + ReSTIRGI_BufferIndices restirGIBufferIndices = restirGIContext.GetBufferIndices(); + m_currentFrameGIOutputReservoir = restirGIBufferIndices.finalShadingInputBufferIndex; - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); dm::int2 dispatchSize = { view.GetViewExtent().width(), view.GetViewExtent().height() }; - if (restirDIContext.getStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) + if (restirDIContext.GetStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) dispatchSize.x /= 2; - ExecuteRayTracingPass(commandList, m_BrdfRayTracingPass, localSettings.enableRayCounts, "BrdfRayTracingPass", dispatchSize, ProfilerSection::BrdfRays); + ExecuteRayTracingPass(commandList, m_brdfRayTracingPass, localSettings.enableRayCounts, "BrdfRayTracingPass", dispatchSize, ProfilerSection::BrdfRays); if (enableIndirect) { // Place an explicit UAV barrier between the passes. See the note on barriers in RenderDirectLighting(...) - nvrhi::utils::BufferUavBarrier(commandList, m_SecondarySurfaceBuffer); + nvrhi::utils::BufferUavBarrier(commandList, m_secondarySurfaceBuffer); - ExecuteRayTracingPass(commandList, m_ShadeSecondarySurfacesPass, localSettings.enableRayCounts, "ShadeSecondarySurfaces", dispatchSize, ProfilerSection::ShadeSecondary, nullptr); + ExecuteRayTracingPass(commandList, m_shadeSecondarySurfacesPass, localSettings.enableRayCounts, "ShadeSecondarySurfaces", dispatchSize, ProfilerSection::ShadeSecondary, nullptr); if (enableReSTIRGI) { - rtxdi::ReSTIRGI_ResamplingMode resamplingMode = restirGIContext.getResamplingMode(); + rtxdi::ReSTIRGI_ResamplingMode resamplingMode = restirGIContext.GetResamplingMode(); if (resamplingMode == rtxdi::ReSTIRGI_ResamplingMode::FusedSpatiotemporal) { nvrhi::utils::BufferUavBarrier(commandList, m_GIReservoirBuffer); @@ -673,6 +673,26 @@ void LightingPasses::RenderBrdfRays( void LightingPasses::NextFrame() { - std::swap(m_BindingSet, m_PrevBindingSet); - m_LastFrameOutputReservoir = m_CurrentFrameOutputReservoir; + std::swap(m_bindingSet, m_prevBindingSet); + m_lastFrameOutputReservoir = m_currentFrameOutputReservoir; } + +nvrhi::IBindingLayout* LightingPasses::GetBindingLayout() const +{ + return m_bindingLayout; +} + +nvrhi::IBindingSet* LightingPasses::GetCurrentBindingSet() const +{ + return m_bindingSet; +} + +uint32_t LightingPasses::GetOutputReservoirBufferIndex() const +{ + return m_currentFrameOutputReservoir; +} + +uint32_t LightingPasses::GetGIOutputReservoirBufferIndex() const +{ + return m_currentFrameGIOutputReservoir; +} \ No newline at end of file diff --git a/src/LightingPasses.h b/Samples/FullSample/Source/RenderPasses/LightingPasses.h similarity index 71% rename from src/LightingPasses.h rename to Samples/FullSample/Source/RenderPasses/LightingPasses.h index f4f573f..73c624d 100644 --- a/src/LightingPasses.h +++ b/Samples/FullSample/Source/RenderPasses/LightingPasses.h @@ -11,15 +11,15 @@ #pragma once #include "RayTracingPass.h" -#include "ProfilerSections.h" +#include "../ProfilerSections.h" #include #include #include -#include -#include -#include "../shaders/BRDFPTParameters.h" +#include +#include +#include "../../shaders/BRDFPTParameters.h" namespace donut::engine { @@ -52,62 +52,13 @@ namespace nrd // A 32-bit bool type to directly use from the command line parser. typedef int ibool; -BRDFPathTracing_MaterialOverrideParameters getDefaultBRDFPathTracingMaterialOverrideParams(); -BRDFPathTracing_SecondarySurfaceReSTIRDIParameters getDefaultBRDFPathTracingSecondarySurfaceReSTIRDIParams(); -BRDFPathTracing_Parameters getDefaultBRDFPathTracingParams(); +BRDFPathTracing_MaterialOverrideParameters GetDefaultBRDFPathTracingMaterialOverrideParams(); +BRDFPathTracing_SecondarySurfaceReSTIRDIParameters GetDefaultBRDFPathTracingSecondarySurfaceReSTIRDIParams(); +BRDFPathTracing_Parameters GetDefaultBRDFPathTracingParams(); class LightingPasses { -private: - struct ComputePass { - nvrhi::ShaderHandle Shader; - nvrhi::ComputePipelineHandle Pipeline; - }; - - nvrhi::DeviceHandle m_Device; - - ComputePass m_PresampleLightsPass; - ComputePass m_PresampleEnvironmentMapPass; - ComputePass m_PresampleReGIR; - RayTracingPass m_GenerateInitialSamplesPass; - RayTracingPass m_TemporalResamplingPass; - RayTracingPass m_SpatialResamplingPass; - RayTracingPass m_ShadeSamplesPass; - RayTracingPass m_BrdfRayTracingPass; - RayTracingPass m_ShadeSecondarySurfacesPass; - RayTracingPass m_FusedResamplingPass; - RayTracingPass m_GradientsPass; - RayTracingPass m_GITemporalResamplingPass; - RayTracingPass m_GISpatialResamplingPass; - RayTracingPass m_GIFusedResamplingPass; - RayTracingPass m_GIFinalShadingPass; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingSetHandle m_PrevBindingSet; - nvrhi::BufferHandle m_ConstantBuffer; - nvrhi::BufferHandle m_LightReservoirBuffer; - nvrhi::BufferHandle m_SecondarySurfaceBuffer; - nvrhi::BufferHandle m_GIReservoirBuffer; - - dm::uint2 m_EnvironmentPdfTextureSize; - dm::uint2 m_LocalLightPdfTextureSize; - - uint32_t m_LastFrameOutputReservoir = 0; - uint32_t m_CurrentFrameOutputReservoir = 0; - uint32_t m_CurrentFrameGIOutputReservoir = 0; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - std::shared_ptr m_Profiler; - - void CreateComputePass(ComputePass& pass, const char* shaderName, const std::vector& macros); - void ExecuteComputePass(nvrhi::ICommandList* commandList, ComputePass& pass, const char* passName, dm::int2 dispatchSize, ProfilerSection::Enum profilerSection); - void ExecuteRayTracingPass(nvrhi::ICommandList* commandList, RayTracingPass& pass, bool enableRayCounts, const char* passName, dm::int2 dispatchSize, ProfilerSection::Enum profilerSection, nvrhi::IBindingSet* extraBindingSet = nullptr); - public: - struct RenderSettings { uint32_t denoiserMode = 0; @@ -123,7 +74,7 @@ class LightingPasses float gradientSensitivity = 8.f; float confidenceHistoryLength = 0.75f; - BRDFPathTracing_Parameters brdfptParams = getDefaultBRDFPathTracingParams(); + BRDFPathTracing_Parameters brdfptParams = GetDefaultBRDFPathTracingParams(); #if WITH_NRD const nrd::HitDistanceParameters* reblurDiffHitDistanceParams = nullptr; @@ -178,10 +129,10 @@ class LightingPasses void NextFrame(); - [[nodiscard]] nvrhi::IBindingLayout* GetBindingLayout() const { return m_BindingLayout; } - [[nodiscard]] nvrhi::IBindingSet* GetCurrentBindingSet() const { return m_BindingSet; } - [[nodiscard]] uint32_t GetOutputReservoirBufferIndex() const { return m_CurrentFrameOutputReservoir; } - [[nodiscard]] uint32_t GetGIOutputReservoirBufferIndex() const { return m_CurrentFrameGIOutputReservoir; } + [[nodiscard]] nvrhi::IBindingLayout* GetBindingLayout() const; + [[nodiscard]] nvrhi::IBindingSet* GetCurrentBindingSet() const; + [[nodiscard]] uint32_t GetOutputReservoirBufferIndex() const; + [[nodiscard]] uint32_t GetGIOutputReservoirBufferIndex() const; static donut::engine::ShaderMacro GetRegirMacro(const rtxdi::ReGIRStaticParameters& regirStaticParams); @@ -191,8 +142,56 @@ class LightingPasses const RenderSettings& lightingSettings, const rtxdi::ImportanceSamplingContext& isContext); - void createPresamplingPipelines(); - void createReGIRPipeline(const rtxdi::ReGIRStaticParameters& regirStaticParams, const std::vector& regirMacros); - void createReSTIRDIPipelines(const std::vector& regirMacros, bool useRayQuery); - void createReSTIRGIPipelines(bool useRayQuery); + void CreatePresamplingPipelines(); + void CreateReGIRPipeline(const rtxdi::ReGIRStaticParameters& regirStaticParams, const std::vector& regirMacros); + void CreateReSTIRDIPipelines(const std::vector& regirMacros, bool useRayQuery); + void CreateReSTIRGIPipelines(bool useRayQuery); + + struct ComputePass + { + nvrhi::ShaderHandle Shader; + nvrhi::ComputePipelineHandle Pipeline; + }; + + void CreateComputePass(ComputePass& pass, const char* shaderName, const std::vector& macros); + void ExecuteComputePass(nvrhi::ICommandList* commandList, ComputePass& pass, const char* passName, dm::int2 dispatchSize, ProfilerSection::Enum profilerSection); + void ExecuteRayTracingPass(nvrhi::ICommandList* commandList, RayTracingPass& pass, bool enableRayCounts, const char* passName, dm::int2 dispatchSize, ProfilerSection::Enum profilerSection, nvrhi::IBindingSet* extraBindingSet = nullptr); + + nvrhi::DeviceHandle m_device; + + ComputePass m_presampleLightsPass; + ComputePass m_presampleEnvironmentMapPass; + ComputePass m_presampleReGIR; + RayTracingPass m_generateInitialSamplesPass; + RayTracingPass m_temporalResamplingPass; + RayTracingPass m_spatialResamplingPass; + RayTracingPass m_shadeSamplesPass; + RayTracingPass m_brdfRayTracingPass; + RayTracingPass m_shadeSecondarySurfacesPass; + RayTracingPass m_fusedResamplingPass; + RayTracingPass m_gradientsPass; + RayTracingPass m_GITemporalResamplingPass; + RayTracingPass m_GISpatialResamplingPass; + RayTracingPass m_GIFusedResamplingPass; + RayTracingPass m_GIFinalShadingPass; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingSetHandle m_prevBindingSet; + nvrhi::BufferHandle m_constantBuffer; + nvrhi::BufferHandle m_lightReservoirBuffer; + nvrhi::BufferHandle m_secondarySurfaceBuffer; + nvrhi::BufferHandle m_GIReservoirBuffer; + + dm::uint2 m_environmentPdfTextureSize; + dm::uint2 m_localLightPdfTextureSize; + + uint32_t m_lastFrameOutputReservoir = 0; + uint32_t m_currentFrameOutputReservoir = 0; + uint32_t m_currentFrameGIOutputReservoir = 0; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; + std::shared_ptr m_profiler; }; diff --git a/src/PrepareLightsPass.cpp b/Samples/FullSample/Source/RenderPasses/PrepareLightsPass.cpp similarity index 87% rename from src/PrepareLightsPass.cpp rename to Samples/FullSample/Source/RenderPasses/PrepareLightsPass.cpp index 30e7879..a733b63 100644 --- a/src/PrepareLightsPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/PrepareLightsPass.cpp @@ -9,20 +9,20 @@ **************************************************************************/ #include "PrepareLightsPass.h" -#include "RtxdiResources.h" -#include "SampleScene.h" +#include "../RtxdiResources.h" +#include "../SampleScene.h" #include #include #include #include -#include +#include #include #include using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -33,11 +33,11 @@ PrepareLightsPass::PrepareLightsPass( std::shared_ptr commonPasses, std::shared_ptr scene, nvrhi::IBindingLayout* bindlessLayout) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) { nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -54,19 +54,19 @@ PrepareLightsPass::PrepareLightsPass( nvrhi::BindingLayoutItem::Sampler(0) }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); } void PrepareLightsPass::CreatePipeline() { donut::log::debug("Initializing PrepareLightsPass..."); - m_ComputeShader = m_ShaderFactory->CreateShader("app/PrepareLights.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/PrepareLights.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void PrepareLightsPass::CreateBindingSet(RtxdiResources& resources) @@ -79,19 +79,19 @@ void PrepareLightsPass::CreateBindingSet(RtxdiResources& resources) nvrhi::BindingSetItem::Texture_UAV(2, resources.LocalLightPdfTexture), nvrhi::BindingSetItem::StructuredBuffer_SRV(0, resources.TaskBuffer), nvrhi::BindingSetItem::StructuredBuffer_SRV(1, resources.PrimitiveLightBuffer), - nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(4, m_Scene->GetMaterialBuffer()), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_AnisotropicWrapSampler) + nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(4, m_scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_AnisotropicWrapSampler) }; - m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); - m_TaskBuffer = resources.TaskBuffer; - m_PrimitiveLightBuffer = resources.PrimitiveLightBuffer; - m_LightIndexMappingBuffer = resources.LightIndexMappingBuffer; - m_GeometryInstanceToLightBuffer = resources.GeometryInstanceToLightBuffer; - m_LocalLightPdfTexture = resources.LocalLightPdfTexture; - m_MaxLightsInBuffer = uint32_t(resources.LightDataBuffer->getDesc().byteSize / (sizeof(PolymorphicLightInfo) * 2)); + m_bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); + m_taskBuffer = resources.TaskBuffer; + m_primitiveLightBuffer = resources.PrimitiveLightBuffer; + m_lightIndexMappingBuffer = resources.LightIndexMappingBuffer; + m_geometryInstanceToLightBuffer = resources.GeometryInstanceToLightBuffer; + m_localLightPdfTexture = resources.LocalLightPdfTexture; + m_maxLightsInBuffer = uint32_t(resources.LightDataBuffer->getDesc().byteSize / (sizeof(PolymorphicLightInfo) * 2)); } void PrepareLightsPass::CountLightsInScene(uint32_t& numEmissiveMeshes, uint32_t& numEmissiveTriangles) @@ -99,7 +99,7 @@ void PrepareLightsPass::CountLightsInScene(uint32_t& numEmissiveMeshes, uint32_t numEmissiveMeshes = 0; numEmissiveTriangles = 0; - const auto& instances = m_Scene->GetSceneGraph()->GetMeshInstances(); + const auto& instances = m_scene->GetSceneGraph()->GetMeshInstances(); for (const auto& instance : instances) { for (const auto& geometry : instance->GetMesh()->geometries) @@ -346,16 +346,16 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( bool enableImportanceSampledEnvironmentLight) { RTXDI_LightBufferParameters outLightBufferParams = {}; - const rtxdi::ReSTIRDIStaticParameters& contextParameters = context.getStaticParameters(); + const rtxdi::ReSTIRDIStaticParameters& contextParameters = context.GetStaticParameters(); commandList->beginMarker("PrepareLights"); std::vector tasks; std::vector primitiveLightInfos; uint32_t lightBufferOffset = 0; - std::vector geometryInstanceToLight(m_Scene->GetSceneGraph()->GetGeometryInstancesCount(), RTXDI_INVALID_LIGHT_INDEX); + std::vector geometryInstanceToLight(m_scene->GetSceneGraph()->GetGeometryInstancesCount(), RTXDI_INVALID_LIGHT_INDEX); - const auto& instances = m_Scene->GetSceneGraph()->GetMeshInstances(); + const auto& instances = m_scene->GetSceneGraph()->GetMeshInstances(); for (const auto& instance : instances) { const auto& mesh = instance->GetMesh(); @@ -374,14 +374,14 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( if (!any(geometry->material->emissiveColor != 0.f) || geometry->material->emissiveIntensity <= 0.f) { // remove the info about this instance, just in case it was emissive and now it's not - m_InstanceLightBufferOffsets.erase(instanceHash); + m_instanceLightBufferOffsets.erase(instanceHash); continue; } geometryInstanceToLight[firstGeometryInstanceIndex + geometryIndex] = lightBufferOffset; // find the previous offset of this instance in the light buffer - auto pOffset = m_InstanceLightBufferOffsets.find(instanceHash); + auto pOffset = m_instanceLightBufferOffsets.find(instanceHash); assert(geometryIndex < 0xfff); @@ -389,10 +389,10 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( task.instanceAndGeometryIndex = (instance->GetInstanceIndex() << 12) | uint32_t(geometryIndex & 0xfff); task.lightBufferOffset = lightBufferOffset; task.triangleCount = geometry->numIndices / 3; - task.previousLightBufferOffset = (pOffset != m_InstanceLightBufferOffsets.end()) ? int(pOffset->second) : -1; + task.previousLightBufferOffset = (pOffset != m_instanceLightBufferOffsets.end()) ? int(pOffset->second) : -1; // record the current offset of this instance for use on the next frame - m_InstanceLightBufferOffsets[instanceHash] = lightBufferOffset; + m_instanceLightBufferOffsets[instanceHash] = lightBufferOffset; lightBufferOffset += task.triangleCount; @@ -400,7 +400,7 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( } } - commandList->writeBuffer(m_GeometryInstanceToLightBuffer, geometryInstanceToLight.data(), geometryInstanceToLight.size() * sizeof(uint32_t)); + commandList->writeBuffer(m_geometryInstanceToLightBuffer, geometryInstanceToLight.data(), geometryInstanceToLight.size() * sizeof(uint32_t)); outLightBufferParams.localLightBufferRegion.firstLightIndex = 0; outLightBufferParams.localLightBufferRegion.numLights = lightBufferOffset; @@ -421,16 +421,16 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( continue; // find the previous offset of this instance in the light buffer - auto pOffset = m_PrimitiveLightBufferOffsets.find(pLight.get()); + auto pOffset = m_primitiveLightBufferOffsets.find(pLight.get()); PrepareLightsTask task; task.instanceAndGeometryIndex = TASK_PRIMITIVE_LIGHT_BIT | uint32_t(primitiveLightInfos.size()); task.lightBufferOffset = lightBufferOffset; task.triangleCount = 1; // technically zero, but we need to allocate 1 thread in the grid to process this light - task.previousLightBufferOffset = (pOffset != m_PrimitiveLightBufferOffsets.end()) ? pOffset->second : -1; + task.previousLightBufferOffset = (pOffset != m_primitiveLightBufferOffsets.end()) ? pOffset->second : -1; // record the current offset of this instance for use on the next frame - m_PrimitiveLightBufferOffsets[pLight.get()] = lightBufferOffset; + m_primitiveLightBufferOffsets[pLight.get()] = lightBufferOffset; lightBufferOffset += task.triangleCount; @@ -453,30 +453,30 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( outLightBufferParams.environmentLightParams.lightIndex = outLightBufferParams.infiniteLightBufferRegion.firstLightIndex + outLightBufferParams.infiniteLightBufferRegion.numLights; outLightBufferParams.environmentLightParams.lightPresent = numImportanceSampledEnvironmentLights; - commandList->writeBuffer(m_TaskBuffer, tasks.data(), tasks.size() * sizeof(PrepareLightsTask)); + commandList->writeBuffer(m_taskBuffer, tasks.data(), tasks.size() * sizeof(PrepareLightsTask)); if (!primitiveLightInfos.empty()) { - commandList->writeBuffer(m_PrimitiveLightBuffer, primitiveLightInfos.data(), primitiveLightInfos.size() * sizeof(PolymorphicLightInfo)); + commandList->writeBuffer(m_primitiveLightBuffer, primitiveLightInfos.data(), primitiveLightInfos.size() * sizeof(PolymorphicLightInfo)); } // clear the mapping buffer - value of 0 means all mappings are invalid - commandList->clearBufferUInt(m_LightIndexMappingBuffer, 0); + commandList->clearBufferUInt(m_lightIndexMappingBuffer, 0); // Clear the PDF texture mip 0 - not all of it might be written by this shader - commandList->clearTextureFloat(m_LocalLightPdfTexture, + commandList->clearTextureFloat(m_localLightPdfTexture, nvrhi::TextureSubresourceSet(0, 1, 0, 1), nvrhi::Color(0.f)); nvrhi::ComputeState state; - state.pipeline = m_ComputePipeline; - state.bindings = { m_BindingSet, m_Scene->GetDescriptorTable() }; + state.pipeline = m_computePipeline; + state.bindings = { m_bindingSet, m_scene->GetDescriptorTable() }; commandList->setComputeState(state); PrepareLightsConstants constants; constants.numTasks = uint32_t(tasks.size()); - constants.currentFrameLightOffset = m_MaxLightsInBuffer * m_OddFrame; - constants.previousFrameLightOffset = m_MaxLightsInBuffer * !m_OddFrame; + constants.currentFrameLightOffset = m_maxLightsInBuffer * m_oddFrame; + constants.previousFrameLightOffset = m_maxLightsInBuffer * !m_oddFrame; commandList->setPushConstants(&constants, sizeof(constants)); commandList->dispatch(dm::div_ceil(lightBufferOffset, 256)); @@ -487,6 +487,6 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process( outLightBufferParams.infiniteLightBufferRegion.firstLightIndex += constants.currentFrameLightOffset; outLightBufferParams.environmentLightParams.lightIndex += constants.currentFrameLightOffset; - m_OddFrame = !m_OddFrame; + m_oddFrame = !m_oddFrame; return outLightBufferParams; } diff --git a/src/PrepareLightsPass.h b/Samples/FullSample/Source/RenderPasses/PrepareLightsPass.h similarity index 66% rename from src/PrepareLightsPass.h rename to Samples/FullSample/Source/RenderPasses/PrepareLightsPass.h index e021be9..8b6b97d 100644 --- a/src/PrepareLightsPass.h +++ b/Samples/FullSample/Source/RenderPasses/PrepareLightsPass.h @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -29,31 +29,6 @@ class RtxdiResources; class PrepareLightsPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingLayoutHandle m_BindlessLayout; - - nvrhi::BufferHandle m_TaskBuffer; - nvrhi::BufferHandle m_PrimitiveLightBuffer; - nvrhi::BufferHandle m_LightIndexMappingBuffer; - nvrhi::BufferHandle m_GeometryInstanceToLightBuffer; - nvrhi::TextureHandle m_LocalLightPdfTexture; - - uint32_t m_MaxLightsInBuffer; - bool m_OddFrame = false; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - - std::unordered_map m_InstanceLightBufferOffsets; // hash(instance*, geometryIndex) -> bufferOffset - std::unordered_map m_PrimitiveLightBufferOffsets; - public: PrepareLightsPass( nvrhi::IDevice* device, @@ -71,4 +46,29 @@ class PrepareLightsPass const rtxdi::ReSTIRDIContext& context, const std::vector>& sceneLights, bool enableImportanceSampledEnvironmentLight); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingLayoutHandle m_bindlessLayout; + + nvrhi::BufferHandle m_taskBuffer; + nvrhi::BufferHandle m_primitiveLightBuffer; + nvrhi::BufferHandle m_lightIndexMappingBuffer; + nvrhi::BufferHandle m_geometryInstanceToLightBuffer; + nvrhi::TextureHandle m_localLightPdfTexture; + + uint32_t m_maxLightsInBuffer; + bool m_oddFrame = false; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; + + std::unordered_map m_instanceLightBufferOffsets; // hash(instance*, geometryIndex) -> bufferOffset + std::unordered_map m_primitiveLightBufferOffsets; }; diff --git a/src/RayTracingPass.cpp b/Samples/FullSample/Source/RenderPasses/RayTracingPass.cpp similarity index 100% rename from src/RayTracingPass.cpp rename to Samples/FullSample/Source/RenderPasses/RayTracingPass.cpp diff --git a/src/RayTracingPass.h b/Samples/FullSample/Source/RenderPasses/RayTracingPass.h similarity index 100% rename from src/RayTracingPass.h rename to Samples/FullSample/Source/RenderPasses/RayTracingPass.h diff --git a/src/RenderEnvironmentMapPass.cpp b/Samples/FullSample/Source/RenderPasses/RenderEnvironmentMapPass.cpp similarity index 76% rename from src/RenderEnvironmentMapPass.cpp rename to Samples/FullSample/Source/RenderPasses/RenderEnvironmentMapPass.cpp index 5d5a82f..35dcd9b 100644 --- a/src/RenderEnvironmentMapPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/RenderEnvironmentMapPass.cpp @@ -21,14 +21,14 @@ #include "donut/engine/SceneTypes.h" using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" RenderEnvironmentMapPass::RenderEnvironmentMapPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory, std::shared_ptr descriptorTable, uint32_t textureWidth) - : m_DescriptorTable(std::move(descriptorTable)) + : m_descriptorTable(std::move(descriptorTable)) { donut::log::debug("Initializing RenderEnvironmentMapPass..."); @@ -41,34 +41,34 @@ RenderEnvironmentMapPass::RenderEnvironmentMapPass( destDesc.initialState = nvrhi::ResourceStates::ShaderResource; destDesc.keepInitialState = true; destDesc.format = nvrhi::Format::RGBA16_FLOAT; - m_DestinationTexture = device->createTexture(destDesc); + m_destinationTexture = device->createTexture(destDesc); nvrhi::BindingSetDesc bindingSetDesc; bindingSetDesc.bindings = { nvrhi::BindingSetItem::PushConstants(0, sizeof(RenderEnvironmentMapConstants)), - nvrhi::BindingSetItem::Texture_UAV(0, m_DestinationTexture) + nvrhi::BindingSetItem::Texture_UAV(0, m_destinationTexture) }; nvrhi::BindingLayoutHandle bindingLayout; nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::Compute, 0, - bindingSetDesc, bindingLayout, m_BindingSet); + bindingSetDesc, bindingLayout, m_bindingSet); nvrhi::ShaderHandle shader = shaderFactory->CreateShader("app/RenderEnvironmentMap.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; pipelineDesc.bindingLayouts = { bindingLayout }; pipelineDesc.CS = shader; - m_Pipeline = device->createComputePipeline(pipelineDesc); + m_pipeline = device->createComputePipeline(pipelineDesc); - m_DestinationTextureIndex = m_DescriptorTable->CreateDescriptor(nvrhi::BindingSetItem::Texture_SRV(0, m_DestinationTexture)); + m_destinationTextureIndex = m_descriptorTable->CreateDescriptor(nvrhi::BindingSetItem::Texture_SRV(0, m_destinationTexture)); } RenderEnvironmentMapPass::~RenderEnvironmentMapPass() { - if (m_DestinationTextureIndex >= 0) + if (m_destinationTextureIndex >= 0) { - m_DescriptorTable->ReleaseDescriptor(m_DestinationTextureIndex); - m_DestinationTextureIndex = -1; + m_descriptorTable->ReleaseDescriptor(m_destinationTextureIndex); + m_destinationTextureIndex = -1; } } @@ -76,11 +76,11 @@ void RenderEnvironmentMapPass::Render(nvrhi::ICommandList* commandList, const do { commandList->beginMarker("RenderEnvironmentMap"); - const auto& destDesc = m_DestinationTexture->getDesc(); + const auto& destDesc = m_destinationTexture->getDesc(); nvrhi::ComputeState state; - state.pipeline = m_Pipeline; - state.bindings = { m_BindingSet }; + state.pipeline = m_pipeline; + state.bindings = { m_bindingSet }; commandList->setComputeState(state); RenderEnvironmentMapConstants constants{}; @@ -92,3 +92,13 @@ void RenderEnvironmentMapPass::Render(nvrhi::ICommandList* commandList, const do commandList->endMarker(); } + +nvrhi::ITexture* RenderEnvironmentMapPass::GetTexture() const +{ + return m_destinationTexture; +} + +int RenderEnvironmentMapPass::GetTextureIndex() const +{ + return m_destinationTextureIndex; +} diff --git a/src/RenderEnvironmentMapPass.h b/Samples/FullSample/Source/RenderPasses/RenderEnvironmentMapPass.h similarity index 77% rename from src/RenderEnvironmentMapPass.h rename to Samples/FullSample/Source/RenderPasses/RenderEnvironmentMapPass.h index f423e77..86d8c8f 100644 --- a/src/RenderEnvironmentMapPass.h +++ b/Samples/FullSample/Source/RenderPasses/RenderEnvironmentMapPass.h @@ -28,16 +28,7 @@ namespace donut::render class RenderEnvironmentMapPass { -private: - nvrhi::ComputePipelineHandle m_Pipeline; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::TextureHandle m_DestinationTexture; - - std::shared_ptr m_DescriptorTable; - int m_DestinationTextureIndex = -1; - public: - RenderEnvironmentMapPass( nvrhi::IDevice* device, std::shared_ptr shaderFactory, @@ -48,6 +39,14 @@ class RenderEnvironmentMapPass void Render(nvrhi::ICommandList* commandList, const donut::engine::DirectionalLight& light, const donut::render::SkyParameters& params); - nvrhi::ITexture* GetTexture() const { return m_DestinationTexture; } - int GetTextureIndex() const { return m_DestinationTextureIndex; } + nvrhi::ITexture* GetTexture() const; + int GetTextureIndex() const; + +private: + nvrhi::ComputePipelineHandle m_pipeline; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::TextureHandle m_destinationTexture; + + std::shared_ptr m_descriptorTable; + int m_destinationTextureIndex = -1; }; diff --git a/src/VisualizationPass.cpp b/Samples/FullSample/Source/RenderPasses/VisualizationPass.cpp similarity index 75% rename from src/VisualizationPass.cpp rename to Samples/FullSample/Source/RenderPasses/VisualizationPass.cpp index bf27806..13c8900 100644 --- a/src/VisualizationPass.cpp +++ b/Samples/FullSample/Source/RenderPasses/VisualizationPass.cpp @@ -14,13 +14,13 @@ #include #include #include -#include +#include -#include "RenderTargets.h" -#include "RtxdiResources.h" +#include "../RenderTargets.h" +#include "../RtxdiResources.h" using namespace donut::math; -#include "../shaders/ShaderParameters.h" +#include "../../shaders/ShaderParameters.h" using namespace donut::engine; @@ -29,15 +29,15 @@ VisualizationPass::VisualizationPass(nvrhi::IDevice* device, ShaderFactory& shaderFactory, RenderTargets& renderTargets, RtxdiResources& rtxdiResources) - : m_Device(device) + : m_device(device) { - m_VertexShader = commonPasses.m_FullscreenVS; - m_HdrPixelShader = shaderFactory.CreateShader("app/VisualizeHdrSignals.hlsl", "main", nullptr, nvrhi::ShaderType::Pixel); - m_ConfidencePixelShader = shaderFactory.CreateShader("app/VisualizeConfidence.hlsl", "main", nullptr, nvrhi::ShaderType::Pixel); + m_vertexShader = commonPasses.m_FullscreenVS; + m_hdrPixelShader = shaderFactory.CreateShader("app/VisualizeHdrSignals.hlsl", "main", nullptr, nvrhi::ShaderType::Pixel); + m_confidencePixelShader = shaderFactory.CreateShader("app/VisualizeConfidence.hlsl", "main", nullptr, nvrhi::ShaderType::Pixel); auto constantBufferDesc = nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(VisualizationConstants), "VisualizationConstants", 16); - m_ConstantBuffer = device->createBuffer(constantBufferDesc); + m_constantBuffer = device->createBuffer(constantBufferDesc); auto bindingDesc = nvrhi::BindingSetDesc() .addItem(nvrhi::BindingSetItem::Texture_SRV(0, renderTargets.HdrColor)) @@ -50,9 +50,9 @@ VisualizationPass::VisualizationPass(nvrhi::IDevice* device, .addItem(nvrhi::BindingSetItem::Texture_SRV(7, renderTargets.Gradients)) .addItem(nvrhi::BindingSetItem::StructuredBuffer_SRV(8, rtxdiResources.LightReservoirBuffer)) .addItem(nvrhi::BindingSetItem::StructuredBuffer_SRV(9, rtxdiResources.GIReservoirBuffer)) - .addItem(nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer)); + .addItem(nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer)); - nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::AllGraphics, 0, bindingDesc, m_HdrBindingLayout, m_HdrBindingSet); + nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::AllGraphics, 0, bindingDesc, m_hdrBindingLayout, m_hdrBindingSet); for (int currentFrame = 0; currentFrame <= 1; currentFrame++) { @@ -60,15 +60,15 @@ VisualizationPass::VisualizationPass(nvrhi::IDevice* device, bindingDesc .addItem(nvrhi::BindingSetItem::Texture_SRV(0, currentFrame ? renderTargets.DiffuseConfidence : renderTargets.PrevDiffuseConfidence)) .addItem(nvrhi::BindingSetItem::Texture_SRV(1, currentFrame ? renderTargets.SpecularConfidence : renderTargets.PrevSpecularConfidence)) - .addItem(nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer)); + .addItem(nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer)); nvrhi::BindingSetHandle bindingSet; - nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::AllGraphics, 0, bindingDesc, m_ConfidenceBindingLayout, bindingSet); + nvrhi::utils::CreateBindingSetAndLayout(device, nvrhi::ShaderType::AllGraphics, 0, bindingDesc, m_confidenceBindingLayout, bindingSet); if (currentFrame) - m_ConfidenceBindingSet = bindingSet; + m_confidenceBindingSet = bindingSet; else - m_ConfidenceBindingSetPrev = bindingSet; + m_confidenceBindingSetPrev = bindingSet; } } @@ -82,12 +82,12 @@ void VisualizationPass::Render( uint32_t visualizationMode, bool enableAccumulation) { - if (m_HdrPipeline == nullptr || m_HdrPipeline->getFramebufferInfo() != framebuffer->getFramebufferInfo()) + if (m_hdrPipeline == nullptr || m_hdrPipeline->getFramebufferInfo() != framebuffer->getFramebufferInfo()) { auto pipelineDesc = nvrhi::GraphicsPipelineDesc() - .setVertexShader(m_VertexShader) - .setPixelShader(m_HdrPixelShader) - .addBindingLayout(m_HdrBindingLayout) + .setVertexShader(m_vertexShader) + .setPixelShader(m_hdrPixelShader) + .addBindingLayout(m_hdrBindingLayout) .setPrimType(nvrhi::PrimitiveType::TriangleStrip) .setRenderState(nvrhi::RenderState() .setDepthStencilState(nvrhi::DepthStencilState().disableDepthTest().disableStencil()) @@ -95,13 +95,13 @@ void VisualizationPass::Render( .setBlendState(nvrhi::BlendState().setRenderTarget(0, nvrhi::utils::CreateAddBlendState(nvrhi::BlendFactor::One, nvrhi::BlendFactor::InvSrcAlpha)))); - m_HdrPipeline = m_Device->createGraphicsPipeline(pipelineDesc, framebuffer); + m_hdrPipeline = m_device->createGraphicsPipeline(pipelineDesc, framebuffer); - pipelineDesc.setPixelShader(m_ConfidencePixelShader); + pipelineDesc.setPixelShader(m_confidencePixelShader); pipelineDesc.bindingLayouts.resize(0); - pipelineDesc.addBindingLayout(m_ConfidenceBindingLayout); + pipelineDesc.addBindingLayout(m_confidenceBindingLayout); - m_ConfidencePipeline = m_Device->createGraphicsPipeline(pipelineDesc, framebuffer); + m_confidencePipeline = m_device->createGraphicsPipeline(pipelineDesc, framebuffer); } bool confidence = @@ -109,8 +109,8 @@ void VisualizationPass::Render( (visualizationMode == VIS_MODE_SPECULAR_CONFIDENCE); auto state = nvrhi::GraphicsState() - .setPipeline(confidence ? m_ConfidencePipeline : m_HdrPipeline) - .addBindingSet(confidence ? m_ConfidenceBindingSet : m_HdrBindingSet) + .setPipeline(confidence ? m_confidencePipeline : m_hdrPipeline) + .addBindingSet(confidence ? m_confidenceBindingSet : m_hdrBindingSet) .setFramebuffer(framebuffer) .setViewport(upscaledView.GetViewportState()); @@ -121,12 +121,12 @@ void VisualizationPass::Render( const auto& upscaledViewport = upscaledView.GetViewportState().viewports[0]; constants.resolutionScale.x = renderViewport.width() / upscaledViewport.width(); constants.resolutionScale.y = renderViewport.height() / upscaledViewport.height(); - constants.restirDIReservoirBufferParams = isContext.getReSTIRDIContext().getReservoirBufferParameters(); - constants.restirGIReservoirBufferParams = isContext.getReSTIRGIContext().getReservoirBufferParameters(); + constants.restirDIReservoirBufferParams = isContext.GetReSTIRDIContext().GetReservoirBufferParameters(); + constants.restirGIReservoirBufferParams = isContext.GetReSTIRGIContext().GetReservoirBufferParameters(); constants.visualizationMode = visualizationMode; constants.inputBufferIndex = inputBufferIndex; constants.enableAccumulation = enableAccumulation; - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); commandList->setGraphicsState(state); commandList->draw(nvrhi::DrawArguments().setVertexCount(4)); @@ -134,5 +134,5 @@ void VisualizationPass::Render( void VisualizationPass::NextFrame() { - std::swap(m_ConfidenceBindingSet, m_ConfidenceBindingSetPrev); + std::swap(m_confidenceBindingSet, m_confidenceBindingSetPrev); } diff --git a/src/VisualizationPass.h b/Samples/FullSample/Source/RenderPasses/VisualizationPass.h similarity index 72% rename from src/VisualizationPass.h rename to Samples/FullSample/Source/RenderPasses/VisualizationPass.h index 6dce5ba..0416304 100644 --- a/src/VisualizationPass.h +++ b/Samples/FullSample/Source/RenderPasses/VisualizationPass.h @@ -32,24 +32,7 @@ class RtxdiResources; class VisualizationPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::BindingLayoutHandle m_HdrBindingLayout; - nvrhi::BindingLayoutHandle m_ConfidenceBindingLayout; - nvrhi::BindingSetHandle m_HdrBindingSet; - nvrhi::BindingSetHandle m_ConfidenceBindingSet; - nvrhi::BindingSetHandle m_ConfidenceBindingSetPrev; - nvrhi::ShaderHandle m_VertexShader; - nvrhi::ShaderHandle m_HdrPixelShader; - nvrhi::ShaderHandle m_ConfidencePixelShader; - nvrhi::GraphicsPipelineHandle m_HdrPipeline; - nvrhi::GraphicsPipelineHandle m_ConfidencePipeline; - - nvrhi::BufferHandle m_ConstantBuffer; - public: - VisualizationPass( nvrhi::IDevice* device, donut::engine::CommonRenderPasses& commonPasses, @@ -68,4 +51,20 @@ class VisualizationPass bool enableAccumulation); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::BindingLayoutHandle m_hdrBindingLayout; + nvrhi::BindingLayoutHandle m_confidenceBindingLayout; + nvrhi::BindingSetHandle m_hdrBindingSet; + nvrhi::BindingSetHandle m_confidenceBindingSet; + nvrhi::BindingSetHandle m_confidenceBindingSetPrev; + nvrhi::ShaderHandle m_vertexShader; + nvrhi::ShaderHandle m_hdrPixelShader; + nvrhi::ShaderHandle m_confidencePixelShader; + nvrhi::GraphicsPipelineHandle m_hdrPipeline; + nvrhi::GraphicsPipelineHandle m_confidencePipeline; + + nvrhi::BufferHandle m_constantBuffer; }; diff --git a/src/RenderTargets.cpp b/Samples/FullSample/Source/RenderTargets.cpp similarity index 99% rename from src/RenderTargets.cpp rename to Samples/FullSample/Source/RenderTargets.cpp index 6d4df8a..b73036c 100644 --- a/src/RenderTargets.cpp +++ b/Samples/FullSample/Source/RenderTargets.cpp @@ -168,7 +168,7 @@ RenderTargets::RenderTargets(nvrhi::IDevice* device, int2 size) desc.format = nvrhi::Format::RGBA32_FLOAT; desc.debugName = "AccumulatedColor"; AccumulatedColor = device->createTexture(desc); - + desc.format = nvrhi::Format::RG16_FLOAT; desc.debugName = "RestirLuminance"; RestirLuminance = device->createTexture(desc); diff --git a/src/RenderTargets.h b/Samples/FullSample/Source/RenderTargets.h similarity index 99% rename from src/RenderTargets.h rename to Samples/FullSample/Source/RenderTargets.h index 35a7161..fb87065 100644 --- a/src/RenderTargets.h +++ b/Samples/FullSample/Source/RenderTargets.h @@ -50,7 +50,7 @@ class RenderTargets nvrhi::TextureHandle AccumulatedColor; nvrhi::TextureHandle RestirLuminance; nvrhi::TextureHandle PrevRestirLuminance; - + nvrhi::TextureHandle Gradients; nvrhi::TextureHandle TemporalSamplePositions; nvrhi::TextureHandle DiffuseConfidence; diff --git a/src/RtxdiResources.cpp b/Samples/FullSample/Source/RtxdiResources.cpp similarity index 89% rename from src/RtxdiResources.cpp rename to Samples/FullSample/Source/RtxdiResources.cpp index 027c066..1524a48 100644 --- a/src/RtxdiResources.cpp +++ b/Samples/FullSample/Source/RtxdiResources.cpp @@ -9,9 +9,9 @@ **************************************************************************/ #include "RtxdiResources.h" -#include -#include -#include +#include +#include +#include #include @@ -28,10 +28,10 @@ RtxdiResources::RtxdiResources( uint32_t maxGeometryInstances, uint32_t environmentMapWidth, uint32_t environmentMapHeight) - : m_MaxEmissiveMeshes(maxEmissiveMeshes) - , m_MaxEmissiveTriangles(maxEmissiveTriangles) - , m_MaxPrimitiveLights(maxPrimitiveLights) - , m_MaxGeometryInstances(maxGeometryInstances) + : m_maxEmissiveMeshes(maxEmissiveMeshes) + , m_maxEmissiveTriangles(maxEmissiveTriangles) + , m_maxPrimitiveLights(maxPrimitiveLights) + , m_maxGeometryInstances(maxGeometryInstances) { nvrhi::BufferDesc taskBufferDesc; taskBufferDesc.byteSize = sizeof(PrepareLightsTask) * (maxEmissiveMeshes + maxPrimitiveLights); @@ -103,7 +103,7 @@ RtxdiResources::RtxdiResources( nvrhi::BufferDesc neighborOffsetBufferDesc; - neighborOffsetBufferDesc.byteSize = context.getStaticParameters().NeighborOffsetCount * 2; + neighborOffsetBufferDesc.byteSize = context.GetStaticParameters().NeighborOffsetCount * 2; neighborOffsetBufferDesc.format = nvrhi::Format::RG8_SNORM; neighborOffsetBufferDesc.canHaveTypedViews = true; neighborOffsetBufferDesc.debugName = "NeighborOffsets"; @@ -113,7 +113,7 @@ RtxdiResources::RtxdiResources( nvrhi::BufferDesc lightReservoirBufferDesc; - lightReservoirBufferDesc.byteSize = sizeof(RTXDI_PackedDIReservoir) * context.getReservoirBufferParameters().reservoirArrayPitch * rtxdi::c_NumReSTIRDIReservoirBuffers; + lightReservoirBufferDesc.byteSize = sizeof(RTXDI_PackedDIReservoir) * context.GetReservoirBufferParameters().reservoirArrayPitch * rtxdi::c_NumReSTIRDIReservoirBuffers; lightReservoirBufferDesc.structStride = sizeof(RTXDI_PackedDIReservoir); lightReservoirBufferDesc.initialState = nvrhi::ResourceStates::UnorderedAccess; lightReservoirBufferDesc.keepInitialState = true; @@ -123,7 +123,7 @@ RtxdiResources::RtxdiResources( nvrhi::BufferDesc secondaryGBufferDesc; - secondaryGBufferDesc.byteSize = sizeof(SecondaryGBufferData) * context.getReservoirBufferParameters().reservoirArrayPitch; + secondaryGBufferDesc.byteSize = sizeof(SecondaryGBufferData) * context.GetReservoirBufferParameters().reservoirArrayPitch; secondaryGBufferDesc.structStride = sizeof(SecondaryGBufferData); secondaryGBufferDesc.initialState = nvrhi::ResourceStates::UnorderedAccess; secondaryGBufferDesc.keepInitialState = true; @@ -154,7 +154,7 @@ RtxdiResources::RtxdiResources( LocalLightPdfTexture = device->createTexture(localLightPdfDesc); nvrhi::BufferDesc giReservoirBufferDesc; - giReservoirBufferDesc.byteSize = sizeof(RTXDI_PackedGIReservoir) * context.getReservoirBufferParameters().reservoirArrayPitch * rtxdi::c_NumReSTIRGIReservoirBuffers; + giReservoirBufferDesc.byteSize = sizeof(RTXDI_PackedGIReservoir) * context.GetReservoirBufferParameters().reservoirArrayPitch * rtxdi::c_NumReSTIRGIReservoirBuffers; giReservoirBufferDesc.structStride = sizeof(RTXDI_PackedGIReservoir); giReservoirBufferDesc.initialState = nvrhi::ResourceStates::UnorderedAccess; giReservoirBufferDesc.keepInitialState = true; @@ -165,7 +165,7 @@ RtxdiResources::RtxdiResources( void RtxdiResources::InitializeNeighborOffsets(nvrhi::ICommandList* commandList, uint32_t neighborOffsetCount) { - if (m_NeighborOffsetsInitialized) + if (m_neighborOffsetsInitialized) return; std::vector offsets; @@ -175,5 +175,25 @@ void RtxdiResources::InitializeNeighborOffsets(nvrhi::ICommandList* commandList, commandList->writeBuffer(NeighborOffsetsBuffer, offsets.data(), offsets.size()); - m_NeighborOffsetsInitialized = true; + m_neighborOffsetsInitialized = true; +} + +uint32_t RtxdiResources::GetMaxEmissiveMeshes() const +{ + return m_maxEmissiveMeshes; +} + +uint32_t RtxdiResources::GetMaxEmissiveTriangles() const +{ + return m_maxEmissiveTriangles; +} + +uint32_t RtxdiResources::GetMaxPrimitiveLights() const +{ + return m_maxPrimitiveLights; +} + +uint32_t RtxdiResources::GetMaxGeometryInstances() const +{ + return m_maxGeometryInstances; } diff --git a/src/RtxdiResources.h b/Samples/FullSample/Source/RtxdiResources.h similarity index 78% rename from src/RtxdiResources.h rename to Samples/FullSample/Source/RtxdiResources.h index 2feaa79..a8707b1 100644 --- a/src/RtxdiResources.h +++ b/Samples/FullSample/Source/RtxdiResources.h @@ -21,13 +21,6 @@ namespace rtxdi class RtxdiResources { -private: - bool m_NeighborOffsetsInitialized = false; - uint32_t m_MaxEmissiveMeshes = 0; - uint32_t m_MaxEmissiveTriangles = 0; - uint32_t m_MaxPrimitiveLights = 0; - uint32_t m_MaxGeometryInstances = 0; - public: nvrhi::BufferHandle TaskBuffer; nvrhi::BufferHandle PrimitiveLightBuffer; @@ -56,8 +49,15 @@ class RtxdiResources void InitializeNeighborOffsets(nvrhi::ICommandList* commandList, uint32_t neighborOffsetCount); - uint32_t GetMaxEmissiveMeshes() const { return m_MaxEmissiveMeshes; } - uint32_t GetMaxEmissiveTriangles() const { return m_MaxEmissiveTriangles; } - uint32_t GetMaxPrimitiveLights() const { return m_MaxPrimitiveLights; } - uint32_t GetMaxGeometryInstances() const { return m_MaxGeometryInstances; } + uint32_t GetMaxEmissiveMeshes() const; + uint32_t GetMaxEmissiveTriangles() const; + uint32_t GetMaxPrimitiveLights() const; + uint32_t GetMaxGeometryInstances() const; + +private: + bool m_neighborOffsetsInitialized = false; + uint32_t m_maxEmissiveMeshes = 0; + uint32_t m_maxEmissiveTriangles = 0; + uint32_t m_maxPrimitiveLights = 0; + uint32_t m_maxGeometryInstances = 0; }; diff --git a/src/SampleScene.cpp b/Samples/FullSample/Source/SampleScene.cpp similarity index 84% rename from src/SampleScene.cpp rename to Samples/FullSample/Source/SampleScene.cpp index 92cb04e..aa7eabc 100644 --- a/src/SampleScene.cpp +++ b/Samples/FullSample/Source/SampleScene.cpp @@ -51,6 +51,11 @@ std::shared_ptr SpotLightWithProfile::Clone() return std::static_pointer_cast(copy); } +int EnvironmentLight::GetLightType() const +{ + return LightType_Environment; +} + std::shared_ptr EnvironmentLight::Clone() { auto copy = std::make_shared(); @@ -78,6 +83,11 @@ void CylinderLight::Store(Json::Value& node) const node["length"] << length; } +int CylinderLight::GetLightType() const +{ + return LightType_Cylinder; +} + std::shared_ptr CylinderLight::Clone() { auto copy = std::make_shared(); @@ -105,6 +115,11 @@ void DiskLight::Store(Json::Value& node) const node["radius"] << radius; } +int DiskLight::GetLightType() const +{ + return LightType_Disk; +} + std::shared_ptr DiskLight::Clone() { auto copy = std::make_shared(); @@ -130,6 +145,11 @@ void RectLight::Store(Json::Value& node) const node["height"] << height; } +int RectLight::GetLightType() const +{ + return LightType_Rect; +} + std::shared_ptr RectLight::Clone() { auto copy = std::make_shared(); @@ -180,7 +200,7 @@ bool SampleScene::LoadWithExecutor(const std::filesystem::path& jsonFileName, tf { if (animation->GetName() == "Benchmark") { - m_BenchmarkAnimation = animation; + m_benchmarkAnimation = animation; for (const auto& channel : animation->GetChannels()) { const auto& targetNode = channel->GetTargetNode(); @@ -189,7 +209,7 @@ bool SampleScene::LoadWithExecutor(const std::filesystem::path& jsonFileName, tf const auto& camera = std::dynamic_pointer_cast(targetNode->GetLeaf()); if (camera) { - m_BenchmarkCamera = camera; + m_benchmarkCamera = camera; break; } } @@ -203,18 +223,28 @@ bool SampleScene::LoadWithExecutor(const std::filesystem::path& jsonFileName, tf const std::string texturePath = "/media/environment/"; m_fs->enumerateFiles(texturePath, { ".exr" }, donut::vfs::enumerate_to_vector(environmentMapNames)); - m_EnvironmentMaps.clear(); - m_EnvironmentMaps.push_back(""); // Procedural env.map with no name + m_environmentMaps.clear(); + m_environmentMaps.push_back(""); // Procedural env.map with no name for (const std::string& mapName : environmentMapNames) { - m_EnvironmentMaps.push_back(texturePath + mapName); + m_environmentMaps.push_back(texturePath + mapName); } return true; } -inline uint64_t advanceHeapPtr(uint64_t& heapPtr, const nvrhi::MemoryRequirements& memReq) +const donut::engine::SceneGraphAnimation* SampleScene::GetBenchmarkAnimation() const +{ + return m_benchmarkAnimation.get(); +} + +const donut::engine::PerspectiveCamera* SampleScene::GetBenchmarkCamera() const +{ + return m_benchmarkCamera.get(); +} + +inline uint64_t AdvanceHeapPtr(uint64_t& heapPtr, const nvrhi::MemoryRequirements& memReq) { heapPtr = nvrhi::align(heapPtr, memReq.alignment); uint64_t current = heapPtr; @@ -271,7 +301,7 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) nvrhi::rt::AccelStructHandle as = device->createAccelStruct(blasDesc); - advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(as)); + AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(as)); // If this is a skinned mesh, create a second BLAS to toggle with the first one on every frame. // RTXDI needs access to the previous frame geometry in order to be unbiased. @@ -280,7 +310,7 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) auto sampleMesh = dynamic_cast(mesh.get()); assert(sampleMesh); sampleMesh->prevAccelStruct = device->createAccelStruct(blasDesc); - advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(as)); + AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(as)); } mesh->accelStruct = as; @@ -293,15 +323,15 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) tlasDesc.debugName = "TopLevelAS"; tlasDesc.buildFlags = nvrhi::rt::AccelStructBuildFlags::AllowUpdate; - m_TopLevelAS = device->createAccelStruct(tlasDesc); + m_topLevelAS = device->createAccelStruct(tlasDesc); - advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_TopLevelAS)); + AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_topLevelAS)); tlasDesc.debugName = "PrevTopLevelAS"; - m_PrevTopLevelAS = device->createAccelStruct(tlasDesc); + m_prevTopLevelAS = device->createAccelStruct(tlasDesc); - advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_PrevTopLevelAS)); + AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_prevTopLevelAS)); nvrhi::HeapDesc heapDecs; @@ -318,7 +348,7 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) if (!mesh->accelStruct) continue; - uint64_t heapOffset = advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(mesh->accelStruct)); + uint64_t heapOffset = AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(mesh->accelStruct)); device->bindAccelStructMemory(mesh->accelStruct, heap, heapOffset); @@ -328,18 +358,18 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) auto sampleMesh = dynamic_cast(mesh.get()); assert(sampleMesh); - heapOffset = advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(sampleMesh->prevAccelStruct)); + heapOffset = AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(sampleMesh->prevAccelStruct)); device->bindAccelStructMemory(sampleMesh->prevAccelStruct, heap, heapOffset); } } - uint64_t heapOffset = advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_TopLevelAS)); + uint64_t heapOffset = AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_topLevelAS)); - device->bindAccelStructMemory(m_TopLevelAS, heap, heapOffset); + device->bindAccelStructMemory(m_topLevelAS, heap, heapOffset); - heapOffset = advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_PrevTopLevelAS)); + heapOffset = AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_prevTopLevelAS)); - device->bindAccelStructMemory(m_PrevTopLevelAS, heap, heapOffset); + device->bindAccelStructMemory(m_prevTopLevelAS, heap, heapOffset); nvrhi::CommandListParameters clparams; @@ -412,9 +442,9 @@ void SampleScene::UpdateSkinnedMeshBLASes(nvrhi::ICommandList* commandList, uint void SampleScene::BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList) { - m_TlasInstances.resize(GetSceneGraph()->GetMeshInstances().size()); + m_tlasInstances.resize(GetSceneGraph()->GetMeshInstances().size()); - nvrhi::rt::AccelStructBuildFlags buildFlags = m_CanUpdateTLAS + nvrhi::rt::AccelStructBuildFlags buildFlags = m_canUpdateTLAS ? nvrhi::rt::AccelStructBuildFlags::PerformUpdate : nvrhi::rt::AccelStructBuildFlags::None; @@ -427,7 +457,7 @@ void SampleScene::BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList) if (!mesh->accelStruct) continue; - nvrhi::rt::InstanceDesc& instanceDesc = m_TlasInstances[index++]; + nvrhi::rt::InstanceDesc& instanceDesc = m_tlasInstances[index++]; instanceDesc.instanceMask = 0; engine::SceneContentFlags contentFlags = instance->GetContentFlags(); @@ -456,28 +486,43 @@ void SampleScene::BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList) instanceDesc.instanceID = uint(instance->GetInstanceIndex()); } - commandList->buildTopLevelAccelStruct(m_TopLevelAS, m_TlasInstances.data(), m_TlasInstances.size(), buildFlags); - m_CanUpdateTLAS = true; + commandList->buildTopLevelAccelStruct(m_topLevelAS, m_tlasInstances.data(), m_tlasInstances.size(), buildFlags); + m_canUpdateTLAS = true; } void SampleScene::NextFrame() { - std::swap(m_TopLevelAS, m_PrevTopLevelAS); - std::swap(m_CanUpdateTLAS, m_CanUpdatePrevTLAS); + std::swap(m_topLevelAS, m_prevTopLevelAS); + std::swap(m_canUpdateTLAS, m_canUpdatePrevTLAS); } void SampleScene::Animate(float fElapsedTimeSeconds) { - m_WallclockTime += fElapsedTimeSeconds; + m_wallclockTime += fElapsedTimeSeconds; for (const auto& animation : m_SceneGraph->GetAnimations()) { - if (animation == m_BenchmarkAnimation) + if (animation == m_benchmarkAnimation) continue; float duration = animation->GetDuration(); double integral; - float animationTime = float(std::modf(m_WallclockTime / double(duration), &integral)) * duration; + float animationTime = float(std::modf(m_wallclockTime / double(duration), &integral)) * duration; (void)animation->Apply(animationTime); } } + +nvrhi::rt::IAccelStruct* SampleScene::GetTopLevelAS() const +{ + return m_topLevelAS; +} + +nvrhi::rt::IAccelStruct* SampleScene::GetPrevTopLevelAS() const +{ + return m_prevTopLevelAS; +} + +std::vector& SampleScene::GetEnvironmentMaps() +{ + return m_environmentMaps; +} \ No newline at end of file diff --git a/src/SampleScene.h b/Samples/FullSample/Source/SampleScene.h similarity index 75% rename from src/SampleScene.h rename to Samples/FullSample/Source/SampleScene.h index c16cc4e..ce91b4c 100644 --- a/src/SampleScene.h +++ b/Samples/FullSample/Source/SampleScene.h @@ -37,7 +37,7 @@ class EnvironmentLight : public donut::engine::Light float rotation = 0.f; dm::uint2 textureSize = 0u; - [[nodiscard]] int GetLightType() const override { return LightType_Environment; } + [[nodiscard]] int GetLightType() const override; [[nodiscard]] std::shared_ptr Clone() override; }; @@ -50,7 +50,7 @@ class CylinderLight : public donut::engine::Light void Load(const Json::Value& node) override; void Store(Json::Value& node) const override; - [[nodiscard]] int GetLightType() const override { return LightType_Cylinder; } + [[nodiscard]] int GetLightType() const override; [[nodiscard]] std::shared_ptr Clone() override; }; @@ -62,7 +62,7 @@ class DiskLight : public donut::engine::Light void Load(const Json::Value& node) override; void Store(Json::Value& node) const override; - [[nodiscard]] int GetLightType() const override { return LightType_Disk; } + [[nodiscard]] int GetLightType() const override; [[nodiscard]] std::shared_ptr Clone() override; }; @@ -75,7 +75,7 @@ class RectLight : public donut::engine::Light void Load(const Json::Value& node) override; void Store(Json::Value& node) const override; - [[nodiscard]] int GetLightType() const override { return LightType_Rect; } + [[nodiscard]] int GetLightType() const override; [[nodiscard]] std::shared_ptr Clone() override; }; @@ -96,27 +96,13 @@ class SampleSceneTypeFactory : public donut::engine::SceneTypeFactory class SampleScene : public donut::engine::Scene { -private: - nvrhi::rt::AccelStructHandle m_TopLevelAS; - nvrhi::rt::AccelStructHandle m_PrevTopLevelAS; - std::vector m_TlasInstances; - std::shared_ptr m_BenchmarkAnimation; - std::shared_ptr m_BenchmarkCamera; - - bool m_CanUpdateTLAS = false; - bool m_CanUpdatePrevTLAS = false; - - double m_WallclockTime = 0; - - std::vector m_EnvironmentMaps; - public: using Scene::Scene; bool LoadWithExecutor(const std::filesystem::path& jsonFileName, tf::Executor* executor) override; - const donut::engine::SceneGraphAnimation* GetBenchmarkAnimation() const { return m_BenchmarkAnimation.get(); } - const donut::engine::PerspectiveCamera* GetBenchmarkCamera() const { return m_BenchmarkCamera.get(); } + const donut::engine::SceneGraphAnimation* GetBenchmarkAnimation() const; + const donut::engine::PerspectiveCamera* GetBenchmarkCamera() const; void BuildMeshBLASes(nvrhi::IDevice* device); void UpdateSkinnedMeshBLASes(nvrhi::ICommandList* commandList, uint32_t frameIndex); @@ -124,8 +110,22 @@ class SampleScene : public donut::engine::Scene void NextFrame(); void Animate(float fElapsedTimeSeconds); - nvrhi::rt::IAccelStruct* GetTopLevelAS() const { return m_TopLevelAS; } - nvrhi::rt::IAccelStruct* GetPrevTopLevelAS() const { return m_PrevTopLevelAS; } + nvrhi::rt::IAccelStruct* GetTopLevelAS() const; + nvrhi::rt::IAccelStruct* GetPrevTopLevelAS() const; + + std::vector& GetEnvironmentMaps(); + +private: + nvrhi::rt::AccelStructHandle m_topLevelAS; + nvrhi::rt::AccelStructHandle m_prevTopLevelAS; + std::vector m_tlasInstances; + std::shared_ptr m_benchmarkAnimation; + std::shared_ptr m_benchmarkCamera; + + bool m_canUpdateTLAS = false; + bool m_canUpdatePrevTLAS = false; + + double m_wallclockTime = 0; - std::vector& GetEnvironmentMaps() { return m_EnvironmentMaps; } + std::vector m_environmentMaps; }; diff --git a/src/Testing.cpp b/Samples/FullSample/Source/Testing.cpp similarity index 98% rename from src/Testing.cpp rename to Samples/FullSample/Source/Testing.cpp index ed588c5..1ff2377 100644 --- a/src/Testing.cpp +++ b/Samples/FullSample/Source/Testing.cpp @@ -89,7 +89,9 @@ std::istream& operator>> (std::istream& is, IndirectLightingMode& mode) return is; } -std::istream& operator>> (std::istream& is, rtxdi::ReSTIRDI_ResamplingMode& mode) +namespace rtxdi +{ +std::istream& operator>> (std::istream& is, ReSTIRDI_ResamplingMode& mode) { std::string s; is >> s; @@ -112,7 +114,7 @@ std::istream& operator>> (std::istream& is, rtxdi::ReSTIRDI_ResamplingMode& mode return is; } -std::istream& operator>> (std::istream& is, rtxdi::ReSTIRGI_ResamplingMode& mode) +std::istream& operator>> (std::istream& is, ReSTIRGI_ResamplingMode& mode) { std::string s; is >> s; @@ -134,6 +136,7 @@ std::istream& operator>> (std::istream& is, rtxdi::ReSTIRGI_ResamplingMode& mode return is; } +} // A hacky operator to allow selecting the preset std::istream& operator>> (std::istream& is, UIData& ui) diff --git a/src/Testing.h b/Samples/FullSample/Source/Testing.h similarity index 100% rename from src/Testing.h rename to Samples/FullSample/Source/Testing.h diff --git a/src/UserInterface.cpp b/Samples/FullSample/Source/UserInterface.cpp similarity index 97% rename from src/UserInterface.cpp rename to Samples/FullSample/Source/UserInterface.cpp index 1f88cf9..780460b 100644 --- a/src/UserInterface.cpp +++ b/Samples/FullSample/Source/UserInterface.cpp @@ -52,15 +52,15 @@ UIData::UIData() taaParams.clampingFactor = 1.3f; restirDI.resamplingMode = rtxdi::ReSTIRDI_ResamplingMode::TemporalAndSpatial; - restirDI.initialSamplingParams = rtxdi::getDefaultReSTIRDIInitialSamplingParams(); - restirDI.temporalResamplingParams = rtxdi::getDefaultReSTIRDITemporalResamplingParams(); - restirDI.spatialResamplingParams = rtxdi::getDefaultReSTIRDISpatialResamplingParams(); - restirDI.shadingParams = rtxdi::getDefaultReSTIRDIShadingParams(); + restirDI.initialSamplingParams = rtxdi::GetDefaultReSTIRDIInitialSamplingParams(); + restirDI.temporalResamplingParams = rtxdi::GetDefaultReSTIRDITemporalResamplingParams(); + restirDI.spatialResamplingParams = rtxdi::GetDefaultReSTIRDISpatialResamplingParams(); + restirDI.shadingParams = rtxdi::GetDefaultReSTIRDIShadingParams(); restirGI.resamplingMode = rtxdi::ReSTIRGI_ResamplingMode::TemporalAndSpatial; - restirGI.temporalResamplingParams = rtxdi::getDefaultReSTIRGITemporalResamplingParams(); - restirGI.spatialResamplingParams = rtxdi::getDefaultReSTIRGISpatialResamplingParams(); - restirGI.finalShadingParams = rtxdi::getDefaultReSTIRGIFinalShadingParams(); + restirGI.temporalResamplingParams = rtxdi::GetDefaultReSTIRGITemporalResamplingParams(); + restirGI.spatialResamplingParams = rtxdi::GetDefaultReSTIRGISpatialResamplingParams(); + restirGI.finalShadingParams = rtxdi::GetDefaultReSTIRGIFinalShadingParams(); ApplyPreset(); @@ -224,11 +224,14 @@ void UIData::SetDefaultDenoiserSettings() #endif -UserInterface::UserInterface(app::DeviceManager* deviceManager, vfs::IFileSystem& rootFS, UIData& ui) - : ImGui_Renderer(deviceManager) - , m_ui(ui) +UserInterface::UserInterface(app::DeviceManager* deviceManager, vfs::IFileSystem& rootFS, UIData& ui) : + ImGui_Renderer(deviceManager), + m_ui(ui), + m_fontOpenSans(nullptr), + m_showAdvancedSamplingSettings(false), + m_showAdvancedDenoisingSettings(false) { - m_FontOpenSans = LoadFont(rootFS, "/media/fonts/OpenSans/OpenSans-Regular.ttf", 17.f); + m_fontOpenSans = CreateFontFromFile(rootFS, "/media/fonts/OpenSans/OpenSans-Regular.ttf", 17.f); } static void ShowHelpMarker(const char* desc) @@ -615,14 +618,14 @@ void UserInterface::SamplingSettings() samplingSettingsChanged |= ImGui::SliderFloat("Spatial Normal Threshold", &m_ui.restirDI.spatialResamplingParams.spatialNormalThreshold, 0.f, 1.f); ShowHelpMarker("Lower values result in accepting samples with normals more different from the center pixel."); - samplingSettingsChanged |= ImGui::Checkbox("Discount Naive Samples", reinterpret_cast(&m_ui.restirDI.spatialResamplingParams.discountNaiveSamples)); - ShowHelpMarker("Prevents samples which are from the current frame or have no reasonable temporal history merged being spread to neighbors."); + samplingSettingsChanged |= ImGui::Checkbox("Discount Naive Samples", reinterpret_cast(&m_ui.restirDI.spatialResamplingParams.discountNaiveSamples)); + ShowHelpMarker("Prevents samples which are from the current frame or have no reasonable temporal history merged being spread to neighbors."); } if (m_showAdvancedSamplingSettings && m_ui.restirDI.resamplingMode != rtxdi::ReSTIRDI_ResamplingMode::Temporal) { - samplingSettingsChanged |= ImGui::Checkbox("Discount Naive Samples", (bool*)&m_ui.restirDI.spatialResamplingParams.discountNaiveSamples); - ShowHelpMarker("Prevents samples which are from the current frame or have no reasonable temporal history merged being spread to neighbors."); + samplingSettingsChanged |= ImGui::Checkbox("Discount Naive Samples", (bool*)&m_ui.restirDI.spatialResamplingParams.discountNaiveSamples); + ShowHelpMarker("Prevents samples which are from the current frame or have no reasonable temporal history merged being spread to neighbors."); } ImGui::TreePop(); @@ -1071,10 +1074,10 @@ void UserInterface::CopySelectedLight() const { Json::Value root(Json::objectValue); - m_SelectedLight->Store(root); + m_selectedLight->Store(root); { - auto n = m_SelectedLight->GetNode(); + auto n = m_selectedLight->GetNode(); auto trn = n->GetLocalToWorldTransform(); donut::math::dquat rotation; donut::math::double3 scaling; @@ -1229,39 +1232,39 @@ void UserInterface::SceneSettings() if (ImGui_ColoredTreeNode("Light Editor", c_ColorRegularHeader)) { - if (ImGui::BeginCombo("Select Light", m_SelectedLight ? m_SelectedLight->GetName().c_str() : "(None)")) + if (ImGui::BeginCombo("Select Light", m_selectedLight ? m_selectedLight->GetName().c_str() : "(None)")) { for (const auto& light : m_ui.resources->scene->GetSceneGraph()->GetLights()) { if (light->GetLightType() == LightType_Environment) continue; - bool selected = m_SelectedLight == light; + bool selected = m_selectedLight == light; ImGui::Selectable(light->GetName().c_str(), &selected); if (selected) { - m_SelectedLight = light; + m_selectedLight = light; ImGui::SetItemDefaultFocus(); } } ImGui::EndCombo(); } - if (m_SelectedLight) + if (m_selectedLight) { ImGui::PushItemWidth(200.f); - switch (m_SelectedLight->GetLightType()) + switch (m_selectedLight->GetLightType()) { case LightType_Directional: { - engine::DirectionalLight& dirLight = static_cast(*m_SelectedLight); + engine::DirectionalLight& dirLight = static_cast(*m_selectedLight); if (app::LightEditor_Directional(dirLight)) m_ui.environmentMapDirty = 1; break; } case LightType_Spot: { - SpotLightWithProfile& spotLight = static_cast(*m_SelectedLight); + SpotLightWithProfile& spotLight = static_cast(*m_selectedLight); app::LightEditor_Spot(spotLight); ImGui::PushItemWidth(150.f); @@ -1307,7 +1310,7 @@ void UserInterface::SceneSettings() } case LightType_Point: { - engine::PointLight& pointLight = static_cast(*m_SelectedLight); + engine::PointLight& pointLight = static_cast(*m_selectedLight); ImGui::SliderFloat("Radius", &pointLight.radius, 0.f, 1.f, "%.2f"); ImGui::ColorEdit3("Color", &pointLight.color.x, ImGuiColorEditFlags_Float); ImGui::SliderFloat("Intensity", &pointLight.intensity, 0.f, 100.f, "%.2f", ImGuiSliderFlags_Logarithmic); @@ -1319,7 +1322,7 @@ void UserInterface::SceneSettings() } case LightType_Cylinder: { - CylinderLight& cylinderLight = static_cast(*m_SelectedLight); + CylinderLight& cylinderLight = static_cast(*m_selectedLight); ImGui::PushItemWidth(150.f); dm::float3 position = dm::float3(cylinderLight.GetPosition()); if (ImGui::DragFloat3("Center", &position.x, 0.01f)) @@ -1340,7 +1343,7 @@ void UserInterface::SceneSettings() } case LightType_Disk: { - DiskLight& diskLight = static_cast(*m_SelectedLight); + DiskLight& diskLight = static_cast(*m_selectedLight); ImGui::PushItemWidth(150.f); dm::float3 position = dm::float3(diskLight.GetPosition()); if (ImGui::DragFloat3("Center", &position.x, 0.01f)) @@ -1361,7 +1364,7 @@ void UserInterface::SceneSettings() } case LightType_Rect: { - RectLight& rectLight = static_cast(*m_SelectedLight); + RectLight& rectLight = static_cast(*m_selectedLight); ImGui::PushItemWidth(150.f); dm::float3 position = dm::float3(rectLight.GetPosition()); if (ImGui::DragFloat3("Center", &position.x, 0.01f)) diff --git a/src/UserInterface.h b/Samples/FullSample/Source/UserInterface.h similarity index 93% rename from src/UserInterface.h rename to Samples/FullSample/Source/UserInterface.h index e4862c5..0eed2df 100644 --- a/src/UserInterface.h +++ b/Samples/FullSample/Source/UserInterface.h @@ -10,16 +10,18 @@ #pragma once -#include -#include -#include -#include +#include + +#include +#include +#include +#include #include #include #include -#include "GBufferPass.h" -#include "LightingPasses.h" +#include "RenderPasses/GBufferPass.h" +#include "RenderPasses/LightingPasses.h" #if WITH_NRD #include @@ -221,17 +223,16 @@ struct UIData class UserInterface : public donut::app::ImGui_Renderer { -private: - UIData& m_ui; - ImFont* m_FontOpenSans = nullptr; - std::shared_ptr m_SelectedLight; +public: + UserInterface(donut::app::DeviceManager* deviceManager, donut::vfs::IFileSystem& rootFS, UIData& ui); - bool m_showAdvancedSamplingSettings = false; - bool m_showAdvancedDenoisingSettings = false; +protected: + void buildUI(void) override; +private: void CopySelectedLight() const; void CopyCamera() const; - + void PerformanceWindow(); void SceneSettings(); void GeneralRenderingSettings(); @@ -242,10 +243,10 @@ class UserInterface : public donut::app::ImGui_Renderer void DenoiserSettings(); #endif -protected: - void buildUI(void) override; - -public: - UserInterface(donut::app::DeviceManager* deviceManager, donut::vfs::IFileSystem& rootFS, UIData& ui); + UIData& m_ui; + std::shared_ptr m_fontOpenSans; + std::shared_ptr m_selectedLight; + bool m_showAdvancedSamplingSettings; + bool m_showAdvancedDenoisingSettings; }; diff --git a/src/main.cpp b/Samples/FullSample/Source/main.cpp similarity index 59% rename from src/main.cpp rename to Samples/FullSample/Source/main.cpp index c9d4bdd..36b5846 100644 --- a/src/main.cpp +++ b/Samples/FullSample/Source/main.cpp @@ -9,7 +9,7 @@ **************************************************************************/ // Include this first just to test the cleanliness -#include +#include #include #include @@ -34,24 +34,24 @@ #include #endif +#include "DebugViz/DebugVizPasses.h" +#include "RenderPasses/AccumulationPass.h" +#include "RenderPasses/CompositingPass.h" +#include "RenderPasses/ConfidencePass.h" +#include "RenderPasses/FilterGradientsPass.h" +#include "RenderPasses/GBufferPass.h" +#include "RenderPasses/GenerateMipsPass.h" +#include "RenderPasses/GlassPass.h" +#include "RenderPasses/LightingPasses.h" +#include "RenderPasses/PrepareLightsPass.h" +#include "RenderPasses/RenderEnvironmentMapPass.h" +#include "RenderPasses/VisualizationPass.h" +#include "Profiler.h" #include "RenderTargets.h" -#include "ConfidencePass.h" -#include "FilterGradientsPass.h" -#include "CompositingPass.h" -#include "AccumulationPass.h" -#include "GBufferPass.h" -#include "GlassPass.h" -#include "PrepareLightsPass.h" -#include "RenderEnvironmentMapPass.h" -#include "GenerateMipsPass.h" -#include "LightingPasses.h" #include "RtxdiResources.h" #include "SampleScene.h" -#include "Profiler.h" -#include "UserInterface.h" -#include "VisualizationPass.h" #include "Testing.h" -#include "DebugViz/DebugVizPasses.h" +#include "UserInterface.h" #if WITH_NRD #include "NrdIntegration.h" @@ -79,124 +79,53 @@ static int g_ExitCode = 0; class SceneRenderer : public app::ApplicationBase { -private: - nvrhi::CommandListHandle m_CommandList; - - nvrhi::BindingLayoutHandle m_BindlessLayout; - - std::shared_ptr m_RootFs; - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_Scene; - std::shared_ptr m_DescriptorTableManager; - std::unique_ptr m_ToneMappingPass; - std::unique_ptr m_TemporalAntiAliasingPass; - std::unique_ptr m_BloomPass; - std::shared_ptr m_RenderTargets; - app::FirstPersonCamera m_Camera; - engine::PlanarView m_View; - engine::PlanarView m_ViewPrevious; - engine::PlanarView m_UpscaledView; - std::shared_ptr m_SunLight; - std::shared_ptr m_EnvironmentLight; - std::shared_ptr m_EnvironmentMap; - engine::BindingCache m_BindingCache; - - std::unique_ptr m_isContext; - std::unique_ptr m_GBufferPass; - std::unique_ptr m_RasterizedGBufferPass; - std::unique_ptr m_PostprocessGBufferPass; - std::unique_ptr m_GlassPass; - std::unique_ptr m_FilterGradientsPass; - std::unique_ptr m_ConfidencePass; - std::unique_ptr m_CompositingPass; - std::unique_ptr m_AccumulationPass; - std::unique_ptr m_PrepareLightsPass; - std::unique_ptr m_RenderEnvironmentMapPass; - std::unique_ptr m_EnvironmentMapPdfMipmapPass; - std::unique_ptr m_LocalLightPdfMipmapPass; - std::unique_ptr m_LightingPasses; - std::unique_ptr m_VisualizationPass; - std::unique_ptr m_RtxdiResources; - std::unique_ptr m_IesProfileLoader; - std::shared_ptr m_Profiler; - std::unique_ptr m_DebugVizPasses; - - uint32_t m_RenderFrameIndex = 0; - -#if WITH_NRD - std::unique_ptr m_NRD; -#endif - -#if WITH_DLSS - std::unique_ptr m_DLSS; -#endif - - UIData& m_ui; - CommandLineArguments& m_args; - uint m_FramesSinceAnimation = 0; - bool m_PreviousViewValid = false; - time_point m_PreviousFrameTimeStamp; - - std::vector> m_IesProfiles; - - dm::float3 m_RegirCenter; - - enum class FrameStepMode - { - Disabled, - Wait, - Step - }; - - FrameStepMode m_FrameStepMode = FrameStepMode::Disabled; - public: SceneRenderer(app::DeviceManager* deviceManager, UIData& ui, CommandLineArguments& args) : ApplicationBase(deviceManager) - , m_BindingCache(deviceManager->GetDevice()) + , m_bindingCache(deviceManager->GetDevice()) , m_ui(ui) , m_args(args) { - m_ui.resources->camera = &m_Camera; + m_ui.resources->camera = &m_camera; } [[nodiscard]] std::shared_ptr GetShaderFactory() const { - return m_ShaderFactory; + return m_shaderFactory; } [[nodiscard]] std::shared_ptr GetRootFs() const { - return m_RootFs; + return m_rootFs; } bool Init() { - std::filesystem::path mediaPath = app::GetDirectoryWithExecutable().parent_path() / "rtxdi-assets"; + std::filesystem::path mediaPath = app::GetDirectoryWithExecutable().parent_path() / "Assets/Media"; if (!std::filesystem::exists(mediaPath)) { - mediaPath = mediaPath.parent_path().parent_path() / "rtxdi-assets"; + mediaPath = app::GetDirectoryWithExecutable().parent_path().parent_path() / "Assets/Media"; if (!std::filesystem::exists(mediaPath)) { - log::error("Couldn't locate the 'rtxdi-assets' folder."); + log::error("Couldn't locate the 'Assets/Media' folder."); return false; } } std::filesystem::path frameworkShaderPath = app::GetDirectoryWithExecutable() / "shaders/framework" / app::GetShaderTypeName(GetDevice()->getGraphicsAPI()); - std::filesystem::path appShaderPath = app::GetDirectoryWithExecutable() / "shaders/rtxdi-sample" / app::GetShaderTypeName(GetDevice()->getGraphicsAPI()); + std::filesystem::path appShaderPath = app::GetDirectoryWithExecutable() / "shaders/full-sample" / app::GetShaderTypeName(GetDevice()->getGraphicsAPI()); - log::debug("Mounting %s to %s", mediaPath.string().c_str(), "/rtxdi-assets"); + log::debug("Mounting %s to %s", mediaPath.string().c_str(), "/Assets/Media"); log::debug("Mounting %s to %s", frameworkShaderPath.string().c_str(), "/shaders/donut"); log::debug("Mounting %s to %s", appShaderPath.string().c_str(), "/shaders/app"); - m_RootFs = std::make_shared(); - m_RootFs->mount("/rtxdi-assets", mediaPath); - m_RootFs->mount("/shaders/donut", frameworkShaderPath); - m_RootFs->mount("/shaders/app", appShaderPath); + m_rootFs = std::make_shared(); + m_rootFs->mount("/Assets/Media", mediaPath); + m_rootFs->mount("/shaders/donut", frameworkShaderPath); + m_rootFs->mount("/shaders/app", appShaderPath); - m_ShaderFactory = std::make_shared(GetDevice(), m_RootFs, "/shaders"); - m_CommonPasses = std::make_shared(GetDevice(), m_ShaderFactory); + m_shaderFactory = std::make_shared(GetDevice(), m_rootFs, "/shaders"); + m_CommonPasses = std::make_shared(GetDevice(), m_shaderFactory); { nvrhi::BindlessLayoutDesc bindlessLayoutDesc; @@ -208,53 +137,53 @@ class SceneRenderer : public app::ApplicationBase }; bindlessLayoutDesc.visibility = nvrhi::ShaderType::All; bindlessLayoutDesc.maxCapacity = 1024; - m_BindlessLayout = GetDevice()->createBindlessLayout(bindlessLayoutDesc); + m_bindlessLayout = GetDevice()->createBindlessLayout(bindlessLayoutDesc); } - std::filesystem::path scenePath = "/rtxdi-assets/bistro-rtxdi.scene.json"; + std::filesystem::path scenePath = "/Assets/Media/bistro-rtxdi.scene.json"; - m_DescriptorTableManager = std::make_shared(GetDevice(), m_BindlessLayout); + m_descriptorTableManager = std::make_shared(GetDevice(), m_bindlessLayout); - m_TextureCache = std::make_shared(GetDevice(), m_RootFs, m_DescriptorTableManager); + m_TextureCache = std::make_shared(GetDevice(), m_rootFs, m_descriptorTableManager); m_TextureCache->SetInfoLogSeverity(donut::log::Severity::Debug); - m_IesProfileLoader = std::make_unique(GetDevice(), m_ShaderFactory, m_DescriptorTableManager); + m_iesProfileLoader = std::make_unique(GetDevice(), m_shaderFactory, m_descriptorTableManager); auto sceneTypeFactory = std::make_shared(); - m_Scene = std::make_shared(GetDevice(), *m_ShaderFactory, m_RootFs, m_TextureCache, m_DescriptorTableManager, sceneTypeFactory); - m_ui.resources->scene = m_Scene; + m_scene = std::make_shared(GetDevice(), *m_shaderFactory, m_rootFs, m_TextureCache, m_descriptorTableManager, sceneTypeFactory); + m_ui.resources->scene = m_scene; SetAsynchronousLoadingEnabled(true); - BeginLoadingScene(m_RootFs, scenePath); + BeginLoadingScene(m_rootFs, scenePath); GetDeviceManager()->SetVsyncEnabled(true); if (!GetDevice()->queryFeatureSupport(nvrhi::Feature::RayQuery)) m_ui.useRayQuery = false; - m_Profiler = std::make_shared(*GetDeviceManager()); - m_ui.resources->profiler = m_Profiler; + m_profiler = std::make_shared(*GetDeviceManager()); + m_ui.resources->profiler = m_profiler; - m_FilterGradientsPass = std::make_unique(GetDevice(), m_ShaderFactory); - m_ConfidencePass = std::make_unique(GetDevice(), m_ShaderFactory); - m_CompositingPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_BindlessLayout); - m_AccumulationPass = std::make_unique(GetDevice(), m_ShaderFactory); - m_GBufferPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_Profiler, m_BindlessLayout); - m_RasterizedGBufferPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_Profiler, m_BindlessLayout); - m_PostprocessGBufferPass = std::make_unique(GetDevice(), m_ShaderFactory); - m_GlassPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_Profiler, m_BindlessLayout); - m_PrepareLightsPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_BindlessLayout); - m_LightingPasses = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_Profiler, m_BindlessLayout); + m_filterGradientsPass = std::make_unique(GetDevice(), m_shaderFactory); + m_confidencePass = std::make_unique(GetDevice(), m_shaderFactory); + m_compositingPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_bindlessLayout); + m_accumulationPass = std::make_unique(GetDevice(), m_shaderFactory); + m_gBufferPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_profiler, m_bindlessLayout); + m_rasterizedGBufferPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_profiler, m_bindlessLayout); + m_postprocessGBufferPass = std::make_unique(GetDevice(), m_shaderFactory); + m_glassPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_profiler, m_bindlessLayout); + m_prepareLightsPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_bindlessLayout); + m_lightingPasses = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_profiler, m_bindlessLayout); #if WITH_DLSS { #if DONUT_WITH_DX12 if (GetDevice()->getGraphicsAPI() == nvrhi::GraphicsAPI::D3D12) - m_DLSS = DLSS::CreateDX12(GetDevice(), *m_ShaderFactory); + m_dlss = DLSS::CreateDX12(GetDevice(), *m_shaderFactory); #endif #if DONUT_WITH_VULKAN if (GetDevice()->getGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN) - m_DLSS = DLSS::CreateVK(GetDevice(), *m_ShaderFactory); + m_dlss = DLSS::CreateVK(GetDevice(), *m_shaderFactory); #endif } #endif @@ -262,27 +191,27 @@ class SceneRenderer : public app::ApplicationBase LoadShaders(); std::vector profileNames; - m_RootFs->enumerateFiles("/rtxdi-assets/ies-profiles", { ".ies" }, vfs::enumerate_to_vector(profileNames)); + m_rootFs->enumerateFiles("/Assets/Media/ies-profiles", { ".ies" }, vfs::enumerate_to_vector(profileNames)); for (const std::string& profileName : profileNames) { - auto profile = m_IesProfileLoader->LoadIesProfile(*m_RootFs, "/rtxdi-assets/ies-profiles/" + profileName); + auto profile = m_iesProfileLoader->LoadIesProfile(*m_rootFs, "/Assets/Media/ies-profiles/" + profileName); if (profile) { - m_IesProfiles.push_back(profile); + m_iesProfiles.push_back(profile); } } - m_ui.resources->iesProfiles = m_IesProfiles; + m_ui.resources->iesProfiles = m_iesProfiles; - m_CommandList = GetDevice()->createCommandList(); + m_commandList = GetDevice()->createCommandList(); return true; } void AssignIesProfiles(nvrhi::ICommandList* commandList) { - for (const auto& light : m_Scene->GetSceneGraph()->GetLights()) + for (const auto& light : m_scene->GetSceneGraph()->GetLights()) { if (light->GetLightType() == LightType_Spot) { @@ -294,12 +223,12 @@ class SceneRenderer : public app::ApplicationBase if (spotLight.profileTextureIndex >= 0) continue; - auto foundProfile = std::find_if(m_IesProfiles.begin(), m_IesProfiles.end(), + auto foundProfile = std::find_if(m_iesProfiles.begin(), m_iesProfiles.end(), [&spotLight](auto it) { return it->name == spotLight.profileName; }); - if (foundProfile != m_IesProfiles.end()) + if (foundProfile != m_iesProfiles.end()) { - m_IesProfileLoader->BakeIesProfile(**foundProfile, commandList); + m_iesProfileLoader->BakeIesProfile(**foundProfile, commandList); spotLight.profileTextureIndex = (*foundProfile)->textureIndex; } @@ -311,45 +240,45 @@ class SceneRenderer : public app::ApplicationBase { ApplicationBase::SceneLoaded(); - m_Scene->FinishedLoading(GetFrameIndex()); + m_scene->FinishedLoading(GetFrameIndex()); - m_Camera.LookAt(float3(-7.688f, 2.0f, 5.594f), float3(-7.3341f, 2.0f, 6.5366f)); - m_Camera.SetMoveSpeed(3.f); + m_camera.LookAt(float3(-7.688f, 2.0f, 5.594f), float3(-7.3341f, 2.0f, 6.5366f)); + m_camera.SetMoveSpeed(3.f); - const auto& sceneGraph = m_Scene->GetSceneGraph(); + const auto& sceneGraph = m_scene->GetSceneGraph(); for (const auto& pLight : sceneGraph->GetLights()) { if (pLight->GetLightType() == LightType_Directional) { - m_SunLight = std::static_pointer_cast(pLight); + m_sunLight = std::static_pointer_cast(pLight); break; } } - if (!m_SunLight) + if (!m_sunLight) { - m_SunLight = std::make_shared(); - sceneGraph->AttachLeafNode(sceneGraph->GetRootNode(), m_SunLight); - m_SunLight->SetDirection(dm::double3(0.15, -1.0, 0.3)); - m_SunLight->angularSize = 1.f; + m_sunLight = std::make_shared(); + sceneGraph->AttachLeafNode(sceneGraph->GetRootNode(), m_sunLight); + m_sunLight->SetDirection(dm::double3(0.15, -1.0, 0.3)); + m_sunLight->angularSize = 1.f; } - m_CommandList->open(); - AssignIesProfiles(m_CommandList); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->open(); + AssignIesProfiles(m_commandList); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); // Create an environment light - m_EnvironmentLight = std::make_shared(); - sceneGraph->AttachLeafNode(sceneGraph->GetRootNode(), m_EnvironmentLight); - m_EnvironmentLight->SetName("Environment"); + m_environmentLight = std::make_shared(); + sceneGraph->AttachLeafNode(sceneGraph->GetRootNode(), m_environmentLight); + m_environmentLight->SetName("Environment"); m_ui.environmentMapDirty = 2; m_ui.environmentMapIndex = 0; - m_RasterizedGBufferPass->CreateBindingSet(); + m_rasterizedGBufferPass->CreateBindingSet(); - m_Scene->BuildMeshBLASes(GetDevice()); + m_scene->BuildMeshBLASes(GetDevice()); GetDeviceManager()->SetVsyncEnabled(false); @@ -358,19 +287,19 @@ class SceneRenderer : public app::ApplicationBase void LoadShaders() { - m_FilterGradientsPass->CreatePipeline(); - m_ConfidencePass->CreatePipeline(); - m_CompositingPass->CreatePipeline(); - m_AccumulationPass->CreatePipeline(); - m_GBufferPass->CreatePipeline(m_ui.useRayQuery); - m_PostprocessGBufferPass->CreatePipeline(); - m_GlassPass->CreatePipeline(m_ui.useRayQuery); - m_PrepareLightsPass->CreatePipeline(); + m_filterGradientsPass->CreatePipeline(); + m_confidencePass->CreatePipeline(); + m_compositingPass->CreatePipeline(); + m_accumulationPass->CreatePipeline(); + m_gBufferPass->CreatePipeline(m_ui.useRayQuery); + m_postprocessGBufferPass->CreatePipeline(); + m_glassPass->CreatePipeline(m_ui.useRayQuery); + m_prepareLightsPass->CreatePipeline(); } virtual bool LoadScene(std::shared_ptr fs, const std::filesystem::path& sceneFileName) override { - if (m_Scene->Load(sceneFileName)) + if (m_scene->Load(sceneFileName)) { return true; } @@ -394,14 +323,14 @@ class SceneRenderer : public app::ApplicationBase if (mods == 0 && key == GLFW_KEY_F1 && action == GLFW_PRESS) { - m_FrameStepMode = (m_FrameStepMode == FrameStepMode::Disabled) ? FrameStepMode::Wait : FrameStepMode::Disabled; + m_frameStepMode = (m_frameStepMode == FrameStepMode::Disabled) ? FrameStepMode::Wait : FrameStepMode::Disabled; return true; } if (mods == 0 && key == GLFW_KEY_F2 && action == GLFW_PRESS) { - if (m_FrameStepMode == FrameStepMode::Wait) - m_FrameStepMode = FrameStepMode::Step; + if (m_frameStepMode == FrameStepMode::Wait) + m_frameStepMode = FrameStepMode::Step; return true; } @@ -420,14 +349,14 @@ class SceneRenderer : public app::ApplicationBase return true; } - m_Camera.KeyboardUpdate(key, scancode, action, mods); + m_camera.KeyboardUpdate(key, scancode, action, mods); return true; } virtual bool MousePosUpdate(double xpos, double ypos) override { - m_Camera.MousePosUpdate(xpos, ypos); + m_camera.MousePosUpdate(xpos, ypos); return true; } @@ -439,15 +368,15 @@ class SceneRenderer : public app::ApplicationBase glfwGetCursorPos(GetDeviceManager()->GetWindow(), &mousex, &mousey); // Scale the mouse position according to the render resolution scale - mousex *= m_View.GetViewport().width() / m_UpscaledView.GetViewport().width(); - mousey *= m_View.GetViewport().height() / m_UpscaledView.GetViewport().height(); + mousex *= m_view.GetViewport().width() / m_upscaledView.GetViewport().width(); + mousey *= m_view.GetViewport().height() / m_upscaledView.GetViewport().height(); m_ui.gbufferSettings.materialReadbackPosition = int2(int(mousex), int(mousey)); m_ui.gbufferSettings.enableMaterialReadback = true; return true; } - m_Camera.MouseButtonUpdate(button, action, mods); + m_camera.MouseButtonUpdate(button, action, mods); return true; } @@ -459,13 +388,13 @@ class SceneRenderer : public app::ApplicationBase if (!m_args.saveFrameFileName.empty()) fElapsedTimeSeconds = 1.f / 60.f; - m_Camera.Animate(fElapsedTimeSeconds); + m_camera.Animate(fElapsedTimeSeconds); if (m_ui.enableAnimations) - m_Scene->Animate(fElapsedTimeSeconds * m_ui.animationSpeed); + m_scene->Animate(fElapsedTimeSeconds * m_ui.animationSpeed); - if (m_ToneMappingPass) - m_ToneMappingPass->AdvanceFrame(fElapsedTimeSeconds); + if (m_toneMappingPass) + m_toneMappingPass->AdvanceFrame(fElapsedTimeSeconds); } virtual void BackBufferResized(const uint32_t width, const uint32_t height, const uint32_t sampleCount) override @@ -474,52 +403,52 @@ class SceneRenderer : public app::ApplicationBase if (m_args.renderWidth > 0 && m_args.renderHeight > 0) return; - if (m_RenderTargets && m_RenderTargets->Size.x == int(width) && m_RenderTargets->Size.y == int(height)) + if (m_renderTargets && m_renderTargets->Size.x == int(width) && m_renderTargets->Size.y == int(height)) return; - m_BindingCache.Clear(); - m_RenderTargets = nullptr; + m_bindingCache.Clear(); + m_renderTargets = nullptr; m_isContext = nullptr; - m_RtxdiResources = nullptr; - m_TemporalAntiAliasingPass = nullptr; - m_ToneMappingPass = nullptr; - m_BloomPass = nullptr; + m_rtxdiResources = nullptr; + m_temporalAntiAliasingPass = nullptr; + m_toneMappingPass = nullptr; + m_bloomPass = nullptr; #if WITH_NRD - m_NRD = nullptr; + m_nrd = nullptr; #endif } void LoadEnvironmentMap() { - if (m_EnvironmentMap) + if (m_environmentMap) { // Make sure there is no rendering in-flight before we unload the texture and erase its descriptor. // Decsriptor manipulations are synchronous and immediately affect whatever is executing on the GPU. GetDevice()->waitForIdle(); - m_TextureCache->UnloadTexture(m_EnvironmentMap); + m_TextureCache->UnloadTexture(m_environmentMap); - m_EnvironmentMap = nullptr; + m_environmentMap = nullptr; } if (m_ui.environmentMapIndex > 0) { - auto& environmentMaps = m_Scene->GetEnvironmentMaps(); + auto& environmentMaps = m_scene->GetEnvironmentMaps(); const std::string& environmentMapPath = environmentMaps[m_ui.environmentMapIndex]; - m_EnvironmentMap = m_TextureCache->LoadTextureFromFileDeferred(environmentMapPath, false); + m_environmentMap = m_TextureCache->LoadTextureFromFileDeferred(environmentMapPath, false); - if (m_TextureCache->IsTextureLoaded(m_EnvironmentMap)) + if (m_TextureCache->IsTextureLoaded(m_environmentMap)) { m_TextureCache->ProcessRenderingThreadCommands(*m_CommonPasses, 0.f); m_TextureCache->LoadingFinished(); - m_EnvironmentMap->bindlessDescriptor = m_DescriptorTableManager->CreateDescriptorHandle(nvrhi::BindingSetItem::Texture_SRV(0, m_EnvironmentMap->texture)); + m_environmentMap->bindlessDescriptor = m_descriptorTableManager->CreateDescriptorHandle(nvrhi::BindingSetItem::Texture_SRV(0, m_environmentMap->texture)); } else { // Failed to load the file: revert to the procedural map and remove this file from the list. - m_EnvironmentMap = nullptr; + m_environmentMap = nullptr; environmentMaps.erase(environmentMaps.begin() + m_ui.environmentMapIndex); m_ui.environmentMapIndex = 0; } @@ -530,43 +459,43 @@ class SceneRenderer : public app::ApplicationBase { nvrhi::Viewport windowViewport((float)renderWidth, (float)renderHeight); - if (m_TemporalAntiAliasingPass) - m_TemporalAntiAliasingPass->SetJitter(m_ui.temporalJitter); + if (m_temporalAntiAliasingPass) + m_temporalAntiAliasingPass->SetJitter(m_ui.temporalJitter); nvrhi::Viewport renderViewport = windowViewport; renderViewport.maxX = roundf(renderViewport.maxX * m_ui.resolutionScale); renderViewport.maxY = roundf(renderViewport.maxY * m_ui.resolutionScale); - m_View.SetViewport(renderViewport); + m_view.SetViewport(renderViewport); - if (m_ui.enablePixelJitter && m_TemporalAntiAliasingPass) + if (m_ui.enablePixelJitter && m_temporalAntiAliasingPass) { - m_View.SetPixelOffset(m_TemporalAntiAliasingPass->GetCurrentPixelOffset()); + m_view.SetPixelOffset(m_temporalAntiAliasingPass->GetCurrentPixelOffset()); } else { - m_View.SetPixelOffset(0.f); + m_view.SetPixelOffset(0.f); } const float aspectRatio = windowViewport.width() / windowViewport.height(); if (activeCamera) - m_View.SetMatrices(activeCamera->GetWorldToViewMatrix(), perspProjD3DStyleReverse(activeCamera->verticalFov, aspectRatio, activeCamera->zNear)); + m_view.SetMatrices(activeCamera->GetWorldToViewMatrix(), perspProjD3DStyleReverse(activeCamera->verticalFov, aspectRatio, activeCamera->zNear)); else - m_View.SetMatrices(m_Camera.GetWorldToViewMatrix(), perspProjD3DStyleReverse(radians(m_ui.verticalFov), aspectRatio, 0.01f)); - m_View.UpdateCache(); + m_view.SetMatrices(m_camera.GetWorldToViewMatrix(), perspProjD3DStyleReverse(radians(m_ui.verticalFov), aspectRatio, 0.01f)); + m_view.UpdateCache(); - if (m_ViewPrevious.GetViewExtent().width() == 0) - m_ViewPrevious = m_View; + if (m_viewPrevious.GetViewExtent().width() == 0) + m_viewPrevious = m_view; - m_UpscaledView = m_View; - m_UpscaledView.SetViewport(windowViewport); + m_upscaledView = m_view; + m_upscaledView.SetViewport(windowViewport); } void SetupRenderPasses(uint32_t renderWidth, uint32_t renderHeight, bool& exposureResetRequired) { if (m_ui.environmentMapDirty == 2) { - m_EnvironmentMapPdfMipmapPass = nullptr; + m_environmentMapPdfMipmapPass = nullptr; m_ui.environmentMapDirty = 1; } @@ -575,13 +504,13 @@ class SceneRenderer : public app::ApplicationBase { GetDevice()->waitForIdle(); - m_ShaderFactory->ClearCache(); - m_TemporalAntiAliasingPass = nullptr; - m_RenderEnvironmentMapPass = nullptr; - m_EnvironmentMapPdfMipmapPass = nullptr; - m_LocalLightPdfMipmapPass = nullptr; - m_VisualizationPass = nullptr; - m_DebugVizPasses = nullptr; + m_shaderFactory->ClearCache(); + m_temporalAntiAliasingPass = nullptr; + m_renderEnvironmentMapPass = nullptr; + m_environmentMapPdfMipmapPass = nullptr; + m_localLightPdfMipmapPass = nullptr; + m_visualizationPass = nullptr; + m_debugVizPasses = nullptr; m_ui.environmentMapDirty = 1; LoadShaders(); @@ -590,31 +519,31 @@ class SceneRenderer : public app::ApplicationBase bool renderTargetsCreated = false; bool rtxdiResourcesCreated = false; - if (!m_RenderEnvironmentMapPass) + if (!m_renderEnvironmentMapPass) { - m_RenderEnvironmentMapPass = std::make_unique(GetDevice(), m_ShaderFactory, m_DescriptorTableManager, 2048); + m_renderEnvironmentMapPass = std::make_unique(GetDevice(), m_shaderFactory, m_descriptorTableManager, 2048); } const auto environmentMap = (m_ui.environmentMapIndex > 0) - ? m_EnvironmentMap->texture.Get() - : m_RenderEnvironmentMapPass->GetTexture(); + ? m_environmentMap->texture.Get() + : m_renderEnvironmentMapPass->GetTexture(); uint32_t numEmissiveMeshes, numEmissiveTriangles; - m_PrepareLightsPass->CountLightsInScene(numEmissiveMeshes, numEmissiveTriangles); - uint32_t numPrimitiveLights = uint32_t(m_Scene->GetSceneGraph()->GetLights().size()); - uint32_t numGeometryInstances = uint32_t(m_Scene->GetSceneGraph()->GetGeometryInstancesCount()); + m_prepareLightsPass->CountLightsInScene(numEmissiveMeshes, numEmissiveTriangles); + uint32_t numPrimitiveLights = uint32_t(m_scene->GetSceneGraph()->GetLights().size()); + uint32_t numGeometryInstances = uint32_t(m_scene->GetSceneGraph()->GetGeometryInstancesCount()); uint2 environmentMapSize = uint2(environmentMap->getDesc().width, environmentMap->getDesc().height); - if (m_RtxdiResources && ( - environmentMapSize.x != m_RtxdiResources->EnvironmentPdfTexture->getDesc().width || - environmentMapSize.y != m_RtxdiResources->EnvironmentPdfTexture->getDesc().height || - numEmissiveMeshes > m_RtxdiResources->GetMaxEmissiveMeshes() || - numEmissiveTriangles > m_RtxdiResources->GetMaxEmissiveTriangles() || - numPrimitiveLights > m_RtxdiResources->GetMaxPrimitiveLights() || - numGeometryInstances > m_RtxdiResources->GetMaxGeometryInstances())) + if (m_rtxdiResources && ( + environmentMapSize.x != m_rtxdiResources->EnvironmentPdfTexture->getDesc().width || + environmentMapSize.y != m_rtxdiResources->EnvironmentPdfTexture->getDesc().height || + numEmissiveMeshes > m_rtxdiResources->GetMaxEmissiveMeshes() || + numEmissiveTriangles > m_rtxdiResources->GetMaxEmissiveTriangles() || + numPrimitiveLights > m_rtxdiResources->GetMaxPrimitiveLights() || + numGeometryInstances > m_rtxdiResources->GetMaxGeometryInstances())) { - m_RtxdiResources = nullptr; + m_rtxdiResources = nullptr; } if (!m_isContext) @@ -627,47 +556,47 @@ class SceneRenderer : public app::ApplicationBase m_isContext = std::make_unique(isStaticParams); - m_ui.regirLightSlotCount = m_isContext->getReGIRContext().getReGIRLightSlotCount(); + m_ui.regirLightSlotCount = m_isContext->GetReGIRContext().GetReGIRLightSlotCount(); } - if (!m_RenderTargets) + if (!m_renderTargets) { - m_RenderTargets = std::make_shared(GetDevice(), int2((int)renderWidth, (int)renderHeight)); + m_renderTargets = std::make_shared(GetDevice(), int2((int)renderWidth, (int)renderHeight)); - m_Profiler->SetRenderTargets(m_RenderTargets); + m_profiler->SetRenderTargets(m_renderTargets); - m_GBufferPass->CreateBindingSet(m_Scene->GetTopLevelAS(), m_Scene->GetPrevTopLevelAS(), *m_RenderTargets); + m_gBufferPass->CreateBindingSet(m_scene->GetTopLevelAS(), m_scene->GetPrevTopLevelAS(), *m_renderTargets); - m_PostprocessGBufferPass->CreateBindingSet(*m_RenderTargets); + m_postprocessGBufferPass->CreateBindingSet(*m_renderTargets); - m_GlassPass->CreateBindingSet(m_Scene->GetTopLevelAS(), m_Scene->GetPrevTopLevelAS(), *m_RenderTargets); + m_glassPass->CreateBindingSet(m_scene->GetTopLevelAS(), m_scene->GetPrevTopLevelAS(), *m_renderTargets); - m_FilterGradientsPass->CreateBindingSet(*m_RenderTargets); + m_filterGradientsPass->CreateBindingSet(*m_renderTargets); - m_ConfidencePass->CreateBindingSet(*m_RenderTargets); + m_confidencePass->CreateBindingSet(*m_renderTargets); - m_AccumulationPass->CreateBindingSet(*m_RenderTargets); + m_accumulationPass->CreateBindingSet(*m_renderTargets); - m_RasterizedGBufferPass->CreatePipeline(*m_RenderTargets); + m_rasterizedGBufferPass->CreatePipeline(*m_renderTargets); - m_CompositingPass->CreateBindingSet(*m_RenderTargets); + m_compositingPass->CreateBindingSet(*m_renderTargets); - m_VisualizationPass = nullptr; - m_DebugVizPasses = nullptr; + m_visualizationPass = nullptr; + m_debugVizPasses = nullptr; renderTargetsCreated = true; } - if (!m_RtxdiResources) + if (!m_rtxdiResources) { uint32_t meshAllocationQuantum = 128; uint32_t triangleAllocationQuantum = 1024; uint32_t primitiveAllocationQuantum = 128; - m_RtxdiResources = std::make_unique( + m_rtxdiResources = std::make_unique( GetDevice(), - m_isContext->getReSTIRDIContext(), - m_isContext->getRISBufferSegmentAllocator(), + m_isContext->GetReSTIRDIContext(), + m_isContext->GetRISBufferSegmentAllocator(), (numEmissiveMeshes + meshAllocationQuantum - 1) & ~(meshAllocationQuantum - 1), (numEmissiveTriangles + triangleAllocationQuantum - 1) & ~(triangleAllocationQuantum - 1), (numPrimitiveLights + primitiveAllocationQuantum - 1) & ~(primitiveAllocationQuantum - 1), @@ -675,7 +604,7 @@ class SceneRenderer : public app::ApplicationBase environmentMapSize.x, environmentMapSize.y); - m_PrepareLightsPass->CreateBindingSet(*m_RtxdiResources); + m_prepareLightsPass->CreateBindingSet(*m_rtxdiResources); rtxdiResourcesCreated = true; @@ -683,92 +612,92 @@ class SceneRenderer : public app::ApplicationBase m_ui.environmentMapDirty = 1; } - if (!m_EnvironmentMapPdfMipmapPass || rtxdiResourcesCreated) + if (!m_environmentMapPdfMipmapPass || rtxdiResourcesCreated) { - m_EnvironmentMapPdfMipmapPass = std::make_unique( + m_environmentMapPdfMipmapPass = std::make_unique( GetDevice(), - m_ShaderFactory, + m_shaderFactory, environmentMap, - m_RtxdiResources->EnvironmentPdfTexture); + m_rtxdiResources->EnvironmentPdfTexture); } - if (!m_LocalLightPdfMipmapPass || rtxdiResourcesCreated) + if (!m_localLightPdfMipmapPass || rtxdiResourcesCreated) { - m_LocalLightPdfMipmapPass = std::make_unique( + m_localLightPdfMipmapPass = std::make_unique( GetDevice(), - m_ShaderFactory, + m_shaderFactory, nullptr, - m_RtxdiResources->LocalLightPdfTexture); + m_rtxdiResources->LocalLightPdfTexture); } if (renderTargetsCreated || rtxdiResourcesCreated) { - m_LightingPasses->CreateBindingSet( - m_Scene->GetTopLevelAS(), - m_Scene->GetPrevTopLevelAS(), - *m_RenderTargets, - *m_RtxdiResources); + m_lightingPasses->CreateBindingSet( + m_scene->GetTopLevelAS(), + m_scene->GetPrevTopLevelAS(), + *m_renderTargets, + *m_rtxdiResources); } if (rtxdiResourcesCreated || m_ui.reloadShaders) { // Some RTXDI context settings affect the shader permutations - m_LightingPasses->CreatePipelines(m_ui.regirStaticParams, m_ui.useRayQuery); + m_lightingPasses->CreatePipelines(m_ui.regirStaticParams, m_ui.useRayQuery); } m_ui.reloadShaders = false; - if (!m_TemporalAntiAliasingPass) + if (!m_temporalAntiAliasingPass) { render::TemporalAntiAliasingPass::CreateParameters taaParams; - taaParams.motionVectors = m_RenderTargets->MotionVectors; - taaParams.unresolvedColor = m_RenderTargets->HdrColor; - taaParams.resolvedColor = m_RenderTargets->ResolvedColor; - taaParams.feedback1 = m_RenderTargets->TaaFeedback1; - taaParams.feedback2 = m_RenderTargets->TaaFeedback2; + taaParams.motionVectors = m_renderTargets->MotionVectors; + taaParams.unresolvedColor = m_renderTargets->HdrColor; + taaParams.resolvedColor = m_renderTargets->ResolvedColor; + taaParams.feedback1 = m_renderTargets->TaaFeedback1; + taaParams.feedback2 = m_renderTargets->TaaFeedback2; taaParams.useCatmullRomFilter = true; - m_TemporalAntiAliasingPass = std::make_unique( - GetDevice(), m_ShaderFactory, m_CommonPasses, m_View, taaParams); + m_temporalAntiAliasingPass = std::make_unique( + GetDevice(), m_shaderFactory, m_CommonPasses, m_view, taaParams); } exposureResetRequired = false; - if (!m_ToneMappingPass) + if (!m_toneMappingPass) { render::ToneMappingPass::CreateParameters toneMappingParams; - m_ToneMappingPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_RenderTargets->LdrFramebuffer, m_UpscaledView, toneMappingParams); + m_toneMappingPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_renderTargets->LdrFramebuffer, m_upscaledView, toneMappingParams); exposureResetRequired = true; } - if (!m_BloomPass) + if (!m_bloomPass) { - m_BloomPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_RenderTargets->ResolvedFramebuffer, m_UpscaledView); + m_bloomPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_renderTargets->ResolvedFramebuffer, m_upscaledView); } - if (!m_VisualizationPass || renderTargetsCreated || rtxdiResourcesCreated) + if (!m_visualizationPass || renderTargetsCreated || rtxdiResourcesCreated) { - m_VisualizationPass = std::make_unique(GetDevice(), *m_CommonPasses, *m_ShaderFactory, *m_RenderTargets, *m_RtxdiResources); + m_visualizationPass = std::make_unique(GetDevice(), *m_CommonPasses, *m_shaderFactory, *m_renderTargets, *m_rtxdiResources); } - if (!m_DebugVizPasses || renderTargetsCreated) + if (!m_debugVizPasses || renderTargetsCreated) { - m_DebugVizPasses = std::make_unique(GetDevice(), m_ShaderFactory, m_Scene, m_BindlessLayout); - m_DebugVizPasses->CreateBindingSets(*m_RenderTargets, m_RenderTargets->DebugColor); - m_DebugVizPasses->CreatePipelines(); + m_debugVizPasses = std::make_unique(GetDevice(), m_shaderFactory, m_scene, m_bindlessLayout); + m_debugVizPasses->CreateBindingSets(*m_renderTargets, m_renderTargets->DebugColor); + m_debugVizPasses->CreatePipelines(); } #if WITH_NRD - if (!m_NRD) + if (!m_nrd) { - m_NRD = std::make_unique(GetDevice(), m_ui.denoisingMethod); - m_NRD->Initialize(m_RenderTargets->Size.x, m_RenderTargets->Size.y); + m_nrd = std::make_unique(GetDevice(), m_ui.denoisingMethod); + m_nrd->Initialize(m_renderTargets->Size.x, m_renderTargets->Size.y); } #endif #if WITH_DLSS { - m_DLSS->SetRenderSize(m_RenderTargets->Size.x, m_RenderTargets->Size.y, m_RenderTargets->Size.x, m_RenderTargets->Size.y); + m_dlss->SetRenderSize(m_renderTargets->Size.x, m_renderTargets->Size.y, m_renderTargets->Size.x, m_renderTargets->Size.y); - m_ui.dlssAvailable = m_DLSS->IsAvailable(); + m_ui.dlssAvailable = m_dlss->IsAvailable(); } #endif } @@ -776,10 +705,10 @@ class SceneRenderer : public app::ApplicationBase virtual void RenderSplashScreen(nvrhi::IFramebuffer* framebuffer) override { nvrhi::ITexture* framebufferTexture = framebuffer->getDesc().colorAttachments[0].texture; - m_CommandList->open(); - m_CommandList->clearTextureFloat(framebufferTexture, nvrhi::AllSubresources, nvrhi::Color(0.f)); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->open(); + m_commandList->clearTextureFloat(framebufferTexture, nvrhi::AllSubresources, nvrhi::Color(0.f)); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); uint32_t loadedObjects = engine::Scene::GetLoadingStats().ObjectsLoaded; uint32_t requestedObjects = engine::Scene::GetLoadingStats().ObjectsTotal; @@ -794,23 +723,23 @@ class SceneRenderer : public app::ApplicationBase void Resolve(nvrhi::ICommandList* commandList, float accumulationWeight) const { - ProfilerScope scope(*m_Profiler, commandList, ProfilerSection::Resolve); + ProfilerScope scope(*m_profiler, commandList, ProfilerSection::Resolve); switch (m_ui.aaMode) { case AntiAliasingMode::None: { engine::BlitParameters blitParams; - blitParams.sourceTexture = m_RenderTargets->HdrColor; - blitParams.sourceBox.m_maxs.x = m_View.GetViewport().width() / m_UpscaledView.GetViewport().width(); - blitParams.sourceBox.m_maxs.y = m_View.GetViewport().height() / m_UpscaledView.GetViewport().height(); - blitParams.targetFramebuffer = m_RenderTargets->ResolvedFramebuffer->GetFramebuffer(m_UpscaledView); + blitParams.sourceTexture = m_renderTargets->HdrColor; + blitParams.sourceBox.m_maxs.x = m_view.GetViewport().width() / m_upscaledView.GetViewport().width(); + blitParams.sourceBox.m_maxs.y = m_view.GetViewport().height() / m_upscaledView.GetViewport().height(); + blitParams.targetFramebuffer = m_renderTargets->ResolvedFramebuffer->GetFramebuffer(m_upscaledView); m_CommonPasses->BlitTexture(commandList, blitParams); break; } case AntiAliasingMode::Accumulation: { - m_AccumulationPass->Render(commandList, m_View, m_UpscaledView, accumulationWeight); - m_CommonPasses->BlitTexture(commandList, m_RenderTargets->ResolvedFramebuffer->GetFramebuffer(m_UpscaledView), m_RenderTargets->AccumulatedColor); + m_accumulationPass->Render(commandList, m_view, m_upscaledView, accumulationWeight); + m_CommonPasses->BlitTexture(commandList, m_renderTargets->ResolvedFramebuffer->GetFramebuffer(m_upscaledView), m_renderTargets->AccumulatedColor); break; } @@ -819,13 +748,13 @@ class SceneRenderer : public app::ApplicationBase if (m_ui.resetAccumulation) taaParams.newFrameWeight = 1.f; - m_TemporalAntiAliasingPass->TemporalResolve(commandList, taaParams, m_PreviousViewValid, m_View, m_UpscaledView); + m_temporalAntiAliasingPass->TemporalResolve(commandList, taaParams, m_previousViewValid, m_view, m_upscaledView); break; } #if WITH_DLSS case AntiAliasingMode::DLSS: { - m_DLSS->Render(commandList, *m_RenderTargets, m_ToneMappingPass->GetExposureBuffer(), m_ui.dlssExposureScale, m_ui.dlssSharpness, m_ui.rasterizeGBuffer, m_ui.resetAccumulation, m_View, m_ViewPrevious); + m_dlss->Render(commandList, *m_renderTargets, m_toneMappingPass->GetExposureBuffer(), m_ui.dlssExposureScale, m_ui.dlssSharpness, m_ui.rasterizeGBuffer, m_ui.resetAccumulation, m_view, m_viewPrevious); break; } #endif @@ -834,15 +763,15 @@ class SceneRenderer : public app::ApplicationBase void UpdateReGIRContextFromUI() { - auto& regirContext = m_isContext->getReGIRContext(); + auto& regirContext = m_isContext->GetReGIRContext(); auto dynamicParams = m_ui.regirDynamicParameters; - dynamicParams.center = { m_RegirCenter.x, m_RegirCenter.y, m_RegirCenter.z }; - regirContext.setDynamicParameters(dynamicParams); + dynamicParams.center = { m_regirCenter.x, m_regirCenter.y, m_regirCenter.z }; + regirContext.SetDynamicParameters(dynamicParams); } void UpdateReSTIRDIContextFromUI() { - rtxdi::ReSTIRDIContext& restirDIContext = m_isContext->getReSTIRDIContext(); + rtxdi::ReSTIRDIContext& restirDIContext = m_isContext->GetReSTIRDIContext(); ReSTIRDI_InitialSamplingParameters initialSamplingParams = m_ui.restirDI.initialSamplingParams; switch (initialSamplingParams.localLightSamplingMode) { @@ -857,20 +786,20 @@ class SceneRenderer : public app::ApplicationBase initialSamplingParams.numPrimaryLocalLightSamples = m_ui.restirDI.numLocalLightReGIRRISSamples; break; } - restirDIContext.setResamplingMode(m_ui.restirDI.resamplingMode); - restirDIContext.setInitialSamplingParameters(initialSamplingParams); - restirDIContext.setTemporalResamplingParameters(m_ui.restirDI.temporalResamplingParams); - restirDIContext.setSpatialResamplingParameters(m_ui.restirDI.spatialResamplingParams); - restirDIContext.setShadingParameters(m_ui.restirDI.shadingParams); + restirDIContext.SetResamplingMode(m_ui.restirDI.resamplingMode); + restirDIContext.SetInitialSamplingParameters(initialSamplingParams); + restirDIContext.SetTemporalResamplingParameters(m_ui.restirDI.temporalResamplingParams); + restirDIContext.SetSpatialResamplingParameters(m_ui.restirDI.spatialResamplingParams); + restirDIContext.SetShadingParameters(m_ui.restirDI.shadingParams); } void UpdateReSTIRGIContextFromUI() { - rtxdi::ReSTIRGIContext& restirGIContext = m_isContext->getReSTIRGIContext(); - restirGIContext.setResamplingMode(m_ui.restirGI.resamplingMode); - restirGIContext.setTemporalResamplingParameters(m_ui.restirGI.temporalResamplingParams); - restirGIContext.setSpatialResamplingParameters(m_ui.restirGI.spatialResamplingParams); - restirGIContext.setFinalShadingParameters(m_ui.restirGI.finalShadingParams); + rtxdi::ReSTIRGIContext& restirGIContext = m_isContext->GetReSTIRGIContext(); + restirGIContext.SetResamplingMode(m_ui.restirGI.resamplingMode); + restirGIContext.SetTemporalResamplingParameters(m_ui.restirGI.temporalResamplingParams); + restirGIContext.SetSpatialResamplingParameters(m_ui.restirGI.spatialResamplingParams); + restirGIContext.SetFinalShadingParameters(m_ui.restirGI.finalShadingParams); } bool IsLocalLightPowerRISEnabled() @@ -879,55 +808,55 @@ class SceneRenderer : public app::ApplicationBase { ReSTIRDI_InitialSamplingParameters indirectReSTIRDISamplingParams = m_ui.lightingSettings.brdfptParams.secondarySurfaceReSTIRDIParams.initialSamplingParams; bool enabled = (indirectReSTIRDISamplingParams.localLightSamplingMode == ReSTIRDI_LocalLightSamplingMode::Power_RIS) || - (indirectReSTIRDISamplingParams.localLightSamplingMode == ReSTIRDI_LocalLightSamplingMode::ReGIR_RIS && m_isContext->getReGIRContext().isLocalLightPowerRISEnable()); + (indirectReSTIRDISamplingParams.localLightSamplingMode == ReSTIRDI_LocalLightSamplingMode::ReGIR_RIS && m_isContext->GetReGIRContext().IsLocalLightPowerRISEnable()); if (enabled) return true; } - return m_isContext->isLocalLightPowerRISEnabled(); + return m_isContext->IsLocalLightPowerRISEnabled(); } void RenderScene(nvrhi::IFramebuffer* framebuffer) override { - if (m_FrameStepMode == FrameStepMode::Wait) + if (m_frameStepMode == FrameStepMode::Wait) { nvrhi::TextureHandle finalImage; if (m_ui.enableToneMapping) - finalImage = m_RenderTargets->LdrColor; + finalImage = m_renderTargets->LdrColor; else - finalImage = m_RenderTargets->HdrColor; + finalImage = m_renderTargets->HdrColor; - m_CommandList->open(); + m_commandList->open(); - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, finalImage, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, finalImage, &m_bindingCache); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); return; } - if (m_FrameStepMode == FrameStepMode::Step) - m_FrameStepMode = FrameStepMode::Wait; + if (m_frameStepMode == FrameStepMode::Step) + m_frameStepMode = FrameStepMode::Wait; const engine::PerspectiveCamera* activeCamera = nullptr; - uint effectiveFrameIndex = m_RenderFrameIndex; + uint effectiveFrameIndex = m_renderFrameIndex; if (m_ui.animationFrame.has_value()) { const float animationTime = float(m_ui.animationFrame.value()) * (1.f / 240.f); - auto* animation = m_Scene->GetBenchmarkAnimation(); + auto* animation = m_scene->GetBenchmarkAnimation(); if (animation && animationTime < animation->GetDuration()) { (void)animation->Apply(animationTime); - activeCamera = m_Scene->GetBenchmarkCamera(); + activeCamera = m_scene->GetBenchmarkCamera(); effectiveFrameIndex = m_ui.animationFrame.value(); m_ui.animationFrame = effectiveFrameIndex + 1; } else { - m_ui.benchmarkResults = m_Profiler->GetAsText(); + m_ui.benchmarkResults = m_profiler->GetAsText(); m_ui.animationFrame.reset(); if (m_args.benchmark) @@ -946,7 +875,7 @@ class SceneRenderer : public app::ApplicationBase while (true) { - uint64_t currentFrametime = duration_cast(steady_clock::now() - m_PreviousFrameTimeStamp).count(); + uint64_t currentFrametime = duration_cast(steady_clock::now() - m_previousFrameTimeStamp).count(); if(currentFrametime >= expectedFrametime) break; @@ -958,11 +887,11 @@ class SceneRenderer : public app::ApplicationBase } } - m_PreviousFrameTimeStamp = steady_clock::now(); + m_previousFrameTimeStamp = steady_clock::now(); #if WITH_NRD - if (m_NRD && m_NRD->GetDenoiser() != m_ui.denoisingMethod) - m_NRD = nullptr; // need to create a new one + if (m_nrd && m_nrd->GetDenoiser() != m_ui.denoisingMethod) + m_nrd = nullptr; // need to create a new one #endif if (m_ui.resetISContext) @@ -970,7 +899,7 @@ class SceneRenderer : public app::ApplicationBase GetDevice()->waitForIdle(); m_isContext = nullptr; - m_RtxdiResources = nullptr; + m_rtxdiResources = nullptr; m_ui.resetISContext = false; } @@ -979,7 +908,7 @@ class SceneRenderer : public app::ApplicationBase LoadEnvironmentMap(); } - m_Scene->RefreshSceneGraph(GetFrameIndex()); + m_scene->RefreshSceneGraph(GetFrameIndex()); const auto& fbinfo = framebuffer->getFramebufferInfo(); uint32_t renderWidth = fbinfo.width; @@ -992,7 +921,7 @@ class SceneRenderer : public app::ApplicationBase SetupView(renderWidth, renderHeight, activeCamera); SetupRenderPasses(renderWidth, renderHeight, exposureResetRequired); if (!m_ui.freezeRegirPosition) - m_RegirCenter = m_Camera.GetPosition(); + m_regirCenter = m_camera.GetPosition(); UpdateReSTIRDIContextFromUI(); UpdateReGIRContextFromUI(); UpdateReSTIRGIContextFromUI(); @@ -1001,26 +930,26 @@ class SceneRenderer : public app::ApplicationBase m_ui.aaMode = AntiAliasingMode::TAA; #endif - m_GBufferPass->NextFrame(); - m_PostprocessGBufferPass->NextFrame(); - m_LightingPasses->NextFrame(); - m_ConfidencePass->NextFrame(); - m_CompositingPass->NextFrame(); - m_VisualizationPass->NextFrame(); - m_RenderTargets->NextFrame(); - m_GlassPass->NextFrame(); - m_Scene->NextFrame(); - m_DebugVizPasses->NextFrame(); + m_gBufferPass->NextFrame(); + m_postprocessGBufferPass->NextFrame(); + m_lightingPasses->NextFrame(); + m_confidencePass->NextFrame(); + m_compositingPass->NextFrame(); + m_visualizationPass->NextFrame(); + m_renderTargets->NextFrame(); + m_glassPass->NextFrame(); + m_scene->NextFrame(); + m_debugVizPasses->NextFrame(); // Advance the TAA jitter offset at half frame rate if accumulation is used with // checkerboard rendering. Otherwise, the jitter pattern resonates with the checkerboard, // and stipple patterns appear in the accumulated results. - if (!((m_ui.aaMode == AntiAliasingMode::Accumulation) && (m_isContext->getReSTIRDIContext().getStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) && (GetFrameIndex() & 1))) + if (!((m_ui.aaMode == AntiAliasingMode::Accumulation) && (m_isContext->GetReSTIRDIContext().GetStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) && (GetFrameIndex() & 1))) { - m_TemporalAntiAliasingPass->AdvanceFrame(); + m_temporalAntiAliasingPass->AdvanceFrame(); } - bool cameraIsStatic = m_PreviousViewValid && m_View.GetViewMatrix() == m_ViewPrevious.GetViewMatrix(); + bool cameraIsStatic = m_previousViewValid && m_view.GetViewMatrix() == m_viewPrevious.GetViewMatrix(); if (cameraIsStatic && (m_ui.aaMode == AntiAliasingMode::Accumulation) && !m_ui.resetAccumulation) { m_ui.numAccumulatedFrames += 1; @@ -1028,22 +957,22 @@ class SceneRenderer : public app::ApplicationBase if (m_ui.framesToAccumulate > 0) m_ui.numAccumulatedFrames = std::min(m_ui.numAccumulatedFrames, m_ui.framesToAccumulate); - m_Profiler->EnableAccumulation(true); + m_profiler->EnableAccumulation(true); } else { m_ui.numAccumulatedFrames = 1; - m_Profiler->EnableAccumulation(m_ui.animationFrame.has_value()); + m_profiler->EnableAccumulation(m_ui.animationFrame.has_value()); } float accumulationWeight = 1.f / (float)m_ui.numAccumulatedFrames; - m_Profiler->ResolvePreviousFrame(); + m_profiler->ResolvePreviousFrame(); - int materialIndex = m_Profiler->GetMaterialReadback(); + int materialIndex = m_profiler->GetMaterialReadback(); if (materialIndex >= 0) { - for (const auto& material : m_Scene->GetSceneGraph()->GetMaterials()) + for (const auto& material : m_scene->GetSceneGraph()->GetMaterials()) { if (material->materialID == materialIndex) { @@ -1055,30 +984,30 @@ class SceneRenderer : public app::ApplicationBase if (m_ui.environmentMapIndex >= 0) { - if (m_EnvironmentMap) + if (m_environmentMap) { - m_EnvironmentLight->textureIndex = m_EnvironmentMap->bindlessDescriptor.Get(); - const auto& textureDesc = m_EnvironmentMap->texture->getDesc(); - m_EnvironmentLight->textureSize = uint2(textureDesc.width, textureDesc.height); + m_environmentLight->textureIndex = m_environmentMap->bindlessDescriptor.Get(); + const auto& textureDesc = m_environmentMap->texture->getDesc(); + m_environmentLight->textureSize = uint2(textureDesc.width, textureDesc.height); } else { - m_EnvironmentLight->textureIndex = m_RenderEnvironmentMapPass->GetTextureIndex(); - const auto& textureDesc = m_RenderEnvironmentMapPass->GetTexture()->getDesc(); - m_EnvironmentLight->textureSize = uint2(textureDesc.width, textureDesc.height); + m_environmentLight->textureIndex = m_renderEnvironmentMapPass->GetTextureIndex(); + const auto& textureDesc = m_renderEnvironmentMapPass->GetTexture()->getDesc(); + m_environmentLight->textureSize = uint2(textureDesc.width, textureDesc.height); } - m_EnvironmentLight->radianceScale = ::exp2f(m_ui.environmentIntensityBias); - m_EnvironmentLight->rotation = m_ui.environmentRotation / 360.f; // +/- 0.5 - m_SunLight->irradiance = (m_ui.environmentMapIndex > 0) ? 0.f : 1.f; + m_environmentLight->radianceScale = ::exp2f(m_ui.environmentIntensityBias); + m_environmentLight->rotation = m_ui.environmentRotation / 360.f; // +/- 0.5 + m_sunLight->irradiance = (m_ui.environmentMapIndex > 0) ? 0.f : 1.f; } else { - m_EnvironmentLight->textureIndex = -1; - m_SunLight->irradiance = 0.f; + m_environmentLight->textureIndex = -1; + m_sunLight->irradiance = 0.f; } #if WITH_NRD - if (!(m_NRD && m_NRD->IsAvailable())) + if (!(m_nrd && m_nrd->IsAvailable())) m_ui.enableDenoiser = false; uint32_t denoiserMode = (m_ui.enableDenoiser) @@ -1089,86 +1018,86 @@ class SceneRenderer : public app::ApplicationBase uint32_t denoiserMode = DENOISER_MODE_OFF; #endif - m_CommandList->open(); + m_commandList->open(); - m_Profiler->BeginFrame(m_CommandList); + m_profiler->BeginFrame(m_commandList); - AssignIesProfiles(m_CommandList); - m_Scene->RefreshBuffers(m_CommandList, GetFrameIndex()); - m_RtxdiResources->InitializeNeighborOffsets(m_CommandList, m_isContext->getNeighborOffsetCount()); + AssignIesProfiles(m_commandList); + m_scene->RefreshBuffers(m_commandList, GetFrameIndex()); + m_rtxdiResources->InitializeNeighborOffsets(m_commandList, m_isContext->GetNeighborOffsetCount()); - if (m_FramesSinceAnimation < 2) + if (m_framesSinceAnimation < 2) { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::TlasUpdate); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::TlasUpdate); - m_Scene->UpdateSkinnedMeshBLASes(m_CommandList, GetFrameIndex()); - m_Scene->BuildTopLevelAccelStruct(m_CommandList); + m_scene->UpdateSkinnedMeshBLASes(m_commandList, GetFrameIndex()); + m_scene->BuildTopLevelAccelStruct(m_commandList); } - m_CommandList->compactBottomLevelAccelStructs(); + m_commandList->compactBottomLevelAccelStructs(); if (m_ui.environmentMapDirty) { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::EnvironmentMap); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::EnvironmentMap); if (m_ui.environmentMapIndex == 0) { donut::render::SkyParameters params; - m_RenderEnvironmentMapPass->Render(m_CommandList, *m_SunLight, params); + m_renderEnvironmentMapPass->Render(m_commandList, *m_sunLight, params); } - m_EnvironmentMapPdfMipmapPass->Process(m_CommandList); + m_environmentMapPdfMipmapPass->Process(m_commandList); m_ui.environmentMapDirty = 0; } - nvrhi::utils::ClearColorAttachment(m_CommandList, framebuffer, 0, nvrhi::Color(0.f)); + nvrhi::utils::ClearColorAttachment(m_commandList, framebuffer, 0, nvrhi::Color(0.f)); { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::GBufferFill); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::GBufferFill); GBufferSettings gbufferSettings = m_ui.gbufferSettings; - float upscalingLodBias = ::log2f(m_View.GetViewport().width() / m_UpscaledView.GetViewport().width()); + float upscalingLodBias = ::log2f(m_view.GetViewport().width() / m_upscaledView.GetViewport().width()); gbufferSettings.textureLodBias += upscalingLodBias; if (m_ui.rasterizeGBuffer) - m_RasterizedGBufferPass->Render(m_CommandList, m_View, m_ViewPrevious, *m_RenderTargets, m_ui.gbufferSettings); + m_rasterizedGBufferPass->Render(m_commandList, m_view, m_viewPrevious, *m_renderTargets, m_ui.gbufferSettings); else - m_GBufferPass->Render(m_CommandList, m_View, m_ViewPrevious, m_ui.gbufferSettings); + m_gBufferPass->Render(m_commandList, m_view, m_viewPrevious, m_ui.gbufferSettings); - m_PostprocessGBufferPass->Render(m_CommandList, m_View); + m_postprocessGBufferPass->Render(m_commandList, m_view); } // The light indexing members of frameParameters are written by PrepareLightsPass below - rtxdi::ReSTIRDIContext& restirDIContext = m_isContext->getReSTIRDIContext(); - restirDIContext.setFrameIndex(effectiveFrameIndex); - m_isContext->getReSTIRGIContext().setFrameIndex(effectiveFrameIndex); + rtxdi::ReSTIRDIContext& restirDIContext = m_isContext->GetReSTIRDIContext(); + restirDIContext.SetFrameIndex(effectiveFrameIndex); + m_isContext->GetReSTIRGIContext().SetFrameIndex(effectiveFrameIndex); { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::MeshProcessing); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::MeshProcessing); - RTXDI_LightBufferParameters lightBufferParams = m_PrepareLightsPass->Process( - m_CommandList, + RTXDI_LightBufferParameters lightBufferParams = m_prepareLightsPass->Process( + m_commandList, restirDIContext, - m_Scene->GetSceneGraph()->GetLights(), - m_EnvironmentMapPdfMipmapPass != nullptr && m_ui.environmentMapImportanceSampling); - m_isContext->setLightBufferParams(lightBufferParams); + m_scene->GetSceneGraph()->GetLights(), + m_environmentMapPdfMipmapPass != nullptr && m_ui.environmentMapImportanceSampling); + m_isContext->SetLightBufferParams(lightBufferParams); - auto initialSamplingParams = restirDIContext.getInitialSamplingParameters(); + auto initialSamplingParams = restirDIContext.GetInitialSamplingParameters(); initialSamplingParams.environmentMapImportanceSampling = lightBufferParams.environmentLightParams.lightPresent; m_ui.restirDI.initialSamplingParams.environmentMapImportanceSampling = initialSamplingParams.environmentMapImportanceSampling; - restirDIContext.setInitialSamplingParameters(initialSamplingParams); + restirDIContext.SetInitialSamplingParameters(initialSamplingParams); } if (IsLocalLightPowerRISEnabled()) { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::LocalLightPdfMap); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::LocalLightPdfMap); - m_LocalLightPdfMipmapPass->Process(m_CommandList); + m_localLightPdfMipmapPass->Process(m_commandList); } #if WITH_NRD - if (restirDIContext.getStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) + if (restirDIContext.GetStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off) { m_ui.reblurSettings.checkerboardMode = nrd::CheckerboardMode::BLACK; m_ui.relaxSettings.checkerboardMode = nrd::CheckerboardMode::BLACK; @@ -1194,7 +1123,7 @@ class SceneRenderer : public app::ApplicationBase if (lightingSettings.denoiserMode == DENOISER_MODE_OFF) lightingSettings.enableGradients = false; - const bool checkerboard = restirDIContext.getStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off; + const bool checkerboard = restirDIContext.GetStaticParameters().CheckerboardSamplingMode != rtxdi::CheckerboardMode::Off; bool enableDirectReStirPass = m_ui.directLightingMode == DirectLightingMode::ReStir; bool enableBrdfAndIndirectPass = m_ui.directLightingMode == DirectLightingMode::Brdf || m_ui.indirectLightingMode != IndirectLightingMode::None; @@ -1202,9 +1131,9 @@ class SceneRenderer : public app::ApplicationBase // When indirect lighting is enabled, we don't want ReSTIR to be the NRD front-end, // it should just write out the raw color data. - ReSTIRDI_ShadingParameters restirDIShadingParams = m_isContext->getReSTIRDIContext().getShadingParameters(); + ReSTIRDI_ShadingParameters restirDIShadingParams = m_isContext->GetReSTIRDIContext().GetShadingParameters(); restirDIShadingParams.enableDenoiserInputPacking = !enableIndirect; - m_isContext->getReSTIRDIContext().setShadingParameters(restirDIShadingParams); + m_isContext->GetReSTIRDIContext().SetShadingParameters(restirDIShadingParams); if (!enableDirectReStirPass) { @@ -1217,45 +1146,45 @@ class SceneRenderer : public app::ApplicationBase if (enableDirectReStirPass || enableIndirect) { - m_LightingPasses->PrepareForLightSampling(m_CommandList, + m_lightingPasses->PrepareForLightSampling(m_commandList, *m_isContext, - m_View, m_ViewPrevious, + m_view, m_viewPrevious, lightingSettings, /* enableAccumulation = */ m_ui.aaMode == AntiAliasingMode::Accumulation); } if (enableDirectReStirPass) { - m_CommandList->clearTextureFloat(m_RenderTargets->Gradients, nvrhi::AllSubresources, nvrhi::Color(0.f)); + m_commandList->clearTextureFloat(m_renderTargets->Gradients, nvrhi::AllSubresources, nvrhi::Color(0.f)); - m_LightingPasses->RenderDirectLighting(m_CommandList, + m_lightingPasses->RenderDirectLighting(m_commandList, restirDIContext, - m_View, + m_view, lightingSettings); // Post-process the gradients into a confidence buffer usable by NRD if (lightingSettings.enableGradients) { - m_FilterGradientsPass->Render(m_CommandList, m_View, checkerboard); - m_ConfidencePass->Render(m_CommandList, m_View, lightingSettings.gradientLogDarknessBias, lightingSettings.gradientSensitivity, lightingSettings.confidenceHistoryLength, checkerboard); + m_filterGradientsPass->Render(m_commandList, m_view, checkerboard); + m_confidencePass->Render(m_commandList, m_view, lightingSettings.gradientLogDarknessBias, lightingSettings.gradientSensitivity, lightingSettings.confidenceHistoryLength, checkerboard); } } if (enableBrdfAndIndirectPass) { - ReSTIRDI_ShadingParameters restirDIShadingParams = m_isContext->getReSTIRDIContext().getShadingParameters(); + restirDIShadingParams = m_isContext->GetReSTIRDIContext().GetShadingParameters(); restirDIShadingParams.enableDenoiserInputPacking = true; - m_isContext->getReSTIRDIContext().setShadingParameters(restirDIShadingParams); + m_isContext->GetReSTIRDIContext().SetShadingParameters(restirDIShadingParams); bool enableReSTIRGI = m_ui.indirectLightingMode == IndirectLightingMode::ReStirGI; - m_LightingPasses->RenderBrdfRays( - m_CommandList, + m_lightingPasses->RenderBrdfRays( + m_commandList, *m_isContext, - m_View, m_ViewPrevious, + m_view, m_viewPrevious, lightingSettings, m_ui.gbufferSettings, - *m_EnvironmentLight, + *m_environmentLight, /* enableIndirect = */ enableIndirect, /* enableAdditiveBlend = */ enableDirectReStirPass, /* enableEmissiveSurfaces = */ m_ui.directLightingMode == DirectLightingMode::Brdf, @@ -1268,60 +1197,60 @@ class SceneRenderer : public app::ApplicationBase // It's a weird mode but it can be selected from the UI. if (!enableDirectReStirPass && !enableBrdfAndIndirectPass) { - m_CommandList->clearTextureFloat(m_RenderTargets->DiffuseLighting, nvrhi::AllSubresources, nvrhi::Color(0.f)); - m_CommandList->clearTextureFloat(m_RenderTargets->SpecularLighting, nvrhi::AllSubresources, nvrhi::Color(0.f)); + m_commandList->clearTextureFloat(m_renderTargets->DiffuseLighting, nvrhi::AllSubresources, nvrhi::Color(0.f)); + m_commandList->clearTextureFloat(m_renderTargets->SpecularLighting, nvrhi::AllSubresources, nvrhi::Color(0.f)); } #if WITH_NRD if (m_ui.enableDenoiser) { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::Denoising); - m_CommandList->beginMarker("Denoising"); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::Denoising); + m_commandList->beginMarker("Denoising"); const void* methodSettings = (m_ui.denoisingMethod == nrd::Denoiser::RELAX_DIFFUSE_SPECULAR) ? (void*)&m_ui.relaxSettings : (void*)&m_ui.reblurSettings; - m_NRD->RunDenoiserPasses(m_CommandList, *m_RenderTargets, m_View, m_ViewPrevious, GetFrameIndex(), lightingSettings.enableGradients, methodSettings, m_ui.debug); + m_nrd->RunDenoiserPasses(m_commandList, *m_renderTargets, m_view, m_viewPrevious, GetFrameIndex(), lightingSettings.enableGradients, methodSettings, m_ui.debug); - m_CommandList->endMarker(); + m_commandList->endMarker(); } #endif - m_CompositingPass->Render( - m_CommandList, - m_View, - m_ViewPrevious, + m_compositingPass->Render( + m_commandList, + m_view, + m_viewPrevious, denoiserMode, checkerboard, m_ui, - *m_EnvironmentLight); + *m_environmentLight); if (m_ui.gbufferSettings.enableTransparentGeometry) { - ProfilerScope scope(*m_Profiler, m_CommandList, ProfilerSection::Glass); + ProfilerScope scope(*m_profiler, m_commandList, ProfilerSection::Glass); - m_GlassPass->Render(m_CommandList, m_View, - *m_EnvironmentLight, + m_glassPass->Render(m_commandList, m_view, + *m_environmentLight, m_ui.gbufferSettings.normalMapScale, m_ui.gbufferSettings.enableMaterialReadback, m_ui.gbufferSettings.materialReadbackPosition); } - Resolve(m_CommandList, accumulationWeight); + Resolve(m_commandList, accumulationWeight); if (m_ui.enableBloom) { #if WITH_DLSS // Use the unresolved image for bloom when DLSS is active because DLSS can modify HDR values significantly and add bloom flicker. nvrhi::ITexture* bloomSource = (m_ui.aaMode == AntiAliasingMode::DLSS && m_ui.resolutionScale == 1.f) - ? m_RenderTargets->HdrColor - : m_RenderTargets->ResolvedColor; + ? m_renderTargets->HdrColor + : m_renderTargets->ResolvedColor; #else nvrhi::ITexture* bloomSource = m_RenderTargets->ResolvedColor; #endif - m_BloomPass->Render(m_CommandList, m_RenderTargets->ResolvedFramebuffer, m_UpscaledView, bloomSource, 32.f, 0.005f); + m_bloomPass->Render(m_commandList, m_renderTargets->ResolvedFramebuffer, m_upscaledView, bloomSource, 32.f, 0.005f); } // Reference image functionality: @@ -1336,7 +1265,7 @@ class SceneRenderer : public app::ApplicationBase // When the user clicks the "Store" button, copy the ResolvedColor texture into ReferenceColor. if (m_ui.storeReferenceImage) { - m_CommandList->copyTexture(m_RenderTargets->ReferenceColor, nvrhi::TextureSlice(), m_RenderTargets->ResolvedColor, nvrhi::TextureSlice()); + m_commandList->copyTexture(m_renderTargets->ReferenceColor, nvrhi::TextureSlice(), m_renderTargets->ResolvedColor, nvrhi::TextureSlice()); m_ui.storeReferenceImage = false; m_ui.referenceImageCaptured = true; } @@ -1346,12 +1275,12 @@ class SceneRenderer : public app::ApplicationBase if (m_ui.referenceImageSplit > 0.f) { engine::BlitParameters blitParams; - blitParams.sourceTexture = m_RenderTargets->ReferenceColor; + blitParams.sourceTexture = m_renderTargets->ReferenceColor; blitParams.sourceBox.m_maxs = float2(m_ui.referenceImageSplit, 1.f); - blitParams.targetFramebuffer = m_RenderTargets->ResolvedFramebuffer->GetFramebuffer(nvrhi::AllSubresources); + blitParams.targetFramebuffer = m_renderTargets->ResolvedFramebuffer->GetFramebuffer(nvrhi::AllSubresources); blitParams.targetBox = blitParams.sourceBox; blitParams.sampler = engine::BlitSampler::Point; - m_CommonPasses->BlitTexture(m_CommandList, blitParams, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, blitParams, &m_bindingCache); } } @@ -1370,11 +1299,11 @@ class SceneRenderer : public app::ApplicationBase ToneMappingParams.eyeAdaptationSpeedDown = 0.f; } - m_ToneMappingPass->SimpleRender(m_CommandList, ToneMappingParams, m_UpscaledView, m_RenderTargets->ResolvedColor); + m_toneMappingPass->SimpleRender(m_commandList, ToneMappingParams, m_upscaledView, m_renderTargets->ResolvedColor); } else { - m_CommonPasses->BlitTexture(m_CommandList, m_RenderTargets->LdrFramebuffer->GetFramebuffer(m_UpscaledView), m_RenderTargets->ResolvedColor, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, m_renderTargets->LdrFramebuffer->GetFramebuffer(m_upscaledView), m_renderTargets->ResolvedColor, &m_bindingCache); } if (m_ui.visualizationMode != VIS_MODE_NONE) @@ -1395,24 +1324,24 @@ class SceneRenderer : public app::ApplicationBase case VIS_MODE_RESERVOIR_WEIGHT: case VIS_MODE_RESERVOIR_M: - inputBufferIndex = m_LightingPasses->GetOutputReservoirBufferIndex(); + inputBufferIndex = m_lightingPasses->GetOutputReservoirBufferIndex(); haveSignal = m_ui.directLightingMode == DirectLightingMode::ReStir; break; case VIS_MODE_GI_WEIGHT: case VIS_MODE_GI_M: - inputBufferIndex = m_LightingPasses->GetGIOutputReservoirBufferIndex(); + inputBufferIndex = m_lightingPasses->GetGIOutputReservoirBufferIndex(); haveSignal = m_ui.indirectLightingMode == IndirectLightingMode::ReStirGI; break; } if (haveSignal) { - m_VisualizationPass->Render( - m_CommandList, - m_RenderTargets->LdrFramebuffer->GetFramebuffer(m_UpscaledView), - m_View, - m_UpscaledView, + m_visualizationPass->Render( + m_commandList, + m_renderTargets->LdrFramebuffer->GetFramebuffer(m_upscaledView), + m_view, + m_upscaledView, *m_isContext, inputBufferIndex, m_ui.visualizationMode, @@ -1423,66 +1352,66 @@ class SceneRenderer : public app::ApplicationBase switch (m_ui.debugRenderOutputBuffer) { case DebugRenderOutput::LDRColor: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->LdrColor, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->LdrColor, &m_bindingCache); break; case DebugRenderOutput::Depth: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->Depth, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->Depth, &m_bindingCache); break; case GBufferDiffuseAlbedo: - m_DebugVizPasses->RenderUnpackedDiffuseAlbeo(m_CommandList, m_UpscaledView); - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DebugColor, &m_BindingCache); + m_debugVizPasses->RenderUnpackedDiffuseAlbeo(m_commandList, m_upscaledView); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DebugColor, &m_bindingCache); break; case GBufferSpecularRough: - m_DebugVizPasses->RenderUnpackedSpecularRoughness(m_CommandList, m_UpscaledView); - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DebugColor, &m_BindingCache); + m_debugVizPasses->RenderUnpackedSpecularRoughness(m_commandList, m_upscaledView); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DebugColor, &m_bindingCache); break; case GBufferNormals: - m_DebugVizPasses->RenderUnpackedNormals(m_CommandList, m_UpscaledView); - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DebugColor, &m_BindingCache); + m_debugVizPasses->RenderUnpackedNormals(m_commandList, m_upscaledView); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DebugColor, &m_bindingCache); break; case GBufferGeoNormals: - m_DebugVizPasses->RenderUnpackedGeoNormals(m_CommandList, m_UpscaledView); - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DebugColor, &m_BindingCache); + m_debugVizPasses->RenderUnpackedGeoNormals(m_commandList, m_upscaledView); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DebugColor, &m_bindingCache); break; case GBufferEmissive: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->GBufferEmissive, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->GBufferEmissive, &m_bindingCache); break; case DiffuseLighting: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DiffuseLighting, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DiffuseLighting, &m_bindingCache); break; case SpecularLighting: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->SpecularLighting, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->SpecularLighting, &m_bindingCache); break; case DenoisedDiffuseLighting: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DenoisedDiffuseLighting, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DenoisedDiffuseLighting, &m_bindingCache); break; case DenoisedSpecularLighting: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DenoisedSpecularLighting, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DenoisedSpecularLighting, &m_bindingCache); break; case RestirLuminance: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->RestirLuminance, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->RestirLuminance, &m_bindingCache); break; case PrevRestirLuminance: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->PrevRestirLuminance, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->PrevRestirLuminance, &m_bindingCache); break; case DiffuseConfidence: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->DiffuseConfidence, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->DiffuseConfidence, &m_bindingCache); break; case SpecularConfidence: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->SpecularConfidence, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->SpecularConfidence, &m_bindingCache); break; case MotionVectors: - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->MotionVectors, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->MotionVectors, &m_bindingCache); } - m_Profiler->EndFrame(m_CommandList); + m_profiler->EndFrame(m_commandList); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); - if (!m_args.saveFrameFileName.empty() && m_RenderFrameIndex == m_args.saveFrameIndex) + if (!m_args.saveFrameFileName.empty() && m_renderFrameIndex == m_args.saveFrameIndex) { - bool success = SaveTexture(GetDevice(), m_RenderTargets->LdrColor, m_args.saveFrameFileName.c_str()); + bool success = SaveTexture(GetDevice(), m_renderTargets->LdrColor, m_args.saveFrameFileName.c_str()); g_ExitCode = success ? 0 : 1; @@ -1492,15 +1421,86 @@ class SceneRenderer : public app::ApplicationBase m_ui.gbufferSettings.enableMaterialReadback = false; if (m_ui.enableAnimations) - m_FramesSinceAnimation = 0; + m_framesSinceAnimation = 0; else - m_FramesSinceAnimation++; + m_framesSinceAnimation++; - m_ViewPrevious = m_View; - m_PreviousViewValid = true; + m_viewPrevious = m_view; + m_previousViewValid = true; m_ui.resetAccumulation = false; - ++m_RenderFrameIndex; + ++m_renderFrameIndex; } + +private: + nvrhi::CommandListHandle m_commandList; + + nvrhi::BindingLayoutHandle m_bindlessLayout; + + std::shared_ptr m_rootFs; + std::shared_ptr m_shaderFactory; + std::shared_ptr m_scene; + std::shared_ptr m_descriptorTableManager; + std::unique_ptr m_toneMappingPass; + std::unique_ptr m_temporalAntiAliasingPass; + std::unique_ptr m_bloomPass; + std::shared_ptr m_renderTargets; + app::FirstPersonCamera m_camera; + engine::PlanarView m_view; + engine::PlanarView m_viewPrevious; + engine::PlanarView m_upscaledView; + std::shared_ptr m_sunLight; + std::shared_ptr m_environmentLight; + std::shared_ptr m_environmentMap; + engine::BindingCache m_bindingCache; + + std::unique_ptr m_isContext; + std::unique_ptr m_gBufferPass; + std::unique_ptr m_rasterizedGBufferPass; + std::unique_ptr m_postprocessGBufferPass; + std::unique_ptr m_glassPass; + std::unique_ptr m_filterGradientsPass; + std::unique_ptr m_confidencePass; + std::unique_ptr m_compositingPass; + std::unique_ptr m_accumulationPass; + std::unique_ptr m_prepareLightsPass; + std::unique_ptr m_renderEnvironmentMapPass; + std::unique_ptr m_environmentMapPdfMipmapPass; + std::unique_ptr m_localLightPdfMipmapPass; + std::unique_ptr m_lightingPasses; + std::unique_ptr m_visualizationPass; + std::unique_ptr m_rtxdiResources; + std::unique_ptr m_iesProfileLoader; + std::shared_ptr m_profiler; + std::unique_ptr m_debugVizPasses; + + uint32_t m_renderFrameIndex = 0; + +#if WITH_NRD + std::unique_ptr m_nrd; +#endif + +#if WITH_DLSS + std::unique_ptr m_dlss; +#endif + + UIData& m_ui; + CommandLineArguments& m_args; + uint m_framesSinceAnimation = 0; + bool m_previousViewValid = false; + time_point m_previousFrameTimeStamp; + + std::vector> m_iesProfiles; + + dm::float3 m_regirCenter; + + enum class FrameStepMode + { + Disabled, + Wait, + Step + }; + + FrameStepMode m_frameStepMode = FrameStepMode::Disabled; }; #if defined(_WIN32) && !defined(IS_CONSOLE_APP) diff --git a/minimal/shaders/CMakeLists.txt b/Samples/MinimalSample/Shaders/CMakeLists.txt similarity index 57% rename from minimal/shaders/CMakeLists.txt rename to Samples/MinimalSample/Shaders/CMakeLists.txt index e69ad2e..a5167e4 100644 --- a/minimal/shaders/CMakeLists.txt +++ b/Samples/MinimalSample/Shaders/CMakeLists.txt @@ -1,10 +1,38 @@ include("${DONUT_PATH}/compileshaders.cmake") -file(GLOB shaders "*.hlsl" "*.hlsli" "*.h" "../rtxdi-runtime/shaders/*.hlsl" "../rtxdi-runtime/include/*.hlsli") +file(GLOB shaders "*.hlsl" "*.hlsli" "*.h") +set(shaders + RtxdiApplicationBridge/RAB_Buffers.hlsli + RtxdiApplicationBridge/RAB_LightInfo.hlsli + RtxdiApplicationBridge/RAB_LightSample.hlsli + RtxdiApplicationBridge/RAB_LightSampling.hlsli + RtxdiApplicationBridge/RAB_Material.hlsli + RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli + RtxdiApplicationBridge/RAB_RayPayload.hlsli + RtxdiApplicationBridge/RAB_RTShaders.hlsli + RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli + RtxdiApplicationBridge/RAB_Surface.hlsli + RtxdiApplicationBridge/RAB_VisibilityTest.hlsli + RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli + GBufferHelpers.hlsli + HelperFunctions.hlsli + PrepareLights.hlsl + PrimaryRays.hlsli + Render.hlsl + SceneGeometry.hlsli + ShaderParameters.h + TriangleLight.hlsli) -set(project minimal-sample) +# Organize MSVS filters (the little folders in the solution explorer) to match the folder structure +foreach(source IN LISTS shaders) + get_filename_component(source_path "${source}" PATH) + string(REPLACE "/" "\\" source_path_msvc "${source_path}") + source_group("${source_path_msvc}" FILES "${source}") +endforeach() + +set(project MinimalSample) set(folder "RTXDI SDK") -set(shaders_target minimal-sample-shaders) +set(shaders_target MinimalSampleShaders) add_custom_target(${shaders_target} DEPENDS ShaderMake @@ -25,7 +53,7 @@ if (DONUT_WITH_DX12) --binaryBlob --outputExt .bin -I ${DONUT_SHADER_INCLUDE_DIR} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../rtxdi-runtime/include + -I ${RTXDI_RUNTIME_INCLUDE_PATH} ${USE_API_OPTION} --relaxedInclude "../Types.h" --compiler ${DXC_PATH}) @@ -45,7 +73,7 @@ if (DONUT_WITH_VULKAN) --binaryBlob --outputExt .bin -I ${DONUT_SHADER_INCLUDE_DIR} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../rtxdi-runtime/include + -I ${RTXDI_RUNTIME_INCLUDE_PATH} ${USE_API_OPTION} --relaxedInclude "../Types.h" -D SPIRV diff --git a/minimal/shaders/GBufferHelpers.hlsli b/Samples/MinimalSample/Shaders/GBufferHelpers.hlsli similarity index 96% rename from minimal/shaders/GBufferHelpers.hlsli rename to Samples/MinimalSample/Shaders/GBufferHelpers.hlsli index cfffc92..c594c60 100644 --- a/minimal/shaders/GBufferHelpers.hlsli +++ b/Samples/MinimalSample/Shaders/GBufferHelpers.hlsli @@ -8,6 +8,9 @@ # license agreement from NVIDIA CORPORATION is strictly prohibited. **************************************************************************/ +#ifndef G_BUFFER_HELPERS_HLSLI +#define G_BUFFER_HELPERS_HLSLI + RayDesc setupPrimaryRay(uint2 pixelPosition, PlanarViewConstants view) { float2 uv = (float2(pixelPosition) + 0.5) * view.viewportSizeInv; @@ -67,3 +70,5 @@ float3 viewDepthToWorldPos( viewPos.xyz *= viewDepth; return mul(viewPos, view.matViewToWorld).xyz; } + +#endif // G_BUFFER_HELPERS_HLSLI diff --git a/minimal/shaders/HelperFunctions.hlsli b/Samples/MinimalSample/Shaders/HelperFunctions.hlsli similarity index 98% rename from minimal/shaders/HelperFunctions.hlsli rename to Samples/MinimalSample/Shaders/HelperFunctions.hlsli index 6fb2a3f..cdbe696 100644 --- a/minimal/shaders/HelperFunctions.hlsli +++ b/Samples/MinimalSample/Shaders/HelperFunctions.hlsli @@ -12,7 +12,7 @@ #define HELPER_FUNCTIONS_HLSLI #include -#include +#include struct RandomSamplerState { diff --git a/minimal/shaders/PrepareLights.hlsl b/Samples/MinimalSample/Shaders/PrepareLights.hlsl similarity index 97% rename from minimal/shaders/PrepareLights.hlsl rename to Samples/MinimalSample/Shaders/PrepareLights.hlsl index 7f9c12b..ac9bed1 100644 --- a/minimal/shaders/PrepareLights.hlsl +++ b/Samples/MinimalSample/Shaders/PrepareLights.hlsl @@ -10,10 +10,12 @@ #pragma pack_matrix(row_major) +#include "RtxdiApplicationBridge/RAB_LightInfo.hlsli" + #include -#include +#include #include -#include +#include #include "ShaderParameters.h" VK_PUSH_CONSTANT ConstantBuffer g_Const : register(b0); @@ -165,7 +167,7 @@ void main(uint dispatchThreadId : SV_DispatchThreadID, uint groupThreadId : SV_G triLight.edge2 = positions[2] - positions[0]; triLight.radiance = radiance; - lightInfo = triLight.Store(); + lightInfo = Store(triLight); } uint lightBufferPtr = task.lightBufferOffset + triangleIdx; diff --git a/minimal/shaders/PrimaryRays.hlsli b/Samples/MinimalSample/Shaders/PrimaryRays.hlsli similarity index 94% rename from minimal/shaders/PrimaryRays.hlsli rename to Samples/MinimalSample/Shaders/PrimaryRays.hlsli index 5526c40..2d996c3 100644 --- a/minimal/shaders/PrimaryRays.hlsli +++ b/Samples/MinimalSample/Shaders/PrimaryRays.hlsli @@ -8,6 +8,8 @@ # license agreement from NVIDIA CORPORATION is strictly prohibited. **************************************************************************/ +#include "GBufferHelpers.hlsli" + struct PrimarySurfaceOutput { RAB_Surface surface; @@ -70,9 +72,9 @@ PrimarySurfaceOutput TracePrimaryRay(int2 pixelPosition) result.surface.worldPos = mul(gs.instance.transform, float4(gs.objectSpacePosition, 1.0)).xyz; result.surface.normal = ms.shadingNormal; result.surface.geoNormal = gs.flatNormal; - result.surface.diffuseAlbedo = ms.diffuseAlbedo; - result.surface.specularF0 = ms.specularF0; - result.surface.roughness = ms.roughness; + result.surface.material.diffuseAlbedo = ms.diffuseAlbedo; + result.surface.material.specularF0 = ms.specularF0; + result.surface.material.roughness = ms.roughness; result.surface.viewDir = -ray.Direction; result.surface.diffuseProbability = getSurfaceDiffuseProbability(result.surface); result.emissiveColor = ms.emissiveColor; diff --git a/minimal/shaders/Render.hlsl b/Samples/MinimalSample/Shaders/Render.hlsl similarity index 95% rename from minimal/shaders/Render.hlsl rename to Samples/MinimalSample/Shaders/Render.hlsl index 90440ea..aa6eb76 100644 --- a/minimal/shaders/Render.hlsl +++ b/Samples/MinimalSample/Shaders/Render.hlsl @@ -11,10 +11,10 @@ #pragma pack_matrix(row_major) #define RTXDI_ENABLE_PRESAMPLING 0 -#include "RtxdiApplicationBridge.hlsli" +#include "RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" -#include -#include +#include +#include #include "PrimaryRays.hlsli" @@ -30,8 +30,8 @@ void main(uint2 pixelPosition : SV_DispatchThreadID) u_GBufferDepth[pixelPosition] = primary.surface.viewDepth; u_GBufferNormals[pixelPosition] = ndirToOctUnorm32(primary.surface.normal); u_GBufferGeoNormals[pixelPosition] = ndirToOctUnorm32(primary.surface.geoNormal); - u_GBufferDiffuseAlbedo[pixelPosition] = Pack_R11G11B10_UFLOAT(primary.surface.diffuseAlbedo); - u_GBufferSpecularRough[pixelPosition] = Pack_R8G8B8A8_Gamma_UFLOAT(float4(primary.surface.specularF0, primary.surface.roughness)); + u_GBufferDiffuseAlbedo[pixelPosition] = Pack_R11G11B10_UFLOAT(primary.surface.material.diffuseAlbedo); + u_GBufferSpecularRough[pixelPosition] = Pack_R8G8B8A8_Gamma_UFLOAT(float4(primary.surface.material.specularF0, primary.surface.material.roughness)); RTXDI_DIReservoir reservoir = RTXDI_EmptyDIReservoir(); diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli new file mode 100644 index 0000000..43c2a1e --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli @@ -0,0 +1,54 @@ +#ifndef RAB_BUFFER_HLSLI +#define RAB_BUFFER_HLSLI + +#include "Rtxdi/RtxdiParameters.h" + +// Previous G-buffer resources +Texture2D t_PrevGBufferDepth : register(t0); +Texture2D t_PrevGBufferNormals : register(t1); +Texture2D t_PrevGBufferGeoNormals : register(t2); +Texture2D t_PrevGBufferDiffuseAlbedo : register(t3); +Texture2D t_PrevGBufferSpecularRough : register(t4); + +// Scene resources +RaytracingAccelerationStructure SceneBVH : register(t30); +StructuredBuffer t_InstanceData : register(t32); +StructuredBuffer t_GeometryData : register(t33); +StructuredBuffer t_MaterialConstants : register(t34); + +// RTXDI resources +StructuredBuffer t_LightDataBuffer : register(t20); +Buffer t_NeighborOffsets : register(t21); +StructuredBuffer t_GeometryInstanceToLight : register(t22); + +// Screen-sized UAVs +RWStructuredBuffer u_LightReservoirs : register(u0); +RWTexture2D u_ShadingOutput : register(u1); +RWTexture2D u_GBufferDepth : register(u2); +RWTexture2D u_GBufferNormals : register(u3); +RWTexture2D u_GBufferGeoNormals : register(u4); +RWTexture2D u_GBufferDiffuseAlbedo : register(u5); +RWTexture2D u_GBufferSpecularRough : register(u6); + +// Other +ConstantBuffer g_Const : register(b0); +SamplerState s_MaterialSampler : register(s0); + +#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs +#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets + +// Translate the light index between the current and previous frame. +// Do nothing as our lights are static in this sample. +int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) +{ + return int(lightIndex); +} + +// Load the packed light information from the buffer. +// Ignore the previousFrame parameter as our lights are static in this sample. +RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) +{ + return t_LightDataBuffer[index]; +} + +#endif // RAB_BUFFER_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli new file mode 100644 index 0000000..67b6582 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli @@ -0,0 +1,40 @@ +#ifndef RAB_LIGHT_INFO_HLSLI +#define RAB_LIGHT_INFO_HLSLI + +#include "../ShaderParameters.h" +#include "../TriangleLight.hlsli" + +RAB_LightInfo RAB_EmptyLightInfo() +{ + return (RAB_LightInfo)0; +} + +RAB_LightInfo RAB_LoadCompactLightInfo(uint linearIndex) +{ + return RAB_EmptyLightInfo(); +} + +bool RAB_StoreCompactLightInfo(uint linearIndex, RAB_LightInfo lightInfo) +{ + return true; +} + +float RAB_GetLightTargetPdfForVolume(RAB_LightInfo light, float3 volumeCenter, float volumeRadius) +{ + return 0.0; +} + +RAB_LightInfo Store(TriangleLight triLight) +{ + RAB_LightInfo lightInfo = (RAB_LightInfo)0; + + lightInfo.radiance = Pack_R16G16B16A16_FLOAT(float4(triLight.radiance, 0)); + lightInfo.center = triLight.base + (triLight.edge1 + triLight.edge2) / 3.0; + lightInfo.direction1 = ndirToOctUnorm32(normalize(triLight.edge1)); + lightInfo.direction2 = ndirToOctUnorm32(normalize(triLight.edge2)); + lightInfo.scalars = f32tof16(length(triLight.edge1)) | (f32tof16(length(triLight.edge2)) << 16); + + return lightInfo; +} + +#endif // RAB_LIGHT_INFO_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli new file mode 100644 index 0000000..c12bb52 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli @@ -0,0 +1,44 @@ +#ifndef RTXDI_RAB_LIGHT_INFO_HLSLI +#define RTXDI_RAB_LIGHT_INFO_HLSLI + +#include "../TriangleLight.hlsli" + +struct RAB_LightSample +{ + float3 position; + float3 normal; + float3 radiance; + float solidAnglePdf; +}; + +RAB_LightSample RAB_EmptyLightSample() +{ + return (RAB_LightSample)0; +} + +bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) +{ + return false; +} + +float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) +{ + return lightSample.solidAnglePdf; +} + +RAB_LightSample CalcSample(TriangleLight triLight, in const float2 random, in const float3 viewerPosition) +{ + RAB_LightSample result; + + float3 bary = sampleTriangle(random); + result.position = triLight.base + triLight.edge1 * bary.y + triLight.edge2 * bary.z; + result.normal = triLight.normal; + + result.solidAnglePdf = triLight.calcSolidAnglePdf(viewerPosition, result.position, result.normal); + + result.radiance = triLight.radiance; + + return result; +} + +#endif // RTXDI_RAB_LIGHT_INFO_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli new file mode 100644 index 0000000..00732ac --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli @@ -0,0 +1,146 @@ +#ifndef RAB_LIGHT_SAMPLING_HLSLI +#define RAB_LIGHT_SAMPLING_HLSLI + +#include "RAB_Material.hlsli" +#include "RAB_RayPayload.hlsli" +#include "RAB_Surface.hlsli" + +float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) +{ + return float2(0.0, 0.0); +} + +float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) +{ + // No Environment sampling + return 0; +} + +float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) +{ + // Uniform pdf + return 1.0 / g_Const.lightBufferParams.localLightBufferRegion.numLights; +} + +float3 RAB_GetReflectedRadianceForSurface(float3 incomingRadianceLocation, float3 incomingRadiance, RAB_Surface surface) +{ + return float3(0.0, 0.0, 0.0); +} + +float RAB_GetReflectedLuminanceForSurface(float3 incomingRadianceLocation, float3 incomingRadiance, RAB_Surface surface) +{ + return 0.0; +} + +// Evaluate the surface BRDF and compute the weighted reflected radiance for the given light sample +float3 ShadeSurfaceWithLightSample(RAB_LightSample lightSample, RAB_Surface surface) +{ + // Ignore invalid light samples + if (lightSample.solidAnglePdf <= 0) + return 0; + + float3 L = normalize(lightSample.position - surface.worldPos); + + // Ignore light samples that are below the geometric surface (but above the normal mapped surface) + if (dot(L, surface.geoNormal) <= 0) + return 0; + + + float3 V = surface.viewDir; + + // Evaluate the BRDF + float diffuse = Lambert(surface.normal, -L); + float3 specular = GGX_times_NdotL(V, L, surface.normal, max(RAB_GetMaterial(surface).roughness, kMinRoughness), RAB_GetMaterial(surface).specularF0); + + float3 reflectedRadiance = lightSample.radiance * (diffuse * surface.material.diffuseAlbedo + specular); + + return reflectedRadiance / lightSample.solidAnglePdf; +} + +// Compute the target PDF (p-hat) for the given light sample relative to a surface +float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) +{ + // Second-best implementation: the PDF is proportional to the reflected radiance. + // The best implementation would be taking visibility into account, + // but that would be prohibitively expensive. + return calcLuminance(ShadeSurfaceWithLightSample(lightSample, surface)); +} + +float RAB_GetGISampleTargetPdfForSurface(float3 samplePosition, float3 sampleRadiance, RAB_Surface surface) +{ + return 0.0; +} + +void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, + out float3 o_lightDir, + out float o_lightDistance) +{ + float3 toLight = lightSample.position - surface.worldPos; + o_lightDistance = length(toLight); + o_lightDir = toLight / o_lightDistance; +} + +bool RTXDI_CompareRelativeDifference(float reference, float candidate, float threshold); + +float3 GetEnvironmentRadiance(float3 direction) +{ + return float3(0.0, 0.0, 0.0); +} + +bool IsComplexSurface(int2 pixelPosition, RAB_Surface surface) +{ + return true; +} + +uint getLightIndex(uint instanceID, uint geometryIndex, uint primitiveIndex) +{ + uint lightIndex = RTXDI_InvalidLightIndex; + InstanceData hitInstance = t_InstanceData[instanceID]; + uint geometryInstanceIndex = hitInstance.firstGeometryInstanceIndex + geometryIndex; + lightIndex = t_GeometryInstanceToLight[geometryInstanceIndex]; + if (lightIndex != RTXDI_InvalidLightIndex) + lightIndex += primitiveIndex; + return lightIndex; +} + +// Return true if anything was hit. If false, RTXDI will do environment map sampling +// o_lightIndex: If hit, must be a valid light index for RAB_LoadLightInfo, if no local light was hit, must be RTXDI_InvalidLightIndex +// randXY: The randXY that corresponds to the hit location and is the same used for RAB_SamplePolymorphicLight +bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, + out uint o_lightIndex, out float2 o_randXY) +{ + o_lightIndex = RTXDI_InvalidLightIndex; + o_randXY = 0; + + RayDesc ray; + ray.Origin = origin; + ray.Direction = direction; + ray.TMin = tMin; + ray.TMax = tMax; + + RayQuery rayQuery; + rayQuery.TraceRayInline(SceneBVH, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); + rayQuery.Proceed(); + + bool hitAnything = rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT; + if (hitAnything) + { + o_lightIndex = getLightIndex(rayQuery.CommittedInstanceID(), rayQuery.CommittedGeometryIndex(), rayQuery.CommittedPrimitiveIndex()); + if (o_lightIndex != RTXDI_InvalidLightIndex) + { + float2 hitUV = rayQuery.CommittedTriangleBarycentrics(); + o_randXY = randomFromBarycentric(hitUVToBarycentric(hitUV)); + } + } + + return hitAnything; +} + +// Compute the position on a triangle light given a pair of random numbers +RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) +{ + TriangleLight triLight = TriangleLight::Create(lightInfo); + return CalcSample(triLight, uv, surface.worldPos); +} + +#endif // RAB_LIGHT_SAMPLING_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Material.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Material.hlsli new file mode 100644 index 0000000..d76c629 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Material.hlsli @@ -0,0 +1,62 @@ +#ifndef RAB_MATERIAL_HLSLI +#define RAB_MATERIAL_HLSLI + +static const float kMinRoughness = 0.05f; + +struct RAB_Material +{ + float3 diffuseAlbedo; + float3 specularF0; + float roughness; +}; + +RAB_Material RAB_EmptyMaterial() +{ + RAB_Material material = (RAB_Material)0; + + return material; +} + +float3 GetDiffuseAlbedo(RAB_Material material) +{ + return float3(0.0, 0.0, 0.0); +} + +float3 GetSpecularF0(RAB_Material material) +{ + return float3(0.0, 0.0, 0.0); +} + +float GetRoughness(RAB_Material material) +{ + return 0.0; +} + +RAB_Material RAB_GetGBufferMaterial( + int2 pixelPosition, + PlanarViewConstants view, + RWTexture2D diffuseAlbedoTexture, + RWTexture2D specularRoughTexture) +{ + RAB_Material material = RAB_EmptyMaterial(); + + if (any(pixelPosition >= view.viewportSize)) + return material; + + material.diffuseAlbedo = Unpack_R11G11B10_UFLOAT(diffuseAlbedoTexture[pixelPosition]).rgb; + float4 specularRough = Unpack_R8G8B8A8_Gamma_UFLOAT(specularRoughTexture[pixelPosition]); + material.roughness = specularRough.a; + material.specularF0 = specularRough.rgb; + + return material; +} + +// Compare the materials of two surfaces to improve resampling quality. +// Just say that everything is similar for simplicity. +bool RAB_AreMaterialsSimilar(RAB_Material a, RAB_Material b) +{ + return true; +} + + +#endif // RAB_MATERIAL_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli new file mode 100644 index 0000000..eb30a7f --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli @@ -0,0 +1,30 @@ +#ifndef RAB_RT_SHADERS_HLSLI +#define RAB_RT_SHADERS_HLSLI + +// #include "RAB_RayPayload.hlsli" +// +// #if !USE_RAY_QUERY +// struct RayAttributes +// { +// float2 uv; +// }; +// +// [shader("miss")] +// void Miss(inout RayPayload payload : SV_RayPayload) +// { +// } +// +// [shader("closesthit")] +// void ClosestHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) +// { +// +// } +// +// [shader("anyhit")] +// void AnyHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) +// { +// +// } +// #endif + +#endif // RAB_RT_SHADERS_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli new file mode 100644 index 0000000..93f4022 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli @@ -0,0 +1,18 @@ +#ifndef RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI +#define RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI + +#include "../HelperFunctions.hlsli" + +typedef RandomSamplerState RAB_RandomSamplerState; + +RAB_RandomSamplerState RAB_InitRandomSampler(uint2 index, uint pass) +{ + return initRandomSampler(index, g_Const.frameIndex + pass * 13); +} + +float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) +{ + return sampleUniformRng(rng); +} + +#endif // RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli new file mode 100644 index 0000000..d721ea8 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli @@ -0,0 +1,9 @@ +#ifndef RAB_RAY_PAYLOAD_HLSLI +#define RAB_RAY_PAYLOAD_HLSLI + +struct RayPayload +{ + uint unused; +}; + +#endif // RAB_RAY_PAYLOAD_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli new file mode 100644 index 0000000..05dc43e --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli @@ -0,0 +1,18 @@ +#ifndef RAB_SPATIAL_HELPERS_HLSLI +#define RAB_SPATIAL_HELPERS_HLSLI + +// This function is called in the spatial resampling passes to make sure that +// the samples actually land on the screen and not outside of its boundaries. +// It can clamp the position or reflect it about the nearest screen edge. +// The simplest implementation will just return the input pixelPosition. +int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) +{ + return clamp(pixelPosition, 0, int2(g_Const.view.viewportSize) - 1); +} + +bool RAB_ValidateGISampleWithJacobian(inout float jacobian) +{ + return true; +} + +#endif // RAB_SPATIAL_HELPERS_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli new file mode 100644 index 0000000..da80123 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli @@ -0,0 +1,151 @@ +#ifndef RTXDI_RAB_SURFACE_HLSLI +#define RTXDI_RAB_SURFACE_HLSLI + +#include "../GBufferHelpers.hlsli" + +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_Material.hlsli" + +// A surface with enough information to evaluate BRDFs +struct RAB_Surface +{ + float3 worldPos; + float3 viewDir; + float viewDepth; + float3 normal; + float3 geoNormal; + float diffuseProbability; + RAB_Material material; +}; + +RAB_Surface RAB_EmptySurface() +{ + RAB_Surface surface = (RAB_Surface)0; + surface.viewDepth = BACKGROUND_DEPTH; + return surface; +} + +bool RAB_IsSurfaceValid(RAB_Surface surface) +{ + return surface.viewDepth != BACKGROUND_DEPTH; +} + +float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) +{ + return surface.worldPos; +} + +RAB_Material RAB_GetMaterial(RAB_Surface surface) +{ + return surface.material; +} + +float3 RAB_GetSurfaceNormal(RAB_Surface surface) +{ + return surface.normal; +} + +float RAB_GetSurfaceLinearDepth(RAB_Surface surface) +{ + return surface.viewDepth; +} + +float getSurfaceDiffuseProbability(RAB_Surface surface) +{ + RAB_Material material = RAB_GetMaterial(surface); + float diffuseWeight = calcLuminance(material.diffuseAlbedo); + float specularWeight = calcLuminance(Schlick_Fresnel(material.specularF0, dot(surface.viewDir, surface.normal))); + float sumWeights = diffuseWeight + specularWeight; + return sumWeights < 1e-7f ? 1.f : (diffuseWeight / sumWeights); +} + +// Load a sample from the previous G-buffer. +RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) +{ + RAB_Surface surface = RAB_EmptySurface(); + + // We do not have access to the current G-buffer in this sample because it's using + // a single render pass with a fused resampling kernel, so just return an invalid surface. + // This should never happen though, as the fused kernel doesn't call RAB_GetGBufferSurface(..., false) + if (!previousFrame) + return surface; + + const PlanarViewConstants view = g_Const.prevView; + + if (any(pixelPosition >= view.viewportSize)) + return surface; + + surface.viewDepth = t_PrevGBufferDepth[pixelPosition]; + + if(surface.viewDepth == BACKGROUND_DEPTH) + return surface; + + surface.normal = octToNdirUnorm32(t_PrevGBufferNormals[pixelPosition]); + surface.geoNormal = octToNdirUnorm32(t_PrevGBufferGeoNormals[pixelPosition]); + float4 specularRough = Unpack_R8G8B8A8_Gamma_UFLOAT(t_PrevGBufferSpecularRough[pixelPosition]); + surface.material = RAB_GetGBufferMaterial(pixelPosition, view, u_GBufferDiffuseAlbedo, u_GBufferSpecularRough); + surface.worldPos = viewDepthToWorldPos(view, pixelPosition, surface.viewDepth); + surface.viewDir = normalize(g_Const.view.cameraDirectionOrPosition.xyz - surface.worldPos); + surface.diffuseProbability = getSurfaceDiffuseProbability(surface); + + return surface; +} + +float3 worldToTangent(RAB_Surface surface, float3 w) +{ + // reconstruct tangent frame based off worldspace normal + // this is ok for isotropic BRDFs + // for anisotropic BRDFs, we need a user defined tangent + float3 tangent; + float3 bitangent; + ConstructONB(surface.normal, tangent, bitangent); + + return float3(dot(bitangent, w), dot(tangent, w), dot(surface.normal, w)); +} + +float3 tangentToWorld(RAB_Surface surface, float3 h) +{ + // reconstruct tangent frame based off worldspace normal + // this is ok for isotropic BRDFs + // for anisotropic BRDFs, we need a user defined tangent + float3 tangent; + float3 bitangent; + ConstructONB(surface.normal, tangent, bitangent); + + return bitangent * h.x + tangent * h.y + surface.normal * h.z; +} + +// Output an importanced sampled reflection direction from the BRDF given the view +// Return true if the returned direction is above the surface +bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) +{ + float3 rand; + rand.x = RAB_GetNextRandom(rng); + rand.y = RAB_GetNextRandom(rng); + rand.z = RAB_GetNextRandom(rng); + if (rand.x < surface.diffuseProbability) + { + float pdf; + float3 h = SampleCosHemisphere(rand.yz, pdf); + dir = tangentToWorld(surface, h); + } + else + { + float3 h = ImportanceSampleGGX(rand.yz, max(surface.material.roughness, kMinRoughness)); + dir = reflect(-surface.viewDir, tangentToWorld(surface, h)); + } + + return dot(surface.normal, dir) > 0.f; +} + +// Return PDF wrt solid angle for the BRDF in the given dir +float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) +{ + float cosTheta = saturate(dot(surface.normal, dir)); + float diffusePdf = cosTheta / M_PI; + float specularPdf = ImportanceSampleGGX_VNDF_PDF(max(surface.material.roughness, kMinRoughness), surface.normal, surface.viewDir, dir); + float pdf = cosTheta > 0.f ? lerp(specularPdf, diffusePdf, surface.diffuseProbability) : 0.f; + return pdf; +} + +#endif // RTXDI_RAB_SURFACE_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli new file mode 100644 index 0000000..d3d7dd7 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli @@ -0,0 +1,52 @@ +#ifndef RAB_VISIBILITY_TEST_HLSLI +#define RAB_VISIBILITY_TEST_HLSLI + +RayDesc setupVisibilityRay(RAB_Surface surface, RAB_LightSample lightSample, float offset = 0.001) +{ + float3 L = lightSample.position - surface.worldPos; + + RayDesc ray; + ray.TMin = offset; + ray.TMax = length(L) - offset; + ray.Direction = normalize(L); + ray.Origin = surface.worldPos; + + return ray; +} + +// Tests the visibility between a surface and a light sample. +// Returns true if there is nothing between them. +bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) +{ + RayDesc ray = setupVisibilityRay(surface, lightSample); + + RayQuery rayQuery; + + rayQuery.TraceRayInline(SceneBVH, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); + + rayQuery.Proceed(); + + bool visible = (rayQuery.CommittedStatus() == COMMITTED_NOTHING); + + return visible; +} + +// Tests the visibility between a surface and a light sample on the previous frame. +// Since the scene is static in this sample app, it's equivalent to RAB_GetConservativeVisibility. +bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, + RAB_LightSample lightSample) +{ + return RAB_GetConservativeVisibility(currentSurface, lightSample); +} + +bool RAB_GetConservativeVisibility(RAB_Surface surface, float3 samplePosition) +{ + return true; +} + +bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, float3 samplePosition) +{ + return true; +} + +#endif // RAB_VISIBILITY_TEST_HLSLI diff --git a/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli new file mode 100644 index 0000000..a47fc49 --- /dev/null +++ b/Samples/MinimalSample/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli @@ -0,0 +1,51 @@ +/*************************************************************************** + # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + # + # NVIDIA CORPORATION and its licensors retain all intellectual property + # and proprietary rights in and to this software, related documentation + # and any modifications thereto. Any use, reproduction, disclosure or + # distribution of this software and related documentation without an express + # license agreement from NVIDIA CORPORATION is strictly prohibited. + **************************************************************************/ + +/* +This header file is the bridge between the RTXDI resampling functions +and the application resources and parts of shader functionality. + +The RTXDI SDK provides the resampling logic, and the application provides +other necessary aspects: + - Material BRDF evaluation; + - Ray tracing and transparent/alpha-tested material processing; + - Light sampling functions and emission profiles. + +The structures and functions that are necessary for SDK operation +start with the RAB_ prefix (for RTXDI-Application Bridge). + +All structures defined here are opaque for the SDK, meaning that +it makes no assumptions about their contents, they are just passed +between the bridge functions. +*/ + +#ifndef RTXDI_APPLICATION_BRIDGE_HLSLI +#define RTXDI_APPLICATION_BRIDGE_HLSLI + +// See RtxdiApplicationBridge.hlsli in the full sample app for more information. +// This is a minimal viable implementation. + +#include "../ShaderParameters.h" +#include "../SceneGeometry.hlsli" + +#include "RAB_Buffers.hlsli" + +#include "RAB_LightInfo.hlsli" +#include "RAB_LightSample.hlsli" +#include "RAB_LightSampling.hlsli" +#include "RAB_Material.hlsli" +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_RayPayload.hlsli" +#include "RAB_RTShaders.hlsli" +#include "RAB_SpatialHelpers.hlsli" +#include "RAB_Surface.hlsli" +#include "RAB_VisibilityTest.hlsli" + +#endif // RTXDI_APPLICATION_BRIDGE_HLSLI diff --git a/shaders/SceneGeometry.hlsli b/Samples/MinimalSample/Shaders/SceneGeometry.hlsli similarity index 99% rename from shaders/SceneGeometry.hlsli rename to Samples/MinimalSample/Shaders/SceneGeometry.hlsli index f910659..29a0ab3 100644 --- a/shaders/SceneGeometry.hlsli +++ b/Samples/MinimalSample/Shaders/SceneGeometry.hlsli @@ -13,7 +13,7 @@ #include -#include +#include #include #include diff --git a/minimal/shaders/ShaderParameters.h b/Samples/MinimalSample/Shaders/ShaderParameters.h similarity index 97% rename from minimal/shaders/ShaderParameters.h rename to Samples/MinimalSample/Shaders/ShaderParameters.h index 06de21d..55f823b 100644 --- a/minimal/shaders/ShaderParameters.h +++ b/Samples/MinimalSample/Shaders/ShaderParameters.h @@ -13,7 +13,7 @@ #include #include -#include +#include #define RTXDI_GRID_BUILD_GROUP_SIZE 256 #define RTXDI_SCREEN_SPACE_GROUP_SIZE 8 diff --git a/minimal/shaders/Shaders.cfg b/Samples/MinimalSample/Shaders/Shaders.cfg similarity index 100% rename from minimal/shaders/Shaders.cfg rename to Samples/MinimalSample/Shaders/Shaders.cfg diff --git a/minimal/shaders/TriangleLight.hlsli b/Samples/MinimalSample/Shaders/TriangleLight.hlsli similarity index 67% rename from minimal/shaders/TriangleLight.hlsli rename to Samples/MinimalSample/Shaders/TriangleLight.hlsli index 5a00746..70613ed 100644 --- a/minimal/shaders/TriangleLight.hlsli +++ b/Samples/MinimalSample/Shaders/TriangleLight.hlsli @@ -12,15 +12,7 @@ #define TRIANGLE_LIGHT_HLSLI #include "HelperFunctions.hlsli" -#include - -struct RAB_LightSample -{ - float3 position; - float3 normal; - float3 radiance; - float solidAnglePdf; -}; +#include struct TriangleLight { @@ -33,21 +25,6 @@ struct TriangleLight // Interface methods - RAB_LightSample calcSample(in const float2 random, in const float3 viewerPosition) - { - RAB_LightSample result; - - float3 bary = sampleTriangle(random); - result.position = base + edge1 * bary.y + edge2 * bary.z; - result.normal = normal; - - result.solidAnglePdf = calcSolidAnglePdf(viewerPosition, result.position, result.normal); - - result.radiance = radiance; - - return result; - } - float calcSolidAnglePdf(in const float3 viewerPosition, in const float3 lightSamplePosition, in const float3 lightSampleNormal) @@ -90,18 +67,6 @@ struct TriangleLight return triLight; } - RAB_LightInfo Store() - { - RAB_LightInfo lightInfo = (RAB_LightInfo)0; - - lightInfo.radiance = Pack_R16G16B16A16_FLOAT(float4(radiance, 0)); - lightInfo.center = base + (edge1 + edge2) / 3.0; - lightInfo.direction1 = ndirToOctUnorm32(normalize(edge1)); - lightInfo.direction2 = ndirToOctUnorm32(normalize(edge2)); - lightInfo.scalars = f32tof16(length(edge1)) | (f32tof16(length(edge2)) << 16); - - return lightInfo; - } }; -#endif // TRIANGLE_LIGHT_HLSLI \ No newline at end of file +#endif // TRIANGLE_LIGHT_HLSLI diff --git a/minimal/src/CMakeLists.txt b/Samples/MinimalSample/Source/CMakeLists.txt similarity index 68% rename from minimal/src/CMakeLists.txt rename to Samples/MinimalSample/Source/CMakeLists.txt index ba2526b..44745ca 100644 --- a/minimal/src/CMakeLists.txt +++ b/Samples/MinimalSample/Source/CMakeLists.txt @@ -1,13 +1,13 @@ file(GLOB sources "*.cpp" "*.h") -set(project minimal-sample) +set(project MinimalSample) set(folder "RTXDI SDK") include(CMakeDependentOption) add_executable(${project} WIN32 ${sources}) -target_link_libraries(${project} donut_core donut_engine donut_app donut_render rtxdi-runtime cxxopts) -add_dependencies(${project} minimal-sample-shaders) +target_link_libraries(${project} donut_core donut_engine donut_app donut_render Rtxdi cxxopts) +add_dependencies(${project} MinimalSampleShaders) set_target_properties(${project} PROPERTIES FOLDER ${folder}) diff --git a/minimal/src/PrepareLightsPass.cpp b/Samples/MinimalSample/Source/PrepareLightsPass.cpp similarity index 79% rename from minimal/src/PrepareLightsPass.cpp rename to Samples/MinimalSample/Source/PrepareLightsPass.cpp index 30ad9a4..646c9d8 100644 --- a/minimal/src/PrepareLightsPass.cpp +++ b/Samples/MinimalSample/Source/PrepareLightsPass.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -32,11 +32,11 @@ PrepareLightsPass::PrepareLightsPass( std::shared_ptr commonPasses, std::shared_ptr scene, nvrhi::IBindingLayout* bindlessLayout) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) { nvrhi::BindingLayoutDesc bindingLayoutDesc; bindingLayoutDesc.visibility = nvrhi::ShaderType::Compute; @@ -50,19 +50,19 @@ PrepareLightsPass::PrepareLightsPass( nvrhi::BindingLayoutItem::Sampler(0) }; - m_BindingLayout = m_Device->createBindingLayout(bindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(bindingLayoutDesc); } void PrepareLightsPass::CreatePipeline() { donut::log::debug("Initializing PrepareLightsPass..."); - m_ComputeShader = m_ShaderFactory->CreateShader("app/PrepareLights.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/PrepareLights.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void PrepareLightsPass::CreateBindingSet(RtxdiResources& resources) @@ -72,15 +72,15 @@ void PrepareLightsPass::CreateBindingSet(RtxdiResources& resources) nvrhi::BindingSetItem::PushConstants(0, sizeof(PrepareLightsConstants)), nvrhi::BindingSetItem::StructuredBuffer_UAV(0, resources.LightDataBuffer), nvrhi::BindingSetItem::StructuredBuffer_SRV(0, resources.TaskBuffer), - nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(4, m_Scene->GetMaterialBuffer()), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_AnisotropicWrapSampler) + nvrhi::BindingSetItem::StructuredBuffer_SRV(2, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(3, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(4, m_scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_AnisotropicWrapSampler) }; - m_BindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); - m_TaskBuffer = resources.TaskBuffer; - m_GeometryInstanceToLightBuffer = resources.GeometryInstanceToLightBuffer; + m_bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); + m_taskBuffer = resources.TaskBuffer; + m_geometryInstanceToLightBuffer = resources.GeometryInstanceToLightBuffer; } void PrepareLightsPass::CountLightsInScene(uint32_t& numEmissiveMeshes, uint32_t& numEmissiveTriangles) @@ -88,7 +88,7 @@ void PrepareLightsPass::CountLightsInScene(uint32_t& numEmissiveMeshes, uint32_t numEmissiveMeshes = 0; numEmissiveTriangles = 0; - const auto& instances = m_Scene->GetSceneGraph()->GetMeshInstances(); + const auto& instances = m_scene->GetSceneGraph()->GetMeshInstances(); for (const auto& instance : instances) { for (const auto& geometry : instance->GetMesh()->geometries) @@ -109,9 +109,9 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process(nvrhi::ICommandList* comm std::vector tasks; uint32_t lightBufferOffset = 0; - std::vector geometryInstanceToLight(m_Scene->GetSceneGraph()->GetGeometryInstancesCount(), RTXDI_INVALID_LIGHT_INDEX); + std::vector geometryInstanceToLight(m_scene->GetSceneGraph()->GetGeometryInstancesCount(), RTXDI_INVALID_LIGHT_INDEX); - const auto& instances = m_Scene->GetSceneGraph()->GetMeshInstances(); + const auto& instances = m_scene->GetSceneGraph()->GetMeshInstances(); for (const auto& instance : instances) { const auto& mesh = instance->GetMesh(); @@ -142,7 +142,7 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process(nvrhi::ICommandList* comm } } - commandList->writeBuffer(m_GeometryInstanceToLightBuffer, geometryInstanceToLight.data(), geometryInstanceToLight.size() * sizeof(uint32_t)); + commandList->writeBuffer(m_geometryInstanceToLightBuffer, geometryInstanceToLight.data(), geometryInstanceToLight.size() * sizeof(uint32_t)); outLightBufferParams.localLightBufferRegion.firstLightIndex = 0; outLightBufferParams.localLightBufferRegion.numLights = lightBufferOffset; @@ -151,11 +151,11 @@ RTXDI_LightBufferParameters PrepareLightsPass::Process(nvrhi::ICommandList* comm outLightBufferParams.environmentLightParams.lightIndex = RTXDI_INVALID_LIGHT_INDEX; outLightBufferParams.environmentLightParams.lightPresent = false; - commandList->writeBuffer(m_TaskBuffer, tasks.data(), tasks.size() * sizeof(PrepareLightsTask)); + commandList->writeBuffer(m_taskBuffer, tasks.data(), tasks.size() * sizeof(PrepareLightsTask)); nvrhi::ComputeState state; - state.pipeline = m_ComputePipeline; - state.bindings = { m_BindingSet, m_Scene->GetDescriptorTable() }; + state.pipeline = m_computePipeline; + state.bindings = { m_bindingSet, m_scene->GetDescriptorTable() }; commandList->setComputeState(state); PrepareLightsConstants constants; diff --git a/minimal/src/PrepareLightsPass.h b/Samples/MinimalSample/Source/PrepareLightsPass.h similarity index 70% rename from minimal/src/PrepareLightsPass.h rename to Samples/MinimalSample/Source/PrepareLightsPass.h index 7f582c5..4fc9bfb 100644 --- a/minimal/src/PrepareLightsPass.h +++ b/Samples/MinimalSample/Source/PrepareLightsPass.h @@ -11,7 +11,7 @@ #pragma once #include -#include +#include #include @@ -27,22 +27,6 @@ class RtxdiResources; class PrepareLightsPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingLayoutHandle m_BindlessLayout; - - nvrhi::BufferHandle m_TaskBuffer; - nvrhi::BufferHandle m_GeometryInstanceToLightBuffer; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - public: PrepareLightsPass( nvrhi::IDevice* device, @@ -56,4 +40,20 @@ class PrepareLightsPass void CountLightsInScene(uint32_t& numEmissiveMeshes, uint32_t& numEmissiveTriangles); RTXDI_LightBufferParameters Process(nvrhi::ICommandList* commandList); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingLayoutHandle m_bindlessLayout; + + nvrhi::BufferHandle m_taskBuffer; + nvrhi::BufferHandle m_geometryInstanceToLightBuffer; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; }; diff --git a/minimal/src/RenderPass.cpp b/Samples/MinimalSample/Source/RenderPass.cpp similarity index 79% rename from minimal/src/RenderPass.cpp rename to Samples/MinimalSample/Source/RenderPass.cpp index 81bc102..f1a8c5a 100644 --- a/minimal/src/RenderPass.cpp +++ b/Samples/MinimalSample/Source/RenderPass.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include using namespace donut::math; #include "../shaders/ShaderParameters.h" @@ -32,11 +32,11 @@ RenderPass::RenderPass( std::shared_ptr scene, nvrhi::IBindingLayout* bindlessLayout ) - : m_Device(device) - , m_BindlessLayout(bindlessLayout) - , m_ShaderFactory(std::move(shaderFactory)) - , m_CommonPasses(std::move(commonPasses)) - , m_Scene(std::move(scene)) + : m_device(device) + , m_bindlessLayout(bindlessLayout) + , m_shaderFactory(std::move(shaderFactory)) + , m_commonPasses(std::move(commonPasses)) + , m_scene(std::move(scene)) { // The binding layout descriptor must match the binding set descriptor defined in CreateBindingSet(...) below @@ -71,9 +71,9 @@ RenderPass::RenderPass( nvrhi::BindingLayoutItem::Sampler(1), }; - m_BindingLayout = m_Device->createBindingLayout(globalBindingLayoutDesc); + m_bindingLayout = m_device->createBindingLayout(globalBindingLayoutDesc); - m_ConstantBuffer = m_Device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(ResamplingConstants), "ResamplingConstants", 16)); + m_constantBuffer = m_device->createBuffer(nvrhi::utils::CreateVolatileConstantBufferDesc(sizeof(ResamplingConstants), "ResamplingConstants", 16)); } void RenderPass::CreateBindingSet( @@ -97,9 +97,9 @@ void RenderPass::CreateBindingSet( nvrhi::BindingSetItem::Texture_SRV(4, currentFrame ? renderTargets.PrevGBufferSpecularRough : renderTargets.GBufferSpecularRough), nvrhi::BindingSetItem::RayTracingAccelStruct(30, topLevelAS), - nvrhi::BindingSetItem::StructuredBuffer_SRV(32, m_Scene->GetInstanceBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(33, m_Scene->GetGeometryBuffer()), - nvrhi::BindingSetItem::StructuredBuffer_SRV(34, m_Scene->GetMaterialBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(32, m_scene->GetInstanceBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(33, m_scene->GetGeometryBuffer()), + nvrhi::BindingSetItem::StructuredBuffer_SRV(34, m_scene->GetMaterialBuffer()), nvrhi::BindingSetItem::StructuredBuffer_SRV(20, resources.LightDataBuffer), nvrhi::BindingSetItem::TypedBuffer_SRV(21, resources.NeighborOffsetsBuffer), @@ -113,30 +113,30 @@ void RenderPass::CreateBindingSet( nvrhi::BindingSetItem::Texture_UAV(5, currentFrame ? renderTargets.GBufferDiffuseAlbedo : renderTargets.PrevGBufferDiffuseAlbedo), nvrhi::BindingSetItem::Texture_UAV(6, currentFrame ? renderTargets.GBufferSpecularRough : renderTargets.PrevGBufferSpecularRough), - nvrhi::BindingSetItem::ConstantBuffer(0, m_ConstantBuffer), - nvrhi::BindingSetItem::Sampler(0, m_CommonPasses->m_LinearWrapSampler), - nvrhi::BindingSetItem::Sampler(1, m_CommonPasses->m_LinearWrapSampler) + nvrhi::BindingSetItem::ConstantBuffer(0, m_constantBuffer), + nvrhi::BindingSetItem::Sampler(0, m_commonPasses->m_LinearWrapSampler), + nvrhi::BindingSetItem::Sampler(1, m_commonPasses->m_LinearWrapSampler) }; - const nvrhi::BindingSetHandle bindingSet = m_Device->createBindingSet(bindingSetDesc, m_BindingLayout); + const nvrhi::BindingSetHandle bindingSet = m_device->createBindingSet(bindingSetDesc, m_bindingLayout); if (currentFrame) - m_BindingSet = bindingSet; + m_bindingSet = bindingSet; else - m_PrevBindingSet = bindingSet; + m_prevBindingSet = bindingSet; } - m_LightReservoirBuffer = resources.LightReservoirBuffer; + m_lightReservoirBuffer = resources.LightReservoirBuffer; } void RenderPass::CreatePipeline() { - m_ComputeShader = m_ShaderFactory->CreateShader("app/Render.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); + m_computeShader = m_shaderFactory->CreateShader("app/Render.hlsl", "main", nullptr, nvrhi::ShaderType::Compute); nvrhi::ComputePipelineDesc pipelineDesc; - pipelineDesc.bindingLayouts = { m_BindingLayout, m_BindlessLayout }; - pipelineDesc.CS = m_ComputeShader; - m_ComputePipeline = m_Device->createComputePipeline(pipelineDesc); + pipelineDesc.bindingLayouts = { m_bindingLayout, m_bindlessLayout }; + pipelineDesc.CS = m_computeShader; + m_computePipeline = m_device->createComputePipeline(pipelineDesc); } void RenderPass::Render( @@ -148,7 +148,7 @@ void RenderPass::Render( const RTXDI_LightBufferParameters& lightBufferParams) { ResamplingConstants constants = {}; - constants.frameIndex = context.getFrameIndex(); + constants.frameIndex = context.GetFrameIndex(); view.FillPlanarViewConstants(constants.view); previousView.FillPlanarViewConstants(constants.prevView); @@ -157,21 +157,21 @@ void RenderPass::Render( constants.numInitialSamples = localSettings.numInitialSamples; constants.numInitialBRDFSamples = localSettings.numInitialBRDFSamples; constants.numSpatialSamples = localSettings.numSpatialSamples; - constants.restirDIReservoirBufferParams = context.getReservoirBufferParameters(); + constants.restirDIReservoirBufferParams = context.GetReservoirBufferParameters(); constants.lightBufferParams = lightBufferParams; - constants.runtimeParams.neighborOffsetMask = context.getStaticParameters().NeighborOffsetCount - 1; + constants.runtimeParams.neighborOffsetMask = context.GetStaticParameters().NeighborOffsetCount - 1; constants.runtimeParams.activeCheckerboardField = 0; - constants.inputBufferIndex = !(context.getFrameIndex() & 1); - constants.outputBufferIndex = context.getFrameIndex() & 1; + constants.inputBufferIndex = !(context.GetFrameIndex() & 1); + constants.outputBufferIndex = context.GetFrameIndex() & 1; - commandList->writeBuffer(m_ConstantBuffer, &constants, sizeof(constants)); + commandList->writeBuffer(m_constantBuffer, &constants, sizeof(constants)); commandList->beginMarker("Render"); nvrhi::ComputeState state; - state.bindings = { m_BindingSet, m_Scene->GetDescriptorTable() }; - state.pipeline = m_ComputePipeline; + state.bindings = { m_bindingSet, m_scene->GetDescriptorTable() }; + state.pipeline = m_computePipeline; commandList->setComputeState(state); commandList->dispatch( @@ -183,5 +183,5 @@ void RenderPass::Render( void RenderPass::NextFrame() { - std::swap(m_BindingSet, m_PrevBindingSet); + std::swap(m_bindingSet, m_prevBindingSet); } diff --git a/minimal/src/RenderPass.h b/Samples/MinimalSample/Source/RenderPass.h similarity index 76% rename from minimal/src/RenderPass.h rename to Samples/MinimalSample/Source/RenderPass.h index 33bc1c6..309e617 100644 --- a/minimal/src/RenderPass.h +++ b/Samples/MinimalSample/Source/RenderPass.h @@ -13,7 +13,7 @@ #include #include #include -#include "rtxdi/ReSTIRDIParameters.h" +#include "Rtxdi/DI/ReSTIRDIParameters.h" namespace donut::engine { @@ -36,23 +36,6 @@ struct ResamplingConstants; class RenderPass { -private: - nvrhi::DeviceHandle m_Device; - - nvrhi::ShaderHandle m_ComputeShader; - nvrhi::ComputePipelineHandle m_ComputePipeline; - - nvrhi::BindingLayoutHandle m_BindingLayout; - nvrhi::BindingLayoutHandle m_BindlessLayout; - nvrhi::BindingSetHandle m_BindingSet; - nvrhi::BindingSetHandle m_PrevBindingSet; - nvrhi::BufferHandle m_ConstantBuffer; - nvrhi::BufferHandle m_LightReservoirBuffer; - - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_CommonPasses; - std::shared_ptr m_Scene; - public: struct Settings { @@ -88,4 +71,21 @@ class RenderPass const RTXDI_LightBufferParameters& lightBufferParams); void NextFrame(); + +private: + nvrhi::DeviceHandle m_device; + + nvrhi::ShaderHandle m_computeShader; + nvrhi::ComputePipelineHandle m_computePipeline; + + nvrhi::BindingLayoutHandle m_bindingLayout; + nvrhi::BindingLayoutHandle m_bindlessLayout; + nvrhi::BindingSetHandle m_bindingSet; + nvrhi::BindingSetHandle m_prevBindingSet; + nvrhi::BufferHandle m_constantBuffer; + nvrhi::BufferHandle m_lightReservoirBuffer; + + std::shared_ptr m_shaderFactory; + std::shared_ptr m_commonPasses; + std::shared_ptr m_scene; }; diff --git a/minimal/src/RenderTargets.cpp b/Samples/MinimalSample/Source/RenderTargets.cpp similarity index 100% rename from minimal/src/RenderTargets.cpp rename to Samples/MinimalSample/Source/RenderTargets.cpp diff --git a/minimal/src/RenderTargets.h b/Samples/MinimalSample/Source/RenderTargets.h similarity index 100% rename from minimal/src/RenderTargets.h rename to Samples/MinimalSample/Source/RenderTargets.h diff --git a/minimal/src/RtxdiResources.cpp b/Samples/MinimalSample/Source/RtxdiResources.cpp similarity index 83% rename from minimal/src/RtxdiResources.cpp rename to Samples/MinimalSample/Source/RtxdiResources.cpp index 46cc681..b4ba81e 100644 --- a/minimal/src/RtxdiResources.cpp +++ b/Samples/MinimalSample/Source/RtxdiResources.cpp @@ -9,7 +9,7 @@ **************************************************************************/ #include "RtxdiResources.h" -#include +#include #include @@ -21,10 +21,11 @@ RtxdiResources::RtxdiResources( const rtxdi::ReSTIRDIContext& context, uint32_t maxEmissiveMeshes, uint32_t maxEmissiveTriangles, - uint32_t maxGeometryInstances) - : m_MaxEmissiveMeshes(maxEmissiveMeshes) - , m_MaxEmissiveTriangles(maxEmissiveTriangles) - , m_MaxGeometryInstances(maxGeometryInstances) + uint32_t maxGeometryInstances) : + m_neighborOffsetsInitialized(false), + m_maxEmissiveMeshes(maxEmissiveMeshes), + m_maxEmissiveTriangles(maxEmissiveTriangles), + m_maxGeometryInstances(maxGeometryInstances) { nvrhi::BufferDesc taskBufferDesc; taskBufferDesc.byteSize = sizeof(PrepareLightsTask) * maxEmissiveMeshes; @@ -56,7 +57,7 @@ RtxdiResources::RtxdiResources( nvrhi::BufferDesc neighborOffsetBufferDesc; - neighborOffsetBufferDesc.byteSize = context.getStaticParameters().NeighborOffsetCount * 2; + neighborOffsetBufferDesc.byteSize = context.GetStaticParameters().NeighborOffsetCount * 2; neighborOffsetBufferDesc.format = nvrhi::Format::RG8_SNORM; neighborOffsetBufferDesc.canHaveTypedViews = true; neighborOffsetBufferDesc.debugName = "NeighborOffsets"; @@ -66,7 +67,7 @@ RtxdiResources::RtxdiResources( nvrhi::BufferDesc lightReservoirBufferDesc; - lightReservoirBufferDesc.byteSize = sizeof(RTXDI_PackedDIReservoir) * context.getReservoirBufferParameters().reservoirArrayPitch * rtxdi::c_NumReSTIRDIReservoirBuffers; + lightReservoirBufferDesc.byteSize = sizeof(RTXDI_PackedDIReservoir) * context.GetReservoirBufferParameters().reservoirArrayPitch * rtxdi::c_NumReSTIRDIReservoirBuffers; lightReservoirBufferDesc.structStride = sizeof(RTXDI_PackedDIReservoir); lightReservoirBufferDesc.initialState = nvrhi::ResourceStates::UnorderedAccess; lightReservoirBufferDesc.keepInitialState = true; @@ -77,7 +78,7 @@ RtxdiResources::RtxdiResources( void RtxdiResources::InitializeNeighborOffsets(nvrhi::ICommandList* commandList, uint32_t neighborOffsetCount) { - if (m_NeighborOffsetsInitialized) + if (m_neighborOffsetsInitialized) return; std::vector offsets; @@ -87,5 +88,20 @@ void RtxdiResources::InitializeNeighborOffsets(nvrhi::ICommandList* commandList, commandList->writeBuffer(NeighborOffsetsBuffer, offsets.data(), offsets.size()); - m_NeighborOffsetsInitialized = true; + m_neighborOffsetsInitialized = true; +} + +uint32_t RtxdiResources::GetMaxEmissiveMeshes() const +{ + return m_maxEmissiveMeshes; +} + +uint32_t RtxdiResources::GetMaxEmissiveTriangles() const +{ + return m_maxEmissiveTriangles; +} + +uint32_t RtxdiResources::GetMaxGeometryInstances() const +{ + return m_maxGeometryInstances; } diff --git a/minimal/src/RtxdiResources.h b/Samples/MinimalSample/Source/RtxdiResources.h similarity index 75% rename from minimal/src/RtxdiResources.h rename to Samples/MinimalSample/Source/RtxdiResources.h index 2a024dd..d8161e8 100644 --- a/minimal/src/RtxdiResources.h +++ b/Samples/MinimalSample/Source/RtxdiResources.h @@ -19,12 +19,6 @@ namespace rtxdi class RtxdiResources { -private: - bool m_NeighborOffsetsInitialized = false; - uint32_t m_MaxEmissiveMeshes = 0; - uint32_t m_MaxEmissiveTriangles = 0; - uint32_t m_MaxGeometryInstances = 0; - public: nvrhi::BufferHandle TaskBuffer; nvrhi::BufferHandle LightDataBuffer; @@ -41,7 +35,13 @@ class RtxdiResources void InitializeNeighborOffsets(nvrhi::ICommandList* commandList, uint32_t neighborOffsetCount); - uint32_t GetMaxEmissiveMeshes() const { return m_MaxEmissiveMeshes; } - uint32_t GetMaxEmissiveTriangles() const { return m_MaxEmissiveTriangles; } - uint32_t GetMaxGeometryInstances() const { return m_MaxGeometryInstances; } + uint32_t GetMaxEmissiveMeshes() const; + uint32_t GetMaxEmissiveTriangles() const; + uint32_t GetMaxGeometryInstances() const; + +private: + bool m_neighborOffsetsInitialized; + uint32_t m_maxEmissiveMeshes; + uint32_t m_maxEmissiveTriangles; + uint32_t m_maxGeometryInstances; }; \ No newline at end of file diff --git a/minimal/src/SampleScene.cpp b/Samples/MinimalSample/Source/SampleScene.cpp similarity index 87% rename from minimal/src/SampleScene.cpp rename to Samples/MinimalSample/Source/SampleScene.cpp index dcbbf10..9ccf030 100644 --- a/minimal/src/SampleScene.cpp +++ b/Samples/MinimalSample/Source/SampleScene.cpp @@ -22,7 +22,7 @@ using namespace donut::math; #include "../shaders/ShaderParameters.h" -inline uint64_t advanceHeapPtr(uint64_t& heapPtr, const nvrhi::MemoryRequirements& memReq) +inline uint64_t AdvanceHeapPtr(uint64_t& heapPtr, const nvrhi::MemoryRequirements& memReq) { heapPtr = nvrhi::align(heapPtr, memReq.alignment); uint64_t current = heapPtr; @@ -79,7 +79,7 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) nvrhi::rt::AccelStructHandle as = device->createAccelStruct(blasDesc); - advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(as)); + AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(as)); mesh->accelStruct = as; } @@ -91,9 +91,9 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) tlasDesc.debugName = "TopLevelAS"; tlasDesc.buildFlags = nvrhi::rt::AccelStructBuildFlags::AllowUpdate; - m_TopLevelAS = device->createAccelStruct(tlasDesc); + m_topLevelAS = device->createAccelStruct(tlasDesc); - advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_TopLevelAS)); + AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_topLevelAS)); tlasDesc.debugName = "PrevTopLevelAS"; @@ -112,14 +112,14 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) if (!mesh->accelStruct) continue; - uint64_t heapOffset = advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(mesh->accelStruct)); + uint64_t heapOffset = AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(mesh->accelStruct)); device->bindAccelStructMemory(mesh->accelStruct, heap, heapOffset); } - uint64_t heapOffset = advanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_TopLevelAS)); + uint64_t heapOffset = AdvanceHeapPtr(heapSize, device->getAccelStructMemoryRequirements(m_topLevelAS)); - device->bindAccelStructMemory(m_TopLevelAS, heap, heapOffset); + device->bindAccelStructMemory(m_topLevelAS, heap, heapOffset); nvrhi::CommandListParameters clparams; @@ -153,9 +153,9 @@ void SampleScene::BuildMeshBLASes(nvrhi::IDevice* device) void SampleScene::BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList) { - m_TlasInstances.resize(GetSceneGraph()->GetMeshInstances().size()); + m_tlasInstances.resize(GetSceneGraph()->GetMeshInstances().size()); - nvrhi::rt::AccelStructBuildFlags buildFlags = m_CanUpdateTLAS + nvrhi::rt::AccelStructBuildFlags buildFlags = m_canUpdateTLAS ? nvrhi::rt::AccelStructBuildFlags::PerformUpdate : nvrhi::rt::AccelStructBuildFlags::None; @@ -168,7 +168,7 @@ void SampleScene::BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList) if (!mesh->accelStruct) continue; - nvrhi::rt::InstanceDesc& instanceDesc = m_TlasInstances[index++]; + nvrhi::rt::InstanceDesc& instanceDesc = m_tlasInstances[index++]; instanceDesc.instanceMask = 0; engine::SceneContentFlags contentFlags = instance->GetContentFlags(); @@ -197,6 +197,11 @@ void SampleScene::BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList) instanceDesc.instanceID = uint(instance->GetInstanceIndex()); } - commandList->buildTopLevelAccelStruct(m_TopLevelAS, m_TlasInstances.data(), m_TlasInstances.size(), buildFlags); - m_CanUpdateTLAS = true; + commandList->buildTopLevelAccelStruct(m_topLevelAS, m_tlasInstances.data(), m_tlasInstances.size(), buildFlags); + m_canUpdateTLAS = true; } + +nvrhi::rt::IAccelStruct* SampleScene::GetTopLevelAS() const +{ + return m_topLevelAS; +} \ No newline at end of file diff --git a/minimal/src/SampleScene.h b/Samples/MinimalSample/Source/SampleScene.h similarity index 77% rename from minimal/src/SampleScene.h rename to Samples/MinimalSample/Source/SampleScene.h index abca1ff..e39ad3a 100644 --- a/minimal/src/SampleScene.h +++ b/Samples/MinimalSample/Source/SampleScene.h @@ -14,19 +14,19 @@ class SampleScene : public donut::engine::Scene { -private: - nvrhi::rt::AccelStructHandle m_TopLevelAS; - std::vector m_TlasInstances; - - bool m_CanUpdateTLAS = false; - - double m_WallclockTime = 0; - public: using Scene::Scene; void BuildMeshBLASes(nvrhi::IDevice* device); void BuildTopLevelAccelStruct(nvrhi::ICommandList* commandList); - nvrhi::rt::IAccelStruct* GetTopLevelAS() const { return m_TopLevelAS; } + nvrhi::rt::IAccelStruct* GetTopLevelAS() const; + +private: + nvrhi::rt::AccelStructHandle m_topLevelAS; + std::vector m_tlasInstances; + + bool m_canUpdateTLAS = false; + + double m_wallclockTime = 0; }; diff --git a/minimal/src/UserInterface.cpp b/Samples/MinimalSample/Source/UserInterface.cpp similarity index 97% rename from minimal/src/UserInterface.cpp rename to Samples/MinimalSample/Source/UserInterface.cpp index 113e0df..66abb1a 100644 --- a/minimal/src/UserInterface.cpp +++ b/Samples/MinimalSample/Source/UserInterface.cpp @@ -41,7 +41,7 @@ UserInterface::UserInterface(app::DeviceManager* deviceManager, vfs::IFileSystem : ImGui_Renderer(deviceManager) , m_ui(ui) { - m_FontOpenSans = LoadFont(rootFS, "/media/fonts/OpenSans/OpenSans-Regular.ttf", 17.f); + m_fontOpenSans = CreateFontFromFile(rootFS, "/media/fonts/OpenSans/OpenSans-Regular.ttf", 17.f); } void UserInterface::buildUI() diff --git a/minimal/src/UserInterface.h b/Samples/MinimalSample/Source/UserInterface.h similarity index 92% rename from minimal/src/UserInterface.h rename to Samples/MinimalSample/Source/UserInterface.h index cc34ad9..a51cfa7 100644 --- a/minimal/src/UserInterface.h +++ b/Samples/MinimalSample/Source/UserInterface.h @@ -10,11 +10,11 @@ #pragma once +#include #include #include #include "RenderPass.h" - struct UIData { bool reloadShaders = false; @@ -24,16 +24,15 @@ struct UIData RenderPass::Settings lightingSettings; }; - class UserInterface : public donut::app::ImGui_Renderer { -private: - UIData& m_ui; - ImFont* m_FontOpenSans = nullptr; +public: + UserInterface(donut::app::DeviceManager* deviceManager, donut::vfs::IFileSystem& rootFS, UIData& ui); protected: void buildUI() override; -public: - UserInterface(donut::app::DeviceManager* deviceManager, donut::vfs::IFileSystem& rootFS, UIData& ui); +private: + UIData& m_ui; + std::shared_ptr m_fontOpenSans = nullptr; }; diff --git a/minimal/src/main.cpp b/Samples/MinimalSample/Source/main.cpp similarity index 68% rename from minimal/src/main.cpp rename to Samples/MinimalSample/Source/main.cpp index c5998f9..091e578 100644 --- a/minimal/src/main.cpp +++ b/Samples/MinimalSample/Source/main.cpp @@ -9,7 +9,7 @@ **************************************************************************/ // Include this first just to test the cleanliness -#include +#include #include #include @@ -48,55 +48,33 @@ using namespace std::chrono; class SceneRenderer : public app::ApplicationBase { -private: - nvrhi::CommandListHandle m_CommandList; - - nvrhi::BindingLayoutHandle m_BindlessLayout; - - std::shared_ptr m_RootFs; - std::shared_ptr m_ShaderFactory; - std::shared_ptr m_Scene; - std::shared_ptr m_DescriptorTableManager; - std::unique_ptr m_RenderTargets; - app::FirstPersonCamera m_Camera; - engine::PlanarView m_View; - engine::PlanarView m_ViewPrevious; - engine::BindingCache m_BindingCache; - - std::unique_ptr m_restirDIContext; - std::unique_ptr m_PrepareLightsPass; - std::unique_ptr m_RenderPass; - std::unique_ptr m_RtxdiResources; - - UIData& m_ui; - public: SceneRenderer(app::DeviceManager* deviceManager, UIData& ui) : ApplicationBase(deviceManager) - , m_BindingCache(deviceManager->GetDevice()) + , m_bindingCache(deviceManager->GetDevice()) , m_ui(ui) { } [[nodiscard]] std::shared_ptr GetShaderFactory() const { - return m_ShaderFactory; + return m_shaderFactory; } [[nodiscard]] std::shared_ptr GetRootFs() const { - return m_RootFs; + return m_rootFs; } bool Init() { - std::filesystem::path mediaPath = app::GetDirectoryWithExecutable().parent_path() / "rtxdi-assets"; + std::filesystem::path mediaPath = app::GetDirectoryWithExecutable().parent_path() / "Assets/Media"; if (!std::filesystem::exists(mediaPath)) { - mediaPath = mediaPath.parent_path().parent_path() / "rtxdi-assets"; + mediaPath = app::GetDirectoryWithExecutable().parent_path().parent_path() / "Assets/Media"; if (!std::filesystem::exists(mediaPath)) { - log::error("Couldn't locate the 'rtxdi-assets' folder."); + log::error("Couldn't locate the 'Assets/Media' folder."); return false; } } @@ -104,17 +82,17 @@ class SceneRenderer : public app::ApplicationBase std::filesystem::path frameworkShaderPath = app::GetDirectoryWithExecutable() / "shaders/framework" / app::GetShaderTypeName(GetDevice()->getGraphicsAPI()); std::filesystem::path appShaderPath = app::GetDirectoryWithExecutable() / "shaders/minimal-sample" / app::GetShaderTypeName(GetDevice()->getGraphicsAPI()); - log::debug("Mounting %s to %s", mediaPath.string().c_str(), "/rtxdi-assets"); + log::debug("Mounting %s to %s", mediaPath.string().c_str(), "/Assets/Media"); log::debug("Mounting %s to %s", frameworkShaderPath.string().c_str(), "/shaders/donut"); log::debug("Mounting %s to %s", appShaderPath.string().c_str(), "/shaders/app"); - m_RootFs = std::make_shared(); - m_RootFs->mount("/rtxdi-assets", mediaPath); - m_RootFs->mount("/shaders/donut", frameworkShaderPath); - m_RootFs->mount("/shaders/app", appShaderPath); + m_rootFs = std::make_shared(); + m_rootFs->mount("/Assets/Media", mediaPath); + m_rootFs->mount("/shaders/donut", frameworkShaderPath); + m_rootFs->mount("/shaders/app", appShaderPath); - m_ShaderFactory = std::make_shared(GetDevice(), m_RootFs, "/shaders"); - m_CommonPasses = std::make_shared(GetDevice(), m_ShaderFactory); + m_shaderFactory = std::make_shared(GetDevice(), m_rootFs, "/shaders"); + m_CommonPasses = std::make_shared(GetDevice(), m_shaderFactory); { nvrhi::BindlessLayoutDesc bindlessLayoutDesc; @@ -126,29 +104,29 @@ class SceneRenderer : public app::ApplicationBase }; bindlessLayoutDesc.visibility = nvrhi::ShaderType::All; bindlessLayoutDesc.maxCapacity = 1024; - m_BindlessLayout = GetDevice()->createBindlessLayout(bindlessLayoutDesc); + m_bindlessLayout = GetDevice()->createBindlessLayout(bindlessLayoutDesc); } - std::filesystem::path scenePath = "/rtxdi-assets/Arcade/Arcade.gltf"; + std::filesystem::path scenePath = "/Assets/Media/Arcade/Arcade.gltf"; - m_DescriptorTableManager = std::make_shared(GetDevice(), m_BindlessLayout); + m_descriptorTableManager = std::make_shared(GetDevice(), m_bindlessLayout); - m_TextureCache = std::make_shared(GetDevice(), m_RootFs, m_DescriptorTableManager); + m_TextureCache = std::make_shared(GetDevice(), m_rootFs, m_descriptorTableManager); m_TextureCache->SetInfoLogSeverity(donut::log::Severity::Debug); - m_Scene = std::make_shared(GetDevice(), *m_ShaderFactory, m_RootFs, m_TextureCache, m_DescriptorTableManager, nullptr); + m_scene = std::make_shared(GetDevice(), *m_shaderFactory, m_rootFs, m_TextureCache, m_descriptorTableManager, nullptr); SetAsynchronousLoadingEnabled(true); - BeginLoadingScene(m_RootFs, scenePath); + BeginLoadingScene(m_rootFs, scenePath); GetDeviceManager()->SetVsyncEnabled(true); - m_PrepareLightsPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_BindlessLayout); - m_RenderPass = std::make_unique(GetDevice(), m_ShaderFactory, m_CommonPasses, m_Scene, m_BindlessLayout); + m_prepareLightsPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_bindlessLayout); + m_renderPass = std::make_unique(GetDevice(), m_shaderFactory, m_CommonPasses, m_scene, m_bindlessLayout); LoadShaders(); - m_CommandList = GetDevice()->createCommandList(); + m_commandList = GetDevice()->createCommandList(); return true; } @@ -157,17 +135,17 @@ class SceneRenderer : public app::ApplicationBase { ApplicationBase::SceneLoaded(); - m_Scene->FinishedLoading(GetFrameIndex()); + m_scene->FinishedLoading(GetFrameIndex()); - m_Camera.LookAt(float3(-1.658f, 1.577f, 1.69f), float3(-0.9645f, 1.2672f, 1.0396f)); - m_Camera.SetMoveSpeed(3.f); + m_camera.LookAt(float3(-1.658f, 1.577f, 1.69f), float3(-0.9645f, 1.2672f, 1.0396f)); + m_camera.SetMoveSpeed(3.f); - m_Scene->BuildMeshBLASes(GetDevice()); + m_scene->BuildMeshBLASes(GetDevice()); - m_CommandList->open(); - m_Scene->BuildTopLevelAccelStruct(m_CommandList); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->open(); + m_scene->BuildTopLevelAccelStruct(m_commandList); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); GetDeviceManager()->SetVsyncEnabled(false); @@ -176,13 +154,13 @@ class SceneRenderer : public app::ApplicationBase void LoadShaders() const { - m_PrepareLightsPass->CreatePipeline(); - m_RenderPass->CreatePipeline(); + m_prepareLightsPass->CreatePipeline(); + m_renderPass->CreatePipeline(); } bool LoadScene(std::shared_ptr fs, const std::filesystem::path& sceneFileName) override { - if (m_Scene->Load(sceneFileName)) + if (m_scene->Load(sceneFileName)) { return true; } @@ -204,20 +182,20 @@ class SceneRenderer : public app::ApplicationBase return true; } - m_Camera.KeyboardUpdate(key, scancode, action, mods); + m_camera.KeyboardUpdate(key, scancode, action, mods); return true; } bool MousePosUpdate(double xpos, double ypos) override { - m_Camera.MousePosUpdate(xpos, ypos); + m_camera.MousePosUpdate(xpos, ypos); return true; } bool MouseButtonUpdate(int button, int action, int mods) override { - m_Camera.MouseButtonUpdate(button, action, mods); + m_camera.MouseButtonUpdate(button, action, mods); return true; } @@ -226,18 +204,18 @@ class SceneRenderer : public app::ApplicationBase if (m_ui.isLoading) return; - m_Camera.Animate(fElapsedTimeSeconds); + m_camera.Animate(fElapsedTimeSeconds); } void BackBufferResized(const uint32_t width, const uint32_t height, const uint32_t sampleCount) override { - if (m_RenderTargets && m_RenderTargets->Size.x == int(width) && m_RenderTargets->Size.y == int(height)) + if (m_renderTargets && m_renderTargets->Size.x == int(width) && m_renderTargets->Size.y == int(height)) return; - m_BindingCache.Clear(); - m_RenderTargets = nullptr; + m_bindingCache.Clear(); + m_renderTargets = nullptr; m_restirDIContext = nullptr; - m_RtxdiResources = nullptr; + m_rtxdiResources = nullptr; } void SetupView(const nvrhi::FramebufferInfoEx& fbinfo, uint effectiveFrameIndex) @@ -245,15 +223,15 @@ class SceneRenderer : public app::ApplicationBase nvrhi::Viewport windowViewport(float(fbinfo.width), float(fbinfo.height)); nvrhi::Viewport renderViewport = windowViewport; - m_View.SetViewport(renderViewport); - m_View.SetPixelOffset(0.f); + m_view.SetViewport(renderViewport); + m_view.SetPixelOffset(0.f); const float aspectRatio = windowViewport.width() / windowViewport.height(); - m_View.SetMatrices(m_Camera.GetWorldToViewMatrix(), perspProjD3DStyleReverse(radians(60.f), aspectRatio, 0.01f)); - m_View.UpdateCache(); + m_view.SetMatrices(m_camera.GetWorldToViewMatrix(), perspProjD3DStyleReverse(radians(60.f), aspectRatio, 0.01f)); + m_view.UpdateCache(); - if (m_ViewPrevious.GetViewExtent().width() == 0) - m_ViewPrevious = m_View; + if (m_viewPrevious.GetViewExtent().width() == 0) + m_viewPrevious = m_view; } void SetupRenderPasses(const nvrhi::FramebufferInfoEx& fbinfo) @@ -262,7 +240,7 @@ class SceneRenderer : public app::ApplicationBase { GetDevice()->waitForIdle(); - m_ShaderFactory->ClearCache(); + m_shaderFactory->ClearCache(); LoadShaders(); @@ -281,42 +259,42 @@ class SceneRenderer : public app::ApplicationBase m_restirDIContext = std::make_unique(contextParams); } - if (!m_RenderTargets) + if (!m_renderTargets) { - m_RenderTargets = std::make_unique(GetDevice(), int2(fbinfo.width, fbinfo.height)); + m_renderTargets = std::make_unique(GetDevice(), int2(fbinfo.width, fbinfo.height)); renderTargetsCreated = true; } - if (!m_RtxdiResources) + if (!m_rtxdiResources) { uint32_t numEmissiveMeshes, numEmissiveTriangles; - m_PrepareLightsPass->CountLightsInScene(numEmissiveMeshes, numEmissiveTriangles); - uint32_t numGeometryInstances = uint32_t(m_Scene->GetSceneGraph()->GetGeometryInstancesCount()); + m_prepareLightsPass->CountLightsInScene(numEmissiveMeshes, numEmissiveTriangles); + uint32_t numGeometryInstances = uint32_t(m_scene->GetSceneGraph()->GetGeometryInstancesCount()); - m_RtxdiResources = std::make_unique(GetDevice(), *m_restirDIContext, + m_rtxdiResources = std::make_unique(GetDevice(), *m_restirDIContext, numEmissiveMeshes, numEmissiveTriangles, numGeometryInstances); - m_PrepareLightsPass->CreateBindingSet(*m_RtxdiResources); + m_prepareLightsPass->CreateBindingSet(*m_rtxdiResources); rtxdiResourcesCreated = true; } if (renderTargetsCreated || rtxdiResourcesCreated) { - m_RenderPass->CreateBindingSet( - m_Scene->GetTopLevelAS(), - *m_RenderTargets, - *m_RtxdiResources); + m_renderPass->CreateBindingSet( + m_scene->GetTopLevelAS(), + *m_renderTargets, + *m_rtxdiResources); } } void RenderSplashScreen(nvrhi::IFramebuffer* framebuffer) override { - m_CommandList->open(); - nvrhi::utils::ClearColorAttachment(m_CommandList, framebuffer, 0, nvrhi::Color(0.f)); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->open(); + nvrhi::utils::ClearColorAttachment(m_commandList, framebuffer, 0, nvrhi::Color(0.f)); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); } void RenderScene(nvrhi::IFramebuffer* framebuffer) override @@ -329,40 +307,62 @@ class SceneRenderer : public app::ApplicationBase // Make sure that the passes and buffers are created and fit the current render size SetupRenderPasses(fbinfo); - m_CommandList->open(); + m_commandList->open(); // Compute transforms, update the scene representation on the GPU in case something's animated - m_Scene->Refresh(m_CommandList, GetFrameIndex()); + m_scene->Refresh(m_commandList, GetFrameIndex()); // Write the neighbor offset buffer data (only happens once) - m_RtxdiResources->InitializeNeighborOffsets(m_CommandList, m_restirDIContext->getStaticParameters().NeighborOffsetCount); + m_rtxdiResources->InitializeNeighborOffsets(m_commandList, m_restirDIContext->GetStaticParameters().NeighborOffsetCount); // The light indexing members of frameParameters are written by PrepareLightsPass below - m_restirDIContext->setFrameIndex(GetFrameIndex()); + m_restirDIContext->SetFrameIndex(GetFrameIndex()); // When the lights are static, there is no need to update them on every frame, // but it's simpler to do so. - RTXDI_LightBufferParameters lightBufferParams = m_PrepareLightsPass->Process(m_CommandList); + RTXDI_LightBufferParameters lightBufferParams = m_prepareLightsPass->Process(m_commandList); // Call the rendering pass - this includes primary rays, fused resampling, and shading - m_RenderPass->Render(m_CommandList, + m_renderPass->Render(m_commandList, *m_restirDIContext, - m_View, m_ViewPrevious, + m_view, m_viewPrevious, m_ui.lightingSettings, lightBufferParams); // Copy the render pass output to the swap chain - m_CommonPasses->BlitTexture(m_CommandList, framebuffer, m_RenderTargets->HdrColor, &m_BindingCache); + m_CommonPasses->BlitTexture(m_commandList, framebuffer, m_renderTargets->HdrColor, &m_bindingCache); - m_CommandList->close(); - GetDevice()->executeCommandList(m_CommandList); + m_commandList->close(); + GetDevice()->executeCommandList(m_commandList); // Swap the even and odd frame buffers - m_RenderPass->NextFrame(); - m_RenderTargets->NextFrame(); + m_renderPass->NextFrame(); + m_renderTargets->NextFrame(); - m_ViewPrevious = m_View; + m_viewPrevious = m_view; } + +private: + nvrhi::CommandListHandle m_commandList; + + nvrhi::BindingLayoutHandle m_bindlessLayout; + + std::shared_ptr m_rootFs; + std::shared_ptr m_shaderFactory; + std::shared_ptr m_scene; + std::shared_ptr m_descriptorTableManager; + std::unique_ptr m_renderTargets; + app::FirstPersonCamera m_camera; + engine::PlanarView m_view; + engine::PlanarView m_viewPrevious; + engine::BindingCache m_bindingCache; + + std::unique_ptr m_restirDIContext; + std::unique_ptr m_prepareLightsPass; + std::unique_ptr m_renderPass; + std::unique_ptr m_rtxdiResources; + + UIData& m_ui; }; void ProcessCommandLine(int argc, char** argv, app::DeviceCreationParameters& deviceParams, nvrhi::GraphicsAPI& api) diff --git a/rtxdi-runtime-shader-tests/CMakeLists.txt b/Support/Tests/RtxdiRuntimeShaderTests/CMakeLists.txt similarity index 51% rename from rtxdi-runtime-shader-tests/CMakeLists.txt rename to Support/Tests/RtxdiRuntimeShaderTests/CMakeLists.txt index f3ad747..1198b44 100644 --- a/rtxdi-runtime-shader-tests/CMakeLists.txt +++ b/Support/Tests/RtxdiRuntimeShaderTests/CMakeLists.txt @@ -1,7 +1,28 @@ -file(GLOB sources "*.cpp" "*.h" "*/*.cpp" "*/*.h") - -set(project rtxdi-runtime-shader-tests) +set(sources + Shaders/RtxdiApplicationBridge/RAB_Buffers.glsli + Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli + Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli + Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli + Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli + Shaders/RtxdiApplicationBridge/RAB_Material.hlsli + Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli + Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli + Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli + Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli + Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli + Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli + Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.glsli + Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli) + +# Organize MSVS filters (the little folders in the solution explorer) to match the folder structure +foreach(source IN LISTS sources) + get_filename_component(source_path "${source}" PATH) + string(REPLACE "/" "\\" source_path_msvc "${source_path}") + source_group("${source_path_msvc}" FILES "${source}") +endforeach() + +set(project RtxdiRuntimeShaderTests) set(folder "RTXDI SDK") include(CMakeDependentOption) @@ -9,14 +30,14 @@ include(CMakeDependentOption) add_library(${project} ${sources}) target_compile_definitions(${project} PRIVATE IS_CONSOLE_APP=1) -target_link_libraries(${project} rtxdi-runtime cxxopts) +target_link_libraries(${project} Rtxdi cxxopts) set_target_properties(${project} PROPERTIES FOLDER ${folder}) # ResamplingCompileTest.hlsl for DXIL target if (DONUT_WITH_DX12) - set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/shaders/ResamplingCompileTest.hlsl") + set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/Shaders/ResamplingCompileTest.hlsl") set(output_file "${CMAKE_CURRENT_BINARY_DIR}/ResamplingCompileTest.hlsl.dxil") add_custom_command( @@ -26,7 +47,7 @@ if (DONUT_WITH_DX12) COMMAND ${DXC_PATH} -nologo -WX -Tcs_6_5 ${source_file} -Fo ${output_file} -I${RTXDI_RUNTIME_INCLUDE_PATH} ) - target_sources(rtxdi-runtime-shader-tests PRIVATE ${output_file}) + target_sources(${project} PRIVATE ${output_file}) endif() @@ -35,7 +56,7 @@ endif() if (DONUT_WITH_VULKAN) - set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/shaders/ResamplingCompileTest.hlsl") + set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/Shaders/ResamplingCompileTest.hlsl") set(output_file "${CMAKE_CURRENT_BINARY_DIR}/ResamplingCompileTest.hlsl.spv") add_custom_command( @@ -45,7 +66,7 @@ if (DONUT_WITH_VULKAN) COMMAND ${DXC_SPIRV_PATH} -nologo -WX -Tcs_6_5 -fspv-target-env=vulkan1.2 ${source_file} -Fo ${output_file} -I${RTXDI_RUNTIME_INCLUDE_PATH} ) - target_sources(rtxdi-runtime-shader-tests PRIVATE ${output_file}) + target_sources(${project} PRIVATE ${output_file}) endif() @@ -55,7 +76,7 @@ endif() if (NOT ${GLSLANG_PATH} STREQUAL "") if (EXISTS ${GLSLANG_PATH}) - set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/shaders/ResamplingCompileTest.glsl") + set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/Shaders/ResamplingCompileTest.glsl") set(output_file "${CMAKE_CURRENT_BINARY_DIR}/ResamplingCompileTest.glsl.spv") add_custom_command( @@ -65,7 +86,7 @@ if (NOT ${GLSLANG_PATH} STREQUAL "") COMMAND ${GLSLANG_PATH} --target-env vulkan1.2 --quiet -S comp ${source_file} -o ${output_file} -I${RTXDI_RUNTIME_INCLUDE_PATH} ) - target_sources(rtxdi-runtime-shader-tests PRIVATE ${output_file}) + target_sources(${project} PRIVATE ${output_file}) else() message(WARNING "The GLSLANG_PATH variable points to a non-existent file: ${GLSLANG_PATH}") diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/ResamplingCompileTest.glsl b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/ResamplingCompileTest.glsl new file mode 100644 index 0000000..436f040 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/ResamplingCompileTest.glsl @@ -0,0 +1,47 @@ +/*************************************************************************** + # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + # + # NVIDIA CORPORATION and its licensors retain all intellectual property + # and proprietary rights in and to this software, related documentation + # and any modifications thereto. Any use, reproduction, disclosure or + # distribution of this software and related documentation without an express + # license agreement from NVIDIA CORPORATION is strictly prohibited. + **************************************************************************/ + +// This shader file is intended for testing the RTXDI header files +// for GLSL compatibility. + +#version 460 +#extension GL_GOOGLE_include_directive : enable + +// Subgroup arithmetic is used in the boiling filter +#extension GL_KHR_shader_subgroup_arithmetic : enable +#extension GL_KHR_shader_subgroup_ballot : enable + +#define RTXDI_GLSL +#define RTXDI_REGIR_MODE RTXDI_REGIR_ONION + +#include "rtxdi/DI/ReSTIRDIParameters.h" +#include "rtxdi/GI/ReSTIRGIParameters.h" + +#include "RtxdiApplicationBridge/RtxdiApplicationBridge.glsli" + +#define RTXDI_ENABLE_BOILING_FILTER +#define RTXDI_BOILING_FILTER_GROUP_SIZE 16 + +#define RTXDI_RIS_BUFFER u_RisBuffer +#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs +#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets +#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs + +#include "rtxdi/LightSampling/PresamplingFunctions.hlsli" +#include "rtxdi/DI/InitialSampling.hlsli" +#include "rtxdi/DI/SpatialResampling.hlsli" +#include "rtxdi/DI/SpatiotemporalResampling.hlsli" +#include "rtxdi/DI/TemporalResampling.hlsli" + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +void main() +{ +} diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/ResamplingCompileTest.hlsl b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/ResamplingCompileTest.hlsl new file mode 100644 index 0000000..0260b74 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/ResamplingCompileTest.hlsl @@ -0,0 +1,37 @@ +/*************************************************************************** + # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + # + # NVIDIA CORPORATION and its licensors retain all intellectual property + # and proprietary rights in and to this software, related documentation + # and any modifications thereto. Any use, reproduction, disclosure or + # distribution of this software and related documentation without an express + # license agreement from NVIDIA CORPORATION is strictly prohibited. + **************************************************************************/ + +// This shader file is intended for testing the RTXDI header files to make sure +// that they do not make any undeclared assumptions about the contents of the +// user-defined structures and about the functions being available. + +#include +#include + +#include "RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli" + +#define RTXDI_ENABLE_BOILING_FILTER +#define RTXDI_BOILING_FILTER_GROUP_SIZE 16 + +#define RTXDI_RIS_BUFFER u_RisBuffer +#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs +#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs +#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets + +#include +#include +#include +#include +#include + +[numthreads(1, 1, 1)] +void main() +{ +} diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Buffers.glsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Buffers.glsli new file mode 100644 index 0000000..332bf11 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Buffers.glsli @@ -0,0 +1,31 @@ +#ifndef RAB_BUFFERS_GLSLI +#define RAB_BUFFERS_GLSLI + +layout(set = 0, binding = 0) buffer RIS_BUFFER +{ + uvec2 u_RisBuffer[]; +}; + +layout(set = 0, binding = 1) buffer LIGHT_RESERVOIR_BUFFER +{ + RTXDI_PackedDIReservoir u_LightReservoirs[]; +}; + +layout(set = 0, binding = 2) readonly buffer NEIGHBOR_OFFSET_BUFFER +{ + vec2 t_NeighborOffsets[]; +}; + +layout(set = 0, binding = 3) buffer GI_RESERVOIR_BUFFER +{ + RTXDI_PackedGIReservoir u_GIReservoirs[]; +}; + +#define IES_SAMPLER s_EnvironmentSampler + +int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) +{ + return 0; +} + +#endif // RAB_BUFFERS_GLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli new file mode 100644 index 0000000..1d93f57 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Buffers.hlsli @@ -0,0 +1,24 @@ +#ifndef RAB_BUFFER_HLSLI +#define RAB_BUFFER_HLSLI + +RWBuffer u_RisBuffer : register(u10); +RWStructuredBuffer u_LightReservoirs : register(u0); +Buffer t_NeighborOffsets : register(t21); +RWStructuredBuffer u_GIReservoirs : register(u6); + +#define RTXDI_RIS_BUFFER u_RisBuffer +#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs +#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets +#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs + +#define IES_SAMPLER s_EnvironmentSampler + +// Translates the light index from the current frame to the previous frame (if currentToPrevious = true) +// or from the previous frame to the current frame (if currentToPrevious = false). +// Returns the new index, or a negative number if the light does not exist in the other frame. +int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) +{ + return 0; +} + +#endif // RAB_BUFFER_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli new file mode 100644 index 0000000..b9aa5cd --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightInfo.hlsli @@ -0,0 +1,43 @@ +#ifndef RAB_LIGHT_INFO_HLSLI +#define RAB_LIGHT_INFO_HLSLI + +#include "RAB_Surface.hlsli" +#include "RAB_LightSample.hlsli" + +struct RAB_LightInfo +{ + uint unused; +}; + +RAB_LightInfo RAB_EmptyLightInfo() +{ + RAB_LightInfo lightInfo; + return lightInfo; +} + +RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) +{ + return RAB_EmptyLightInfo(); +} + +RAB_LightInfo RAB_LoadCompactLightInfo(uint linearIndex) +{ + return RAB_EmptyLightInfo(); +} + +bool RAB_StoreCompactLightInfo(uint linearIndex, RAB_LightInfo lightInfo) +{ + return true; +} + +float RAB_GetLightTargetPdfForVolume(RAB_LightInfo light, float3 volumeCenter, float volumeRadius) +{ + return 0.0; +} + +RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) +{ + return RAB_EmptyLightSample(); +} + +#endif // RAB_LIGHT_INFO_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli new file mode 100644 index 0000000..934da55 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightSample.hlsli @@ -0,0 +1,26 @@ +#ifndef RTXDI_RAB_LIGHT_INFO_HLSLI +#define RTXDI_RAB_LIGHT_INFO_HLSLI + +struct RAB_LightSample +{ + float unused; +}; + +RAB_LightSample RAB_EmptyLightSample() +{ + RAB_LightSample lightSample; + + return lightSample; +} + +bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) +{ + return true; +} + +float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) +{ + return 0.0; +} + +#endif // RTXDI_RAB_LIGHT_INFO_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli new file mode 100644 index 0000000..f8f025c --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_LightSampling.hlsli @@ -0,0 +1,72 @@ +#ifndef RAB_LIGHT_SAMPLING_HLSLI +#define RAB_LIGHT_SAMPLING_HLSLI + +#include "RAB_RayPayload.hlsli" + +float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) +{ + return float2(0.0, 0.0); +} + +float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) +{ + return 0.0; +} + +float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) +{ + return 0.0; +} + +float3 RAB_GetReflectedRadianceForSurface(float3 incomingRadianceLocation, float3 incomingRadiance, RAB_Surface surface) +{ + return float3(0.0, 0.0, 0.0); +} + +float RAB_GetReflectedLuminanceForSurface(float3 incomingRadianceLocation, float3 incomingRadiance, RAB_Surface surface) +{ + return 0.0; +} + +float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) +{ + return 0.0; +} + +float RAB_GetGISampleTargetPdfForSurface(float3 samplePosition, float3 sampleRadiance, RAB_Surface surface) +{ + return 0.0; +} + +void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, + out float3 o_lightDir, + out float o_lightDistance) +{ + o_lightDir = float3(0.0, 0.0, 0.0); + o_lightDistance = 0; +} + +bool RTXDI_CompareRelativeDifference(float reference, float candidate, float threshold); + +float3 GetEnvironmentRadiance(float3 direction) +{ + return float3(0.0, 0.0, 0.0); +} + +bool IsComplexSurface(int2 pixelPosition, RAB_Surface surface) +{ + return true; +} + +uint getLightIndex(uint instanceID, uint geometryIndex, uint primitiveIndex) +{ + return 0; +} + +bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, + out uint o_lightIndex, out float2 o_randXY) +{ + return true; +} + +#endif // RAB_LIGHT_SAMPLING_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Material.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Material.hlsli new file mode 100644 index 0000000..9ebb3b0 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Material.hlsli @@ -0,0 +1,43 @@ +#ifndef RAB_MATERIAL_HLSLI +#define RAB_MATERIAL_HLSLI + +static const float kMinRoughness = 0.05f; + +struct RAB_Material +{ + float unused; +}; + +RAB_Material RAB_EmptyMaterial() +{ + RAB_Material material; + + return material; +} + +float3 GetDiffuseAlbedo(RAB_Material material) +{ + return float3(0.0, 0.0, 0.0); +} + +float3 GetSpecularF0(RAB_Material material) +{ + return float3(0.0, 0.0, 0.0); +} + +float GetRoughness(RAB_Material material) +{ + return 0.0; +} + +RAB_Material RAB_GetGBufferMaterial(int2 pixelPosition, bool previousFrame) +{ + return RAB_EmptyMaterial(); +} + +bool RAB_AreMaterialsSimilar(RAB_Material a, RAB_Material b) +{ + return true; +} + +#endif // RAB_MATERIAL_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli new file mode 100644 index 0000000..1e7abb9 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RTShaders.hlsli @@ -0,0 +1,30 @@ +#ifndef RAB_RT_SHADERS_HLSLI +#define RAB_RT_SHADERS_HLSLI + +#include "RAB_RayPayload.hlsli" + +// #if !USE_RAY_QUERY +// struct RayAttributes +// { +// float2 uv; +// }; +// +// [shader("miss")] +// void Miss(inout RayPayload payload : SV_RayPayload) +// { +// } +// +// [shader("closesthit")] +// void ClosestHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) +// { +// +// } +// +// [shader("anyhit")] +// void AnyHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) +// { +// +// } +// #endif + +#endif // RAB_RT_SHADERS_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli new file mode 100644 index 0000000..60949d0 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RandomSamplerState.hlsli @@ -0,0 +1,20 @@ +#ifndef RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI +#define RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI + +struct RAB_RandomSamplerState +{ + uint unused; +}; + +RAB_RandomSamplerState RAB_InitRandomSampler(uint2 index, uint pass) +{ + RAB_RandomSamplerState rng; + return rng; +} + +float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) +{ + return 0.0; +} + +#endif // RTXDI_RAB_RANDOM_SAMPLER_STATE_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli new file mode 100644 index 0000000..d721ea8 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_RayPayload.hlsli @@ -0,0 +1,9 @@ +#ifndef RAB_RAY_PAYLOAD_HLSLI +#define RAB_RAY_PAYLOAD_HLSLI + +struct RayPayload +{ + uint unused; +}; + +#endif // RAB_RAY_PAYLOAD_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli new file mode 100644 index 0000000..dfbd4dd --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_SpatialHelpers.hlsli @@ -0,0 +1,14 @@ +#ifndef RAB_SPATIAL_HELPERS_HLSLI +#define RAB_SPATIAL_HELPERS_HLSLI + +int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) +{ + return int2(0, 0); +} + +bool RAB_ValidateGISampleWithJacobian(inout float jacobian) +{ + return true; +} + +#endif // RAB_SPATIAL_HELPERS_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli new file mode 100644 index 0000000..0b42cf1 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_Surface.hlsli @@ -0,0 +1,61 @@ +#ifndef RTXDI_RAB_SURFACE_HLSLI +#define RTXDI_RAB_SURFACE_HLSLI + +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_Material.hlsli" + +static const bool kSpecularOnly = false; + +struct RAB_Surface +{ + uint unused; +}; + +RAB_Surface RAB_EmptySurface() +{ + RAB_Surface surface; + return surface; +} + +bool RAB_IsSurfaceValid(RAB_Surface surface) +{ + return true; +} + +float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) +{ + return float3(0.0, 0.0, 0.0); +} + +RAB_Material RAB_GetMaterial(RAB_Surface surface) +{ + return RAB_EmptyMaterial(); +} + +float3 RAB_GetSurfaceNormal(RAB_Surface surface) +{ + return float3(0.0, 0.0, 0.0); +} + +float RAB_GetSurfaceLinearDepth(RAB_Surface surface) +{ + return 0.0; +} + +RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) +{ + return RAB_EmptySurface(); +} + +bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) +{ + dir = float3(0.0, 0.0, 0.0); + return false; +} + +float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) +{ + return 0.0; +} + +#endif // RTXDI_RAB_SURFACE_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli new file mode 100644 index 0000000..2c6ca58 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RAB_VisibilityTest.hlsli @@ -0,0 +1,24 @@ +#ifndef RAB_VISIBILITY_TEST_HLSLI +#define RAB_VISIBILITY_TEST_HLSLI + +bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) +{ + return true; +} + +bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, RAB_LightSample lightSample) +{ + return true; +} + +bool RAB_GetConservativeVisibility(RAB_Surface surface, float3 samplePosition) +{ + return true; +} + +bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, float3 samplePosition) +{ + return true; +} + +#endif // RAB_VISIBILITY_TEST_HLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.glsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.glsli new file mode 100644 index 0000000..ffcfbe0 --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.glsli @@ -0,0 +1,45 @@ +/*************************************************************************** + # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + # + # NVIDIA CORPORATION and its licensors retain all intellectual property + # and proprietary rights in and to this software, related documentation + # and any modifications thereto. Any use, reproduction, disclosure or + # distribution of this software and related documentation without an express + # license agreement from NVIDIA CORPORATION is strictly prohibited. + **************************************************************************/ + +/* +This header file is the bridge between the RTXDI resampling functions +and the application resources and parts of shader functionality. + +The RTXDI SDK provides the resampling logic, and the application provides +other necessary aspects: + - Material BRDF evaluation; + - Ray tracing and transparent/alpha-tested material processing; + - Light sampling functions and emission profiles. + +The structures and functions that are necessary for SDK operation +start with the RAB_ prefix (for RTXDI-Application Bridge). + +All structures defined here are opaque for the SDK, meaning that +it makes no assumptions about their contents, they are just passed +between the bridge functions. +*/ + +#ifndef RTXDI_APPLICATION_BRIDGE_GLSLI +#define RTXDI_APPLICATION_BRIDGE_GLSLI + +#include "RAB_Buffers.glsli" + +#include "RAB_LightInfo.hlsli" +#include "RAB_LightSample.hlsli" +#include "RAB_LightSampling.hlsli" +#include "RAB_Material.hlsli" +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_RayPayload.hlsli" +#include "RAB_RTShaders.hlsli" +#include "RAB_SpatialHelpers.hlsli" +#include "RAB_Surface.hlsli" +#include "RAB_VisibilityTest.hlsli" + +#endif // RTXDI_APPLICATION_BRIDGE_GLSLI diff --git a/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli new file mode 100644 index 0000000..c5d64ac --- /dev/null +++ b/Support/Tests/RtxdiRuntimeShaderTests/Shaders/RtxdiApplicationBridge/RtxdiApplicationBridge.hlsli @@ -0,0 +1,45 @@ +/*************************************************************************** + # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. + # + # NVIDIA CORPORATION and its licensors retain all intellectual property + # and proprietary rights in and to this software, related documentation + # and any modifications thereto. Any use, reproduction, disclosure or + # distribution of this software and related documentation without an express + # license agreement from NVIDIA CORPORATION is strictly prohibited. + **************************************************************************/ + +/* +This header file is the bridge between the RTXDI resampling functions +and the application resources and parts of shader functionality. + +The RTXDI SDK provides the resampling logic, and the application provides +other necessary aspects: + - Material BRDF evaluation; + - Ray tracing and transparent/alpha-tested material processing; + - Light sampling functions and emission profiles. + +The structures and functions that are necessary for SDK operation +start with the RAB_ prefix (for RTXDI-Application Bridge). + +All structures defined here are opaque for the SDK, meaning that +it makes no assumptions about their contents, they are just passed +between the bridge functions. +*/ + +#ifndef RTXDI_APPLICATION_BRIDGE_HLSLI +#define RTXDI_APPLICATION_BRIDGE_HLSLI + +#include "RAB_Buffers.hlsli" + +#include "RAB_LightInfo.hlsli" +#include "RAB_LightSample.hlsli" +#include "RAB_LightSampling.hlsli" +#include "RAB_Material.hlsli" +#include "RAB_RandomSamplerState.hlsli" +#include "RAB_RayPayload.hlsli" +#include "RAB_RTShaders.hlsli" +#include "RAB_SpatialHelpers.hlsli" +#include "RAB_Surface.hlsli" +#include "RAB_VisibilityTest.hlsli" + +#endif // RTXDI_APPLICATION_BRIDGE_HLSLI diff --git a/donut b/donut deleted file mode 160000 index cf82366..0000000 --- a/donut +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cf823665cc20ae568d3d0da1641818441405da38 diff --git a/minimal/shaders/RtxdiApplicationBridge.hlsli b/minimal/shaders/RtxdiApplicationBridge.hlsli deleted file mode 100644 index 4f1abd3..0000000 --- a/minimal/shaders/RtxdiApplicationBridge.hlsli +++ /dev/null @@ -1,420 +0,0 @@ -/*************************************************************************** - # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. - # - # NVIDIA CORPORATION and its licensors retain all intellectual property - # and proprietary rights in and to this software, related documentation - # and any modifications thereto. Any use, reproduction, disclosure or - # distribution of this software and related documentation without an express - # license agreement from NVIDIA CORPORATION is strictly prohibited. - **************************************************************************/ - -#ifndef RTXDI_APPLICATION_BRIDGE_HLSLI -#define RTXDI_APPLICATION_BRIDGE_HLSLI - -// See RtxdiApplicationBridge.hlsli in the full sample app for more information. -// This is a minimal viable implementation. - -#include -#include - -#include "ShaderParameters.h" -#include "SceneGeometry.hlsli" -#include "GBufferHelpers.hlsli" - -// Previous G-buffer resources -Texture2D t_PrevGBufferDepth : register(t0); -Texture2D t_PrevGBufferNormals : register(t1); -Texture2D t_PrevGBufferGeoNormals : register(t2); -Texture2D t_PrevGBufferDiffuseAlbedo : register(t3); -Texture2D t_PrevGBufferSpecularRough : register(t4); - -// Scene resources -RaytracingAccelerationStructure SceneBVH : register(t30); -StructuredBuffer t_InstanceData : register(t32); -StructuredBuffer t_GeometryData : register(t33); -StructuredBuffer t_MaterialConstants : register(t34); - -// RTXDI resources -StructuredBuffer t_LightDataBuffer : register(t20); -Buffer t_NeighborOffsets : register(t21); -StructuredBuffer t_GeometryInstanceToLight : register(t22); - -// Screen-sized UAVs -RWStructuredBuffer u_LightReservoirs : register(u0); -RWTexture2D u_ShadingOutput : register(u1); -RWTexture2D u_GBufferDepth : register(u2); -RWTexture2D u_GBufferNormals : register(u3); -RWTexture2D u_GBufferGeoNormals : register(u4); -RWTexture2D u_GBufferDiffuseAlbedo : register(u5); -RWTexture2D u_GBufferSpecularRough : register(u6); - -// Other -ConstantBuffer g_Const : register(b0); -SamplerState s_MaterialSampler : register(s0); - -#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs -#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets - -#include "TriangleLight.hlsli" - -static const float kMinRoughness = 0.05f; - -// A surface with enough information to evaluate BRDFs -struct RAB_Surface -{ - float3 worldPos; - float3 viewDir; - float viewDepth; - float3 normal; - float3 geoNormal; - float3 diffuseAlbedo; - float3 specularF0; - float roughness; - float diffuseProbability; -}; - -typedef RandomSamplerState RAB_RandomSamplerState; - -float getSurfaceDiffuseProbability(RAB_Surface surface) -{ - float diffuseWeight = calcLuminance(surface.diffuseAlbedo); - float specularWeight = calcLuminance(Schlick_Fresnel(surface.specularF0, dot(surface.viewDir, surface.normal))); - float sumWeights = diffuseWeight + specularWeight; - return sumWeights < 1e-7f ? 1.f : (diffuseWeight / sumWeights); -} - -RAB_Surface RAB_EmptySurface() -{ - RAB_Surface surface = (RAB_Surface)0; - surface.viewDepth = BACKGROUND_DEPTH; - return surface; -} - -RAB_LightInfo RAB_EmptyLightInfo() -{ - return (RAB_LightInfo)0; -} - -RAB_LightSample RAB_EmptyLightSample() -{ - return (RAB_LightSample)0; -} - -void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, - out float3 o_lightDir, - out float o_lightDistance) -{ - float3 toLight = lightSample.position - surface.worldPos; - o_lightDistance = length(toLight); - o_lightDir = toLight / o_lightDistance; -} - -bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) -{ - return false; -} - -float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) -{ - return lightSample.solidAnglePdf; -} - - -float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) -{ - return 0; -} - -float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) -{ - // No Environment sampling - return 0; -} - -float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) -{ - // Uniform pdf - return 1.0 / g_Const.lightBufferParams.localLightBufferRegion.numLights; -} - -RayDesc setupVisibilityRay(RAB_Surface surface, RAB_LightSample lightSample, float offset = 0.001) -{ - float3 L = lightSample.position - surface.worldPos; - - RayDesc ray; - ray.TMin = offset; - ray.TMax = length(L) - offset; - ray.Direction = normalize(L); - ray.Origin = surface.worldPos; - - return ray; -} - -// Tests the visibility between a surface and a light sample. -// Returns true if there is nothing between them. -bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) -{ - RayDesc ray = setupVisibilityRay(surface, lightSample); - - RayQuery rayQuery; - - rayQuery.TraceRayInline(SceneBVH, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); - - rayQuery.Proceed(); - - bool visible = (rayQuery.CommittedStatus() == COMMITTED_NOTHING); - - return visible; -} - -// Tests the visibility between a surface and a light sample on the previous frame. -// Since the scene is static in this sample app, it's equivalent to RAB_GetConservativeVisibility. -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, - RAB_LightSample lightSample) -{ - return RAB_GetConservativeVisibility(currentSurface, lightSample); -} - -// This function is called in the spatial resampling passes to make sure that -// the samples actually land on the screen and not outside of its boundaries. -// It can clamp the position or reflect it about the nearest screen edge. -// The simplest implementation will just return the input pixelPosition. -int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) -{ - return clamp(pixelPosition, 0, int2(g_Const.view.viewportSize) - 1); -} - -// Load a sample from the previous G-buffer. -RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) -{ - RAB_Surface surface = RAB_EmptySurface(); - - // We do not have access to the current G-buffer in this sample because it's using - // a single render pass with a fused resampling kernel, so just return an invalid surface. - // This should never happen though, as the fused kernel doesn't call RAB_GetGBufferSurface(..., false) - if (!previousFrame) - return surface; - - const PlanarViewConstants view = g_Const.prevView; - - if (any(pixelPosition >= view.viewportSize)) - return surface; - - surface.viewDepth = t_PrevGBufferDepth[pixelPosition]; - - if(surface.viewDepth == BACKGROUND_DEPTH) - return surface; - - surface.normal = octToNdirUnorm32(t_PrevGBufferNormals[pixelPosition]); - surface.geoNormal = octToNdirUnorm32(t_PrevGBufferGeoNormals[pixelPosition]); - surface.diffuseAlbedo = Unpack_R11G11B10_UFLOAT(t_PrevGBufferDiffuseAlbedo[pixelPosition]).rgb; - float4 specularRough = Unpack_R8G8B8A8_Gamma_UFLOAT(t_PrevGBufferSpecularRough[pixelPosition]); - surface.specularF0 = specularRough.rgb; - surface.roughness = specularRough.a; - surface.worldPos = viewDepthToWorldPos(view, pixelPosition, surface.viewDepth); - surface.viewDir = normalize(g_Const.view.cameraDirectionOrPosition.xyz - surface.worldPos); - surface.diffuseProbability = getSurfaceDiffuseProbability(surface); - - return surface; -} - -bool RAB_IsSurfaceValid(RAB_Surface surface) -{ - return surface.viewDepth != BACKGROUND_DEPTH; -} - -float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) -{ - return surface.worldPos; -} - -// World space from surface to eye -float3 RAB_GetSurfaceViewDir(RAB_Surface surface) -{ - return surface.viewDir; -} - -float3 RAB_GetSurfaceNormal(RAB_Surface surface) -{ - return surface.normal; -} - -float RAB_GetSurfaceLinearDepth(RAB_Surface surface) -{ - return surface.viewDepth; -} - -float3 worldToTangent(RAB_Surface surface, float3 w) -{ - // reconstruct tangent frame based off worldspace normal - // this is ok for isotropic BRDFs - // for anisotropic BRDFs, we need a user defined tangent - float3 tangent; - float3 bitangent; - ConstructONB(surface.normal, tangent, bitangent); - - return float3(dot(bitangent, w), dot(tangent, w), dot(surface.normal, w)); -} - -float3 tangentToWorld(RAB_Surface surface, float3 h) -{ - // reconstruct tangent frame based off worldspace normal - // this is ok for isotropic BRDFs - // for anisotropic BRDFs, we need a user defined tangent - float3 tangent; - float3 bitangent; - ConstructONB(surface.normal, tangent, bitangent); - - return bitangent * h.x + tangent * h.y + surface.normal * h.z; -} - -RAB_RandomSamplerState RAB_InitRandomSampler(uint2 index, uint pass) -{ - return initRandomSampler(index, g_Const.frameIndex + pass * 13); -} - -float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) -{ - return sampleUniformRng(rng); -} - -// Output an importanced sampled reflection direction from the BRDF given the view -// Return true if the returned direction is above the surface -bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) -{ - float3 rand; - rand.x = RAB_GetNextRandom(rng); - rand.y = RAB_GetNextRandom(rng); - rand.z = RAB_GetNextRandom(rng); - if (rand.x < surface.diffuseProbability) - { - float pdf; - float3 h = SampleCosHemisphere(rand.yz, pdf); - dir = tangentToWorld(surface, h); - } - else - { - float3 h = ImportanceSampleGGX(rand.yz, max(surface.roughness, kMinRoughness)); - dir = reflect(-surface.viewDir, tangentToWorld(surface, h)); - } - - return dot(surface.normal, dir) > 0.f; -} - -// Return PDF wrt solid angle for the BRDF in the given dir -float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) -{ - float cosTheta = saturate(dot(surface.normal, dir)); - float diffusePdf = cosTheta / M_PI; - float specularPdf = ImportanceSampleGGX_VNDF_PDF(max(surface.roughness, kMinRoughness), surface.normal, surface.viewDir, dir); - float pdf = cosTheta > 0.f ? lerp(specularPdf, diffusePdf, surface.diffuseProbability) : 0.f; - return pdf; -} - -// Evaluate the surface BRDF and compute the weighted reflected radiance for the given light sample -float3 ShadeSurfaceWithLightSample(RAB_LightSample lightSample, RAB_Surface surface) -{ - // Ignore invalid light samples - if (lightSample.solidAnglePdf <= 0) - return 0; - - float3 L = normalize(lightSample.position - surface.worldPos); - - // Ignore light samples that are below the geometric surface (but above the normal mapped surface) - if (dot(L, surface.geoNormal) <= 0) - return 0; - - - float3 V = surface.viewDir; - - // Evaluate the BRDF - float diffuse = Lambert(surface.normal, -L); - float3 specular = GGX_times_NdotL(V, L, surface.normal, max(surface.roughness, kMinRoughness), surface.specularF0); - - float3 reflectedRadiance = lightSample.radiance * (diffuse * surface.diffuseAlbedo + specular); - - return reflectedRadiance / lightSample.solidAnglePdf; -} - -// Compute the target PDF (p-hat) for the given light sample relative to a surface -float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) -{ - // Second-best implementation: the PDF is proportional to the reflected radiance. - // The best implementation would be taking visibility into account, - // but that would be prohibitively expensive. - return calcLuminance(ShadeSurfaceWithLightSample(lightSample, surface)); -} - -// Compute the position on a triangle light given a pair of random numbers -RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) -{ - return TriangleLight::Create(lightInfo).calcSample(uv, surface.worldPos); -} - -// Load the packed light information from the buffer. -// Ignore the previousFrame parameter as our lights are static in this sample. -RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) -{ - return t_LightDataBuffer[index]; -} - -// Translate the light index between the current and previous frame. -// Do nothing as our lights are static in this sample. -int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) -{ - return int(lightIndex); -} - -// Compare the materials of two surfaces to improve resampling quality. -// Just say that everything is similar for simplicity. -bool RAB_AreMaterialsSimilar(RAB_Surface a, RAB_Surface b) -{ - return true; -} - -uint getLightIndex(uint instanceID, uint geometryIndex, uint primitiveIndex) -{ - uint lightIndex = RTXDI_InvalidLightIndex; - InstanceData hitInstance = t_InstanceData[instanceID]; - uint geometryInstanceIndex = hitInstance.firstGeometryInstanceIndex + geometryIndex; - lightIndex = t_GeometryInstanceToLight[geometryInstanceIndex]; - if (lightIndex != RTXDI_InvalidLightIndex) - lightIndex += primitiveIndex; - return lightIndex; -} - - -// Return true if anything was hit. If false, RTXDI will do environment map sampling -// o_lightIndex: If hit, must be a valid light index for RAB_LoadLightInfo, if no local light was hit, must be RTXDI_InvalidLightIndex -// randXY: The randXY that corresponds to the hit location and is the same used for RAB_SamplePolymorphicLight -bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, - out uint o_lightIndex, out float2 o_randXY) -{ - o_lightIndex = RTXDI_InvalidLightIndex; - o_randXY = 0; - - RayDesc ray; - ray.Origin = origin; - ray.Direction = direction; - ray.TMin = tMin; - ray.TMax = tMax; - - RayQuery rayQuery; - rayQuery.TraceRayInline(SceneBVH, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); - rayQuery.Proceed(); - - bool hitAnything = rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT; - if (hitAnything) - { - o_lightIndex = getLightIndex(rayQuery.CommittedInstanceID(), rayQuery.CommittedGeometryIndex(), rayQuery.CommittedPrimitiveIndex()); - if (o_lightIndex != RTXDI_InvalidLightIndex) - { - float2 hitUV = rayQuery.CommittedTriangleBarycentrics(); - o_randXY = randomFromBarycentric(hitUVToBarycentric(hitUV)); - } - } - - return hitAnything; -} - -#endif // RTXDI_APPLICATION_BRIDGE_HLSLI diff --git a/rtxdi-runtime b/rtxdi-runtime deleted file mode 160000 index 5ee2a55..0000000 --- a/rtxdi-runtime +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5ee2a55fedf865b0a19409ae8d2b6539b937d797 diff --git a/rtxdi-runtime-shader-tests/shaders/ResamplingCompileTest.glsl b/rtxdi-runtime-shader-tests/shaders/ResamplingCompileTest.glsl deleted file mode 100644 index faa43f5..0000000 --- a/rtxdi-runtime-shader-tests/shaders/ResamplingCompileTest.glsl +++ /dev/null @@ -1,246 +0,0 @@ -/*************************************************************************** - # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. - # - # NVIDIA CORPORATION and its licensors retain all intellectual property - # and proprietary rights in and to this software, related documentation - # and any modifications thereto. Any use, reproduction, disclosure or - # distribution of this software and related documentation without an express - # license agreement from NVIDIA CORPORATION is strictly prohibited. - **************************************************************************/ - -// This shader file is intended for testing the RTXDI header files -// for GLSL compatibility. - -#version 460 -#extension GL_GOOGLE_include_directive : enable - -// Subgroup arithmetic is used in the boiling filter -#extension GL_KHR_shader_subgroup_arithmetic : enable -#extension GL_KHR_shader_subgroup_ballot : enable - -#define RTXDI_GLSL -#define RTXDI_REGIR_MODE RTXDI_REGIR_ONION - -#include "rtxdi/ReSTIRDIParameters.h" -#include "rtxdi/ReSTIRGIParameters.h" - -struct RAB_RandomSamplerState -{ - uint unused; -}; - -struct RAB_Surface -{ - uint unused; -}; - -struct RAB_LightSample -{ - uint unused; -}; - -struct RAB_LightInfo -{ - uint unused; -}; - -RAB_Surface RAB_EmptySurface() -{ - return RAB_Surface(0); -} - -RAB_LightInfo RAB_EmptyLightInfo() -{ - return RAB_LightInfo(0); -} - -RAB_LightSample RAB_EmptyLightSample() -{ - return RAB_LightSample(0); -} - -void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, - out float3 o_lightDir, - out float o_lightDistance) -{ -} - -bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) -{ - return true; -} - -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, RAB_LightSample lightSample) -{ - return true; -} - -int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) -{ - return pixelPosition; -} - -RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) -{ - return RAB_Surface(0); -} - -bool RAB_IsSurfaceValid(RAB_Surface surface) -{ - return true; -} - -float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) -{ - return float3(0.0); -} - -float3 RAB_GetSurfaceNormal(RAB_Surface surface) -{ - return float3(0.0); -} - -float RAB_GetSurfaceLinearDepth(RAB_Surface surface) -{ - return 0.0; -} - -float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) -{ - return 0.0; -} - -bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) -{ - return true; -} - -float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) -{ - return 0.0; -} - -float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) -{ - return 1.0; -} - -float RAB_GetLightTargetPdfForVolume(RAB_LightInfo light, float3 volumeCenter, float volumeRadius) -{ - return 1.0; -} - -RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) -{ - return RAB_LightSample(0); -} - -RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) -{ - return RAB_LightInfo(0); -} - -RAB_LightInfo RAB_LoadCompactLightInfo(uint linearIndex) -{ - return RAB_LightInfo(0); -} - -bool RAB_StoreCompactLightInfo(uint linearIndex, RAB_LightInfo lightInfo) -{ - return true; -} - -int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) -{ - return -1; -} - -float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) -{ - return 0.0; -} - -bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) -{ - return false; -} - -float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) -{ - return 0.0; -} - -float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) -{ - return 0.0; -} - -float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) -{ - return float2(0.0); -} - -bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, - out uint o_lightIndex, out float2 o_randXY) -{ - return false; -} - -bool RAB_AreMaterialsSimilar(RAB_Surface a, RAB_Surface b) -{ - return true; -} - -bool RAB_ValidateGISampleWithJacobian(inout float jacobian) -{ - return true; -} - -float RAB_GetGISampleTargetPdfForSurface(float3 samplePosition, float3 sampleRadiance, RAB_Surface surface) -{ - return 1.0; -} - -bool RAB_GetConservativeVisibility(RAB_Surface surface, float3 samplePosition) -{ - return true; -} - -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, float3 samplePosition) -{ - return true; -} - -#define RTXDI_ENABLE_BOILING_FILTER -#define RTXDI_BOILING_FILTER_GROUP_SIZE 16 - -layout(set = 0, binding = 0) buffer RIS_BUFFER { - uvec2 u_RisBuffer[]; -}; - -layout(set = 0, binding = 1) buffer LIGHT_RESERVOIR_BUFFER { - RTXDI_PackedDIReservoir u_LightReservoirs[]; -}; - -layout(set = 0, binding = 2) readonly buffer NEIGHBOR_OFFSET_BUFFER { - vec2 t_NeighborOffsets[]; -}; - -layout(set = 0, binding = 3) buffer GI_RESERVOIR_BUFFER { - RTXDI_PackedGIReservoir u_GIReservoirs[]; -}; - -#define RTXDI_RIS_BUFFER u_RisBuffer -#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs -#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets -#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs - -#include "rtxdi/PresamplingFunctions.hlsli" -#include "rtxdi/InitialSamplingFunctions.hlsli" -#include "rtxdi/DIResamplingFunctions.hlsli" - -layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; - -void main() -{ -} diff --git a/rtxdi-runtime-shader-tests/shaders/ResamplingCompileTest.hlsl b/rtxdi-runtime-shader-tests/shaders/ResamplingCompileTest.hlsl deleted file mode 100644 index 704f861..0000000 --- a/rtxdi-runtime-shader-tests/shaders/ResamplingCompileTest.hlsl +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************** - # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. - # - # NVIDIA CORPORATION and its licensors retain all intellectual property - # and proprietary rights in and to this software, related documentation - # and any modifications thereto. Any use, reproduction, disclosure or - # distribution of this software and related documentation without an express - # license agreement from NVIDIA CORPORATION is strictly prohibited. - **************************************************************************/ - -// This shader file is intended for testing the RTXDI header files to make sure -// that they do not make any undeclared assumptions about the contents of the -// user-defined structures and about the functions being available. - -#include -#include - -struct RAB_RandomSamplerState -{ - uint unused; -}; - -struct RAB_Surface -{ - uint unused; -}; - -struct RAB_LightSample -{ - uint unused; -}; - -struct RAB_LightInfo -{ - uint unused; -}; - -RAB_Surface RAB_EmptySurface() -{ - return RAB_Surface(0); -} - -RAB_LightInfo RAB_EmptyLightInfo() -{ - return RAB_LightInfo(0); -} - -RAB_LightSample RAB_EmptyLightSample() -{ - return RAB_LightSample(0); -} - -void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, - out float3 o_lightDir, - out float o_lightDistance) -{ - o_lightDistance = 0.f; -} - -bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) -{ - return true; -} - -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, RAB_LightSample lightSample) -{ - return true; -} - -int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) -{ - return pixelPosition; -} - -RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) -{ - return (RAB_Surface)0; -} - -bool RAB_IsSurfaceValid(RAB_Surface surface) -{ - return true; -} - -float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) -{ - return 0.0; -} - -float3 RAB_GetSurfaceNormal(RAB_Surface surface) -{ - return 0.0; -} - -float RAB_GetSurfaceLinearDepth(RAB_Surface surface) -{ - return 0.0; -} - -float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) -{ - return 0.0; -} - -bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) -{ - return true; -} - -float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) -{ - return 0.0; -} - -float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) -{ - return 1.0; -} - -float RAB_GetLightTargetPdfForVolume(RAB_LightInfo light, float3 volumeCenter, float volumeRadius) -{ - return 1.0; -} - -RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) -{ - return (RAB_LightSample)0; -} - -RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) -{ - return (RAB_LightInfo)0; -} - -RAB_LightInfo RAB_LoadCompactLightInfo(uint linearIndex) -{ - return (RAB_LightInfo)0; -} - -bool RAB_StoreCompactLightInfo(uint linearIndex, RAB_LightInfo lightInfo) -{ - return true; -} - -int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) -{ - return -1; -} - -float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) -{ - return 0.0; -} - -bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) -{ - return false; -} - -float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) -{ - return 0.0; -} - -float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) -{ - return 0.0; -} - -float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) -{ - return 0.0; -} - -bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, out uint o_lightIndex, out float2 o_randXY) -{ - o_lightIndex = 0; - return false; -} - -bool RAB_AreMaterialsSimilar(RAB_Surface a, RAB_Surface b) -{ - return true; -} - -bool RAB_ValidateGISampleWithJacobian(inout float jacobian) -{ - return true; -} - -float RAB_GetGISampleTargetPdfForSurface(float3 samplePosition, float3 sampleRadiance, RAB_Surface surface) -{ - return 1.0; -} - -bool RAB_GetConservativeVisibility(RAB_Surface surface, float3 samplePosition) -{ - return true; -} - -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, float3 samplePosition) -{ - return true; -} - -#define RTXDI_ENABLE_BOILING_FILTER -#define RTXDI_BOILING_FILTER_GROUP_SIZE 16 - -RWBuffer u_RisBuffer; -RWStructuredBuffer u_LightReservoirs; -RWStructuredBuffer u_GIReservoirs; -Buffer t_NeighborOffsets; - -#define RTXDI_RIS_BUFFER u_RisBuffer -#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs -#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs -#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets - -#include -#include -#include - -[numthreads(1, 1, 1)] -void main() -{ -} diff --git a/rtxdi-runtime.cmake b/rtxdi-runtime.cmake deleted file mode 100644 index 407261f..0000000 --- a/rtxdi-runtime.cmake +++ /dev/null @@ -1,5 +0,0 @@ -if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/rtxdi-runtime/CMakeLists.txt") - - add_subdirectory(rtxdi-runtime) - -endif() \ No newline at end of file diff --git a/set_vs_vars.ps1 b/set_vs_vars.ps1 deleted file mode 100644 index 155122d..0000000 --- a/set_vs_vars.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -# -# Find vswhere (installed with recent Visual Studio versions). -# -If ($vsWhere = Get-Command "vswhere.exe" -ErrorAction SilentlyContinue) { - $vsWhere = $vsWhere.Path -} ElseIf (Test-Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe") { - $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -} - Else { - Write-Error "vswhere not found. Aborting." -ErrorAction Stop -} -Write-Host "vswhere found at: $vsWhere" -ForegroundColor Yellow - - -# -# Get path to Visual Studio installation using vswhere. -# -$vsPath = &$vsWhere -latest -version "[16.0,17.0)" -products * ` - -requires Microsoft.Component.MSBuild ` - -property installationPath -If ([string]::IsNullOrEmpty("$vsPath")) { - Write-Error "Failed to find Visual Studio 2019 installation. Aborting." -ErrorAction Stop -} -Write-Host "Using Visual Studio installation at: ${vsPath}" -ForegroundColor Yellow - - -# -# Make sure the Visual Studio Command Prompt variables are set. -# -If (Test-Path env:LIBPATH) { - Write-Host "Visual Studio Command Prompt variables already set." -ForegroundColor Yellow -} Else { - # Load VC vars - Push-Location "${vsPath}\VC\Auxiliary\Build" - cmd /c "vcvarsall.bat x64&set" | - ForEach-Object { - If ($_ -match "=") { - $v = $_.split("="); Set-Item -Force -Path "ENV:\$($v[0])" -Value "$($v[1])" - } - } - Pop-Location - Write-Host "Visual Studio Command Prompt variables set." -ForegroundColor Yellow -} - diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt deleted file mode 100644 index 75e5393..0000000 --- a/shaders/CMakeLists.txt +++ /dev/null @@ -1,71 +0,0 @@ - -include("${DONUT_PATH}/compileshaders.cmake") -file(GLOB shaders "*.h*" "LightingPasses/*.h*" "DebugViz/*.h*" "../rtxdi-runtime/shaders/*.hlsl" "../rtxdi-runtime/include/*.hlsli") - -set(project rtxdi-sample) -set(folder "RTXDI SDK") -set(shaders_target rtxdi-sample-shaders) - -add_custom_target(${shaders_target} - DEPENDS ShaderMake - SOURCES ${shaders} Shaders.cfg) - -if(TARGET NRD) - set(NRD_OPTIONS -I "${CMAKE_CURRENT_SOURCE_DIR}/../NRD/Shaders/Include" -D WITH_NRD -D NRD_USE_OCT_NORMAL_ENCODING=0 -D NRD_USE_MATERIAL_ID=0) -else() - set(NRD_OPTIONS --relaxedInclude NRD.hlsli) -endif() - -set (OUTPUT_PATH_BASE "${CMAKE_BINARY_DIR}/bin/shaders/rtxdi-sample") - - if (WIN32) - set (USE_API_OPTION --useAPI) - else() - set (USE_API_OPTION "") - endif() - -if (DONUT_WITH_DX12) - set(DX12_COMPILER_OPTIONS - --platform DXIL - --shaderModel 6_5 - --binaryBlob - --outputExt .bin - -I ${DONUT_SHADER_INCLUDE_DIR} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../rtxdi-runtime/include - --relaxedInclude "../Types.h" - ${NRD_OPTIONS} - ${USE_API_OPTION} - --compiler ${DXC_PATH}) - - add_custom_command(TARGET ${shaders_target} PRE_BUILD - COMMAND ShaderMake - --config ${CMAKE_CURRENT_SOURCE_DIR}/Shaders.cfg - --out ${OUTPUT_PATH_BASE}/dxil - ${DX12_COMPILER_OPTIONS}) -endif() - -if (DONUT_WITH_VULKAN) - set(VULKAN_COMPILER_OPTIONS - --platform SPIRV - --shaderModel 6_5 - --vulkanVersion 1.2 - --binaryBlob - --outputExt .bin - -I ${DONUT_SHADER_INCLUDE_DIR} - -I ${CMAKE_CURRENT_SOURCE_DIR}/../rtxdi-runtime/include - --relaxedInclude "../Types.h" - ${NRD_OPTIONS} - ${USE_API_OPTION} - ${NVRHI_DEFAULT_VK_REGISTER_OFFSETS} - -D SPIRV - --compiler ${DXC_SPIRV_PATH}) - - add_custom_command(TARGET ${shaders_target} PRE_BUILD - COMMAND ShaderMake - --config ${CMAKE_CURRENT_SOURCE_DIR}/Shaders.cfg - --out ${OUTPUT_PATH_BASE}/spirv - ${VULKAN_COMPILER_OPTIONS}) -endif() - -set_target_properties(${shaders_target} PROPERTIES FOLDER ${folder}) -set_source_files_properties(${shaders} PROPERTIES VS_TOOL_OVERRIDE "None") diff --git a/shaders/LightingPasses/RtxdiApplicationBridge.hlsli b/shaders/LightingPasses/RtxdiApplicationBridge.hlsli deleted file mode 100644 index 722f580..0000000 --- a/shaders/LightingPasses/RtxdiApplicationBridge.hlsli +++ /dev/null @@ -1,904 +0,0 @@ -/*************************************************************************** - # Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved. - # - # NVIDIA CORPORATION and its licensors retain all intellectual property - # and proprietary rights in and to this software, related documentation - # and any modifications thereto. Any use, reproduction, disclosure or - # distribution of this software and related documentation without an express - # license agreement from NVIDIA CORPORATION is strictly prohibited. - **************************************************************************/ - -/* -This header file is the bridge between the RTXDI resampling functions -and the application resources and parts of shader functionality. - -The RTXDI SDK provides the resampling logic, and the application provides -other necessary aspects: - - Material BRDF evaluation; - - Ray tracing and transparent/alpha-tested material processing; - - Light sampling functions and emission profiles. - -The structures and functions that are necessary for SDK operation -start with the RAB_ prefix (for RTXDI-Application Bridge). - -All structures defined here are opaque for the SDK, meaning that -it makes no assumptions about their contents, they are just passed -between the bridge functions. -*/ - -#ifndef RTXDI_APPLICATION_BRIDGE_HLSLI -#define RTXDI_APPLICATION_BRIDGE_HLSLI - -#include -#include - -#include "../ShaderParameters.h" -#include "../SceneGeometry.hlsli" -#include "../GBufferHelpers.hlsli" - -// G-buffer resources -Texture2D t_GBufferDepth : register(t0); -Texture2D t_GBufferNormals : register(t1); -Texture2D t_GBufferGeoNormals : register(t2); -Texture2D t_GBufferDiffuseAlbedo : register(t3); -Texture2D t_GBufferSpecularRough : register(t4); -Texture2D t_PrevGBufferDepth : register(t5); -Texture2D t_PrevGBufferNormals : register(t6); -Texture2D t_PrevGBufferGeoNormals : register(t7); -Texture2D t_PrevGBufferDiffuseAlbedo : register(t8); -Texture2D t_PrevGBufferSpecularRough : register(t9); -Texture2D t_PrevRestirLuminance : register(t10); -Texture2D t_MotionVectors : register(t11); -Texture2D t_DenoiserNormalRoughness : register(t12); - -// Scene resources -RaytracingAccelerationStructure SceneBVH : register(t30); -RaytracingAccelerationStructure PrevSceneBVH : register(t31); -StructuredBuffer t_InstanceData : register(t32); -StructuredBuffer t_GeometryData : register(t33); -StructuredBuffer t_MaterialConstants : register(t34); - -// RTXDI resources -StructuredBuffer t_LightDataBuffer : register(t20); -Buffer t_NeighborOffsets : register(t21); -Buffer t_LightIndexMappingBuffer : register(t22); -Texture2D t_EnvironmentPdfTexture : register(t23); -Texture2D t_LocalLightPdfTexture : register(t24); -StructuredBuffer t_GeometryInstanceToLight : register(t25); - -// Screen-sized UAVs -RWStructuredBuffer u_LightReservoirs : register(u0); -RWTexture2D u_DiffuseLighting : register(u1); -RWTexture2D u_SpecularLighting : register(u2); -RWTexture2D u_TemporalSamplePositions : register(u3); -RWTexture2DArray u_Gradients : register(u4); -RWTexture2D u_RestirLuminance : register(u5); -RWStructuredBuffer u_GIReservoirs : register(u6); - -// RTXDI UAVs -RWBuffer u_RisBuffer : register(u10); -RWBuffer u_RisLightDataBuffer : register(u11); -RWBuffer u_RayCountBuffer : register(u12); -RWStructuredBuffer u_SecondaryGBuffer : register(u13); - -// Other -ConstantBuffer g_Const : register(b0); -VK_PUSH_CONSTANT ConstantBuffer g_PerPassConstants : register(b1); -SamplerState s_MaterialSampler : register(s0); -SamplerState s_EnvironmentSampler : register(s1); - -#define RTXDI_RIS_BUFFER u_RisBuffer -#define RTXDI_LIGHT_RESERVOIR_BUFFER u_LightReservoirs -#define RTXDI_NEIGHBOR_OFFSETS_BUFFER t_NeighborOffsets -#define RTXDI_GI_RESERVOIR_BUFFER u_GIReservoirs - -#define IES_SAMPLER s_EnvironmentSampler - -#include "../PolymorphicLight.hlsli" - -static const bool kSpecularOnly = false; -static const float kMinRoughness = 0.05f; - -struct RAB_Surface -{ - float3 worldPos; - float3 viewDir; - float viewDepth; - float3 normal; - float3 geoNormal; - float3 diffuseAlbedo; - float3 specularF0; - float roughness; - float diffuseProbability; -}; - -struct RAB_LightSample -{ - float3 position; - float3 normal; - float3 radiance; - float solidAnglePdf; - PolymorphicLightType lightType; -}; - -typedef PolymorphicLightInfo RAB_LightInfo; -typedef RandomSamplerState RAB_RandomSamplerState; - -float getSurfaceDiffuseProbability(RAB_Surface surface) -{ - float diffuseWeight = calcLuminance(surface.diffuseAlbedo); - float specularWeight = calcLuminance(Schlick_Fresnel(surface.specularF0, dot(surface.viewDir, surface.normal))); - float sumWeights = diffuseWeight + specularWeight; - return sumWeights < 1e-7f ? 1.f : (diffuseWeight / sumWeights); -} - -struct SplitBrdf -{ - float demodulatedDiffuse; - float3 specular; -}; - -SplitBrdf EvaluateBrdf(RAB_Surface surface, float3 samplePosition) -{ - float3 N = surface.normal; - float3 V = surface.viewDir; - float3 L = normalize(samplePosition - surface.worldPos); - - SplitBrdf brdf; - brdf.demodulatedDiffuse = Lambert(surface.normal, -L); - if (surface.roughness == 0) - brdf.specular = 0; - else - brdf.specular = GGX_times_NdotL(V, L, surface.normal, max(surface.roughness, kMinRoughness), surface.specularF0); - return brdf; -} - -RAB_Surface RAB_EmptySurface() -{ - RAB_Surface surface = (RAB_Surface)0; - surface.viewDepth = BACKGROUND_DEPTH; - return surface; -} - -RAB_LightInfo RAB_EmptyLightInfo() -{ - return (RAB_LightInfo)0; -} - -RAB_LightSample RAB_EmptyLightSample() -{ - return (RAB_LightSample)0; -} - -struct RayPayload -{ - float3 throughput; - float committedRayT; - uint instanceID; - uint geometryIndex; - uint primitiveIndex; - bool frontFace; - float2 barycentrics; -}; - -RayDesc setupVisibilityRay(RAB_Surface surface, float3 samplePosition, float offset = 0.001) -{ - float3 L = samplePosition - surface.worldPos; - - RayDesc ray; - ray.TMin = offset; - ray.TMax = max(offset, length(L) - offset * 2); - ray.Direction = normalize(L); - ray.Origin = surface.worldPos; - - return ray; -} - -bool considerTransparentMaterial(uint instanceIndex, uint geometryIndex, uint triangleIndex, float2 rayBarycentrics, inout float3 throughput) -{ - GeometrySample gs = getGeometryFromHit( - instanceIndex, - geometryIndex, - triangleIndex, - rayBarycentrics, - GeomAttr_TexCoord, - t_InstanceData, t_GeometryData, t_MaterialConstants); - - MaterialSample ms = sampleGeometryMaterial(gs, 0, 0, 0, - MatAttr_BaseColor | MatAttr_Transmission, s_MaterialSampler); - - bool alphaMask = ms.opacity >= gs.material.alphaCutoff; - - if (gs.material.domain == MaterialDomain_AlphaTested) - return alphaMask; - - if (gs.material.domain == MaterialDomain_AlphaBlended) - { - throughput *= (1.0 - ms.opacity); - return false; - } - - if (gs.material.domain == MaterialDomain_Transmissive || - (gs.material.domain == MaterialDomain_TransmissiveAlphaTested && alphaMask) || - gs.material.domain == MaterialDomain_TransmissiveAlphaBlended) - { - throughput *= ms.transmission; - - if (ms.hasMetalRoughParams) - throughput *= (1.0 - ms.metalness) * ms.baseColor; - - if (gs.material.domain == MaterialDomain_TransmissiveAlphaBlended) - throughput *= (1.0 - ms.opacity); - - return all(throughput == 0); - } - - return false; -} - -#if !USE_RAY_QUERY -struct RayAttributes -{ - float2 uv; -}; - -[shader("miss")] -void Miss(inout RayPayload payload : SV_RayPayload) -{ -} - -[shader("closesthit")] -void ClosestHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) -{ - payload.committedRayT = RayTCurrent(); - payload.instanceID = InstanceID(); - payload.geometryIndex = GeometryIndex(); - payload.primitiveIndex = PrimitiveIndex(); - payload.frontFace = HitKind() == HIT_KIND_TRIANGLE_FRONT_FACE; - payload.barycentrics = attrib.uv; -} - -[shader("anyhit")] -void AnyHit(inout RayPayload payload : SV_RayPayload, in RayAttributes attrib : SV_IntersectionAttributes) -{ - if (!considerTransparentMaterial(InstanceID(), GeometryIndex(), PrimitiveIndex(), attrib.uv, payload.throughput)) - IgnoreHit(); -} -#endif - -bool GetConservativeVisibility(RaytracingAccelerationStructure accelStruct, RAB_Surface surface, float3 samplePosition) -{ - RayDesc ray = setupVisibilityRay(surface, samplePosition); - -#if USE_RAY_QUERY - RayQuery rayQuery; - - rayQuery.TraceRayInline(accelStruct, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); - - rayQuery.Proceed(); - - bool visible = (rayQuery.CommittedStatus() == COMMITTED_NOTHING); -#else - RayPayload payload = (RayPayload)0; - payload.instanceID = ~0u; - payload.throughput = 1.0; - - TraceRay(accelStruct, RAY_FLAG_CULL_NON_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, INSTANCE_MASK_OPAQUE, 0, 0, 0, ray, payload); - - bool visible = (payload.instanceID == ~0u); -#endif - - REPORT_RAY(!visible); - - return visible; -} - -// Traces a cheap visibility ray that returns approximate, conservative visibility -// between the surface and the light sample. Conservative means if unsure, assume the light is visible. -// Significant differences between this conservative visibility and the final one will result in more noise. -// This function is used in the spatial resampling functions for ray traced bias correction. -bool RAB_GetConservativeVisibility(RAB_Surface surface, RAB_LightSample lightSample) -{ - return GetConservativeVisibility(SceneBVH, surface, lightSample.position); -} - -// Same as RAB_GetConservativeVisibility but for temporal resampling. -// When the previous frame TLAS and BLAS are available, the implementation should use the previous position and the previous AS. -// When they are not available, use the current AS. That will result in transient bias. -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, RAB_LightSample lightSample) -{ - if (g_Const.enablePreviousTLAS) - return GetConservativeVisibility(PrevSceneBVH, previousSurface, lightSample.position); - else - return GetConservativeVisibility(SceneBVH, currentSurface, lightSample.position); -} - -// Traces an expensive visibility ray that considers all alpha tested and transparent geometry along the way. -// Only used for final shading. -// Not a required bridge function. -float3 GetFinalVisibility(RaytracingAccelerationStructure accelStruct, RAB_Surface surface, float3 samplePosition) -{ - RayDesc ray = setupVisibilityRay(surface, samplePosition, 0.01); - - uint instanceMask = INSTANCE_MASK_OPAQUE; - uint rayFlags = RAY_FLAG_NONE; - - if (g_Const.sceneConstants.enableAlphaTestedGeometry) - instanceMask |= INSTANCE_MASK_ALPHA_TESTED; - - if (g_Const.sceneConstants.enableTransparentGeometry) - instanceMask |= INSTANCE_MASK_TRANSPARENT; - - if (!g_Const.sceneConstants.enableTransparentGeometry && !g_Const.sceneConstants.enableAlphaTestedGeometry) - rayFlags |= RAY_FLAG_CULL_NON_OPAQUE; - - RayPayload payload = (RayPayload)0; - payload.instanceID = ~0u; - payload.throughput = 1.0; - -#if USE_RAY_QUERY - RayQuery rayQuery; - - rayQuery.TraceRayInline(accelStruct, rayFlags, instanceMask, ray); - - while (rayQuery.Proceed()) - { - if (rayQuery.CandidateType() == CANDIDATE_NON_OPAQUE_TRIANGLE) - { - if (considerTransparentMaterial( - rayQuery.CandidateInstanceID(), - rayQuery.CandidateGeometryIndex(), - rayQuery.CandidatePrimitiveIndex(), - rayQuery.CandidateTriangleBarycentrics(), - payload.throughput)) - { - rayQuery.CommitNonOpaqueTriangleHit(); - } - } - } - - if (rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT) - { - payload.instanceID = rayQuery.CommittedInstanceID(); - payload.primitiveIndex = rayQuery.CommittedPrimitiveIndex(); - payload.geometryIndex = rayQuery.CommittedGeometryIndex(); - payload.barycentrics = rayQuery.CommittedTriangleBarycentrics(); - payload.committedRayT = rayQuery.CommittedRayT(); - payload.frontFace = rayQuery.CommittedTriangleFrontFace(); - } -#else - TraceRay(accelStruct, rayFlags, instanceMask, 0, 0, 0, ray, payload); -#endif - - REPORT_RAY(payload.instanceID != ~0u); - - if(payload.instanceID == ~0u) - return payload.throughput.rgb; - else - return 0; -} - -// This function is called in the spatial resampling passes to make sure that -// the samples actually land on the screen and not outside of its boundaries. -// It can clamp the position or reflect it across the nearest screen edge. -// The simplest implementation will just return the input pixelPosition. -int2 RAB_ClampSamplePositionIntoView(int2 pixelPosition, bool previousFrame) -{ - int width = int(g_Const.view.viewportSize.x); - int height = int(g_Const.view.viewportSize.y); - - // Reflect the position across the screen edges. - // Compared to simple clamping, this prevents the spread of colorful blobs from screen edges. - if (pixelPosition.x < 0) pixelPosition.x = -pixelPosition.x; - if (pixelPosition.y < 0) pixelPosition.y = -pixelPosition.y; - if (pixelPosition.x >= width) pixelPosition.x = 2 * width - pixelPosition.x - 1; - if (pixelPosition.y >= height) pixelPosition.y = 2 * height - pixelPosition.y - 1; - - return pixelPosition; -} - -RAB_Surface GetGBufferSurface( - int2 pixelPosition, - PlanarViewConstants view, - Texture2D depthTexture, - Texture2D normalsTexture, - Texture2D geoNormalsTexture, - Texture2D diffuseAlbedoTexture, - Texture2D specularRoughTexture) -{ - RAB_Surface surface = RAB_EmptySurface(); - - if (any(pixelPosition >= view.viewportSize)) - return surface; - - surface.viewDepth = depthTexture[pixelPosition]; - - if(surface.viewDepth == BACKGROUND_DEPTH) - return surface; - - surface.normal = octToNdirUnorm32(normalsTexture[pixelPosition]); - surface.geoNormal = octToNdirUnorm32(geoNormalsTexture[pixelPosition]); - surface.diffuseAlbedo = Unpack_R11G11B10_UFLOAT(diffuseAlbedoTexture[pixelPosition]).rgb; - float4 specularRough = Unpack_R8G8B8A8_Gamma_UFLOAT(specularRoughTexture[pixelPosition]); - surface.specularF0 = specularRough.rgb; - surface.roughness = specularRough.a; - surface.worldPos = viewDepthToWorldPos(view, pixelPosition, surface.viewDepth); - surface.viewDir = normalize(view.cameraDirectionOrPosition.xyz - surface.worldPos); - surface.diffuseProbability = getSurfaceDiffuseProbability(surface); - - return surface; -} - - -// Reads the G-buffer, either the current one or the previous one, and returns a surface. -// If the provided pixel position is outside of the viewport bounds, the surface -// should indicate that it's invalid when RAB_IsSurfaceValid is called on it. -RAB_Surface RAB_GetGBufferSurface(int2 pixelPosition, bool previousFrame) -{ - if(previousFrame) - { - return GetGBufferSurface( - pixelPosition, - g_Const.prevView, - t_PrevGBufferDepth, - t_PrevGBufferNormals, - t_PrevGBufferGeoNormals, - t_PrevGBufferDiffuseAlbedo, - t_PrevGBufferSpecularRough); - } - else - { - return GetGBufferSurface( - pixelPosition, - g_Const.view, - t_GBufferDepth, - t_GBufferNormals, - t_GBufferGeoNormals, - t_GBufferDiffuseAlbedo, - t_GBufferSpecularRough); - } -} - -// Checks if the given surface is valid, see RAB_GetGBufferSurface. -bool RAB_IsSurfaceValid(RAB_Surface surface) -{ - return surface.viewDepth != BACKGROUND_DEPTH; -} - -// Returns the world position of the given surface -float3 RAB_GetSurfaceWorldPos(RAB_Surface surface) -{ - return surface.worldPos; -} - -// Returns the world shading normal of the given surface -float3 RAB_GetSurfaceNormal(RAB_Surface surface) -{ - return surface.normal; -} - -// Returns the linear depth of the given surface. -// It doesn't have to be linear depth in a strict sense (i.e. viewPos.z), -// and can be distance to the camera or primary path length instead. -// Just make sure that the motion vectors' .z component follows the same logic. -float RAB_GetSurfaceLinearDepth(RAB_Surface surface) -{ - return surface.viewDepth; -} - -// Initialized the random sampler for a given pixel or tile index. -// The pass parameter is provided to help generate different RNG sequences -// for different resampling passes, which is important for image quality. -// In general, a high quality RNG is critical to get good results from ReSTIR. -// A table-based blue noise RNG dose not provide enough entropy, for example. -RAB_RandomSamplerState RAB_InitRandomSampler(uint2 index, uint pass) -{ - return initRandomSampler(index, g_Const.frameIndex + pass * 13); -} - -// Draws a random number X from the sampler, so that (0 <= X < 1). -float RAB_GetNextRandom(inout RAB_RandomSamplerState rng) -{ - return sampleUniformRng(rng); -} - -float2 RAB_GetEnvironmentMapRandXYFromDir(float3 worldDir) -{ - float2 uv = directionToEquirectUV(worldDir); - uv.x -= g_Const.sceneConstants.environmentRotation; - uv = frac(uv); - return uv; -} - -// Computes the probability of a particular direction being sampled from the environment map -// relative to all the other possible directions, based on the environment map pdf texture. -float RAB_EvaluateEnvironmentMapSamplingPdf(float3 L) -{ - if (!g_Const.restirDI.initialSamplingParams.environmentMapImportanceSampling) - return 1.0; - - float2 uv = RAB_GetEnvironmentMapRandXYFromDir(L); - - uint2 pdfTextureSize = g_Const.environmentPdfTextureSize.xy; - uint2 texelPosition = uint2(pdfTextureSize * uv); - float texelValue = t_EnvironmentPdfTexture[texelPosition].r; - - int lastMipLevel = max(0, int(floor(log2(max(pdfTextureSize.x, pdfTextureSize.y))))); - float averageValue = t_EnvironmentPdfTexture.mips[lastMipLevel][uint2(0, 0)].x; - - // The single texel in the last mip level is effectively the average of all texels in mip 0, - // padded to a square shape with zeros. So, in case the PDF texture has a 2:1 aspect ratio, - // that texel's value is only half of the true average of the rectangular input texture. - // Compensate for that by assuming that the input texture is square. - float sum = averageValue * square(1u << lastMipLevel); - - return texelValue / sum; -} - -// Evaluates pdf for a particular light -float RAB_EvaluateLocalLightSourcePdf(uint lightIndex) -{ - uint2 pdfTextureSize = g_Const.localLightPdfTextureSize.xy; - uint2 texelPosition = RTXDI_LinearIndexToZCurve(lightIndex); - float texelValue = t_LocalLightPdfTexture[texelPosition].r; - - int lastMipLevel = max(0, int(floor(log2(max(pdfTextureSize.x, pdfTextureSize.y))))); - float averageValue = t_LocalLightPdfTexture.mips[lastMipLevel][uint2(0, 0)].x; - - // See the comment at 'sum' in RAB_EvaluateEnvironmentMapSamplingPdf. - // The same texture shape considerations apply to local lights. - float sum = averageValue * square(1u << lastMipLevel); - - return texelValue / sum; -} - -float3 worldToTangent(RAB_Surface surface, float3 w) -{ - // reconstruct tangent frame based off worldspace normal - // this is ok for isotropic BRDFs - // for anisotropic BRDFs, we need a user defined tangent - float3 tangent; - float3 bitangent; - ConstructONB(surface.normal, tangent, bitangent); - - return float3(dot(bitangent, w), dot(tangent, w), dot(surface.normal, w)); -} - -float3 tangentToWorld(RAB_Surface surface, float3 h) -{ - // reconstruct tangent frame based off worldspace normal - // this is ok for isotropic BRDFs - // for anisotropic BRDFs, we need a user defined tangent - float3 tangent; - float3 bitangent; - ConstructONB(surface.normal, tangent, bitangent); - - return bitangent * h.x + tangent * h.y + surface.normal * h.z; -} - -bool RAB_GetSurfaceBrdfSample(RAB_Surface surface, inout RAB_RandomSamplerState rng, out float3 dir) -{ - float3 rand; - rand.x = RAB_GetNextRandom(rng); - rand.y = RAB_GetNextRandom(rng); - rand.z = RAB_GetNextRandom(rng); - if (rand.x < surface.diffuseProbability) - { - if (kSpecularOnly) - return false; - - float pdf; - float3 h = SampleCosHemisphere(rand.yz, pdf); - dir = tangentToWorld(surface, h); - } - else - { - float3 Ve = normalize(worldToTangent(surface, surface.viewDir)); - float3 h = ImportanceSampleGGX_VNDF(rand.yz, max(surface.roughness, kMinRoughness), Ve, 1.0); - h = normalize(h); - dir = reflect(-surface.viewDir, tangentToWorld(surface, h)); - } - - return dot(surface.normal, dir) > 0.f; -} - -float RAB_GetSurfaceBrdfPdf(RAB_Surface surface, float3 dir) -{ - float cosTheta = saturate(dot(surface.normal, dir)); - float diffusePdf = kSpecularOnly ? 0.f : (cosTheta / M_PI); - float specularPdf = ImportanceSampleGGX_VNDF_PDF(max(surface.roughness, kMinRoughness), surface.normal, surface.viewDir, dir); - float pdf = cosTheta > 0.f ? lerp(specularPdf, diffusePdf, surface.diffuseProbability) : 0.f; - return pdf; -} - -// Computes the weight of the given light samples when the given surface is -// shaded using that light sample. Exact or approximate BRDF evaluation can be -// used to compute the weight. ReSTIR will converge to a correct lighting result -// even if all samples have a fixed weight of 1.0, but that will be very noisy. -// Scaling of the weights can be arbitrary, as long as it's consistent -// between all lights and surfaces. -float RAB_GetLightSampleTargetPdfForSurface(RAB_LightSample lightSample, RAB_Surface surface) -{ - if (lightSample.solidAnglePdf <= 0) - return 0; - - float3 L = normalize(lightSample.position - surface.worldPos); - - if (dot(L, surface.geoNormal) <= 0) - return 0; - - float3 V = surface.viewDir; - - float d = Lambert(surface.normal, -L); - float3 s; - if (surface.roughness == 0) - s = 0; - else - s = GGX_times_NdotL(V, L, surface.normal, max(surface.roughness, kMinRoughness), surface.specularF0); - - float3 reflectedRadiance = lightSample.radiance * (d * surface.diffuseAlbedo + s); - - return calcLuminance(reflectedRadiance) / lightSample.solidAnglePdf; -} - -// Computes the weight of the given light for arbitrary surfaces located inside -// the specified volume. Used for world-space light grid construction. -float RAB_GetLightTargetPdfForVolume(RAB_LightInfo light, float3 volumeCenter, float volumeRadius) -{ - return PolymorphicLight::getWeightForVolume(light, volumeCenter, volumeRadius); -} - -// Samples a polymorphic light relative to the given receiver surface. -// For most light types, the "uv" parameter is just a pair of uniform random numbers, originally -// produced by the RAB_GetNextRandom function and then stored in light reservoirs. -// For importance sampled environment lights, the "uv" parameter has the texture coordinates -// in the PDF texture, normalized to the (0..1) range. -RAB_LightSample RAB_SamplePolymorphicLight(RAB_LightInfo lightInfo, RAB_Surface surface, float2 uv) -{ - PolymorphicLightSample pls = PolymorphicLight::calcSample(lightInfo, uv, surface.worldPos); - - RAB_LightSample lightSample; - lightSample.position = pls.position; - lightSample.normal = pls.normal; - lightSample.radiance = pls.radiance; - lightSample.solidAnglePdf = pls.solidAnglePdf; - lightSample.lightType = getLightType(lightInfo); - return lightSample; -} - -void RAB_GetLightDirDistance(RAB_Surface surface, RAB_LightSample lightSample, - out float3 o_lightDir, - out float o_lightDistance) -{ - if (lightSample.lightType == PolymorphicLightType::kEnvironment) - { - o_lightDir = -lightSample.normal; - o_lightDistance = DISTANT_LIGHT_DISTANCE; - } - else - { - float3 toLight = lightSample.position - surface.worldPos; - o_lightDistance = length(toLight); - o_lightDir = toLight / o_lightDistance; - } -} - -bool RAB_IsAnalyticLightSample(RAB_LightSample lightSample) -{ - return lightSample.lightType != PolymorphicLightType::kTriangle && - lightSample.lightType != PolymorphicLightType::kEnvironment; -} - -float RAB_LightSampleSolidAnglePdf(RAB_LightSample lightSample) -{ - return lightSample.solidAnglePdf; -} - -// Loads polymorphic light data from the global light buffer. -RAB_LightInfo RAB_LoadLightInfo(uint index, bool previousFrame) -{ - return t_LightDataBuffer[index]; -} - -// Loads triangle light data from a tile produced by the presampling pass. -RAB_LightInfo RAB_LoadCompactLightInfo(uint linearIndex) -{ - uint4 packedData1, packedData2; - packedData1 = u_RisLightDataBuffer[linearIndex * 2 + 0]; - packedData2 = u_RisLightDataBuffer[linearIndex * 2 + 1]; - return unpackCompactLightInfo(packedData1, packedData2); -} - -// Stores triangle light data into a tile. -// Returns true if this light can be stored in a tile (i.e. compacted). -// If it cannot, for example it's a shaped light, this function returns false and doesn't store. -// A basic implementation can ignore this feature and always return false, which is just slower. -bool RAB_StoreCompactLightInfo(uint linearIndex, RAB_LightInfo lightInfo) -{ - uint4 data1, data2; - if (!packCompactLightInfo(lightInfo, data1, data2)) - return false; - - u_RisLightDataBuffer[linearIndex * 2 + 0] = data1; - u_RisLightDataBuffer[linearIndex * 2 + 1] = data2; - - return true; -} - -// Translates the light index from the current frame to the previous frame (if currentToPrevious = true) -// or from the previous frame to the current frame (if currentToPrevious = false). -// Returns the new index, or a negative number if the light does not exist in the other frame. -int RAB_TranslateLightIndex(uint lightIndex, bool currentToPrevious) -{ - // In this implementation, the mapping buffer contains both forward and reverse mappings, - // stored at different offsets, so we don't care about the currentToPrevious parameter. - uint mappedIndexPlusOne = t_LightIndexMappingBuffer[lightIndex]; - - // The mappings are stored offset by 1 to differentiate between valid and invalid mappings. - // The buffer is cleared with zeros which indicate an invalid mapping. - // Subtract that one to make this function return expected values. - return int(mappedIndexPlusOne) - 1; -} - -// Forward declare the SDK function that's used in RAB_AreMaterialsSimilar -bool RTXDI_CompareRelativeDifference(float reference, float candidate, float threshold); - -// Compares the materials of two surfaces, returns true if the surfaces -// are similar enough that we can share the light reservoirs between them. -// If unsure, just return true. -bool RAB_AreMaterialsSimilar(RAB_Surface a, RAB_Surface b) -{ - const float roughnessThreshold = 0.5; - const float reflectivityThreshold = 0.25; - const float albedoThreshold = 0.25; - - if (!RTXDI_CompareRelativeDifference(a.roughness, b.roughness, roughnessThreshold)) - return false; - - if (abs(calcLuminance(a.specularF0) - calcLuminance(b.specularF0)) > reflectivityThreshold) - return false; - - if (abs(calcLuminance(a.diffuseAlbedo) - calcLuminance(b.diffuseAlbedo)) > albedoThreshold) - return false; - - return true; -} - -float3 GetEnvironmentRadiance(float3 direction) -{ - if (!g_Const.sceneConstants.enableEnvironmentMap) - return 0; - - Texture2D environmentLatLongMap = t_BindlessTextures[g_Const.sceneConstants.environmentMapTextureIndex]; - - float2 uv = directionToEquirectUV(direction); - uv.x -= g_Const.sceneConstants.environmentRotation; - - float3 environmentRadiance = environmentLatLongMap.SampleLevel(s_EnvironmentSampler, uv, 0).rgb; - environmentRadiance *= g_Const.sceneConstants.environmentScale; - - return environmentRadiance; -} - -bool IsComplexSurface(int2 pixelPosition, RAB_Surface surface) -{ - // Use a simple classification of surfaces into simple and complex based on the roughness. - // The PostprocessGBuffer pass modifies the surface roughness and writes the DenoiserNormalRoughness - // channel where the roughness is preserved. The roughness stored in the regular G-buffer is modified - // based on the surface curvature around the current pixel. If the surface is curved, roughness increases. - // Detect that increase here and disable permutation sampling based on a threshold. - // Other classification methods can be employed for better quality. - float originalRoughness = t_DenoiserNormalRoughness[pixelPosition].a; - return originalRoughness < (surface.roughness * g_Const.restirDI.temporalResamplingParams.permutationSamplingThreshold); -} - -uint getLightIndex(uint instanceID, uint geometryIndex, uint primitiveIndex) -{ - uint lightIndex = RTXDI_InvalidLightIndex; - InstanceData hitInstance = t_InstanceData[instanceID]; - uint geometryInstanceIndex = hitInstance.firstGeometryInstanceIndex + geometryIndex; - lightIndex = t_GeometryInstanceToLight[geometryInstanceIndex]; - if (lightIndex != RTXDI_InvalidLightIndex) - lightIndex += primitiveIndex; - return lightIndex; -} - - -// Return true if anything was hit. If false, RTXDI will do environment map sampling -// o_lightIndex: If hit, must be a valid light index for RAB_LoadLightInfo, if no local light was hit, must be RTXDI_InvalidLightIndex -// randXY: The randXY that corresponds to the hit location and is the same used for RAB_SamplePolymorphicLight -bool RAB_TraceRayForLocalLight(float3 origin, float3 direction, float tMin, float tMax, - out uint o_lightIndex, out float2 o_randXY) -{ - o_lightIndex = RTXDI_InvalidLightIndex; - o_randXY = 0; - - RayDesc ray; - ray.Origin = origin; - ray.Direction = direction; - ray.TMin = tMin; - ray.TMax = tMax; - - float2 hitUV; - bool hitAnything; -#if USE_RAY_QUERY - RayQuery rayQuery; - rayQuery.TraceRayInline(SceneBVH, RAY_FLAG_NONE, INSTANCE_MASK_OPAQUE, ray); - rayQuery.Proceed(); - - hitAnything = rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT; - if (hitAnything) - { - o_lightIndex = getLightIndex(rayQuery.CommittedInstanceID(), rayQuery.CommittedGeometryIndex(), rayQuery.CommittedPrimitiveIndex()); - hitUV = rayQuery.CommittedTriangleBarycentrics(); - } -#else - RayPayload payload = (RayPayload)0; - payload.instanceID = ~0u; - payload.throughput = 1.0; - - TraceRay(SceneBVH, RAY_FLAG_CULL_NON_OPAQUE | RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES, INSTANCE_MASK_OPAQUE, 0, 0, 0, ray, payload); - hitAnything = payload.instanceID != ~0u; - if (hitAnything) - { - o_lightIndex = getLightIndex(payload.instanceID, payload.geometryIndex, payload.primitiveIndex); - hitUV = payload.barycentrics; - } -#endif - - if (o_lightIndex != RTXDI_InvalidLightIndex) - { - o_randXY = randomFromBarycentric(hitUVToBarycentric(hitUV)); - } - - return hitAnything; -} - - -// Check if the sample is fine to be used as a valid spatial sample. -// This function also be able to clamp the value of the Jacobian. -bool RAB_ValidateGISampleWithJacobian(inout float jacobian) -{ - // Sold angle ratio is too different. Discard the sample. - if (jacobian > 10.0 || jacobian < 1 / 10.0) { - return false; - } - - // clamp Jacobian. - jacobian = clamp(jacobian, 1 / 3.0, 3.0); - - return true; -} - -// Computes the weight of the given GI sample when the given surface is shaded using that GI sample. -float RAB_GetGISampleTargetPdfForSurface(float3 samplePosition, float3 sampleRadiance, RAB_Surface surface) -{ - SplitBrdf brdf = EvaluateBrdf(surface, samplePosition); - - float3 reflectedRadiance = sampleRadiance * (brdf.demodulatedDiffuse * surface.diffuseAlbedo + brdf.specular); - - return RTXDI_Luminance(reflectedRadiance); -} - -// Traces a cheap visibility ray that returns approximate, conservative visibility -// between the surface and the light sample. Conservative means if unsure, assume the light is visible. -// Significant differences between this conservative visibility and the final one will result in more noise. -// This function is used in the spatial resampling functions for ray traced bias correction. -bool RAB_GetConservativeVisibility(RAB_Surface surface, float3 samplePosition) -{ - return GetConservativeVisibility(SceneBVH, surface, samplePosition); -} - -// Same as RAB_GetConservativeVisibility but for temporal resampling. -// When the previous frame TLAS and BLAS are available, the implementation should use the previous position and the previous AS. -// When they are not available, use the current AS. That will result in transient bias. -bool RAB_GetTemporalConservativeVisibility(RAB_Surface currentSurface, RAB_Surface previousSurface, float3 samplePosition) -{ - if (g_Const.enablePreviousTLAS) - return GetConservativeVisibility(PrevSceneBVH, previousSurface, samplePosition); - else - return GetConservativeVisibility(SceneBVH, currentSurface, samplePosition); -} - - -#endif // RTXDI_APPLICATION_BRIDGE_HLSLI diff --git a/shaders/Shaders.cfg b/shaders/Shaders.cfg deleted file mode 100644 index 4a14240..0000000 --- a/shaders/Shaders.cfg +++ /dev/null @@ -1,50 +0,0 @@ -RasterizedGBuffer.hlsl -T vs -E vs_main -RasterizedGBuffer.hlsl -T ps -E ps_main -D ALPHA_TESTED={0,1} -RaytracedGBuffer.hlsl -T cs -E main -D USE_RAY_QUERY=1 -RaytracedGBuffer.hlsl -T lib -D USE_RAY_QUERY=0 -CompositingPass.hlsl -T cs -E main -GlassPass.hlsl -T cs -E main -D USE_RAY_QUERY=1 -GlassPass.hlsl -T lib -D USE_RAY_QUERY=0 -AccumulationPass.hlsl -T cs -E main -RenderEnvironmentMap.hlsl -T cs -E main -PreprocessEnvironmentMap.hlsl -T cs -E main -D INPUT_ENVIRONMENT_MAP={0,1} -VisualizeHdrSignals.hlsl -T ps -E main -VisualizeConfidence.hlsl -T ps -E main -DlssExposure.hlsl -T cs -E main -PostprocessGBuffer.hlsl -T cs -E main -DebugViz/NDirOctUNorm32Viz.hlsl -T cs -E main -DebugViz/PackedR8G8B8A8GammaUFloatViz.hlsl -T cs -E main -DebugViz/PackedR11G11B10UFloatViz.hlsl -T cs -E main - -PrepareLights.hlsl -T cs -E main -LightingPasses/PresampleLights.hlsl -T cs -E main -LightingPasses/PresampleEnvironmentMap.hlsl -T cs -E main -LightingPasses/PresampleReGIR.hlsl -T cs -E main -D RTXDI_REGIR_MODE={RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DIGenerateInitialSamples.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DIGenerateInitialSamples.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DITemporalResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/DITemporalResampling.hlsl -T lib -D USE_RAY_QUERY=0 -LightingPasses/DISpatialResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/DISpatialResampling.hlsl -T lib -D USE_RAY_QUERY=0 -LightingPasses/DIFusedResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DIFusedResampling.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DIShadeSamples.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DIShadeSamples.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/DIComputeGradients.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/DIComputeGradients.hlsl -T lib -D USE_RAY_QUERY=0 - -LightingPasses/BrdfRayTracing.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/BrdfRayTracing.hlsl -T lib -D USE_RAY_QUERY=0 -LightingPasses/ShadeSecondarySurfaces.hlsl -T cs -E main -D USE_RAY_QUERY=1 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -LightingPasses/ShadeSecondarySurfaces.hlsl -T lib -D USE_RAY_QUERY=0 -D RTXDI_REGIR_MODE={RTXDI_REGIR_DISABLED,RTXDI_REGIR_GRID,RTXDI_REGIR_ONION} -FilterGradientsPass.hlsl -T cs -E main -ConfidencePass.hlsl -T cs -E main - -LightingPasses/GITemporalResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/GITemporalResampling.hlsl -T lib -E main -D USE_RAY_QUERY=0 -LightingPasses/GISpatialResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/GISpatialResampling.hlsl -T lib -E main -D USE_RAY_QUERY=0 -LightingPasses/GIFusedResampling.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/GIFusedResampling.hlsl -T lib -E main -D USE_RAY_QUERY=0 -LightingPasses/GIFinalShading.hlsl -T cs -E main -D USE_RAY_QUERY=1 -LightingPasses/GIFinalShading.hlsl -T lib -E main -D USE_RAY_QUERY=0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index ec1eb6a..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ - -file(GLOB sources "*.cpp" "*.h" "*/*.cpp" "*/*.h") - -set(project rtxdi-sample) -set(folder "RTXDI SDK") - -include(CMakeDependentOption) - -cmake_dependent_option(RTXDI_CONSOLE_APP "Build the sample as a console application" OFF WIN32 OFF) - -if (RTXDI_CONSOLE_APP) - add_executable(${project} ${sources}) - target_compile_definitions(${project} PRIVATE IS_CONSOLE_APP=1) -else() - add_executable(${project} WIN32 ${sources}) -endif() - -target_link_libraries(${project} donut_core donut_engine donut_app donut_render rtxdi-runtime cxxopts) -add_dependencies(${project} rtxdi-sample-shaders) -set_target_properties(${project} PROPERTIES FOLDER ${folder}) - -if (TARGET NRD) - target_compile_definitions(${project} PRIVATE WITH_NRD=1) - target_link_libraries(${project} NRD) - - # NRD doesn't add a public include path at this time, work around that - target_include_directories(${project} PRIVATE "${CMAKE_SOURCE_DIR}/NRD/Include") -endif() - -if (TARGET DLSS) - target_compile_definitions(${project} PRIVATE WITH_DLSS=1) - target_link_libraries(${project} DLSS) - add_custom_command(TARGET ${project} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${DLSS_SHARED_LIBRARY_PATH}" - "$/") -endif()