New documentation

This commit is contained in:
mklefrancois 2020-08-31 16:57:10 +02:00
parent e1dff2a4e7
commit 3465e08c77
31 changed files with 2825 additions and 55 deletions

62
docs/setup.md Normal file
View file

@ -0,0 +1,62 @@

# Environment Setup
## Repositories
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.
The directory structure should be looking like this:
~~~~
\
|
+-- :file_folder: shared_external
|
+-- :file_folder: shared_sources
|
+-- :open_file_folder: vk_raytracing_tutorial_KHR
| |
| +-- :file_folder: ray_tracing__simple
| |
| +-- :file_folder: ray_tracing_...
| |
| ⋮
|
~~~~
## Latest Vulkan SDK
This repository tries to always be up to date with the latest Vulkan SDK, therefore we suggest to download and install it.
**Vulkan SDK**: https://vulkan.lunarg.com/sdk/home
## Beta Installation
KHR ray tracing is still in Beta, therefore you will need the latest
Vulkan driver.
**Latest driver**: https://developer.nvidia.com/vulkan-driver
## 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
`vk_raytracing_tutorial_KHR` directory.
**_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.
## Starting From Extra Tutorial
All _extra_ tutorials are starting from the end result of the _first tutorial_. The directory of the _extra_ tutorials is the end result of doing it.
To start the tutorial from the begining.
* Make a copy of the ray_tutorial__simple (backup)
* Follow the tutorial by modifying ray_tutorial__simple

View file

@ -235,6 +235,174 @@ As mentioned earlier, for the effect to work, we need to accumulate frames over
* [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.
![](Images/anyhit_0.png)
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.
![](Images/anyhit_01.png)
## 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)
stages.push_back({{}, vk::ShaderStageFlagBits::eAnyHitNV, ahit1SM, "main"});
hg.setAnyHitShader(static_cast<uint32_t>(stages.size() - 1));
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)