Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/renderer_rd/cluster_builder_rd.cpp
10279 views
1
/**************************************************************************/
2
/* cluster_builder_rd.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "cluster_builder_rd.h"
32
#include "servers/rendering/rendering_device.h"
33
#include "servers/rendering/rendering_server_globals.h"
34
35
ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
36
RD::VertexFormatID vertex_format;
37
38
{
39
Vector<RD::VertexAttribute> attributes;
40
{
41
RD::VertexAttribute va;
42
va.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
43
va.stride = sizeof(float) * 3;
44
attributes.push_back(va);
45
}
46
vertex_format = RD::get_singleton()->vertex_format_create(attributes);
47
}
48
49
{
50
RD::FramebufferFormatID fb_format;
51
RD::PipelineColorBlendState blend_state;
52
RD::PipelineRasterizationState rasterization_state;
53
RD::PipelineMultisampleState ms;
54
rasterization_state.enable_depth_clamp = true;
55
ms.sample_count = RD::TEXTURE_SAMPLES_4;
56
57
Vector<String> variants;
58
variants.push_back("");
59
variants.push_back("\n#define USE_ATTACHMENT\n");
60
variants.push_back("\n#define MOLTENVK_USED\n#define NO_IMAGE_ATOMICS\n");
61
variants.push_back("\n#define USE_ATTACHMENT\n#define MOLTENVK_USED\n#define NO_IMAGE_ATOMICS\n");
62
variants.push_back("\n#define NO_IMAGE_ATOMICS\n");
63
variants.push_back("\n#define MOLTENVK_USED\n#define NO_IMAGE_ATOMICS\n");
64
65
ClusterRender::ShaderVariant shader_variant;
66
RenderingDevice *rd = RD::get_singleton();
67
if (rd->has_feature(RD::SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS)) {
68
fb_format = rd->framebuffer_format_create_empty();
69
blend_state = RD::PipelineColorBlendState::create_disabled();
70
#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))
71
if (rd->get_device_capabilities().device_family == RDD::DEVICE_VULKAN) {
72
shader_variant = ClusterRender::SHADER_NORMAL_MOLTENVK;
73
} else if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
74
shader_variant = ClusterRender::SHADER_NORMAL;
75
} else {
76
shader_variant = ClusterRender::SHADER_NORMAL_NO_ATOMICS;
77
}
78
#else
79
if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
80
shader_variant = ClusterRender::SHADER_NORMAL;
81
} else {
82
shader_variant = ClusterRender::SHADER_NORMAL_NO_ATOMICS;
83
}
84
#endif
85
} else {
86
Vector<RD::AttachmentFormat> afs;
87
afs.push_back(RD::AttachmentFormat());
88
afs.write[0].usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
89
fb_format = rd->framebuffer_format_create(afs);
90
blend_state = RD::PipelineColorBlendState::create_blend();
91
#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))
92
if (rd->get_device_capabilities().device_family == RDD::DEVICE_VULKAN) {
93
shader_variant = ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK;
94
} else if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
95
shader_variant = ClusterRender::SHADER_USE_ATTACHMENT;
96
} else {
97
shader_variant = ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS;
98
}
99
#else
100
if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
101
shader_variant = ClusterRender::SHADER_USE_ATTACHMENT;
102
} else {
103
shader_variant = ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS;
104
}
105
#endif
106
}
107
108
cluster_render.cluster_render_shader.initialize(variants);
109
#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))
110
if (rd->get_device_capabilities().device_family == RDD::DEVICE_VULKAN) {
111
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL, false);
112
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT, false);
113
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_NO_ATOMICS, false);
114
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS, false);
115
} else if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
116
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);
117
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);
118
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_NO_ATOMICS, false);
119
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS, false);
120
} else {
121
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL, false);
122
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT, false);
123
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);
124
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);
125
}
126
#else
127
if (rd->has_feature(RD::SUPPORTS_IMAGE_ATOMIC_32_BIT)) {
128
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);
129
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);
130
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_NO_ATOMICS, false);
131
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_NO_ATOMICS, false);
132
} else {
133
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL, false);
134
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT, false);
135
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_NORMAL_MOLTENVK, false);
136
cluster_render.cluster_render_shader.set_variant_enabled(ClusterRender::SHADER_USE_ATTACHMENT_MOLTENVK, false);
137
}
138
#endif
139
cluster_render.shader_version = cluster_render.cluster_render_shader.version_create();
140
cluster_render.shader = cluster_render.cluster_render_shader.version_get_shader(cluster_render.shader_version, shader_variant);
141
cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, rasterization_state, RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
142
cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, rasterization_state, ms, RD::PipelineDepthStencilState(), blend_state, 0);
143
}
144
{
145
Vector<String> versions;
146
versions.push_back("");
147
cluster_store.cluster_store_shader.initialize(versions);
148
cluster_store.shader_version = cluster_store.cluster_store_shader.version_create();
149
cluster_store.shader = cluster_store.cluster_store_shader.version_get_shader(cluster_store.shader_version, 0);
150
cluster_store.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_store.shader);
151
}
152
{
153
Vector<String> versions;
154
versions.push_back("");
155
cluster_debug.cluster_debug_shader.initialize(versions);
156
cluster_debug.shader_version = cluster_debug.cluster_debug_shader.version_create();
157
cluster_debug.shader = cluster_debug.cluster_debug_shader.version_get_shader(cluster_debug.shader_version, 0);
158
cluster_debug.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_debug.shader);
159
}
160
161
{ // Sphere mesh data.
162
static const uint32_t icosphere_vertex_count = 42;
163
static const float icosphere_vertices[icosphere_vertex_count * 3] = {
164
0, 0, -1, 0.7236073, -0.5257253, -0.4472195, -0.276388, -0.8506492, -0.4472199, -0.8944262, 0, -0.4472156, -0.276388, 0.8506492, -0.4472199, 0.7236073, 0.5257253, -0.4472195, 0.276388, -0.8506492, 0.4472199, -0.7236073, -0.5257253, 0.4472195, -0.7236073, 0.5257253, 0.4472195, 0.276388, 0.8506492, 0.4472199, 0.8944262, 0, 0.4472156, 0, 0, 1, -0.1624555, -0.4999952, -0.8506544, 0.4253227, -0.3090114, -0.8506542, 0.2628688, -0.8090116, -0.5257377, 0.8506479, 0, -0.5257359, 0.4253227, 0.3090114, -0.8506542, -0.5257298, 0, -0.8506517, -0.6881894, -0.4999969, -0.5257362, -0.1624555, 0.4999952, -0.8506544, -0.6881894, 0.4999969, -0.5257362, 0.2628688, 0.8090116, -0.5257377, 0.9510579, -0.3090126, 0, 0.9510579, 0.3090126, 0, 0, -1, 0, 0.5877856, -0.8090167, 0, -0.9510579, -0.3090126, 0, -0.5877856, -0.8090167, 0, -0.5877856, 0.8090167, 0, -0.9510579, 0.3090126, 0, 0.5877856, 0.8090167, 0, 0, 1, 0, 0.6881894, -0.4999969, 0.5257362, -0.2628688, -0.8090116, 0.5257377, -0.8506479, 0, 0.5257359, -0.2628688, 0.8090116, 0.5257377, 0.6881894, 0.4999969, 0.5257362, 0.1624555, -0.4999952, 0.8506544, 0.5257298, 0, 0.8506517, -0.4253227, -0.3090114, 0.8506542, -0.4253227, 0.3090114, 0.8506542, 0.1624555, 0.4999952, 0.8506544
165
};
166
static const uint32_t icosphere_triangle_count = 80;
167
static const uint16_t icosphere_triangle_indices[icosphere_triangle_count * 3] = {
168
0, 13, 12, 1, 13, 15, 0, 12, 17, 0, 17, 19, 0, 19, 16, 1, 15, 22, 2, 14, 24, 3, 18, 26, 4, 20, 28, 5, 21, 30, 1, 22, 25, 2, 24, 27, 3, 26, 29, 4, 28, 31, 5, 30, 23, 6, 32, 37, 7, 33, 39, 8, 34, 40, 9, 35, 41, 10, 36, 38, 38, 41, 11, 38, 36, 41, 36, 9, 41, 41, 40, 11, 41, 35, 40, 35, 8, 40, 40, 39, 11, 40, 34, 39, 34, 7, 39, 39, 37, 11, 39, 33, 37, 33, 6, 37, 37, 38, 11, 37, 32, 38, 32, 10, 38, 23, 36, 10, 23, 30, 36, 30, 9, 36, 31, 35, 9, 31, 28, 35, 28, 8, 35, 29, 34, 8, 29, 26, 34, 26, 7, 34, 27, 33, 7, 27, 24, 33, 24, 6, 33, 25, 32, 6, 25, 22, 32, 22, 10, 32, 30, 31, 9, 30, 21, 31, 21, 4, 31, 28, 29, 8, 28, 20, 29, 20, 3, 29, 26, 27, 7, 26, 18, 27, 18, 2, 27, 24, 25, 6, 24, 14, 25, 14, 1, 25, 22, 23, 10, 22, 15, 23, 15, 5, 23, 16, 21, 5, 16, 19, 21, 19, 4, 21, 19, 20, 4, 19, 17, 20, 17, 3, 20, 17, 18, 3, 17, 12, 18, 12, 2, 18, 15, 16, 5, 15, 13, 16, 13, 0, 16, 12, 14, 2, 12, 13, 14, 13, 1, 14
169
};
170
171
Vector<uint8_t> vertex_data;
172
vertex_data.resize(sizeof(float) * icosphere_vertex_count * 3);
173
memcpy(vertex_data.ptrw(), icosphere_vertices, vertex_data.size());
174
175
sphere_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
176
177
Vector<uint8_t> index_data;
178
index_data.resize(sizeof(uint16_t) * icosphere_triangle_count * 3);
179
memcpy(index_data.ptrw(), icosphere_triangle_indices, index_data.size());
180
181
sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
182
183
Vector<RID> buffers;
184
buffers.push_back(sphere_vertex_buffer);
185
186
sphere_vertex_array = RD::get_singleton()->vertex_array_create(icosphere_vertex_count, vertex_format, buffers);
187
188
sphere_index_array = RD::get_singleton()->index_array_create(sphere_index_buffer, 0, icosphere_triangle_count * 3);
189
190
float min_d = 1e20;
191
for (uint32_t i = 0; i < icosphere_triangle_count; i++) {
192
Vector3 vertices[3];
193
for (uint32_t j = 0; j < 3; j++) {
194
uint32_t index = icosphere_triangle_indices[i * 3 + j];
195
for (uint32_t k = 0; k < 3; k++) {
196
vertices[j][k] = icosphere_vertices[index * 3 + k];
197
}
198
}
199
Plane p(vertices[0], vertices[1], vertices[2]);
200
min_d = MIN(Math::abs(p.d), min_d);
201
}
202
sphere_overfit = 1.0 / min_d;
203
}
204
205
{ // Cone mesh data.
206
static const uint32_t cone_vertex_count = 99;
207
static const float cone_vertices[cone_vertex_count * 3] = {
208
0, 1, -1, 0.1950903, 0.9807853, -1, 0.3826835, 0.9238795, -1, 0.5555703, 0.8314696, -1, 0.7071068, 0.7071068, -1, 0.8314697, 0.5555702, -1, 0.9238795, 0.3826834, -1, 0.9807853, 0.1950903, -1, 1, 0, -1, 0.9807853, -0.1950902, -1, 0.9238796, -0.3826833, -1, 0.8314697, -0.5555702, -1, 0.7071068, -0.7071068, -1, 0.5555702, -0.8314697, -1, 0.3826833, -0.9238796, -1, 0.1950901, -0.9807853, -1, -3.25841e-7, -1, -1, -0.1950907, -0.9807852, -1, -0.3826839, -0.9238793, -1, -0.5555707, -0.8314693, -1, -0.7071073, -0.7071063, -1, -0.83147, -0.5555697, -1, -0.9238799, -0.3826827, -1, 0, 0, 0, -0.9807854, -0.1950894, -1, -1, 9.65599e-7, -1, -0.9807851, 0.1950913, -1, -0.9238791, 0.3826845, -1, -0.8314689, 0.5555713, -1, -0.7071059, 0.7071077, -1, -0.5555691, 0.8314704, -1, -0.3826821, 0.9238801, -1, -0.1950888, 0.9807856, -1
209
};
210
static const uint32_t cone_triangle_count = 62;
211
static const uint16_t cone_triangle_indices[cone_triangle_count * 3] = {
212
0, 23, 1, 1, 23, 2, 2, 23, 3, 3, 23, 4, 4, 23, 5, 5, 23, 6, 6, 23, 7, 7, 23, 8, 8, 23, 9, 9, 23, 10, 10, 23, 11, 11, 23, 12, 12, 23, 13, 13, 23, 14, 14, 23, 15, 15, 23, 16, 16, 23, 17, 17, 23, 18, 18, 23, 19, 19, 23, 20, 20, 23, 21, 21, 23, 22, 22, 23, 24, 24, 23, 25, 25, 23, 26, 26, 23, 27, 27, 23, 28, 28, 23, 29, 29, 23, 30, 30, 23, 31, 31, 23, 32, 32, 23, 0, 7, 15, 24, 32, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 3, 6, 7, 3, 7, 8, 9, 9, 10, 7, 10, 11, 7, 11, 12, 15, 12, 13, 15, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 24, 20, 21, 24, 21, 22, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 1, 3, 15, 17, 24, 17, 19, 24, 24, 26, 32, 26, 28, 32, 28, 30, 32, 32, 3, 7, 7, 11, 15, 32, 7, 24
213
};
214
215
Vector<uint8_t> vertex_data;
216
vertex_data.resize(sizeof(float) * cone_vertex_count * 3);
217
memcpy(vertex_data.ptrw(), cone_vertices, vertex_data.size());
218
219
cone_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
220
221
Vector<uint8_t> index_data;
222
index_data.resize(sizeof(uint16_t) * cone_triangle_count * 3);
223
memcpy(index_data.ptrw(), cone_triangle_indices, index_data.size());
224
225
cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
226
227
Vector<RID> buffers;
228
buffers.push_back(cone_vertex_buffer);
229
230
cone_vertex_array = RD::get_singleton()->vertex_array_create(cone_vertex_count, vertex_format, buffers);
231
232
cone_index_array = RD::get_singleton()->index_array_create(cone_index_buffer, 0, cone_triangle_count * 3);
233
234
float min_d = 1e20;
235
for (uint32_t i = 0; i < cone_triangle_count; i++) {
236
Vector3 vertices[3];
237
int32_t zero_index = -1;
238
for (uint32_t j = 0; j < 3; j++) {
239
uint32_t index = cone_triangle_indices[i * 3 + j];
240
for (uint32_t k = 0; k < 3; k++) {
241
vertices[j][k] = cone_vertices[index * 3 + k];
242
}
243
if (vertices[j] == Vector3()) {
244
zero_index = j;
245
}
246
}
247
248
if (zero_index != -1) {
249
Vector3 a = vertices[(zero_index + 1) % 3];
250
Vector3 b = vertices[(zero_index + 2) % 3];
251
Vector3 c = a + Vector3(0, 0, 1);
252
Plane p(a, b, c);
253
min_d = MIN(Math::abs(p.d), min_d);
254
}
255
}
256
cone_overfit = 1.0 / min_d;
257
}
258
259
{ // Box mesh data.
260
static const uint32_t box_vertex_count = 8;
261
static const float box_vertices[box_vertex_count * 3] = {
262
-1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1
263
};
264
static const uint32_t box_triangle_count = 12;
265
static const uint16_t box_triangle_indices[box_triangle_count * 3] = {
266
1, 2, 0, 3, 6, 2, 7, 4, 6, 5, 0, 4, 6, 0, 2, 3, 5, 7, 1, 3, 2, 3, 7, 6, 7, 5, 4, 5, 1, 0, 6, 4, 0, 3, 1, 5
267
};
268
269
Vector<uint8_t> vertex_data;
270
vertex_data.resize(sizeof(float) * box_vertex_count * 3);
271
memcpy(vertex_data.ptrw(), box_vertices, vertex_data.size());
272
273
box_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
274
275
Vector<uint8_t> index_data;
276
index_data.resize(sizeof(uint16_t) * box_triangle_count * 3);
277
memcpy(index_data.ptrw(), box_triangle_indices, index_data.size());
278
279
box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
280
281
Vector<RID> buffers;
282
buffers.push_back(box_vertex_buffer);
283
284
box_vertex_array = RD::get_singleton()->vertex_array_create(box_vertex_count, vertex_format, buffers);
285
286
box_index_array = RD::get_singleton()->index_array_create(box_index_buffer, 0, box_triangle_count * 3);
287
}
288
}
289
ClusterBuilderSharedDataRD::~ClusterBuilderSharedDataRD() {
290
RD::get_singleton()->free(sphere_vertex_buffer);
291
RD::get_singleton()->free(sphere_index_buffer);
292
RD::get_singleton()->free(cone_vertex_buffer);
293
RD::get_singleton()->free(cone_index_buffer);
294
RD::get_singleton()->free(box_vertex_buffer);
295
RD::get_singleton()->free(box_index_buffer);
296
297
cluster_render.cluster_render_shader.version_free(cluster_render.shader_version);
298
cluster_store.cluster_store_shader.version_free(cluster_store.shader_version);
299
cluster_debug.cluster_debug_shader.version_free(cluster_debug.shader_version);
300
}
301
302
/////////////////////////////
303
304
void ClusterBuilderRD::_clear() {
305
if (cluster_buffer.is_null()) {
306
return;
307
}
308
309
RD::get_singleton()->free(cluster_buffer);
310
RD::get_singleton()->free(cluster_render_buffer);
311
RD::get_singleton()->free(element_buffer);
312
cluster_buffer = RID();
313
cluster_render_buffer = RID();
314
element_buffer = RID();
315
316
memfree(render_elements);
317
318
render_elements = nullptr;
319
render_element_max = 0;
320
render_element_count = 0;
321
322
RD::get_singleton()->free(framebuffer);
323
framebuffer = RID();
324
325
cluster_render_uniform_set = RID();
326
cluster_store_uniform_set = RID();
327
}
328
329
void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer) {
330
ERR_FAIL_COND(p_max_elements == 0);
331
ERR_FAIL_COND(p_screen_size.x < 1);
332
ERR_FAIL_COND(p_screen_size.y < 1);
333
334
_clear();
335
336
screen_size = p_screen_size;
337
338
cluster_screen_size.width = Math::division_round_up((uint32_t)p_screen_size.width, cluster_size);
339
cluster_screen_size.height = Math::division_round_up((uint32_t)p_screen_size.height, cluster_size);
340
341
max_elements_by_type = p_max_elements;
342
if (max_elements_by_type % 32) { // Needs to be aligned to 32.
343
max_elements_by_type += 32 - (max_elements_by_type % 32);
344
}
345
346
cluster_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (max_elements_by_type / 32 + 32) * ELEMENT_TYPE_MAX * 4;
347
348
render_element_max = max_elements_by_type * ELEMENT_TYPE_MAX;
349
350
uint32_t element_tag_bits_size = render_element_max / 32;
351
uint32_t element_tag_depth_bits_size = render_element_max;
352
353
cluster_render_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (element_tag_bits_size + element_tag_depth_bits_size) * 4; // Tag bits (element was used) and tag depth (depth range in which it was used).
354
355
cluster_render_buffer = RD::get_singleton()->storage_buffer_create(cluster_render_buffer_size);
356
cluster_buffer = RD::get_singleton()->storage_buffer_create(cluster_buffer_size);
357
358
render_elements = static_cast<RenderElementData *>(memalloc(sizeof(RenderElementData) * render_element_max));
359
render_element_count = 0;
360
361
element_buffer = RD::get_singleton()->storage_buffer_create(sizeof(RenderElementData) * render_element_max);
362
363
uint32_t div_value = 1 << divisor;
364
if (use_msaa) {
365
framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value, RD::TEXTURE_SAMPLES_4);
366
} else {
367
framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value);
368
}
369
370
{
371
Vector<RD::Uniform> uniforms;
372
{
373
RD::Uniform u;
374
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
375
u.binding = 1;
376
u.append_id(state_uniform);
377
uniforms.push_back(u);
378
}
379
{
380
RD::Uniform u;
381
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
382
u.binding = 2;
383
u.append_id(element_buffer);
384
uniforms.push_back(u);
385
}
386
{
387
RD::Uniform u;
388
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
389
u.binding = 3;
390
u.append_id(cluster_render_buffer);
391
uniforms.push_back(u);
392
}
393
394
cluster_render_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_render.shader, 0);
395
}
396
397
{
398
Vector<RD::Uniform> uniforms;
399
{
400
RD::Uniform u;
401
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
402
u.binding = 1;
403
u.append_id(cluster_render_buffer);
404
uniforms.push_back(u);
405
}
406
{
407
RD::Uniform u;
408
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
409
u.binding = 2;
410
u.append_id(cluster_buffer);
411
uniforms.push_back(u);
412
}
413
414
{
415
RD::Uniform u;
416
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
417
u.binding = 3;
418
u.append_id(element_buffer);
419
uniforms.push_back(u);
420
}
421
422
cluster_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_store.shader, 0);
423
}
424
425
if (p_color_buffer.is_valid()) {
426
Vector<RD::Uniform> uniforms;
427
{
428
RD::Uniform u;
429
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
430
u.binding = 1;
431
u.append_id(cluster_buffer);
432
uniforms.push_back(u);
433
}
434
{
435
RD::Uniform u;
436
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
437
u.binding = 2;
438
u.append_id(p_color_buffer);
439
uniforms.push_back(u);
440
}
441
442
{
443
RD::Uniform u;
444
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
445
u.binding = 3;
446
u.append_id(p_depth_buffer);
447
uniforms.push_back(u);
448
}
449
{
450
RD::Uniform u;
451
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
452
u.binding = 4;
453
u.append_id(p_depth_buffer_sampler);
454
uniforms.push_back(u);
455
}
456
457
debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_debug.shader, 0);
458
} else {
459
debug_uniform_set = RID();
460
}
461
}
462
463
void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y) {
464
view_xform = p_view_transform.affine_inverse();
465
projection = p_cam_projection;
466
z_near = projection.get_z_near();
467
z_far = projection.get_z_far();
468
camera_orthogonal = p_cam_projection.is_orthogonal();
469
adjusted_projection = projection;
470
if (!camera_orthogonal) {
471
adjusted_projection.adjust_perspective_znear(0.0001);
472
}
473
474
Projection correction;
475
correction.set_depth_correction(p_flip_y);
476
projection = correction * projection;
477
adjusted_projection = correction * adjusted_projection;
478
479
// Reset counts.
480
render_element_count = 0;
481
for (uint32_t i = 0; i < ELEMENT_TYPE_MAX; i++) {
482
cluster_count_by_type[i] = 0;
483
}
484
}
485
486
void ClusterBuilderRD::bake_cluster() {
487
RENDER_TIMESTAMP("> Bake 3D Cluster");
488
489
RD::get_singleton()->draw_command_begin_label("Bake Light Cluster");
490
491
// Clear cluster buffer.
492
RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size);
493
494
if (render_element_count > 0) {
495
// Clear render buffer.
496
RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size);
497
498
{ // Fill state uniform.
499
500
StateUniform state;
501
502
RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection);
503
state.inv_z_far = 1.0 / z_far;
504
state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);
505
state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less
506
507
state.cluster_screen_width = cluster_screen_size.x;
508
state.cluster_depth_offset = (render_element_max / 32);
509
state.cluster_data_size = state.cluster_depth_offset + render_element_max;
510
511
RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state);
512
}
513
514
// Update instances.
515
516
RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements);
517
518
RENDER_TIMESTAMP("Render 3D Cluster Elements");
519
520
// Render elements.
521
{
522
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
523
ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {};
524
525
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shared->cluster_render.shader_pipelines[use_msaa ? ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_MSAA : ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_NORMAL]);
526
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, cluster_render_uniform_set, 0);
527
528
for (uint32_t i = 0; i < render_element_count;) {
529
push_constant.base_index = i;
530
switch (render_elements[i].type) {
531
case ELEMENT_TYPE_OMNI_LIGHT: {
532
RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);
533
RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
534
} break;
535
case ELEMENT_TYPE_SPOT_LIGHT: {
536
// If the spot angle is above a certain threshold, use a sphere instead of a cone for building the clusters
537
// since the cone gets too flat/large (spot angle close to 90 degrees) or
538
// can't even cover the affected area of the light (spot angle above 90 degrees).
539
if (render_elements[i].has_wide_spot_angle) {
540
RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);
541
RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
542
} else {
543
RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array);
544
RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array);
545
}
546
} break;
547
case ELEMENT_TYPE_DECAL:
548
case ELEMENT_TYPE_REFLECTION_PROBE: {
549
RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->box_vertex_array);
550
RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->box_index_array);
551
} break;
552
}
553
554
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterRender::PushConstant));
555
556
uint32_t instances = 1;
557
RD::get_singleton()->draw_list_draw(draw_list, true, instances);
558
i += instances;
559
}
560
RD::get_singleton()->draw_list_end();
561
}
562
// Store elements.
563
RENDER_TIMESTAMP("Pack 3D Cluster Elements");
564
565
{
566
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
567
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_store.shader_pipeline);
568
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cluster_store_uniform_set, 0);
569
570
ClusterBuilderSharedDataRD::ClusterStore::PushConstant push_constant;
571
push_constant.cluster_render_data_size = render_element_max / 32 + render_element_max;
572
push_constant.max_render_element_count_div_32 = render_element_max / 32;
573
push_constant.cluster_screen_size[0] = cluster_screen_size.x;
574
push_constant.cluster_screen_size[1] = cluster_screen_size.y;
575
576
push_constant.render_element_count_div_32 = Math::division_round_up(render_element_count, 32U);
577
push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
578
push_constant.pad1 = 0;
579
push_constant.pad2 = 0;
580
581
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterStore::PushConstant));
582
583
RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1);
584
585
RD::get_singleton()->compute_list_end();
586
}
587
}
588
RENDER_TIMESTAMP("< Bake 3D Cluster");
589
RD::get_singleton()->draw_command_end_label();
590
}
591
592
void ClusterBuilderRD::debug(ElementType p_element) {
593
ERR_FAIL_COND(debug_uniform_set.is_null());
594
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
595
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_debug.shader_pipeline);
596
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0);
597
598
ClusterBuilderSharedDataRD::ClusterDebug::PushConstant push_constant;
599
push_constant.screen_size[0] = screen_size.x;
600
push_constant.screen_size[1] = screen_size.y;
601
push_constant.cluster_screen_size[0] = cluster_screen_size.x;
602
push_constant.cluster_screen_size[1] = cluster_screen_size.y;
603
push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size);
604
push_constant.cluster_type = p_element;
605
push_constant.orthogonal = camera_orthogonal;
606
push_constant.z_far = z_far;
607
push_constant.z_near = z_near;
608
push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
609
610
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterDebug::PushConstant));
611
612
RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1);
613
614
RD::get_singleton()->compute_list_end();
615
}
616
617
RID ClusterBuilderRD::get_cluster_buffer() const {
618
return cluster_buffer;
619
}
620
621
uint32_t ClusterBuilderRD::get_cluster_size() const {
622
return cluster_size;
623
}
624
625
uint32_t ClusterBuilderRD::get_max_cluster_elements() const {
626
return max_elements_by_type;
627
}
628
629
void ClusterBuilderRD::set_shared(ClusterBuilderSharedDataRD *p_shared) {
630
shared = p_shared;
631
}
632
633
ClusterBuilderRD::ClusterBuilderRD() {
634
state_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(StateUniform));
635
}
636
637
ClusterBuilderRD::~ClusterBuilderRD() {
638
_clear();
639
RD::get_singleton()->free(state_uniform);
640
}
641
642