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
35ClusterBuilderSharedDataRD::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 String defines;
53 if (RD::get_singleton()->has_feature(RD::SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS)) {
54 fb_format = RD::get_singleton()->framebuffer_format_create_empty();
55 blend_state = RD::PipelineColorBlendState::create_disabled();
56 } else {
57 Vector<RD::AttachmentFormat> afs;
58 afs.push_back(RD::AttachmentFormat());
59 afs.write[0].usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
60 fb_format = RD::get_singleton()->framebuffer_format_create(afs);
61 blend_state = RD::PipelineColorBlendState::create_blend();
62 defines = "\n#define USE_ATTACHMENT\n";
63 }
64
65 Vector<String> versions;
66 versions.push_back("");
67 cluster_render.cluster_render_shader.initialize(versions, defines);
68 cluster_render.shader_version = cluster_render.cluster_render_shader.version_create();
69 cluster_render.shader = cluster_render.cluster_render_shader.version_get_shader(cluster_render.shader_version, 0);
70 cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
71 RD::PipelineMultisampleState ms;
72 ms.sample_count = RD::TEXTURE_SAMPLES_4;
73 cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, fb_format, vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), ms, RD::PipelineDepthStencilState(), blend_state, 0);
74 }
75 {
76 Vector<String> versions;
77 versions.push_back("");
78 cluster_store.cluster_store_shader.initialize(versions);
79 cluster_store.shader_version = cluster_store.cluster_store_shader.version_create();
80 cluster_store.shader = cluster_store.cluster_store_shader.version_get_shader(cluster_store.shader_version, 0);
81 cluster_store.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_store.shader);
82 }
83 {
84 Vector<String> versions;
85 versions.push_back("");
86 cluster_debug.cluster_debug_shader.initialize(versions);
87 cluster_debug.shader_version = cluster_debug.cluster_debug_shader.version_create();
88 cluster_debug.shader = cluster_debug.cluster_debug_shader.version_get_shader(cluster_debug.shader_version, 0);
89 cluster_debug.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_debug.shader);
90 }
91
92 { // Sphere mesh data.
93 static const uint32_t icosphere_vertex_count = 42;
94 static const float icosphere_vertices[icosphere_vertex_count * 3] = {
95 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
96 };
97 static const uint32_t icosphere_triangle_count = 80;
98 static const uint16_t icosphere_triangle_indices[icosphere_triangle_count * 3] = {
99 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
100 };
101
102 Vector<uint8_t> vertex_data;
103 vertex_data.resize(sizeof(float) * icosphere_vertex_count * 3);
104 memcpy(vertex_data.ptrw(), icosphere_vertices, vertex_data.size());
105
106 sphere_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
107
108 Vector<uint8_t> index_data;
109 index_data.resize(sizeof(uint16_t) * icosphere_triangle_count * 3);
110 memcpy(index_data.ptrw(), icosphere_triangle_indices, index_data.size());
111
112 sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
113
114 Vector<RID> buffers;
115 buffers.push_back(sphere_vertex_buffer);
116
117 sphere_vertex_array = RD::get_singleton()->vertex_array_create(icosphere_vertex_count, vertex_format, buffers);
118
119 sphere_index_array = RD::get_singleton()->index_array_create(sphere_index_buffer, 0, icosphere_triangle_count * 3);
120
121 float min_d = 1e20;
122 for (uint32_t i = 0; i < icosphere_triangle_count; i++) {
123 Vector3 vertices[3];
124 for (uint32_t j = 0; j < 3; j++) {
125 uint32_t index = icosphere_triangle_indices[i * 3 + j];
126 for (uint32_t k = 0; k < 3; k++) {
127 vertices[j][k] = icosphere_vertices[index * 3 + k];
128 }
129 }
130 Plane p(vertices[0], vertices[1], vertices[2]);
131 min_d = MIN(Math::abs(p.d), min_d);
132 }
133 sphere_overfit = 1.0 / min_d;
134 }
135
136 { // Cone mesh data.
137 static const uint32_t cone_vertex_count = 99;
138 static const float cone_vertices[cone_vertex_count * 3] = {
139 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
140 };
141 static const uint32_t cone_triangle_count = 62;
142 static const uint16_t cone_triangle_indices[cone_triangle_count * 3] = {
143 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
144 };
145
146 Vector<uint8_t> vertex_data;
147 vertex_data.resize(sizeof(float) * cone_vertex_count * 3);
148 memcpy(vertex_data.ptrw(), cone_vertices, vertex_data.size());
149
150 cone_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
151
152 Vector<uint8_t> index_data;
153 index_data.resize(sizeof(uint16_t) * cone_triangle_count * 3);
154 memcpy(index_data.ptrw(), cone_triangle_indices, index_data.size());
155
156 cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
157
158 Vector<RID> buffers;
159 buffers.push_back(cone_vertex_buffer);
160
161 cone_vertex_array = RD::get_singleton()->vertex_array_create(cone_vertex_count, vertex_format, buffers);
162
163 cone_index_array = RD::get_singleton()->index_array_create(cone_index_buffer, 0, cone_triangle_count * 3);
164
165 float min_d = 1e20;
166 for (uint32_t i = 0; i < cone_triangle_count; i++) {
167 Vector3 vertices[3];
168 int32_t zero_index = -1;
169 for (uint32_t j = 0; j < 3; j++) {
170 uint32_t index = cone_triangle_indices[i * 3 + j];
171 for (uint32_t k = 0; k < 3; k++) {
172 vertices[j][k] = cone_vertices[index * 3 + k];
173 }
174 if (vertices[j] == Vector3()) {
175 zero_index = j;
176 }
177 }
178
179 if (zero_index != -1) {
180 Vector3 a = vertices[(zero_index + 1) % 3];
181 Vector3 b = vertices[(zero_index + 2) % 3];
182 Vector3 c = a + Vector3(0, 0, 1);
183 Plane p(a, b, c);
184 min_d = MIN(Math::abs(p.d), min_d);
185 }
186 }
187 cone_overfit = 1.0 / min_d;
188 }
189
190 { // Box mesh data.
191 static const uint32_t box_vertex_count = 8;
192 static const float box_vertices[box_vertex_count * 3] = {
193 -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1
194 };
195 static const uint32_t box_triangle_count = 12;
196 static const uint16_t box_triangle_indices[box_triangle_count * 3] = {
197 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
198 };
199
200 Vector<uint8_t> vertex_data;
201 vertex_data.resize(sizeof(float) * box_vertex_count * 3);
202 memcpy(vertex_data.ptrw(), box_vertices, vertex_data.size());
203
204 box_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
205
206 Vector<uint8_t> index_data;
207 index_data.resize(sizeof(uint16_t) * box_triangle_count * 3);
208 memcpy(index_data.ptrw(), box_triangle_indices, index_data.size());
209
210 box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT16, index_data);
211
212 Vector<RID> buffers;
213 buffers.push_back(box_vertex_buffer);
214
215 box_vertex_array = RD::get_singleton()->vertex_array_create(box_vertex_count, vertex_format, buffers);
216
217 box_index_array = RD::get_singleton()->index_array_create(box_index_buffer, 0, box_triangle_count * 3);
218 }
219}
220ClusterBuilderSharedDataRD::~ClusterBuilderSharedDataRD() {
221 RD::get_singleton()->free(sphere_vertex_buffer);
222 RD::get_singleton()->free(sphere_index_buffer);
223 RD::get_singleton()->free(cone_vertex_buffer);
224 RD::get_singleton()->free(cone_index_buffer);
225 RD::get_singleton()->free(box_vertex_buffer);
226 RD::get_singleton()->free(box_index_buffer);
227
228 cluster_render.cluster_render_shader.version_free(cluster_render.shader_version);
229 cluster_store.cluster_store_shader.version_free(cluster_store.shader_version);
230 cluster_debug.cluster_debug_shader.version_free(cluster_debug.shader_version);
231}
232
233/////////////////////////////
234
235void ClusterBuilderRD::_clear() {
236 if (cluster_buffer.is_null()) {
237 return;
238 }
239
240 RD::get_singleton()->free(cluster_buffer);
241 RD::get_singleton()->free(cluster_render_buffer);
242 RD::get_singleton()->free(element_buffer);
243 cluster_buffer = RID();
244 cluster_render_buffer = RID();
245 element_buffer = RID();
246
247 memfree(render_elements);
248
249 render_elements = nullptr;
250 render_element_max = 0;
251 render_element_count = 0;
252
253 RD::get_singleton()->free(framebuffer);
254 framebuffer = RID();
255
256 cluster_render_uniform_set = RID();
257 cluster_store_uniform_set = RID();
258}
259
260void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer) {
261 ERR_FAIL_COND(p_max_elements == 0);
262 ERR_FAIL_COND(p_screen_size.x < 1);
263 ERR_FAIL_COND(p_screen_size.y < 1);
264
265 _clear();
266
267 screen_size = p_screen_size;
268
269 cluster_screen_size.width = (p_screen_size.width - 1) / cluster_size + 1;
270 cluster_screen_size.height = (p_screen_size.height - 1) / cluster_size + 1;
271
272 max_elements_by_type = p_max_elements;
273 if (max_elements_by_type % 32) { // Needs to be aligned to 32.
274 max_elements_by_type += 32 - (max_elements_by_type % 32);
275 }
276
277 cluster_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (max_elements_by_type / 32 + 32) * ELEMENT_TYPE_MAX * 4;
278
279 render_element_max = max_elements_by_type * ELEMENT_TYPE_MAX;
280
281 uint32_t element_tag_bits_size = render_element_max / 32;
282 uint32_t element_tag_depth_bits_size = render_element_max;
283
284 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).
285
286 cluster_render_buffer = RD::get_singleton()->storage_buffer_create(cluster_render_buffer_size);
287 cluster_buffer = RD::get_singleton()->storage_buffer_create(cluster_buffer_size);
288
289 render_elements = static_cast<RenderElementData *>(memalloc(sizeof(RenderElementData) * render_element_max));
290 render_element_count = 0;
291
292 element_buffer = RD::get_singleton()->storage_buffer_create(sizeof(RenderElementData) * render_element_max);
293
294 uint32_t div_value = 1 << divisor;
295 if (use_msaa) {
296 framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value, RD::TEXTURE_SAMPLES_4);
297 } else {
298 framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value);
299 }
300
301 {
302 Vector<RD::Uniform> uniforms;
303 {
304 RD::Uniform u;
305 u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
306 u.binding = 1;
307 u.append_id(state_uniform);
308 uniforms.push_back(u);
309 }
310 {
311 RD::Uniform u;
312 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
313 u.binding = 2;
314 u.append_id(element_buffer);
315 uniforms.push_back(u);
316 }
317 {
318 RD::Uniform u;
319 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
320 u.binding = 3;
321 u.append_id(cluster_render_buffer);
322 uniforms.push_back(u);
323 }
324
325 cluster_render_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_render.shader, 0);
326 }
327
328 {
329 Vector<RD::Uniform> uniforms;
330 {
331 RD::Uniform u;
332 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
333 u.binding = 1;
334 u.append_id(cluster_render_buffer);
335 uniforms.push_back(u);
336 }
337 {
338 RD::Uniform u;
339 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
340 u.binding = 2;
341 u.append_id(cluster_buffer);
342 uniforms.push_back(u);
343 }
344
345 {
346 RD::Uniform u;
347 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
348 u.binding = 3;
349 u.append_id(element_buffer);
350 uniforms.push_back(u);
351 }
352
353 cluster_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_store.shader, 0);
354 }
355
356 if (p_color_buffer.is_valid()) {
357 Vector<RD::Uniform> uniforms;
358 {
359 RD::Uniform u;
360 u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
361 u.binding = 1;
362 u.append_id(cluster_buffer);
363 uniforms.push_back(u);
364 }
365 {
366 RD::Uniform u;
367 u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
368 u.binding = 2;
369 u.append_id(p_color_buffer);
370 uniforms.push_back(u);
371 }
372
373 {
374 RD::Uniform u;
375 u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
376 u.binding = 3;
377 u.append_id(p_depth_buffer);
378 uniforms.push_back(u);
379 }
380 {
381 RD::Uniform u;
382 u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
383 u.binding = 4;
384 u.append_id(p_depth_buffer_sampler);
385 uniforms.push_back(u);
386 }
387
388 debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_debug.shader, 0);
389 } else {
390 debug_uniform_set = RID();
391 }
392}
393
394void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y) {
395 view_xform = p_view_transform.affine_inverse();
396 projection = p_cam_projection;
397 z_near = projection.get_z_near();
398 z_far = projection.get_z_far();
399 camera_orthogonal = p_cam_projection.is_orthogonal();
400 adjusted_projection = projection;
401 if (!camera_orthogonal) {
402 adjusted_projection.adjust_perspective_znear(0.0001);
403 }
404
405 Projection correction;
406 correction.set_depth_correction(p_flip_y);
407 projection = correction * projection;
408 adjusted_projection = correction * adjusted_projection;
409
410 // Reset counts.
411 render_element_count = 0;
412 for (uint32_t i = 0; i < ELEMENT_TYPE_MAX; i++) {
413 cluster_count_by_type[i] = 0;
414 }
415}
416
417void ClusterBuilderRD::bake_cluster() {
418 RENDER_TIMESTAMP("> Bake 3D Cluster");
419
420 RD::get_singleton()->draw_command_begin_label("Bake Light Cluster");
421
422 // Clear cluster buffer.
423 RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
424
425 if (render_element_count > 0) {
426 // Clear render buffer.
427 RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size, RD::BARRIER_MASK_RASTER);
428
429 { // Fill state uniform.
430
431 StateUniform state;
432
433 RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection);
434 state.inv_z_far = 1.0 / z_far;
435 state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);
436 state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less
437
438 state.cluster_screen_width = cluster_screen_size.x;
439 state.cluster_depth_offset = (render_element_max / 32);
440 state.cluster_data_size = state.cluster_depth_offset + render_element_max;
441
442 RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
443 }
444
445 // Update instances.
446
447 RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
448
449 RENDER_TIMESTAMP("Render 3D Cluster Elements");
450
451 // Render elements.
452 {
453 RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
454 ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {};
455
456 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]);
457 RD::get_singleton()->draw_list_bind_uniform_set(draw_list, cluster_render_uniform_set, 0);
458
459 for (uint32_t i = 0; i < render_element_count;) {
460 push_constant.base_index = i;
461 switch (render_elements[i].type) {
462 case ELEMENT_TYPE_OMNI_LIGHT: {
463 RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);
464 RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
465 } break;
466 case ELEMENT_TYPE_SPOT_LIGHT: {
467 // If the spot angle is above a certain threshold, use a sphere instead of a cone for building the clusters
468 // since the cone gets too flat/large (spot angle close to 90 degrees) or
469 // can't even cover the affected area of the light (spot angle above 90 degrees).
470 if (render_elements[i].has_wide_spot_angle) {
471 RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);
472 RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
473 } else {
474 RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array);
475 RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array);
476 }
477 } break;
478 case ELEMENT_TYPE_DECAL:
479 case ELEMENT_TYPE_REFLECTION_PROBE: {
480 RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->box_vertex_array);
481 RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->box_index_array);
482 } break;
483 }
484
485 RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterRender::PushConstant));
486
487 uint32_t instances = 1;
488 RD::get_singleton()->draw_list_draw(draw_list, true, instances);
489 i += instances;
490 }
491 RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE);
492 }
493 // Store elements.
494 RENDER_TIMESTAMP("Pack 3D Cluster Elements");
495
496 {
497 RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
498 RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_store.shader_pipeline);
499 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cluster_store_uniform_set, 0);
500
501 ClusterBuilderSharedDataRD::ClusterStore::PushConstant push_constant;
502 push_constant.cluster_render_data_size = render_element_max / 32 + render_element_max;
503 push_constant.max_render_element_count_div_32 = render_element_max / 32;
504 push_constant.cluster_screen_size[0] = cluster_screen_size.x;
505 push_constant.cluster_screen_size[1] = cluster_screen_size.y;
506 push_constant.render_element_count_div_32 = render_element_count > 0 ? (render_element_count - 1) / 32 + 1 : 0;
507 push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
508 push_constant.pad1 = 0;
509 push_constant.pad2 = 0;
510
511 RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterStore::PushConstant));
512
513 RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1);
514
515 RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
516 }
517 } else {
518 RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
519 }
520 RENDER_TIMESTAMP("< Bake 3D Cluster");
521 RD::get_singleton()->draw_command_end_label();
522}
523
524void ClusterBuilderRD::debug(ElementType p_element) {
525 ERR_FAIL_COND(debug_uniform_set.is_null());
526 RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
527 RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_debug.shader_pipeline);
528 RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0);
529
530 ClusterBuilderSharedDataRD::ClusterDebug::PushConstant push_constant;
531 push_constant.screen_size[0] = screen_size.x;
532 push_constant.screen_size[1] = screen_size.y;
533 push_constant.cluster_screen_size[0] = cluster_screen_size.x;
534 push_constant.cluster_screen_size[1] = cluster_screen_size.y;
535 push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size);
536 push_constant.cluster_type = p_element;
537 push_constant.orthogonal = camera_orthogonal;
538 push_constant.z_far = z_far;
539 push_constant.z_near = z_near;
540 push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
541
542 RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterDebug::PushConstant));
543
544 RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1);
545
546 RD::get_singleton()->compute_list_end();
547}
548
549RID ClusterBuilderRD::get_cluster_buffer() const {
550 return cluster_buffer;
551}
552
553uint32_t ClusterBuilderRD::get_cluster_size() const {
554 return cluster_size;
555}
556
557uint32_t ClusterBuilderRD::get_max_cluster_elements() const {
558 return max_elements_by_type;
559}
560
561void ClusterBuilderRD::set_shared(ClusterBuilderSharedDataRD *p_shared) {
562 shared = p_shared;
563}
564
565ClusterBuilderRD::ClusterBuilderRD() {
566 state_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(StateUniform));
567}
568
569ClusterBuilderRD::~ClusterBuilderRD() {
570 _clear();
571 RD::get_singleton()->free(state_uniform);
572}
573