diff --git a/README.md b/README.md
index 74bc572d..1877b305 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ This personal project follows my own attempts at CPU ray tracing following Peter
## Gallery
-
+
## Performance
@@ -78,6 +78,7 @@ If in doubt, please check the GitHub Actions [continuous integration configurati
* [D3D12 Raytracing Samples](https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12Raytracing)
* [George Ouzounoudis's vk_exp](https://github.com/georgeouzou/vk_exp)
* [NVIDIA Vulkan Forums](https://devtalk.nvidia.com/default/board/166/vulkan)
+* [Profiling DXR shaders with Timer Instrumentation](https://www.reddit.com/r/vulkan/comments/hhyeyj/profiling_dxr_shaders_with_timer_instrumentation/)
### VK_KHR_ray_tracing Port
diff --git a/assets/shaders/Heatmap.glsl b/assets/shaders/Heatmap.glsl
new file mode 100644
index 00000000..ae90f8da
--- /dev/null
+++ b/assets/shaders/Heatmap.glsl
@@ -0,0 +1,33 @@
+
+// Profiling DXR Shaders with Timer Instrumentation
+// https://developer.nvidia.com/blog/profiling-dxr-shaders-with-timer-instrumentation/
+vec3 heatmap(float t)
+{
+ const vec3 c[10] = {
+ vec3(0.0f / 255.0f, 2.0f / 255.0f, 91.0f / 255.0f),
+ vec3(0.0f / 255.0f, 108.0f / 255.0f, 251.0f / 255.0f),
+ vec3(0.0f / 255.0f, 221.0f / 255.0f, 221.0f / 255.0f),
+ vec3(51.0f / 255.0f, 221.0f / 255.0f, 0.0f / 255.0f),
+ vec3(255.0f / 255.0f, 252.0f / 255.0f, 0.0f / 255.0f),
+ vec3(255.0f / 255.0f, 180.0f / 255.0f, 0.0f / 255.0f),
+ vec3(255.0f / 255.0f, 104.0f / 255.0f, 0.0f / 255.0f),
+ vec3(226.0f / 255.0f, 22.0f / 255.0f, 0.0f / 255.0f),
+ vec3(191.0f / 255.0f, 0.0f / 255.0f, 83.0f / 255.0f),
+ vec3(145.0f / 255.0f, 0.0f / 255.0f, 65.0f / 255.0f)
+ };
+
+ const float s = t * 10.0f;
+
+ const int cur = int(s) <= 9 ? int(s) : 9;
+ const int prv = cur >= 1 ? cur - 1 : 0;
+ const int nxt = cur < 9 ? cur + 1 : 9;
+
+ const float blur = 0.8f;
+
+ const float wc = smoothstep(float(cur) - blur, float(cur) + blur, s) * (1.0f - smoothstep(float(cur + 1) - blur, float(cur + 1) + blur, s));
+ const float wp = 1.0f - smoothstep(float(cur) - blur, float(cur) + blur, s);
+ const float wn = smoothstep(float(cur + 1) - blur, float(cur + 1) + blur, s);
+
+ const vec3 r = wc * c[cur] + wp * c[prv] + wn * c[nxt];
+ return vec3(clamp(r.x, 0.0f, 1.0f), clamp(r.y, 0.0f, 1.0f), clamp(r.z, 0.0f, 1.0f));
+}
\ No newline at end of file
diff --git a/assets/shaders/RayTracing.rgen b/assets/shaders/RayTracing.rgen
index ee24b51c..4036f6fe 100644
--- a/assets/shaders/RayTracing.rgen
+++ b/assets/shaders/RayTracing.rgen
@@ -1,6 +1,10 @@
#version 460
+#extension GL_ARB_gpu_shader_int64 : require
+#extension GL_ARB_shader_clock : require
#extension GL_GOOGLE_include_directive : require
#extension GL_EXT_ray_tracing : require
+
+#include "Heatmap.glsl"
#include "Random.glsl"
#include "RayPayload.glsl"
#include "UniformBufferObject.glsl"
@@ -12,8 +16,11 @@ layout(binding = 3) readonly uniform UniformBufferObjectStruct { UniformBufferOb
layout(location = 0) rayPayloadEXT RayPayload Ray;
+
void main()
{
+ const uint64_t clock = Camera.ShowHeatmap ? clockARB() : 0;
+
// Initialise separate random seeds for the pixel and the rays.
// - pixel: we want the same random seed for each pixel to get a homogeneous anti-aliasing.
// - ray: we want a noisy random seed, different for each pixel.
@@ -79,10 +86,16 @@ void main()
pixelColor = accumulatedColor / Camera.TotalNumberOfSamples;
- if (Camera.GammaCorrection)
+ // Apply raytracing-in-one-weekend gamma correction.
+ pixelColor = sqrt(pixelColor);
+
+ if (Camera.ShowHeatmap)
{
- // Apply raytracing-in-one-weekend gamma correction.
- pixelColor = sqrt(pixelColor);
+ const uint64_t deltaTime = clockARB() - clock;
+ const float heatmapScale = 1000000.0f * Camera.HeatmapScale * Camera.HeatmapScale;
+ const float deltaTimeScaled = clamp(float(deltaTime) / heatmapScale, 0.0f, 1.0f);
+
+ pixelColor = heatmap(deltaTimeScaled);
}
imageStore(AccumulationImage, ivec2(gl_LaunchIDEXT.xy), vec4(accumulatedColor, 0));
diff --git a/assets/shaders/UniformBufferObject.glsl b/assets/shaders/UniformBufferObject.glsl
index 6fe97b85..0ecefb55 100644
--- a/assets/shaders/UniformBufferObject.glsl
+++ b/assets/shaders/UniformBufferObject.glsl
@@ -7,10 +7,11 @@ struct UniformBufferObject
mat4 ProjectionInverse;
float Aperture;
float FocusDistance;
+ float HeatmapScale;
uint TotalNumberOfSamples;
uint NumberOfSamples;
uint NumberOfBounces;
uint RandomSeed;
- bool GammaCorrection;
bool HasSky;
+ bool ShowHeatmap;
};
diff --git a/gallery/Heatmap.png b/gallery/Heatmap.png
new file mode 100644
index 00000000..86797e43
Binary files /dev/null and b/gallery/Heatmap.png differ
diff --git a/gallery/LucyHeatmap.png b/gallery/LucyHeatmap.png
new file mode 100644
index 00000000..6b7c9515
Binary files /dev/null and b/gallery/LucyHeatmap.png differ
diff --git a/src/Assets/UniformBuffer.hpp b/src/Assets/UniformBuffer.hpp
index 5dfadf0b..abf42db0 100644
--- a/src/Assets/UniformBuffer.hpp
+++ b/src/Assets/UniformBuffer.hpp
@@ -22,12 +22,13 @@ namespace Assets
glm::mat4 ProjectionInverse;
float Aperture;
float FocusDistance;
+ float HeatmapScale;
uint32_t TotalNumberOfSamples;
uint32_t NumberOfSamples;
uint32_t NumberOfBounces;
uint32_t RandomSeed;
- uint32_t GammaCorrection; // bool
uint32_t HasSky; // bool
+ uint32_t ShowHeatmap; // bool
};
class UniformBuffer
diff --git a/src/ModelViewController.cpp b/src/ModelViewController.cpp
index 50acdc95..8b5b3e1a 100644
--- a/src/ModelViewController.cpp
+++ b/src/ModelViewController.cpp
@@ -13,6 +13,9 @@ void ModelViewController::Reset(const glm::mat4& modelView)
modelRotX_ = 0;
modelRotY_ = 0;
+ mouseLeftPressed_ = false;
+ mouseRightPressed_ = false;
+
UpdateVectors();
}
diff --git a/src/RayTracer.cpp b/src/RayTracer.cpp
index 9f60d637..59f771f5 100644
--- a/src/RayTracer.cpp
+++ b/src/RayTracer.cpp
@@ -51,8 +51,9 @@ Assets::UniformBufferObject RayTracer::GetUniformBufferObject(const VkExtent2D e
ubo.NumberOfSamples = numberOfSamples_;
ubo.NumberOfBounces = userSettings_.NumberOfBounces;
ubo.RandomSeed = 1;
- ubo.GammaCorrection = userSettings_.GammaCorrection;
ubo.HasSky = init.HasSky;
+ ubo.ShowHeatmap = userSettings_.ShowHeatmap;
+ ubo.HeatmapScale = userSettings_.HeatmapScale;
return ubo;
}
@@ -63,9 +64,17 @@ void RayTracer::SetPhysicalDevice(
VkPhysicalDeviceFeatures& deviceFeatures,
void* nextDeviceFeatures)
{
+ // Required extensions.
+ requiredExtensions.insert(requiredExtensions.end(),
+ {
+ // VK_KHR_SHADER_CLOCK is required for heatmap
+ VK_KHR_SHADER_CLOCK_EXTENSION_NAME
+ });
+
// Opt-in into mandatory device features.
deviceFeatures.fillModeNonSolid = true;
deviceFeatures.samplerAnisotropy = true;
+ deviceFeatures.shaderInt64 = true;
Application::SetPhysicalDevice(physicalDevice, requiredExtensions, deviceFeatures, nextDeviceFeatures);
}
@@ -187,6 +196,7 @@ void RayTracer::OnKey(int key, int scancode, int action, int mods)
case GLFW_KEY_F1: userSettings_.ShowSettings = !userSettings_.ShowSettings; break;
case GLFW_KEY_F2: userSettings_.ShowOverlay = !userSettings_.ShowOverlay; break;
case GLFW_KEY_R: userSettings_.IsRayTraced = !userSettings_.IsRayTraced; break;
+ case GLFW_KEY_H: userSettings_.ShowHeatmap = !userSettings_.ShowHeatmap; break;
case GLFW_KEY_P: isWireFrame_ = !isWireFrame_; break;
default: break;
}
@@ -261,7 +271,6 @@ void RayTracer::LoadScene(const uint32_t sceneIndex)
userSettings_.FieldOfView = cameraInitialSate_.FieldOfView;
userSettings_.Aperture = cameraInitialSate_.Aperture;
userSettings_.FocusDistance = cameraInitialSate_.FocusDistance;
- userSettings_.GammaCorrection = cameraInitialSate_.GammaCorrection;
modelViewController_.Reset(cameraInitialSate_.ModelView);
diff --git a/src/UserInterface.cpp b/src/UserInterface.cpp
index 07742b71..1c7d4b33 100644
--- a/src/UserInterface.cpp
+++ b/src/UserInterface.cpp
@@ -181,21 +181,15 @@ void UserInterface::DrawSettings()
ImGui::Text("Help");
ImGui::Separator();
- ImGui::BulletText("Press F1 to toggle Settings.");
- ImGui::BulletText("Press F2 to toggle Statistics.");
- ImGui::BulletText("Press R to toggle ray tracing.");
- ImGui::NewLine();
-
- ImGui::Text("Controls");
- ImGui::Separator();
+ ImGui::BulletText("F1: toggle Settings.");
+ ImGui::BulletText("F2: toggle Statistics.");
ImGui::BulletText(
- "Press %c%c%c%c/SHIFT/CTRL to move camera.",
+ "%c%c%c%c/SHIFT/CTRL: move camera.",
std::toupper(window.GetKeyName(GLFW_KEY_W, 0)[0]),
std::toupper(window.GetKeyName(GLFW_KEY_A, 0)[0]),
std::toupper(window.GetKeyName(GLFW_KEY_S, 0)[0]),
std::toupper(window.GetKeyName(GLFW_KEY_D, 0)[0]));
- ImGui::BulletText("Click left mouse to rotate camera.");
- ImGui::BulletText("Click right mouse to rotate scene.");
+ ImGui::BulletText("L/R Mouse: rotate camera/scene.");
ImGui::NewLine();
ImGui::Text("Scene");
@@ -203,7 +197,6 @@ void UserInterface::DrawSettings()
ImGui::PushItemWidth(-1);
ImGui::Combo("", &Settings().SceneIndex, scenes.data(), static_cast(scenes.size()));
ImGui::PopItemWidth();
- ImGui::Checkbox("Show statistics overlay", &Settings().ShowOverlay);
ImGui::NewLine();
ImGui::Text("Ray Tracing");
@@ -221,7 +214,12 @@ void UserInterface::DrawSettings()
ImGui::SliderFloat("FoV", &Settings().FieldOfView, UserSettings::FieldOfViewMinValue, UserSettings::FieldOfViewMaxValue, "%.0f");
ImGui::SliderFloat("Aperture", &Settings().Aperture, 0.0f, 1.0f, "%.2f");
ImGui::SliderFloat("Focus", &Settings().FocusDistance, 0.1f, 20.0f, "%.1f");
- ImGui::Checkbox("Apply gamma correction", &Settings().GammaCorrection);
+ ImGui::NewLine();
+
+ ImGui::Text("Profiler");
+ ImGui::Separator();
+ ImGui::Checkbox("Show heatmap", &Settings().ShowHeatmap);
+ ImGui::SliderFloat("Scaling", &Settings().HeatmapScale, 0.01f, 10.0f, "%.2f", 2);
ImGui::NewLine();
}
ImGui::End();
diff --git a/src/UserSettings.hpp b/src/UserSettings.hpp
index dd2fac0f..3339a9b0 100644
--- a/src/UserSettings.hpp
+++ b/src/UserSettings.hpp
@@ -23,7 +23,10 @@ struct UserSettings final
float FieldOfView;
float Aperture;
float FocusDistance;
- bool GammaCorrection;
+
+ // Profiler
+ bool ShowHeatmap;
+ float HeatmapScale;
// UI
bool ShowSettings;
diff --git a/src/main.cpp b/src/main.cpp
index fc3d5498..de811b25 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -108,6 +108,9 @@ namespace
userSettings.ShowSettings = !options.Benchmark;
userSettings.ShowOverlay = true;
+ userSettings.ShowHeatmap = false;
+ userSettings.HeatmapScale = 1.5f;
+
return userSettings;
}