|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <common/assert.hpp> |
| 4 | +#include <common/units/angle.hpp> |
| 5 | + |
| 6 | +#include <glm/glm.hpp> |
| 7 | +#include <hw-skymodel/hw_skymodel.h> |
| 8 | + |
| 9 | +#include <array> |
| 10 | +#include <cstring> |
| 11 | +#include <numbers> |
| 12 | + |
| 13 | +namespace nlrs |
| 14 | +{ |
| 15 | +struct Sky |
| 16 | +{ |
| 17 | + float turbidity = 1.0f; |
| 18 | + std::array<float, 3> albedo = {1.0f, 1.0f, 1.0f}; |
| 19 | + float sunZenithDegrees = 30.0f; |
| 20 | + float sunAzimuthDegrees = 0.0f; |
| 21 | + |
| 22 | + bool operator==(const Sky&) const noexcept = default; |
| 23 | +}; |
| 24 | + |
| 25 | +// A 16-byte aligned sky state for the hw-skymodel library. Matches the layout of the following WGSL |
| 26 | +// struct: |
| 27 | +// |
| 28 | +// struct SkyState { |
| 29 | +// params: array<f32, 27>, |
| 30 | +// skyRadiances: array<f32, 3>, |
| 31 | +// solarRadiances: array<f32, 3>, |
| 32 | +// sunDirection: vec3<f32>, |
| 33 | +// }; |
| 34 | +struct AlignedSkyState |
| 35 | +{ |
| 36 | + float params[27]; // offset: 0 |
| 37 | + float skyRadiances[3]; // offset: 27 |
| 38 | + float solarRadiances[3]; // offset: 30 |
| 39 | + float padding1[3]; // offset: 33 |
| 40 | + glm::vec3 sunDirection; // offset: 36 |
| 41 | + float padding2; // offset: 39 |
| 42 | + |
| 43 | + inline AlignedSkyState(const Sky& sky) |
| 44 | + : params{0}, |
| 45 | + skyRadiances{0}, |
| 46 | + solarRadiances{0}, |
| 47 | + padding1{0.f, 0.f, 0.f}, |
| 48 | + sunDirection(0.f), |
| 49 | + padding2(0.0f) |
| 50 | + { |
| 51 | + const float sunZenith = Angle::degrees(sky.sunZenithDegrees).asRadians(); |
| 52 | + const float sunAzimuth = Angle::degrees(sky.sunAzimuthDegrees).asRadians(); |
| 53 | + |
| 54 | + sunDirection = glm::normalize(glm::vec3( |
| 55 | + std::sin(sunZenith) * std::cos(sunAzimuth), |
| 56 | + std::cos(sunZenith), |
| 57 | + -std::sin(sunZenith) * std::sin(sunAzimuth))); |
| 58 | + |
| 59 | + const sky_params skyParams{ |
| 60 | + .elevation = 0.5f * std::numbers::pi_v<float> - sunZenith, |
| 61 | + .turbidity = sky.turbidity, |
| 62 | + .albedo = {sky.albedo[0], sky.albedo[1], sky.albedo[2]}}; |
| 63 | + |
| 64 | + sky_state skyState; |
| 65 | + NLRS_ASSERT(sky_state_new(&skyParams, &skyState) == sky_state_result_success); |
| 66 | + |
| 67 | + std::memcpy(params, skyState.params, sizeof(skyState.params)); |
| 68 | + std::memcpy(skyRadiances, skyState.sky_radiances, sizeof(skyState.sky_radiances)); |
| 69 | + std::memcpy(solarRadiances, skyState.solar_radiances, sizeof(skyState.solar_radiances)); |
| 70 | + } |
| 71 | +}; |
| 72 | +} // namespace nlrs |
0 commit comments