diff --git a/src/pt/aligned_sky_state.hpp b/src/pt/aligned_sky_state.hpp new file mode 100644 index 0000000..1da45eb --- /dev/null +++ b/src/pt/aligned_sky_state.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include +#include + +#include +#include + +#include +#include +#include + +namespace nlrs +{ +struct Sky +{ + float turbidity = 1.0f; + std::array albedo = {1.0f, 1.0f, 1.0f}; + float sunZenithDegrees = 30.0f; + float sunAzimuthDegrees = 0.0f; + + bool operator==(const Sky&) const noexcept = default; +}; + +// A 16-byte aligned sky state for the hw-skymodel library. Matches the layout of the following WGSL +// struct: +// +// struct SkyState { +// params: array, +// skyRadiances: array, +// solarRadiances: array, +// sunDirection: vec3, +// }; +struct AlignedSkyState +{ + float params[27]; // offset: 0 + float skyRadiances[3]; // offset: 27 + float solarRadiances[3]; // offset: 30 + float padding1[3]; // offset: 33 + glm::vec3 sunDirection; // offset: 36 + float padding2; // offset: 39 + + inline AlignedSkyState(const Sky& sky) + : params{0}, + skyRadiances{0}, + solarRadiances{0}, + padding1{0.f, 0.f, 0.f}, + sunDirection(0.f), + padding2(0.0f) + { + const float sunZenith = Angle::degrees(sky.sunZenithDegrees).asRadians(); + const float sunAzimuth = Angle::degrees(sky.sunAzimuthDegrees).asRadians(); + + sunDirection = glm::normalize(glm::vec3( + std::sin(sunZenith) * std::cos(sunAzimuth), + std::cos(sunZenith), + -std::sin(sunZenith) * std::sin(sunAzimuth))); + + const sky_params skyParams{ + .elevation = 0.5f * std::numbers::pi_v - sunZenith, + .turbidity = sky.turbidity, + .albedo = {sky.albedo[0], sky.albedo[1], sky.albedo[2]}}; + + sky_state skyState; + NLRS_ASSERT(sky_state_new(&skyParams, &skyState) == sky_state_result_success); + + std::memcpy(params, skyState.params, sizeof(skyState.params)); + std::memcpy(skyRadiances, skyState.sky_radiances, sizeof(skyState.sky_radiances)); + std::memcpy(solarRadiances, skyState.solar_radiances, sizeof(skyState.solar_radiances)); + } +}; +} // namespace nlrs diff --git a/src/pt/reference_path_tracer.cpp b/src/pt/reference_path_tracer.cpp index 29123ce..271c0c5 100644 --- a/src/pt/reference_path_tracer.cpp +++ b/src/pt/reference_path_tracer.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -27,9 +26,6 @@ namespace nlrs { -inline constexpr float PI = std::numbers::pi_v; -inline constexpr float DEGREES_TO_RADIANS = PI / 180.0f; - namespace { struct FrameDataLayout @@ -96,47 +92,6 @@ struct SamplingStateLayout } }; -struct SkyStateLayout -{ - float params[27]; // offset: 0 - float skyRadiances[3]; // offset: 27 - float solarRadiances[3]; // offset: 30 - float padding1[3]; // offset: 33 - glm::vec3 sunDirection; // offset: 36 - float padding2; // offset: 39 - - SkyStateLayout(const Sky& sky) - : params{0}, - skyRadiances{0}, - solarRadiances{0}, - padding1{0.f, 0.f, 0.f}, - sunDirection(0.f), - padding2(0.0f) - { - const float sunZenith = sky.sunZenithDegrees * DEGREES_TO_RADIANS; - const float sunAzimuth = sky.sunAzimuthDegrees * DEGREES_TO_RADIANS; - - sunDirection = glm::normalize(glm::vec3( - std::sin(sunZenith) * std::cos(sunAzimuth), - std::cos(sunZenith), - -std::sin(sunZenith) * std::sin(sunAzimuth))); - - const sky_params skyParams{ - .elevation = 0.5f * PI - sunZenith, - .turbidity = sky.turbidity, - .albedo = {sky.albedo[0], sky.albedo[1], sky.albedo[2]}}; - - sky_state skyState; - [[maybe_unused]] const auto r = sky_state_new(&skyParams, &skyState); - // TODO: exceptional error handling - assert(r == sky_state_result_success); - - std::memcpy(params, skyState.params, sizeof(skyState.params)); - std::memcpy(skyRadiances, skyState.sky_radiances, sizeof(skyState.sky_radiances)); - std::memcpy(solarRadiances, skyState.solar_radiances, sizeof(skyState.solar_radiances)); - } -}; - struct RenderParamsLayout { FrameDataLayout frameData; @@ -187,7 +142,7 @@ ReferencePathTracer::ReferencePathTracer( gpuContext.device, "sky state buffer", GpuBufferUsage::ReadOnlyStorage | GpuBufferUsage::CopyDst, - sizeof(SkyStateLayout)), + sizeof(AlignedSkyState)), mRenderParamsBindGroup(), mBvhNodeBuffer( gpuContext.device, @@ -624,9 +579,9 @@ void ReferencePathTracer::render(const GpuContext& gpuContext, WGPUTextureView t 0, &mCurrentPostProcessingParams, sizeof(PostProcessingParameters)); - const SkyStateLayout skyStateLayout{mCurrentRenderParams.sky}; + const AlignedSkyState skyState{mCurrentRenderParams.sky}; wgpuQueueWriteBuffer( - gpuContext.queue, mSkyStateBuffer.ptr(), 0, &skyStateLayout, sizeof(SkyStateLayout)); + gpuContext.queue, mSkyStateBuffer.ptr(), 0, &skyState, sizeof(AlignedSkyState)); } const WGPUCommandEncoder encoder = [&gpuContext]() { diff --git a/src/pt/reference_path_tracer.hpp b/src/pt/reference_path_tracer.hpp index a666e34..2bc1c75 100644 --- a/src/pt/reference_path_tracer.hpp +++ b/src/pt/reference_path_tracer.hpp @@ -1,5 +1,6 @@ #pragma once +#include "aligned_sky_state.hpp" #include "gpu_bind_group.hpp" #include "gpu_buffer.hpp" @@ -29,16 +30,6 @@ struct SamplingParams bool operator==(const SamplingParams&) const noexcept = default; }; -struct Sky -{ - float turbidity = 1.0f; - std::array albedo = {1.0f, 1.0f, 1.0f}; - float sunZenithDegrees = 30.0f; - float sunAzimuthDegrees = 0.0f; - - bool operator==(const Sky&) const noexcept = default; -}; - struct RenderParameters { Extent2u framebufferSize;