-
Notifications
You must be signed in to change notification settings - Fork 0
/
renderer.hpp
197 lines (170 loc) · 5.96 KB
/
renderer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#pragma once
#include "gpu_buffer.hpp"
#include <common/bvh.hpp>
#include <common/camera.hpp>
#include <common/extent.hpp>
#include <common/texture.hpp>
#include <webgpu/webgpu.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <span>
namespace nlrs
{
struct GpuContext;
class Gui;
struct SamplingParams
{
std::uint32_t numSamplesPerPixel = 128;
std::uint32_t numBounces = 4;
bool operator==(const SamplingParams&) const noexcept = default;
};
struct Sky
{
float turbidity = 1.0f;
std::array<float, 3> 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;
Camera camera;
SamplingParams samplingParams;
Sky sky;
bool operator==(const RenderParameters&) const noexcept = default;
};
enum class Tonemapping : std::uint32_t
{
Linear = 0,
Filmic,
};
struct PostProcessingParameters
{
// Exposure is calculated as 1 / (2 ^ stops), stops >= 0. Increasing a stop by one halves the
// exposure.
std::uint32_t stops = 0;
Tonemapping tonemapping = Tonemapping::Filmic;
};
struct PositionAttribute
{
glm::vec3 p0; // offset: 0, size: 12
float pad0; // offset: 12, size: 4
glm::vec3 p1; // offset: 16, size: 12
float pad1; // offset: 28, size: 4
glm::vec3 p2; // offset: 32, size: 12
float pad2; // offset: 44, size: 4
};
struct VertexAttributes
{
// Normals
glm::vec3 n0; // offset 0, size: 12
float pad0; // offset 12, size: 4
glm::vec3 n1; // offset 16, size: 12
float pad1; // offset 28, size: 4
glm::vec3 n2; // offset 32, size: 12
float pad2; // offset 44, size: 4
// Texture coordinates
glm::vec2 uv0; // offset 48, size: 8
glm::vec2 uv1; // offset 56, size: 8
glm::vec2 uv2; // offset 64, size: 8
// Texture index
std::uint32_t textureIdx; // offset 72, size: 4
std::uint32_t pad3; // offset: 76, size 4
};
struct Scene
{
const Bvh& bvh;
std::span<const PositionAttribute> positionAttributes;
std::span<const VertexAttributes> vertexAttributes;
std::span<const Texture> baseColorTextures;
};
struct RendererDescriptor
{
RenderParameters renderParams;
Extent2i maxFramebufferSize;
};
struct Renderer
{
GpuBuffer vertexBuffer;
GpuBuffer uniformsBuffer;
WGPUBindGroup uniformsBindGroup;
GpuBuffer renderParamsBuffer;
GpuBuffer postProcessingParamsBuffer;
GpuBuffer skyStateBuffer;
WGPUBindGroup renderParamsBindGroup;
GpuBuffer bvhNodeBuffer;
GpuBuffer positionAttributesBuffer;
GpuBuffer vertexAttributesBuffer;
GpuBuffer textureDescriptorBuffer;
GpuBuffer textureBuffer;
WGPUBindGroup sceneBindGroup;
GpuBuffer imageBuffer;
WGPUBindGroup imageBindGroup;
WGPUQuerySet querySet;
GpuBuffer queryBuffer;
GpuBuffer timestampBuffer;
WGPURenderPipeline renderPipeline;
RenderParameters currentRenderParams;
PostProcessingParameters currentPostProcessingParams;
std::uint32_t frameCount;
std::uint32_t accumulatedSampleCount;
std::deque<std::uint64_t> drawDurationsNs;
std::deque<std::uint64_t> renderPassDurationsNs;
struct TimestampBufferMapContext
{
GpuBuffer* timestampBuffer = nullptr;
std::deque<std::uint64_t>* drawDurationsNs = nullptr;
std::deque<std::uint64_t>* renderPassDurationsNs = nullptr;
};
TimestampBufferMapContext timestampBufferMapContext;
Renderer(const RendererDescriptor&, const GpuContext&, Scene);
~Renderer();
void setRenderParameters(const RenderParameters&);
void setPostProcessingParameters(const PostProcessingParameters&);
void render(const GpuContext&, Gui&);
float averageDrawDurationMs() const;
float averageRenderpassDurationMs() const;
float renderProgressPercentage() const;
static constexpr WGPURequiredLimits wgpuRequiredLimits{
.nextInChain = nullptr,
.limits =
WGPULimits{
.maxTextureDimension1D = 0,
.maxTextureDimension2D = 0,
.maxTextureDimension3D = 0,
.maxTextureArrayLayers = 0,
.maxBindGroups = 2,
.maxBindGroupsPlusVertexBuffers = 0,
.maxBindingsPerBindGroup = 7,
.maxDynamicUniformBuffersPerPipelineLayout = 0,
.maxDynamicStorageBuffersPerPipelineLayout = 0,
.maxSampledTexturesPerShaderStage = 0,
.maxSamplersPerShaderStage = 0,
.maxStorageBuffersPerShaderStage = 6,
.maxStorageTexturesPerShaderStage = 0,
.maxUniformBuffersPerShaderStage = 1,
.maxUniformBufferBindingSize = 80,
.maxStorageBufferBindingSize = 1 << 28, // 256 MiB
.minUniformBufferOffsetAlignment = 256,
.minStorageBufferOffsetAlignment = 256,
.maxVertexBuffers = 1,
.maxBufferSize = 0,
.maxVertexAttributes = 2,
.maxVertexBufferArrayStride = 2 * sizeof(float),
.maxInterStageShaderComponents = 0,
.maxInterStageShaderVariables = 0,
.maxColorAttachments = 0,
.maxColorAttachmentBytesPerSample = 0,
.maxComputeWorkgroupStorageSize = 0,
.maxComputeInvocationsPerWorkgroup = 0,
.maxComputeWorkgroupSizeX = 0,
.maxComputeWorkgroupSizeY = 0,
.maxComputeWorkgroupSizeZ = 0,
.maxComputeWorkgroupsPerDimension = 0,
},
};
};
} // namespace nlrs