New: motion blur
This commit is contained in:
parent
fe070436a2
commit
596b641a56
5 changed files with 102 additions and 60 deletions
|
|
@ -59,6 +59,7 @@ add_subdirectory(ray_tracing_ao)
|
||||||
add_subdirectory(ray_tracing_indirect_scissor)
|
add_subdirectory(ray_tracing_indirect_scissor)
|
||||||
add_subdirectory(ray_tracing_specialization)
|
add_subdirectory(ray_tracing_specialization)
|
||||||
add_subdirectory(ray_tracing_advanced_compilation)
|
add_subdirectory(ray_tracing_advanced_compilation)
|
||||||
|
add_subdirectory(ray_tracing_motionblur)
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------------------------
|
#--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,4 @@ Tutorial | Details
|
||||||
 | [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)).
|
 | [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.
|
 | [Specialization Constants](ray_tracing_specialization) <br> Showing how to use specialization constant and using interactively different specialization.
|
||||||
 | [Advanced Compilation](ray_tracing_advanced_compilation) <br> Shows how to create reusable pipeline libraries and compile pipelines on multiple threads.
|
 | [Advanced Compilation](ray_tracing_advanced_compilation) <br> Shows how to create reusable pipeline libraries and compile pipelines on multiple threads.
|
||||||
|
 | [Motion Blur](ray_tracing_motionblur) <br> Using vertex motion and instance motion: matrix and SRT.
|
||||||
|
|
@ -5,8 +5,6 @@ It is the starting point of the [ray tracing tutorial](https://nvpro-samples.git
|
||||||
the source of the application where ray tracing will be added.
|
the source of the application where ray tracing will be added.
|
||||||

|

|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Before starting the tutorial and adding what is necessary to enable ray tracing, here is a brief description of how this basic example was created.
|
Before starting the tutorial and adding what is necessary to enable ray tracing, here is a brief description of how this basic example was created.
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,27 @@ This is an extension of the Vulkan ray tracing [tutorial](https://nvpro-samples.
|
||||||
|
|
||||||
If you haven't compiled it before, here is the [setup](../docs/setup.md).
|
If you haven't compiled it before, here is the [setup](../docs/setup.md).
|
||||||
|
|
||||||
|
## Beta Feature
|
||||||
|
|
||||||
|
:warning: This feature is in beta and the following are needed:
|
||||||
|
|
||||||
|
* Vulkan Beta Driver: [472.02](https://developer.nvidia.com/vulkan-driver)
|
||||||
|
* Vulkan SDK: [1.2.189.0](https://vulkan.lunarg.com/sdk/home)
|
||||||
|
|
||||||
|
:warning: This new feature is not fully supported by the validation layer and produces (harmless) error messages.
|
||||||
|
|
||||||
## VK_NV_ray_tracing_motion_blur
|
## VK_NV_ray_tracing_motion_blur
|
||||||
|
|
||||||
This sample shows the usage of the [motion blur extension](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_NV_ray_tracing_motion_blur.html). In changes from the original sample, we will do the following:
|
This sample shows the usage of the [motion blur extension](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_NV_ray_tracing_motion_blur.html).
|
||||||
|
|
||||||
|
The following changes were made to the [original sample](../ray_tracing__simple):
|
||||||
|
|
||||||
* Use trace call with a time parameter.
|
* Use trace call with a time parameter.
|
||||||
* Using the various flags to enable motion support in an acceleration structure.
|
* Using the various flags to enable motion support in an acceleration structure.
|
||||||
* Support for time-varying vertex positions in a geometry.
|
* Support for time-varying vertex positions in a geometry.
|
||||||
* Add motion over time to instances, including scaling, shearing, rotation, and translation (SRT) and matrix motion, while keeping some static.
|
* Add motion over time to instances, including scaling, shearing, rotation, and translation (SRT) and matrix motion, while keeping some static.
|
||||||
|
|
||||||
Defining an animation works by defining the state of the scene at a start time, T0, and an end time, T1. For instance, T0 could be the start of a frame, and T1 could be the end of a frame, then rays can be traced at any intermediate time, such as at t=0.5, halfway through the frame, and motion blur can be done by choosing a random t for each ray.
|
The definition of an animation consists in defining the state of the scene at a start time, T0, and at an end time, T1. For example, T0 can be the beginning of a frame and T1 the end of a frame, then rays can be drawn at any intermediate time, for example at t=0.5, in the middle of the frame, and motion blur can be achieved through sampling, using a random t for each ray.
|
||||||
|
|
||||||
## Enabling Motion Blur
|
## Enabling Motion Blur
|
||||||
|
|
||||||
|
|
@ -32,7 +42,7 @@ In main.cpp, we add the device extension `VK_NV_ray_tracing_motion_blur` and ena
|
||||||
|
|
||||||
### Pipeline
|
### Pipeline
|
||||||
|
|
||||||
When creating the ray tracing pipeline, the VkRayTracingPipelineCreateInfoKHR struct's flags must include `VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV`.
|
When creating the ray tracing pipeline, the `flag` member of `VkRayTracingPipelineCreateInfoKHR` must include `VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV`.
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
rayPipelineInfo.flags = VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV;
|
rayPipelineInfo.flags = VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV;
|
||||||
|
|
@ -41,10 +51,9 @@ When creating the ray tracing pipeline, the VkRayTracingPipelineCreateInfoKHR st
|
||||||
### Scene Objects
|
### Scene Objects
|
||||||
|
|
||||||
We will use the following four models. The later sections will add matrix animation to two instances of the cube_multi.obj model,
|
We will use the following four models. The later sections will add matrix animation to two instances of the cube_multi.obj model,
|
||||||
and the plane.obj model will stay static. The third and fourth models are the keyframes for a vertex animation. Cube.obj is the
|
and the plane.obj model will remain static. The third and fourth models are the keyframes for a vertex animation. The cube.obj file represents the
|
||||||
cube at time 0 (T0), and cube_modif.obj is the cube at time 1 (T1).
|
cube at time 0 (T0), and cube_modif.obj is the cube at time 1 (T1).
|
||||||
|
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Creation of the example
|
// Creation of the example
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/cube_multi.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/cube_multi.obj", defaultSearchPaths, true));
|
||||||
|
|
@ -53,21 +62,18 @@ cube at time 0 (T0), and cube_modif.obj is the cube at time 1 (T1).
|
||||||
helloVk.loadModel(nvh::findFile("media/scenes/cube_modif.obj", defaultSearchPaths, true));
|
helloVk.loadModel(nvh::findFile("media/scenes/cube_modif.obj", defaultSearchPaths, true));
|
||||||
````
|
````
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Vertex Varying Motion
|
## Vertex Varying Motion
|
||||||
|
|
||||||
As seen in the picture, the vertices of the left green cube change positions over time.
|
As shown in the image, the positions of the vertices of the left green cube change over time.
|
||||||
We specify this by giving two geometries to the BLAS builder. Setting the geometry at T0
|
We specify this by giving two geometries to the BLAS builder. Setting the geometry at T0
|
||||||
is done the same way as before. To add the destination keyframe at T1, we make the
|
is done the same way as before. To add the destination keyframe at T1, we make the
|
||||||
`VkAccelerationStructureGeometryTrianglesDataKHR` structure's `pNext` field point to a
|
`VkAccelerationStructureGeometryTrianglesDataKHR` structure's `pNext` field point to a
|
||||||
`VkAccelerationStructureGeometryMotionTrianglesDataNV` structure. Additionally, we must add
|
`VkAccelerationStructureGeometryMotionTrianglesDataNV` structure. Additionally, we must add
|
||||||
`VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV` to the BLAS build info flags.
|
`VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV` to the BLAS build info flags.
|
||||||
|
|
||||||
|
At first we are adding the cube_multi and plane. The geometry of cube_multi is not animated
|
||||||
|
by itself, but the transformation matrix of its instance is, so we will set its animation
|
||||||
At first we are adding the cube_multi and plane. The cube_multi object's geometry doesn't animate,
|
in the TLAS in the Instance Motion section.
|
||||||
but its transformation does, so we will set its animation in the TLAS in the Instance Motion section.
|
|
||||||
|
|
||||||
````C
|
````C
|
||||||
void HelloVulkan::createBottomLevelAS()
|
void HelloVulkan::createBottomLevelAS()
|
||||||
|
|
@ -78,8 +84,7 @@ void HelloVulkan::createBottomLevelAS()
|
||||||
allBlas.emplace_back(objectToVkGeometryKHR(m_objModel[1]));
|
allBlas.emplace_back(objectToVkGeometryKHR(m_objModel[1]));
|
||||||
````
|
````
|
||||||
|
|
||||||
Then we add the cube and add the motion information; the reference to the geometry at T1 and the flag for which
|
We then add the cube along with its motion information, which contains a reference to the geometry at time T1 and the motion type flag. This flag indicates the vertices of the geometry are animated.
|
||||||
we want this object to have motion.
|
|
||||||
|
|
||||||
````C
|
````C
|
||||||
// Animated geometry
|
// Animated geometry
|
||||||
|
|
@ -93,7 +98,7 @@ we want this object to have motion.
|
||||||
allBlas[2].flags = VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV;
|
allBlas[2].flags = VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV;
|
||||||
````
|
````
|
||||||
|
|
||||||
Building all the BLAS stays the same.
|
Building all the BLAS remains the same.
|
||||||
|
|
||||||
````C
|
````C
|
||||||
|
|
||||||
|
|
@ -109,30 +114,42 @@ Instance motion describes motion in the TLAS, where objects move as a whole. The
|
||||||
* Matrix motion
|
* Matrix motion
|
||||||
* SRT motion
|
* SRT motion
|
||||||
|
|
||||||
The array of instances uses [`VkAccelerationStructureMotionInstanceNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureMotionInstanceNV.html) instead of `VkAccelerationStructureInstanceKHR`.
|
The instance array uses [`VkAccelerationStructureMotionInstanceNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureMotionInstanceNV.html) instead of `VkAccelerationStructureInstanceKHR`, but since we have a packed structure array, and the stride of the motion structure [must be 160 bytes](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureGeometryInstancesDataKHR.html), we create a new structure and derive from `VkAccelerationStructureMotionInstanceNV` and add the missing 8 padding bytes.
|
||||||
|
|
||||||
|
```` C
|
||||||
|
// VkAccelerationStructureMotionInstanceNV must have a stride of 160 bytes.
|
||||||
|
// See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureGeometryInstancesDataKHR.html
|
||||||
|
struct VkAccelerationStructureMotionInstanceNVPad : VkAccelerationStructureMotionInstanceNV
|
||||||
|
{
|
||||||
|
uint64_t _pad{0};
|
||||||
|
};
|
||||||
|
static_assert((sizeof(VkAccelerationStructureMotionInstanceNVPad) == 160));
|
||||||
|
````
|
||||||
|
|
||||||
|
All instances will be stored in the vector of `VkAccelerationStructureMotionInstanceNVPad`. The `ObjId` will be the index of the object this instance refers to.
|
||||||
|
|
||||||
````C
|
````C
|
||||||
std::vector<VkAccelerationStructureMotionInstanceNVPad> tlas;
|
uint32_t objId;
|
||||||
|
std::vector<VkAccelerationStructureMotionInstanceNVPad> tlas;
|
||||||
````
|
````
|
||||||
|
|
||||||
### Matrix Motion
|
### Matrix Motion
|
||||||
|
|
||||||
The moving matrix needs to fill the [`VkAccelerationStructureMatrixMotionInstanceNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureMatrixMotionInstanceNV.html) structure.
|
The motion matrix must fill the structure [`VkAccelerationStructureMatrixMotionInstanceNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureMatrixMotionInstanceNV.html). We use the transformation matrix stored in the instance for *time 0* and we set the *time 1* with a translation of 0.3 on the X axis.
|
||||||
|
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Cube (moving/matrix translation)
|
// Cube (moving/matrix translation)
|
||||||
objId = 0;
|
objId = 0;
|
||||||
{
|
{
|
||||||
// Position of the instance at T0 and T1
|
// Position of the instance at T0 and T1
|
||||||
nvmath::mat4f matT0(1); // Identity
|
nvmath::mat4f matT0 = m_instances[0].transform;
|
||||||
nvmath::mat4f matT1 = nvmath::translation_mat4(nvmath::vec3f(0.30f, 0.0f, 0.0f));
|
nvmath::mat4f matT1 = nvmath::translation_mat4(nvmath::vec3f(0.30f, 0.0f, 0.0f)) * matT0;
|
||||||
|
|
||||||
VkAccelerationStructureMatrixMotionInstanceNV data;
|
VkAccelerationStructureMatrixMotionInstanceNV data;
|
||||||
data.transformT0 = nvvk::toTransformMatrixKHR(matT0);
|
data.transformT0 = nvvk::toTransformMatrixKHR(matT0);
|
||||||
data.transformT1 = nvvk::toTransformMatrixKHR(matT1);
|
data.transformT1 = nvvk::toTransformMatrixKHR(matT1);
|
||||||
data.instanceCustomIndex = objId; // gl_InstanceCustomIndexEXT
|
data.instanceCustomIndex = objId; // gl_InstanceCustomIndexEXT
|
||||||
data.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(m_objInstance[objId].objIndex);
|
data.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(m_instances[objId].objIndex);
|
||||||
data.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
data.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||||
data.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
data.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
data.mask = 0xFF;
|
data.mask = 0xFF;
|
||||||
|
|
@ -145,8 +162,8 @@ The moving matrix needs to fill the [`VkAccelerationStructureMatrixMotionInstanc
|
||||||
|
|
||||||
### SRT Motion
|
### SRT Motion
|
||||||
|
|
||||||
The SRT motion uses the [`VkAccelerationStructureSRTMotionInstanceNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureSRTMotionInstanceNV.html)
|
The SRT motion uses the structure [`VkAccelerationStructureSRTMotionInstanceNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureSRTMotionInstanceNV.html)
|
||||||
structure, where it interpolates between two [`VkSRTDataNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSRTDataNV.html) structures.
|
where it interpolates between two structures [`VkSRTDataNV`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSRTDataNV.html). In this case, we start with the object translated to [2, 0, 0] and apply a rotation for *time 1*.
|
||||||
|
|
||||||
````C
|
````C
|
||||||
// Cube (moving/SRT rotation)
|
// Cube (moving/SRT rotation)
|
||||||
|
|
@ -188,18 +205,20 @@ structure, where it interpolates between two [`VkSRTDataNV`](https://www.khronos
|
||||||
|
|
||||||
### Static
|
### Static
|
||||||
|
|
||||||
Static instances use the same structure as we normally use with static scenes, `VkAccelerationStructureInstanceKHR`.
|
Static instances use the same structure as we normally use with static scenes, `VkAccelerationStructureInstanceKHR`. Static objects are not moving, but they can be deformed, as it is with the cube.
|
||||||
|
|
||||||
|
First the plane is not moving at all
|
||||||
|
|
||||||
```` C
|
```` C
|
||||||
// Plane (static)
|
// Plane (static)
|
||||||
objId = 1;
|
objId = 1;
|
||||||
{
|
{
|
||||||
nvmath::mat4f matT0 = nvmath::translation_mat4(nvmath::vec3f(0, -1, 0));
|
nvmath::mat4f matT0 = m_instances[1].transform;
|
||||||
|
|
||||||
VkAccelerationStructureInstanceKHR data{};
|
VkAccelerationStructureInstanceKHR data{};
|
||||||
data.transform = nvvk::toTransformMatrixKHR(matT0); // Position of the instance
|
data.transform = nvvk::toTransformMatrixKHR(matT0); // Position of the instance
|
||||||
data.instanceCustomIndex = objId; // gl_InstanceCustomIndexEXT
|
data.instanceCustomIndex = objId; // gl_InstanceCustomIndexEXT
|
||||||
data.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(m_objInstance[objId].objIndex);
|
data.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(m_instances[objId].objIndex);
|
||||||
data.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
data.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||||
data.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
data.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
data.mask = 0xFF;
|
data.mask = 0xFF;
|
||||||
|
|
@ -210,9 +229,31 @@ Static instances use the same structure as we normally use with static scenes, `
|
||||||
}
|
}
|
||||||
````
|
````
|
||||||
|
|
||||||
### Building
|
Second the deformed cube is not moving, only its geometry. This was done when setting the BLAS.
|
||||||
|
|
||||||
The building call is similar, only the flag is changing.
|
```` C
|
||||||
|
// Cube+Cubemodif (static)
|
||||||
|
objId = 2;
|
||||||
|
{
|
||||||
|
nvmath::mat4f matT0 = m_instances[2].transform;
|
||||||
|
|
||||||
|
VkAccelerationStructureInstanceKHR data{};
|
||||||
|
data.transform = nvvk::toTransformMatrixKHR(matT0); // Position of the instance
|
||||||
|
data.instanceCustomIndex = objId; // gl_InstanceCustomIndexEXT
|
||||||
|
data.accelerationStructureReference = m_rtBuilder.getBlasDeviceAddress(m_instances[objId].objIndex);
|
||||||
|
data.instanceShaderBindingTableRecordOffset = 0; // We will use the same hit group for all objects
|
||||||
|
data.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||||
|
data.mask = 0xFF;
|
||||||
|
VkAccelerationStructureMotionInstanceNVPad rayInst;
|
||||||
|
rayInst.type = VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_STATIC_NV;
|
||||||
|
rayInst.data.staticInstance = data;
|
||||||
|
tlas.emplace_back(rayInst);
|
||||||
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
The building call for the TLAS is similar, only the flag for motion is changing to true.
|
||||||
|
|
||||||
````C
|
````C
|
||||||
m_rtBuilder.buildTlas(tlas, VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV, false, true);
|
m_rtBuilder.buildTlas(tlas, VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV, false, true);
|
||||||
|
|
@ -226,7 +267,7 @@ In the shader, we enable the `GL_NV_ray_tracing_motion_blur` extension.
|
||||||
#extension GL_NV_ray_tracing_motion_blur : require
|
#extension GL_NV_ray_tracing_motion_blur : require
|
||||||
````
|
````
|
||||||
|
|
||||||
Then we call `traceRayMotionNV` instead of `traceRayEXT`. The `time` argument varies between 0 and 1.
|
Then we call `traceRayMotionNV` instead of `traceRayEXT`. The `time` argument must vary between 0 and 1 for each call.
|
||||||
|
|
||||||
````C
|
````C
|
||||||
traceRayMotionNV(topLevelAS, // acceleration structure
|
traceRayMotionNV(topLevelAS, // acceleration structure
|
||||||
|
|
@ -244,17 +285,13 @@ Then we call `traceRayMotionNV` instead of `traceRayEXT`. The `time` argument va
|
||||||
);
|
);
|
||||||
````
|
````
|
||||||
|
|
||||||
|
|
||||||
## Other
|
|
||||||
|
|
||||||
We have used some technique from the [jitter cam](../ray_tracing_jitter_cam) to sampling time randomly.
|
We have used some technique from the [jitter cam](../ray_tracing_jitter_cam) to sampling time randomly.
|
||||||
Using random time value for each pixel at each frame gives a nicer look when accumulated over time then using a single time per frame.
|
Using random time value for each pixel at each frame gives a nicer look when accumulated over time than using a single time per frame.
|
||||||
|
|
||||||
|
If we were using constant time instead, the image would have a [stuttered motion](https://en.wikipedia.org/wiki/Rotary_disc_shutter) look, like this:
|
||||||
|
|
||||||
This is the how stuttered motion would look like.
|
|
||||||

|

|
||||||
https://en.wikipedia.org/wiki/Rotary_disc_shutter
|
|
||||||
|
|
||||||
|
:warning: Using motion blur pipeline with all instances static will be slower than using the static pipeline. The performance hit is minor, but optimized applications should use motion blur only where necessary.
|
||||||
:warning: Using motion blur pipeline with all instances static will be slower than using the static pipeline. Not by much but for performance, it's better to use the appropriate pipeline.
|
|
||||||
|
|
||||||
:warning: Calling `traceRayEXT` from `raytrace.rchit` works, and we get motion-blurred shadows without having to call `traceRayMotionNV` in the closest-hit shader. This works only if `traceRayEXT` is called within the execution of a motion trace call.
|
:warning: Calling `traceRayEXT` from `raytrace.rchit` works, and we get motion-blurred shadows without having to call `traceRayMotionNV` in the closest-hit shader. This works only if `traceRayEXT` is called within the execution of a motion trace call.
|
||||||
|
|
@ -663,13 +663,18 @@ void HelloVulkan::createBottomLevelAS()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
void HelloVulkan::createTopLevelAS()
|
void HelloVulkan::createTopLevelAS()
|
||||||
{
|
{
|
||||||
// This is to fix a padding issue 2021.08.13
|
// VkAccelerationStructureMotionInstanceNV must have a stride of 160 bytes.
|
||||||
|
// See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAccelerationStructureGeometryInstancesDataKHR.html
|
||||||
struct VkAccelerationStructureMotionInstanceNVPad : VkAccelerationStructureMotionInstanceNV
|
struct VkAccelerationStructureMotionInstanceNVPad : VkAccelerationStructureMotionInstanceNV
|
||||||
{
|
{
|
||||||
short _pad;
|
uint64_t _pad{0};
|
||||||
};
|
};
|
||||||
|
static_assert((sizeof(VkAccelerationStructureMotionInstanceNVPad) == 160));
|
||||||
|
|
||||||
// #NV_Motion_blur
|
// #NV_Motion_blur
|
||||||
uint32_t objId;
|
uint32_t objId;
|
||||||
|
|
@ -679,7 +684,7 @@ void HelloVulkan::createTopLevelAS()
|
||||||
objId = 0;
|
objId = 0;
|
||||||
{
|
{
|
||||||
// Position of the instance at T0 and T1
|
// Position of the instance at T0 and T1
|
||||||
nvmath::mat4f matT0 = m_instances[0].transform; // Identity
|
nvmath::mat4f matT0 = m_instances[0].transform;
|
||||||
nvmath::mat4f matT1 = nvmath::translation_mat4(nvmath::vec3f(0.30f, 0.0f, 0.0f)) * matT0;
|
nvmath::mat4f matT1 = nvmath::translation_mat4(nvmath::vec3f(0.30f, 0.0f, 0.0f)) * matT0;
|
||||||
|
|
||||||
VkAccelerationStructureMatrixMotionInstanceNV data;
|
VkAccelerationStructureMatrixMotionInstanceNV data;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue