Bulk update nvpro-samples 05/17/21
Changing license from BSD-3 to Apache2
This commit is contained in:
parent
d370c2168b
commit
d2ade024c4
279 changed files with 7236 additions and 6905 deletions
|
|
@ -2,24 +2,24 @@ cmake_minimum_required(VERSION 3.9.6 FATAL_ERROR)
|
|||
project(vk_raytracing_tutorial)
|
||||
|
||||
#--------------------------------------------------------------------------------------------------
|
||||
# look for shared_sources 1) as a sub-folder 2) at some other locations
|
||||
# look for nvpro_core 1) as a sub-folder 2) at some other locations
|
||||
# this cannot be put anywhere else since we still didn't find setup.cmake yet
|
||||
if(NOT BASE_DIRECTORY)
|
||||
|
||||
find_path(BASE_DIRECTORY
|
||||
NAMES shared_sources/cmake/setup.cmake
|
||||
NAMES nvpro_core/cmake/setup.cmake
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/../..
|
||||
REQUIRED
|
||||
DOC "Directory containing shared_sources"
|
||||
DOC "Directory containing nvpro_core"
|
||||
)
|
||||
endif()
|
||||
|
||||
## Various functions and macros REQUIRED
|
||||
if(EXISTS ${BASE_DIRECTORY}/shared_sources/cmake/setup.cmake)
|
||||
include(${BASE_DIRECTORY}/shared_sources/cmake/setup.cmake)
|
||||
include(${BASE_DIRECTORY}/shared_sources/cmake/utilities.cmake)
|
||||
if(EXISTS ${BASE_DIRECTORY}/nvpro_core/cmake/setup.cmake)
|
||||
include(${BASE_DIRECTORY}/nvpro_core/cmake/setup.cmake)
|
||||
include(${BASE_DIRECTORY}/nvpro_core/cmake/utilities.cmake)
|
||||
else()
|
||||
message(FATAL_ERROR "could not find base directory, please set BASE_DIRECTORY to folder containing shared_sources")
|
||||
message(FATAL_ERROR "could not find base directory, please set BASE_DIRECTORY to folder containing nvpro_core")
|
||||
endif()
|
||||
|
||||
set(TUTO_KHR_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
|
@ -29,7 +29,7 @@ set(TUTO_KHR_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
|||
# Package shared by all projects
|
||||
_add_package_VulkanSDK()
|
||||
_add_package_ImGUI()
|
||||
_add_shared_sources_lib()
|
||||
_add_nvpro_core_lib()
|
||||
|
||||
message(STATUS "COPY ${CMAKE_CURRENT_SOURCE_DIR}/media to ${OUTPUT_PATH}")
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/media DESTINATION ${OUTPUT_PATH})
|
||||
|
|
@ -53,6 +53,7 @@ add_subdirectory(ray_tracing_rayquery)
|
|||
add_subdirectory(ray_tracing_reflections)
|
||||
add_subdirectory(ray_tracing_ao)
|
||||
add_subdirectory(ray_tracing_indirect_scissor)
|
||||
add_subdirectory(ray_tracing_specialization)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
177
LICENSE
Normal file
177
LICENSE
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
31
LICENSE.md
31
LICENSE.md
|
|
@ -1,31 +0,0 @@
|
|||
*Copyright 2016 NVIDIA Corporation*
|
||||
|
||||
BY DOWNLOADING THE SOFTWARE AND OTHER AVAILABLE MATERIALS, YOU ("DEVELOPER") AGREE TO BE BOUND BY THE FOLLOWING TERMS AND CONDITIONS
|
||||
|
||||
----------
|
||||
|
||||
The materials available for download to Developers may include software in both sample source ("*Source Code*") and object code ("*Object Code*") versions, documentation ("*Documentation*"), certain art work ("*Art Assets*") and other materials (collectively, these materials referred to herein as "*Materials*"). Except as expressly indicated herein, all terms and conditions of this Agreement apply to all of the Materials.
|
||||
|
||||
Except as expressly set forth herein, NVIDIA owns all of the Materials and makes them available to Developer only under the terms and conditions set forth in this Agreement.
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
**License**: Subject to the terms of this Agreement, NVIDIA hereby grants to Developer a royalty-free, non-exclusive license to possess and to use the Materials. The following terms apply to the specified type of Material:
|
||||
|
||||
**Source Code**: Developer shall have the right to modify and create derivative works with the Source Code. Developer shall own any derivative works ("*Derivatives*") it creates to the Source Code, provided that Developer uses the Materials in accordance with the terms of this Agreement. Developer may distribute the Derivatives, provided that all NVIDIA copyright notices and trademarks are used properly and the Derivatives include the following statement: "This software contains source code provided by NVIDIA Corporation."
|
||||
|
||||
**Object Code**: Developer agrees not to disassemble, decompile or reverse engineer the Object Code versions of any of the Materials. Developer acknowledges that certain of the Materials provided in Object Code version may contain third party components that may be subject to restrictions, and expressly agrees not to attempt to modify or distribute such Materials without first receiving consent from NVIDIA.
|
||||
|
||||
**Art Assets**: Developer shall have the right to modify and create Derivatives of the Art Assets, but may not distribute any of the Art Assets or Derivatives created therefrom without NVIDIA’s prior written consent.
|
||||
|
||||
**Government End Users**: If you are acquiring the Software on behalf of any unit or agency of the United States Government, the following provisions apply. The Government agrees the Software and documentation were developed at private expense and are provided with “RESTRICTED RIGHTS”. Use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 227.7202-1(a) and 227.7202-3(a) (1995), DFARS 252.227-7013(c)(1)(ii) (Oct 1988), FAR 12.212(a)(1995), FAR 52.227-19, (June 1987) or FAR 52.227-14(ALT III) (June 1987),as amended from time to time. In the event that this License, or any part thereof, is deemed inconsistent with the minimum rights identified in the Restricted Rights provisions, the minimum rights shall prevail.
|
||||
No Other License. No rights or licenses are granted by NVIDIA under this License, expressly or by implication, with respect to any proprietary information or patent, copyright, trade secret or other intellectual property right owned or controlled by NVIDIA, except as expressly provided in this License.
|
||||
Term: This License is effective until terminated. NVIDIA may terminate this Agreement (and with it, all of Developer’s right to the Materials) immediately upon written notice (which may include email) to Developer, with or without cause.
|
||||
|
||||
**Support**: NVIDIA has no obligation to support or to continue providing or updating any of the Materials.
|
||||
|
||||
**No Warranty**: THE SOFTWARE AND ANY OTHER MATERIALS PROVIDED BY NVIDIA TO DEVELOPER HEREUNDER ARE PROVIDED "AS IS." NVIDIA DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
|
||||
**LIMITATION OF LIABILITY**: NVIDIA SHALL NOT BE LIABLE TO DEVELOPER, DEVELOPER’S CUSTOMERS, OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR UNDER DEVELOPER FOR ANY LOSS OF PROFITS, INCOME, SAVINGS, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, SPECIAL, PUNITIVE, DIRECT OR INDIRECT DAMAGES (WHETHER IN AN ACTION IN CONTRACT, TORT OR BASED ON A WARRANTY), EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF THE ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. IN NO EVENT SHALL NVIDIA’S AGGREGATE LIABILITY TO DEVELOPER OR ANY OTHER PERSON OR ENTITY CLAIMING THROUGH OR UNDER DEVELOPER EXCEED THE AMOUNT OF MONEY ACTUALLY PAID BY DEVELOPER TO NVIDIA FOR THE SOFTWARE OR ANY OTHER MATERIALS.
|
||||
|
|
@ -44,3 +44,4 @@ Tutorial | Details
|
|||
 | [Advance](ray_tracing__advance) <br> An example combining most of the above samples in a single application.
|
||||
 | [Trace Rays Indirect](ray_tracing_indirect_scissor) <br> Teaches the use of `vkCmdTraceRaysIndirectKHR`, which sources width/height/depth from a buffer. As a use case, we add lanterns to the scene and use a compute shader to calculate scissor rectangles for each of them.
|
||||
 | [AO Raytracing](ray_tracing_ao) <br> This extension to the tutorial is showing how G-Buffers from the fragment shader, can be used in a compute shader to cast ambient occlusion rays using ray queries ([GLSL_EXT_ray_query](https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GLSL_EXT_ray_query.txt)).
|
||||
 | [Specialization Constants](ray_tracing_specialization) <br> Showing how to use specialization constant and using interactively different specialization.
|
||||
|
|
@ -1,6 +1,21 @@
|
|||
/******************************************************************************
|
||||
* Copyright 1998-2018 NVIDIA Corp. All Rights Reserved.
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// This file exist only to do the implementation of tiny obj loader
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
|
|
|
|||
|
|
@ -1,10 +1,25 @@
|
|||
/******************************************************************************
|
||||
* Copyright 1998-2018 NVIDIA Corp. All Rights Reserved.
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "fileformats/tiny_obj_loader.h"
|
||||
#include "nvmath/nvmath.h"
|
||||
#include "tiny_obj_loader.h"
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ of the above structures.
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Converting a OBJ primitive to the ray tracing geometry used for the BLAS
|
||||
//
|
||||
nvvkpp::RaytracingBuilderKHR::Blas HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
{
|
||||
// Setting up the creation info of acceleration structure
|
||||
vk::AccelerationStructureCreateGeometryTypeInfoKHR asCreate;
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
<meta charset="utf-8">
|
||||
(insert vkrt_tutorial.md.html here)
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -6,14 +6,12 @@
|
|||
|
||||
Besides the current repository, you will also need to clone or download the following repositories:
|
||||
|
||||
* [shared_sources](https://github.com/nvpro-samples/shared_sources): The primary framework that all samples depend on.
|
||||
* [shared_external](https://github.com/nvpro-samples/shared_external): Third party libraries that are provided pre-compiled, mostly for Windows x64 / MSVC.
|
||||
* [nvpro_core](https://github.com/nvpro-samples/nvpro_core): The primary framework that all samples depend on.
|
||||
|
||||
Cloning all repositories
|
||||
|
||||
~~~~~
|
||||
git clone https://github.com/nvpro-samples/shared_sources.git
|
||||
git clone https://github.com/nvpro-samples/shared_external.git
|
||||
git clone --recursive --shallow-submodules https://github.com/nvpro-samples/nvpro_core.git
|
||||
git clone https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR.git
|
||||
~~~~~
|
||||
|
||||
|
|
@ -22,8 +20,7 @@ The directory structure should be looking like this:
|
|||
~~~~
|
||||
C:\Vulkan\nvpro-samples
|
||||
|
|
||||
+---shared_external
|
||||
+---shared_sources
|
||||
+---nvpro_core
|
||||
+---vk_raytracing_tutorial_KHR
|
||||
| +---ray_tracing__simple
|
||||
| +---ray_tracing_...
|
||||
|
|
@ -42,7 +39,7 @@ Version 1.2.162.0 and up has ray tracing extensions support.
|
|||
|
||||
## Driver
|
||||
|
||||
NVIDIA driver 160.0 and up support Vulkan ray tracing.
|
||||
NVIDIA driver 450.0 and up support Vulkan ray tracing.
|
||||
|
||||
* Standard driver: https://www.nvidia.com/Download/index.aspx
|
||||
* Vulkan beta driver: https://developer.nvidia.com/vulkan-driver
|
||||
|
|
@ -50,9 +47,11 @@ NVIDIA driver 160.0 and up support Vulkan ray tracing.
|
|||
|
||||
## CMake
|
||||
|
||||
The CMakefile will use other makefiles from `shared_sources` and look for Vulkan environment variables for the installation of the SDK. Therefore, it is important to have all the above installed before running Cmake in the
|
||||
The CMakefile will use other makefiles from `nvpro_core` and look for Vulkan environment variables for the installation of the SDK. Therefore, it is important to have all the above installed before running Cmake in the
|
||||
`vk_raytracing_tutorial_KHR` directory.
|
||||
|
||||
**Note:** Ray tracing only works with 64 bit environment. Therefore, make sure to choose the right build environment.
|
||||
|
||||
**Note:** If you are using your own Vulkan header files, it is possible to overide the default search path.
|
||||
Modify `VULKAN > VULKAN_HEADERS_OVERRIDE_INCLUDE_DIR` to the path to beta vulkan headers.
|
||||
|
||||
|
|
|
|||
|
|
@ -22,17 +22,14 @@ All following instructions are based on the modification of this project.
|
|||
|
||||
Besides the current repository, you will also need to clone or download the following repositories:
|
||||
|
||||
* [shared_sources](https://github.com/nvpro-samples/shared_sources): The primary framework that all samples depend on.
|
||||
* [shared_external](https://github.com/nvpro-samples/shared_external): Third party libraries that are provided pre-compiled, mostly for Windows x64 / MSVC.
|
||||
* [nvpro_core](https://github.com/nvpro-samples/nvpro_core): The primary framework that all samples depend on.
|
||||
|
||||
The directory structure should be looking like:
|
||||
|
||||
**********************************************************
|
||||
* \
|
||||
* |
|
||||
* +-- 📂 shared_external
|
||||
* |
|
||||
* +-- 📂 shared_sources
|
||||
* +-- 📂 nvpro_core
|
||||
* |
|
||||
* +-- 📂 vk_raytracing_tutorial_KHR
|
||||
* | |
|
||||
|
|
@ -49,9 +46,11 @@ The directory structure should be looking like:
|
|||
!!! Warning
|
||||
**Run CMake** in vk_raytracing_tutorial_KHR.
|
||||
|
||||
!!! Warning Beta
|
||||
!!! Warning Beta Vulkan SDK
|
||||
Modify `VULKAN > VULKAN_HEADERS_OVERRIDE_INCLUDE_DIR` to the path to beta vulkan headers.
|
||||
|
||||
!!! Error
|
||||
**32 bit is not supported**
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
|
|
|
|||
|
|
@ -1,614 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Animation**
|
||||
|
||||
<small>Authors: [Martin-Karl Lefrançois](https://devblogs.nvidia.com/author/mlefrancois/), Neil Bickford </small>
|
||||
|
||||
|
||||
# Animation
|
||||
|
||||

|
||||
|
||||
This is an extension of the [Vulkan ray tracing tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
We will discuss two animation methods: animating only the transformation matrices, and animating the geometry itself.
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
# Animating the Matrices
|
||||
This first example shows how we can update the matrices used for instances in the TLAS.
|
||||
|
||||
## Creating a Scene
|
||||
|
||||
In main.cpp we can create a new scene with a ground plane and 21 instances of the Wuson model, by replacing the
|
||||
`helloVk.loadModel` calls in `main()`. The code below creates all of the instances
|
||||
at the same position, but we will displace them later in the animation function. If you run the example,
|
||||
you will find that the rendering is considerably slow, because the geometries are exactly at the same position
|
||||
and the acceleration structure does not deal with this well.
|
||||
|
||||
~~~~ C++
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths),
|
||||
nvmath::scale_mat4(nvmath::vec3f(2.f, 1.f, 2.f)));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/wuson.obj", defaultSearchPaths));
|
||||
HelloVulkan::ObjInstance inst = helloVk.m_objInstance.back();
|
||||
for(int i = 0; i < 20; i++)
|
||||
helloVk.m_objInstance.push_back(inst);
|
||||
~~~~
|
||||
|
||||
## Animation Function
|
||||
We want to have all of the Wuson models running in a circle, and we will first modify the rasterizer to handle this.
|
||||
Animating the transformation matrices will be done entirely on the CPU, and we will copy the computed transformation to the GPU.
|
||||
In the next example, the animation will be done on the GPU using a compute shader.
|
||||
|
||||
Add the declaration of the animation to the `HelloVulkan` class.
|
||||
~~~~ C++
|
||||
void animationInstances(float time);
|
||||
~~~~
|
||||
|
||||
The first part computes the transformations for all of the Wuson models, placing each one behind another.
|
||||
~~~~ C++
|
||||
void HelloVulkan::animationInstances(float time)
|
||||
{
|
||||
const int32_t nbWuson = static_cast<int32_t>(m_objInstance.size() - 1);
|
||||
const float deltaAngle = 6.28318530718f / static_cast<float>(nbWuson);
|
||||
const float wusonLength = 3.f;
|
||||
const float radius = wusonLength / (2.f * sin(deltaAngle / 2.0f));
|
||||
const float offset = time * 0.5f;
|
||||
|
||||
for(int i = 0; i < nbWuson; i++)
|
||||
{
|
||||
int wusonIdx = i + 1;
|
||||
ObjInstance& inst = m_objInstance[wusonIdx];
|
||||
inst.transform = nvmath::rotation_mat4_y(i * deltaAngle + offset)
|
||||
* nvmath::translation_mat4(radius, 0.f, 0.f);
|
||||
inst.transformIT = nvmath::transpose(nvmath::invert(inst.transform));
|
||||
}
|
||||
~~~~
|
||||
|
||||
Next, we update the buffer that describes the scene, which is used by the rasterizer to set each object's position, and also by the ray tracer to compute shading normals.
|
||||
~~~~ C++
|
||||
// Update the buffer
|
||||
vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance);
|
||||
nvvkBuffer stagingBuffer = m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
// Copy data to staging buffer
|
||||
auto* gInst = m_alloc.map(stagingBuffer);
|
||||
memcpy(gInst, m_objInstance.data(), bufferSize);
|
||||
m_alloc.unmap(stagingBuffer);
|
||||
// Copy staging buffer to the Scene Description buffer
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
cmdBuf.copyBuffer(stagingBuffer.buffer, m_sceneDesc.buffer, vk::BufferCopy(0, 0, bufferSize));
|
||||
m_debug.endLabel(cmdBuf);
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
m_alloc.destroy(stagingBuffer);
|
||||
|
||||
m_rtBuilder.updateTlasMatrices(m_tlas);
|
||||
m_rtBuilder.updateBlas(2);
|
||||
}
|
||||
~~~~
|
||||
<script type="preformatted">
|
||||
|
||||
!!! Note:
|
||||
We could have used `cmdBuf.updateBuffer<ObjInstance>(m_sceneDesc.buffer, 0, m_objInstance)` to
|
||||
update the buffer, but this function only works for buffers with less than 65,536 bytes. If we had 2000 Wuson models, this
|
||||
call wouldn't work.
|
||||
|
||||
## Loop Animation
|
||||
In `main()`, just before the main loop, add a variable to hold the start time.
|
||||
We will use this time in our animation function.
|
||||
|
||||
~~~~ C++
|
||||
auto start = std::chrono::system_clock::now();
|
||||
~~~~
|
||||
|
||||
Inside the `while` loop, just before calling `appBase.prepareFrame()`, invoke the animation function.
|
||||
|
||||
~~~~ C++
|
||||
std::chrono::duration<float> diff = std::chrono::system_clock::now() - start;
|
||||
helloVk.animationInstances(diff.count());
|
||||
~~~~
|
||||
|
||||
If you run the application, the Wuson models will be running in a circle when using the rasterizer, but
|
||||
they will still be at their original positions in the ray traced version. We will need to update the TLAS for this.
|
||||
|
||||
|
||||
# Update TLAS
|
||||
|
||||
Since we want to update the transformation matrices in the TLAS, we need to keep some of the objects used to create it.
|
||||
|
||||
First, move the vector of `nvvk::RaytracingBuilder::Instance` objects from `HelloVulkan::createTopLevelAS()` to the
|
||||
`HelloVulkan` class.
|
||||
~~~~ C++
|
||||
std::vector<nvvk::RaytracingBuilder::Instance> m_tlas;
|
||||
~~~~
|
||||
|
||||
Make sure to rename it to `m_tlas`, instead of `tlas`.
|
||||
|
||||
One important point is that we need to set the TLAS build flags to allow updates, by adding the`vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate` flag.
|
||||
This is absolutely needed, since otherwise the TLAS cannot be updated.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::createTopLevelAS()
|
||||
{
|
||||
m_tlas.reserve(m_objInstance.size());
|
||||
for(uint32_t i = 0; i < static_cast<uint32_t>(m_objInstance.size()); i++)
|
||||
{
|
||||
nvvk::RaytracingBuilder::Instance rayInst;
|
||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||
rayInst.blasId = m_objInstance[i].objIndex;
|
||||
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
||||
m_tlas.emplace_back(rayInst);
|
||||
}
|
||||
m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace
|
||||
| vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate);
|
||||
}
|
||||
~~~~
|
||||
|
||||
Back in `HelloVulkan::animationInstances()`, we need to copy the new computed transformation
|
||||
matrices to the vector of `nvvk::RaytracingBuilder::Instance` objects.
|
||||
|
||||
In the `for` loop, add at the end
|
||||
|
||||
~~~~ C++
|
||||
nvvk::RaytracingBuilder::Instance& tinst = m_tlas[wusonIdx];
|
||||
tinst.transform = inst.transform;
|
||||
~~~~
|
||||
|
||||
The last point is to call the update at the end of the function.
|
||||
|
||||
~~~~ C++
|
||||
m_rtBuilder.updateTlasMatrices(m_tlas);
|
||||
~~~~
|
||||
|
||||

|
||||
|
||||
## nvvk::RaytracingBuilder::updateTlasMatrices (Implementation)
|
||||
|
||||
We currently use `nvvk::RaytracingBuilder` to update the matrices for convenience, but
|
||||
this could be done more efficiently if one kept some of the buffer and memory references. Using a
|
||||
memory allocator, such as the one described in the [Many Objects Tutorial](vkrt_tuto_instances.md.html),
|
||||
could also be an alternative for avoiding multiple reallocations. Here's the implementation of `nvvk::RaytracingBuilder::updateTlasMatrices`.
|
||||
|
||||
### Staging Buffer
|
||||
|
||||
As in the rasterizer, the data needs to be staged before it can be copied to the buffer used for
|
||||
building the TLAS.
|
||||
|
||||
~~~~ C++
|
||||
void updateTlasMatrices(const std::vector<Instance>& instances)
|
||||
{
|
||||
VkDeviceSize bufferSize = instances.size() * sizeof(VkAccelerationStructureInstanceKHR);
|
||||
// Create a staging buffer on the host to upload the new instance data
|
||||
nvvkBuffer stagingBuffer = m_alloc.createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
#if defined(ALLOC_VMA)
|
||||
VmaMemoryUsage::VMA_MEMORY_USAGE_CPU_TO_GPU
|
||||
#else
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||
#endif
|
||||
);
|
||||
|
||||
// Copy the instance data into the staging buffer
|
||||
auto* gInst = reinterpret_cast<VkAccelerationStructureInstanceKHR*>(m_alloc.map(stagingBuffer));
|
||||
for(int i = 0; i < instances.size(); i++)
|
||||
{
|
||||
gInst[i] = instanceToVkGeometryInstanceKHR(instances[i]);
|
||||
}
|
||||
m_alloc.unmap(stagingBuffer);
|
||||
~~~~
|
||||
|
||||
### Scratch Memory
|
||||
Building the TLAS always needs scratch memory, and so we need to request it. If
|
||||
we hadn't set the `eAllowUpdate` flag, the returned size would be zero and the rest of the code
|
||||
would fail.
|
||||
~~~~ C++
|
||||
// Compute the amount of scratch memory required by the AS builder to update
|
||||
VkAccelerationStructureMemoryRequirementsInfoKHR memoryRequirementsInfo{
|
||||
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR};
|
||||
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
|
||||
memoryRequirementsInfo.accelerationStructure = m_tlas.as.accel;
|
||||
memoryRequirementsInfo.buildType = VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR;
|
||||
|
||||
VkMemoryRequirements2 reqMem{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
|
||||
vkGetAccelerationStructureMemoryRequirementsKHR(m_device, &memoryRequirementsInfo, &reqMem);
|
||||
VkDeviceSize scratchSize = reqMem.memoryRequirements.size;
|
||||
|
||||
// Allocate the scratch buffer
|
||||
nvvkBuffer scratchBuffer =
|
||||
m_alloc.createBuffer(scratchSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||
VkBufferDeviceAddressInfo bufferInfo{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
||||
bufferInfo.buffer = scratchBuffer.buffer;
|
||||
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(m_device, &bufferInfo);
|
||||
~~~~
|
||||
|
||||
### Update the Buffer
|
||||
In a new command buffer, we copy the staging buffer to the device buffer and
|
||||
add a barrier to make sure the memory finishes copying before updating the TLAS.
|
||||
|
||||
~~~~ C++
|
||||
// Update the instance buffer on the device side and build the TLAS
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_queueIndex);
|
||||
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
|
||||
VkBufferCopy region{0, 0, bufferSize};
|
||||
vkCmdCopyBuffer(cmdBuf, stagingBuffer.buffer, m_instBuffer.buffer, 1, ®ion);
|
||||
|
||||
//VkBufferDeviceAddressInfo bufferInfo{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
||||
bufferInfo.buffer = m_instBuffer.buffer;
|
||||
VkDeviceAddress instanceAddress = vkGetBufferDeviceAddress(m_device, &bufferInfo);
|
||||
|
||||
|
||||
// Make sure the copy of the instance buffer are copied before triggering the
|
||||
// acceleration structure build
|
||||
VkMemoryBarrier barrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER};
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
|
||||
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
|
||||
0, 1, &barrier, 0, nullptr, 0, nullptr);
|
||||
~~~~
|
||||
|
||||
### Update Acceleration Structure
|
||||
|
||||
We update the TLAS using the same acceleration structure for source and
|
||||
destination to update it in place, and using the VK_TRUE parameter to trigger the update.
|
||||
|
||||
~~~~ C++
|
||||
VkAccelerationStructureGeometryDataKHR geometry{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR};
|
||||
geometry.instances.arrayOfPointers = VK_FALSE;
|
||||
geometry.instances.data.deviceAddress = instanceAddress;
|
||||
VkAccelerationStructureGeometryKHR topASGeometry{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR};
|
||||
topASGeometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
|
||||
topASGeometry.geometry = geometry;
|
||||
|
||||
const VkAccelerationStructureGeometryKHR* pGeometry = &topASGeometry;
|
||||
|
||||
VkAccelerationStructureBuildGeometryInfoKHR topASInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
||||
topASInfo.flags = m_tlas.flags;
|
||||
topASInfo.update = VK_TRUE;
|
||||
topASInfo.srcAccelerationStructure = m_tlas.as.accel;
|
||||
topASInfo.dstAccelerationStructure = m_tlas.as.accel;
|
||||
topASInfo.geometryArrayOfPointers = VK_FALSE;
|
||||
topASInfo.geometryCount = 1;
|
||||
topASInfo.ppGeometries = &pGeometry;
|
||||
topASInfo.scratchData.deviceAddress = scratchAddress;
|
||||
|
||||
uint32_t nbInstances = (uint32_t)instances.size();
|
||||
VkAccelerationStructureBuildOffsetInfoKHR buildOffsetInfo = {nbInstances, 0, 0, 0};
|
||||
const VkAccelerationStructureBuildOffsetInfoKHR* pBuildOffsetInfo = &buildOffsetInfo;
|
||||
|
||||
// Build the TLAS
|
||||
|
||||
// Update the acceleration structure. Note the VK_TRUE parameter to trigger the update,
|
||||
// and the existing TLAS being passed and updated in place
|
||||
vkCmdBuildAccelerationStructureKHR(cmdBuf, 1, &topASInfo, &pBuildOffsetInfo);
|
||||
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
~~~~
|
||||
|
||||
### Cleanup
|
||||
|
||||
Finally, we release all temporary buffers.
|
||||
|
||||
~~~~ C++
|
||||
m_alloc.destroy(scratchBuffer);
|
||||
m_alloc.destroy(stagingBuffer);
|
||||
}
|
||||
~~~~
|
||||
|
||||
# BLAS Animation
|
||||
|
||||
In the previous chapter, we updated the transformation matrices. In this one we will modify vertices in a compute shader.
|
||||
|
||||
## Adding a Sphere
|
||||
|
||||
In this chapter, we will animate a sphere. In `main.cpp`, set up the scene like this:
|
||||
|
||||
~~~~ C++
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths),
|
||||
nvmath::scale_mat4(nvmath::vec3f(2.f, 1.f, 2.f)));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/wuson.obj", defaultSearchPaths));
|
||||
HelloVulkan::ObjInstance inst = helloVk.m_objInstance.back();
|
||||
for(int i = 0; i < 5; i++)
|
||||
helloVk.m_objInstance.push_back(inst);
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/sphere.obj", defaultSearchPaths));
|
||||
~~~~
|
||||
|
||||
Because we now have a new instance, we have to adjust the calculation of the number of Wuson models in `HelloVulkan::animationInstances()`.
|
||||
|
||||
~~~~ C++
|
||||
const int32_t nbWuson = static_cast<int32_t>(m_objInstance.size() - 2);
|
||||
~~~~
|
||||
|
||||
## Compute Shader
|
||||
|
||||
The compute shader will update the vertices in-place.
|
||||
|
||||
Add all of the following members to the `HelloVulkan` class:
|
||||
|
||||
~~~~ C++
|
||||
void createCompDescriptors();
|
||||
void updateCompDescriptors(nvvkBuffer& vertex);
|
||||
void createCompPipelines();
|
||||
|
||||
nvvk::DescriptorSetBindings m_compDescSetLayoutBind;
|
||||
vk::DescriptorPool m_compDescPool;
|
||||
vk::DescriptorSetLayout m_compDescSetLayout;
|
||||
vk::DescriptorSet m_compDescSet;
|
||||
vk::Pipeline m_compPipeline;
|
||||
vk::PipelineLayout m_compPipelineLayout;
|
||||
~~~~
|
||||
|
||||
The compute shader will work on a single `VertexObj` buffer.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::createCompDescriptors()
|
||||
{
|
||||
m_compDescSetLayoutBind.addBinding(vk::DescriptorSetLayoutBinding(
|
||||
0, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eCompute));
|
||||
|
||||
m_compDescSetLayout = m_compDescSetLayoutBind.createLayout(m_device);
|
||||
m_compDescPool = m_compDescSetLayoutBind.createPool(m_device, 1);
|
||||
m_compDescSet = nvvk::allocateDescriptorSet(m_device, m_compDescPool, m_compDescSetLayout);
|
||||
}
|
||||
~~~~
|
||||
|
||||
`updateCompDescriptors` will set the set the descriptor to the buffer of `VertexObj` objects to which the animation will be applied.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::updateCompDescriptors(nvvkBuffer& vertex)
|
||||
{
|
||||
std::vector<vk::WriteDescriptorSet> writes;
|
||||
vk::DescriptorBufferInfo dbiUnif{vertex.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_compDescSetLayoutBind.makeWrite(m_compDescSet, 0, dbiUnif));
|
||||
m_device.updateDescriptorSets(static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||
}
|
||||
~~~~
|
||||
|
||||
The compute pipeline will consist of a simple shader and a push constant, which will be used
|
||||
to set the animation time.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::createCompPipelines()
|
||||
{
|
||||
// pushing time
|
||||
vk::PushConstantRange push_constants = {vk::ShaderStageFlagBits::eCompute, 0, sizeof(float)};
|
||||
vk::PipelineLayoutCreateInfo layout_info{{}, 1, &m_compDescSetLayout, 1, &push_constants};
|
||||
m_compPipelineLayout = m_device.createPipelineLayout(layout_info);
|
||||
vk::ComputePipelineCreateInfo computePipelineCreateInfo{{}, {}, m_compPipelineLayout};
|
||||
|
||||
computePipelineCreateInfo.stage =
|
||||
nvvk::createShaderStageInfo(m_device,
|
||||
nvh::loadFile("shaders/anim.comp.spv", true, defaultSearchPaths),
|
||||
VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
m_compPipeline = m_device.createComputePipeline({}, computePipelineCreateInfo, nullptr);
|
||||
m_device.destroy(computePipelineCreateInfo.stage.module);
|
||||
}
|
||||
~~~~
|
||||
|
||||
Finally, destroy the resources in `HelloVulkan::destroyResources()`:
|
||||
|
||||
~~~~ C++
|
||||
m_device.destroy(m_compDescPool);
|
||||
m_device.destroy(m_compDescSetLayout);
|
||||
m_device.destroy(m_compPipeline);
|
||||
m_device.destroy(m_compPipelineLayout);
|
||||
~~~~
|
||||
|
||||
## `anim.comp`
|
||||
The compute shader will be simple. We need to add a new shader file, `anim.comp`, to the `shaders` filter in the solution.
|
||||
|
||||
This will move each vertex up and down over time.
|
||||
|
||||
~~~~ C++
|
||||
#version 460
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#include "wavefront.glsl"
|
||||
|
||||
layout(binding = 0, scalar) buffer Vertices
|
||||
{
|
||||
Vertex v[];
|
||||
}
|
||||
vertices;
|
||||
|
||||
layout(push_constant) uniform shaderInformation
|
||||
{
|
||||
float iTime;
|
||||
}
|
||||
pushc;
|
||||
|
||||
void main()
|
||||
{
|
||||
Vertex v0 = vertices.v[gl_GlobalInvocationID.x];
|
||||
|
||||
// Compute vertex position
|
||||
const float PI = 3.14159265;
|
||||
const float signY = (v0.pos.y >= 0 ? 1 : -1);
|
||||
const float radius = length(v0.pos.xz);
|
||||
const float argument = pushc.iTime * 4 + radius * PI;
|
||||
const float s = sin(argument);
|
||||
v0.pos.y = signY * abs(s) * 0.5;
|
||||
|
||||
// Compute normal
|
||||
if(radius == 0.0f)
|
||||
{
|
||||
v0.nrm = vec3(0.0f, signY, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float c = cos(argument);
|
||||
const float xzFactor = -PI * s * c;
|
||||
const float yFactor = 2.0f * signY * radius * abs(s);
|
||||
v0.nrm = normalize(vec3(v0.pos.x * xzFactor, yFactor, v0.pos.z * xzFactor));
|
||||
}
|
||||
|
||||
vertices.v[gl_GlobalInvocationID.x] = v0;
|
||||
}
|
||||
~~~~
|
||||
|
||||
## Animating the Object
|
||||
|
||||
First add the declaration of the animation function in `HelloVulkan`:
|
||||
|
||||
~~~~ C++
|
||||
void animationObject(float time);
|
||||
~~~~
|
||||
|
||||
The implementation only pushes the current time and calls the compute shader (`dispatch`).
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::animationObject(float time)
|
||||
{
|
||||
ObjModel& model = m_objModel[2];
|
||||
|
||||
updateCompDescriptors(model.vertexBuffer);
|
||||
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
|
||||
cmdBuf.bindPipeline(vk::PipelineBindPoint::eCompute, m_compPipeline);
|
||||
cmdBuf.bindDescriptorSets(vk::PipelineBindPoint::eCompute, m_compPipelineLayout, 0,
|
||||
{m_compDescSet}, {});
|
||||
cmdBuf.pushConstants(m_compPipelineLayout, vk::ShaderStageFlagBits::eCompute, 0, sizeof(float),
|
||||
&time);
|
||||
cmdBuf.dispatch(model.nbVertices, 1, 1);
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
}
|
||||
~~~~
|
||||
|
||||
## Invoking Animation
|
||||
|
||||
In `main.cpp`, after the other resource creation functions, add the creation functions for the compute shader.
|
||||
|
||||
~~~~ C++
|
||||
helloVk.createCompDescriptors();
|
||||
helloVk.createCompPipelines();
|
||||
~~~~
|
||||
|
||||
In the rendering loop, after the call to `animationInstances`, call the object animation function.
|
||||
|
||||
~~~~ C++
|
||||
helloVk.animationObject(diff.count());
|
||||
~~~~
|
||||
|
||||
!!! Note
|
||||
At this point, the object should be animated when using the rasterizer, but should still be immobile when using the ray tracer.
|
||||
|
||||
## Update BLAS
|
||||
|
||||
In `nvvk::RaytracingBuilder` in `raytrace_vkpp.hpp`, we can add a function to update a BLAS whose vertex buffer was previously updated. This function is very similar to the one used for instances, but in this case, there is no buffer transfer to do.
|
||||
|
||||
~~~~ C++
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Refit the BLAS from updated buffers
|
||||
//
|
||||
void updateBlas(uint32_t blasIdx)
|
||||
{
|
||||
Blas& blas = m_blas[blasIdx];
|
||||
|
||||
// Compute the amount of scratch memory required by the AS builder to update the BLAS
|
||||
VkAccelerationStructureMemoryRequirementsInfoKHR memoryRequirementsInfo{
|
||||
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR};
|
||||
memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR;
|
||||
memoryRequirementsInfo.accelerationStructure = blas.as.accel;
|
||||
memoryRequirementsInfo.buildType = VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR;
|
||||
|
||||
VkMemoryRequirements2 reqMem{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
|
||||
vkGetAccelerationStructureMemoryRequirementsKHR(m_device, &memoryRequirementsInfo, &reqMem);
|
||||
VkDeviceSize scratchSize = reqMem.memoryRequirements.size;
|
||||
|
||||
// Allocate the scratch buffer
|
||||
nvvkBuffer scratchBuffer =
|
||||
m_alloc.createBuffer(scratchSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
|
||||
VkBufferDeviceAddressInfo bufferInfo{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO};
|
||||
bufferInfo.buffer = scratchBuffer.buffer;
|
||||
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(m_device, &bufferInfo);
|
||||
|
||||
|
||||
const VkAccelerationStructureGeometryKHR* pGeometry = blas.asGeometry.data();
|
||||
VkAccelerationStructureBuildGeometryInfoKHR asInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
||||
asInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
||||
asInfo.flags = blas.flags;
|
||||
asInfo.update = VK_TRUE;
|
||||
asInfo.srcAccelerationStructure = blas.as.accel;
|
||||
asInfo.dstAccelerationStructure = blas.as.accel;
|
||||
asInfo.geometryArrayOfPointers = VK_FALSE;
|
||||
asInfo.geometryCount = (uint32_t)blas.asGeometry.size();
|
||||
asInfo.ppGeometries = &pGeometry;
|
||||
asInfo.scratchData.deviceAddress = scratchAddress;
|
||||
|
||||
std::vector<const VkAccelerationStructureBuildOffsetInfoKHR*> pBuildOffset(blas.asBuildOffsetInfo.size());
|
||||
for(size_t i = 0; i < blas.asBuildOffsetInfo.size(); i++)
|
||||
pBuildOffset[i] = &blas.asBuildOffsetInfo[i];
|
||||
|
||||
// Update the instance buffer on the device side and build the TLAS
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_queueIndex);
|
||||
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
|
||||
|
||||
// Update the acceleration structure. Note the VK_TRUE parameter to trigger the update,
|
||||
// and the existing BLAS being passed and updated in place
|
||||
vkCmdBuildAccelerationStructureKHR(cmdBuf, 1, &asInfo, pBuildOffset.data());
|
||||
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
m_alloc.destroy(scratchBuffer);
|
||||
}
|
||||
~~~~
|
||||
|
||||
The previous function (`updateBlas`) uses geometry information stored in `m_blas`.
|
||||
To be able to re-use this information, we need to keep the structure of `nvvk::RaytracingBuilderKHR::Blas` objects
|
||||
used for its creation.
|
||||
|
||||
Move the `nvvk::RaytracingBuilderKHR::Blas` vector from `HelloVulkan::createBottomLevelAS()` to the `HelloVulkan` class, renaming it to `m_blas`.
|
||||
|
||||
~~~~ C++
|
||||
std::vector<nvvk::RaytracingBuilderKHR::Blas> m_blas;
|
||||
~~~~
|
||||
|
||||
As with the TLAS, the BLAS needs to allow updates. We will also enable the
|
||||
`VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR` flag, which indicates that the given
|
||||
acceleration structure build should prioritize build time over trace performance.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::createBottomLevelAS()
|
||||
{
|
||||
// BLAS - Storing each primitive in a geometry
|
||||
m_blas.reserve(m_objModel.size());
|
||||
for(const auto & obj : m_objModel)
|
||||
{
|
||||
auto blas = objectToVkGeometryKHR(obj);
|
||||
|
||||
// We could add more geometry in each BLAS, but we add only one for now
|
||||
m_blas.push_back(blas);
|
||||
}
|
||||
m_rtBuilder.buildBlas(m_blas, vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate
|
||||
| vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastBuild);
|
||||
}
|
||||
~~~~
|
||||
|
||||
Finally, we can add a line at the end of `HelloVulkan::animationObject()` to update the BLAS.
|
||||
|
||||
~~~~ C++
|
||||
m_rtBuilder.updateBlas(2);
|
||||
~~~~
|
||||
|
||||

|
||||
|
||||
</script>
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_animation](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_animation)
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,418 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Anyhit Shaders**
|
||||
|
||||
<small>Authors: [Martin-Karl Lefrançois](https://devblogs.nvidia.com/author/mlefrancois/), Neil Bickford </small>
|
||||
|
||||
|
||||

|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
Like closest hit shaders, any hit shaders operate on intersections between rays and geometry. However, the any hit
|
||||
shader will be executed for all hits along the ray. The closest hit shader will then be invoked on the closest accepted
|
||||
intersection.
|
||||
|
||||
The any hit shader can be useful for discarding intersections, such as for alpha cutouts for example, but can also be
|
||||
used for simple transparency. In this example we will show what is needed to do to add this shader type and to create a
|
||||
transparency effect.
|
||||
|
||||
!!! Note Note
|
||||
This example is based on many elements from the [Antialiasing Tutorial](vkrt_tuto_jitter_cam.md.html).
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
# Any Hit
|
||||
|
||||
## `raytrace.rahit`
|
||||
|
||||
Create a new shader file `raytrace.rahit` and rerun CMake to have it added to the solution.
|
||||
|
||||
This shader starts like `raytrace.chit`, but uses less information.
|
||||
~~~~ C++
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "random.glsl"
|
||||
#include "raycommon.glsl"
|
||||
#include "wavefront.glsl"
|
||||
|
||||
// clang-format off
|
||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||
|
||||
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
|
||||
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
|
||||
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
|
||||
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
|
||||
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
|
||||
// clang-format on
|
||||
~~~~
|
||||
|
||||
!!! Note
|
||||
You can find the source of `random.glsl` in the Antialiasing Tutorial [here](../ray_tracing_jitter_cam/README.md#toc1.1).
|
||||
|
||||
|
||||
For the any hit shader, we need to know which material we hit, and whether that material supports transparency. If it is
|
||||
opaque, we simply return, which means that the hit will be accepted.
|
||||
|
||||
~~~~ C++
|
||||
void main()
|
||||
{
|
||||
// Object of this instance
|
||||
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
|
||||
// Indices of the triangle
|
||||
uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0];
|
||||
// Vertex of the triangle
|
||||
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
|
||||
|
||||
// Material of the object
|
||||
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
|
||||
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
|
||||
|
||||
if (mat.illum != 4)
|
||||
return;
|
||||
~~~~
|
||||
|
||||
Now we will apply transparency:
|
||||
|
||||
~~~~ C++
|
||||
if (mat.dissolve == 0.0)
|
||||
ignoreIntersectionEXT();
|
||||
else if(rnd(prd.seed) > mat.dissolve)
|
||||
ignoreIntersectionEXT();
|
||||
}
|
||||
~~~~
|
||||
|
||||
As you can see, we are using a random number generator to determine if the ray hits or ignores the object. If we
|
||||
accumulate enough rays, the final result will converge to what we want.
|
||||
|
||||
## `raycommon.glsl`
|
||||
|
||||
The random `seed` also needs to be passed in the ray payload.
|
||||
|
||||
In `raycommon.glsl`, add the seed:
|
||||
|
||||
~~~~ C++
|
||||
struct hitPayload
|
||||
{
|
||||
vec3 hitValue;
|
||||
uint seed;
|
||||
};
|
||||
~~~~
|
||||
|
||||
## Adding Any Hit to `createRtPipeline`
|
||||
|
||||
The any hit shader will be part of the hit shader group. Currently, the hit shader group only contains the closest hit shader.
|
||||
|
||||
In `createRtPipeline()`, after loading `raytrace.rchit.spv`, load `raytrace.rahit.spv`
|
||||
|
||||
~~~~ C++
|
||||
vk::ShaderModule ahitSM =
|
||||
nvvk::createShaderModule(m_device, //
|
||||
nvh::loadFile("shaders/raytrace.rahit.spv", true, paths));
|
||||
~~~~
|
||||
|
||||
add the any hit shader to the hit group
|
||||
|
||||
~~~~ C++
|
||||
hg.setClosestHitShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eClosestHitKHR, chitSM, "main"});
|
||||
hg.setAnyHitShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eAnyHitKHR, ahitSM, "main"});
|
||||
m_rtShaderGroups.push_back(hg);
|
||||
~~~~
|
||||
|
||||
and at the end, delete it:
|
||||
|
||||
~~~~ C++
|
||||
m_device.destroy(ahitSM);
|
||||
~~~~
|
||||
|
||||
## Give access of the buffers to the Any Hit shader
|
||||
|
||||
In `createDescriptorSetLayout()`, we need to allow the Any Hit shader to access some buffers.
|
||||
|
||||
This is the case for the material and scene description buffers
|
||||
|
||||
~~~~ C++
|
||||
// Materials (binding = 1)
|
||||
m_descSetLayoutBind.emplace_back(
|
||||
vkDS(1, vkDT::eStorageBuffer, nbObj,
|
||||
vkSS::eVertex | vkSS::eFragment | vkSS::eClosestHitKHR | vkSS::eAnyHitKHR));
|
||||
// Scene description (binding = 2)
|
||||
m_descSetLayoutBind.emplace_back( //
|
||||
vkDS(2, vkDT::eStorageBuffer, 1,
|
||||
vkSS::eVertex | vkSS::eFragment | vkSS::eClosestHitKHR | vkSS::eAnyHitKHR));
|
||||
~~~~
|
||||
|
||||
and also for the vertex, index and material index buffers:
|
||||
|
||||
~~~~ C++
|
||||
// Materials (binding = 4)
|
||||
m_descSetLayoutBind.emplace_back( //
|
||||
vkDS(4, vkDT::eStorageBuffer, nbObj,
|
||||
vkSS::eFragment | vkSS::eClosestHitKHR | vkSS::eAnyHitKHR));
|
||||
// Storing vertices (binding = 5)
|
||||
m_descSetLayoutBind.emplace_back( //
|
||||
vkDS(5, vkDT::eStorageBuffer, nbObj, vkSS::eClosestHitKHR | vkSS::eAnyHitKHR));
|
||||
// Storing indices (binding = 6)
|
||||
m_descSetLayoutBind.emplace_back( //
|
||||
vkDS(6, vkDT::eStorageBuffer, nbObj, vkSS::eClosestHitKHR | vkSS::eAnyHitKHR));
|
||||
~~~~
|
||||
|
||||
## Opaque Flag
|
||||
|
||||
In the example, when creating `VkAccelerationStructureGeometryKHR` objects, we set their flags to `vk::GeometryFlagBitsKHR::eOpaque`. However, this avoided invoking the any hit shader.
|
||||
|
||||
We could remove all of the flags, but another issue could happen: the any hit shader could be called multiple times for the same triangle. To have the any hit shader process only one hit per triangle, set the `eNoDuplicateAnyHitInvocation` flag:
|
||||
|
||||
~~~~ C++
|
||||
geometry.setFlags(vk::GeometryFlagBitsKHR::eNoDuplicateAnyHitInvocation);
|
||||
~~~~
|
||||
|
||||
## `raytrace.rgen`
|
||||
|
||||
If you have done the previous [Jitter Camera/Antialiasing](../ray_tracing_jitter_cam) tutorial,
|
||||
you will need just a few changes.
|
||||
|
||||
First, `seed` will need to be available in the any hit shader, which is the reason we have added it to the hitPayload structure.
|
||||
|
||||
Change the local `seed` to `prd.seed` everywhere.
|
||||
|
||||
~~~~ C++
|
||||
prd.seed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame);
|
||||
~~~~
|
||||
|
||||
For optimization, the `TraceRayEXT` call was using the `gl_RayFlagsOpaqueEXT` flag. But
|
||||
this will skip the any hit shader, so change it to
|
||||
|
||||
~~~~ C++
|
||||
uint rayFlags = gl_RayFlagsNoneEXT;
|
||||
~~~~
|
||||
|
||||
## `raytrace.rchit`
|
||||
|
||||
Similarly, in the closest hit shader, change the flag to `gl_RayFlagsSkipClosestHitShaderEXT`, as we want to enable the any hit and miss shaders, but we still don't care
|
||||
about the closest hit shader for shadow rays. This will enable transparent shadows.
|
||||
|
||||
~~~~ C++
|
||||
uint flags = gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
~~~~
|
||||
|
||||
# Scene and Model
|
||||
|
||||
For a more interesting scene, you can replace the `helloVk.loadModel` calls in `main()` with the following scene:
|
||||
|
||||
~~~~ C++
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/wuson.obj", defaultSearchPaths));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/sphere.obj", defaultSearchPaths),
|
||||
nvmath::scale_mat4(nvmath::vec3f(1.5f))
|
||||
* nvmath::translation_mat4(nvmath::vec3f(0.0f, 1.0f, 0.0f)));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths));
|
||||
~~~~
|
||||
|
||||
## OBJ Materials
|
||||
|
||||
By default, all objects are opaque, you will need to change the material description.
|
||||
|
||||
Edit the first few lines of `media/scenes/wuson.mtl` and `media/scenes/sphere.mtl` to use a new illumination model (4) with a dissolve value of 0.5:
|
||||
|
||||
~~~~ C++
|
||||
newmtl default
|
||||
illum 4
|
||||
d 0.5
|
||||
...
|
||||
~~~~
|
||||
|
||||
# Accumulation
|
||||
|
||||
As mentioned earlier, for the effect to work, we need to accumulate frames over time. Please implement the following from [Jitter Camera/Antialiasing](vkrt_tuto_jitter_cam.md):
|
||||
|
||||
* [Frame Number](vkrt_tuto_jitter_cam.md.htm#toc1.2)
|
||||
* [Storing or Updating](vkrt_tuto_jitter_cam.md.htm#toc1.4)
|
||||
* [Application Frame Update](vkrt_tuto_jitter_cam.md.htm#toc2)
|
||||
|
||||
|
||||
# Fixing Pipeline
|
||||
|
||||
The above code works, but might not work in the future. The reason is, the shadow ray `traceRayEXT` call in the Closest Hit shader, uses payload 1
|
||||
and when intersecting the object, the any hit shader will be executed using payload 0. In the time of writing those lines, the driver add
|
||||
padding and there are no side effect, but this is not how thing should be done.
|
||||
|
||||
Each `traceRayEXT` invocation should have as many Hit Groups as there are trace calls with different payload. For the other examples, it is still fine,
|
||||
because we are using the `gl_RayFlagsSkipClosestHitShaderNV` flag and the closest hit shader (payload 0) will not be called and there were not
|
||||
any hit or intersection shaders in the Hit Group. But in this example, the closest hit will be skiped, but not the any hit.
|
||||
|
||||
**To fix this**, we need to add another hit group.
|
||||
|
||||
This is how the current SBT looks like.
|
||||
|
||||

|
||||
|
||||
And we need to add the following to the ray tracing pipeline, a copy of the previous Hit Group, with a new AnyHit using the proper payload.
|
||||
|
||||

|
||||
|
||||
|
||||
## New shaders
|
||||
|
||||
Create two new files `raytrace_0.ahit` and `raytrace_1.ahit`, and rename `raytrace.ahit` to `raytrace_ahit.glsl`
|
||||
|
||||
!!! WARNING CMake
|
||||
Cmake need to be re-run to add the new files to the project.
|
||||
|
||||
In `raytrace_0.ahit` add the following code
|
||||
|
||||
~~~~ C
|
||||
#version 460
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#define PAYLOAD_0
|
||||
#include "raytrace_rahit.glsl"
|
||||
~~~~
|
||||
|
||||
and in `raytrace_1.ahit`, replace `PAYLOAD_0` by `PAYLOAD_1`
|
||||
|
||||
Then in `raytrace_ahit.glsl` remove the `#version 460` and add the following code, so that we have the right layout.
|
||||
|
||||
~~~~ C
|
||||
#ifdef PAYLOAD_0
|
||||
layout(location = 0) rayPayloadInNV hitPayload prd;
|
||||
#elif defined(PAYLOAD_1)
|
||||
layout(location = 1) rayPayloadInNV shadowPayload prd;
|
||||
#endif
|
||||
~~~~
|
||||
|
||||
## New Payload
|
||||
|
||||
We cannot simply have a bool for our shadow ray payload. We also need the `seed` for the random function.
|
||||
|
||||
In the `raycommon.glsl` file, add the following structure
|
||||
|
||||
~~~~ C
|
||||
struct shadowPayload
|
||||
{
|
||||
bool isHit;
|
||||
uint seed;
|
||||
};
|
||||
~~~~
|
||||
|
||||
The usage of the shadow payload is done in the closest hit and shadow miss shader. First, let's modify `raytraceShadow.rmiss` to look like this
|
||||
|
||||
~~~~ C
|
||||
#version 460
|
||||
#extension GL_NV_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "raycommon.glsl"
|
||||
|
||||
layout(location = 1) rayPayloadInNV shadowPayload prd;
|
||||
|
||||
void main()
|
||||
{
|
||||
prd.isHit = false;
|
||||
}
|
||||
~~~~
|
||||
|
||||
The the change in the closest hit shader `raytrace.rchit`, need to change the usage of the payload, but also the call to `traceRayEXT`
|
||||
|
||||
Replace the payload to
|
||||
|
||||
~~~~ C
|
||||
layout(location = 1) rayPayloadNV shadowPayload prdShadow;
|
||||
~~~~
|
||||
|
||||
Then just before the call to `traceRayEXT`, initialize the values to
|
||||
|
||||
~~~~ C
|
||||
prdShadow.isHit = true;
|
||||
prdShadow.seed = prd.seed;
|
||||
~~~~
|
||||
|
||||
and after the trace, set the seed value back to the main payload
|
||||
|
||||
~~~~ C
|
||||
prd.seed = prdShadow.seed;
|
||||
~~~~
|
||||
|
||||
And check if the trace shadow hit an object of not
|
||||
|
||||
~~~~ C
|
||||
if(prdShadow.isHit)
|
||||
~~~~
|
||||
|
||||
### traceRayEXT
|
||||
|
||||
When we call `traceRayEXT`, since we are using the payload 1 (last argument), we also
|
||||
need the trace to hit the alternative hit group, the one using the payload 1.
|
||||
To do this, we need to set the sbtRecordOffset to 1
|
||||
|
||||
~~~~ C
|
||||
traceRayEXT(topLevelAS, // acceleration structure
|
||||
flags, // rayFlags
|
||||
0xFF, // cullMask
|
||||
1, // sbtRecordOffset
|
||||
0, // sbtRecordStride
|
||||
1, // missIndex
|
||||
origin, // ray origin
|
||||
tMin, // ray min range
|
||||
rayDir, // ray direction
|
||||
tMax, // ray max range
|
||||
1 // payload (location = 1)
|
||||
);
|
||||
~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
## Ray tracing Pipeline
|
||||
|
||||
The final step is to add the new Hit Group. This is a change in `HelloVulkan::createRtPipeline()`.
|
||||
We need to load the new any hit shader and create a new Hit Group.
|
||||
|
||||
Replace the `"shaders/raytrace.rahit.spv"` for `"shaders/raytrace_0.rahit.spv"`
|
||||
|
||||
Then, after the creating of the first Hit Group, create a new one, where only the any hit using payload 1
|
||||
is added. We are skipping the closest hit shader in the trace call, so we can ignore it in the Hit Group.
|
||||
|
||||
~~~~ C
|
||||
// Payload 1
|
||||
vk::ShaderModule ahit1SM =
|
||||
nvvk::createShaderModule(m_device, //
|
||||
nvh::loadFile("shaders/raytrace_1.rahit.spv", true, paths));
|
||||
hg.setClosestHitShader(VK_SHADER_UNUSED_NV); // Not used by shadow (skipped)
|
||||
hg.setAnyHitShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eAnyHitNV, ahit1SM, "main"});
|
||||
m_rtShaderGroups.push_back(hg);
|
||||
~~~~
|
||||
|
||||
At the end of the function, delete the shader module `ahit1SM`.
|
||||
|
||||
|
||||
!!! NOTE Re-Run
|
||||
Everything should work as before, but now it does it right.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_anyhit](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_anyhit)
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Instances**
|
||||
|
||||
<small>Author: [Martin-Karl Lefrançois](https://devblogs.nvidia.com/author/mlefrancois/)</small>
|
||||
|
||||
|
||||

|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.htm).
|
||||
|
||||
Ray tracing allow to use [callable shaders](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap8.html#shaders-callable)
|
||||
in ray-generation, closest-hit, miss or another callable shader stage.
|
||||
It is similar to an indirect function call, whitout having to link those shaders with the executable program.
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
|
||||
# Data Storage
|
||||
|
||||
Data can only access data passed in to the callable from parent stage. There will be only one structure pass at a time and should be declared like for payload.
|
||||
|
||||
In the parent stage, using the `callableDataEXT` storage qualifier, it could be declared like:
|
||||
|
||||
~~~~ C++
|
||||
layout(location = 0) callableDataEXT rayLight cLight;
|
||||
~~~~
|
||||
|
||||
where `rayLight` struct is defined in a shared file.
|
||||
|
||||
~~~~ C++
|
||||
struct rayLight
|
||||
{
|
||||
vec3 inHitPosition;
|
||||
float outLightDistance;
|
||||
vec3 outLightDir;
|
||||
float outIntensity;
|
||||
};
|
||||
~~~~
|
||||
|
||||
And in the incoming callable shader, you must use the `callableDataInEXT` storage qualifier.
|
||||
|
||||
~~~~ C++
|
||||
layout(location = 0) callableDataInEXT rayLight cLight;
|
||||
~~~~
|
||||
|
||||
# Execution
|
||||
|
||||
To execute one of the callable shader, the parent stage need to call `executeCallableEXT`.
|
||||
|
||||
The first parameter is the SBT record index, the second one correspond to the 'location' index.
|
||||
|
||||
Example of how it is called.
|
||||
|
||||
~~~~ C++
|
||||
executeCallableEXT(pushC.lightType, 0);
|
||||
~~~~
|
||||
|
||||
|
||||
# Adding Callable Shaders to the SBT
|
||||
|
||||
## Create Shader Modules
|
||||
|
||||
In `HelloVulkan::createRtPipeline()`, immediately after adding the closest-hit shader, we will add
|
||||
3 callable shaders, for each type of light.
|
||||
|
||||
~~~~ C++
|
||||
// Callable shaders
|
||||
vk::RayTracingShaderGroupCreateInfoKHR callGroup{vk::RayTracingShaderGroupTypeKHR::eGeneral,
|
||||
VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR,
|
||||
VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR};
|
||||
|
||||
vk::ShaderModule call0 =
|
||||
nvvk::createShaderModule(m_device,
|
||||
nvh::loadFile("shaders/light_point.rcall.spv", true, paths));
|
||||
vk::ShaderModule call1 =
|
||||
nvvk::createShaderModule(m_device,
|
||||
nvh::loadFile("shaders/light_spot.rcall.spv", true, paths));
|
||||
vk::ShaderModule call2 =
|
||||
nvvk::createShaderModule(m_device, nvh::loadFile("shaders/light_inf.rcall.spv", true, paths));
|
||||
|
||||
callGroup.setGeneralShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eCallableKHR, call0, "main"});
|
||||
m_rtShaderGroups.push_back(callGroup);
|
||||
callGroup.setGeneralShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eCallableKHR, call1, "main"});
|
||||
m_rtShaderGroups.push_back(callGroup);
|
||||
callGroup.setGeneralShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eCallableKHR, call2, "main"});
|
||||
m_rtShaderGroups.push_back(callGroup);
|
||||
~~~~
|
||||
|
||||
And at the end of the function, delete the shaders.
|
||||
|
||||
~~~~ C++
|
||||
m_device.destroy(call0);
|
||||
m_device.destroy(call1);
|
||||
m_device.destroy(call2);
|
||||
~~~~
|
||||
|
||||
### Shaders
|
||||
|
||||
Here are the source of all shaders
|
||||
|
||||
* [light_point.rcall](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/blob/master/ray_tracing_callable/shaders/light_point.rcall)
|
||||
* [light_spot.rcall](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/blob/master/ray_tracing_callable/shaders/light_spot.rcall)
|
||||
* [light_inf.rcall](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/blob/master/ray_tracing_callable/shaders/light_inf.rcall)
|
||||
|
||||
|
||||
## Passing Callable to traceRaysKHR
|
||||
|
||||
In `HelloVulkan::raytrace()`, we have to tell where the callable shader starts. Since they were added after the hit shader, we have in the SBT the following.
|
||||
|
||||
********************
|
||||
* +---------+
|
||||
* | ray-gen |
|
||||
* +---------+
|
||||
* | miss0 |
|
||||
* | miss1 |
|
||||
* +---------+
|
||||
* | hit0 |
|
||||
* +---------+
|
||||
* | call0 |
|
||||
* | call1 |
|
||||
* | call2 |
|
||||
* +---------+
|
||||
********************
|
||||
|
||||
Therefore, the callable starts at `4 * progSize`
|
||||
|
||||
~~~~ C++
|
||||
vk::DeviceSize callableGroupOffset = 4u * progSize; // Jump over the previous shaders
|
||||
vk::DeviceSize callableGroupStride = progSize;
|
||||
~~~~
|
||||
|
||||
Then we can call `traceRaysKHR`
|
||||
|
||||
~~~~ C++
|
||||
const vk::StridedBufferRegionKHR callableShaderBindingTable = {
|
||||
m_rtSBTBuffer.buffer, callableGroupOffset, progSize, sbtSize};
|
||||
|
||||
cmdBuf.traceRaysKHR(&raygenShaderBindingTable, &missShaderBindingTable, &hitShaderBindingTable,
|
||||
&callableShaderBindingTable, //
|
||||
m_size.width, m_size.height, 1); //
|
||||
~~~~
|
||||
|
||||
# Calling the Callable Shaders
|
||||
|
||||
In the closest-hit shader, instead of having a if-else case, we can now call directly the right shader base on the type of light.
|
||||
|
||||
~~~~ C++
|
||||
cLight.inHitPosition = worldPos;
|
||||
//#define DONT_USE_CALLABLE
|
||||
#if defined(DONT_USE_CALLABLE)
|
||||
// Point light
|
||||
if(pushC.lightType == 0)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - cLight.inHitPosition;
|
||||
float lightDistance = length(lDir);
|
||||
cLight.outIntensity = pushC.lightIntensity / (lightDistance * lightDistance);
|
||||
cLight.outLightDir = normalize(lDir);
|
||||
cLight.outLightDistance = lightDistance;
|
||||
}
|
||||
else if(pushC.lightType == 1)
|
||||
{
|
||||
vec3 lDir = pushC.lightPosition - cLight.inHitPosition;
|
||||
cLight.outLightDistance = length(lDir);
|
||||
cLight.outIntensity =
|
||||
pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance);
|
||||
cLight.outLightDir = normalize(lDir);
|
||||
float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection));
|
||||
float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff;
|
||||
float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0);
|
||||
cLight.outIntensity *= spotIntensity;
|
||||
}
|
||||
else // Directional light
|
||||
{
|
||||
cLight.outLightDir = normalize(-pushC.lightDirection);
|
||||
cLight.outIntensity = 1.0;
|
||||
cLight.outLightDistance = 10000000;
|
||||
}
|
||||
#else
|
||||
executeCallableEXT(pushC.lightType, 0);
|
||||
#endif
|
||||
~~~~
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_callable](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_callable)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
|
||||
|
||||
## [Jitter Camera (Anti-Aliasing)](vkrt_tuto_jitter_cam.md.htm)
|
||||
|
||||
Anti-aliases the image by accumulating small variations of rays over time.
|
||||
|
||||
* Random ray direction generation
|
||||
* Read/write/accumulate final image
|
||||
|
||||

|
||||
|
||||
## [Handle Thousands of Objects](vkrt_tuto_instances.md.htm)
|
||||
|
||||
The current example allocates memory for each object, each of which has several buffers.
|
||||
This shows how to get around Vulkan's limits on the total number of memory allocations by using a memory allocator.
|
||||
|
||||
* Extend the limit of 4096 memory allocations
|
||||
* Using memory allocators: DMA, VMA
|
||||
|
||||

|
||||
|
||||
## [Any Hit Shader (Transparency)](vkrt_tuto_anyhit.md.htm)
|
||||
|
||||
Implements transparent materials by adding a new shader to the Hit group and using the material
|
||||
information to discard hits over time.
|
||||
|
||||
* Adding anyhit (.ahit) to the ray tracing pipeline
|
||||
* Randomly letting the ray hit or not which is making simple transparency
|
||||
|
||||

|
||||
|
||||
|
||||
## [Reflections](vkrt_tuto_reflection.md.htm)
|
||||
|
||||
Reflections can be implemented by shooting new rays from the closest hit shader, or by iteratively shooting them from
|
||||
the raygen shader. This example shows the limitations and differences of these implementations.
|
||||
|
||||
* Calling traceRayEXT() from the closest hit shader (recursive)
|
||||
* Adding more data to the ray payload to continue the ray from the raygen shader.
|
||||
|
||||

|
||||
|
||||
|
||||
## [Multiple Closest Hits Shader and Shader Records](vkrt_tuto_manyhits.md.htm)
|
||||
|
||||
Explains how to add more closest hit shaders, choose which instance uses which shader, and add data per SBT that can be
|
||||
retrieved in the shader, and more.
|
||||
|
||||
* One closest hit shader per object
|
||||
* Sharing closest hit shaders for some object
|
||||
* Passing shader record to closest hit shader
|
||||
|
||||

|
||||
|
||||
|
||||
## [Animation](vkrt_tuto_animation.md.htm)
|
||||
|
||||
This tutorial shows how animating the transformation matrices of the instances (TLAS)
|
||||
and animating the vertices of an object (BLAS) in a compute shader, could be done.
|
||||
|
||||
* Refit of top level acceleration structure
|
||||
* Refit of bottom level acceleration structure
|
||||
|
||||

|
||||
|
||||
|
||||
## [Intersection Shader](vkrt_tuto_intersection.md.html)
|
||||
|
||||
Adding thousands of implicit primitives and using an intersection shader to render spheres and cubes. The tutorial
|
||||
explains what is needed to get procedural hit group working.
|
||||
|
||||
* Intersection Shader
|
||||
* Sphere intersection
|
||||
* Axis aligned bounding box intersection
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## [Callable Shader](vkrt_tuto_callable.md.html)
|
||||
|
||||
Replacing if/else by callable shaders. The code to execute the lighting is done in separate callable shaders instead of been part of the code.
|
||||
|
||||
* Adding multiple callable shaders
|
||||
* Calling ExecuteCallableEXT from the closest hit shader
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
## [Ray Query](vkrt_tuto_rayquery.md.htm)
|
||||
|
||||
Invoking ray intersection queries directly from the fragment shader to cast shadow rays.
|
||||
|
||||
* Ray tracing directly from the fragment shader
|
||||
|
||||

|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://casual-effects.com/markdeep/latest/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,272 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Instances**
|
||||
|
||||
<small>Authors: [Martin-Karl Lefrançois](https://devblogs.nvidia.com/author/mlefrancois/), Neil Bickford </small>
|
||||
|
||||
|
||||

|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
Ray tracing can easily handle having many object instances at once. For instance, a top level acceleration structure can
|
||||
have many different instances of a bottom level acceleration structure. However, when we have many different objects, we
|
||||
can run into problems with memory allocation. Many Vulkan implementations support no more than 4096 allocations, while
|
||||
our current application creates 4 allocations per object (Vertex, Index, and Material), then one for the BLAS. That
|
||||
means we are hitting the limit with just above 1000 objects.
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
# Many Instances
|
||||
|
||||
First, let's look how the scene would look like when we have just a few objects, with many instances.
|
||||
|
||||
In `main.cpp`, add the following includes:
|
||||
|
||||
~~~~ C++
|
||||
#include <random>
|
||||
~~~~
|
||||
|
||||
Then replace the calls to `helloVk.loadModel` in `main()` by
|
||||
|
||||
~~~~ C++
|
||||
// Creation of the example
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/cube.obj", defaultSearchPaths));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/cube_multi.obj", defaultSearchPaths));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths));
|
||||
|
||||
std::random_device rd; // Will be used to obtain a seed for the random number engine
|
||||
std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
|
||||
std::normal_distribution<float> dis(1.0f, 1.0f);
|
||||
std::normal_distribution<float> disn(0.05f, 0.05f);
|
||||
|
||||
for(int n = 0; n < 2000; ++n)
|
||||
{
|
||||
HelloVulkan::ObjInstance inst;
|
||||
inst.objIndex = n % 2;
|
||||
inst.txtOffset = 0;
|
||||
float scale = fabsf(disn(gen));
|
||||
nvmath::mat4f mat =
|
||||
nvmath::translation_mat4(nvmath::vec3f{dis(gen), 2.0f + dis(gen), dis(gen)});
|
||||
mat = mat * nvmath::rotation_mat4_x(dis(gen));
|
||||
mat = mat * nvmath::scale_mat4(nvmath::vec3f(scale));
|
||||
inst.transform = mat;
|
||||
inst.transformIT = nvmath::transpose(nvmath::invert((inst.transform)));
|
||||
helloVk.m_objInstance.push_back(inst);
|
||||
}
|
||||
~~~~
|
||||
|
||||
!!! Note:
|
||||
This will create 3 models (OBJ) and their instances, and then add 2000 instances
|
||||
distributed between green cubes and cubes with one color per face.
|
||||
|
||||
# Many Objects
|
||||
|
||||
Instead of creating many instances, create many objects.
|
||||
|
||||
Remove the previous code and replace it with the following
|
||||
|
||||
~~~~ C++
|
||||
// Creation of the example
|
||||
std::random_device rd; //Will be used to obtain a seed for the random number engine
|
||||
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
|
||||
std::normal_distribution<float> dis(1.0f, 1.0f);
|
||||
std::normal_distribution<float> disn(0.05f, 0.05f);
|
||||
for(int n = 0; n < 2000; ++n)
|
||||
{
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/cube_multi.obj", defaultSearchPaths));
|
||||
HelloVulkan::ObjInstance& inst = helloVk.m_objInstance.back();
|
||||
|
||||
float scale = fabsf(disn(gen));
|
||||
nvmath::mat4f mat =
|
||||
nvmath::translation_mat4(nvmath::vec3f{dis(gen), 2.0f + dis(gen), dis(gen)});
|
||||
mat = mat * nvmath::rotation_mat4_x(dis(gen));
|
||||
mat = mat * nvmath::scale_mat4(nvmath::vec3f(scale));
|
||||
inst.transform = mat;
|
||||
inst.transformIT = nvmath::transpose(nvmath::invert((inst.transform)));
|
||||
}
|
||||
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths));
|
||||
~~~~
|
||||
|
||||
The example might still work, but the console will print the following error after loading 1363 objects. All other objects allocated after the 1363rd will fail to be displayed.
|
||||
!!! Error
|
||||
Error: VUID_Undefined
|
||||
Number of currently valid memory objects is not less than the maximum allowed (4096).
|
||||
- Object[0] - Type Device
|
||||
|
||||
!!! Note:
|
||||
This is the best case; the application can run out of memory and crash if substantially more objects are created (e.g. 20,000)
|
||||
|
||||
# Device Memory Allocator (DMA)
|
||||
|
||||
It is possible to use a memory allocator to fix this issue.
|
||||
|
||||
## `hello_vulkan.h`
|
||||
|
||||
In `hello_vulkan.h`, add the following defines at the top of the file to indicate which allocator to use
|
||||
|
||||
~~~~ C++
|
||||
// #VKRay
|
||||
//#define ALLOC_DEDICATED
|
||||
#define ALLOC_DMA
|
||||
~~~~
|
||||
|
||||
|
||||
Replace the definition of buffers and textures and include the right allocator.
|
||||
|
||||
~~~~ C++
|
||||
#if defined(ALLOC_DEDICATED)
|
||||
#include "nvvk/allocator_dedicated_vk.hpp"
|
||||
using nvvkBuffer = nvvk::BufferDedicated;
|
||||
using nvvkTexture = nvvk::TextureDedicated;
|
||||
#elif defined(ALLOC_DMA)
|
||||
#include "nvvk/allocator_dma_vk.hpp"
|
||||
using nvvkBuffer = nvvk::BufferDma;
|
||||
using nvvkTexture = nvvk::TextureDma;
|
||||
#endif
|
||||
~~~~
|
||||
|
||||
And do the same for the allocator
|
||||
|
||||
~~~~ C++
|
||||
#if defined(ALLOC_DEDICATED)
|
||||
nvvk::AllocatorDedicated m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
#elif defined(ALLOC_DMA)
|
||||
nvvk::AllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DeviceMemoryAllocator m_memAllocator;
|
||||
nvvk::StagingMemoryManagerDma m_staging;
|
||||
#endif
|
||||
~~~~
|
||||
|
||||
## `hello_vulkan.cpp`
|
||||
|
||||
In the source file there are also a few changes to make.
|
||||
|
||||
DMA needs to be initialized, which will be done in the `setup()` function:
|
||||
|
||||
~~~~ C++
|
||||
#if defined(ALLOC_DEDICATED)
|
||||
m_alloc.init(device, physicalDevice);
|
||||
#elif defined(ALLOC_DMA)
|
||||
m_memAllocator.init(device, physicalDevice);
|
||||
m_memAllocator.setAllocateFlags(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR, true);
|
||||
m_staging.init(m_memAllocator);
|
||||
m_alloc.init(device, m_memAllocator, m_staging);
|
||||
#endif
|
||||
~~~~
|
||||
|
||||
When using DMA, memory buffer mapping is done through the DMA interface (instead of the VKDevice).
|
||||
Therefore, change the lines at the end of `updateUniformBuffer()` to use the common allocator interface.
|
||||
|
||||
~~~~ C++
|
||||
void* data = m_alloc.map(m_cameraMat);
|
||||
memcpy(data, &ubo, sizeof(ubo));
|
||||
m_alloc.unmap(m_cameraMat);
|
||||
~~~~
|
||||
|
||||
The RaytracerBuilder was made to allow various allocators, therefore nothing to change in the call to `m_rtBuilder.setup()`
|
||||
|
||||
|
||||
## Destruction
|
||||
|
||||
The VMA allocator need to be released in `HelloVulkan::destroyResources()` after the last `m_alloc.destroy`.
|
||||
|
||||
~~~~ C++
|
||||
#if defined(ALLOC_DMA)
|
||||
m_dmaAllocator.deinit();
|
||||
#endif
|
||||
~~~~
|
||||
|
||||
# Result
|
||||
|
||||
Instead of thousands of allocations, our example will have only 14 allocations. Note that some of these allocations are allocated by Dear ImGui, and not by DMA. These are the 14 objects with blue borders below:
|
||||
|
||||

|
||||
|
||||
Finally, here is the Vulkan Device Memory view from Nsight Graphics:
|
||||

|
||||
|
||||
|
||||
|
||||
# VMA: Vulkan Memory Allocator
|
||||
|
||||
We can also modify the code to use the [Vulkan Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) from AMD.
|
||||
|
||||
Download [vk_mem_alloc.h](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/blob/master/src/vk_mem_alloc.h) from GitHub and add this to the `shared_sources` folder.
|
||||
|
||||
There is already a variation of the allocator for VMA, which is located under [nvpro-samples](https://github.com/nvpro-samples/shared_sources/tree/master/nvvk). This allocator has the same simple interface as the `AllocatorDedicated` class in `allocator_dedicated_vkpp.hpp`, but will use VMA for memory management.
|
||||
|
||||
VMA might use dedicated memory, which we do, so you need to add the following extension to the
|
||||
creation of the context in `main.cpp`.
|
||||
|
||||
~~~~ C++
|
||||
contextInfo.addDeviceExtension(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
|
||||
~~~~
|
||||
|
||||
## hello_vulkan.h
|
||||
|
||||
Follow the changes done before and add the following
|
||||
|
||||
~~~~ C++
|
||||
#define ALLOC_VMA
|
||||
~~~~
|
||||
|
||||
~~~~ C++
|
||||
#elif defined(ALLOC_VMA)
|
||||
#include "nvvk/allocator_vma_vk.hpp"
|
||||
using nvvkBuffer = nvvk::BufferVma;
|
||||
using nvvkTexture = nvvk::TextureVma;
|
||||
~~~~
|
||||
|
||||
~~~~ C++
|
||||
#elif defined(ALLOC_VMA)
|
||||
nvvk::AllocatorVma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::StagingMemoryManagerVma m_staging;
|
||||
VmaAllocator m_memAllocator;
|
||||
~~~~
|
||||
|
||||
|
||||
## hello_vulkan.cpp
|
||||
First, the following should only be defined once in the entire program, and it should be defined before `#include "hello_vulkan.h"`:
|
||||
|
||||
~~~~ C++
|
||||
#define VMA_IMPLEMENTATION
|
||||
~~~~
|
||||
|
||||
In `setup()`
|
||||
|
||||
~~~~ C++
|
||||
#elif defined(ALLOC_VMA)
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.instance = instance;
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
allocatorInfo.device = device;
|
||||
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
||||
vmaCreateAllocator(&allocatorInfo, &m_memAllocator);
|
||||
m_staging.init(device, physicalDevice, m_memAllocator);
|
||||
m_alloc.init(device, m_memAllocator, m_staging);
|
||||
~~~~
|
||||
|
||||
In `destroyResources()`
|
||||
|
||||
~~~~ C++
|
||||
#elif defined(ALLOC_VMA)
|
||||
vmaDestroyAllocator(m_vmaAllocator);
|
||||
~~~~
|
||||
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_instances](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_instances)
|
||||
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,564 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Intersection Shader**
|
||||
|
||||
<small>Author: [Martin-Karl Lefrançois](https://devblogs.nvidia.com/author/mlefrancois/)</small>
|
||||
|
||||
|
||||

|
||||
|
||||
# Introduction
|
||||
|
||||
This tutorial chapter shows how to use intersection shader and render different primitives with different materials.
|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.htm).
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
## High Level Implementation
|
||||
|
||||
On a high level view, we will
|
||||
|
||||
* Add 2.000.000 axis aligned bounding boxes in a BLAS
|
||||
* 2 materials will be added
|
||||
* Every second intersected object will be a sphere or a cube and will use one of the two material.
|
||||
|
||||
To do this, we will need to:
|
||||
|
||||
* Add an intersection shader (.rint)
|
||||
* Add a new closest hit shader (.chit)
|
||||
* Create `VkAccelerationStructureGeometryKHR` from `VkAccelerationStructureGeometryAabbsDataKHR`
|
||||
|
||||
## Creating all spheres
|
||||
|
||||
In the HelloVulkan class, we will add the structures we will need. First the structure that defines a sphere.
|
||||
|
||||
~~~~ C++
|
||||
struct Sphere
|
||||
{
|
||||
nvmath::vec3f center;
|
||||
float radius;
|
||||
};
|
||||
~~~~
|
||||
|
||||
Then we need the Aabb structure holding all the spheres, but also used for the creation of the BLAS (`VK_GEOMETRY_TYPE_AABBS_KHR`).
|
||||
|
||||
~~~~ C++
|
||||
struct Aabb
|
||||
{
|
||||
nvmath::vec3f minimum;
|
||||
nvmath::vec3f maximum;
|
||||
};
|
||||
~~~~
|
||||
|
||||
All the information will need to be hold in buffers, which will be available to the shaders.
|
||||
|
||||
<script type="preformatted">
|
||||
~~~~ C++
|
||||
std::vector<Sphere> m_spheres; // All spheres
|
||||
nvvkBuffer m_spheresBuffer; // Buffer holding the spheres
|
||||
nvvkBuffer m_spheresAabbBuffer; // Buffer of all Aabb
|
||||
nvvkBuffer m_spheresMatColorBuffer; // Multiple materials
|
||||
nvvkBuffer m_spheresMatIndexBuffer; // Define which sphere uses which material
|
||||
~~~~
|
||||
|
||||
Finally, there are two functions, one to create the spheres, and one that will create the intermediate structure for the BLAS.
|
||||
|
||||
~~~~ C++
|
||||
void createSpheres();
|
||||
nvvk::RaytracingBuilderKHR::Blas sphereToVkGeometryKHR();
|
||||
~~~~
|
||||
|
||||
The following implementation will create 2.000.000 spheres at random positions and radius. It will create the Aabb from the sphere definition, two materials which will be assigned alternatively to each object. All the created information will be moved to Vulkan buffers to be accessed by the intersection and closest shaders.
|
||||
|
||||
~~~~ C++
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Creating all spheres
|
||||
//
|
||||
void HelloVulkan::createSpheres()
|
||||
{
|
||||
std::random_device rd{};
|
||||
std::mt19937 gen{rd()};
|
||||
std::normal_distribution<float> xzd{0.f, 5.f};
|
||||
std::normal_distribution<float> yd{3.f, 1.f};
|
||||
std::uniform_real_distribution<float> radd{.05f, .2f};
|
||||
|
||||
// All spheres
|
||||
Sphere s;
|
||||
for(uint32_t i = 0; i < 2000000; i++)
|
||||
{
|
||||
s.center = nvmath::vec3f(xzd(gen), yd(gen), xzd(gen));
|
||||
s.radius = radd(gen);
|
||||
m_spheres.emplace_back(s);
|
||||
}
|
||||
|
||||
// Axis aligned bounding box of each sphere
|
||||
std::vector<Aabb> aabbs;
|
||||
for(const auto& s : m_spheres)
|
||||
{
|
||||
Aabb aabb;
|
||||
aabb.minimum = s.center - nvmath::vec3f(s.radius);
|
||||
aabb.maximum = s.center + nvmath::vec3f(s.radius);
|
||||
aabbs.emplace_back(aabb);
|
||||
}
|
||||
|
||||
// Creating two materials
|
||||
MatrialObj mat;
|
||||
mat.diffuse = vec3f(0, 1, 1);
|
||||
std::vector<MatrialObj> materials;
|
||||
std::vector<int> matIdx;
|
||||
materials.emplace_back(mat);
|
||||
mat.diffuse = vec3f(1, 1, 0);
|
||||
materials.emplace_back(mat);
|
||||
|
||||
// Assign a material to each sphere
|
||||
for(size_t i = 0; i < m_spheres.size(); i++)
|
||||
{
|
||||
matIdx.push_back(i % 2);
|
||||
}
|
||||
|
||||
// Creating all buffers
|
||||
using vkBU = vk::BufferUsageFlagBits;
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
||||
auto cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
m_spheresBuffer = m_alloc.createBuffer(cmdBuf, m_spheres, vkBU::eStorageBuffer);
|
||||
m_spheresAabbBuffer = m_alloc.createBuffer(cmdBuf, aabbs, vkBU::eShaderDeviceAddress);
|
||||
m_spheresMatIndexBuffer = m_alloc.createBuffer(cmdBuf, matIdx, vkBU::eStorageBuffer);
|
||||
m_spheresMatColorBuffer = m_alloc.createBuffer(cmdBuf, materials, vkBU::eStorageBuffer);
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
|
||||
// Debug information
|
||||
m_debug.setObjectName(m_spheresBuffer.buffer, "spheres");
|
||||
m_debug.setObjectName(m_spheresAabbBuffer.buffer, "spheresAabb");
|
||||
m_debug.setObjectName(m_spheresMatColorBuffer.buffer, "spheresMat");
|
||||
m_debug.setObjectName(m_spheresMatIndexBuffer.buffer, "spheresMatIdx");
|
||||
}
|
||||
~~~~
|
||||
|
||||
Do not forget to destroy the buffers in `destroyResources()`
|
||||
|
||||
~~~~ C++
|
||||
m_alloc.destroy(m_spheresBuffer);
|
||||
m_alloc.destroy(m_spheresAabbBuffer);
|
||||
m_alloc.destroy(m_spheresMatColorBuffer);
|
||||
m_alloc.destroy(m_spheresMatIndexBuffer);
|
||||
~~~~
|
||||
|
||||
We need a new bottom level acceleration structure (BLAS) to hold the implicit primitives. For efficiency and since all those primitives are static, they will all be added in a single BLAS.
|
||||
|
||||
What is changing compare to triangle primitive is the Aabb data (see Aabb structure) and the geometry type (`VK_GEOMETRY_TYPE_AABBS_KHR`).
|
||||
|
||||
~~~~ C++
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Returning the ray tracing geometry used for the BLAS, containing all spheres
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::Blas HelloVulkan::sphereToVkGeometryKHR()
|
||||
{
|
||||
vk::AccelerationStructureCreateGeometryTypeInfoKHR asCreate;
|
||||
asCreate.setGeometryType(vk::GeometryTypeKHR::eAabbs);
|
||||
asCreate.setMaxPrimitiveCount((uint32_t)m_spheres.size()); // Nb triangles
|
||||
asCreate.setIndexType(vk::IndexType::eNoneKHR);
|
||||
asCreate.setVertexFormat(vk::Format::eUndefined);
|
||||
asCreate.setMaxVertexCount(0);
|
||||
asCreate.setAllowsTransforms(VK_FALSE); // No adding transformation matrices
|
||||
|
||||
|
||||
vk::DeviceAddress dataAddress = m_device.getBufferAddress({m_spheresAabbBuffer.buffer});
|
||||
vk::AccelerationStructureGeometryAabbsDataKHR aabbs;
|
||||
aabbs.setData(dataAddress);
|
||||
aabbs.setStride(sizeof(Aabb));
|
||||
|
||||
// Setting up the build info of the acceleration
|
||||
vk::AccelerationStructureGeometryKHR asGeom;
|
||||
asGeom.setGeometryType(asCreate.geometryType);
|
||||
asGeom.setFlags(vk::GeometryFlagBitsKHR::eOpaque);
|
||||
asGeom.geometry.setAabbs(aabbs);
|
||||
|
||||
vk::AccelerationStructureBuildOffsetInfoKHR offset;
|
||||
offset.setFirstVertex(0);
|
||||
offset.setPrimitiveCount(asCreate.maxPrimitiveCount);
|
||||
offset.setPrimitiveOffset(0);
|
||||
offset.setTransformOffset(0);
|
||||
|
||||
nvvk::RaytracingBuilderKHR::Blas blas;
|
||||
blas.asGeometry.emplace_back(asGeom);
|
||||
blas.asCreateGeometryInfo.emplace_back(asCreate);
|
||||
blas.asBuildOffsetInfo.emplace_back(offset);
|
||||
return blas;
|
||||
}
|
||||
~~~~
|
||||
|
||||
## Setting up the scene
|
||||
|
||||
In `main.cpp`, where we are loading the OBJ model, we can replace it with
|
||||
|
||||
~~~~ C++
|
||||
// Creation of the example
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths));
|
||||
helloVk.createSpheres();
|
||||
~~~~
|
||||
|
||||
**Note**: it is possible to have more OBJ models, but the spheres will need to be added after all of them.
|
||||
|
||||
The scene will be large, better to move the camera out
|
||||
|
||||
~~~~ C++
|
||||
CameraManip.setLookat(nvmath::vec3f(20, 20, 20), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
||||
~~~~
|
||||
|
||||
## Acceleration structures
|
||||
|
||||
### BLAS
|
||||
|
||||
The function `createBottomLevelAS()` is creating a BLAS per OBJ, the following modification will add a new BLAS containing the Aabb's of all spheres.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::createBottomLevelAS()
|
||||
{
|
||||
// BLAS - Storing each primitive in a geometry
|
||||
std::vector<nvvk::RaytracingBuilderKHR::Blas> allBlas;
|
||||
allBlas.reserve(m_objModel.size());
|
||||
for(const auto& obj : m_objModel)
|
||||
{
|
||||
auto blas = objectToVkGeometryKHR(obj);
|
||||
|
||||
// We could add more geometry in each BLAS, but we add only one for now
|
||||
allBlas.emplace_back(blas);
|
||||
}
|
||||
|
||||
// Spheres
|
||||
{
|
||||
auto blas = sphereToVkGeometryKHR();
|
||||
allBlas.emplace_back(blas);
|
||||
}
|
||||
|
||||
m_rtBuilder.buildBlas(allBlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
|
||||
}
|
||||
~~~~
|
||||
|
||||
### TLAS
|
||||
|
||||
Similarly in `createTopLevelAS()`, the top level acceleration structure will need to add a reference to the BLAS of the spheres. We are setting the instanceCustomId and blasId to the last element, which is why the sphere BLAS must be added after everything else.
|
||||
|
||||
The hitGroupId will be set to 1 instead of 0. We need to add a new hit group for the implicit primitives, since we will need to compute attributes like the normal, since they are not provide like with triangle primitives.
|
||||
|
||||
Just before building the TLAS, we need to add the following
|
||||
|
||||
~~~~ C++
|
||||
// Add the blas containing all spheres
|
||||
{
|
||||
nvvk::RaytracingBuilder::Instance rayInst;
|
||||
rayInst.transform = m_objInstance[0].transform; // Position of the instance
|
||||
rayInst.instanceCustomId = static_cast<uint32_t>(tlas.size()); // gl_InstanceCustomIndexEXT
|
||||
rayInst.blasId = static_cast<uint32_t>(m_objModel.size());
|
||||
rayInst.hitGroupId = 1; // We will use the same hit group for all objects
|
||||
rayInst.flags = vk::GeometryInstanceFlagBitsKHR::eTriangleCullDisable;
|
||||
tlas.emplace_back(rayInst);
|
||||
}
|
||||
~~~~
|
||||
|
||||
## Descriptors
|
||||
|
||||
To access the newly created buffers holding all the spheres and materials, some changes are required to the descriptors.
|
||||
|
||||
In function `createDescriptorSetLayout()`, the addition of the material and material index need to be instructed.
|
||||
|
||||
~~~~ C++
|
||||
// Materials (binding = 1)
|
||||
m_descSetLayoutBind.emplace_back(vkDS(1, vkDT::eStorageBuffer, nbObj + 1,
|
||||
vkSS::eVertex | vkSS::eFragment | vkSS::eClosestHitKHR));
|
||||
// Materials Index (binding = 4)
|
||||
m_descSetLayoutBind.emplace_back(
|
||||
vkDS(4, vkDT::eStorageBuffer, nbObj + 1, vkSS::eFragment | vkSS::eClosestHitKHR));
|
||||
~~~~
|
||||
|
||||
And the new buffer holding the spheres
|
||||
|
||||
~~~~ C++
|
||||
// Storing spheres (binding = 7)
|
||||
m_descSetLayoutBind.emplace_back( //
|
||||
vkDS(7, vkDT::eStorageBuffer, 1, vkSS::eClosestHitKHR | vkSS::eIntersectionKHR));
|
||||
~~~~
|
||||
|
||||
The function `updateDescriptorSet()` which is writing the values of the buffer need also to be modified.
|
||||
|
||||
At the end of the loop on all models, lets add the new material and material index.
|
||||
|
||||
~~~~ C++
|
||||
for(auto& model : m_objModel)
|
||||
{
|
||||
dbiMat.emplace_back(model.matColorBuffer.buffer, 0, VK_WHOLE_SIZE);
|
||||
dbiMatIdx.emplace_back(model.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE);
|
||||
dbiVert.emplace_back(model.vertexBuffer.buffer, 0, VK_WHOLE_SIZE);
|
||||
dbiIdx.emplace_back(model.indexBuffer.buffer, 0, VK_WHOLE_SIZE);
|
||||
}
|
||||
dbiMat.emplace_back(m_spheresMatColorBuffer.buffer, 0, VK_WHOLE_SIZE);
|
||||
dbiMatIdx.emplace_back(m_spheresMatIndexBuffer.buffer, 0, VK_WHOLE_SIZE);
|
||||
~~~~
|
||||
|
||||
Then write the buffer for the spheres
|
||||
|
||||
~~~~ C++
|
||||
vk::DescriptorBufferInfo dbiSpheres{m_spheresBuffer.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, dbiSpheres));
|
||||
~~~~
|
||||
|
||||
## Intersection Shader
|
||||
|
||||
The intersection shader is added to the Hit Group `VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR`. In our example, we already have a Hit Group for triangle and a closest hit associated. We will add a new one, which will become the Hit Group ID (1), see the TLAS section.
|
||||
|
||||
Here is how the two hit group looks like:
|
||||
|
||||
~~~~ C++
|
||||
// Hit Group0 - Closest Hit
|
||||
vk::ShaderModule chitSM =
|
||||
nvvk::createShaderModule(m_device, //
|
||||
nvh::loadFile("shaders/raytrace.rchit.spv", true, paths));
|
||||
|
||||
{
|
||||
vk::RayTracingShaderGroupCreateInfoKHR hg{vk::RayTracingShaderGroupTypeKHR::eTrianglesHitGroup,
|
||||
VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR,
|
||||
VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR};
|
||||
hg.setClosestHitShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eClosestHitKHR, chitSM, "main"});
|
||||
m_rtShaderGroups.push_back(hg);
|
||||
}
|
||||
|
||||
// Hit Group1 - Closest Hit + Intersection (procedural)
|
||||
vk::ShaderModule chit2SM =
|
||||
nvvk::createShaderModule(m_device, //
|
||||
nvh::loadFile("shaders/raytrace2.rchit.spv", true, paths));
|
||||
vk::ShaderModule rintSM =
|
||||
nvvk::createShaderModule(m_device, //
|
||||
nvh::loadFile("shaders/raytrace.rint.spv", true, paths));
|
||||
{
|
||||
vk::RayTracingShaderGroupCreateInfoKHR hg{vk::RayTracingShaderGroupTypeKHR::eProceduralHitGroup,
|
||||
VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR,
|
||||
VK_SHADER_UNUSED_KHR, VK_SHADER_UNUSED_KHR};
|
||||
hg.setClosestHitShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eClosestHitKHR, chit2SM, "main"});
|
||||
hg.setIntersectionShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eIntersectionKHR, rintSM, "main"});
|
||||
m_rtShaderGroups.push_back(hg);
|
||||
}
|
||||
~~~~
|
||||
|
||||
And destroy the two shaders at the end
|
||||
|
||||
~~~~ C++
|
||||
m_device.destroy(chit2SM);
|
||||
m_device.destroy(rintSM);
|
||||
~~~~
|
||||
|
||||
### raycommon.glsl
|
||||
|
||||
To share the structure of the data across the shaders, we can add the following to `raycommon.glsl`
|
||||
|
||||
~~~~ C++
|
||||
struct Sphere
|
||||
{
|
||||
vec3 center;
|
||||
float radius;
|
||||
};
|
||||
|
||||
struct Aabb
|
||||
{
|
||||
vec3 minimum;
|
||||
vec3 maximum;
|
||||
};
|
||||
|
||||
#define KIND_SPHERE 0
|
||||
#define KIND_CUBE 1
|
||||
~~~~
|
||||
|
||||
### raytrace.rint
|
||||
|
||||
The intersection shader `raytrace.rint` need to be added to the shader directory and CMake to be rerun such that it is added to the project. The shader will be called every time a ray will hit one of the Aabb of the scene. Note that there are no Aabb information that can be retrieved in the intersection shader. It is also not possible to have the value of the hit point that the ray tracer might have calculated on the GPU.
|
||||
|
||||
The only information we have is that one of the Aabb was hit and using the `gl_PrimitiveID`, it is possible to know which one it was. Then, with the information stored in the buffer, we can retrive the geometry information of the sphere.
|
||||
|
||||
We first declare the extensions and include common files.
|
||||
|
||||
~~~~ C++
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#include "raycommon.glsl"
|
||||
#include "wavefront.glsl"
|
||||
~~~~
|
||||
|
||||
Then we **must** add the following, otherwise the intersection shader will not report any hit.
|
||||
|
||||
~~~~ C++
|
||||
hitAttributeEXT vec3 HitAttribute;
|
||||
~~~~
|
||||
|
||||
The following is the topology of all spheres, which we will be able to retrieve using `gl_PrimitiveID`.
|
||||
|
||||
~~~~ C++
|
||||
layout(binding = 7, set = 1, scalar) buffer allSpheres_
|
||||
{
|
||||
Sphere i[];
|
||||
}
|
||||
allSpheres;
|
||||
~~~~
|
||||
|
||||
We will implement two intersetion method against the incoming ray.
|
||||
|
||||
~~~~ C++
|
||||
struct Ray
|
||||
{
|
||||
vec3 origin;
|
||||
vec3 direction;
|
||||
};
|
||||
~~~~
|
||||
|
||||
The sphere intersection
|
||||
|
||||
~~~~ C++
|
||||
// Ray-Sphere intersection
|
||||
// http://viclw17.github.io/2018/07/16/raytracing-ray-sphere-intersection/
|
||||
float hitSphere(const Sphere s, const Ray r)
|
||||
{
|
||||
vec3 oc = r.origin - s.center;
|
||||
float a = dot(r.direction, r.direction);
|
||||
float b = 2.0 * dot(oc, r.direction);
|
||||
float c = dot(oc, oc) - s.radius * s.radius;
|
||||
float discriminant = b * b - 4 * a * c;
|
||||
if(discriminant < 0)
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (-b - sqrt(discriminant)) / (2.0 * a);
|
||||
}
|
||||
}
|
||||
~~~~
|
||||
|
||||
And the axis aligned bounding box intersection
|
||||
|
||||
~~~~ C++
|
||||
// Ray-AABB intersection
|
||||
float hitAabb(const Aabb aabb, const Ray r)
|
||||
{
|
||||
vec3 invDir = 1.0 / r.direction;
|
||||
vec3 tbot = invDir * (aabb.minimum - r.origin);
|
||||
vec3 ttop = invDir * (aabb.maximum - r.origin);
|
||||
vec3 tmin = min(ttop, tbot);
|
||||
vec3 tmax = max(ttop, tbot);
|
||||
float t0 = max(tmin.x, max(tmin.y, tmin.z));
|
||||
float t1 = min(tmax.x, min(tmax.y, tmax.z));
|
||||
return t1 > max(t0, 0.0) ? t0 : -1.0;
|
||||
}
|
||||
~~~~
|
||||
|
||||
Both are returning -1 if there is no hit, otherwise, it returns the distance from to origin of the ray.
|
||||
|
||||
Retrieving the ray is straight forward
|
||||
|
||||
~~~~ C++
|
||||
void main()
|
||||
{
|
||||
Ray ray;
|
||||
ray.origin = gl_WorldRayOriginEXT;
|
||||
ray.direction = gl_WorldRayDirectionEXT;
|
||||
~~~~
|
||||
|
||||
And getting the information about the geometry enclosed in the Aabb can be done like this.
|
||||
|
||||
~~~~ C++
|
||||
// Sphere data
|
||||
Sphere sphere = allSpheres.i[gl_PrimitiveID];
|
||||
~~~~
|
||||
|
||||
Now we just need to know if we will hit a sphere or a cube.
|
||||
|
||||
~~~~ C++
|
||||
float tHit = -1;
|
||||
int hitKind = gl_PrimitiveID % 2 == 0 ? KIND_SPHERE : KIND_CUBE;
|
||||
if(hitKind == KIND_SPHERE)
|
||||
{
|
||||
// Sphere intersection
|
||||
tHit = hitSphere(sphere, ray);
|
||||
}
|
||||
else
|
||||
{
|
||||
// AABB intersection
|
||||
Aabb aabb;
|
||||
aabb.minimum = sphere.center - vec3(sphere.radius);
|
||||
aabb.maximum = sphere.center + vec3(sphere.radius);
|
||||
tHit = hitAabb(aabb, ray);
|
||||
}
|
||||
~~~~
|
||||
|
||||
Intersection information is reported using `reportIntersectionEXT`, with a distance from the origin and a second argument (hitKind) that can be used to differentiate the primitive type.
|
||||
|
||||
~~~~ C++
|
||||
|
||||
// Report hit point
|
||||
if(tHit > 0)
|
||||
reportIntersectionEXT(tHit, hitKind);
|
||||
}
|
||||
~~~~
|
||||
|
||||
The shader can be found [here](shaders/raytrace.rint)
|
||||
|
||||
### raytrace2.rchit
|
||||
|
||||
The new closest hit can be found [here](shaders/raytrace2.rchit)
|
||||
|
||||
This shader is almost identical to original `raytrace.rchit`, but since the primitive is implicit, we will only need to compute the normal for the primitive that was hit.
|
||||
|
||||
We retrieve the world position from the ray and the `gl_HitTEXT` which was set in the intersection shader.
|
||||
|
||||
~~~~ C++
|
||||
vec3 worldPos = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
|
||||
~~~~
|
||||
|
||||
The sphere information is retrieved the same way as in the `raytrace.rint` shader.
|
||||
|
||||
~~~~ C++
|
||||
Sphere instance = allSpheres.i[gl_PrimitiveID];
|
||||
~~~~
|
||||
|
||||
Then we compute the normal, as for a sphere.
|
||||
|
||||
~~~~ C++
|
||||
// Computing the normal at hit position
|
||||
vec3 normal = normalize(worldPos - instance.center);
|
||||
~~~~
|
||||
|
||||
To know if we have intersect a cube rather than a sphere, we are using `gl_HitKindEXT`, which was set in the second argument of `reportIntersectionEXT`.
|
||||
|
||||
So when this is a cube, we set the normal to the major axis.
|
||||
|
||||
~~~~ C++
|
||||
// Computing the normal for a cube if the hit intersection was reported as 1
|
||||
if(gl_HitKindEXT == KIND_CUBE) // Aabb
|
||||
{
|
||||
vec3 absN = abs(normal);
|
||||
float maxC = max(max(absN.x, absN.y), absN.z);
|
||||
normal = (maxC == absN.x) ?
|
||||
vec3(sign(normal.x), 0, 0) :
|
||||
(maxC == absN.y) ? vec3(0, sign(normal.y), 0) : vec3(0, 0, sign(normal.z));
|
||||
}
|
||||
~~~~
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_intersection](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_intersection)
|
||||
|
||||
</script>
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,299 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Antialiasing**
|
||||
|
||||
|
||||

|
||||
|
||||
# Introduction
|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
In this extension, we will implement antialiasing by jittering the offset of each ray for each pixel over time, instead of always shooting each ray from the middle of its pixel.
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
|
||||
## Random Functions
|
||||
|
||||
We will use some simple functions for random number generation, which suffice for this example.
|
||||
|
||||
Create a new shader file `random.glsl` with the following code. Add it to the `shaders` directory and rerun CMake, and include this new file in `raytrace.rgen`:
|
||||
|
||||
~~~~ C++
|
||||
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
||||
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
||||
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
||||
uint tea(uint val0, uint val1)
|
||||
{
|
||||
uint v0 = val0;
|
||||
uint v1 = val1;
|
||||
uint s0 = 0;
|
||||
|
||||
for(uint n = 0; n < 16; n++)
|
||||
{
|
||||
s0 += 0x9e3779b9;
|
||||
v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + s0) ^ ((v1 >> 5) + 0xc8013ea4);
|
||||
v1 += ((v0 << 4) + 0xad90777d) ^ (v0 + s0) ^ ((v0 >> 5) + 0x7e95761e);
|
||||
}
|
||||
|
||||
return v0;
|
||||
}
|
||||
|
||||
// Generate a random unsigned int in [0, 2^24) given the previous RNG state
|
||||
// using the Numerical Recipes linear congruential generator
|
||||
uint lcg(inout uint prev)
|
||||
{
|
||||
uint LCG_A = 1664525u;
|
||||
uint LCG_C = 1013904223u;
|
||||
prev = (LCG_A * prev + LCG_C);
|
||||
return prev & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
// Generate a random float in [0, 1) given the previous RNG state
|
||||
float rnd(inout uint prev)
|
||||
{
|
||||
return (float(lcg(prev)) / float(0x01000000));
|
||||
}
|
||||
~~~~
|
||||
|
||||
## Frame Number
|
||||
|
||||
Since our jittered samples will be accumulated across frames, we need to know which frame we are currently rendering. A frame number of 0 will indicate a new frame, and we will accumulate the data for larger frame numbers.
|
||||
|
||||
Note that the uniform image is read/write, which makes it possible to accumulate previous frames.
|
||||
|
||||
In `raytrace.rgen`, add the push constant block from `raytrace.rchit`, adding a new `frame` member:
|
||||
|
||||
~~~~ C++
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame;
|
||||
}
|
||||
pushC;
|
||||
~~~~
|
||||
|
||||
Also add this frame member to the `RtPushConstant` struct in `hello_vulkan.h`:
|
||||
|
||||
~~~~ C++
|
||||
struct RtPushConstant
|
||||
{
|
||||
nvmath::vec4f clearColor;
|
||||
nvmath::vec3f lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int frame{0};
|
||||
} m_rtPushConstants;
|
||||
~~~~
|
||||
|
||||
## Random and Jitter
|
||||
|
||||
In `raytrace.rgen`, at the beginning of `main()`, initialize the random seed:
|
||||
|
||||
~~~~ C++
|
||||
// Initialize the random number
|
||||
uint seed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame);
|
||||
~~~~
|
||||
|
||||
Then we need two random numbers to vary the X and Y inside the pixel, except for frame 0, where we always shoot
|
||||
in the center.
|
||||
|
||||
~~~~ C++
|
||||
float r1 = rnd(seed);
|
||||
float r2 = rnd(seed);
|
||||
// Subpixel jitter: send the ray through a different position inside the pixel
|
||||
// each time, to provide antialiasing.
|
||||
vec2 subpixel_jitter = pushC.frame == 0 ? vec2(0.5f, 0.5f) : vec2(r1, r2);
|
||||
~~~~
|
||||
|
||||
Now we only need to change how we compute the pixel center:
|
||||
|
||||
~~~~ C++
|
||||
const vec2 pixelCenter = vec2(gl_LaunchIDEXT.xy) + subpixel_jitter;
|
||||
~~~~
|
||||
|
||||
## Storing or Updating
|
||||
|
||||
At the end of `main()`, if the frame number is equal to 0, we write directly to the image.
|
||||
Otherwise, we combine the new image with the previous `frame` frames.
|
||||
|
||||
~~~~ C++
|
||||
// Do accumulation over time
|
||||
if(pushC.frame > 0)
|
||||
{
|
||||
float a = 1.0f / float(pushC.frame + 1);
|
||||
vec3 old_color = imageLoad(image, ivec2(gl_LaunchIDEXT.xy)).xyz;
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(mix(old_color, prd.hitValue, a), 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
// First frame, replace the value in the buffer
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(prd.hitValue, 1.f));
|
||||
}
|
||||
~~~~
|
||||
|
||||
# Application Frame Update
|
||||
|
||||
We need to increment the current rendering frame, but we also need to reset it when something in the
|
||||
scene is changing.
|
||||
|
||||
Add two new functions to the `HelloVulkan` class:
|
||||
|
||||
~~~~ C++
|
||||
void resetFrame();
|
||||
void updateFrame();
|
||||
~~~~
|
||||
|
||||
The implementation of `updateFrame` resets the frame counter if the camera has changed; otherwise, it increments the frame counter.
|
||||
|
||||
~~~~ C++
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// If the camera matrix has changed, resets the frame.
|
||||
// otherwise, increments frame.
|
||||
//
|
||||
void HelloVulkan::updateFrame()
|
||||
{
|
||||
static nvmath::mat4f refCamMatrix;
|
||||
|
||||
auto& m = CameraManip.getMatrix();
|
||||
if(memcmp(&refCamMatrix.a00, &m.a00, sizeof(nvmath::mat4f)) != 0)
|
||||
{
|
||||
resetFrame();
|
||||
refCamMatrix = m;
|
||||
}
|
||||
m_rtPushConstants.frame++;
|
||||
}
|
||||
~~~~
|
||||
|
||||
Since `resetFrame` will be called before `updateFrame` increments the frame counter, `resetFrame` will set the frame counter to -1:
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::resetFrame()
|
||||
{
|
||||
m_rtPushConstants.frame = -1;
|
||||
}
|
||||
~~~~
|
||||
|
||||
At the begining of `HelloVulkan::raytrace`, call
|
||||
|
||||
~~~~ C++
|
||||
updateFrame();
|
||||
~~~~
|
||||
|
||||
The application will now antialias the image when ray tracing is enabled.
|
||||
|
||||
Adding `resetFrame()` in `HelloVulkan::onResize()` will also take care of clearing the buffer while resizing the window.
|
||||
|
||||
|
||||
|
||||
## Resetting Frame on UI Change
|
||||
|
||||
The frame number should also be reset when any parts of the scene change, such as the light direction or the background color. In `renderUI()` in `main.cpp`, check for UI changes and reset the frame number when they happen:
|
||||
|
||||
~~~~ C++
|
||||
void renderUI(HelloVulkan& helloVk)
|
||||
{
|
||||
static int item = 1;
|
||||
bool changed = false;
|
||||
if(ImGui::Combo("Up Vector", &item, "X\0Y\0Z\0\0"))
|
||||
{
|
||||
nvmath::vec3f pos, eye, up;
|
||||
CameraManip.getLookat(pos, eye, up);
|
||||
up = nvmath::vec3f(item == 0, item == 1, item == 2);
|
||||
CameraManip.setLookat(pos, eye, up);
|
||||
changed = true;
|
||||
}
|
||||
changed |=
|
||||
ImGui::SliderFloat3("Light Position", &helloVk.m_pushConstant.lightPosition.x, -20.f, 20.f);
|
||||
changed |=
|
||||
ImGui::SliderFloat("Light Intensity", &helloVk.m_pushConstant.lightIntensity, 0.f, 100.f);
|
||||
changed |= ImGui::RadioButton("Point", &helloVk.m_pushConstant.lightType, 0);
|
||||
ImGui::SameLine();
|
||||
changed |= ImGui::RadioButton("Infinite", &helloVk.m_pushConstant.lightType, 1);
|
||||
if(changed)
|
||||
helloVk.resetFrame();
|
||||
}
|
||||
~~~~
|
||||
|
||||
We also need to check for UI changes inside the main loop inside `main()`:
|
||||
|
||||
~~~~ C++
|
||||
bool changed = false;
|
||||
// Edit 3 floats representing a color
|
||||
changed |= ImGui::ColorEdit3("Clear color", reinterpret_cast<float*>(&clearColor));
|
||||
// Switch between raster and ray tracing
|
||||
changed |= ImGui::Checkbox("Ray Tracer mode", &useRaytracer);
|
||||
if(changed)
|
||||
helloVk.resetFrame();
|
||||
~~~~
|
||||
|
||||
# Quality
|
||||
|
||||
After enough samples, the quality of the rendering will be sufficiently high that it might make sense to avoid accumulating further images.
|
||||
|
||||
Add a member variable to `HelloVulkan`
|
||||
|
||||
~~~~ C++
|
||||
int m_maxFrames{100};
|
||||
~~~~
|
||||
|
||||
and also add a way to control it in `renderUI()`, making sure that `m_maxFrames` cannot be set below 1:
|
||||
|
||||
~~~~ C++
|
||||
changed |= ImGui::InputInt("Max Frames", &helloVk.m_maxFrames);
|
||||
helloVk.m_maxFrames = std::max(helloVk.m_maxFrames, 1);
|
||||
~~~~
|
||||
|
||||
Then in `raytrace()`, immediately after the call to `updateFrame()`, return if the current frame has exceeded the max frame.
|
||||
|
||||
~~~~ C++
|
||||
if(m_rtPushConstants.frame >= m_maxFrames)
|
||||
return;
|
||||
~~~~
|
||||
|
||||
Since the output image won't be modified by the ray tracer, we will simply display the last good image, reducing GPU usage when the target quality has been reached.
|
||||
|
||||
# More Samples in RayGen
|
||||
|
||||
To improve efficiency, we can perform multiple samples directly in the ray generation shader. This will be faster than calling `raytrace()` the equivalent number of times.
|
||||
|
||||
To do this, add a constant to `raytrace.rgen` (this could alternatively be added to the push constant block and controlled by the application):
|
||||
|
||||
~~~~ C++
|
||||
const int NBSAMPLES = 10;
|
||||
~~~~
|
||||
|
||||
In `main()`, after initializing the random number seed, create a loop that encloses the lines from the generation of `r1` and `r2` to the `traceRayEXT` call, and accumulates the colors returned by `traceRayEXT`. At the end of the loop, divide by the number of samples that were taken.
|
||||
|
||||
~~~~ C++
|
||||
vec3 hitValues = vec3(0);
|
||||
|
||||
for(int smpl = 0; smpl < NBSAMPLES; smpl++)
|
||||
{
|
||||
float r1 = rnd(seed);
|
||||
float r2 = rnd(seed);
|
||||
// ...
|
||||
// TraceRayEXT( ... );
|
||||
hitValues += prd.hitValue;
|
||||
}
|
||||
prd.hitValue = hitValues / NBSAMPLES;
|
||||
~~~~
|
||||
|
||||
For a given value of `m_maxFrames` and `NBSAMPLE`, the image this converges to will have `m_maxFrames * NBSAMPLE` antialiasing samples. For instance, if `m_maxFrames = 10` and `NBSAMPLE = 10`, this will be equivalent in quality to an image using `m_maxFrames = 100` and `NBSAMPLE = 1`. However, using `NBSAMPLE=10` in the ray generation shader will be faster than calling `raytrace()` with `NBSAMPLE=1` 10 times in a row.
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_jitter_cam](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_jitter_cam)
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,360 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Multiple Closest Hit Shaders**
|
||||
|
||||

|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
The ray tracing tutorial only uses one closest hit shader, but it is also possible to have multiple closest hit shaders.
|
||||
For example, this could be used to give different models different shaders, or to use a less complex shader when tracing
|
||||
reflections.
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
# Setting up the Scene
|
||||
|
||||
For this example, we will load the `wuson` model and create another translated instance of it.
|
||||
|
||||
Then you can change the `helloVk.loadModel` calls to the following:
|
||||
|
||||
~~~~ C++
|
||||
// Creation of the example
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/wuson.obj", defaultSearchPaths),
|
||||
nvmath::translation_mat4(nvmath::vec3f(-1, 0, 0)));
|
||||
HelloVulkan::ObjInstance inst;
|
||||
inst.objIndex = 0;
|
||||
inst.transform = nvmath::translation_mat4(nvmath::vec3f(1, 0, 0));
|
||||
inst.transformIT = nvmath::transpose(nvmath::invert(inst.transform));
|
||||
helloVk.m_objInstance.push_back(inst);
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths));
|
||||
~~~~
|
||||
|
||||
# Adding a new Closest Hit Shader
|
||||
|
||||
We will need to create a new closest hit shader (CHIT), to add it to the raytracing pipeline, and to indicate which instance will use this shader.
|
||||
|
||||
## `raytrace2.rchit`
|
||||
|
||||
We can make a very simple shader to differentiate this closest hit shader from the other one.
|
||||
As an example, create a new file called `raytrace2.rchit`, and add it to Visual Studio's `shaders` filter with the other shaders.
|
||||
|
||||
~~~~ C++
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "raycommon.glsl"
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload prd;
|
||||
|
||||
void main()
|
||||
{
|
||||
prd.hitValue = vec3(1,0,0);
|
||||
}
|
||||
~~~~
|
||||
|
||||
## `createRtPipeline`
|
||||
|
||||
This new shader needs to be added to the raytracing pipeline. So, in `createRtPipeline` in `hello_vulkan.cpp`, load the new closest hit shader immediately after loading the first one.
|
||||
|
||||
~~~~ C++
|
||||
vk::ShaderModule chit2SM =
|
||||
nvvk::createShaderModule(m_device, //
|
||||
nvh::loadFile("shaders/raytrace2.rchit.spv", true, paths));
|
||||
~~~~
|
||||
|
||||
Then add a new hit group group immediately after adding the first hit group:
|
||||
|
||||
~~~~ C++
|
||||
// Second group
|
||||
hg.setClosestHitShader(static_cast<uint32_t>(stages.size()));
|
||||
stages.push_back({{}, vk::ShaderStageFlagBits::eClosestHitKHR, chit2SM, "main"});
|
||||
m_rtShaderGroups.push_back(hg);
|
||||
~~~~
|
||||
|
||||
## `raytrace.rgen`
|
||||
|
||||
As a test, you can try changing the `sbtRecordOffset` parameter of the `traceRayEXT` call in `raytrace.rgen`.
|
||||
If you set the offset to `1`, then all ray hits will use the new CHIT, and the raytraced output should look like the image below:
|
||||
|
||||

|
||||
|
||||
!!! Warning
|
||||
After testing this out, make sure to revert this change in `raytrace.rgen` before continuing.
|
||||
|
||||
## `hello_vulkan.h`
|
||||
|
||||
In the `ObjInstance` structure, we will add a new member variable that specifies which hit shader the instance will use:
|
||||
|
||||
~~~~ C++
|
||||
uint32_t hitgroup{0}; // Hit group of the instance
|
||||
~~~~
|
||||
|
||||
This change also needs to be reflected in the `sceneDesc` structure in `wavefront.glsl`:
|
||||
|
||||
~~~~ C++
|
||||
struct sceneDesc
|
||||
{
|
||||
int objId;
|
||||
int txtOffset;
|
||||
mat4 transfo;
|
||||
mat4 transfoIT;
|
||||
int hitGroup;
|
||||
};
|
||||
~~~~
|
||||
|
||||
!!! Warning:
|
||||
The solution will not automatically recompile the shaders after this change to `wavefront.glsl`; instead, you will need to recompile all of the SPIR-V shaders.
|
||||
|
||||
## `hello_vulkan.cpp`
|
||||
|
||||
Finally, we need to tell the top-level acceleration structure which hit group to use for each instance. In `createTopLevelAS()` in `hello_vulkan.cpp`, change the line setting `rayInst.hitGroupId` to
|
||||
|
||||
~~~~ C++
|
||||
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
||||
~~~~
|
||||
|
||||
## Choosing the Hit shader
|
||||
|
||||
Back in `main.cpp`, after loading the scene's models, we can now have both `wuson` models use the new CHIT by adding the following:
|
||||
|
||||
~~~~ C++
|
||||
helloVk.m_objInstance[0].hitgroup = 1;
|
||||
helloVk.m_objInstance[1].hitgroup = 1;
|
||||
~~~~
|
||||
|
||||

|
||||
|
||||
# Shader Record Data `shaderRecordKHR`
|
||||
|
||||
When creating the [Shader Binding Table](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap33.html#shader-binding-table), see previous, each entry in the table consists of a handle referring to the shader that it invokes. We have packed all data to the size of `shaderGroupHandleSize`, but each entry could be made larger, to store data that can later be referenced by a `shaderRecordKHR` block in the shader.
|
||||
|
||||
This information can be used to pass extra information to a shader, for each entry in the SBT.
|
||||
|
||||
!!! Note: Note
|
||||
Since each entry in an SBT group must have the same size, each entry of the group has to have enough space to accommodate the largest element in the entire group.
|
||||
|
||||
The following diagram represents our current SBT, with the addition of some data to `HitGroup1`. As mentioned in the **note**, even if
|
||||
`HitGroup0` doesn't have any shader record data, it still needs to have the same size as `HitGroup1`.
|
||||
|
||||
**************************
|
||||
*+-----------+----------+*
|
||||
*| RayGen | Handle 0 |*
|
||||
*+-----------+----------+*
|
||||
*| Miss | Handle 1 |*
|
||||
*+-----------+----------+*
|
||||
*| Miss | Handle 2 |*
|
||||
*+-----------+----------+*
|
||||
*| HitGroup0 | Handle 3 |*
|
||||
*| | -Empty- |*
|
||||
*+-----------+----------+*
|
||||
*| HitGroup1 | Handle 4 |*
|
||||
*| | Data 0 |*
|
||||
*+-----------+----------+*
|
||||
**************************
|
||||
|
||||
## `hello_vulkan.h`
|
||||
|
||||
In the HelloVulkan class, we will add a structure to hold the hit group data.
|
||||
|
||||
<script type="preformatted">
|
||||
~~~~ C++
|
||||
struct HitRecordBuffer
|
||||
{
|
||||
nvmath::vec4f color;
|
||||
};
|
||||
std::vector<HitRecordBuffer> m_hitShaderRecord;
|
||||
~~~~
|
||||
</script>
|
||||
|
||||
## `raytrace2.rchit`
|
||||
|
||||
In the closest hit shader, we can retrieve the shader record using the `layout(shaderRecordEXT)` descriptor
|
||||
|
||||
~~~~ C++
|
||||
layout(shaderRecordEXT) buffer sr_ { vec4 c; } shaderRec;
|
||||
~~~~
|
||||
|
||||
and use this information to return the color:
|
||||
|
||||
~~~~ C++
|
||||
void main()
|
||||
{
|
||||
prd.hitValue = shaderRec.c.rgb;
|
||||
}
|
||||
~~~~
|
||||
|
||||
!!! Note
|
||||
Adding a new shader requires to rerun CMake to added to the project compilation system.
|
||||
|
||||
|
||||
## `main.cpp`
|
||||
|
||||
In `main`, after we set which hit group an instance will use, we can add the data we want to set through the shader record.
|
||||
|
||||
~~~~ C++
|
||||
helloVk.m_hitShaderRecord.resize(1);
|
||||
helloVk.m_hitShaderRecord[0].color = nvmath::vec4f(1, 1, 0, 0); // Yellow
|
||||
~~~~
|
||||
|
||||
## `HelloVulkan::createRtShaderBindingTable`
|
||||
|
||||
Since we are no longer compacting all handles in a continuous buffer, we need to fill the SBT as described above.
|
||||
|
||||
After retrieving the handles of all 5 groups (raygen, miss, miss shadow, hit0, and hit1)
|
||||
using `getRayTracingShaderGroupHandlesKHR`, store the pointers to easily retrieve them.
|
||||
|
||||
~~~~ C++
|
||||
// Retrieve the handle pointers
|
||||
std::vector<uint8_t*> handles(groupCount);
|
||||
for(uint32_t i = 0; i < groupCount; i++)
|
||||
{
|
||||
handles[i] = &shaderHandleStorage[i * groupHandleSize];
|
||||
}
|
||||
~~~~
|
||||
|
||||
The size of each group can be described as follows:
|
||||
|
||||
~~~~ C++
|
||||
// Sizes
|
||||
uint32_t rayGenSize = groupSizeAligned;
|
||||
uint32_t missSize = groupSizeAligned;
|
||||
uint32_t hitSize =
|
||||
nvh::align_up(groupHandleSize + static_cast<int>(sizeof(HitRecordBuffer)), groupSizeAligned);
|
||||
uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize;
|
||||
~~~~
|
||||
|
||||
Then write the new SBT like this, where only Hit 1 has extra data.
|
||||
|
||||
~~~~ C++
|
||||
std::vector<uint8_t> sbtBuffer(newSbtSize);
|
||||
{
|
||||
uint8_t* pBuffer = sbtBuffer.data();
|
||||
|
||||
memcpy(pBuffer, handles[0], groupHandleSize); // Raygen
|
||||
pBuffer += rayGenSize;
|
||||
memcpy(pBuffer, handles[1], groupHandleSize); // Miss 0
|
||||
pBuffer += missSize;
|
||||
memcpy(pBuffer, handles[2], groupHandleSize); // Miss 1
|
||||
pBuffer += missSize;
|
||||
|
||||
uint8_t* pHitBuffer = pBuffer;
|
||||
memcpy(pHitBuffer, handles[3], groupHandleSize); // Hit 0
|
||||
// No data
|
||||
pBuffer += hitSize;
|
||||
|
||||
pHitBuffer = pBuffer;
|
||||
memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 1
|
||||
pHitBuffer += groupHandleSize;
|
||||
memcpy(pHitBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data
|
||||
pBuffer += hitSize;
|
||||
}
|
||||
~~~~
|
||||
|
||||
Then change the call to `m_alloc.createBuffer` to create the SBT buffer from `sbtBuffer`:
|
||||
|
||||
~~~~ C++
|
||||
m_rtSBTBuffer = m_alloc.createBuffer(cmdBuf, sbtBuffer, vk::BufferUsageFlagBits::eRayTracingKHR);
|
||||
~~~~
|
||||
|
||||
|
||||
## `raytrace`
|
||||
|
||||
Finally, since the size of the hit group is now larger than just the handle,
|
||||
we need to set the new value of the hit group stride in `HelloVulkan::raytrace`.
|
||||
|
||||
~~~~ C++
|
||||
vk::DeviceSize hitGroupSize =
|
||||
nvh::align_up(m_rtProperties.shaderGroupHandleSize + sizeof(HitRecordBuffer),
|
||||
m_rtProperties.shaderGroupBaseAlignment);
|
||||
|
||||
|
||||
std::array<Stride, 4> strideAddresses{
|
||||
Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
||||
Stride{sbtAddress + 1u * groupSize, groupStride, groupSize * 2}, // miss
|
||||
Stride{sbtAddress + 3u * groupSize, hitGroupSize, hitGroupSize * 3}, // hit
|
||||
Stride{0u, 0u, 0u}}; // callable
|
||||
~~~~
|
||||
|
||||
!!! Note:
|
||||
The result should now show both `wuson` models with a yellow color.
|
||||
|
||||

|
||||
|
||||
# Extending Hit
|
||||
|
||||
The SBT can be larger than the number of shading models, which could then be used to have one shader per instance with its own data.
|
||||
For some applications, instead of retrieving the material information as in the main tutorial using a storage buffer and indexing
|
||||
into it using the `gl_InstanceCustomIndexEXT`, it is possible to set all of the material information in the SBT.
|
||||
|
||||
The following modification will add another entry to the SBT with a different color per instance. The new SBT hit group (2) will use the same CHIT handle (4) as hit group 1.
|
||||
|
||||
**************************
|
||||
*+-----------+----------+*
|
||||
*| RayGen | Handle 0 |*
|
||||
*+-----------+----------+*
|
||||
*| Miss | Handle 1 |*
|
||||
*+-----------+----------+*
|
||||
*| Miss | Handle 2 |*
|
||||
*+-----------+----------+*
|
||||
*| HitGroup0 | Handle 3 |*
|
||||
*| | -Empty- |*
|
||||
*+-----------+----------+*
|
||||
*| HitGroup1 | Handle 4 |*
|
||||
*| | Data 0 |*
|
||||
*+-----------+----------+*
|
||||
*| HitGroup2 | Handle 4 |*
|
||||
*| | Data 1 |*
|
||||
*+-----------+----------+*
|
||||
**************************
|
||||
|
||||
## `main.cpp`
|
||||
|
||||
In the description of the scene in `main`, we will tell the `wuson` models to use hit groups 1 and 2 respectively, and to have different colors.
|
||||
|
||||
~~~~ C++
|
||||
helloVk.m_objInstance[0].hitgroup = 1;
|
||||
helloVk.m_objInstance[1].hitgroup = 2;
|
||||
helloVk.m_hitShaderRecord.resize(2);
|
||||
helloVk.m_hitShaderRecord[0].color = nvmath::vec4f(0, 1, 0, 0); // Green
|
||||
helloVk.m_hitShaderRecord[1].color = nvmath::vec4f(0, 1, 1, 0); // Cyan
|
||||
~~~~
|
||||
|
||||
## `createRtShaderBindingTable`
|
||||
|
||||
The size of the SBT will now account for its 3 hit groups:
|
||||
|
||||
~~~~ C++
|
||||
uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize;
|
||||
~~~~
|
||||
|
||||
Finally, we need to add the new entry as well at the end of the buffer, reusing the handle of the second Hit Group and setting a different color.
|
||||
|
||||
~~~~ C++
|
||||
pHitBuffer = pBuffer;
|
||||
memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 2
|
||||
pHitBuffer += groupHandleSize;
|
||||
memcpy(pHitBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data
|
||||
pBuffer += hitSize;
|
||||
~~~~
|
||||
|
||||
!!! Warning
|
||||
Adding entries like this can be error-prone and inconvenient for decent
|
||||
scene sizes. Instead, it is recommended to wrap the storage of handles, data,
|
||||
and size per group in a SBT utility to handle this automatically.
|
||||
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_manyhits](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_manyhits)
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Ray Query**
|
||||
|
||||
|
||||

|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
# Ray Query
|
||||
|
||||
This extension is allowing to execute ray intersection queries in any shader stages. In this example, we will add
|
||||
ray queries [(GLSL_EXT_ray_query)](https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GLSL_EXT_ray_query.txt) to the fragment shader to cast shadow rays.
|
||||
|
||||
In the contrary to all other examples, with this one, we are removing code. There are no need to have a SBT and a raytracing pipeline, the only thing that
|
||||
will matter, is the creation of the acceleration structure.
|
||||
|
||||
Starting from the end of the tutorial, [ray_tracing__simple](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing__simple) we will remove
|
||||
all functions that were dedicated to ray tracing and keep only the construction of the BLAS and TLAS.
|
||||
|
||||
# Cleanup
|
||||
|
||||
First, let's remove all extra code
|
||||
|
||||
## hello_vulkan (header)
|
||||
|
||||
Remove most functions and members to keep only what is need to create the acceleration structure:
|
||||
|
||||
~~~~ C++
|
||||
// #VKRay
|
||||
void initRayTracing();
|
||||
nvvk::RaytracingBuilderKHR::Blas objectToVkGeometryKHR(const ObjModel& model);
|
||||
void createBottomLevelAS();
|
||||
void createTopLevelAS();
|
||||
|
||||
vk::PhysicalDeviceRayTracingPropertiesKHR m_rtProperties;
|
||||
nvvk::RaytracingBuilderKHR m_rtBuilder;
|
||||
~~~~
|
||||
|
||||
## hello_vulkan (source)
|
||||
|
||||
From the source code, remove the code for all functions that was previously removed.
|
||||
|
||||
## Shaders
|
||||
|
||||
You can safely remove all raytrace.* shaders
|
||||
|
||||
|
||||
# Support for Fragment shader
|
||||
|
||||
In `HelloVulkan::createDescriptorSetLayout`, add the acceleration structure to the description layout.
|
||||
|
||||
~~~~ C++
|
||||
// The top level acceleration structure
|
||||
m_descSetLayoutBind.emplace_back( //
|
||||
vkDS(7, vkDT::eAccelerationStructureKHR, 1, vkSS::eFragment));
|
||||
~~~~
|
||||
|
||||
In `HelloVulkan::updateDescriptorSet`, write the value to the descriptor set.
|
||||
|
||||
~~~~ C++
|
||||
vk::AccelerationStructureKHR tlas = m_rtBuilder.getAccelerationStructure();
|
||||
vk::WriteDescriptorSetAccelerationStructureKHR descASInfo;
|
||||
descASInfo.setAccelerationStructureCount(1);
|
||||
descASInfo.setPAccelerationStructures(&tlas);
|
||||
writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, descASInfo));
|
||||
~~~~
|
||||
|
||||
|
||||
## Shader
|
||||
|
||||
The last modification is in the fragment shader, where we will add the ray intersection query to trace shadow rays.
|
||||
|
||||
First, the version has bumpped to 460
|
||||
|
||||
~~~~ C++
|
||||
#version 460
|
||||
~~~~
|
||||
|
||||
Then we need to add new extensions
|
||||
|
||||
~~~~ C++
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_ray_query : enable
|
||||
~~~~
|
||||
|
||||
We have to add the layout to access the top level acceleration structure.
|
||||
|
||||
~~~~ C++
|
||||
layout(binding = 7, set = 0) uniform accelerationStructureEXT topLevelAS;
|
||||
~~~~
|
||||
|
||||
|
||||
Ad the end of the shader, add the following code to initiate the ray query. As we are only interested to know if the ray
|
||||
has hit something, we can keep the minimal.
|
||||
|
||||
~~~~ C++
|
||||
// Ray Query for shadow
|
||||
vec3 origin = worldPos;
|
||||
vec3 direction = L; // vector to light
|
||||
float tMin = 0.01f;
|
||||
float tMax = lightDistance;
|
||||
|
||||
// Initializes a ray query object but does not start traversal
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, tMin,
|
||||
direction, tMax);
|
||||
|
||||
// Start traversal: return false if traversal is complete
|
||||
while(rayQueryProceedEXT(rayQuery))
|
||||
{
|
||||
}
|
||||
|
||||
// Returns type of committed (true) intersection
|
||||
if(rayQueryGetIntersectionTypeEXT(rayQuery, true) != gl_RayQueryCommittedIntersectionNoneEXT)
|
||||
{
|
||||
// Got an intersection == Shadow
|
||||
outColor *= 0.1;
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_rayquery](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_rayquery)
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
<meta charset="utf-8" lang="en">
|
||||
**NVIDIA Vulkan Ray Tracing Tutorial**
|
||||
**Reflections**
|
||||
|
||||
|
||||

|
||||
|
||||
This is an extension of the Vulkan ray tracing [tutorial](vkrt_tutorial.md.html).
|
||||
|
||||
(insert setup.md.html here)
|
||||
|
||||
# Setting Up the scene
|
||||
|
||||
First, we will create a scene with two reflective planes and a multicolored cube in the center. Change the `helloVk.loadModel` calls in `main()` to
|
||||
|
||||
~~~~ C++
|
||||
// Creation of the example
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/cube.obj", defaultSearchPaths),
|
||||
nvmath::translation_mat4(nvmath::vec3f(-2, 0, 0))
|
||||
* nvmath::scale_mat4(nvmath::vec3f(.1f, 5.f, 5.f)));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/cube.obj", defaultSearchPaths),
|
||||
nvmath::translation_mat4(nvmath::vec3f(2, 0, 0))
|
||||
* nvmath::scale_mat4(nvmath::vec3f(.1f, 5.f, 5.f)));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/cube_multi.obj", defaultSearchPaths));
|
||||
helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths),
|
||||
nvmath::translation_mat4(nvmath::vec3f(0, -1, 0)));
|
||||
~~~~
|
||||
|
||||
Then find `cube.mtl` in `media/scenes` and modify the material to be 95% reflective, without any diffuse
|
||||
contribution:
|
||||
|
||||
~~~~ C++
|
||||
newmtl cube_instance_material
|
||||
illum 3
|
||||
d 1
|
||||
Ns 32
|
||||
Ni 0
|
||||
Ka 0 0 0
|
||||
Kd 0 0 0
|
||||
Ks 0.95 0.95 0.95
|
||||
~~~~
|
||||
|
||||
# Recursive Reflections
|
||||
|
||||
Vulkan ray tracing allows recursive calls to traceRayEXT, up to a limit defined by `VkPhysicalDeviceRayTracingPropertiesKHR`.
|
||||
|
||||
In `createRtPipeline()` in `hello_vulkan.cpp`, bring the maximum recursion depth up to 10, making sure not to exceed the physical device's maximum recursion limit:
|
||||
|
||||
~~~~ C++
|
||||
rayPipelineInfo.setMaxRecursionDepth(
|
||||
std::max(10u, m_rtProperties.maxRecursionDepth)); // Ray depth
|
||||
~~~~
|
||||
|
||||
## `raycommon.glsl`
|
||||
|
||||
We will need to track the depth and the attenuation of the ray.
|
||||
In the `hitPayload` struct in `raycommon.glsl`, add the following:
|
||||
|
||||
~~~~ C++
|
||||
int depth;
|
||||
vec3 attenuation;
|
||||
~~~~
|
||||
|
||||
## `raytrace.rgen`
|
||||
|
||||
In the ray generation shader, we will initialize all payload values before calling `traceRayEXT`.
|
||||
|
||||
~~~~ C++
|
||||
prd.depth = 0;
|
||||
prd.hitValue = vec3(0);
|
||||
prd.attenuation = vec3(1.f, 1.f, 1.f);
|
||||
~~~~
|
||||
|
||||
## `raytrace.rchit`
|
||||
|
||||
At the end of the closest hit shader, before setting `prd.hitValue`, we need to shoot a ray if the material is reflective.
|
||||
|
||||
~~~~ C++
|
||||
// Reflection
|
||||
if(mat.illum == 3 && prd.depth < 10)
|
||||
{
|
||||
vec3 origin = worldPos;
|
||||
vec3 rayDir = reflect(gl_WorldRayDirectionEXT, normal);
|
||||
prd.attenuation *= mat.specular;
|
||||
|
||||
prd.depth++;
|
||||
traceRayEXT(topLevelAS, // acceleration structure
|
||||
gl_RayFlagsNoneEXT, // rayFlags
|
||||
0xFF, // cullMask
|
||||
0, // sbtRecordOffset
|
||||
0, // sbtRecordStride
|
||||
0, // missIndex
|
||||
origin, // ray origin
|
||||
0.1, // ray min range
|
||||
rayDir, // ray direction
|
||||
100000.0, // ray max range
|
||||
0 // payload (location = 0)
|
||||
);
|
||||
prd.depth--;
|
||||
}
|
||||
~~~~
|
||||
|
||||
The calculated `hitValue` needs to be accumulated, since the payload is global for the
|
||||
entire execution from raygen, so change the last line of `main()` to
|
||||
|
||||
~~~~ C++
|
||||
prd.hitValue += vec3(attenuation * lightIntensity * (diffuse + specular)) * prd.attenuation;
|
||||
~~~~
|
||||
|
||||
## `raytrace.rmiss`
|
||||
|
||||
Finally, the miss shader also needs to attenuate its contribution:
|
||||
|
||||
~~~~ C++
|
||||
prd.hitValue = clearColor.xyz * 0.8 * prd.attenuation;
|
||||
~~~~
|
||||
|
||||
## Working, but limited
|
||||
|
||||
This is working, but it is limited to the number of recursions the GPU can do, and could also impact performance. Trying to go over the limit of recursions would eventually generate a device lost error.
|
||||
|
||||
# Iterative Reflections
|
||||
|
||||
Instead of dispatching new rays from the closest hit shader, we will return the information in the payload to shoot new rays if needed.
|
||||
|
||||
## 'raycommon.glsl'
|
||||
|
||||
Enhance the structure to add information to start new rays if wanted.
|
||||
|
||||
~~~~ C++
|
||||
int done;
|
||||
vec3 rayOrigin;
|
||||
vec3 rayDir;
|
||||
~~~~
|
||||
|
||||
## `raytrace.rgen`
|
||||
|
||||
Initialize the new members of the payload:
|
||||
|
||||
~~~~ C++
|
||||
prd.done = 1;
|
||||
prd.rayOrigin = origin.xyz;
|
||||
prd.rayDir = direction.xyz;
|
||||
~~~~
|
||||
|
||||
Instead of calling traceRayEXT only once, we will call it in a loop until we are done.
|
||||
|
||||
Wrap the trace call in `raytrace.rgen` like this:
|
||||
|
||||
~~~~ C++
|
||||
vec3 hitValue = vec3(0);
|
||||
for(;;)
|
||||
{
|
||||
traceRayEXT( /*.. */);
|
||||
|
||||
hitValue += prd.hitValue * prd.attenuation;
|
||||
|
||||
prd.depth++;
|
||||
if(prd.done == 1 || prd.depth >= 10)
|
||||
break;
|
||||
|
||||
origin.xyz = prd.rayOrigin;
|
||||
direction.xyz = prd.rayDir;
|
||||
prd.done = 1; // Will stop if a reflective material isn't hit
|
||||
}
|
||||
~~~~
|
||||
|
||||
And make sure to write the correct value
|
||||
|
||||
~~~~ C++
|
||||
imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(hitValue, 1.0));
|
||||
~~~~
|
||||
|
||||
## `raytrace.rchit`
|
||||
|
||||
We no longer need to shoot rays from the closest hit shader, so we can replace the block at the end with
|
||||
|
||||
~~~~ C++
|
||||
if(mat.illum == 3)
|
||||
{
|
||||
vec3 origin = worldPos;
|
||||
vec3 rayDir = reflect(gl_WorldRayDirectionEXT, normal);
|
||||
prd.attenuation *= mat.specular;
|
||||
prd.done = 0;
|
||||
prd.rayOrigin = origin;
|
||||
prd.rayDir = rayDir;
|
||||
}
|
||||
~~~~
|
||||
|
||||
The calculation of the hitValue also no longer needs to be additive, or take attenuation into account:
|
||||
|
||||
~~~~ C++
|
||||
prd.hitValue = vec3(attenuation * lightIntensity * (diffuse + specular));
|
||||
~~~~
|
||||
|
||||
## `raytrace.rmiss`
|
||||
|
||||
Since the ray generation shader now handles attenuation, we no longer need to attenuate the value returned in the miss shader:
|
||||
|
||||
~~~~ C++
|
||||
prd.hitValue = clearColor.xyz * 0.8;
|
||||
~~~~
|
||||
|
||||
## Max Recursion
|
||||
|
||||
Finally, we no longer need to have a deep recursion setting in `createRtPipeline` -- just a depth of 2, one for the initial ray generation segment and another for shadow rays.
|
||||
|
||||
~~~~ C++
|
||||
rayPipelineInfo.setMaxRecursionDepth(2); // Ray depth
|
||||
~~~~
|
||||
|
||||
In `raytrace.rgen`, we can now make the maximum ray depth significantly larger -- such as 100, for instance -- without causing a device lost error.
|
||||
|
||||
# Controlling Depth
|
||||
|
||||
As an extra, we can also add UI to control the maximum depth.
|
||||
|
||||
In the `RtPushConstant` structure, we can add a new `maxDepth` member to pass to the shader.
|
||||
|
||||
~~~~ C++
|
||||
struct RtPushConstant
|
||||
{
|
||||
nvmath::vec4f clearColor;
|
||||
nvmath::vec3f lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int maxDepth{10};
|
||||
} m_rtPushConstants;
|
||||
~~~~
|
||||
|
||||
In the `raytrace.rgen` shader, we will collect the push constant data
|
||||
|
||||
~~~~ C++
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 clearColor;
|
||||
vec3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
int maxDepth;
|
||||
}
|
||||
pushC;
|
||||
~~~~
|
||||
|
||||
Then test for the value for when to stop
|
||||
|
||||
~~~~ C++
|
||||
if(prd.done == 1 || prd.depth >= pushC.maxDepth)
|
||||
break;
|
||||
~~~~
|
||||
|
||||
Finally, in `main.cpp` in the `renderUI` function, we will add a slider to control the value.
|
||||
|
||||
~~~~ C++
|
||||
ImGui::SliderInt("Max Depth", &helloVk.m_rtPushConstants.maxDepth, 1, 100);
|
||||
~~~~
|
||||
|
||||
# Final Code
|
||||
|
||||
You can find the final code in the folder [ray_tracing_reflections](https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR/tree/master/ray_tracing_reflections)
|
||||
|
||||
|
||||
<!-- Markdeep: -->
|
||||
<link rel="stylesheet" href="vkrt_tutorial.css?">
|
||||
<script> window.markdeepOptions = { tocStyle: "medium" };</script>
|
||||
<script src="markdeep.min.js" charset="utf-8"></script>
|
||||
<script src="https://developer.nvidia.com/sites/default/files/akamai/gameworks/whitepapers/markdeep.min.js" charset="utf-8"></script>
|
||||
<script>
|
||||
window.alreadyProcessedMarkdeep || (document.body.style.visibility = "visible")
|
||||
</script>
|
||||
|
|
@ -21,7 +21,7 @@ methods and functions. The sections are organized by components, with subsection
|
|||
<script type="preformatted">
|
||||
This tutorial highlights the steps to add ray tracing to an existing Vulkan application, and assumes a working knowledge
|
||||
of Vulkan in general. The code verbosity of classical components such as swapchain management, render passes etc. is
|
||||
reduced using [C++ API helpers](https://github.com/nvpro-samples/shared_sources/tree/master/nvvk) and
|
||||
reduced using [C++ API helpers](https://github.com/nvpro-samples/nvpro_core/tree/master/nvvk) and
|
||||
NVIDIA's [nvpro-samples](https://github.com/nvpro-samples/build_all) framework. This framework contains many advanced
|
||||
examples and best practices for Vulkan and OpenGL. We also use a helper for the creation of the ray tracing acceleration
|
||||
structures, but we will document its contents extensively in this tutorial. The code is further simplified by using the
|
||||
|
|
@ -52,8 +52,7 @@ Then open the `build_all` folder and run either `clone_all.bat` (Windows) or
|
|||
**If you want to clone as few repositories as possible**, open a command line,
|
||||
and run the following commands to clone the repositories you need:
|
||||
~~~~~
|
||||
git clone https://github.com/nvpro-samples/shared_sources.git
|
||||
git clone https://github.com/nvpro-samples/shared_external.git
|
||||
git clone --recursive --shallow-submodules https://github.com/nvpro-samples/nvpro_core.git
|
||||
git clone https://github.com/nvpro-samples/vk_raytracing_tutorial_KHR.git
|
||||
~~~~~
|
||||
|
||||
|
|
@ -229,7 +228,7 @@ with utility functions for building those acceleration structures. In the header
|
|||
|
||||
```` C
|
||||
// #VKRay
|
||||
#include "nvvk/raytrace_vk.hpp"
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
````
|
||||
|
||||
so that we can add that helper as a member in the `HelloVulkan` class,
|
||||
|
|
@ -245,9 +244,9 @@ m_rtBuilder.setup(m_device, m_alloc, m_graphicsQueueIndex);
|
|||
````
|
||||
|
||||
!!! Note Memory Management
|
||||
The raytrace helper uses `"nvvk/allocator_vk.hpp"` to avoid having to deal with vulkan memory management.
|
||||
The raytrace helper uses `"nvvk/resourceallocator_vk.hpp"` to avoid having to deal with vulkan memory management.
|
||||
This provides the `nvvk::AccelKHR` type, which consists of a `VkAccelerationStructureKHR` paired
|
||||
with info needed by the allocator to manage the buffer memory backing it. `"nvvk/allocator_vk.hpp"` requires a macro to
|
||||
with info needed by the allocator to manage the buffer memory backing it. `"nvvk/resourceallocator_vk.hpp"` requires a macro to
|
||||
be defined before inclusion to select its memory allocation strategy. In this tutorial, we defined `NVVK_ALLOC_DEDICATED`.
|
||||
This selects the simple one-`VkDeviceMemory`-per-object strategy, which is easier to understand for
|
||||
teaching purposes but not practical for production use.
|
||||
|
|
@ -262,7 +261,7 @@ Add a new method to the `HelloVulkan`
|
|||
class:
|
||||
|
||||
```` C
|
||||
nvvk::RaytracingBuilderKHR::BlasInput objectToVkGeometryKHR(const ObjModel& model);
|
||||
auto objectToVkGeometryKHR(const ObjModel& model);
|
||||
````
|
||||
|
||||
Its implementation will fill three structures that will eventually be passed to the AS builder (`vkCmdBuildAccelerationStructuresKHR`).
|
||||
|
|
@ -300,7 +299,7 @@ potential optimization. (More specifically, this disables calls to the anyhit sh
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Convert an OBJ model into the ray tracing geometry used to build the BLAS
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::BlasInput HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
{
|
||||
// BLAS builder requires raw device addresses.
|
||||
vk::DeviceAddress vertexAddress = m_device.getBufferAddress({model.vertexBuffer.buffer});
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
|||
#--------------------------------------------------------------------------------------------------
|
||||
# Linkage
|
||||
#
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} shared_sources)
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} nvpro_core)
|
||||
|
||||
foreach(DEBUGLIB ${LIBRARIES_DEBUG})
|
||||
target_link_libraries(${PROJNAME} debug ${DEBUGLIB})
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
|
|
@ -33,12 +26,13 @@ extern std::vector<std::string> defaultSearchPaths;
|
|||
#define VMA_IMPLEMENTATION
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "fileformats/stb_image.h"
|
||||
#include "obj_loader.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "nvh//cameramanipulator.hpp"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/pipeline_vk.hpp"
|
||||
|
||||
#include "nvh/fileoperations.hpp"
|
||||
|
|
@ -66,21 +60,7 @@ void HelloVulkan::setup(const vk::Instance& instance,
|
|||
uint32_t queueFamily)
|
||||
{
|
||||
AppBase::setup(instance, device, physicalDevice, queueFamily);
|
||||
#if defined(NVVK_ALLOC_DEDICATED)
|
||||
m_alloc.init(device, physicalDevice);
|
||||
#elif defined(NVVK_ALLOC_DMA)
|
||||
m_memAllocator.init(device, physicalDevice);
|
||||
m_memAllocator.setAllocateFlags(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, true);
|
||||
m_alloc.init(device, physicalDevice, &m_memAllocator);
|
||||
#elif defined(NVVK_ALLOC_VMA)
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
allocatorInfo.instance = instance;
|
||||
allocatorInfo.device = device;
|
||||
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
|
||||
vmaCreateAllocator(&allocatorInfo, &m_memAllocator);
|
||||
m_alloc.init(device, physicalDevice, m_memAllocator);
|
||||
#endif
|
||||
m_alloc.init(instance, device, physicalDevice);
|
||||
m_debug.setup(m_device);
|
||||
|
||||
|
||||
|
|
@ -459,11 +439,6 @@ void HelloVulkan::destroyResources()
|
|||
m_raytrace.destroy();
|
||||
|
||||
m_alloc.deinit();
|
||||
#ifdef NVVK_ALLOC_DMA
|
||||
m_memAllocator.deinit();
|
||||
#elif defined(NVVK_ALLOC_VMA)
|
||||
vmaDestroyAllocator(m_memAllocator);
|
||||
#endif // NVVK_ALLOC_DMA
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -530,7 +505,6 @@ void HelloVulkan::initRayTracing()
|
|||
m_raytrace.createTopLevelAS(m_objInstance, m_implObjects);
|
||||
m_raytrace.createRtDescriptorSet(m_offscreen.colorTexture().descriptor.imageView);
|
||||
m_raytrace.createRtPipeline(m_descSetLayout);
|
||||
m_raytrace.createRtShaderBindingTable();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,36 +1,27 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vkalloc.hpp"
|
||||
|
||||
#include "nvvk/allocator_dedicated_vk.hpp"
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
// #VKRay
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
|
|
@ -39,6 +30,25 @@
|
|||
#include "obj.hpp"
|
||||
#include "raytrace.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
// Choosing the allocator to use
|
||||
#define ALLOC_DMA
|
||||
//#define ALLOC_DEDICATED
|
||||
//#define ALLOC_VMA
|
||||
#include <nvvk/resourceallocator_vk.hpp>
|
||||
|
||||
#if defined(ALLOC_DMA)
|
||||
#include <nvvk/memallocator_dma_vk.hpp>
|
||||
using Allocator = nvvk::ResourceAllocatorDma;
|
||||
#elif defined(ALLOC_VMA)
|
||||
#include <nvvk/memallocator_vma_vk.hpp>
|
||||
using Allocator = nvvk::ResourceAllocatorVma;
|
||||
#else
|
||||
using Allocator = nvvk::ResourceAllocatorDedicated;
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Simple rasterizer of OBJ objects
|
||||
// - Each OBJ loaded are stored in an `ObjModel` and referenced by a `ObjInstance`
|
||||
|
|
@ -94,8 +104,7 @@ public:
|
|||
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
nvvk::Allocator m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::MemAllocator m_memAllocator;
|
||||
Allocator m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
|
||||
// #Post
|
||||
Offscreen m_offscreen;
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// ImGui - standalone example application for Glfw + Vulkan, using programmable
|
||||
// pipeline If you are new to ImGui, see examples/README.txt and documentation
|
||||
// at the top of imgui.cpp.
|
||||
|
|
@ -33,8 +26,8 @@
|
|||
#include <vulkan/vulkan.hpp>
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui/backends/imgui_impl_glfw.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
|
|
@ -44,7 +37,7 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
|||
#include "nvvk/commands_vk.hpp"
|
||||
#include "nvvk/context_vk.hpp"
|
||||
|
||||
#include "imgui/extras/imgui_camera_widget.h"
|
||||
#include "imgui/imgui_camera_widget.h"
|
||||
#include <random>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "obj_loader.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,20 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -30,6 +22,7 @@
|
|||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvvk/commands_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/pipeline_vk.hpp"
|
||||
#include "nvvk/renderpasses_vk.hpp"
|
||||
|
||||
|
|
@ -41,7 +34,7 @@ extern std::vector<std::string> defaultSearchPaths;
|
|||
|
||||
void Offscreen::setup(const vk::Device& device,
|
||||
const vk::PhysicalDevice& physicalDevice,
|
||||
nvvk::Allocator* allocator,
|
||||
nvvk::ResourceAllocator* allocator,
|
||||
uint32_t queueFamily)
|
||||
{
|
||||
m_device = device;
|
||||
|
|
|
|||
|
|
@ -1,35 +1,28 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "vkalloc.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Class to render in off-screen framebuffers. Instead of rendering directly to the
|
||||
|
|
@ -42,7 +35,7 @@ class Offscreen
|
|||
public:
|
||||
void setup(const vk::Device& device,
|
||||
const vk::PhysicalDevice& physicalDevice,
|
||||
nvvk::Allocator* allocator,
|
||||
nvvk::ResourceAllocator* allocator,
|
||||
uint32_t queueFamily);
|
||||
void destroy();
|
||||
|
||||
|
|
@ -71,7 +64,8 @@ private:
|
|||
nvvk::Texture m_depthTexture;
|
||||
vk::Format m_depthFormat;
|
||||
|
||||
nvvk::Allocator* m_alloc{nullptr}; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::ResourceAllocator* m_alloc{
|
||||
nullptr}; // Allocator for buffer, images, acceleration structures
|
||||
vk::Device m_device;
|
||||
int m_graphicsQueueIndex{0};
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
|
|
|||
|
|
@ -1,28 +1,20 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -39,7 +31,7 @@ extern std::vector<std::string> defaultSearchPaths;
|
|||
|
||||
void Raytracer::setup(const vk::Device& device,
|
||||
const vk::PhysicalDevice& physicalDevice,
|
||||
nvvk::Allocator* allocator,
|
||||
nvvk::ResourceAllocator* allocator,
|
||||
uint32_t queueFamily)
|
||||
{
|
||||
m_device = device;
|
||||
|
|
@ -54,12 +46,14 @@ void Raytracer::setup(const vk::Device& device,
|
|||
m_rtProperties = properties.get<vk::PhysicalDeviceRayTracingPipelinePropertiesKHR>();
|
||||
m_rtBuilder.setup(m_device, allocator, m_graphicsQueueIndex);
|
||||
|
||||
m_sbtWrapper.setup(device, queueFamily, allocator, m_rtProperties);
|
||||
m_debug.setup(device);
|
||||
}
|
||||
|
||||
|
||||
void Raytracer::destroy()
|
||||
{
|
||||
m_sbtWrapper.destroy();
|
||||
m_rtBuilder.destroy();
|
||||
m_device.destroy(m_rtDescPool);
|
||||
m_device.destroy(m_rtDescSetLayout);
|
||||
|
|
@ -71,7 +65,7 @@ void Raytracer::destroy()
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Converting a OBJ primitive to the ray tracing geometry used for the BLAS
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::BlasInput Raytracer::objectToVkGeometryKHR(const ObjModel& model)
|
||||
auto Raytracer::objectToVkGeometryKHR(const ObjModel& model)
|
||||
{
|
||||
// Building part
|
||||
vk::DeviceAddress vertexAddress = m_device.getBufferAddress({model.vertexBuffer.buffer});
|
||||
|
|
@ -109,8 +103,7 @@ nvvk::RaytracingBuilderKHR::BlasInput Raytracer::objectToVkGeometryKHR(const Obj
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Returning the ray tracing geometry used for the BLAS, containing all spheres
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::BlasInput Raytracer::implicitToVkGeometryKHR(
|
||||
const ImplInst& implicitObj)
|
||||
auto Raytracer::implicitToVkGeometryKHR(const ImplInst& implicitObj)
|
||||
{
|
||||
vk::DeviceAddress dataAddress = m_device.getBufferAddress({implicitObj.implBuf.buffer});
|
||||
|
||||
|
|
@ -370,6 +363,9 @@ void Raytracer::createRtPipeline(vk::DescriptorSetLayout& sceneDescLayout)
|
|||
m_rtPipeline = static_cast<const vk::Pipeline&>(
|
||||
m_device.createRayTracingPipelineKHR({}, {}, rayPipelineInfo));
|
||||
|
||||
|
||||
m_sbtWrapper.create(m_rtPipeline, rayPipelineInfo);
|
||||
|
||||
m_device.destroy(raygenSM);
|
||||
m_device.destroy(missSM);
|
||||
m_device.destroy(shadowmissSM);
|
||||
|
|
@ -383,50 +379,6 @@ void Raytracer::createRtPipeline(vk::DescriptorSetLayout& sceneDescLayout)
|
|||
m_device.destroy(call2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// The Shader Binding Table (SBT)
|
||||
// - getting all shader handles and writing them in a SBT buffer
|
||||
// - Besides exception, this could be always done like this
|
||||
// See how the SBT buffer is used in run()
|
||||
//
|
||||
void Raytracer::createRtShaderBindingTable()
|
||||
{
|
||||
auto groupCount =
|
||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit
|
||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||
uint32_t groupSizeAligned =
|
||||
nvh::align_up(groupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
||||
|
||||
|
||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||
uint32_t sbtSize = groupCount * groupSizeAligned;
|
||||
|
||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||
auto result = m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||
shaderHandleStorage.data());
|
||||
assert(result == vk::Result::eSuccess);
|
||||
|
||||
// Write the handles in the SBT
|
||||
m_rtSBTBuffer = m_alloc->createBuffer(
|
||||
sbtSize,
|
||||
vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eShaderDeviceAddress
|
||||
| vk::BufferUsageFlagBits::eShaderBindingTableKHR,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||
|
||||
// Write the handles in the SBT
|
||||
void* mapped = m_alloc->map(m_rtSBTBuffer);
|
||||
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||
for(uint32_t g = 0; g < groupCount; g++)
|
||||
{
|
||||
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||
pData += groupSizeAligned;
|
||||
}
|
||||
m_alloc->unmap(m_rtSBTBuffer);
|
||||
|
||||
m_alloc->finalizeAndReleaseStaging();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Ray Tracing the scene
|
||||
//
|
||||
|
|
@ -457,22 +409,9 @@ void Raytracer::raytrace(const vk::CommandBuffer& cmdBuf,
|
|||
| vk::ShaderStageFlagBits::eCallableKHR,
|
||||
0, m_rtPushConstants);
|
||||
|
||||
// Size of a program identifier
|
||||
uint32_t groupSize =
|
||||
nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
||||
uint32_t groupStride = groupSize;
|
||||
vk::DeviceAddress sbtAddress = m_device.getBufferAddress({m_rtSBTBuffer.buffer});
|
||||
|
||||
using Stride = vk::StridedDeviceAddressRegionKHR;
|
||||
std::array<Stride, 4> strideAddresses{
|
||||
Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
||||
Stride{sbtAddress + 1u * groupSize, groupStride, groupSize * 2}, // miss
|
||||
Stride{sbtAddress + 3u * groupSize, groupStride, groupSize * 2}, // hit
|
||||
Stride{sbtAddress + 5u * groupSize, groupStride, groupSize * 3}}; // callable
|
||||
|
||||
cmdBuf.traceRaysKHR(&strideAddresses[0], &strideAddresses[1], &strideAddresses[2],
|
||||
&strideAddresses[3], //
|
||||
size.width, size.height, 1); //
|
||||
auto regions = m_sbtWrapper.getRegions();
|
||||
cmdBuf.traceRaysKHR(regions[0], regions[1], regions[2], regions[3], size.width, size.height, 1);
|
||||
|
||||
m_debug.endLabel(cmdBuf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,29 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "vkalloc.hpp"
|
||||
|
||||
#include "nvmath/nvmath.h"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
#include "nvvk/sbtwrapper_vk.hpp"
|
||||
#include "obj.hpp"
|
||||
|
||||
class Raytracer
|
||||
|
|
@ -39,18 +31,17 @@ class Raytracer
|
|||
public:
|
||||
void setup(const vk::Device& device,
|
||||
const vk::PhysicalDevice& physicalDevice,
|
||||
nvvk::Allocator* allocator,
|
||||
nvvk::ResourceAllocator* allocator,
|
||||
uint32_t queueFamily);
|
||||
void destroy();
|
||||
|
||||
nvvk::RaytracingBuilderKHR::BlasInput objectToVkGeometryKHR(const ObjModel& model);
|
||||
nvvk::RaytracingBuilderKHR::BlasInput implicitToVkGeometryKHR(const ImplInst& implicitObj);
|
||||
auto objectToVkGeometryKHR(const ObjModel& model);
|
||||
auto implicitToVkGeometryKHR(const ImplInst& implicitObj);
|
||||
void createBottomLevelAS(std::vector<ObjModel>& models, ImplInst& implicitObj);
|
||||
void createTopLevelAS(std::vector<ObjInstance>& instances, ImplInst& implicitObj);
|
||||
void createRtDescriptorSet(const vk::ImageView& outputImage);
|
||||
void updateRtDescriptorSet(const vk::ImageView& outputImage);
|
||||
void createRtPipeline(vk::DescriptorSetLayout& sceneDescLayout);
|
||||
void createRtShaderBindingTable();
|
||||
void raytrace(const vk::CommandBuffer& cmdBuf,
|
||||
const nvmath::vec4f& clearColor,
|
||||
vk::DescriptorSet& sceneDescSet,
|
||||
|
|
@ -58,12 +49,13 @@ public:
|
|||
ObjPushConstants& sceneConstants);
|
||||
|
||||
private:
|
||||
nvvk::Allocator* m_alloc{nullptr}; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::ResourceAllocator* m_alloc{
|
||||
nullptr}; // Allocator for buffer, images, acceleration structures
|
||||
vk::PhysicalDevice m_physicalDevice;
|
||||
vk::Device m_device;
|
||||
int m_graphicsQueueIndex{0};
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
nvvk::SBTWrapper m_sbtWrapper;
|
||||
|
||||
vk::PhysicalDeviceRayTracingPipelinePropertiesKHR m_rtProperties;
|
||||
nvvk::RaytracingBuilderKHR m_rtBuilder;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460 core
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout(location = 0) in vec2 outUV;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
||||
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
||||
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
vec3 hitValue;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
vec3 pos;
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
//#define NVVK_ALLOC_DEDICATED
|
||||
#define NVVK_ALLOC_DMA
|
||||
//#define NVVK_ALLOC_VMA
|
||||
|
||||
#include <nvvk/allocator_vk.hpp>
|
||||
|
|
@ -58,7 +58,7 @@ source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
|||
#--------------------------------------------------------------------------------------------------
|
||||
# Linkage
|
||||
#
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} shared_sources)
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} nvpro_core)
|
||||
|
||||
foreach(DEBUGLIB ${LIBRARIES_DEBUG})
|
||||
target_link_libraries(${PROJNAME} debug ${DEBUGLIB})
|
||||
|
|
|
|||
|
|
@ -1,42 +1,36 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
extern std::vector<std::string> defaultSearchPaths;
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "fileformats/stb_image.h"
|
||||
#include "obj_loader.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "nvh//cameramanipulator.hpp"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/pipeline_vk.hpp"
|
||||
|
||||
#include "nvh/fileoperations.hpp"
|
||||
|
|
@ -359,8 +353,7 @@ void HelloVulkan::createTextureImages(const vk::CommandBuffer& cmdBuf,
|
|||
auto imageCreateInfo = nvvk::makeImage2DCreateInfo(imgSize, format, vkIU::eSampled, true);
|
||||
|
||||
{
|
||||
nvvk::ImageDedicated image =
|
||||
m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::cmdGenerateMipmaps(cmdBuf, image.image, format, imgSize, imageCreateInfo.mipLevels);
|
||||
vk::ImageViewCreateInfo ivInfo =
|
||||
nvvk::makeImageViewCreateInfo(image.image, imageCreateInfo);
|
||||
|
|
@ -408,6 +401,8 @@ void HelloVulkan::destroyResources()
|
|||
m_alloc.destroy(m_offscreenDepth);
|
||||
m_device.destroy(m_offscreenRenderPass);
|
||||
m_device.destroy(m_offscreenFramebuffer);
|
||||
|
||||
m_alloc.deinit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -475,7 +470,7 @@ void HelloVulkan::createOffscreenRender()
|
|||
| vk::ImageUsageFlagBits::eStorage);
|
||||
|
||||
|
||||
nvvk::ImageDedicated image = m_alloc.createImage(colorCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(colorCreateInfo);
|
||||
vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo);
|
||||
m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo());
|
||||
m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
|
|
|||
|
|
@ -1,36 +1,29 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NVVK_ALLOC_DEDICATED
|
||||
#include "nvvk/allocator_vk.hpp"
|
||||
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Simple rasterizer of OBJ objects
|
||||
|
|
@ -106,7 +99,8 @@ public:
|
|||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
|
||||
nvvk::AllocatorDedicated m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::ResourceAllocatorDedicated
|
||||
m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// ImGui - standalone example application for Glfw + Vulkan, using programmable
|
||||
// pipeline If you are new to ImGui, see examples/README.txt and documentation
|
||||
// at the top of imgui.cpp.
|
||||
|
|
@ -33,11 +26,11 @@
|
|||
#include <vulkan/vulkan.hpp>
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui/backends/imgui_impl_glfw.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "imgui/extras/imgui_camera_widget.h"
|
||||
#include "imgui/imgui_camera_widget.h"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvpsystem.hpp"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout(location = 0) in vec2 outUV;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
vec3 pos;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
|||
#--------------------------------------------------------------------------------------------------
|
||||
# Linkage
|
||||
#
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} shared_sources)
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} nvpro_core)
|
||||
|
||||
foreach(DEBUGLIB ${LIBRARIES_DEBUG})
|
||||
target_link_libraries(${PROJNAME} debug ${DEBUGLIB})
|
||||
|
|
|
|||
|
|
@ -11,4 +11,4 @@ If you haven't done it, [**Start Ray Tracing Tutorial**](https://nvpro-samples.g
|
|||
|
||||
Once the tutorial completed and the basics of ray tracing are in place, other tuturials are going further from this code base.
|
||||
|
||||
See all other [additional ray tracing tutorials](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/vkrt_tuto_further.md.html)
|
||||
See all other [additional ray tracing tutorials](../README.md#extra-tutorials)
|
||||
|
|
|
|||
|
|
@ -1,38 +1,31 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
extern std::vector<std::string> defaultSearchPaths;
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "fileformats/stb_image.h"
|
||||
#include "obj_loader.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "nvh/alignment.hpp"
|
||||
|
|
@ -40,6 +33,7 @@ extern std::vector<std::string> defaultSearchPaths;
|
|||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvvk/commands_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/pipeline_vk.hpp"
|
||||
#include "nvvk/renderpasses_vk.hpp"
|
||||
#include "nvvk/shaders_vk.hpp"
|
||||
|
|
@ -384,8 +378,7 @@ void HelloVulkan::createTextureImages(const vk::CommandBuffer& cmdBuf,
|
|||
auto imageCreateInfo = nvvk::makeImage2DCreateInfo(imgSize, format, vkIU::eSampled, true);
|
||||
|
||||
{
|
||||
nvvk::ImageDedicated image =
|
||||
m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::cmdGenerateMipmaps(cmdBuf, image.image, format, imgSize, imageCreateInfo.mipLevels);
|
||||
vk::ImageViewCreateInfo ivInfo =
|
||||
nvvk::makeImageViewCreateInfo(image.image, imageCreateInfo);
|
||||
|
|
@ -441,6 +434,8 @@ void HelloVulkan::destroyResources()
|
|||
m_device.destroy(m_rtPipeline);
|
||||
m_device.destroy(m_rtPipelineLayout);
|
||||
m_alloc.destroy(m_rtSBTBuffer);
|
||||
|
||||
m_alloc.deinit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -660,7 +655,7 @@ void HelloVulkan::initRayTracing()
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Convert an OBJ model into the ray tracing geometry used to build the BLAS
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::BlasInput HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
{
|
||||
// BLAS builder requires raw device addresses.
|
||||
vk::DeviceAddress vertexAddress = m_device.getBufferAddress({model.vertexBuffer.buffer});
|
||||
|
|
|
|||
|
|
@ -1,37 +1,30 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#define NVVK_ALLOC_DEDICATED
|
||||
#include "nvvk/allocator_vk.hpp"
|
||||
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
// #VKRay
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
|
|
@ -109,7 +102,8 @@ public:
|
|||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
nvvk::AllocatorDedicated m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::ResourceAllocatorDedicated
|
||||
m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
// #Post
|
||||
|
|
@ -134,7 +128,7 @@ public:
|
|||
|
||||
// #VKRay
|
||||
void initRayTracing();
|
||||
nvvk::RaytracingBuilderKHR::BlasInput objectToVkGeometryKHR(const ObjModel& model);
|
||||
auto objectToVkGeometryKHR(const ObjModel& model);
|
||||
void createBottomLevelAS();
|
||||
void createTopLevelAS();
|
||||
void createRtDescriptorSet();
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// ImGui - standalone example application for Glfw + Vulkan, using programmable
|
||||
// pipeline If you are new to ImGui, see examples/README.txt and documentation
|
||||
// at the top of imgui.cpp.
|
||||
|
|
@ -33,11 +26,11 @@
|
|||
#include <vulkan/vulkan.hpp>
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui/backends/imgui_impl_glfw.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "imgui/extras/imgui_camera_widget.h"
|
||||
#include "imgui/imgui_camera_widget.h"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvpsystem.hpp"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout(location = 0) in vec2 outUV;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
vec3 hitValue;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
|
|
|
|||
|
|
@ -1,158 +0,0 @@
|
|||
//#include "raycommon.hlsl"
|
||||
//#include "wavefront.hlsl"
|
||||
|
||||
struct MyAttrib
|
||||
{
|
||||
float3 attribs;
|
||||
};
|
||||
|
||||
struct Payload
|
||||
{
|
||||
bool isShadowed;
|
||||
};
|
||||
|
||||
[[vk::binding(0,0)]] RaytracingAccelerationStructure topLevelAS;
|
||||
|
||||
[[vk::binding(2,1)]] RWStructuredBuffer<sceneDesc> scnDesc;
|
||||
|
||||
[[vk::binding(5,1)]] StructuredBuffer<Vertex> vertices[];
|
||||
|
||||
[[vk::binding(6,1)]] StructuredBuffer<uint> indices[];
|
||||
|
||||
|
||||
[[vk::binding(1,1)]] StructuredBuffer<WaveFrontMaterial> materials[];
|
||||
|
||||
[[vk::binding(3,1)]] Texture2D textures[];
|
||||
[[vk::binding(3,1)]] SamplerState samplers[];
|
||||
|
||||
[[vk::binding(4,1)]] StructuredBuffer<int> matIndex[];
|
||||
|
||||
// clang-format on
|
||||
|
||||
struct Constants
|
||||
{
|
||||
float4 clearColor;
|
||||
float3 lightPosition;
|
||||
float lightIntensity;
|
||||
int lightType;
|
||||
};
|
||||
|
||||
[[vk::push_constant]] Constants pushC;
|
||||
|
||||
[shader("closesthit")]
|
||||
void main(inout hitPayload prd, in MyAttrib attr)
|
||||
{
|
||||
// Object of this instance
|
||||
uint objId = scnDesc[InstanceIndex()].objId;
|
||||
|
||||
// Indices of the triangle
|
||||
int3 ind = int3(indices[objId][3 * PrimitiveIndex() + 0],
|
||||
indices[objId][3 * PrimitiveIndex() + 1],
|
||||
indices[objId][3 * PrimitiveIndex() + 2]);
|
||||
// Vertex of the triangle
|
||||
Vertex v0 = vertices[objId][ind.x];
|
||||
Vertex v1 = vertices[objId][ind.y];
|
||||
Vertex v2 = vertices[objId][ind.z];
|
||||
|
||||
const float3 barycentrics = float3(1.0 - attr.attribs.x -
|
||||
attr.attribs.y, attr.attribs.x, attr.attribs.y);
|
||||
|
||||
// Computing the normal at hit position
|
||||
float3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y +
|
||||
v2.nrm * barycentrics.z;
|
||||
// Transforming the normal to world space
|
||||
normal = normalize((mul(scnDesc[InstanceIndex()].transfoIT
|
||||
,float4(normal, 0.0))).xyz);
|
||||
|
||||
|
||||
// Computing the coordinates of the hit position
|
||||
float3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y
|
||||
+ v2.pos * barycentrics.z;
|
||||
// Transforming the position to world space
|
||||
worldPos = (mul(scnDesc[InstanceIndex()].transfo, float4(worldPos,
|
||||
1.0))).xyz;
|
||||
|
||||
// Vector toward the light
|
||||
float3 L;
|
||||
float lightIntensity = pushC.lightIntensity;
|
||||
float lightDistance = 100000.0;
|
||||
|
||||
// Point light
|
||||
if(pushC.lightType == 0)
|
||||
{
|
||||
float3 lDir = pushC.lightPosition - worldPos;
|
||||
lightDistance = length(lDir);
|
||||
lightIntensity = pushC.lightIntensity / (lightDistance *
|
||||
lightDistance);
|
||||
L = normalize(lDir);
|
||||
}
|
||||
else // Directional light
|
||||
{
|
||||
L = normalize(pushC.lightPosition - float3(0,0,0));
|
||||
}
|
||||
|
||||
// Material of the object
|
||||
int matIdx = matIndex[objId][PrimitiveIndex()];
|
||||
WaveFrontMaterial mat = materials[objId][matIdx];
|
||||
|
||||
|
||||
// Diffuse
|
||||
float3 diffuse = computeDiffuse(mat, L, normal);
|
||||
if(mat.textureId >= 0)
|
||||
{
|
||||
uint txtId = mat.textureId + scnDesc[InstanceIndex()].txtOffset;
|
||||
float2 texCoord =
|
||||
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y +
|
||||
v2.texCoord * barycentrics.z;
|
||||
diffuse *= textures[txtId].SampleLevel(samplers[txtId], texCoord,
|
||||
0).xyz;
|
||||
}
|
||||
|
||||
float3 specular = float3(0,0,0);
|
||||
float attenuation = 1;
|
||||
|
||||
// Tracing shadow ray only if the light is visible from the surface
|
||||
if(dot(normal, L) > 0)
|
||||
{
|
||||
float tMin = 0.001;
|
||||
float tMax = lightDistance;
|
||||
float3 origin = WorldRayOrigin() + WorldRayDirection() *
|
||||
RayTCurrent();
|
||||
float3 rayDir = L;
|
||||
uint flags =
|
||||
RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH |
|
||||
RAY_FLAG_FORCE_OPAQUE |
|
||||
RAY_FLAG_SKIP_CLOSEST_HIT_SHADER;
|
||||
|
||||
RayDesc desc;
|
||||
desc.Origin = origin;
|
||||
desc.Direction = rayDir;
|
||||
desc.TMin = tMin;
|
||||
desc.TMax = tMax;
|
||||
|
||||
Payload shadowPayload;
|
||||
shadowPayload.isShadowed = true;
|
||||
TraceRay(topLevelAS,
|
||||
flags,
|
||||
0xFF,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
desc,
|
||||
shadowPayload
|
||||
);
|
||||
|
||||
if(shadowPayload.isShadowed)
|
||||
{
|
||||
attenuation = 0.9;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Specular
|
||||
specular = computeSpecular(mat, WorldRayDirection(), L, normal);
|
||||
}
|
||||
}
|
||||
|
||||
prd.hitValue = float3(lightIntensity * attenuation * (diffuse +
|
||||
specular));
|
||||
}
|
||||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
vec3 pos;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
|||
#--------------------------------------------------------------------------------------------------
|
||||
# Linkage
|
||||
#
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} shared_sources)
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} nvpro_core)
|
||||
|
||||
foreach(DEBUGLIB ${LIBRARIES_DEBUG})
|
||||
target_link_libraries(${PROJNAME} debug ${DEBUGLIB})
|
||||
|
|
|
|||
|
|
@ -1,42 +1,36 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
extern std::vector<std::string> defaultSearchPaths;
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "fileformats/stb_image.h"
|
||||
#include "obj_loader.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "nvh//cameramanipulator.hpp"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/pipeline_vk.hpp"
|
||||
|
||||
#include "nvh/alignment.hpp"
|
||||
|
|
@ -66,7 +60,7 @@ void HelloVulkan::setup(const vk::Instance& instance,
|
|||
uint32_t queueFamily)
|
||||
{
|
||||
AppBase::setup(instance, device, physicalDevice, queueFamily);
|
||||
m_alloc.init(device, physicalDevice);
|
||||
m_alloc.init(instance, device, physicalDevice);
|
||||
m_debug.setup(m_device);
|
||||
m_offscreenDepthFormat = nvvk::findDepthFormat(physicalDevice);
|
||||
}
|
||||
|
|
@ -383,8 +377,7 @@ void HelloVulkan::createTextureImages(const vk::CommandBuffer& cmdBuf,
|
|||
auto imageCreateInfo = nvvk::makeImage2DCreateInfo(imgSize, format, vkIU::eSampled, true);
|
||||
|
||||
{
|
||||
nvvk::ImageDedicated image =
|
||||
m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::cmdGenerateMipmaps(cmdBuf, image.image, format, imgSize, imageCreateInfo.mipLevels);
|
||||
vk::ImageViewCreateInfo ivInfo =
|
||||
nvvk::makeImageViewCreateInfo(image.image, imageCreateInfo);
|
||||
|
|
@ -435,17 +428,19 @@ void HelloVulkan::destroyResources()
|
|||
|
||||
// #VKRay
|
||||
m_rtBuilder.destroy();
|
||||
m_sbtWrapper.destroy();
|
||||
m_device.destroy(m_rtDescPool);
|
||||
m_device.destroy(m_rtDescSetLayout);
|
||||
m_device.destroy(m_rtPipeline);
|
||||
m_device.destroy(m_rtPipelineLayout);
|
||||
m_alloc.destroy(m_rtSBTBuffer);
|
||||
|
||||
// #VK_compute
|
||||
m_device.destroy(m_compDescPool);
|
||||
m_device.destroy(m_compDescSetLayout);
|
||||
m_device.destroy(m_compPipeline);
|
||||
m_device.destroy(m_compPipelineLayout);
|
||||
|
||||
m_alloc.deinit();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -512,7 +507,7 @@ void HelloVulkan::createOffscreenRender()
|
|||
| vk::ImageUsageFlagBits::eStorage);
|
||||
|
||||
|
||||
nvvk::ImageDedicated image = m_alloc.createImage(colorCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(colorCreateInfo);
|
||||
vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo);
|
||||
m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo());
|
||||
m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
|
@ -661,12 +656,13 @@ void HelloVulkan::initRayTracing()
|
|||
vk::PhysicalDeviceRayTracingPipelinePropertiesKHR>();
|
||||
m_rtProperties = properties.get<vk::PhysicalDeviceRayTracingPipelinePropertiesKHR>();
|
||||
m_rtBuilder.setup(m_device, &m_alloc, m_graphicsQueueIndex);
|
||||
m_sbtWrapper.setup(m_device, m_graphicsQueueIndex, &m_alloc, m_rtProperties);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Converting a OBJ primitive to the ray tracing geometry used for the BLAS
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::BlasInput HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
{
|
||||
vk::DeviceAddress vertexAddress = m_device.getBufferAddress({model.vertexBuffer.buffer});
|
||||
vk::DeviceAddress indexAddress = m_device.getBufferAddress({model.indexBuffer.buffer});
|
||||
|
|
@ -858,56 +854,16 @@ void HelloVulkan::createRtPipeline()
|
|||
m_rtPipeline = static_cast<const vk::Pipeline&>(
|
||||
m_device.createRayTracingPipelineKHR({}, {}, rayPipelineInfo));
|
||||
|
||||
|
||||
m_sbtWrapper.create(m_rtPipeline, rayPipelineInfo);
|
||||
|
||||
|
||||
m_device.destroy(raygenSM);
|
||||
m_device.destroy(missSM);
|
||||
m_device.destroy(shadowmissSM);
|
||||
m_device.destroy(chitSM);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// The Shader Binding Table (SBT)
|
||||
// - getting all shader handles and writing them in a SBT buffer
|
||||
// - Besides exception, this could be always done like this
|
||||
// See how the SBT buffer is used in run()
|
||||
//
|
||||
void HelloVulkan::createRtShaderBindingTable()
|
||||
{
|
||||
auto groupCount =
|
||||
static_cast<uint32_t>(m_rtShaderGroups.size()); // shaders: raygen, 2 miss, chit
|
||||
uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier
|
||||
uint32_t groupSizeAligned =
|
||||
nvh::align_up(groupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
||||
|
||||
// Fetch all the shader handles used in the pipeline, so that they can be written in the SBT
|
||||
uint32_t sbtSize = groupCount * groupSizeAligned;
|
||||
|
||||
std::vector<uint8_t> shaderHandleStorage(sbtSize);
|
||||
auto result = m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
|
||||
shaderHandleStorage.data());
|
||||
assert(result == vk::Result::eSuccess);
|
||||
|
||||
// Write the handles in the SBT
|
||||
m_rtSBTBuffer = m_alloc.createBuffer(
|
||||
sbtSize,
|
||||
vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eShaderDeviceAddress
|
||||
| vk::BufferUsageFlagBits::eShaderBindingTableKHR,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
|
||||
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
|
||||
|
||||
// Write the handles in the SBT
|
||||
void* mapped = m_alloc.map(m_rtSBTBuffer);
|
||||
auto* pData = reinterpret_cast<uint8_t*>(mapped);
|
||||
for(uint32_t g = 0; g < groupCount; g++)
|
||||
{
|
||||
memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
|
||||
pData += groupSizeAligned;
|
||||
}
|
||||
m_alloc.unmap(m_rtSBTBuffer);
|
||||
|
||||
|
||||
m_alloc.finalizeAndReleaseStaging();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Ray Tracing the scene
|
||||
//
|
||||
|
|
@ -930,22 +886,9 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
|
|||
0, m_rtPushConstants);
|
||||
|
||||
|
||||
// Size of a program identifier
|
||||
uint32_t groupSize =
|
||||
nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment);
|
||||
uint32_t groupStride = groupSize;
|
||||
vk::DeviceAddress sbtAddress = m_device.getBufferAddress({m_rtSBTBuffer.buffer});
|
||||
|
||||
using Stride = vk::StridedDeviceAddressRegionKHR;
|
||||
std::array<Stride, 4> strideAddresses{
|
||||
Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen
|
||||
Stride{sbtAddress + 1u * groupSize, groupStride, groupSize * 2}, // miss
|
||||
Stride{sbtAddress + 3u * groupSize, groupStride, groupSize * 1}, // hit
|
||||
Stride{0u, 0u, 0u}}; // callable
|
||||
|
||||
cmdBuf.traceRaysKHR(&strideAddresses[0], &strideAddresses[1], &strideAddresses[2],
|
||||
&strideAddresses[3], //
|
||||
m_size.width, m_size.height, 1); //
|
||||
auto regions = m_sbtWrapper.getRegions();
|
||||
cmdBuf.traceRaysKHR(regions[0], regions[1], regions[2], regions[3], m_size.width, m_size.height,
|
||||
1);
|
||||
|
||||
m_debug.endLabel(cmdBuf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,33 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NVVK_ALLOC_DEDICATED
|
||||
#include "nvvk/allocator_vk.hpp"
|
||||
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
// #VKRay
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
#include "nvvk/sbtwrapper_vk.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Simple rasterizer of OBJ objects
|
||||
|
|
@ -108,7 +102,8 @@ public:
|
|||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
nvvk::AllocatorDedicated m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::ResourceAllocatorDedicated
|
||||
m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
// #Post
|
||||
|
|
@ -133,13 +128,12 @@ public:
|
|||
|
||||
// #VKRay
|
||||
void initRayTracing();
|
||||
nvvk::RaytracingBuilderKHR::BlasInput objectToVkGeometryKHR(const ObjModel& model);
|
||||
auto objectToVkGeometryKHR(const ObjModel& model);
|
||||
void createBottomLevelAS();
|
||||
void createTopLevelAS();
|
||||
void createRtDescriptorSet();
|
||||
void updateRtDescriptorSet();
|
||||
void createRtPipeline();
|
||||
void createRtShaderBindingTable();
|
||||
void raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& clearColor);
|
||||
|
||||
|
||||
|
|
@ -152,7 +146,7 @@ public:
|
|||
std::vector<vk::RayTracingShaderGroupCreateInfoKHR> m_rtShaderGroups;
|
||||
vk::PipelineLayout m_rtPipelineLayout;
|
||||
vk::Pipeline m_rtPipeline;
|
||||
nvvk::Buffer m_rtSBTBuffer;
|
||||
nvvk::SBTWrapper m_sbtWrapper;
|
||||
|
||||
std::vector<nvvk::RaytracingBuilderKHR::Instance> m_tlas;
|
||||
std::vector<nvvk::RaytracingBuilderKHR::BlasInput> m_blas;
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// ImGui - standalone example application for Glfw + Vulkan, using programmable
|
||||
// pipeline If you are new to ImGui, see examples/README.txt and documentation
|
||||
// at the top of imgui.cpp.
|
||||
|
|
@ -32,11 +25,11 @@
|
|||
#include <array>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui/backends/imgui_impl_glfw.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "imgui/extras/imgui_camera_widget.h"
|
||||
#include "imgui/imgui_camera_widget.h"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvpsystem.hpp"
|
||||
|
|
@ -198,7 +191,6 @@ int main(int argc, char** argv)
|
|||
helloVk.createTopLevelAS();
|
||||
helloVk.createRtDescriptorSet();
|
||||
helloVk.createRtPipeline();
|
||||
helloVk.createRtShaderBindingTable();
|
||||
|
||||
helloVk.createPostDescriptor();
|
||||
helloVk.createPostPipeline();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout(location = 0) in vec2 outUV;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
vec3 hitValue;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
vec3 pos;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS})
|
|||
#--------------------------------------------------------------------------------------------------
|
||||
# Linkage
|
||||
#
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} shared_sources)
|
||||
target_link_libraries(${PROJNAME} ${PLATFORM_LIBRARIES} nvpro_core)
|
||||
|
||||
foreach(DEBUGLIB ${LIBRARIES_DEBUG})
|
||||
target_link_libraries(${PROJNAME} debug ${DEBUGLIB})
|
||||
|
|
|
|||
|
|
@ -1,42 +1,36 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
extern std::vector<std::string> defaultSearchPaths;
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "fileformats/stb_image.h"
|
||||
#include "obj_loader.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "nvh//cameramanipulator.hpp"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/images_vk.hpp"
|
||||
#include "nvvk/pipeline_vk.hpp"
|
||||
|
||||
#include "nvh/alignment.hpp"
|
||||
|
|
@ -386,8 +380,7 @@ void HelloVulkan::createTextureImages(const vk::CommandBuffer& cmdBuf,
|
|||
auto imageCreateInfo = nvvk::makeImage2DCreateInfo(imgSize, format, vkIU::eSampled, true);
|
||||
|
||||
{
|
||||
nvvk::ImageDedicated image =
|
||||
m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(cmdBuf, bufferSize, pixels, imageCreateInfo);
|
||||
nvvk::cmdGenerateMipmaps(cmdBuf, image.image, format, imgSize, imageCreateInfo.mipLevels);
|
||||
vk::ImageViewCreateInfo ivInfo =
|
||||
nvvk::makeImageViewCreateInfo(image.image, imageCreateInfo);
|
||||
|
|
@ -443,6 +436,8 @@ void HelloVulkan::destroyResources()
|
|||
m_device.destroy(m_rtPipeline);
|
||||
m_device.destroy(m_rtPipelineLayout);
|
||||
m_alloc.destroy(m_rtSBTBuffer);
|
||||
|
||||
m_alloc.deinit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -509,7 +504,7 @@ void HelloVulkan::createOffscreenRender()
|
|||
| vk::ImageUsageFlagBits::eStorage);
|
||||
|
||||
|
||||
nvvk::ImageDedicated image = m_alloc.createImage(colorCreateInfo);
|
||||
nvvk::Image image = m_alloc.createImage(colorCreateInfo);
|
||||
vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo);
|
||||
m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo());
|
||||
m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
|
@ -663,7 +658,7 @@ void HelloVulkan::initRayTracing()
|
|||
//--------------------------------------------------------------------------------------------------
|
||||
// Converting a OBJ primitive to the ray tracing geometry used for the BLAS
|
||||
//
|
||||
nvvk::RaytracingBuilderKHR::BlasInput HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model)
|
||||
{
|
||||
vk::DeviceAddress vertexAddress = m_device.getBufferAddress({model.vertexBuffer.buffer});
|
||||
vk::DeviceAddress indexAddress = m_device.getBufferAddress({model.indexBuffer.buffer});
|
||||
|
|
|
|||
|
|
@ -1,36 +1,29 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NVVK_ALLOC_DEDICATED
|
||||
#include "nvvk/allocator_vk.hpp"
|
||||
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
// #VKRay
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
|
|
@ -108,7 +101,8 @@ public:
|
|||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
nvvk::AllocatorDedicated m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::ResourceAllocatorDedicated
|
||||
m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
// #Post
|
||||
|
|
@ -133,7 +127,7 @@ public:
|
|||
|
||||
// #VKRay
|
||||
void initRayTracing();
|
||||
nvvk::RaytracingBuilderKHR::BlasInput objectToVkGeometryKHR(const ObjModel& model);
|
||||
auto objectToVkGeometryKHR(const ObjModel& model);
|
||||
void createBottomLevelAS();
|
||||
void createTopLevelAS();
|
||||
void createRtDescriptorSet();
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
/* Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// ImGui - standalone example application for Glfw + Vulkan, using programmable
|
||||
// pipeline If you are new to ImGui, see examples/README.txt and documentation
|
||||
// at the top of imgui.cpp.
|
||||
|
|
@ -32,11 +25,11 @@
|
|||
#include <array>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui/backends/imgui_impl_glfw.h"
|
||||
|
||||
#include "hello_vulkan.h"
|
||||
#include "imgui/extras/imgui_camera_widget.h"
|
||||
#include "imgui/imgui_camera_widget.h"
|
||||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvpsystem.hpp"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
layout(location = 0) in vec2 outUV;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// Generate a random unsigned int from two unsigned int values, using 16 pairs
|
||||
// of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis,
|
||||
// "GPU Random Numbers via the Tiny Encryption Algorithm"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct hitPayload
|
||||
{
|
||||
vec3 hitValue;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue