Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add profiling heatmap as per "Profiling DXR Shaders with Timer Instrumentation" #12

Merged
merged 11 commits into from
Oct 10, 2020
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This personal project follows my own attempts at CPU ray tracing following Peter

## Gallery

<img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/OneWeekend.jpg" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/Planets.jpg" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/CornellBox.jpg" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/CornellBoxLucy.jpg" width="49%"></img>
<img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/OneWeekend.jpg" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/Planets.jpg" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/Heatmap/gallery/Heatmap.png" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/Heatmap/gallery/LucyHeatmap.png" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/CornellBox.jpg" width="49%"></img> <img src="https:/GPSnoopy/RayTracingInVulkan/blob/master/gallery/CornellBoxLucy.jpg" width="49%"></img>

## Performance

Expand Down Expand Up @@ -78,6 +78,7 @@ If in doubt, please check the GitHub Actions [continuous integration configurati
* [D3D12 Raytracing Samples](https:/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12Raytracing)
* [George Ouzounoudis's vk_exp](https:/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

Expand Down
33 changes: 33 additions & 0 deletions assets/shaders/Heatmap.glsl
Original file line number Diff line number Diff line change
@@ -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));
}
19 changes: 16 additions & 3 deletions assets/shaders/RayTracing.rgen
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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.
Expand Down Expand Up @@ -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));
Expand Down
3 changes: 2 additions & 1 deletion assets/shaders/UniformBufferObject.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Binary file added gallery/Heatmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added gallery/LucyHeatmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/Assets/UniformBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/ModelViewController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ void ModelViewController::Reset(const glm::mat4& modelView)
modelRotX_ = 0;
modelRotY_ = 0;

mouseLeftPressed_ = false;
mouseRightPressed_ = false;

UpdateVectors();
}

Expand Down
13 changes: 11 additions & 2 deletions src/RayTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down
22 changes: 10 additions & 12 deletions src/UserInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,29 +181,22 @@ 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");
ImGui::Separator();
ImGui::PushItemWidth(-1);
ImGui::Combo("", &Settings().SceneIndex, scenes.data(), static_cast<int>(scenes.size()));
ImGui::PopItemWidth();
ImGui::Checkbox("Show statistics overlay", &Settings().ShowOverlay);
ImGui::NewLine();

ImGui::Text("Ray Tracing");
Expand All @@ -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();
Expand Down
5 changes: 4 additions & 1 deletion src/UserSettings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ struct UserSettings final
float FieldOfView;
float Aperture;
float FocusDistance;
bool GammaCorrection;

// Profiler
bool ShowHeatmap;
float HeatmapScale;

// UI
bool ShowSettings;
Expand Down
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ namespace
userSettings.ShowSettings = !options.Benchmark;
userSettings.ShowOverlay = true;

userSettings.ShowHeatmap = false;
userSettings.HeatmapScale = 1.5f;

return userSettings;
}

Expand Down