Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions en/courses/18_Ray_tracing/00_Overview.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
== SIGGRAPH 2025: Hands-on Vulkan Ray Tracing with Dynamic Rendering
= SIGGRAPH 2025: Hands-on Vulkan Ray Tracing with Dynamic Rendering

=== Overview
== Overview

Welcome! In this series, we enhance a Vulkan renderer with ray tracing features to implement real-time pixel-perfect shadows (with and without transparency) and a bonus reflection effect. You will work with provided scaffolded code (based on the Vulkan Tutorial) and fill in key shader functions following step-by-step instructions.

Expand Down Expand Up @@ -41,7 +41,7 @@ At the top of the C++ file, note the following variable:

At certain intervals, you will be instructed to update this variable and re-build to verify the effect of key changes, no need to write new code.

=== Chapters in this series
== Chapters in this series

- xref:./00_Overview.adoc[Overview]
- xref:./01_Dynamic_rendering.adoc[Dynamic rendering]
Expand All @@ -52,7 +52,7 @@ At certain intervals, you will be instructed to update this variable and re-buil
- xref:./06_Reflections.adoc[Reflections]
- xref:./07_Conclusion.adoc[Conclusion]

=== Build and run
== Build and run

You can build and run the provided sample either from Visual Studio (set 38_ray_tracing as the start-up project) or via command line:

Expand All @@ -63,5 +63,5 @@ cmake --build build --target 38_ray_tracing --parallel; start .\build\38_ray_tra

Note that the above hasn't changed from the base tutorial, and you may continue to build on other platforms as you have for the rest of the tutorial.

=== Navigation
== Navigation
- Next: xref:./01_Dynamic_rendering.adoc[Dynamic rendering]
8 changes: 4 additions & 4 deletions en/courses/18_Ray_tracing/01_Dynamic_rendering.adoc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
== Dynamic Rendering
= Dynamic Rendering

*Objective*: Ensure the base project uses *dynamic rendering* and understand how to verify it using RenderDoc.

In dynamic rendering, we no longer create a VkRenderPass or VkFrameBuffer; instead we begin rendering with `vkCmdBeginRenderingKHR`, specifying attachments on-the-fly. This makes our code more flexible (no need to predeclare subpasses) and is now the "modern" way to render in Vulkan.

=== Task 1: Check the setup for dynamic rendering
== Task 1: Check the setup for dynamic rendering

In the provided code base, locate the initialization of the graphics pipeline:

Expand Down Expand Up @@ -83,7 +83,7 @@ commandBuffers[currentFrame].beginRendering(renderingInfo);

For more context, refer to the previous tutorial link:../../03_Drawing_a_triangle/02_Graphics_pipeline_basics/03_Render_passes.adoc[chapter].

==== Dynamic rendering with RenderDoc
=== Dynamic rendering with RenderDoc

Use RenderDoc to launch the application and capture a frame:

