Convert Figma logo to code with AI

nvpro-samples logovk_raytracing_tutorial_KHR

Ray tracing examples and tutorials using VK_KHR_ray_tracing

1,353
143
1,353
4

Top Related Projects

One stop solution for all Vulkan samples

10,285

C++ examples for the Vulkan graphics API

A beginner-friendly Vulkan path tracing tutorial in under 300 lines of C++.

17,590

Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WebGL2

Quick Overview

The nvpro-samples/vk_raytracing_tutorial_KHR repository is a comprehensive tutorial for implementing ray tracing using Vulkan and the KHR ray tracing extension. It provides step-by-step guidance on setting up a ray tracing pipeline, creating acceleration structures, and implementing various ray tracing techniques in Vulkan.

Pros

  • Detailed, step-by-step tutorial for learning Vulkan ray tracing
  • Includes practical examples and explanations for each concept
  • Covers advanced topics like multi-level acceleration structures and denoising
  • Regularly updated to incorporate the latest Vulkan ray tracing features

Cons

  • Requires a solid understanding of Vulkan and graphics programming
  • May be overwhelming for beginners due to the complexity of ray tracing concepts
  • Limited to Vulkan-specific implementation, not applicable to other graphics APIs
  • Requires compatible hardware with ray tracing support

Code Examples

  1. Creating a ray tracing pipeline:
void HelloVulkan::createRtPipeline()
{
  vk::ShaderModule raygenSM = nvvk::createShaderModule(m_device, nvh::loadFile("spv/raygen.rgen.spv", true, defaultSearchPaths, true));
  vk::ShaderModule missSM = nvvk::createShaderModule(m_device, nvh::loadFile("spv/miss.rmiss.spv", true, defaultSearchPaths, true));

  std::vector<vk::PipelineShaderStageCreateInfo> stages;
  stages.push_back({{}, vk::ShaderStageFlagBits::eRaygenKHR, raygenSM, "main"});
  stages.push_back({{}, vk::ShaderStageFlagBits::eMissKHR, missSM, "main"});

  vk::RayTracingPipelineCreateInfoKHR rayPipelineInfo;
  rayPipelineInfo.setStages(stages);
  // ... (set other pipeline properties)

  m_rtPipeline = m_device.createRayTracingPipelineKHR({}, {}, rayPipelineInfo).value;
}
  1. Building an acceleration structure:
