SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
SSAOKernel.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cmath>
5#include <cstdint>
6#include <random>
7
8namespace Sleak {
9namespace RenderEngine {
10
11// Generates a hemisphere sample kernel for SSAO.
12// Samples are distributed in a unit hemisphere (z >= 0) with
13// cosine-weighted distribution biased toward the center.
14struct SSAOKernel {
15 static constexpr uint32_t MAX_KERNEL_SIZE = 64;
16
17 /// One hemisphere sample offset (w unused, kept for GPU alignment).
18 struct Sample {
19 float x, y, z, _pad;
20 };
21
22 std::array<Sample, MAX_KERNEL_SIZE> samples{};
23
24 // 4x4 noise texture data (random rotations for kernel)
25 static constexpr uint32_t NOISE_SIZE = 4;
26 std::array<float, NOISE_SIZE * NOISE_SIZE * 4> noiseData{};
27
28 /// Fills samples[] and noiseData[] with a deterministic (seed 42) cosine-weighted kernel.
29 void Generate(uint32_t kernelSize = MAX_KERNEL_SIZE) {
30 std::mt19937 rng(42); // deterministic seed for reproducibility
31 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
32 std::uniform_real_distribution<float> ndist(-1.0f, 1.0f);
33
34 for (uint32_t i = 0; i < kernelSize; ++i) {
35 // Random point in unit hemisphere
36 float x = ndist(rng);
37 float y = ndist(rng);
38 float z = dist(rng); // z in [0, 1] — hemisphere
39
40 // Normalize
41 float len = std::sqrt(x * x + y * y + z * z);
42 if (len < 0.0001f) len = 0.0001f;
43 x /= len;
44 y /= len;
45 z /= len;
46
47 // Scale with accelerating interpolation (more samples near origin)
48 float scale = static_cast<float>(i) / static_cast<float>(kernelSize);
49 scale = Lerp(0.1f, 1.0f, scale * scale);
50 x *= scale;
51 y *= scale;
52 z *= scale;
53
54 samples[i] = {x, y, z, 0.0f};
55 }
56
57 // Generate 4x4 noise texture (random tangent-space rotations around z)
58 for (uint32_t i = 0; i < NOISE_SIZE * NOISE_SIZE; ++i) {
59 noiseData[i * 4 + 0] = ndist(rng); // x rotation
60 noiseData[i * 4 + 1] = ndist(rng); // y rotation
61 noiseData[i * 4 + 2] = 0.0f; // z = 0 (rotate around z)
62 noiseData[i * 4 + 3] = 0.0f; // pad
63 }
64 }
65
66private:
67 static float Lerp(float a, float b, float t) {
68 return a + t * (b - a);
69 }
70};
71
72} // namespace RenderEngine
73} // namespace Sleak
constexpr T Lerp(const T &start, const T &end, float t)
Linear interpolation from start to end; t is clamped to [0,1].
Definition Math.hpp:37
Backend-facing rendering layer shared by the four graphics backends.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
One hemisphere sample offset (w unused, kept for GPU alignment).
void Generate(uint32_t kernelSize=MAX_KERNEL_SIZE)
Fills samples[] and noiseData[] with a deterministic (seed 42) cosine-weighted kernel.
static constexpr uint32_t MAX_KERNEL_SIZE
std::array< Sample, MAX_KERNEL_SIZE > samples
static constexpr uint32_t NOISE_SIZE
std::array< float, NOISE_SIZE *NOISE_SIZE *4 > noiseData