Expand All @@ -109,6 +109,6 @@ NOTE: Dynamic rendering reduces CPU overhead and, with the `VK_KHR_dynamic_rende

After this step, you should be comfortable that dynamic rendering is set up correctly. We can now move on to ray tracing features.

=== Navigation
== Navigation
- Previous: xref:./00_Overview.adoc[Overview]
- Next: xref:./02_Acceleration_structures.adoc[Acceleration structures]
10 changes: 5 additions & 5 deletions en/courses/18_Ray_tracing/02_Acceleration_structures.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
== Acceleration Structures (BLAS/TLAS)
= Acceleration Structures (BLAS/TLAS)

*Objective*: Create *Bottom-Level Acceleration Structures* (BLAS) for the model's geometry, and a *Top-Level Acceleration Structure* (TLAS) to instance those BLASes.
Bind the TLAS to the shader so we can use Ray Queries.
Expand All @@ -17,7 +17,7 @@ We'll create one BLAS per distinct mesh/material and one TLAS that references th
The ray query will use the TLAS.
In Vulkan, building an AS involves a few steps: describe geometry, query build sizes, allocate buffers, create the AS handle, then issue a build command.

=== Task 2: Create a BLAS for each submesh
== Task 2: Create a BLAS for each submesh

Go to the definition of `createAccelerationStructures`. Here we will first create the BLASes for each submesh in the model. The code already has a loop iterating over `submeshes`, which contains the geometry data.

Expand Down Expand Up @@ -125,7 +125,7 @@ image::../../../images/38_TASK02_blas_build.png[]

Now you have a BLAS for each model in the scene. Next we need to put them all together into a single TLAS which will then be consumed by our fragment shader.

=== Task 3: Create a TLAS with instances of the BLASes
== Task 3: Create a TLAS with instances of the BLASes

Now that we have the BLASes, we need to create a TLAS that references them. The TLAS will hold instances of the BLASes, allowing us to place them in the scene with transformations (position, rotation, scale).

Expand Down Expand Up @@ -239,7 +239,7 @@ endSingleTimeCommands(*cmd);

Done! You have now created a TLAS that references all the BLASes for the submeshes in the model. The TLAS is ready to be used in ray queries in the fragment shader.

=== Task 4: Bind the acceleration structure to the shader
== Task 4: Bind the acceleration structure to the shader

To make the acceleration structure available in the shader, we need to add a descriptor set binding for the TLAS. This is done in the `createDescriptorSetLayout()` function (you may ignore the higher bindings for now):

Expand Down Expand Up @@ -301,6 +301,6 @@ Re-build and run using:

You will see no visual difference, but rest assured, your Acceleration Structures are now set up and ready to be used in the fragment shader.

=== Navigation
== Navigation
- Previous: xref:./01_Dynamic_rendering.adoc[Dynamic rendering]
- Next: xref:./03_Ray_query_shadows.adoc[Ray query shadows]
6 changes: 3 additions & 3 deletions en/courses/18_Ray_tracing/03_Ray_query_shadows.adoc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
== Ray Query Shadows (Opaque Geometry)
= Ray Query Shadows (Opaque Geometry)

*Objective*: Add a simple shadow test in the fragment shader using a ray query. We will cast a ray from each fragment point toward the light and darken the fragment if something is hit (hard shadow).

Congratulations: you have a valid TLAS/BLAS for the scene! Now, let's use it to cast some rays.

=== Task 5: Implement ray query shadows
== Task 5: Implement ray query shadows

In the fragment shader, we will use a ray query to cast a shadow ray from the fragment position towards the light source. If the ray hits any geometry before reaching the light, we will darken the fragment color:

Expand Down Expand Up @@ -102,6 +102,6 @@ image::../../../images/38_TASK06_shadows_static.gif[]

The object is rotating, but the shadows are static. This is because we have not yet updated the TLAS to account for the object's animation. The TLAS needs to be rebuilt whenever the object moves or animates, so let's implement that next.

=== Navigation
== Navigation
- Previous: xref:./02_Acceleration_structures.adoc[Acceleration structures]
- Next: xref:./04_TLAS_animation.adoc[TLAS animation]
6 changes: 3 additions & 3 deletions en/courses/18_Ray_tracing/04_TLAS_animation.adoc
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
== TLAS Animation
= TLAS Animation

*Objective*: Ensure shadows update when the object animates by rebuilding the TLAS with updated instance transforms each frame.

To account for the object's animation, we need to update the TLAS whenever the object moves or changes.
This involves updating the instance transforms and rebuilding the TLAS.
We will do this in the `updateTopLevelAS()` function, which is called every frame with the current model matrix.

=== Task 6: Update the TLAS for animations
== Task 6: Update the TLAS for animations

First we need to update the instance transforms with the current model matrix. This is done by iterating over the `instances` vector and setting the transform for each instance, then update the instances buffer.

Expand Down Expand Up @@ -277,6 +277,6 @@ float4 fragMain(VSOutput vertIn) : SV_TARGET {

NOTE: Ray Query vs Ray Tracing Pipeline: Notice how we added a ray tracing effect (shadows) directly in the fragment shader. We did not need a separate ray generation shader or any new pipeline. This is the power of ray queries (also known as inline ray tracing): we integrate ray traversal into our existing rendering pipeline. This keeps the shader logic unified and avoids extra GPU shader launches. On many mobile GPUs, this approach is not only more convenient but necessary: as mentioned, current mobile devices mostly support ray queries and not the full ray pipeline, and they run ray queries efficiently in fragment shaders. This is a key reason we focus on ray queries in this lab.

=== Navigation
== Navigation
- Previous: xref:./03_Ray_query_shadows.adoc[Ray query shadows]
- Next: xref:./05_Shadow_transparency.adoc[Shadow transparency]
12 changes: 6 additions & 6 deletions en/courses/18_Ray_tracing/05_Shadow_transparency.adoc
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
== Implementing Transparency in Shadows
= Implementing Transparency in Shadows

*Objective*: Add support for transparent objects in the scene. We will implement a simple alpha test to discard fragments with low alpha values, and replicate this in their corresponding ray traced shadows.

So far we have treated every geometry as opaque. Note however that the leaves are rendered with a texture that uses the alpha channel to define transparency, and currently that is not taken into account, so that we have some dark pixels around the edges of the leaves:

image::../../../images/38_TASK08_alphacut_before.png[]

=== Task 7: Alpha-cut transparency
== Task 7: Alpha-cut transparency

To implement alpha-cut transparency, we will discard fragments with low alpha values in the fragment shader. This is a common technique to handle transparent textures without needing complex blending or sorting:

Expand Down Expand Up @@ -43,7 +43,7 @@ You will see that the shadows for the leaves are now completely missing! This is

Before we do that, let's first inspect the acceleration structures we have built so far, to understand how they are structured and what information is available for each triangle.

=== Task 8: Inspect the acceleration structures with NVIDIA Nsight Graphics
== Task 8: Inspect the acceleration structures with NVIDIA Nsight Graphics

RenderDoc does not yet support inspecting Vulkan acceleration structures, but we can use *Nsight Graphics* to verify that our BLAS/TLAS are built correctly. This helps catch mistakes (e.g. wrong geometry counts, offsets) before we rely on them in shaders.

Expand Down Expand Up @@ -79,7 +79,7 @@ In the new window, you can see the TLAS and its instances:

image::../../../images/38_TASK04_nsight_inspector.png[]

=== Task 9: Bindless resources and instance look-up table
== Task 9: Bindless resources and instance look-up table

Until now, we did not need to know what triangle our ray intersected, we only cared about whether it hit something or not. But to implement transparency, we need to know the alpha value of the texture used to shade the point on the triangle we hit. This way we can determine if we hit a transparent pixel and we need to continue the traversal, in case we hit some other opaque triangle behind it on the way towards the light.

Expand Down Expand Up @@ -169,7 +169,7 @@ StructuredBuffer<InstanceLUT> instanceLUTBuffer;

Now we will see how we can use these resources with ray query to handle transparent intersections.

=== Task 10: Ray query with alpha test
== Task 10: Ray query with alpha test

Remember how `Proceed()` advances the state of the `RayQuery` object to the next intersection candidate along the ray? This is where we will implement our alpha test logic. We will check the alpha value of the texture used for shading the triangle we hit, and if it is below a certain threshold, we will continue the traversal to find the next opaque triangle. Once we find it, we 'commit' it, and the traversal will end.

Expand Down Expand Up @@ -278,7 +278,7 @@ image::../../../images/38_TASK10_alphacut_shadows.png[]

With everything set in place to support transparency in shadows, implementing other effects like reflections is very straightforward!

=== Navigation
== Navigation
- Previous: xref:./04_TLAS_animation.adoc[TLAS animation]
- Next: xref:./06_Reflections.adoc[Reflections]

Expand Down
6 changes: 3 additions & 3 deletions en/courses/18_Ray_tracing/06_Reflections.adoc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
== Ray Query Reflections
= Ray Query Reflections

*Objective*: We will cast a ray in the mirror-reflection direction from the fragment to see what it hits, simulating reflective materials (like a mirror or shiny surface).

Reflections are implemented similarly to shadow rays, but we cast a ray from the shaded point along the mirror direction and sample the hit surface color.

=== Task 11: Implement ray query reflections
== Task 11: Implement ray query reflections

First, we will use push constants to pass the reflective material flag to the fragment shader. This will allow us to determine if the current material is reflective or not.

Expand Down Expand Up @@ -158,6 +158,6 @@ With all this in place, you should now see some shiny reflections on the table:
image::../../../images/38_TASK11_alphacut_reflections.png[]


=== Navigation
== Navigation
- Previous: xref:./05_Shadow_transparency.adoc[Shadow transparency]
- Next: xref:./07_Conclusion.adoc[Conclusion]
6 changes: 3 additions & 3 deletions en/courses/18_Ray_tracing/07_Conclusion.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
== Conclusion
= Conclusion

In this course, you've implemented ray traced effects into a Vulkan rasterization pipeline using dynamic rendering and ray queries. Let's summarize the key points:

Expand All @@ -12,7 +12,7 @@ In this course, you've implemented ray traced effects into a Vulkan rasterizatio

We hope this lab gave you a hands-on taste of hybrid rendering with Vulkan's latest features. Happy rendering with Vulkan, and enjoy creating more advanced ray traced effects in your applications!

=== References
== References

- Complete the full Vulkan Tutorial at https://github.com/KhronosGroup/Vulkan-Tutorial
- Find more Vulkan documentation and resources at https://www.khronos.org/vulkan
Expand All @@ -27,5 +27,5 @@ The 3D assets were provided by Poly Haven and combined using Blender:
- https://polyhaven.com/a/potted_plant_02
- https://polyhaven.com/a/wooden_picnic_table

=== Navigation
== Navigation
- Previous: xref:./06_Reflections.adoc[Reflections]
Loading