void HelloVulkan::buildAccelerationStructures()
{
  // Bottom-level acceleration structure
  vk::AccelerationStructureGeometryKHR asGeom;
  asGeom.setGeometryType(vk::GeometryTypeKHR::eTriangles);
  asGeom.geometry.triangles.setVertexFormat(vk::Format::eR32G32B32Sfloat);
  asGeom.geometry.triangles.setVertexData(m_vertexBuffer.buffer);
  asGeom.geometry.triangles.setIndexType(vk::IndexType::eUint32);
  asGeom.geometry.triangles.setIndexData(m_indexBuffer.buffer);

  vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo;
  asBuildInfo.setType(vk::AccelerationStructureTypeKHR::eBottomLevel);
  asBuildInfo.setFlags(vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
  asBuildInfo.setGeometries(asGeom);

  // ... (build acceleration structure)
}
  1. Tracing rays:
void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf)
{
  cmdBuf.bindPipeline(vk::PipelineBindPoint::eRayTracingKHR, m_rtPipeline);
  cmdBuf.bindDescriptorSets(vk::PipelineBindPoint::eRayTracingKHR, m_rtPipelineLayout, 0, {m_rtDescSet}, {});

  vk::DeviceSize rayGenOffset = 0;
  cmdBuf.traceRaysKHR(&m_rgenRegion, &m_missRegion, &

Competitor Comparisons

One stop solution for all Vulkan samples

Pros of Vulkan-Samples

  • Comprehensive collection of Vulkan samples covering various aspects of the API
  • Regularly updated with new features and best practices
  • Well-documented and maintained by the Khronos Group

Cons of Vulkan-Samples

  • Focuses on general Vulkan features, not specifically on ray tracing
  • May be overwhelming for beginners due to its extensive coverage

Code Comparison

vk_raytracing_tutorial_KHR:

void createBottomLevelAS()
{
  // Create the bottom-level acceleration structure
  nvvk::RaytracingBuilderKHR::BottomLevelInput bottomLevelInput;
  bottomLevelInput.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
  // ... (specific ray tracing setup)
}

Vulkan-Samples:

void create_acceleration_structure()
{
  VkAccelerationStructureCreateInfoKHR create_info{};
  create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
  create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
  // ... (general Vulkan acceleration structure setup)
}

The vk_raytracing_tutorial_KHR code is more focused on ray tracing specifics, while Vulkan-Samples provides a more general Vulkan implementation. The former uses NVIDIA's nvvk helper library, while the latter uses standard Vulkan calls.

10,285

C++ examples for the Vulkan graphics API

Pros of Vulkan

  • Comprehensive collection of Vulkan examples covering a wide range of features and techniques
  • Well-documented and organized codebase with clear explanations for each example
  • Regularly updated to include new Vulkan features and best practices

Cons of Vulkan

  • Focuses on general Vulkan usage rather than specializing in ray tracing
  • May be overwhelming for beginners due to the large number of examples and advanced topics

Code Comparison

vk_raytracing_tutorial_KHR:

void HelloVulkan::createBottomLevelAS()
{
  // ... (ray tracing specific code)
}

Vulkan:

void VulkanExample::prepareUniformBuffers()
{
  // ... (general Vulkan setup code)
}

Summary

Vulkan provides a broader overview of Vulkan capabilities, making it suitable for developers looking to explore various aspects of the API. vk_raytracing_tutorial_KHR, on the other hand, offers a more focused approach to ray tracing in Vulkan, making it ideal for those specifically interested in implementing ray tracing techniques.

While Vulkan covers a wide range of topics, vk_raytracing_tutorial_KHR delves deeper into ray tracing specifics, providing more detailed examples and explanations for this particular use case. Developers should choose based on their specific needs and level of expertise in Vulkan programming.

A beginner-friendly Vulkan path tracing tutorial in under 300 lines of C++.

Pros of vk_mini_path_tracer

  • More compact and focused implementation, easier for beginners to grasp
  • Includes a complete path tracing algorithm, demonstrating advanced rendering techniques
  • Utilizes modern C++ features and coding practices

Cons of vk_mini_path_tracer

  • Less comprehensive in covering Vulkan ray tracing features compared to vk_raytracing_tutorial_KHR
  • May not be as suitable for learning the full range of Vulkan ray tracing capabilities
  • Limited to a specific rendering technique (path tracing) rather than exploring various ray tracing applications

Code Comparison

vk_mini_path_tracer:

void createRayTracingPipeline()
{
  vk::RayTracingPipelineCreateInfoKHR rayPipelineInfo;
  rayPipelineInfo.setStages(stages);
  rayPipelineInfo.setGroups(groups);
  rayPipelineInfo.setMaxPipelineRayRecursionDepth(10);
  rayPipelineInfo.setLayout(pipelineLayout);
  m_rtPipeline = m_device.createRayTracingPipelineKHR({}, {}, rayPipelineInfo);
}

vk_raytracing_tutorial_KHR:

void createRayTracingPipeline()
{
  VkRayTracingPipelineCreateInfoKHR rayPipelineInfo{VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR};
  rayPipelineInfo.stageCount = static_cast<uint32_t>(stages.size());
  rayPipelineInfo.pStages = stages.data();
  rayPipelineInfo.groupCount = static_cast<uint32_t>(groups.size());
  rayPipelineInfo.pGroups = groups.data();
  rayPipelineInfo.maxPipelineRayRecursionDepth = 1;
  rayPipelineInfo.layout = pipelineLayout;
  vkCreateRayTracingPipelinesKHR(device, VK_NULL_HANDLE, VK_NULL_HANDLE, 1, &rayPipelineInfo, nullptr, &pipeline);
}
17,590

Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WebGL2

Pros of Filament

  • Comprehensive real-time rendering engine with support for multiple platforms
  • Extensive documentation and examples for easier adoption
  • Active development and maintenance by Google

Cons of Filament

  • Steeper learning curve due to its broader scope and feature set
  • May be overkill for simple ray tracing projects
  • Less focused on Vulkan-specific ray tracing techniques

Code Comparison

vk_raytracing_tutorial_KHR:

void createRayTracingPipeline()
{
  vk::ShaderModule rayGenShader = createShaderModule(loadFile("shaders/raygen.rgen.spv"));
  vk::ShaderModule missShader = createShaderModule(loadFile("shaders/miss.rmiss.spv"));
  vk::ShaderModule chitShader = createShaderModule(loadFile("shaders/chit.rchit.spv"));
  // ... (pipeline creation code)
}

Filament:

FilamentApp& app = FilamentApp::get();
auto& engine = app.getEngine();
auto scene = engine.createScene();
auto& view = app.getGuiView();
view.setScene(scene);
// ... (scene setup and rendering code)

The vk_raytracing_tutorial_KHR focuses on low-level Vulkan ray tracing setup, while Filament provides a higher-level abstraction for scene management and rendering across multiple platforms.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

logo

NVIDIA Vulkan Ray Tracing Tutorials

resultRaytraceShadowMedieval

The focus of this repository and the provided code is to showcase a basic integration of ray tracing and ray traversal within an existing Vulkan sample, using the VK_KHR_acceleration_structure, VK_KHR_ray_tracing_pipeline and VK_KHR_ray_query extensions.

Setup

To be able to compile and run those examples, please follow the setup instructions. Find more over nvpro-samples setup at: https://github.com/nvpro-samples/build_all.

Tutorials

The first tutorial starts from a very simple Vulkan application. It loads a OBJ file and uses the rasterizer to render it. The tutorial then adds, step-by-step, all that is needed to be able to ray trace the scene.


Ray Tracing Tutorial: :arrow_forward: Start Here :arrow_backward:


Extra Tutorials

All other tutorials start from the end of the first ray tracing tutorial and also provide step-by-step instructions to modify and add methods and functions for that extra section.

TutorialDetails
smallAny Hit Shader
Implements transparent materials by adding a new shader to the Hit group and using the material information to discard hits over time. Adds an anyhit (.ahit) shader to the ray tracing pipeline. Creates simple transparency by randomly letting the ray hit or not.
smallJitter Camera
Anti-aliases the image by accumulating small variations of rays over time. Generates random ray directions. Read/write/accumulates the final image.
imgThousands of Objects
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. Extends the limit of 4096 memory allocations. Uses these memory allocators: DMA, VMA.
imgReflections
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. Calls traceRayEXT() from the closest hit shader (recursive). Adds more data to the ray payload to continue the ray from the raygen shader.
imgMultiple Closest Hits Shader and Shader Records
Explains how to add more closest hit shaders, choose which instance uses which shader, 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 objects. Passing a shader record to the closest hit shader.
imgAnimation
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. Refitting top level acceleration structures. Refitting bottom level acceleration structures.
imgIntersection Shader
Adds thousands of implicit primitives and uses an intersection shader to render spheres and cubes. Explains what is needed to get procedural hit group working. Intersection Shaders. Sphere intersection. Axis aligned bounding box intersection.
imgCallable Shader
Replacing if/else by callable shaders. The code to execute the lighting is done in separate callable shaders instead of being part of the main code. Adding multiple callable shaders. Calling ExecuteCallableEXT from the closest hit shader.
imgRay Query
Invokes ray intersection queries directly from the fragment shader to cast shadow rays. Ray tracing directly from the fragment shader.
imgglTF Scene
Instead of loading separate OBJ objects, the example was modified to load glTF scene files containing multiple objects. This example is not about shading, but using more complex data than OBJ. However, it also shows a basic path tracer implementation.
imgAdvance
An example combining most of the above samples in a single application.
imgTrace Rays Indirect
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.
imgAO Raytracing
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).
imgSpecialization Constants
Showing how to use specialization constant and using interactively different specialization.
imgAdvanced Compilation
Shows how to create reusable pipeline libraries and compile pipelines on multiple threads.
imgMotion Blur
Using vertex motion and instance motion: matrix and SRT.