Skip to content

Commit 2e2aeec

Browse files
gpx1000JoseEmilio-ARM
authored andcommitted
Ray tracing siggraph25 (#4)
Moved 18_Ray_tracing.adoc to courses/18_Ray_tracing folder and broke it up into subsections. Did a few minor edits to address flow. The courses folder should make it easier to create courseware content in the future and provide attribution easily via a README file.
1 parent fb2364c commit 2e2aeec

12 files changed

+1390
-1303
lines changed

antora/modules/ROOT/nav.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,13 @@
5252
* xref:15_GLTF_KTX2_Migration.adoc[Migrating to Modern Asset Formats: glTF and KTX2]
5353
* xref:16_Multiple_Objects.adoc[Rendering Multiple Objects]
5454
* xref:17_Multithreading.adoc[Multithreading]
55+
* xref:courses/18_Ray_tracing/00_Overview.adoc[Ray Tracing]
56+
** xref:courses/18_Ray_tracing/00_Overview.adoc[Overview]
57+
** xref:courses/18_Ray_tracing/01_Dynamic_rendering.adoc[Dynamic rendering]
58+
** xref:courses/18_Ray_tracing/02_Acceleration_structures.adoc[Acceleration structures]
59+
** xref:courses/18_Ray_tracing/03_Ray_query_shadows.adoc[Ray query shadows]
60+
** xref:courses/18_Ray_tracing/04_TLAS_animation.adoc[TLAS animation]
61+
** xref:courses/18_Ray_tracing/05_Shadow_transparency.adoc[Shadow transparency]
62+
** xref:courses/18_Ray_tracing/06_Reflections.adoc[Reflections]
63+
** xref:courses/18_Ray_tracing/07_Conclusion.adoc[Conclusion]
5564
* xref:90_FAQ.adoc[FAQ]

en/18_Ray_tracing.adoc

Lines changed: 1 addition & 1303 deletions
Large diffs are not rendered by default.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
== SIGGRAPH 2025: Hands-on Vulkan Ray Tracing with Dynamic Rendering
2+
3+
=== Overview
4+
5+
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.
6+
7+
Slides available link:Vulkan%20Ray%20Tracing%20With%20Dynamic%20Rendering.pdf[here].
8+
9+
By the end, you'll learn how to:
10+
11+
- Use Vulkan *dynamic rendering* (no pre-defined render passes) and verify it with *RenderDoc*.
12+
- Create bottom-level and top-level *Acceleration Structures* (BLAS and TLAS) for ray tracing.
13+
- Implement ray query based *shadow rays* (first with all-opaque geometry, then with alpha-test *transparency*).
14+
- Debug/inspect the acceleration structures in *Nsight Graphics*.
15+
- (Bonus) Implement ray query based *reflections*.
16+
17+
*Prerequisites*:
18+
This series targets intermediate Vulkan programmers. We assume you have completed the basic Vulkan Tutorial (graphics pipeline, descriptor sets, etc.). If not, you can still follow along conceptually. A Windows machine with up-to-date Vulkan SDK (1.4.311), a GPU supporting ray tracing (Vulkan Ray Query), plus RenderDoc and Nsight Graphics is provided.
19+
20+
*Mobile Best-Practice Notes*:
21+
22+
- We use `VK_KHR_dynamic_rendering` (core in Vulkan 1.3) instead of traditional render passes. This not only simplifies the API but also, with the `VK_KHR_dynamic_rendering_local_read` extension, enables tile-local storage reads similar to subpasses, a big deal for mobile tile-based GPUs to save bandwidth.
23+
- We use Ray Queries (from `VK_KHR_ray_query`) within fragment shaders instead of a separate ray tracing pipeline. On mobile, ray queries are far more widely supported and often (depending on the use case) more efficient than the full ray tracing pipeline. Ray queries integrate nicely into fragment shading, benefiting from on-chip compression and avoiding context switches.
24+
25+
*Provided Code*:
26+
The provided code is a Vulkan renderer that already implements a basic graphics pipeline with dynamic rendering. It is based on the Vulkan Tutorial and it is self-contained in a single C++ source file and a Slang shader file:
27+
28+
- link:../../../attachments/38_ray_tracing.cpp[38_ray_tracing.cpp]
29+
- link:../../../attachments/38_ray_tracing.slang[38_ray_tracing.slang]
30+
- If you get stuck on shader tasks, you can refer to the provided reference solution: link:../../../attachments/38_ray_tracing_complete.slang[38_ray_tracing_complete.slang]
31+
32+
The source code is structured to guide you through the steps, with hints and boilerplate provided. It also sets up all the required extensions and features, including `VK_KHR_acceleration_structure` and `VK_KHR_ray_query`.
33+
You will find sections of code marked with `// TASKxx` which we reference in each chapter.
34+
35+
At the top of the C++ file, note the following variable:
36+
37+
[,c{pp}]
38+
----
39+
#define LAB_TASK_LEVEL 1
40+
----
41+
42+
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.
43+
44+
=== Chapters in this series
45+
46+
- link:00_Overview.adoc[Overview]
47+
- link:01_Dynamic_rendering.adoc[Dynamic rendering]
48+
- link:02_Acceleration_structures.adoc[Acceleration structures]
49+
- link:03_Ray_query_shadows.adoc[Ray query shadows]
50+
- link:04_TLAS_animation.adoc[TLAS animation]
51+
- link:05_Shadow_transparency.adoc[Shadow transparency]
52+
- link:06_Reflections.adoc[Reflections]
53+
- link:07_Conclusion.adoc[Conclusion]
54+
55+
=== Build and run
56+
57+
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:
58+
59+
[,shell]
60+
----
61+
cmake --build build --target 38_ray_tracing --parallel; start .\build\38_ray_tracing\Debug\38_ray_tracing.exe -wo .\build\38_ray_tracing\
62+
----
63+
64+
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.
65+
66+
=== Navigation
67+
- Next: link:01_Dynamic_rendering.adoc[Dynamic rendering]
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
== Dynamic Rendering
2+
3+
*Objective*: Ensure the base project uses *dynamic rendering* and understand how to verify it using RenderDoc.
4+
5+
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.
6+
7+
=== Task 1: Check the setup for dynamic rendering
8+
9+
In the provided code base, locate the initialization of the graphics pipeline:
10+
11+
[,c{pp}]
12+
----
13+
/* TASK01: Check the setup for dynamic rendering
14+
*
15+
* This new struct replaces what previously was the render pass in the pipeline creation.
16+
* Note how this structure is now linked in .pNext below, and .renderPass is not used.
17+
*/
18+
vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{
19+
.colorAttachmentCount = 1,
20+
.pColorAttachmentFormats = &swapChainImageFormat,
21+
.depthAttachmentFormat = depthFormat
22+
};
23+
24+
vk::GraphicsPipelineCreateInfo pipelineInfo{
25+
.pNext = &pipelineRenderingCreateInfo,
26+
.stageCount = 2,
27+
.pStages = shaderStages,
28+
.pVertexInputState = &vertexInputInfo,
29+
.pInputAssemblyState = &inputAssembly,
30+
.pViewportState = &viewportState,
31+
.pRasterizationState = &rasterizer,
32+
.pMultisampleState = &multisampling,
33+
.pDepthStencilState = &depthStencil,
34+
.pColorBlendState = &colorBlending,
35+
.pDynamicState = &dynamicState,
36+
.layout = pipelineLayout,
37+
.renderPass = nullptr
38+
};
39+
40+
graphicsPipeline = vk::raii::Pipeline(device, nullptr, pipelineInfo);
41+
----
42+
43+
And later on, the command buffer recording where we begin rendering:
44+
45+
[,c{pp}]
46+
----
47+
/* TASK01: Check the setup for dynamic rendering
48+
*
49+
* With dynamic rendering, we specify the image view and load/store operations directly
50+
* in the vk::RenderingAttachmentInfo structure.
51+
* This approach eliminates the need for explicit render pass and framebuffer objects,
52+
* simplifying the code and providing flexibility to change attachments at runtime.
53+
*/
54+
55+
vk::RenderingAttachmentInfo colorAttachmentInfo = {
56+
.imageView = swapChainImageViews[imageIndex],
57+
.imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
58+
.loadOp = vk::AttachmentLoadOp::eClear,
59+
.storeOp = vk::AttachmentStoreOp::eStore,
60+
.clearValue = clearColor
61+
};
62+
63+
vk::RenderingAttachmentInfo depthAttachmentInfo = {
64+
.imageView = depthImageView,
65+
.imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal,
66+
.loadOp = vk::AttachmentLoadOp::eClear,
67+
.storeOp = vk::AttachmentStoreOp::eDontCare,
68+
.clearValue = clearDepth
69+
};
70+
71+
// The vk::RenderingInfo structure combines these attachments with other rendering parameters.
72+
vk::RenderingInfo renderingInfo = {
73+
.renderArea = { .offset = { 0, 0 }, .extent = swapChainExtent },
74+
.layerCount = 1,
75+
.colorAttachmentCount = 1,
76+
.pColorAttachments = &colorAttachmentInfo,
77+
.pDepthAttachment = &depthAttachmentInfo
78+
};
79+
80+
// Note: .beginRendering replaces the previous .beginRenderPass call.
81+
commandBuffers[currentFrame].beginRendering(renderingInfo);
82+
----
83+
84+
For more context, refer to the previous tutorial link:../../03_Drawing_a_triangle/02_Graphics_pipeline_basics/03_Render_passes.adoc[chapter].
85+
86+
==== Dynamic rendering with RenderDoc
87+
88+
Use RenderDoc to launch the application and capture a frame:
89+
90+
. Specify executable path: `Vulkan-Tutorial\attachments\build\38_ray_tracing\Debug\38_ray_tracing.exe`.
91+
. Specify working directory: `Vulkan-Tutorial\attachments\build\38_ray_tracing`.
92+
. Launch the application.
93+
94+
image::../../../images/38_TASK01_renderdoc_launch.png[]
95+
96+
In the Event Browser, you should see the calls that confirm that dynamic rendering is set up correctly:
97+
98+
. `vkCmdBeginRenderingKHR` and `vkCmdEndRenderingKHR`.
99+
. `VkRenderingInfoKHR` replacing the old render pass/framebuffer concept.
100+
. Color (and depth) attachments set via `VkRenderingAttachmentInfo`.
101+
102+
image::../../../images/38_TASK01_renderdoc_events.png[]
103+
104+
In RenderDoc's Texture Viewer, you can inspect the color and depth attachments at various points:
105+
106+
image::../../../images/38_TASK01_renderdoc_color.gif[]
107+
108+
NOTE: Dynamic rendering reduces CPU overhead and, with the `VK_KHR_dynamic_rendering_local_read` extension, lets you do subpass-style tile-local reads without full render passes. This is great for techniques like deferred shading on tilers, where reading from a previous pass's attachment can be done on-tile without extra memory bandwidth. While we won't implement a deferred renderer here, be aware of this benefit for mobile.
109+
110+
After this step, you should be comfortable that dynamic rendering is set up correctly. We can now move on to ray tracing features.
111+
112+
=== Navigation
113+
- Previous: link:00_Overview.adoc[Overview]
114+
- Next: link:02_Acceleration_structures.adoc[Acceleration structures]

0 commit comments

Comments
 (0)