1 | /**************************************************************************/ |
2 | /* gi.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 "gi.h" |
32 | |
33 | #include "core/config/project_settings.h" |
34 | #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" |
35 | #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" |
36 | #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" |
37 | #include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h" |
38 | #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" |
39 | #include "servers/rendering/rendering_server_default.h" |
40 | |
41 | using namespace RendererRD; |
42 | |
43 | const Vector3i GI::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF); |
44 | |
45 | GI *GI::singleton = nullptr; |
46 | |
47 | //////////////////////////////////////////////////////////////////////////////// |
48 | // VOXEL GI STORAGE |
49 | |
50 | RID GI::voxel_gi_allocate() { |
51 | return voxel_gi_owner.allocate_rid(); |
52 | } |
53 | |
54 | void GI::voxel_gi_free(RID p_voxel_gi) { |
55 | voxel_gi_allocate_data(p_voxel_gi, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate |
56 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
57 | voxel_gi->dependency.deleted_notify(p_voxel_gi); |
58 | voxel_gi_owner.free(p_voxel_gi); |
59 | } |
60 | |
61 | void GI::voxel_gi_initialize(RID p_voxel_gi) { |
62 | voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI()); |
63 | } |
64 | |
65 | void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { |
66 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
67 | ERR_FAIL_COND(!voxel_gi); |
68 | |
69 | if (voxel_gi->octree_buffer.is_valid()) { |
70 | RD::get_singleton()->free(voxel_gi->octree_buffer); |
71 | RD::get_singleton()->free(voxel_gi->data_buffer); |
72 | if (voxel_gi->sdf_texture.is_valid()) { |
73 | RD::get_singleton()->free(voxel_gi->sdf_texture); |
74 | } |
75 | |
76 | voxel_gi->sdf_texture = RID(); |
77 | voxel_gi->octree_buffer = RID(); |
78 | voxel_gi->data_buffer = RID(); |
79 | voxel_gi->octree_buffer_size = 0; |
80 | voxel_gi->data_buffer_size = 0; |
81 | voxel_gi->cell_count = 0; |
82 | } |
83 | |
84 | voxel_gi->to_cell_xform = p_to_cell_xform; |
85 | voxel_gi->bounds = p_aabb; |
86 | voxel_gi->octree_size = p_octree_size; |
87 | voxel_gi->level_counts = p_level_counts; |
88 | |
89 | if (p_octree_cells.size()) { |
90 | ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32 |
91 | |
92 | uint32_t cell_count = p_octree_cells.size() / 32; |
93 | |
94 | ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches |
95 | |
96 | voxel_gi->cell_count = cell_count; |
97 | voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells); |
98 | voxel_gi->octree_buffer_size = p_octree_cells.size(); |
99 | voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells); |
100 | voxel_gi->data_buffer_size = p_data_cells.size(); |
101 | |
102 | if (p_distance_field.size()) { |
103 | RD::TextureFormat tf; |
104 | tf.format = RD::DATA_FORMAT_R8_UNORM; |
105 | tf.width = voxel_gi->octree_size.x; |
106 | tf.height = voxel_gi->octree_size.y; |
107 | tf.depth = voxel_gi->octree_size.z; |
108 | tf.texture_type = RD::TEXTURE_TYPE_3D; |
109 | tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; |
110 | Vector<Vector<uint8_t>> s; |
111 | s.push_back(p_distance_field); |
112 | voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s); |
113 | RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture" ); |
114 | } |
115 | #if 0 |
116 | { |
117 | RD::TextureFormat tf; |
118 | tf.format = RD::DATA_FORMAT_R8_UNORM; |
119 | tf.width = voxel_gi->octree_size.x; |
120 | tf.height = voxel_gi->octree_size.y; |
121 | tf.depth = voxel_gi->octree_size.z; |
122 | tf.type = RD::TEXTURE_TYPE_3D; |
123 | tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; |
124 | tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM); |
125 | tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT); |
126 | voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
127 | RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture" ); |
128 | } |
129 | RID shared_tex; |
130 | { |
131 | RD::TextureView tv; |
132 | tv.format_override = RD::DATA_FORMAT_R8_UINT; |
133 | shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture); |
134 | } |
135 | //update SDF texture |
136 | Vector<RD::Uniform> uniforms; |
137 | { |
138 | RD::Uniform u; |
139 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
140 | u.binding = 1; |
141 | u.append_id(voxel_gi->octree_buffer); |
142 | uniforms.push_back(u); |
143 | } |
144 | { |
145 | RD::Uniform u; |
146 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
147 | u.binding = 2; |
148 | u.append_id(voxel_gi->data_buffer); |
149 | uniforms.push_back(u); |
150 | } |
151 | { |
152 | RD::Uniform u; |
153 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
154 | u.binding = 3; |
155 | u.append_id(shared_tex); |
156 | uniforms.push_back(u); |
157 | } |
158 | |
159 | RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0); |
160 | |
161 | { |
162 | uint32_t push_constant[4] = { 0, 0, 0, 0 }; |
163 | |
164 | for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) { |
165 | push_constant[0] += voxel_gi->level_counts[i]; |
166 | } |
167 | push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1]; |
168 | |
169 | print_line("offset: " + itos(push_constant[0])); |
170 | print_line("size: " + itos(push_constant[1])); |
171 | //create SDF |
172 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
173 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline); |
174 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0); |
175 | RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4); |
176 | RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4); |
177 | RD::get_singleton()->compute_list_end(); |
178 | } |
179 | |
180 | RD::get_singleton()->free(uniform_set); |
181 | RD::get_singleton()->free(shared_tex); |
182 | } |
183 | #endif |
184 | } |
185 | |
186 | voxel_gi->version++; |
187 | voxel_gi->data_version++; |
188 | |
189 | voxel_gi->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); |
190 | } |
191 | |
192 | AABB GI::voxel_gi_get_bounds(RID p_voxel_gi) const { |
193 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
194 | ERR_FAIL_COND_V(!voxel_gi, AABB()); |
195 | |
196 | return voxel_gi->bounds; |
197 | } |
198 | |
199 | Vector3i GI::voxel_gi_get_octree_size(RID p_voxel_gi) const { |
200 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
201 | ERR_FAIL_COND_V(!voxel_gi, Vector3i()); |
202 | return voxel_gi->octree_size; |
203 | } |
204 | |
205 | Vector<uint8_t> GI::voxel_gi_get_octree_cells(RID p_voxel_gi) const { |
206 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
207 | ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); |
208 | |
209 | if (voxel_gi->octree_buffer.is_valid()) { |
210 | return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer); |
211 | } |
212 | return Vector<uint8_t>(); |
213 | } |
214 | |
215 | Vector<uint8_t> GI::voxel_gi_get_data_cells(RID p_voxel_gi) const { |
216 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
217 | ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); |
218 | |
219 | if (voxel_gi->data_buffer.is_valid()) { |
220 | return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer); |
221 | } |
222 | return Vector<uint8_t>(); |
223 | } |
224 | |
225 | Vector<uint8_t> GI::voxel_gi_get_distance_field(RID p_voxel_gi) const { |
226 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
227 | ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); |
228 | |
229 | if (voxel_gi->data_buffer.is_valid()) { |
230 | return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0); |
231 | } |
232 | return Vector<uint8_t>(); |
233 | } |
234 | |
235 | Vector<int> GI::voxel_gi_get_level_counts(RID p_voxel_gi) const { |
236 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
237 | ERR_FAIL_COND_V(!voxel_gi, Vector<int>()); |
238 | |
239 | return voxel_gi->level_counts; |
240 | } |
241 | |
242 | Transform3D GI::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const { |
243 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
244 | ERR_FAIL_COND_V(!voxel_gi, Transform3D()); |
245 | |
246 | return voxel_gi->to_cell_xform; |
247 | } |
248 | |
249 | void GI::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) { |
250 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
251 | ERR_FAIL_COND(!voxel_gi); |
252 | |
253 | voxel_gi->dynamic_range = p_range; |
254 | voxel_gi->version++; |
255 | } |
256 | |
257 | float GI::voxel_gi_get_dynamic_range(RID p_voxel_gi) const { |
258 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
259 | ERR_FAIL_COND_V(!voxel_gi, 0); |
260 | |
261 | return voxel_gi->dynamic_range; |
262 | } |
263 | |
264 | void GI::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) { |
265 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
266 | ERR_FAIL_COND(!voxel_gi); |
267 | |
268 | voxel_gi->propagation = p_range; |
269 | voxel_gi->version++; |
270 | } |
271 | |
272 | float GI::voxel_gi_get_propagation(RID p_voxel_gi) const { |
273 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
274 | ERR_FAIL_COND_V(!voxel_gi, 0); |
275 | return voxel_gi->propagation; |
276 | } |
277 | |
278 | void GI::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) { |
279 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
280 | ERR_FAIL_COND(!voxel_gi); |
281 | |
282 | voxel_gi->energy = p_energy; |
283 | } |
284 | |
285 | float GI::voxel_gi_get_energy(RID p_voxel_gi) const { |
286 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
287 | ERR_FAIL_COND_V(!voxel_gi, 0); |
288 | return voxel_gi->energy; |
289 | } |
290 | |
291 | void GI::voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) { |
292 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
293 | ERR_FAIL_COND(!voxel_gi); |
294 | |
295 | voxel_gi->baked_exposure = p_baked_exposure; |
296 | } |
297 | |
298 | float GI::voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const { |
299 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
300 | ERR_FAIL_COND_V(!voxel_gi, 0); |
301 | return voxel_gi->baked_exposure; |
302 | } |
303 | |
304 | void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) { |
305 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
306 | ERR_FAIL_COND(!voxel_gi); |
307 | |
308 | voxel_gi->bias = p_bias; |
309 | } |
310 | |
311 | float GI::voxel_gi_get_bias(RID p_voxel_gi) const { |
312 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
313 | ERR_FAIL_COND_V(!voxel_gi, 0); |
314 | return voxel_gi->bias; |
315 | } |
316 | |
317 | void GI::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) { |
318 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
319 | ERR_FAIL_COND(!voxel_gi); |
320 | |
321 | voxel_gi->normal_bias = p_normal_bias; |
322 | } |
323 | |
324 | float GI::voxel_gi_get_normal_bias(RID p_voxel_gi) const { |
325 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
326 | ERR_FAIL_COND_V(!voxel_gi, 0); |
327 | return voxel_gi->normal_bias; |
328 | } |
329 | |
330 | void GI::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) { |
331 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
332 | ERR_FAIL_COND(!voxel_gi); |
333 | |
334 | voxel_gi->interior = p_enable; |
335 | } |
336 | |
337 | void GI::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) { |
338 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
339 | ERR_FAIL_COND(!voxel_gi); |
340 | |
341 | voxel_gi->use_two_bounces = p_enable; |
342 | voxel_gi->version++; |
343 | } |
344 | |
345 | bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const { |
346 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
347 | ERR_FAIL_COND_V(!voxel_gi, false); |
348 | return voxel_gi->use_two_bounces; |
349 | } |
350 | |
351 | bool GI::voxel_gi_is_interior(RID p_voxel_gi) const { |
352 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
353 | ERR_FAIL_COND_V(!voxel_gi, 0); |
354 | return voxel_gi->interior; |
355 | } |
356 | |
357 | uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const { |
358 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
359 | ERR_FAIL_COND_V(!voxel_gi, 0); |
360 | return voxel_gi->version; |
361 | } |
362 | |
363 | uint32_t GI::voxel_gi_get_data_version(RID p_voxel_gi) { |
364 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
365 | ERR_FAIL_COND_V(!voxel_gi, 0); |
366 | return voxel_gi->data_version; |
367 | } |
368 | |
369 | RID GI::voxel_gi_get_octree_buffer(RID p_voxel_gi) const { |
370 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
371 | ERR_FAIL_COND_V(!voxel_gi, RID()); |
372 | return voxel_gi->octree_buffer; |
373 | } |
374 | |
375 | RID GI::voxel_gi_get_data_buffer(RID p_voxel_gi) const { |
376 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
377 | ERR_FAIL_COND_V(!voxel_gi, RID()); |
378 | return voxel_gi->data_buffer; |
379 | } |
380 | |
381 | RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) { |
382 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
383 | ERR_FAIL_COND_V(!voxel_gi, RID()); |
384 | |
385 | return voxel_gi->sdf_texture; |
386 | } |
387 | |
388 | Dependency *GI::voxel_gi_get_dependency(RID p_voxel_gi) const { |
389 | VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); |
390 | ERR_FAIL_COND_V(!voxel_gi, nullptr); |
391 | |
392 | return &voxel_gi->dependency; |
393 | } |
394 | |
395 | //////////////////////////////////////////////////////////////////////////////// |
396 | // SDFGI |
397 | |
398 | static RID create_clear_texture(const RD::TextureFormat &p_format, const String &p_name) { |
399 | RID texture = RD::get_singleton()->texture_create(p_format, RD::TextureView()); |
400 | ERR_FAIL_COND_V_MSG(texture.is_null(), RID(), String("Cannot create texture: " ) + p_name); |
401 | |
402 | RD::get_singleton()->set_resource_name(texture, p_name); |
403 | RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, p_format.mipmaps, 0, p_format.array_layers); |
404 | |
405 | return texture; |
406 | } |
407 | |
408 | void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) { |
409 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
410 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
411 | |
412 | gi = p_gi; |
413 | num_cascades = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_cascades(p_env); |
414 | min_cell_size = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_min_cell_size(p_env); |
415 | uses_occlusion = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_use_occlusion(p_env); |
416 | y_scale_mode = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_y_scale(p_env); |
417 | static const float y_scale[3] = { 2.0, 1.5, 1.0 }; |
418 | y_mult = y_scale[y_scale_mode]; |
419 | cascades.resize(num_cascades); |
420 | probe_axis_count = SDFGI::PROBE_DIVISOR + 1; |
421 | solid_cell_ratio = gi->sdfgi_solid_cell_ratio; |
422 | solid_cell_count = uint32_t(float(cascade_size * cascade_size * cascade_size) * solid_cell_ratio); |
423 | |
424 | float base_cell_size = min_cell_size; |
425 | |
426 | RD::TextureFormat tf_sdf; |
427 | tf_sdf.format = RD::DATA_FORMAT_R8_UNORM; |
428 | tf_sdf.width = cascade_size; // Always 64x64 |
429 | tf_sdf.height = cascade_size; |
430 | tf_sdf.depth = cascade_size; |
431 | tf_sdf.texture_type = RD::TEXTURE_TYPE_3D; |
432 | tf_sdf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; |
433 | |
434 | { |
435 | RD::TextureFormat tf_render = tf_sdf; |
436 | tf_render.format = RD::DATA_FORMAT_R16_UINT; |
437 | render_albedo = create_clear_texture(tf_render, "SDFGI Render Albedo" ); |
438 | |
439 | tf_render.format = RD::DATA_FORMAT_R32_UINT; |
440 | render_emission = create_clear_texture(tf_render, "SDFGI Render Emission" ); |
441 | render_emission_aniso = create_clear_texture(tf_render, "SDFGI Render Emission Aniso" ); |
442 | |
443 | tf_render.format = RD::DATA_FORMAT_R8_UNORM; //at least its easy to visualize |
444 | |
445 | for (int i = 0; i < 8; i++) { |
446 | render_occlusion[i] = create_clear_texture(tf_render, String("SDFGI Render Occlusion " ) + itos(i)); |
447 | } |
448 | |
449 | tf_render.format = RD::DATA_FORMAT_R32_UINT; |
450 | render_geom_facing = create_clear_texture(tf_render, "SDFGI Render Geometry Facing" ); |
451 | |
452 | tf_render.format = RD::DATA_FORMAT_R8G8B8A8_UINT; |
453 | render_sdf[0] = create_clear_texture(tf_render, "SDFGI Render SDF 0" ); |
454 | render_sdf[1] = create_clear_texture(tf_render, "SDFGI Render SDF 1" ); |
455 | |
456 | tf_render.width /= 2; |
457 | tf_render.height /= 2; |
458 | tf_render.depth /= 2; |
459 | |
460 | render_sdf_half[0] = create_clear_texture(tf_render, "SDFGI Render SDF Half 0" ); |
461 | render_sdf_half[1] = create_clear_texture(tf_render, "SDFGI Render SDF Half 1" ); |
462 | } |
463 | |
464 | RD::TextureFormat tf_occlusion = tf_sdf; |
465 | tf_occlusion.format = RD::DATA_FORMAT_R16_UINT; |
466 | tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R16_UINT); |
467 | tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16); |
468 | tf_occlusion.depth *= cascades.size(); //use depth for occlusion slices |
469 | tf_occlusion.width *= 2; //use width for the other half |
470 | |
471 | RD::TextureFormat tf_light = tf_sdf; |
472 | tf_light.format = RD::DATA_FORMAT_R32_UINT; |
473 | tf_light.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT); |
474 | tf_light.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32); |
475 | |
476 | RD::TextureFormat tf_aniso0 = tf_sdf; |
477 | tf_aniso0.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; |
478 | RD::TextureFormat tf_aniso1 = tf_sdf; |
479 | tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM; |
480 | |
481 | int passes = nearest_shift(cascade_size) - 1; |
482 | |
483 | //store lightprobe SH |
484 | RD::TextureFormat tf_probes; |
485 | tf_probes.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; |
486 | tf_probes.width = probe_axis_count * probe_axis_count; |
487 | tf_probes.height = probe_axis_count * SDFGI::SH_SIZE; |
488 | tf_probes.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; |
489 | tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; |
490 | |
491 | history_size = p_requested_history_size; |
492 | |
493 | RD::TextureFormat tf_probe_history = tf_probes; |
494 | tf_probe_history.format = RD::DATA_FORMAT_R16G16B16A16_SINT; //signed integer because SH are signed |
495 | tf_probe_history.array_layers = history_size; |
496 | |
497 | RD::TextureFormat tf_probe_average = tf_probes; |
498 | tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed |
499 | tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D; |
500 | |
501 | lightprobe_history_scroll = create_clear_texture(tf_probe_history, "SDFGI LightProbe History Scroll" ); |
502 | lightprobe_average_scroll = create_clear_texture(tf_probe_average, "SDFGI LightProbe Average Scroll" ); |
503 | |
504 | { |
505 | //octahedral lightprobes |
506 | RD::TextureFormat tf_octprobes = tf_probes; |
507 | tf_octprobes.array_layers = cascades.size() * 2; |
508 | tf_octprobes.format = RD::DATA_FORMAT_R32_UINT; //pack well with RGBE |
509 | tf_octprobes.width = probe_axis_count * probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2); |
510 | tf_octprobes.height = probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2); |
511 | tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT); |
512 | tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32); |
513 | //lightprobe texture is an octahedral texture |
514 | |
515 | lightprobe_data = create_clear_texture(tf_octprobes, "SDFGI LightProbe Data" ); |
516 | RD::TextureView tv; |
517 | tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32; |
518 | lightprobe_texture = RD::get_singleton()->texture_create_shared(tv, lightprobe_data); |
519 | |
520 | //texture handling ambient data, to integrate with volumetric foc |
521 | RD::TextureFormat tf_ambient = tf_probes; |
522 | tf_ambient.array_layers = cascades.size(); |
523 | tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE |
524 | tf_ambient.width = probe_axis_count * probe_axis_count; |
525 | tf_ambient.height = probe_axis_count; |
526 | tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; |
527 | //lightprobe texture is an octahedral texture |
528 | ambient_texture = create_clear_texture(tf_ambient, "SDFGI Ambient Texture" ); |
529 | } |
530 | |
531 | cascades_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES); |
532 | |
533 | occlusion_data = create_clear_texture(tf_occlusion, "SDFGI Occlusion Data" ); |
534 | { |
535 | RD::TextureView tv; |
536 | tv.format_override = RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16; |
537 | occlusion_texture = RD::get_singleton()->texture_create_shared(tv, occlusion_data); |
538 | } |
539 | |
540 | for (SDFGI::Cascade &cascade : cascades) { |
541 | /* 3D Textures */ |
542 | |
543 | cascade.sdf_tex = create_clear_texture(tf_sdf, "SDFGI Cascade SDF Texture" ); |
544 | |
545 | cascade.light_data = create_clear_texture(tf_light, "SDFGI Cascade Light Data" ); |
546 | |
547 | cascade.light_aniso_0_tex = create_clear_texture(tf_aniso0, "SDFGI Cascade Light Aniso 0 Texture" ); |
548 | cascade.light_aniso_1_tex = create_clear_texture(tf_aniso1, "SDFGI Cascade Light Aniso 1 Texture" ); |
549 | |
550 | { |
551 | RD::TextureView tv; |
552 | tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32; |
553 | cascade.light_tex = RD::get_singleton()->texture_create_shared(tv, cascade.light_data); |
554 | } |
555 | |
556 | cascade.cell_size = base_cell_size; |
557 | Vector3 world_position = p_world_position; |
558 | world_position.y *= y_mult; |
559 | int32_t probe_cells = cascade_size / SDFGI::PROBE_DIVISOR; |
560 | Vector3 probe_size = Vector3(1, 1, 1) * cascade.cell_size * probe_cells; |
561 | Vector3i probe_pos = Vector3i((world_position / probe_size + Vector3(0.5, 0.5, 0.5)).floor()); |
562 | cascade.position = probe_pos * probe_cells; |
563 | |
564 | cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL; |
565 | |
566 | base_cell_size *= 2.0; |
567 | |
568 | /* Probe History */ |
569 | |
570 | cascade.lightprobe_history_tex = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView()); |
571 | RD::get_singleton()->set_resource_name(cascade.lightprobe_history_tex, "SDFGI Cascade LightProbe History Texture" ); |
572 | RD::get_singleton()->texture_clear(cascade.lightprobe_history_tex, Color(0, 0, 0, 0), 0, 1, 0, tf_probe_history.array_layers); //needs to be cleared for average to work |
573 | |
574 | cascade.lightprobe_average_tex = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView()); |
575 | RD::get_singleton()->set_resource_name(cascade.lightprobe_average_tex, "SDFGI Cascade LightProbe Average Texture" ); |
576 | RD::get_singleton()->texture_clear(cascade.lightprobe_average_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); //needs to be cleared for average to work |
577 | |
578 | /* Buffers */ |
579 | |
580 | cascade.solid_cell_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGI::Cascade::SolidCell) * solid_cell_count); |
581 | cascade.solid_cell_dispatch_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT); |
582 | cascade.lights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGIShader::Light) * MAX(SDFGI::MAX_STATIC_LIGHTS, SDFGI::MAX_DYNAMIC_LIGHTS)); |
583 | { |
584 | Vector<RD::Uniform> uniforms; |
585 | { |
586 | RD::Uniform u; |
587 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
588 | u.binding = 1; |
589 | u.append_id(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1 |
590 | uniforms.push_back(u); |
591 | } |
592 | { |
593 | RD::Uniform u; |
594 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
595 | u.binding = 2; |
596 | u.append_id(render_albedo); |
597 | uniforms.push_back(u); |
598 | } |
599 | { |
600 | RD::Uniform u; |
601 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
602 | u.binding = 3; |
603 | for (int j = 0; j < 8; j++) { |
604 | u.append_id(render_occlusion[j]); |
605 | } |
606 | uniforms.push_back(u); |
607 | } |
608 | { |
609 | RD::Uniform u; |
610 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
611 | u.binding = 4; |
612 | u.append_id(render_emission); |
613 | uniforms.push_back(u); |
614 | } |
615 | { |
616 | RD::Uniform u; |
617 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
618 | u.binding = 5; |
619 | u.append_id(render_emission_aniso); |
620 | uniforms.push_back(u); |
621 | } |
622 | { |
623 | RD::Uniform u; |
624 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
625 | u.binding = 6; |
626 | u.append_id(render_geom_facing); |
627 | uniforms.push_back(u); |
628 | } |
629 | |
630 | { |
631 | RD::Uniform u; |
632 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
633 | u.binding = 7; |
634 | u.append_id(cascade.sdf_tex); |
635 | uniforms.push_back(u); |
636 | } |
637 | { |
638 | RD::Uniform u; |
639 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
640 | u.binding = 8; |
641 | u.append_id(occlusion_data); |
642 | uniforms.push_back(u); |
643 | } |
644 | { |
645 | RD::Uniform u; |
646 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
647 | u.binding = 10; |
648 | u.append_id(cascade.solid_cell_dispatch_buffer); |
649 | uniforms.push_back(u); |
650 | } |
651 | { |
652 | RD::Uniform u; |
653 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
654 | u.binding = 11; |
655 | u.append_id(cascade.solid_cell_buffer); |
656 | uniforms.push_back(u); |
657 | } |
658 | |
659 | cascade.sdf_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_STORE), 0); |
660 | } |
661 | |
662 | { |
663 | Vector<RD::Uniform> uniforms; |
664 | { |
665 | RD::Uniform u; |
666 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
667 | u.binding = 1; |
668 | u.append_id(render_albedo); |
669 | uniforms.push_back(u); |
670 | } |
671 | { |
672 | RD::Uniform u; |
673 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
674 | u.binding = 2; |
675 | u.append_id(render_geom_facing); |
676 | uniforms.push_back(u); |
677 | } |
678 | { |
679 | RD::Uniform u; |
680 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
681 | u.binding = 3; |
682 | u.append_id(render_emission); |
683 | uniforms.push_back(u); |
684 | } |
685 | { |
686 | RD::Uniform u; |
687 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
688 | u.binding = 4; |
689 | u.append_id(render_emission_aniso); |
690 | uniforms.push_back(u); |
691 | } |
692 | { |
693 | RD::Uniform u; |
694 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
695 | u.binding = 5; |
696 | u.append_id(cascade.solid_cell_dispatch_buffer); |
697 | uniforms.push_back(u); |
698 | } |
699 | { |
700 | RD::Uniform u; |
701 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
702 | u.binding = 6; |
703 | u.append_id(cascade.solid_cell_buffer); |
704 | uniforms.push_back(u); |
705 | } |
706 | |
707 | cascade.scroll_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_SCROLL), 0); |
708 | } |
709 | { |
710 | Vector<RD::Uniform> uniforms; |
711 | { |
712 | RD::Uniform u; |
713 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
714 | u.binding = 1; |
715 | for (int j = 0; j < 8; j++) { |
716 | u.append_id(render_occlusion[j]); |
717 | } |
718 | uniforms.push_back(u); |
719 | } |
720 | { |
721 | RD::Uniform u; |
722 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
723 | u.binding = 2; |
724 | u.append_id(occlusion_data); |
725 | uniforms.push_back(u); |
726 | } |
727 | |
728 | cascade.scroll_occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION), 0); |
729 | } |
730 | } |
731 | |
732 | //direct light |
733 | for (SDFGI::Cascade &cascade : cascades) { |
734 | Vector<RD::Uniform> uniforms; |
735 | { |
736 | RD::Uniform u; |
737 | u.binding = 1; |
738 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
739 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
740 | if (j < cascades.size()) { |
741 | u.append_id(cascades[j].sdf_tex); |
742 | } else { |
743 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
744 | } |
745 | } |
746 | uniforms.push_back(u); |
747 | } |
748 | { |
749 | RD::Uniform u; |
750 | u.binding = 2; |
751 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
752 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
753 | uniforms.push_back(u); |
754 | } |
755 | { |
756 | RD::Uniform u; |
757 | u.binding = 3; |
758 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
759 | u.append_id(cascade.solid_cell_dispatch_buffer); |
760 | uniforms.push_back(u); |
761 | } |
762 | { |
763 | RD::Uniform u; |
764 | u.binding = 4; |
765 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
766 | u.append_id(cascade.solid_cell_buffer); |
767 | uniforms.push_back(u); |
768 | } |
769 | { |
770 | RD::Uniform u; |
771 | u.binding = 5; |
772 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
773 | u.append_id(cascade.light_data); |
774 | uniforms.push_back(u); |
775 | } |
776 | { |
777 | RD::Uniform u; |
778 | u.binding = 6; |
779 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
780 | u.append_id(cascade.light_aniso_0_tex); |
781 | uniforms.push_back(u); |
782 | } |
783 | { |
784 | RD::Uniform u; |
785 | u.binding = 7; |
786 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
787 | u.append_id(cascade.light_aniso_1_tex); |
788 | uniforms.push_back(u); |
789 | } |
790 | { |
791 | RD::Uniform u; |
792 | u.binding = 8; |
793 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
794 | u.append_id(cascades_ubo); |
795 | uniforms.push_back(u); |
796 | } |
797 | { |
798 | RD::Uniform u; |
799 | u.binding = 9; |
800 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
801 | u.append_id(cascade.lights_buffer); |
802 | uniforms.push_back(u); |
803 | } |
804 | { |
805 | RD::Uniform u; |
806 | u.binding = 10; |
807 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
808 | u.append_id(lightprobe_texture); |
809 | uniforms.push_back(u); |
810 | } |
811 | { |
812 | RD::Uniform u; |
813 | u.binding = 11; |
814 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
815 | u.append_id(occlusion_texture); |
816 | uniforms.push_back(u); |
817 | } |
818 | |
819 | cascade.sdf_direct_light_static_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, SDFGIShader::DIRECT_LIGHT_MODE_STATIC), 0); |
820 | cascade.sdf_direct_light_dynamic_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC), 0); |
821 | } |
822 | |
823 | //preprocess initialize uniform set |
824 | { |
825 | Vector<RD::Uniform> uniforms; |
826 | { |
827 | RD::Uniform u; |
828 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
829 | u.binding = 1; |
830 | u.append_id(render_albedo); |
831 | uniforms.push_back(u); |
832 | } |
833 | { |
834 | RD::Uniform u; |
835 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
836 | u.binding = 2; |
837 | u.append_id(render_sdf[0]); |
838 | uniforms.push_back(u); |
839 | } |
840 | |
841 | sdf_initialize_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE), 0); |
842 | } |
843 | |
844 | { |
845 | Vector<RD::Uniform> uniforms; |
846 | { |
847 | RD::Uniform u; |
848 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
849 | u.binding = 1; |
850 | u.append_id(render_albedo); |
851 | uniforms.push_back(u); |
852 | } |
853 | { |
854 | RD::Uniform u; |
855 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
856 | u.binding = 2; |
857 | u.append_id(render_sdf_half[0]); |
858 | uniforms.push_back(u); |
859 | } |
860 | |
861 | sdf_initialize_half_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF), 0); |
862 | } |
863 | |
864 | //jump flood uniform set |
865 | { |
866 | Vector<RD::Uniform> uniforms; |
867 | { |
868 | RD::Uniform u; |
869 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
870 | u.binding = 1; |
871 | u.append_id(render_sdf[0]); |
872 | uniforms.push_back(u); |
873 | } |
874 | { |
875 | RD::Uniform u; |
876 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
877 | u.binding = 2; |
878 | u.append_id(render_sdf[1]); |
879 | uniforms.push_back(u); |
880 | } |
881 | |
882 | jump_flood_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); |
883 | RID aux0 = uniforms.write[0].get_id(0); |
884 | RID aux1 = uniforms.write[1].get_id(0); |
885 | uniforms.write[0].set_id(0, aux1); |
886 | uniforms.write[1].set_id(0, aux0); |
887 | jump_flood_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); |
888 | } |
889 | //jump flood half uniform set |
890 | { |
891 | Vector<RD::Uniform> uniforms; |
892 | { |
893 | RD::Uniform u; |
894 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
895 | u.binding = 1; |
896 | u.append_id(render_sdf_half[0]); |
897 | uniforms.push_back(u); |
898 | } |
899 | { |
900 | RD::Uniform u; |
901 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
902 | u.binding = 2; |
903 | u.append_id(render_sdf_half[1]); |
904 | uniforms.push_back(u); |
905 | } |
906 | |
907 | jump_flood_half_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); |
908 | RID aux0 = uniforms.write[0].get_id(0); |
909 | RID aux1 = uniforms.write[1].get_id(0); |
910 | uniforms.write[0].set_id(0, aux1); |
911 | uniforms.write[1].set_id(0, aux0); |
912 | jump_flood_half_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); |
913 | } |
914 | |
915 | //upscale half size sdf |
916 | { |
917 | Vector<RD::Uniform> uniforms; |
918 | { |
919 | RD::Uniform u; |
920 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
921 | u.binding = 1; |
922 | u.append_id(render_albedo); |
923 | uniforms.push_back(u); |
924 | } |
925 | { |
926 | RD::Uniform u; |
927 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
928 | u.binding = 2; |
929 | u.append_id(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size |
930 | uniforms.push_back(u); |
931 | } |
932 | { |
933 | RD::Uniform u; |
934 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
935 | u.binding = 3; |
936 | u.append_id(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass |
937 | uniforms.push_back(u); |
938 | } |
939 | |
940 | upscale_jfa_uniform_set_index = (passes & 1) ? 0 : 1; |
941 | sdf_upscale_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE), 0); |
942 | } |
943 | |
944 | //occlusion uniform set |
945 | { |
946 | Vector<RD::Uniform> uniforms; |
947 | { |
948 | RD::Uniform u; |
949 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
950 | u.binding = 1; |
951 | u.append_id(render_albedo); |
952 | uniforms.push_back(u); |
953 | } |
954 | { |
955 | RD::Uniform u; |
956 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
957 | u.binding = 2; |
958 | for (int i = 0; i < 8; i++) { |
959 | u.append_id(render_occlusion[i]); |
960 | } |
961 | uniforms.push_back(u); |
962 | } |
963 | { |
964 | RD::Uniform u; |
965 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
966 | u.binding = 3; |
967 | u.append_id(render_geom_facing); |
968 | uniforms.push_back(u); |
969 | } |
970 | |
971 | occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_OCCLUSION), 0); |
972 | } |
973 | |
974 | for (uint32_t i = 0; i < cascades.size(); i++) { |
975 | //integrate uniform |
976 | |
977 | Vector<RD::Uniform> uniforms; |
978 | |
979 | { |
980 | RD::Uniform u; |
981 | u.binding = 1; |
982 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
983 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
984 | if (j < cascades.size()) { |
985 | u.append_id(cascades[j].sdf_tex); |
986 | } else { |
987 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
988 | } |
989 | } |
990 | uniforms.push_back(u); |
991 | } |
992 | { |
993 | RD::Uniform u; |
994 | u.binding = 2; |
995 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
996 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
997 | if (j < cascades.size()) { |
998 | u.append_id(cascades[j].light_tex); |
999 | } else { |
1000 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1001 | } |
1002 | } |
1003 | uniforms.push_back(u); |
1004 | } |
1005 | { |
1006 | RD::Uniform u; |
1007 | u.binding = 3; |
1008 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1009 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
1010 | if (j < cascades.size()) { |
1011 | u.append_id(cascades[j].light_aniso_0_tex); |
1012 | } else { |
1013 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1014 | } |
1015 | } |
1016 | uniforms.push_back(u); |
1017 | } |
1018 | { |
1019 | RD::Uniform u; |
1020 | u.binding = 4; |
1021 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1022 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
1023 | if (j < cascades.size()) { |
1024 | u.append_id(cascades[j].light_aniso_1_tex); |
1025 | } else { |
1026 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1027 | } |
1028 | } |
1029 | uniforms.push_back(u); |
1030 | } |
1031 | { |
1032 | RD::Uniform u; |
1033 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
1034 | u.binding = 6; |
1035 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
1036 | uniforms.push_back(u); |
1037 | } |
1038 | |
1039 | { |
1040 | RD::Uniform u; |
1041 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
1042 | u.binding = 7; |
1043 | u.append_id(cascades_ubo); |
1044 | uniforms.push_back(u); |
1045 | } |
1046 | { |
1047 | RD::Uniform u; |
1048 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1049 | u.binding = 8; |
1050 | u.append_id(lightprobe_data); |
1051 | uniforms.push_back(u); |
1052 | } |
1053 | |
1054 | { |
1055 | RD::Uniform u; |
1056 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1057 | u.binding = 9; |
1058 | u.append_id(cascades[i].lightprobe_history_tex); |
1059 | uniforms.push_back(u); |
1060 | } |
1061 | { |
1062 | RD::Uniform u; |
1063 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1064 | u.binding = 10; |
1065 | u.append_id(cascades[i].lightprobe_average_tex); |
1066 | uniforms.push_back(u); |
1067 | } |
1068 | |
1069 | { |
1070 | RD::Uniform u; |
1071 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1072 | u.binding = 11; |
1073 | u.append_id(lightprobe_history_scroll); |
1074 | uniforms.push_back(u); |
1075 | } |
1076 | { |
1077 | RD::Uniform u; |
1078 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1079 | u.binding = 12; |
1080 | u.append_id(lightprobe_average_scroll); |
1081 | uniforms.push_back(u); |
1082 | } |
1083 | { |
1084 | RD::Uniform u; |
1085 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1086 | u.binding = 13; |
1087 | RID parent_average; |
1088 | if (cascades.size() == 1) { |
1089 | // If there is only one SDFGI cascade, we can't use the previous cascade for blending. |
1090 | parent_average = cascades[i].lightprobe_average_tex; |
1091 | } else if (i < cascades.size() - 1) { |
1092 | parent_average = cascades[i + 1].lightprobe_average_tex; |
1093 | } else { |
1094 | parent_average = cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used |
1095 | } |
1096 | u.append_id(parent_average); |
1097 | uniforms.push_back(u); |
1098 | } |
1099 | { |
1100 | RD::Uniform u; |
1101 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1102 | u.binding = 14; |
1103 | u.append_id(ambient_texture); |
1104 | uniforms.push_back(u); |
1105 | } |
1106 | |
1107 | cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 0); |
1108 | } |
1109 | |
1110 | bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env); |
1111 | energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env); |
1112 | normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env); |
1113 | probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env); |
1114 | reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env); |
1115 | } |
1116 | |
1117 | void GI::SDFGI::free_data() { |
1118 | // we don't free things here, we handle SDFGI differently at the moment destructing the object when it needs to change. |
1119 | } |
1120 | |
1121 | GI::SDFGI::~SDFGI() { |
1122 | for (const SDFGI::Cascade &c : cascades) { |
1123 | RD::get_singleton()->free(c.light_data); |
1124 | RD::get_singleton()->free(c.light_aniso_0_tex); |
1125 | RD::get_singleton()->free(c.light_aniso_1_tex); |
1126 | RD::get_singleton()->free(c.sdf_tex); |
1127 | RD::get_singleton()->free(c.solid_cell_dispatch_buffer); |
1128 | RD::get_singleton()->free(c.solid_cell_buffer); |
1129 | RD::get_singleton()->free(c.lightprobe_history_tex); |
1130 | RD::get_singleton()->free(c.lightprobe_average_tex); |
1131 | RD::get_singleton()->free(c.lights_buffer); |
1132 | } |
1133 | |
1134 | RD::get_singleton()->free(render_albedo); |
1135 | RD::get_singleton()->free(render_emission); |
1136 | RD::get_singleton()->free(render_emission_aniso); |
1137 | |
1138 | RD::get_singleton()->free(render_sdf[0]); |
1139 | RD::get_singleton()->free(render_sdf[1]); |
1140 | |
1141 | RD::get_singleton()->free(render_sdf_half[0]); |
1142 | RD::get_singleton()->free(render_sdf_half[1]); |
1143 | |
1144 | for (int i = 0; i < 8; i++) { |
1145 | RD::get_singleton()->free(render_occlusion[i]); |
1146 | } |
1147 | |
1148 | RD::get_singleton()->free(render_geom_facing); |
1149 | |
1150 | RD::get_singleton()->free(lightprobe_data); |
1151 | RD::get_singleton()->free(lightprobe_history_scroll); |
1152 | RD::get_singleton()->free(lightprobe_average_scroll); |
1153 | RD::get_singleton()->free(occlusion_data); |
1154 | RD::get_singleton()->free(ambient_texture); |
1155 | |
1156 | RD::get_singleton()->free(cascades_ubo); |
1157 | |
1158 | for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { |
1159 | if (RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) { |
1160 | RD::get_singleton()->free(debug_uniform_set[v]); |
1161 | } |
1162 | debug_uniform_set[v] = RID(); |
1163 | } |
1164 | |
1165 | if (RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) { |
1166 | RD::get_singleton()->free(debug_probes_uniform_set); |
1167 | } |
1168 | debug_probes_uniform_set = RID(); |
1169 | |
1170 | if (debug_probes_scene_data_ubo.is_valid()) { |
1171 | RD::get_singleton()->free(debug_probes_scene_data_ubo); |
1172 | debug_probes_scene_data_ubo = RID(); |
1173 | } |
1174 | } |
1175 | |
1176 | void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) { |
1177 | bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env); |
1178 | energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env); |
1179 | normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env); |
1180 | probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env); |
1181 | reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env); |
1182 | |
1183 | int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2; |
1184 | |
1185 | for (SDFGI::Cascade &cascade : cascades) { |
1186 | cascade.dirty_regions = Vector3i(); |
1187 | |
1188 | Vector3 probe_half_size = Vector3(1, 1, 1) * cascade.cell_size * float(cascade_size / SDFGI::PROBE_DIVISOR) * 0.5; |
1189 | probe_half_size = Vector3(0, 0, 0); |
1190 | |
1191 | Vector3 world_position = p_world_position; |
1192 | world_position.y *= y_mult; |
1193 | Vector3i pos_in_cascade = Vector3i((world_position + probe_half_size) / cascade.cell_size); |
1194 | |
1195 | for (int j = 0; j < 3; j++) { |
1196 | if (pos_in_cascade[j] < cascade.position[j]) { |
1197 | while (pos_in_cascade[j] < (cascade.position[j] - drag_margin)) { |
1198 | cascade.position[j] -= drag_margin * 2; |
1199 | cascade.dirty_regions[j] += drag_margin * 2; |
1200 | } |
1201 | } else if (pos_in_cascade[j] > cascade.position[j]) { |
1202 | while (pos_in_cascade[j] > (cascade.position[j] + drag_margin)) { |
1203 | cascade.position[j] += drag_margin * 2; |
1204 | cascade.dirty_regions[j] -= drag_margin * 2; |
1205 | } |
1206 | } |
1207 | |
1208 | if (cascade.dirty_regions[j] == 0) { |
1209 | continue; // not dirty |
1210 | } else if (uint32_t(ABS(cascade.dirty_regions[j])) >= cascade_size) { |
1211 | //moved too much, just redraw everything (make all dirty) |
1212 | cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL; |
1213 | break; |
1214 | } |
1215 | } |
1216 | |
1217 | if (cascade.dirty_regions != Vector3i() && cascade.dirty_regions != SDFGI::Cascade::DIRTY_ALL) { |
1218 | //see how much the total dirty volume represents from the total volume |
1219 | uint32_t total_volume = cascade_size * cascade_size * cascade_size; |
1220 | uint32_t safe_volume = 1; |
1221 | for (int j = 0; j < 3; j++) { |
1222 | safe_volume *= cascade_size - ABS(cascade.dirty_regions[j]); |
1223 | } |
1224 | uint32_t dirty_volume = total_volume - safe_volume; |
1225 | if (dirty_volume > (safe_volume / 2)) { |
1226 | //more than half the volume is dirty, make all dirty so its only rendered once |
1227 | cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL; |
1228 | } |
1229 | } |
1230 | } |
1231 | } |
1232 | |
1233 | void GI::SDFGI::update_light() { |
1234 | RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light" ); |
1235 | |
1236 | /* Update dynamic light */ |
1237 | |
1238 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
1239 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC]); |
1240 | |
1241 | SDFGIShader::DirectLightPushConstant push_constant; |
1242 | |
1243 | push_constant.grid_size[0] = cascade_size; |
1244 | push_constant.grid_size[1] = cascade_size; |
1245 | push_constant.grid_size[2] = cascade_size; |
1246 | push_constant.max_cascades = cascades.size(); |
1247 | push_constant.probe_axis_size = probe_axis_count; |
1248 | push_constant.bounce_feedback = bounce_feedback; |
1249 | push_constant.y_mult = y_mult; |
1250 | push_constant.use_occlusion = uses_occlusion; |
1251 | |
1252 | for (uint32_t i = 0; i < cascades.size(); i++) { |
1253 | SDFGI::Cascade &cascade = cascades[i]; |
1254 | push_constant.light_count = cascade_dynamic_light_count[i]; |
1255 | push_constant.cascade = i; |
1256 | |
1257 | if (cascades[i].all_dynamic_lights_dirty || gi->sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) { |
1258 | push_constant.process_offset = 0; |
1259 | push_constant.process_increment = 1; |
1260 | } else { |
1261 | static const uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = { |
1262 | 1, 2, 4, 8, 16 |
1263 | }; |
1264 | |
1265 | uint32_t frames_to_update = frames_to_update_table[gi->sdfgi_frames_to_update_light]; |
1266 | |
1267 | push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update; |
1268 | push_constant.process_increment = frames_to_update; |
1269 | } |
1270 | cascades[i].all_dynamic_lights_dirty = false; |
1271 | |
1272 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_dynamic_uniform_set, 0); |
1273 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DirectLightPushConstant)); |
1274 | RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0); |
1275 | } |
1276 | RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); |
1277 | RD::get_singleton()->draw_command_end_label(); |
1278 | } |
1279 | |
1280 | void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) { |
1281 | RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes" ); |
1282 | |
1283 | SDFGIShader::IntegratePushConstant push_constant; |
1284 | push_constant.grid_size[1] = cascade_size; |
1285 | push_constant.grid_size[2] = cascade_size; |
1286 | push_constant.grid_size[0] = cascade_size; |
1287 | push_constant.max_cascades = cascades.size(); |
1288 | push_constant.probe_axis_size = probe_axis_count; |
1289 | push_constant.history_index = render_pass % history_size; |
1290 | push_constant.history_size = history_size; |
1291 | static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 }; |
1292 | push_constant.ray_count = ray_count[gi->sdfgi_ray_count]; |
1293 | push_constant.ray_bias = probe_bias; |
1294 | push_constant.image_size[0] = probe_axis_count * probe_axis_count; |
1295 | push_constant.image_size[1] = probe_axis_count; |
1296 | push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env); |
1297 | |
1298 | RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set; |
1299 | push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_DISABLED; |
1300 | push_constant.y_mult = y_mult; |
1301 | |
1302 | if (reads_sky && p_env.is_valid()) { |
1303 | push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy_multiplier(p_env); |
1304 | |
1305 | if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) { |
1306 | push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; |
1307 | Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear(); |
1308 | push_constant.sky_color[0] = c.r; |
1309 | push_constant.sky_color[1] = c.g; |
1310 | push_constant.sky_color[2] = c.b; |
1311 | } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) { |
1312 | push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; |
1313 | Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env); |
1314 | push_constant.sky_color[0] = c.r; |
1315 | push_constant.sky_color[1] = c.g; |
1316 | push_constant.sky_color[2] = c.b; |
1317 | |
1318 | } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) { |
1319 | if (p_sky && p_sky->radiance.is_valid()) { |
1320 | if (integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(integrate_sky_uniform_set)) { |
1321 | Vector<RD::Uniform> uniforms; |
1322 | |
1323 | { |
1324 | RD::Uniform u; |
1325 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1326 | u.binding = 0; |
1327 | u.append_id(p_sky->radiance); |
1328 | uniforms.push_back(u); |
1329 | } |
1330 | |
1331 | { |
1332 | RD::Uniform u; |
1333 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
1334 | u.binding = 1; |
1335 | u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
1336 | uniforms.push_back(u); |
1337 | } |
1338 | |
1339 | integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 1); |
1340 | } |
1341 | sky_uniform_set = integrate_sky_uniform_set; |
1342 | push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_SKY; |
1343 | } |
1344 | } |
1345 | } |
1346 | |
1347 | render_pass++; |
1348 | |
1349 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); |
1350 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_PROCESS]); |
1351 | |
1352 | int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR; |
1353 | for (uint32_t i = 0; i < cascades.size(); i++) { |
1354 | push_constant.cascade = i; |
1355 | push_constant.world_offset[0] = cascades[i].position.x / probe_divisor; |
1356 | push_constant.world_offset[1] = cascades[i].position.y / probe_divisor; |
1357 | push_constant.world_offset[2] = cascades[i].position.z / probe_divisor; |
1358 | |
1359 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0); |
1360 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1); |
1361 | |
1362 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant)); |
1363 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1); |
1364 | } |
1365 | |
1366 | //end later after raster to avoid barriering on layout changes |
1367 | //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); |
1368 | |
1369 | RD::get_singleton()->draw_command_end_label(); |
1370 | } |
1371 | |
1372 | void GI::SDFGI::store_probes() { |
1373 | RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE); |
1374 | RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes" ); |
1375 | |
1376 | SDFGIShader::IntegratePushConstant push_constant; |
1377 | push_constant.grid_size[1] = cascade_size; |
1378 | push_constant.grid_size[2] = cascade_size; |
1379 | push_constant.grid_size[0] = cascade_size; |
1380 | push_constant.max_cascades = cascades.size(); |
1381 | push_constant.probe_axis_size = probe_axis_count; |
1382 | push_constant.history_index = render_pass % history_size; |
1383 | push_constant.history_size = history_size; |
1384 | static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 }; |
1385 | push_constant.ray_count = ray_count[gi->sdfgi_ray_count]; |
1386 | push_constant.ray_bias = probe_bias; |
1387 | push_constant.image_size[0] = probe_axis_count * probe_axis_count; |
1388 | push_constant.image_size[1] = probe_axis_count; |
1389 | push_constant.store_ambient_texture = false; |
1390 | |
1391 | push_constant.sky_mode = 0; |
1392 | push_constant.y_mult = y_mult; |
1393 | |
1394 | // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces |
1395 | RENDER_TIMESTAMP("Average SDFGI Probes" ); |
1396 | |
1397 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
1398 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]); |
1399 | |
1400 | //convert to octahedral to store |
1401 | push_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE; |
1402 | push_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE; |
1403 | |
1404 | for (uint32_t i = 0; i < cascades.size(); i++) { |
1405 | push_constant.cascade = i; |
1406 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0); |
1407 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1); |
1408 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant)); |
1409 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1); |
1410 | } |
1411 | |
1412 | RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); |
1413 | |
1414 | RD::get_singleton()->draw_command_end_label(); |
1415 | } |
1416 | |
1417 | int GI::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const { |
1418 | int dirty_count = 0; |
1419 | for (uint32_t i = 0; i < cascades.size(); i++) { |
1420 | const SDFGI::Cascade &c = cascades[i]; |
1421 | |
1422 | if (c.dirty_regions == SDFGI::Cascade::DIRTY_ALL) { |
1423 | if (dirty_count == p_region) { |
1424 | r_local_offset = Vector3i(); |
1425 | r_local_size = Vector3i(1, 1, 1) * cascade_size; |
1426 | |
1427 | r_bounds.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position)) * c.cell_size * Vector3(1, 1.0 / y_mult, 1); |
1428 | r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1); |
1429 | return i; |
1430 | } |
1431 | dirty_count++; |
1432 | } else { |
1433 | for (int j = 0; j < 3; j++) { |
1434 | if (c.dirty_regions[j] != 0) { |
1435 | if (dirty_count == p_region) { |
1436 | Vector3i from = Vector3i(0, 0, 0); |
1437 | Vector3i to = Vector3i(1, 1, 1) * cascade_size; |
1438 | |
1439 | if (c.dirty_regions[j] > 0) { |
1440 | //fill from the beginning |
1441 | to[j] = c.dirty_regions[j]; |
1442 | } else { |
1443 | //fill from the end |
1444 | from[j] = to[j] + c.dirty_regions[j]; |
1445 | } |
1446 | |
1447 | for (int k = 0; k < j; k++) { |
1448 | // "chip" away previous regions to avoid re-voxelizing the same thing |
1449 | if (c.dirty_regions[k] > 0) { |
1450 | from[k] += c.dirty_regions[k]; |
1451 | } else if (c.dirty_regions[k] < 0) { |
1452 | to[k] += c.dirty_regions[k]; |
1453 | } |
1454 | } |
1455 | |
1456 | r_local_offset = from; |
1457 | r_local_size = to - from; |
1458 | |
1459 | r_bounds.position = Vector3(from + Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position) * c.cell_size * Vector3(1, 1.0 / y_mult, 1); |
1460 | r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1); |
1461 | |
1462 | return i; |
1463 | } |
1464 | |
1465 | dirty_count++; |
1466 | } |
1467 | } |
1468 | } |
1469 | } |
1470 | return -1; |
1471 | } |
1472 | |
1473 | void GI::SDFGI::update_cascades() { |
1474 | //update cascades |
1475 | SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES]; |
1476 | int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR; |
1477 | |
1478 | for (uint32_t i = 0; i < cascades.size(); i++) { |
1479 | Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size; |
1480 | |
1481 | cascade_data[i].offset[0] = pos.x; |
1482 | cascade_data[i].offset[1] = pos.y; |
1483 | cascade_data[i].offset[2] = pos.z; |
1484 | cascade_data[i].to_cell = 1.0 / cascades[i].cell_size; |
1485 | cascade_data[i].probe_offset[0] = cascades[i].position.x / probe_divisor; |
1486 | cascade_data[i].probe_offset[1] = cascades[i].position.y / probe_divisor; |
1487 | cascade_data[i].probe_offset[2] = cascades[i].position.z / probe_divisor; |
1488 | cascade_data[i].pad = 0; |
1489 | } |
1490 | |
1491 | RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); |
1492 | } |
1493 | |
1494 | void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) { |
1495 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
1496 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
1497 | RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); |
1498 | |
1499 | for (uint32_t v = 0; v < p_view_count; v++) { |
1500 | if (!debug_uniform_set[v].is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) { |
1501 | Vector<RD::Uniform> uniforms; |
1502 | { |
1503 | RD::Uniform u; |
1504 | u.binding = 1; |
1505 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1506 | for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { |
1507 | if (i < cascades.size()) { |
1508 | u.append_id(cascades[i].sdf_tex); |
1509 | } else { |
1510 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1511 | } |
1512 | } |
1513 | uniforms.push_back(u); |
1514 | } |
1515 | { |
1516 | RD::Uniform u; |
1517 | u.binding = 2; |
1518 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1519 | for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { |
1520 | if (i < cascades.size()) { |
1521 | u.append_id(cascades[i].light_tex); |
1522 | } else { |
1523 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1524 | } |
1525 | } |
1526 | uniforms.push_back(u); |
1527 | } |
1528 | { |
1529 | RD::Uniform u; |
1530 | u.binding = 3; |
1531 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1532 | for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { |
1533 | if (i < cascades.size()) { |
1534 | u.append_id(cascades[i].light_aniso_0_tex); |
1535 | } else { |
1536 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1537 | } |
1538 | } |
1539 | uniforms.push_back(u); |
1540 | } |
1541 | { |
1542 | RD::Uniform u; |
1543 | u.binding = 4; |
1544 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1545 | for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { |
1546 | if (i < cascades.size()) { |
1547 | u.append_id(cascades[i].light_aniso_1_tex); |
1548 | } else { |
1549 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
1550 | } |
1551 | } |
1552 | uniforms.push_back(u); |
1553 | } |
1554 | { |
1555 | RD::Uniform u; |
1556 | u.binding = 5; |
1557 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1558 | u.append_id(occlusion_texture); |
1559 | uniforms.push_back(u); |
1560 | } |
1561 | { |
1562 | RD::Uniform u; |
1563 | u.binding = 8; |
1564 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
1565 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
1566 | uniforms.push_back(u); |
1567 | } |
1568 | { |
1569 | RD::Uniform u; |
1570 | u.binding = 9; |
1571 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
1572 | u.append_id(cascades_ubo); |
1573 | uniforms.push_back(u); |
1574 | } |
1575 | { |
1576 | RD::Uniform u; |
1577 | u.binding = 10; |
1578 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
1579 | u.append_id(p_texture_views[v]); |
1580 | uniforms.push_back(u); |
1581 | } |
1582 | { |
1583 | RD::Uniform u; |
1584 | u.binding = 11; |
1585 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1586 | u.append_id(lightprobe_texture); |
1587 | uniforms.push_back(u); |
1588 | } |
1589 | debug_uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0); |
1590 | } |
1591 | |
1592 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
1593 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline); |
1594 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set[v], 0); |
1595 | |
1596 | SDFGIShader::DebugPushConstant push_constant; |
1597 | push_constant.grid_size[0] = cascade_size; |
1598 | push_constant.grid_size[1] = cascade_size; |
1599 | push_constant.grid_size[2] = cascade_size; |
1600 | push_constant.max_cascades = cascades.size(); |
1601 | push_constant.screen_size[0] = p_width; |
1602 | push_constant.screen_size[1] = p_height; |
1603 | push_constant.y_mult = y_mult; |
1604 | |
1605 | push_constant.z_near = -p_projections[v].get_z_near(); |
1606 | |
1607 | for (int i = 0; i < 3; i++) { |
1608 | for (int j = 0; j < 3; j++) { |
1609 | push_constant.cam_basis[i][j] = p_transform.basis.rows[j][i]; |
1610 | } |
1611 | } |
1612 | push_constant.cam_origin[0] = p_transform.origin[0]; |
1613 | push_constant.cam_origin[1] = p_transform.origin[1]; |
1614 | push_constant.cam_origin[2] = p_transform.origin[2]; |
1615 | |
1616 | // need to properly unproject for asymmetric projection matrices in stereo.. |
1617 | Projection inv_projection = p_projections[v].inverse(); |
1618 | for (int i = 0; i < 4; i++) { |
1619 | for (int j = 0; j < 3; j++) { |
1620 | push_constant.inv_projection[j][i] = inv_projection.columns[i][j]; |
1621 | } |
1622 | } |
1623 | |
1624 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant)); |
1625 | |
1626 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1); |
1627 | RD::get_singleton()->compute_list_end(); |
1628 | } |
1629 | |
1630 | Size2i rtsize = texture_storage->render_target_get_size(p_render_target); |
1631 | copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2i(Point2i(), rtsize), true, false, false, false, RID(), p_view_count > 1); |
1632 | } |
1633 | |
1634 | void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { |
1635 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
1636 | |
1637 | // setup scene data |
1638 | { |
1639 | SDFGIShader::DebugProbesSceneData scene_data; |
1640 | |
1641 | if (debug_probes_scene_data_ubo.is_null()) { |
1642 | debug_probes_scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIShader::DebugProbesSceneData)); |
1643 | } |
1644 | |
1645 | for (uint32_t v = 0; v < p_view_count; v++) { |
1646 | RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]); |
1647 | } |
1648 | |
1649 | RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data, RD::BARRIER_MASK_RASTER); |
1650 | } |
1651 | |
1652 | // setup push constant |
1653 | SDFGIShader::DebugProbesPushConstant push_constant; |
1654 | |
1655 | //gen spheres from strips |
1656 | uint32_t band_points = 16; |
1657 | push_constant.band_power = 4; |
1658 | push_constant.sections_in_band = ((band_points / 2) - 1); |
1659 | push_constant.band_mask = band_points - 2; |
1660 | push_constant.section_arc = Math_TAU / float(push_constant.sections_in_band); |
1661 | push_constant.y_mult = y_mult; |
1662 | |
1663 | uint32_t total_points = push_constant.sections_in_band * band_points; |
1664 | uint32_t total_probes = probe_axis_count * probe_axis_count * probe_axis_count; |
1665 | |
1666 | push_constant.grid_size[0] = cascade_size; |
1667 | push_constant.grid_size[1] = cascade_size; |
1668 | push_constant.grid_size[2] = cascade_size; |
1669 | push_constant.cascade = 0; |
1670 | |
1671 | push_constant.probe_axis_size = probe_axis_count; |
1672 | |
1673 | if (!debug_probes_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) { |
1674 | Vector<RD::Uniform> uniforms; |
1675 | { |
1676 | RD::Uniform u; |
1677 | u.binding = 1; |
1678 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
1679 | u.append_id(cascades_ubo); |
1680 | uniforms.push_back(u); |
1681 | } |
1682 | { |
1683 | RD::Uniform u; |
1684 | u.binding = 2; |
1685 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1686 | u.append_id(lightprobe_texture); |
1687 | uniforms.push_back(u); |
1688 | } |
1689 | { |
1690 | RD::Uniform u; |
1691 | u.binding = 3; |
1692 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
1693 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
1694 | uniforms.push_back(u); |
1695 | } |
1696 | { |
1697 | RD::Uniform u; |
1698 | u.binding = 4; |
1699 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
1700 | u.append_id(occlusion_texture); |
1701 | uniforms.push_back(u); |
1702 | } |
1703 | { |
1704 | RD::Uniform u; |
1705 | u.binding = 5; |
1706 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
1707 | u.append_id(debug_probes_scene_data_ubo); |
1708 | uniforms.push_back(u); |
1709 | } |
1710 | |
1711 | debug_probes_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_probes.version_get_shader(gi->sdfgi_shader.debug_probes_shader, 0), 0); |
1712 | } |
1713 | |
1714 | SDFGIShader::ProbeDebugMode mode = p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_PROBES_MULTIVIEW : SDFGIShader::PROBE_DEBUG_PROBES; |
1715 | |
1716 | RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CONTINUE, p_will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); |
1717 | RD::get_singleton()->draw_command_begin_label("Debug SDFGI" ); |
1718 | |
1719 | RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[mode].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); |
1720 | RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0); |
1721 | RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant)); |
1722 | RD::get_singleton()->draw_list_draw(draw_list, false, total_probes, total_points); |
1723 | |
1724 | if (gi->sdfgi_debug_probe_dir != Vector3()) { |
1725 | uint32_t cascade = 0; |
1726 | Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[cascade].position)) * cascades[cascade].cell_size * Vector3(1.0, 1.0 / y_mult, 1.0); |
1727 | Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0); |
1728 | Vector3 ray_from = gi->sdfgi_debug_probe_pos; |
1729 | Vector3 ray_to = gi->sdfgi_debug_probe_pos + gi->sdfgi_debug_probe_dir * cascades[cascade].cell_size * Math::sqrt(3.0) * cascade_size; |
1730 | float sphere_radius = 0.2; |
1731 | float closest_dist = 1e20; |
1732 | gi->sdfgi_debug_probe_enabled = false; |
1733 | |
1734 | Vector3i probe_from = cascades[cascade].position / (cascade_size / SDFGI::PROBE_DIVISOR); |
1735 | for (int i = 0; i < (SDFGI::PROBE_DIVISOR + 1); i++) { |
1736 | for (int j = 0; j < (SDFGI::PROBE_DIVISOR + 1); j++) { |
1737 | for (int k = 0; k < (SDFGI::PROBE_DIVISOR + 1); k++) { |
1738 | Vector3 pos = offset + probe_size * Vector3(i, j, k); |
1739 | Vector3 res; |
1740 | if (Geometry3D::segment_intersects_sphere(ray_from, ray_to, pos, sphere_radius, &res)) { |
1741 | float d = ray_from.distance_to(res); |
1742 | if (d < closest_dist) { |
1743 | closest_dist = d; |
1744 | gi->sdfgi_debug_probe_enabled = true; |
1745 | gi->sdfgi_debug_probe_index = probe_from + Vector3i(i, j, k); |
1746 | } |
1747 | } |
1748 | } |
1749 | } |
1750 | } |
1751 | |
1752 | gi->sdfgi_debug_probe_dir = Vector3(); |
1753 | } |
1754 | |
1755 | if (gi->sdfgi_debug_probe_enabled) { |
1756 | uint32_t cascade = 0; |
1757 | uint32_t probe_cells = (cascade_size / SDFGI::PROBE_DIVISOR); |
1758 | Vector3i probe_from = cascades[cascade].position / probe_cells; |
1759 | Vector3i ofs = gi->sdfgi_debug_probe_index - probe_from; |
1760 | if (ofs.x < 0 || ofs.y < 0 || ofs.z < 0) { |
1761 | return; |
1762 | } |
1763 | if (ofs.x > SDFGI::PROBE_DIVISOR || ofs.y > SDFGI::PROBE_DIVISOR || ofs.z > SDFGI::PROBE_DIVISOR) { |
1764 | return; |
1765 | } |
1766 | |
1767 | uint32_t mult = (SDFGI::PROBE_DIVISOR + 1); |
1768 | uint32_t index = ofs.z * mult * mult + ofs.y * mult + ofs.x; |
1769 | |
1770 | push_constant.probe_debug_index = index; |
1771 | |
1772 | uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2; |
1773 | |
1774 | RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_VISIBILITY_MULTIVIEW : SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); |
1775 | RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0); |
1776 | RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant)); |
1777 | RD::get_singleton()->draw_list_draw(draw_list, false, cell_count, total_points); |
1778 | } |
1779 | |
1780 | RD::get_singleton()->draw_command_end_label(); |
1781 | RD::get_singleton()->draw_list_end(); |
1782 | } |
1783 | |
1784 | void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data) { |
1785 | RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); |
1786 | /* Update general SDFGI Buffer */ |
1787 | |
1788 | SDFGIData sdfgi_data; |
1789 | |
1790 | sdfgi_data.grid_size[0] = cascade_size; |
1791 | sdfgi_data.grid_size[1] = cascade_size; |
1792 | sdfgi_data.grid_size[2] = cascade_size; |
1793 | |
1794 | sdfgi_data.max_cascades = cascades.size(); |
1795 | sdfgi_data.probe_axis_size = probe_axis_count; |
1796 | sdfgi_data.cascade_probe_size[0] = sdfgi_data.probe_axis_size - 1; //float version for performance |
1797 | sdfgi_data.cascade_probe_size[1] = sdfgi_data.probe_axis_size - 1; |
1798 | sdfgi_data.cascade_probe_size[2] = sdfgi_data.probe_axis_size - 1; |
1799 | |
1800 | float csize = cascade_size; |
1801 | sdfgi_data.probe_to_uvw = 1.0 / float(sdfgi_data.cascade_probe_size[0]); |
1802 | sdfgi_data.use_occlusion = uses_occlusion; |
1803 | //sdfgi_data.energy = energy; |
1804 | |
1805 | sdfgi_data.y_mult = y_mult; |
1806 | |
1807 | float cascade_voxel_size = (csize / sdfgi_data.cascade_probe_size[0]); |
1808 | float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size; |
1809 | sdfgi_data.occlusion_clamp[0] = occlusion_clamp; |
1810 | sdfgi_data.occlusion_clamp[1] = occlusion_clamp; |
1811 | sdfgi_data.occlusion_clamp[2] = occlusion_clamp; |
1812 | sdfgi_data.normal_bias = (normal_bias / csize) * sdfgi_data.cascade_probe_size[0]; |
1813 | |
1814 | //vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) ); |
1815 | //vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx; |
1816 | |
1817 | uint32_t oct_size = SDFGI::LIGHTPROBE_OCT_SIZE; |
1818 | |
1819 | sdfgi_data.lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size * sdfgi_data.probe_axis_size); |
1820 | sdfgi_data.lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size); |
1821 | sdfgi_data.lightprobe_tex_pixel_size[2] = 1.0; |
1822 | |
1823 | sdfgi_data.energy = energy; |
1824 | |
1825 | sdfgi_data.lightprobe_uv_offset[0] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[0]; |
1826 | sdfgi_data.lightprobe_uv_offset[1] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[1]; |
1827 | sdfgi_data.lightprobe_uv_offset[2] = float((oct_size + 2) * sdfgi_data.probe_axis_size) * sdfgi_data.lightprobe_tex_pixel_size[0]; |
1828 | |
1829 | sdfgi_data.occlusion_renormalize[0] = 0.5; |
1830 | sdfgi_data.occlusion_renormalize[1] = 1.0; |
1831 | sdfgi_data.occlusion_renormalize[2] = 1.0 / float(sdfgi_data.max_cascades); |
1832 | |
1833 | int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR; |
1834 | |
1835 | for (uint32_t i = 0; i < sdfgi_data.max_cascades; i++) { |
1836 | SDFGIData::ProbeCascadeData &c = sdfgi_data.cascades[i]; |
1837 | Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size; |
1838 | Vector3 cam_origin = p_transform.origin; |
1839 | cam_origin.y *= y_mult; |
1840 | pos -= cam_origin; //make pos local to camera, to reduce numerical error |
1841 | c.position[0] = pos.x; |
1842 | c.position[1] = pos.y; |
1843 | c.position[2] = pos.z; |
1844 | c.to_probe = 1.0 / (float(cascade_size) * cascades[i].cell_size / float(probe_axis_count - 1)); |
1845 | |
1846 | Vector3i probe_ofs = cascades[i].position / probe_divisor; |
1847 | c.probe_world_offset[0] = probe_ofs.x; |
1848 | c.probe_world_offset[1] = probe_ofs.y; |
1849 | c.probe_world_offset[2] = probe_ofs.z; |
1850 | |
1851 | c.to_cell = 1.0 / cascades[i].cell_size; |
1852 | c.exposure_normalization = 1.0; |
1853 | if (p_render_data->camera_attributes.is_valid()) { |
1854 | float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); |
1855 | c.exposure_normalization = exposure_normalization / cascades[i].baked_exposure_normalization; |
1856 | } |
1857 | } |
1858 | |
1859 | RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data, RD::BARRIER_MASK_COMPUTE); |
1860 | |
1861 | /* Update dynamic lights in SDFGI cascades */ |
1862 | |
1863 | for (uint32_t i = 0; i < cascades.size(); i++) { |
1864 | SDFGI::Cascade &cascade = cascades[i]; |
1865 | |
1866 | SDFGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS]; |
1867 | uint32_t idx = 0; |
1868 | for (uint32_t j = 0; j < (uint32_t)p_render_data->sdfgi_update_data->directional_lights->size(); j++) { |
1869 | if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { |
1870 | break; |
1871 | } |
1872 | |
1873 | RID light_instance = p_render_data->sdfgi_update_data->directional_lights->get(j); |
1874 | ERR_CONTINUE(!light_storage->owns_light_instance(light_instance)); |
1875 | |
1876 | RID light = light_storage->light_instance_get_base_light(light_instance); |
1877 | Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance); |
1878 | |
1879 | if (RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { |
1880 | continue; |
1881 | } |
1882 | |
1883 | Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z); |
1884 | dir.y *= y_mult; |
1885 | dir.normalize(); |
1886 | lights[idx].direction[0] = dir.x; |
1887 | lights[idx].direction[1] = dir.y; |
1888 | lights[idx].direction[2] = dir.z; |
1889 | Color color = RSG::light_storage->light_get_color(light); |
1890 | color = color.srgb_to_linear(); |
1891 | lights[idx].color[0] = color.r; |
1892 | lights[idx].color[1] = color.g; |
1893 | lights[idx].color[2] = color.b; |
1894 | lights[idx].type = RS::LIGHT_DIRECTIONAL; |
1895 | lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); |
1896 | if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { |
1897 | lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); |
1898 | } |
1899 | |
1900 | if (p_render_data->camera_attributes.is_valid()) { |
1901 | lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); |
1902 | } |
1903 | |
1904 | lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light); |
1905 | |
1906 | idx++; |
1907 | } |
1908 | |
1909 | AABB cascade_aabb; |
1910 | cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascade.position)) * cascade.cell_size; |
1911 | cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cascade.cell_size; |
1912 | |
1913 | for (uint32_t j = 0; j < p_render_data->sdfgi_update_data->positional_light_count; j++) { |
1914 | if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) { |
1915 | break; |
1916 | } |
1917 | |
1918 | RID light_instance = p_render_data->sdfgi_update_data->positional_light_instances[j]; |
1919 | ERR_CONTINUE(!light_storage->owns_light_instance(light_instance)); |
1920 | |
1921 | RID light = light_storage->light_instance_get_base_light(light_instance); |
1922 | AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance); |
1923 | Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance); |
1924 | |
1925 | uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light); |
1926 | if (i > max_sdfgi_cascade) { |
1927 | continue; |
1928 | } |
1929 | |
1930 | if (!cascade_aabb.intersects(light_aabb)) { |
1931 | continue; |
1932 | } |
1933 | |
1934 | Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z); |
1935 | //faster to not do this here |
1936 | //dir.y *= y_mult; |
1937 | //dir.normalize(); |
1938 | lights[idx].direction[0] = dir.x; |
1939 | lights[idx].direction[1] = dir.y; |
1940 | lights[idx].direction[2] = dir.z; |
1941 | Vector3 pos = light_transform.origin; |
1942 | pos.y *= y_mult; |
1943 | lights[idx].position[0] = pos.x; |
1944 | lights[idx].position[1] = pos.y; |
1945 | lights[idx].position[2] = pos.z; |
1946 | Color color = RSG::light_storage->light_get_color(light); |
1947 | color = color.srgb_to_linear(); |
1948 | lights[idx].color[0] = color.r; |
1949 | lights[idx].color[1] = color.g; |
1950 | lights[idx].color[2] = color.b; |
1951 | lights[idx].type = RSG::light_storage->light_get_type(light); |
1952 | |
1953 | lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); |
1954 | if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { |
1955 | lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); |
1956 | |
1957 | // Convert from Luminous Power to Luminous Intensity |
1958 | if (lights[idx].type == RS::LIGHT_OMNI) { |
1959 | lights[idx].energy *= 1.0 / (Math_PI * 4.0); |
1960 | } else if (lights[idx].type == RS::LIGHT_SPOT) { |
1961 | // Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle. |
1962 | // We make this assumption to keep them easy to control. |
1963 | lights[idx].energy *= 1.0 / Math_PI; |
1964 | } |
1965 | } |
1966 | |
1967 | if (p_render_data->camera_attributes.is_valid()) { |
1968 | lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); |
1969 | } |
1970 | |
1971 | lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light); |
1972 | lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); |
1973 | lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE); |
1974 | lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); |
1975 | lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); |
1976 | |
1977 | idx++; |
1978 | } |
1979 | |
1980 | if (idx > 0) { |
1981 | RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights, RD::BARRIER_MASK_COMPUTE); |
1982 | } |
1983 | |
1984 | cascade_dynamic_light_count[i] = idx; |
1985 | } |
1986 | } |
1987 | |
1988 | void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization) { |
1989 | //print_line("rendering region " + itos(p_region)); |
1990 | ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but... |
1991 | AABB bounds; |
1992 | Vector3i from; |
1993 | Vector3i size; |
1994 | |
1995 | int cascade_prev = get_pending_region_data(p_region - 1, from, size, bounds); |
1996 | int cascade_next = get_pending_region_data(p_region + 1, from, size, bounds); |
1997 | int cascade = get_pending_region_data(p_region, from, size, bounds); |
1998 | ERR_FAIL_COND(cascade < 0); |
1999 | |
2000 | if (cascade_prev != cascade) { |
2001 | //initialize render |
2002 | RD::get_singleton()->texture_clear(render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2003 | RD::get_singleton()->texture_clear(render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2004 | RD::get_singleton()->texture_clear(render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2005 | RD::get_singleton()->texture_clear(render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2006 | } |
2007 | |
2008 | //print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(cascades[cascade].cell_size)); |
2009 | RendererSceneRenderRD::get_singleton()->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization); |
2010 | |
2011 | if (cascade_next != cascade) { |
2012 | RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade" ); |
2013 | |
2014 | RENDER_TIMESTAMP("> SDFGI Update SDF" ); |
2015 | //done rendering! must update SDF |
2016 | //clear dispatch indirect data |
2017 | |
2018 | SDFGIShader::PreprocessPushConstant push_constant; |
2019 | memset(&push_constant, 0, sizeof(SDFGIShader::PreprocessPushConstant)); |
2020 | |
2021 | RENDER_TIMESTAMP("SDFGI Scroll SDF" ); |
2022 | |
2023 | //scroll |
2024 | if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) { |
2025 | //for scroll |
2026 | Vector3i dirty = cascades[cascade].dirty_regions; |
2027 | push_constant.scroll[0] = dirty.x; |
2028 | push_constant.scroll[1] = dirty.y; |
2029 | push_constant.scroll[2] = dirty.z; |
2030 | } else { |
2031 | //for no scroll |
2032 | push_constant.scroll[0] = 0; |
2033 | push_constant.scroll[1] = 0; |
2034 | push_constant.scroll[2] = 0; |
2035 | } |
2036 | |
2037 | cascades[cascade].all_dynamic_lights_dirty = true; |
2038 | cascades[cascade].baked_exposure_normalization = p_exposure_normalization; |
2039 | |
2040 | push_constant.grid_size = cascade_size; |
2041 | push_constant.cascade = cascade; |
2042 | |
2043 | if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) { |
2044 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
2045 | |
2046 | //must pre scroll existing data because not all is dirty |
2047 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL]); |
2048 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_uniform_set, 0); |
2049 | |
2050 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2051 | RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascades[cascade].solid_cell_dispatch_buffer, 0); |
2052 | // no barrier do all together |
2053 | |
2054 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION]); |
2055 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_occlusion_uniform_set, 0); |
2056 | |
2057 | Vector3i dirty = cascades[cascade].dirty_regions; |
2058 | Vector3i groups; |
2059 | groups.x = cascade_size - ABS(dirty.x); |
2060 | groups.y = cascade_size - ABS(dirty.y); |
2061 | groups.z = cascade_size - ABS(dirty.z); |
2062 | |
2063 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2064 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z); |
2065 | |
2066 | //no barrier, continue together |
2067 | |
2068 | { |
2069 | //scroll probes and their history also |
2070 | |
2071 | SDFGIShader::IntegratePushConstant ipush_constant; |
2072 | ipush_constant.grid_size[1] = cascade_size; |
2073 | ipush_constant.grid_size[2] = cascade_size; |
2074 | ipush_constant.grid_size[0] = cascade_size; |
2075 | ipush_constant.max_cascades = cascades.size(); |
2076 | ipush_constant.probe_axis_size = probe_axis_count; |
2077 | ipush_constant.history_index = 0; |
2078 | ipush_constant.history_size = history_size; |
2079 | ipush_constant.ray_count = 0; |
2080 | ipush_constant.ray_bias = 0; |
2081 | ipush_constant.sky_mode = 0; |
2082 | ipush_constant.sky_energy = 0; |
2083 | ipush_constant.sky_color[0] = 0; |
2084 | ipush_constant.sky_color[1] = 0; |
2085 | ipush_constant.sky_color[2] = 0; |
2086 | ipush_constant.y_mult = y_mult; |
2087 | ipush_constant.store_ambient_texture = false; |
2088 | |
2089 | ipush_constant.image_size[0] = probe_axis_count * probe_axis_count; |
2090 | ipush_constant.image_size[1] = probe_axis_count; |
2091 | |
2092 | int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR; |
2093 | ipush_constant.cascade = cascade; |
2094 | ipush_constant.world_offset[0] = cascades[cascade].position.x / probe_divisor; |
2095 | ipush_constant.world_offset[1] = cascades[cascade].position.y / probe_divisor; |
2096 | ipush_constant.world_offset[2] = cascades[cascade].position.z / probe_divisor; |
2097 | |
2098 | ipush_constant.scroll[0] = dirty.x / probe_divisor; |
2099 | ipush_constant.scroll[1] = dirty.y / probe_divisor; |
2100 | ipush_constant.scroll[2] = dirty.z / probe_divisor; |
2101 | |
2102 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL]); |
2103 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0); |
2104 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1); |
2105 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant)); |
2106 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1); |
2107 | |
2108 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2109 | |
2110 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL_STORE]); |
2111 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0); |
2112 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1); |
2113 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant)); |
2114 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1); |
2115 | |
2116 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2117 | |
2118 | if (bounce_feedback > 0.0) { |
2119 | //multibounce requires this to be stored so direct light can read from it |
2120 | |
2121 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]); |
2122 | |
2123 | //convert to octahedral to store |
2124 | ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE; |
2125 | ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE; |
2126 | |
2127 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0); |
2128 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1); |
2129 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant)); |
2130 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1); |
2131 | } |
2132 | } |
2133 | |
2134 | //ok finally barrier |
2135 | RD::get_singleton()->compute_list_end(); |
2136 | } |
2137 | |
2138 | //clear dispatch indirect data |
2139 | uint32_t dispatch_indirct_data[4] = { 0, 0, 0, 0 }; |
2140 | RD::get_singleton()->buffer_update(cascades[cascade].solid_cell_dispatch_buffer, 0, sizeof(uint32_t) * 4, dispatch_indirct_data); |
2141 | |
2142 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
2143 | |
2144 | bool half_size = true; //much faster, very little difference |
2145 | static const int optimized_jf_group_size = 8; |
2146 | |
2147 | if (half_size) { |
2148 | push_constant.grid_size >>= 1; |
2149 | |
2150 | uint32_t cascade_half_size = cascade_size >> 1; |
2151 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF]); |
2152 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_half_uniform_set, 0); |
2153 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2154 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); |
2155 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2156 | |
2157 | //must start with regular jumpflood |
2158 | |
2159 | push_constant.half_size = true; |
2160 | { |
2161 | RENDER_TIMESTAMP("SDFGI Jump Flood (Half-Size)" ); |
2162 | |
2163 | uint32_t s = cascade_half_size; |
2164 | |
2165 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD]); |
2166 | |
2167 | int jf_us = 0; |
2168 | //start with regular jump flood for very coarse reads, as this is impossible to optimize |
2169 | while (s > 1) { |
2170 | s /= 2; |
2171 | push_constant.step_size = s; |
2172 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0); |
2173 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2174 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); |
2175 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2176 | jf_us = jf_us == 0 ? 1 : 0; |
2177 | |
2178 | if (cascade_half_size / (s / 2) >= optimized_jf_group_size) { |
2179 | break; |
2180 | } |
2181 | } |
2182 | |
2183 | RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half-Size)" ); |
2184 | |
2185 | //continue with optimized jump flood for smaller reads |
2186 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); |
2187 | while (s > 1) { |
2188 | s /= 2; |
2189 | push_constant.step_size = s; |
2190 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0); |
2191 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2192 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size); |
2193 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2194 | jf_us = jf_us == 0 ? 1 : 0; |
2195 | } |
2196 | } |
2197 | |
2198 | // restore grid size for last passes |
2199 | push_constant.grid_size = cascade_size; |
2200 | |
2201 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE]); |
2202 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_upscale_uniform_set, 0); |
2203 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2204 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size); |
2205 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2206 | |
2207 | //run one pass of fullsize jumpflood to fix up half size artifacts |
2208 | |
2209 | push_constant.half_size = false; |
2210 | push_constant.step_size = 1; |
2211 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); |
2212 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[upscale_jfa_uniform_set_index], 0); |
2213 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2214 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size); |
2215 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2216 | |
2217 | } else { |
2218 | //full size jumpflood |
2219 | RENDER_TIMESTAMP("SDFGI Jump Flood (Full-Size)" ); |
2220 | |
2221 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]); |
2222 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_uniform_set, 0); |
2223 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2224 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size); |
2225 | |
2226 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2227 | |
2228 | push_constant.half_size = false; |
2229 | { |
2230 | uint32_t s = cascade_size; |
2231 | |
2232 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD]); |
2233 | |
2234 | int jf_us = 0; |
2235 | //start with regular jump flood for very coarse reads, as this is impossible to optimize |
2236 | while (s > 1) { |
2237 | s /= 2; |
2238 | push_constant.step_size = s; |
2239 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0); |
2240 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2241 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size); |
2242 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2243 | jf_us = jf_us == 0 ? 1 : 0; |
2244 | |
2245 | if (cascade_size / (s / 2) >= optimized_jf_group_size) { |
2246 | break; |
2247 | } |
2248 | } |
2249 | |
2250 | RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Full-Size)" ); |
2251 | |
2252 | //continue with optimized jump flood for smaller reads |
2253 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); |
2254 | while (s > 1) { |
2255 | s /= 2; |
2256 | push_constant.step_size = s; |
2257 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0); |
2258 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2259 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size); |
2260 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2261 | jf_us = jf_us == 0 ? 1 : 0; |
2262 | } |
2263 | } |
2264 | } |
2265 | |
2266 | RENDER_TIMESTAMP("SDFGI Occlusion" ); |
2267 | |
2268 | // occlusion |
2269 | { |
2270 | uint32_t probe_size = cascade_size / SDFGI::PROBE_DIVISOR; |
2271 | Vector3i probe_global_pos = cascades[cascade].position / probe_size; |
2272 | |
2273 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_OCCLUSION]); |
2274 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, occlusion_uniform_set, 0); |
2275 | for (int i = 0; i < 8; i++) { |
2276 | //dispatch all at once for performance |
2277 | Vector3i offset(i & 1, (i >> 1) & 1, (i >> 2) & 1); |
2278 | |
2279 | if ((probe_global_pos.x & 1) != 0) { |
2280 | offset.x = (offset.x + 1) & 1; |
2281 | } |
2282 | if ((probe_global_pos.y & 1) != 0) { |
2283 | offset.y = (offset.y + 1) & 1; |
2284 | } |
2285 | if ((probe_global_pos.z & 1) != 0) { |
2286 | offset.z = (offset.z + 1) & 1; |
2287 | } |
2288 | push_constant.probe_offset[0] = offset.x; |
2289 | push_constant.probe_offset[1] = offset.y; |
2290 | push_constant.probe_offset[2] = offset.z; |
2291 | push_constant.occlusion_index = i; |
2292 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2293 | |
2294 | Vector3i groups = Vector3i(probe_size + 1, probe_size + 1, probe_size + 1) - offset; //if offset, it's one less probe per axis to compute |
2295 | RD::get_singleton()->compute_list_dispatch(compute_list, groups.x, groups.y, groups.z); |
2296 | } |
2297 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
2298 | } |
2299 | |
2300 | RENDER_TIMESTAMP("SDFGI Store" ); |
2301 | |
2302 | // store |
2303 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_STORE]); |
2304 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].sdf_store_uniform_set, 0); |
2305 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant)); |
2306 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size); |
2307 | |
2308 | RD::get_singleton()->compute_list_end(); |
2309 | |
2310 | //clear these textures, as they will have previous garbage on next draw |
2311 | RD::get_singleton()->texture_clear(cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2312 | RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2313 | RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); |
2314 | |
2315 | #if 0 |
2316 | Vector<uint8_t> data = RD::get_singleton()->texture_get_data(cascades[cascade].sdf, 0); |
2317 | Ref<Image> img; |
2318 | img.instantiate(); |
2319 | for (uint32_t i = 0; i < cascade_size; i++) { |
2320 | Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1)); |
2321 | img->set_data(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr); |
2322 | img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png" ); |
2323 | } |
2324 | |
2325 | //finalize render and update sdf |
2326 | #endif |
2327 | |
2328 | #if 0 |
2329 | Vector<uint8_t> data = RD::get_singleton()->texture_get_data(render_albedo, 0); |
2330 | Ref<Image> img; |
2331 | img.instantiate(); |
2332 | for (uint32_t i = 0; i < cascade_size; i++) { |
2333 | Vector<uint8_t> subarr = data.slice(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2); |
2334 | img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr); |
2335 | img->convert(Image::FORMAT_RGBA8); |
2336 | img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png" ); |
2337 | } |
2338 | |
2339 | //finalize render and update sdf |
2340 | #endif |
2341 | |
2342 | RENDER_TIMESTAMP("< SDFGI Update SDF" ); |
2343 | RD::get_singleton()->draw_command_end_label(); |
2344 | } |
2345 | } |
2346 | |
2347 | void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) { |
2348 | ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but... |
2349 | |
2350 | RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); |
2351 | |
2352 | RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights" ); |
2353 | |
2354 | update_cascades(); |
2355 | |
2356 | SDFGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS]; |
2357 | uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS]; |
2358 | |
2359 | for (uint32_t i = 0; i < p_cascade_count; i++) { |
2360 | ERR_CONTINUE(p_cascade_indices[i] >= cascades.size()); |
2361 | |
2362 | SDFGI::Cascade &cc = cascades[p_cascade_indices[i]]; |
2363 | |
2364 | { //fill light buffer |
2365 | |
2366 | AABB cascade_aabb; |
2367 | cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cc.position)) * cc.cell_size; |
2368 | cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cc.cell_size; |
2369 | |
2370 | int idx = 0; |
2371 | |
2372 | for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) { |
2373 | if (idx == SDFGI::MAX_STATIC_LIGHTS) { |
2374 | break; |
2375 | } |
2376 | |
2377 | RID light_instance = p_positional_light_cull_result[i][j]; |
2378 | ERR_CONTINUE(!light_storage->owns_light_instance(light_instance)); |
2379 | |
2380 | RID light = light_storage->light_instance_get_base_light(light_instance); |
2381 | AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance); |
2382 | Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance); |
2383 | |
2384 | uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light); |
2385 | if (p_cascade_indices[i] > max_sdfgi_cascade) { |
2386 | continue; |
2387 | } |
2388 | |
2389 | if (!cascade_aabb.intersects(light_aabb)) { |
2390 | continue; |
2391 | } |
2392 | |
2393 | lights[idx].type = RSG::light_storage->light_get_type(light); |
2394 | |
2395 | Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z); |
2396 | if (lights[idx].type == RS::LIGHT_DIRECTIONAL) { |
2397 | dir.y *= y_mult; //only makes sense for directional |
2398 | dir.normalize(); |
2399 | } |
2400 | lights[idx].direction[0] = dir.x; |
2401 | lights[idx].direction[1] = dir.y; |
2402 | lights[idx].direction[2] = dir.z; |
2403 | Vector3 pos = light_transform.origin; |
2404 | pos.y *= y_mult; |
2405 | lights[idx].position[0] = pos.x; |
2406 | lights[idx].position[1] = pos.y; |
2407 | lights[idx].position[2] = pos.z; |
2408 | Color color = RSG::light_storage->light_get_color(light); |
2409 | color = color.srgb_to_linear(); |
2410 | lights[idx].color[0] = color.r; |
2411 | lights[idx].color[1] = color.g; |
2412 | lights[idx].color[2] = color.b; |
2413 | |
2414 | lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); |
2415 | if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { |
2416 | lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); |
2417 | |
2418 | // Convert from Luminous Power to Luminous Intensity |
2419 | if (lights[idx].type == RS::LIGHT_OMNI) { |
2420 | lights[idx].energy *= 1.0 / (Math_PI * 4.0); |
2421 | } else if (lights[idx].type == RS::LIGHT_SPOT) { |
2422 | // Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle. |
2423 | // We make this assumption to keep them easy to control. |
2424 | lights[idx].energy *= 1.0 / Math_PI; |
2425 | } |
2426 | } |
2427 | |
2428 | if (p_render_data->camera_attributes.is_valid()) { |
2429 | lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); |
2430 | } |
2431 | |
2432 | lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light); |
2433 | lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); |
2434 | lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE); |
2435 | lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); |
2436 | lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); |
2437 | |
2438 | idx++; |
2439 | } |
2440 | |
2441 | if (idx > 0) { |
2442 | RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights); |
2443 | } |
2444 | |
2445 | light_count[i] = idx; |
2446 | } |
2447 | } |
2448 | |
2449 | /* Static Lights */ |
2450 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
2451 | |
2452 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_STATIC]); |
2453 | |
2454 | SDFGIShader::DirectLightPushConstant dl_push_constant; |
2455 | |
2456 | dl_push_constant.grid_size[0] = cascade_size; |
2457 | dl_push_constant.grid_size[1] = cascade_size; |
2458 | dl_push_constant.grid_size[2] = cascade_size; |
2459 | dl_push_constant.max_cascades = cascades.size(); |
2460 | dl_push_constant.probe_axis_size = probe_axis_count; |
2461 | dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet |
2462 | dl_push_constant.y_mult = y_mult; |
2463 | dl_push_constant.use_occlusion = uses_occlusion; |
2464 | |
2465 | //all must be processed |
2466 | dl_push_constant.process_offset = 0; |
2467 | dl_push_constant.process_increment = 1; |
2468 | |
2469 | for (uint32_t i = 0; i < p_cascade_count; i++) { |
2470 | ERR_CONTINUE(p_cascade_indices[i] >= cascades.size()); |
2471 | |
2472 | SDFGI::Cascade &cc = cascades[p_cascade_indices[i]]; |
2473 | |
2474 | dl_push_constant.light_count = light_count[i]; |
2475 | dl_push_constant.cascade = p_cascade_indices[i]; |
2476 | |
2477 | if (dl_push_constant.light_count > 0) { |
2478 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_static_uniform_set, 0); |
2479 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDFGIShader::DirectLightPushConstant)); |
2480 | RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer, 0); |
2481 | } |
2482 | } |
2483 | |
2484 | RD::get_singleton()->compute_list_end(); |
2485 | |
2486 | RD::get_singleton()->draw_command_end_label(); |
2487 | } |
2488 | |
2489 | //////////////////////////////////////////////////////////////////////////////// |
2490 | // VoxelGIInstance |
2491 | |
2492 | void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { |
2493 | RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); |
2494 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
2495 | |
2496 | uint32_t data_version = gi->voxel_gi_get_data_version(probe); |
2497 | |
2498 | // (RE)CREATE IF NEEDED |
2499 | |
2500 | if (last_probe_data_version != data_version) { |
2501 | //need to re-create everything |
2502 | free_resources(); |
2503 | |
2504 | Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); |
2505 | |
2506 | if (octree_size != Vector3i()) { |
2507 | //can create a 3D texture |
2508 | Vector<int> levels = gi->voxel_gi_get_level_counts(probe); |
2509 | |
2510 | RD::TextureFormat tf; |
2511 | tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; |
2512 | tf.width = octree_size.x; |
2513 | tf.height = octree_size.y; |
2514 | tf.depth = octree_size.z; |
2515 | tf.texture_type = RD::TEXTURE_TYPE_3D; |
2516 | tf.mipmaps = levels.size(); |
2517 | |
2518 | tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; |
2519 | |
2520 | texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
2521 | RD::get_singleton()->set_resource_name(texture, "VoxelGI Instance Texture" ); |
2522 | |
2523 | RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1); |
2524 | |
2525 | { |
2526 | int total_elements = 0; |
2527 | for (int i = 0; i < levels.size(); i++) { |
2528 | total_elements += levels[i]; |
2529 | } |
2530 | |
2531 | write_buffer = RD::get_singleton()->storage_buffer_create(total_elements * 16); |
2532 | } |
2533 | |
2534 | for (int i = 0; i < levels.size(); i++) { |
2535 | VoxelGIInstance::Mipmap mipmap; |
2536 | mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, 1, RD::TEXTURE_SLICE_3D); |
2537 | mipmap.level = levels.size() - i - 1; |
2538 | mipmap.cell_offset = 0; |
2539 | for (uint32_t j = 0; j < mipmap.level; j++) { |
2540 | mipmap.cell_offset += levels[j]; |
2541 | } |
2542 | mipmap.cell_count = levels[mipmap.level]; |
2543 | |
2544 | Vector<RD::Uniform> uniforms; |
2545 | { |
2546 | RD::Uniform u; |
2547 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
2548 | u.binding = 1; |
2549 | u.append_id(gi->voxel_gi_get_octree_buffer(probe)); |
2550 | uniforms.push_back(u); |
2551 | } |
2552 | { |
2553 | RD::Uniform u; |
2554 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
2555 | u.binding = 2; |
2556 | u.append_id(gi->voxel_gi_get_data_buffer(probe)); |
2557 | uniforms.push_back(u); |
2558 | } |
2559 | |
2560 | { |
2561 | RD::Uniform u; |
2562 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
2563 | u.binding = 4; |
2564 | u.append_id(write_buffer); |
2565 | uniforms.push_back(u); |
2566 | } |
2567 | { |
2568 | RD::Uniform u; |
2569 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
2570 | u.binding = 9; |
2571 | u.append_id(gi->voxel_gi_get_sdf_texture(probe)); |
2572 | uniforms.push_back(u); |
2573 | } |
2574 | { |
2575 | RD::Uniform u; |
2576 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
2577 | u.binding = 10; |
2578 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
2579 | uniforms.push_back(u); |
2580 | } |
2581 | |
2582 | { |
2583 | Vector<RD::Uniform> copy_uniforms = uniforms; |
2584 | if (i == 0) { |
2585 | { |
2586 | RD::Uniform u; |
2587 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
2588 | u.binding = 3; |
2589 | u.append_id(gi->voxel_gi_lights_uniform); |
2590 | copy_uniforms.push_back(u); |
2591 | } |
2592 | |
2593 | mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT], 0); |
2594 | |
2595 | copy_uniforms = uniforms; //restore |
2596 | |
2597 | { |
2598 | RD::Uniform u; |
2599 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
2600 | u.binding = 5; |
2601 | u.append_id(texture); |
2602 | copy_uniforms.push_back(u); |
2603 | } |
2604 | mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0); |
2605 | } else { |
2606 | mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP], 0); |
2607 | } |
2608 | } |
2609 | |
2610 | { |
2611 | RD::Uniform u; |
2612 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2613 | u.binding = 5; |
2614 | u.append_id(mipmap.texture); |
2615 | uniforms.push_back(u); |
2616 | } |
2617 | |
2618 | mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE], 0); |
2619 | |
2620 | mipmaps.push_back(mipmap); |
2621 | } |
2622 | |
2623 | { |
2624 | uint32_t dynamic_map_size = MAX(MAX(octree_size.x, octree_size.y), octree_size.z); |
2625 | uint32_t oversample = nearest_power_of_2_templated(4); |
2626 | int mipmap_index = 0; |
2627 | |
2628 | while (mipmap_index < mipmaps.size()) { |
2629 | VoxelGIInstance::DynamicMap dmap; |
2630 | |
2631 | if (oversample > 0) { |
2632 | dmap.size = dynamic_map_size * (1 << oversample); |
2633 | dmap.mipmap = -1; |
2634 | oversample--; |
2635 | } else { |
2636 | dmap.size = dynamic_map_size >> mipmap_index; |
2637 | dmap.mipmap = mipmap_index; |
2638 | mipmap_index++; |
2639 | } |
2640 | |
2641 | RD::TextureFormat dtf; |
2642 | dtf.width = dmap.size; |
2643 | dtf.height = dmap.size; |
2644 | dtf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; |
2645 | dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; |
2646 | |
2647 | if (dynamic_maps.size() == 0) { |
2648 | dtf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; |
2649 | } |
2650 | dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView()); |
2651 | RD::get_singleton()->set_resource_name(dmap.texture, "VoxelGI Instance DMap Texture" ); |
2652 | |
2653 | if (dynamic_maps.size() == 0) { |
2654 | // Render depth for first one. |
2655 | // Use 16-bit depth when supported to improve performance. |
2656 | dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D16_UNORM, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; |
2657 | dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; |
2658 | dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView()); |
2659 | RD::get_singleton()->set_resource_name(dmap.fb_depth, "VoxelGI Instance DMap FB Depth" ); |
2660 | } |
2661 | |
2662 | //just use depth as-is |
2663 | dtf.format = RD::DATA_FORMAT_R32_SFLOAT; |
2664 | dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; |
2665 | |
2666 | dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView()); |
2667 | RD::get_singleton()->set_resource_name(dmap.depth, "VoxelGI Instance DMap Depth" ); |
2668 | |
2669 | if (dynamic_maps.size() == 0) { |
2670 | dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; |
2671 | dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; |
2672 | dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView()); |
2673 | RD::get_singleton()->set_resource_name(dmap.albedo, "VoxelGI Instance DMap Albedo" ); |
2674 | dmap.normal = RD::get_singleton()->texture_create(dtf, RD::TextureView()); |
2675 | RD::get_singleton()->set_resource_name(dmap.normal, "VoxelGI Instance DMap Normal" ); |
2676 | dmap.orm = RD::get_singleton()->texture_create(dtf, RD::TextureView()); |
2677 | RD::get_singleton()->set_resource_name(dmap.orm, "VoxelGI Instance DMap ORM" ); |
2678 | |
2679 | Vector<RID> fb; |
2680 | fb.push_back(dmap.albedo); |
2681 | fb.push_back(dmap.normal); |
2682 | fb.push_back(dmap.orm); |
2683 | fb.push_back(dmap.texture); //emission |
2684 | fb.push_back(dmap.depth); |
2685 | fb.push_back(dmap.fb_depth); |
2686 | |
2687 | dmap.fb = RD::get_singleton()->framebuffer_create(fb); |
2688 | |
2689 | { |
2690 | Vector<RD::Uniform> uniforms; |
2691 | { |
2692 | RD::Uniform u; |
2693 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
2694 | u.binding = 3; |
2695 | u.append_id(gi->voxel_gi_lights_uniform); |
2696 | uniforms.push_back(u); |
2697 | } |
2698 | |
2699 | { |
2700 | RD::Uniform u; |
2701 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2702 | u.binding = 5; |
2703 | u.append_id(dmap.albedo); |
2704 | uniforms.push_back(u); |
2705 | } |
2706 | { |
2707 | RD::Uniform u; |
2708 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2709 | u.binding = 6; |
2710 | u.append_id(dmap.normal); |
2711 | uniforms.push_back(u); |
2712 | } |
2713 | { |
2714 | RD::Uniform u; |
2715 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2716 | u.binding = 7; |
2717 | u.append_id(dmap.orm); |
2718 | uniforms.push_back(u); |
2719 | } |
2720 | { |
2721 | RD::Uniform u; |
2722 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
2723 | u.binding = 8; |
2724 | u.append_id(dmap.fb_depth); |
2725 | uniforms.push_back(u); |
2726 | } |
2727 | { |
2728 | RD::Uniform u; |
2729 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
2730 | u.binding = 9; |
2731 | u.append_id(gi->voxel_gi_get_sdf_texture(probe)); |
2732 | uniforms.push_back(u); |
2733 | } |
2734 | { |
2735 | RD::Uniform u; |
2736 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
2737 | u.binding = 10; |
2738 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
2739 | uniforms.push_back(u); |
2740 | } |
2741 | { |
2742 | RD::Uniform u; |
2743 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2744 | u.binding = 11; |
2745 | u.append_id(dmap.texture); |
2746 | uniforms.push_back(u); |
2747 | } |
2748 | { |
2749 | RD::Uniform u; |
2750 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2751 | u.binding = 12; |
2752 | u.append_id(dmap.depth); |
2753 | uniforms.push_back(u); |
2754 | } |
2755 | |
2756 | dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0); |
2757 | } |
2758 | } else { |
2759 | bool plot = dmap.mipmap >= 0; |
2760 | bool write = dmap.mipmap < (mipmaps.size() - 1); |
2761 | |
2762 | Vector<RD::Uniform> uniforms; |
2763 | |
2764 | { |
2765 | RD::Uniform u; |
2766 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2767 | u.binding = 5; |
2768 | u.append_id(dynamic_maps[dynamic_maps.size() - 1].texture); |
2769 | uniforms.push_back(u); |
2770 | } |
2771 | { |
2772 | RD::Uniform u; |
2773 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2774 | u.binding = 6; |
2775 | u.append_id(dynamic_maps[dynamic_maps.size() - 1].depth); |
2776 | uniforms.push_back(u); |
2777 | } |
2778 | |
2779 | if (write) { |
2780 | { |
2781 | RD::Uniform u; |
2782 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2783 | u.binding = 7; |
2784 | u.append_id(dmap.texture); |
2785 | uniforms.push_back(u); |
2786 | } |
2787 | { |
2788 | RD::Uniform u; |
2789 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2790 | u.binding = 8; |
2791 | u.append_id(dmap.depth); |
2792 | uniforms.push_back(u); |
2793 | } |
2794 | } |
2795 | |
2796 | { |
2797 | RD::Uniform u; |
2798 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
2799 | u.binding = 9; |
2800 | u.append_id(gi->voxel_gi_get_sdf_texture(probe)); |
2801 | uniforms.push_back(u); |
2802 | } |
2803 | { |
2804 | RD::Uniform u; |
2805 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
2806 | u.binding = 10; |
2807 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
2808 | uniforms.push_back(u); |
2809 | } |
2810 | |
2811 | if (plot) { |
2812 | { |
2813 | RD::Uniform u; |
2814 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
2815 | u.binding = 11; |
2816 | u.append_id(mipmaps[dmap.mipmap].texture); |
2817 | uniforms.push_back(u); |
2818 | } |
2819 | } |
2820 | |
2821 | dmap.uniform_set = RD::get_singleton()->uniform_set_create( |
2822 | uniforms, |
2823 | gi->voxel_gi_lighting_shader_version_shaders[(write && plot) ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)], |
2824 | 0); |
2825 | } |
2826 | |
2827 | dynamic_maps.push_back(dmap); |
2828 | } |
2829 | } |
2830 | } |
2831 | |
2832 | last_probe_data_version = data_version; |
2833 | p_update_light_instances = true; //just in case |
2834 | |
2835 | RendererSceneRenderRD::get_singleton()->base_uniforms_changed(); |
2836 | } |
2837 | |
2838 | // UDPDATE TIME |
2839 | |
2840 | if (has_dynamic_object_data) { |
2841 | //if it has dynamic object data, it needs to be cleared |
2842 | RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, mipmaps.size(), 0, 1); |
2843 | } |
2844 | |
2845 | uint32_t light_count = 0; |
2846 | |
2847 | if (p_update_light_instances || p_dynamic_objects.size() > 0) { |
2848 | light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size()); |
2849 | |
2850 | { |
2851 | Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe); |
2852 | Transform3D to_probe_xform = to_cell * transform.affine_inverse(); |
2853 | |
2854 | //update lights |
2855 | |
2856 | for (uint32_t i = 0; i < light_count; i++) { |
2857 | VoxelGILight &l = gi->voxel_gi_lights[i]; |
2858 | RID light_instance = p_light_instances[i]; |
2859 | RID light = light_storage->light_instance_get_base_light(light_instance); |
2860 | |
2861 | l.type = RSG::light_storage->light_get_type(light); |
2862 | if (l.type == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { |
2863 | light_count--; |
2864 | continue; |
2865 | } |
2866 | |
2867 | l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION); |
2868 | l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY); |
2869 | |
2870 | if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { |
2871 | l.energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY); |
2872 | |
2873 | l.energy *= gi->voxel_gi_get_baked_exposure_normalization(probe); |
2874 | |
2875 | // Convert from Luminous Power to Luminous Intensity |
2876 | if (l.type == RS::LIGHT_OMNI) { |
2877 | l.energy *= 1.0 / (Math_PI * 4.0); |
2878 | } else if (l.type == RS::LIGHT_SPOT) { |
2879 | // Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle. |
2880 | // We make this assumption to keep them easy to control. |
2881 | l.energy *= 1.0 / Math_PI; |
2882 | } |
2883 | } |
2884 | |
2885 | l.radius = to_cell.basis.xform(Vector3(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length(); |
2886 | Color color = RSG::light_storage->light_get_color(light).srgb_to_linear(); |
2887 | l.color[0] = color.r; |
2888 | l.color[1] = color.g; |
2889 | l.color[2] = color.b; |
2890 | |
2891 | l.cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE))); |
2892 | l.inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION); |
2893 | |
2894 | Transform3D xform = light_storage->light_instance_get_base_transform(light_instance); |
2895 | |
2896 | Vector3 pos = to_probe_xform.xform(xform.origin); |
2897 | Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_column(2)).normalized(); |
2898 | |
2899 | l.position[0] = pos.x; |
2900 | l.position[1] = pos.y; |
2901 | l.position[2] = pos.z; |
2902 | |
2903 | l.direction[0] = dir.x; |
2904 | l.direction[1] = dir.y; |
2905 | l.direction[2] = dir.z; |
2906 | |
2907 | l.has_shadow = RSG::light_storage->light_has_shadow(light); |
2908 | } |
2909 | |
2910 | RD::get_singleton()->buffer_update(gi->voxel_gi_lights_uniform, 0, sizeof(VoxelGILight) * light_count, gi->voxel_gi_lights); |
2911 | } |
2912 | } |
2913 | |
2914 | if (has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) { |
2915 | // PROCESS MIPMAPS |
2916 | if (mipmaps.size()) { |
2917 | //can update mipmaps |
2918 | |
2919 | Vector3i probe_size = gi->voxel_gi_get_octree_size(probe); |
2920 | |
2921 | VoxelGIPushConstant push_constant; |
2922 | |
2923 | push_constant.limits[0] = probe_size.x; |
2924 | push_constant.limits[1] = probe_size.y; |
2925 | push_constant.limits[2] = probe_size.z; |
2926 | push_constant.stack_size = mipmaps.size(); |
2927 | push_constant.emission_scale = 1.0; |
2928 | push_constant.propagation = gi->voxel_gi_get_propagation(probe); |
2929 | push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe); |
2930 | push_constant.light_count = light_count; |
2931 | push_constant.aniso_strength = 0; |
2932 | |
2933 | /* print_line("probe update to version " + itos(last_probe_version)); |
2934 | print_line("propagation " + rtos(push_constant.propagation)); |
2935 | print_line("dynrange " + rtos(push_constant.dynamic_range)); |
2936 | */ |
2937 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
2938 | |
2939 | int passes; |
2940 | if (p_update_light_instances) { |
2941 | passes = gi->voxel_gi_is_using_two_bounces(probe) ? 2 : 1; |
2942 | } else { |
2943 | passes = 1; //only re-blitting is necessary |
2944 | } |
2945 | int wg_size = 64; |
2946 | int64_t wg_limit_x = (int64_t)RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); |
2947 | |
2948 | for (int pass = 0; pass < passes; pass++) { |
2949 | if (p_update_light_instances) { |
2950 | for (int i = 0; i < mipmaps.size(); i++) { |
2951 | if (i == 0) { |
2952 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[pass == 0 ? VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT : VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]); |
2953 | } else if (i == 1) { |
2954 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP]); |
2955 | } |
2956 | |
2957 | if (pass == 1 || i > 0) { |
2958 | RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done |
2959 | } |
2960 | if (pass == 0 || i > 0) { |
2961 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].uniform_set, 0); |
2962 | } else { |
2963 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].second_bounce_uniform_set, 0); |
2964 | } |
2965 | |
2966 | push_constant.cell_offset = mipmaps[i].cell_offset; |
2967 | push_constant.cell_count = mipmaps[i].cell_count; |
2968 | |
2969 | int64_t wg_todo = (mipmaps[i].cell_count + wg_size - 1) / wg_size; |
2970 | while (wg_todo) { |
2971 | int64_t wg_count = MIN(wg_todo, wg_limit_x); |
2972 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant)); |
2973 | RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); |
2974 | wg_todo -= wg_count; |
2975 | push_constant.cell_offset += wg_count * wg_size; |
2976 | } |
2977 | } |
2978 | |
2979 | RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done |
2980 | } |
2981 | |
2982 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE]); |
2983 | |
2984 | for (int i = 0; i < mipmaps.size(); i++) { |
2985 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].write_uniform_set, 0); |
2986 | |
2987 | push_constant.cell_offset = mipmaps[i].cell_offset; |
2988 | push_constant.cell_count = mipmaps[i].cell_count; |
2989 | |
2990 | int64_t wg_todo = (mipmaps[i].cell_count + wg_size - 1) / wg_size; |
2991 | while (wg_todo) { |
2992 | int64_t wg_count = MIN(wg_todo, wg_limit_x); |
2993 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant)); |
2994 | RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); |
2995 | wg_todo -= wg_count; |
2996 | push_constant.cell_offset += wg_count * wg_size; |
2997 | } |
2998 | } |
2999 | } |
3000 | |
3001 | RD::get_singleton()->compute_list_end(); |
3002 | } |
3003 | } |
3004 | |
3005 | has_dynamic_object_data = false; //clear until dynamic object data is used again |
3006 | |
3007 | if (p_dynamic_objects.size() && dynamic_maps.size()) { |
3008 | Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); |
3009 | int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z); |
3010 | |
3011 | Transform3D oversample_scale; |
3012 | oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier)); |
3013 | |
3014 | Transform3D to_cell = oversample_scale * gi->voxel_gi_get_to_cell_xform(probe); |
3015 | Transform3D to_world_xform = transform * to_cell.affine_inverse(); |
3016 | Transform3D to_probe_xform = to_world_xform.affine_inverse(); |
3017 | |
3018 | AABB probe_aabb(Vector3(), octree_size); |
3019 | |
3020 | //this could probably be better parallelized in compute.. |
3021 | for (int i = 0; i < (int)p_dynamic_objects.size(); i++) { |
3022 | RenderGeometryInstance *instance = p_dynamic_objects[i]; |
3023 | |
3024 | //transform aabb to voxel_gi |
3025 | AABB aabb = (to_probe_xform * instance->get_transform()).xform(instance->get_aabb()); |
3026 | |
3027 | //this needs to wrap to grid resolution to avoid jitter |
3028 | //also extend margin a bit just in case |
3029 | Vector3i begin = aabb.position - Vector3i(1, 1, 1); |
3030 | Vector3i end = aabb.position + aabb.size + Vector3i(1, 1, 1); |
3031 | |
3032 | for (int j = 0; j < 3; j++) { |
3033 | if ((end[j] - begin[j]) & 1) { |
3034 | end[j]++; //for half extents split, it needs to be even |
3035 | } |
3036 | begin[j] = MAX(begin[j], 0); |
3037 | end[j] = MIN(end[j], octree_size[j] * multiplier); |
3038 | } |
3039 | |
3040 | //aabb = aabb.intersection(probe_aabb); //intersect |
3041 | aabb.position = begin; |
3042 | aabb.size = end - begin; |
3043 | |
3044 | //print_line("aabb: " + aabb); |
3045 | |
3046 | for (int j = 0; j < 6; j++) { |
3047 | //if (j != 0 && j != 3) { |
3048 | // continue; |
3049 | //} |
3050 | static const Vector3 render_z[6] = { |
3051 | Vector3(1, 0, 0), |
3052 | Vector3(0, 1, 0), |
3053 | Vector3(0, 0, 1), |
3054 | Vector3(-1, 0, 0), |
3055 | Vector3(0, -1, 0), |
3056 | Vector3(0, 0, -1), |
3057 | }; |
3058 | static const Vector3 render_up[6] = { |
3059 | Vector3(0, 1, 0), |
3060 | Vector3(0, 0, 1), |
3061 | Vector3(0, 1, 0), |
3062 | Vector3(0, 1, 0), |
3063 | Vector3(0, 0, 1), |
3064 | Vector3(0, 1, 0), |
3065 | }; |
3066 | |
3067 | Vector3 render_dir = render_z[j]; |
3068 | Vector3 up_dir = render_up[j]; |
3069 | |
3070 | Vector3 center = aabb.get_center(); |
3071 | Transform3D xform; |
3072 | xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir); |
3073 | |
3074 | Vector3 x_dir = xform.basis.get_column(0).abs(); |
3075 | int x_axis = int(Vector3(0, 1, 2).dot(x_dir)); |
3076 | Vector3 y_dir = xform.basis.get_column(1).abs(); |
3077 | int y_axis = int(Vector3(0, 1, 2).dot(y_dir)); |
3078 | Vector3 z_dir = -xform.basis.get_column(2); |
3079 | int z_axis = int(Vector3(0, 1, 2).dot(z_dir.abs())); |
3080 | |
3081 | Rect2i rect(aabb.position[x_axis], aabb.position[y_axis], aabb.size[x_axis], aabb.size[y_axis]); |
3082 | bool x_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(0)) < 0); |
3083 | bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(1)) < 0); |
3084 | bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(2)) > 0); |
3085 | |
3086 | Projection cm; |
3087 | cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]); |
3088 | |
3089 | if (RendererSceneRenderRD::get_singleton()->cull_argument.size() == 0) { |
3090 | RendererSceneRenderRD::get_singleton()->cull_argument.push_back(nullptr); |
3091 | } |
3092 | RendererSceneRenderRD::get_singleton()->cull_argument[0] = instance; |
3093 | |
3094 | float exposure_normalization = 1.0; |
3095 | if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { |
3096 | exposure_normalization = gi->voxel_gi_get_baked_exposure_normalization(probe); |
3097 | } |
3098 | |
3099 | RendererSceneRenderRD::get_singleton()->_render_material(to_world_xform * xform, cm, true, RendererSceneRenderRD::get_singleton()->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization); |
3100 | |
3101 | VoxelGIDynamicPushConstant push_constant; |
3102 | memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant)); |
3103 | push_constant.limits[0] = octree_size.x; |
3104 | push_constant.limits[1] = octree_size.y; |
3105 | push_constant.limits[2] = octree_size.z; |
3106 | push_constant.light_count = p_light_instances.size(); |
3107 | push_constant.x_dir[0] = x_dir[0]; |
3108 | push_constant.x_dir[1] = x_dir[1]; |
3109 | push_constant.x_dir[2] = x_dir[2]; |
3110 | push_constant.y_dir[0] = y_dir[0]; |
3111 | push_constant.y_dir[1] = y_dir[1]; |
3112 | push_constant.y_dir[2] = y_dir[2]; |
3113 | push_constant.z_dir[0] = z_dir[0]; |
3114 | push_constant.z_dir[1] = z_dir[1]; |
3115 | push_constant.z_dir[2] = z_dir[2]; |
3116 | push_constant.z_base = xform.origin[z_axis]; |
3117 | push_constant.z_sign = (z_flip ? -1.0 : 1.0); |
3118 | push_constant.pos_multiplier = float(1.0) / multiplier; |
3119 | push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe); |
3120 | push_constant.flip_x = x_flip; |
3121 | push_constant.flip_y = y_flip; |
3122 | push_constant.rect_pos[0] = rect.position[0]; |
3123 | push_constant.rect_pos[1] = rect.position[1]; |
3124 | push_constant.rect_size[0] = rect.size[0]; |
3125 | push_constant.rect_size[1] = rect.size[1]; |
3126 | push_constant.prev_rect_ofs[0] = 0; |
3127 | push_constant.prev_rect_ofs[1] = 0; |
3128 | push_constant.prev_rect_size[0] = 0; |
3129 | push_constant.prev_rect_size[1] = 0; |
3130 | push_constant.on_mipmap = false; |
3131 | push_constant.propagation = gi->voxel_gi_get_propagation(probe); |
3132 | push_constant.pad[0] = 0; |
3133 | push_constant.pad[1] = 0; |
3134 | push_constant.pad[2] = 0; |
3135 | |
3136 | //process lighting |
3137 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); |
3138 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]); |
3139 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[0].uniform_set, 0); |
3140 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant)); |
3141 | RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1); |
3142 | //print_line("rect: " + itos(i) + ": " + rect); |
3143 | |
3144 | for (int k = 1; k < dynamic_maps.size(); k++) { |
3145 | // enlarge the rect if needed so all pixels fit when downscaled, |
3146 | // this ensures downsampling is smooth and optimal because no pixels are left behind |
3147 | |
3148 | //x |
3149 | if (rect.position.x & 1) { |
3150 | rect.size.x++; |
3151 | push_constant.prev_rect_ofs[0] = 1; //this is used to ensure reading is also optimal |
3152 | } else { |
3153 | push_constant.prev_rect_ofs[0] = 0; |
3154 | } |
3155 | if (rect.size.x & 1) { |
3156 | rect.size.x++; |
3157 | } |
3158 | |
3159 | rect.position.x >>= 1; |
3160 | rect.size.x = MAX(1, rect.size.x >> 1); |
3161 | |
3162 | //y |
3163 | if (rect.position.y & 1) { |
3164 | rect.size.y++; |
3165 | push_constant.prev_rect_ofs[1] = 1; |
3166 | } else { |
3167 | push_constant.prev_rect_ofs[1] = 0; |
3168 | } |
3169 | if (rect.size.y & 1) { |
3170 | rect.size.y++; |
3171 | } |
3172 | |
3173 | rect.position.y >>= 1; |
3174 | rect.size.y = MAX(1, rect.size.y >> 1); |
3175 | |
3176 | //shrink limits to ensure plot does not go outside map |
3177 | if (dynamic_maps[k].mipmap > 0) { |
3178 | for (int l = 0; l < 3; l++) { |
3179 | push_constant.limits[l] = MAX(1, push_constant.limits[l] >> 1); |
3180 | } |
3181 | } |
3182 | |
3183 | //print_line("rect: " + itos(i) + ": " + rect); |
3184 | push_constant.rect_pos[0] = rect.position[0]; |
3185 | push_constant.rect_pos[1] = rect.position[1]; |
3186 | push_constant.prev_rect_size[0] = push_constant.rect_size[0]; |
3187 | push_constant.prev_rect_size[1] = push_constant.rect_size[1]; |
3188 | push_constant.rect_size[0] = rect.size[0]; |
3189 | push_constant.rect_size[1] = rect.size[1]; |
3190 | push_constant.on_mipmap = dynamic_maps[k].mipmap > 0; |
3191 | |
3192 | RD::get_singleton()->compute_list_add_barrier(compute_list); |
3193 | |
3194 | if (dynamic_maps[k].mipmap < 0) { |
3195 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]); |
3196 | } else if (k < dynamic_maps.size() - 1) { |
3197 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]); |
3198 | } else { |
3199 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]); |
3200 | } |
3201 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[k].uniform_set, 0); |
3202 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant)); |
3203 | RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1); |
3204 | } |
3205 | |
3206 | RD::get_singleton()->compute_list_end(); |
3207 | } |
3208 | } |
3209 | |
3210 | has_dynamic_object_data = true; //clear until dynamic object data is used again |
3211 | } |
3212 | |
3213 | last_probe_version = gi->voxel_gi_get_version(probe); |
3214 | } |
3215 | |
3216 | void GI::VoxelGIInstance::free_resources() { |
3217 | if (texture.is_valid()) { |
3218 | RD::get_singleton()->free(texture); |
3219 | RD::get_singleton()->free(write_buffer); |
3220 | |
3221 | texture = RID(); |
3222 | write_buffer = RID(); |
3223 | mipmaps.clear(); |
3224 | } |
3225 | |
3226 | for (int i = 0; i < dynamic_maps.size(); i++) { |
3227 | RD::get_singleton()->free(dynamic_maps[i].texture); |
3228 | RD::get_singleton()->free(dynamic_maps[i].depth); |
3229 | |
3230 | // these only exist on the first level... |
3231 | if (dynamic_maps[i].fb_depth.is_valid()) { |
3232 | RD::get_singleton()->free(dynamic_maps[i].fb_depth); |
3233 | } |
3234 | if (dynamic_maps[i].albedo.is_valid()) { |
3235 | RD::get_singleton()->free(dynamic_maps[i].albedo); |
3236 | } |
3237 | if (dynamic_maps[i].normal.is_valid()) { |
3238 | RD::get_singleton()->free(dynamic_maps[i].normal); |
3239 | } |
3240 | if (dynamic_maps[i].orm.is_valid()) { |
3241 | RD::get_singleton()->free(dynamic_maps[i].orm); |
3242 | } |
3243 | } |
3244 | dynamic_maps.clear(); |
3245 | } |
3246 | |
3247 | void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { |
3248 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
3249 | |
3250 | if (mipmaps.size() == 0) { |
3251 | return; |
3252 | } |
3253 | |
3254 | Projection cam_transform = (p_camera_with_transform * Projection(transform)) * Projection(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse()); |
3255 | |
3256 | int level = 0; |
3257 | Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); |
3258 | |
3259 | VoxelGIDebugPushConstant push_constant; |
3260 | push_constant.alpha = p_alpha; |
3261 | push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe); |
3262 | push_constant.cell_offset = mipmaps[level].cell_offset; |
3263 | push_constant.level = level; |
3264 | |
3265 | push_constant.bounds[0] = octree_size.x >> level; |
3266 | push_constant.bounds[1] = octree_size.y >> level; |
3267 | push_constant.bounds[2] = octree_size.z >> level; |
3268 | push_constant.pad = 0; |
3269 | |
3270 | for (int i = 0; i < 4; i++) { |
3271 | for (int j = 0; j < 4; j++) { |
3272 | push_constant.projection[i * 4 + j] = cam_transform.columns[i][j]; |
3273 | } |
3274 | } |
3275 | |
3276 | if (gi->voxel_gi_debug_uniform_set.is_valid()) { |
3277 | RD::get_singleton()->free(gi->voxel_gi_debug_uniform_set); |
3278 | } |
3279 | Vector<RD::Uniform> uniforms; |
3280 | { |
3281 | RD::Uniform u; |
3282 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
3283 | u.binding = 1; |
3284 | u.append_id(gi->voxel_gi_get_data_buffer(probe)); |
3285 | uniforms.push_back(u); |
3286 | } |
3287 | { |
3288 | RD::Uniform u; |
3289 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3290 | u.binding = 2; |
3291 | u.append_id(texture); |
3292 | uniforms.push_back(u); |
3293 | } |
3294 | { |
3295 | RD::Uniform u; |
3296 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
3297 | u.binding = 3; |
3298 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
3299 | uniforms.push_back(u); |
3300 | } |
3301 | |
3302 | int cell_count; |
3303 | if (!p_emission && p_lighting && has_dynamic_object_data) { |
3304 | cell_count = push_constant.bounds[0] * push_constant.bounds[1] * push_constant.bounds[2]; |
3305 | } else { |
3306 | cell_count = mipmaps[level].cell_count; |
3307 | } |
3308 | |
3309 | gi->voxel_gi_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_debug_shader_version_shaders[0], 0); |
3310 | |
3311 | int voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_COLOR; |
3312 | if (p_emission) { |
3313 | voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_EMISSION; |
3314 | } else if (p_lighting) { |
3315 | voxel_gi_debug_pipeline = has_dynamic_object_data ? VOXEL_GI_DEBUG_LIGHT_FULL : VOXEL_GI_DEBUG_LIGHT; |
3316 | } |
3317 | RD::get_singleton()->draw_list_bind_render_pipeline( |
3318 | p_draw_list, |
3319 | gi->voxel_gi_debug_shader_version_pipelines[voxel_gi_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer))); |
3320 | RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->voxel_gi_debug_uniform_set, 0); |
3321 | RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(VoxelGIDebugPushConstant)); |
3322 | RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36); |
3323 | } |
3324 | |
3325 | //////////////////////////////////////////////////////////////////////////////// |
3326 | // GI |
3327 | |
3328 | GI::GI() { |
3329 | singleton = this; |
3330 | |
3331 | sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count" )), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1))); |
3332 | sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge" )), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1))); |
3333 | sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_update_lights" )), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1))); |
3334 | } |
3335 | |
3336 | GI::~GI() { |
3337 | singleton = nullptr; |
3338 | } |
3339 | |
3340 | void GI::init(SkyRD *p_sky) { |
3341 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
3342 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
3343 | |
3344 | /* GI */ |
3345 | |
3346 | { |
3347 | //kinda complicated to compute the amount of slots, we try to use as many as we can |
3348 | |
3349 | voxel_gi_lights = memnew_arr(VoxelGILight, voxel_gi_max_lights); |
3350 | voxel_gi_lights_uniform = RD::get_singleton()->uniform_buffer_create(voxel_gi_max_lights * sizeof(VoxelGILight)); |
3351 | voxel_gi_quality = RS::VoxelGIQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/voxel_gi/quality" )), 0, 1)); |
3352 | |
3353 | String defines = "\n#define MAX_LIGHTS " + itos(voxel_gi_max_lights) + "\n" ; |
3354 | |
3355 | Vector<String> versions; |
3356 | versions.push_back("\n#define MODE_COMPUTE_LIGHT\n" ); |
3357 | versions.push_back("\n#define MODE_SECOND_BOUNCE\n" ); |
3358 | versions.push_back("\n#define MODE_UPDATE_MIPMAPS\n" ); |
3359 | versions.push_back("\n#define MODE_WRITE_TEXTURE\n" ); |
3360 | versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_LIGHTING\n" ); |
3361 | versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_WRITE\n" ); |
3362 | versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n" ); |
3363 | versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n" ); |
3364 | |
3365 | voxel_gi_shader.initialize(versions, defines); |
3366 | voxel_gi_lighting_shader_version = voxel_gi_shader.version_create(); |
3367 | for (int i = 0; i < VOXEL_GI_SHADER_VERSION_MAX; i++) { |
3368 | voxel_gi_lighting_shader_version_shaders[i] = voxel_gi_shader.version_get_shader(voxel_gi_lighting_shader_version, i); |
3369 | voxel_gi_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(voxel_gi_lighting_shader_version_shaders[i]); |
3370 | } |
3371 | } |
3372 | |
3373 | { |
3374 | String defines; |
3375 | Vector<String> versions; |
3376 | versions.push_back("\n#define MODE_DEBUG_COLOR\n" ); |
3377 | versions.push_back("\n#define MODE_DEBUG_LIGHT\n" ); |
3378 | versions.push_back("\n#define MODE_DEBUG_EMISSION\n" ); |
3379 | versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n" ); |
3380 | |
3381 | voxel_gi_debug_shader.initialize(versions, defines); |
3382 | voxel_gi_debug_shader_version = voxel_gi_debug_shader.version_create(); |
3383 | for (int i = 0; i < VOXEL_GI_DEBUG_MAX; i++) { |
3384 | voxel_gi_debug_shader_version_shaders[i] = voxel_gi_debug_shader.version_get_shader(voxel_gi_debug_shader_version, i); |
3385 | |
3386 | RD::PipelineRasterizationState rs; |
3387 | rs.cull_mode = RD::POLYGON_CULL_FRONT; |
3388 | RD::PipelineDepthStencilState ds; |
3389 | ds.enable_depth_test = true; |
3390 | ds.enable_depth_write = true; |
3391 | ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; |
3392 | |
3393 | voxel_gi_debug_shader_version_pipelines[i].setup(voxel_gi_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); |
3394 | } |
3395 | } |
3396 | |
3397 | /* SDGFI */ |
3398 | |
3399 | { |
3400 | Vector<String> preprocess_modes; |
3401 | preprocess_modes.push_back("\n#define MODE_SCROLL\n" ); |
3402 | preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n" ); |
3403 | preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n" ); |
3404 | preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n" ); |
3405 | preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n" ); |
3406 | preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n" ); |
3407 | preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n" ); |
3408 | preprocess_modes.push_back("\n#define MODE_OCCLUSION\n" ); |
3409 | preprocess_modes.push_back("\n#define MODE_STORE\n" ); |
3410 | String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n" ; |
3411 | sdfgi_shader.preprocess.initialize(preprocess_modes, defines); |
3412 | sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create(); |
3413 | for (int i = 0; i < SDFGIShader::PRE_PROCESS_MAX; i++) { |
3414 | sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i)); |
3415 | } |
3416 | } |
3417 | |
3418 | { |
3419 | //calculate tables |
3420 | String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n" ; |
3421 | |
3422 | Vector<String> direct_light_modes; |
3423 | direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n" ); |
3424 | direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n" ); |
3425 | sdfgi_shader.direct_light.initialize(direct_light_modes, defines); |
3426 | sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create(); |
3427 | for (int i = 0; i < SDFGIShader::DIRECT_LIGHT_MODE_MAX; i++) { |
3428 | sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i)); |
3429 | } |
3430 | } |
3431 | |
3432 | { |
3433 | //calculate tables |
3434 | String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n" ; |
3435 | defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n" ; |
3436 | if (p_sky->sky_use_cubemap_array) { |
3437 | defines += "\n#define USE_CUBEMAP_ARRAY\n" ; |
3438 | } |
3439 | |
3440 | Vector<String> integrate_modes; |
3441 | integrate_modes.push_back("\n#define MODE_PROCESS\n" ); |
3442 | integrate_modes.push_back("\n#define MODE_STORE\n" ); |
3443 | integrate_modes.push_back("\n#define MODE_SCROLL\n" ); |
3444 | integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n" ); |
3445 | sdfgi_shader.integrate.initialize(integrate_modes, defines); |
3446 | sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create(); |
3447 | |
3448 | for (int i = 0; i < SDFGIShader::INTEGRATE_MODE_MAX; i++) { |
3449 | sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i)); |
3450 | } |
3451 | |
3452 | { |
3453 | Vector<RD::Uniform> uniforms; |
3454 | |
3455 | { |
3456 | RD::Uniform u; |
3457 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3458 | u.binding = 0; |
3459 | if (p_sky->sky_use_cubemap_array) { |
3460 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE)); |
3461 | } else { |
3462 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); |
3463 | } |
3464 | uniforms.push_back(u); |
3465 | } |
3466 | { |
3467 | RD::Uniform u; |
3468 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
3469 | u.binding = 1; |
3470 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
3471 | uniforms.push_back(u); |
3472 | } |
3473 | |
3474 | sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1); |
3475 | } |
3476 | } |
3477 | |
3478 | //GK |
3479 | { |
3480 | //calculate tables |
3481 | String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n" ; |
3482 | if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { |
3483 | defines += "\n#define USE_VRS\n" ; |
3484 | } |
3485 | if (!RD::get_singleton()->sampler_is_format_supported_for_filter(RD::DATA_FORMAT_R8G8_UINT, RD::SAMPLER_FILTER_LINEAR)) { |
3486 | defines += "\n#define SAMPLE_VOXEL_GI_NEAREST\n" ; |
3487 | } |
3488 | |
3489 | Vector<String> gi_modes; |
3490 | |
3491 | gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n" ); // MODE_VOXEL_GI |
3492 | gi_modes.push_back("\n#define USE_SDFGI\n" ); // MODE_SDFGI |
3493 | gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n" ); // MODE_COMBINED |
3494 | |
3495 | shader.initialize(gi_modes, defines); |
3496 | shader_version = shader.version_create(); |
3497 | |
3498 | Vector<RD::PipelineSpecializationConstant> specialization_constants; |
3499 | |
3500 | { |
3501 | RD::PipelineSpecializationConstant sc; |
3502 | sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; |
3503 | sc.constant_id = 0; // SHADER_SPECIALIZATION_HALF_RES |
3504 | sc.bool_value = false; |
3505 | specialization_constants.push_back(sc); |
3506 | |
3507 | sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; |
3508 | sc.constant_id = 1; // SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX |
3509 | sc.bool_value = false; |
3510 | specialization_constants.push_back(sc); |
3511 | |
3512 | sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; |
3513 | sc.constant_id = 2; // SHADER_SPECIALIZATION_USE_VRS |
3514 | sc.bool_value = false; |
3515 | specialization_constants.push_back(sc); |
3516 | } |
3517 | |
3518 | for (int v = 0; v < SHADER_SPECIALIZATION_VARIATIONS; v++) { |
3519 | specialization_constants.ptrw()[0].bool_value = (v & SHADER_SPECIALIZATION_HALF_RES) ? true : false; |
3520 | specialization_constants.ptrw()[1].bool_value = (v & SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX) ? true : false; |
3521 | specialization_constants.ptrw()[2].bool_value = (v & SHADER_SPECIALIZATION_USE_VRS) ? true : false; |
3522 | for (int i = 0; i < MODE_MAX; i++) { |
3523 | pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i), specialization_constants); |
3524 | } |
3525 | } |
3526 | |
3527 | sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIData)); |
3528 | } |
3529 | { |
3530 | String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n" ; |
3531 | Vector<String> debug_modes; |
3532 | debug_modes.push_back("" ); |
3533 | sdfgi_shader.debug.initialize(debug_modes, defines); |
3534 | sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create(); |
3535 | sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0); |
3536 | sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version); |
3537 | } |
3538 | { |
3539 | String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n" ; |
3540 | |
3541 | Vector<String> versions; |
3542 | versions.push_back("\n#define MODE_PROBES\n" ); |
3543 | versions.push_back("\n#define MODE_PROBES\n#define USE_MULTIVIEW\n" ); |
3544 | versions.push_back("\n#define MODE_VISIBILITY\n" ); |
3545 | versions.push_back("\n#define MODE_VISIBILITY\n#define USE_MULTIVIEW\n" ); |
3546 | |
3547 | sdfgi_shader.debug_probes.initialize(versions, defines); |
3548 | |
3549 | // TODO disable multiview versions if turned off |
3550 | |
3551 | sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create(); |
3552 | |
3553 | { |
3554 | RD::PipelineRasterizationState rs; |
3555 | rs.cull_mode = RD::POLYGON_CULL_DISABLED; |
3556 | RD::PipelineDepthStencilState ds; |
3557 | ds.enable_depth_test = true; |
3558 | ds.enable_depth_write = true; |
3559 | ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; |
3560 | for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) { |
3561 | // TODO check if version is enabled |
3562 | |
3563 | RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i); |
3564 | sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0); |
3565 | } |
3566 | } |
3567 | } |
3568 | default_voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(VoxelGIData) * MAX_VOXEL_GI_INSTANCES); |
3569 | half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution" ); |
3570 | } |
3571 | |
3572 | void GI::free() { |
3573 | if (default_voxel_gi_buffer.is_valid()) { |
3574 | RD::get_singleton()->free(default_voxel_gi_buffer); |
3575 | } |
3576 | if (voxel_gi_lights_uniform.is_valid()) { |
3577 | RD::get_singleton()->free(voxel_gi_lights_uniform); |
3578 | } |
3579 | if (sdfgi_ubo.is_valid()) { |
3580 | RD::get_singleton()->free(sdfgi_ubo); |
3581 | } |
3582 | |
3583 | if (voxel_gi_debug_shader_version.is_valid()) { |
3584 | voxel_gi_debug_shader.version_free(voxel_gi_debug_shader_version); |
3585 | } |
3586 | if (voxel_gi_lighting_shader_version.is_valid()) { |
3587 | voxel_gi_shader.version_free(voxel_gi_lighting_shader_version); |
3588 | } |
3589 | if (shader_version.is_valid()) { |
3590 | shader.version_free(shader_version); |
3591 | } |
3592 | if (sdfgi_shader.debug_probes_shader.is_valid()) { |
3593 | sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader); |
3594 | } |
3595 | if (sdfgi_shader.debug_shader.is_valid()) { |
3596 | sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader); |
3597 | } |
3598 | if (sdfgi_shader.direct_light_shader.is_valid()) { |
3599 | sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader); |
3600 | } |
3601 | if (sdfgi_shader.integrate_shader.is_valid()) { |
3602 | sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader); |
3603 | } |
3604 | if (sdfgi_shader.preprocess_shader.is_valid()) { |
3605 | sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader); |
3606 | } |
3607 | |
3608 | if (voxel_gi_lights) { |
3609 | memdelete_arr(voxel_gi_lights); |
3610 | } |
3611 | } |
3612 | |
3613 | Ref<GI::SDFGI> GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { |
3614 | Ref<SDFGI> sdfgi; |
3615 | sdfgi.instantiate(); |
3616 | |
3617 | sdfgi->create(p_env, p_world_position, p_requested_history_size, this); |
3618 | |
3619 | return sdfgi; |
3620 | } |
3621 | |
3622 | void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used) { |
3623 | ERR_FAIL_COND(p_render_buffers.is_null()); |
3624 | |
3625 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
3626 | ERR_FAIL_NULL(texture_storage); |
3627 | |
3628 | r_voxel_gi_instances_used = 0; |
3629 | |
3630 | Ref<RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI); |
3631 | ERR_FAIL_COND(rbgi.is_null()); |
3632 | |
3633 | RID voxel_gi_buffer = rbgi->get_voxel_gi_buffer(); |
3634 | VoxelGIData voxel_gi_data[MAX_VOXEL_GI_INSTANCES]; |
3635 | |
3636 | bool voxel_gi_instances_changed = false; |
3637 | |
3638 | Transform3D to_camera; |
3639 | to_camera.origin = p_transform.origin; //only translation, make local |
3640 | |
3641 | for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { |
3642 | RID texture; |
3643 | if (i < (int)p_voxel_gi_instances.size()) { |
3644 | VoxelGIInstance *gipi = voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]); |
3645 | |
3646 | if (gipi) { |
3647 | texture = gipi->texture; |
3648 | VoxelGIData &gipd = voxel_gi_data[i]; |
3649 | |
3650 | RID base_probe = gipi->probe; |
3651 | |
3652 | Transform3D to_cell = voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera; |
3653 | |
3654 | gipd.xform[0] = to_cell.basis.rows[0][0]; |
3655 | gipd.xform[1] = to_cell.basis.rows[1][0]; |
3656 | gipd.xform[2] = to_cell.basis.rows[2][0]; |
3657 | gipd.xform[3] = 0; |
3658 | gipd.xform[4] = to_cell.basis.rows[0][1]; |
3659 | gipd.xform[5] = to_cell.basis.rows[1][1]; |
3660 | gipd.xform[6] = to_cell.basis.rows[2][1]; |
3661 | gipd.xform[7] = 0; |
3662 | gipd.xform[8] = to_cell.basis.rows[0][2]; |
3663 | gipd.xform[9] = to_cell.basis.rows[1][2]; |
3664 | gipd.xform[10] = to_cell.basis.rows[2][2]; |
3665 | gipd.xform[11] = 0; |
3666 | gipd.xform[12] = to_cell.origin.x; |
3667 | gipd.xform[13] = to_cell.origin.y; |
3668 | gipd.xform[14] = to_cell.origin.z; |
3669 | gipd.xform[15] = 1; |
3670 | |
3671 | Vector3 bounds = voxel_gi_get_octree_size(base_probe); |
3672 | |
3673 | gipd.bounds[0] = bounds.x; |
3674 | gipd.bounds[1] = bounds.y; |
3675 | gipd.bounds[2] = bounds.z; |
3676 | |
3677 | gipd.dynamic_range = voxel_gi_get_dynamic_range(base_probe) * voxel_gi_get_energy(base_probe); |
3678 | gipd.bias = voxel_gi_get_bias(base_probe); |
3679 | gipd.normal_bias = voxel_gi_get_normal_bias(base_probe); |
3680 | gipd.blend_ambient = !voxel_gi_is_interior(base_probe); |
3681 | gipd.mipmaps = gipi->mipmaps.size(); |
3682 | gipd.exposure_normalization = 1.0; |
3683 | if (p_render_data->camera_attributes.is_valid()) { |
3684 | float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); |
3685 | gipd.exposure_normalization = exposure_normalization / voxel_gi_get_baked_exposure_normalization(base_probe); |
3686 | } |
3687 | } |
3688 | |
3689 | r_voxel_gi_instances_used++; |
3690 | } |
3691 | |
3692 | if (texture == RID()) { |
3693 | texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); |
3694 | } |
3695 | |
3696 | if (texture != rbgi->voxel_gi_textures[i]) { |
3697 | voxel_gi_instances_changed = true; |
3698 | rbgi->voxel_gi_textures[i] = texture; |
3699 | } |
3700 | } |
3701 | |
3702 | if (voxel_gi_instances_changed) { |
3703 | for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { |
3704 | if (RD::get_singleton()->uniform_set_is_valid(rbgi->uniform_set[v])) { |
3705 | RD::get_singleton()->free(rbgi->uniform_set[v]); |
3706 | } |
3707 | rbgi->uniform_set[v] = RID(); |
3708 | } |
3709 | } |
3710 | |
3711 | if (p_voxel_gi_instances.size() > 0) { |
3712 | RD::get_singleton()->draw_command_begin_label("VoxelGIs Setup" ); |
3713 | |
3714 | RD::get_singleton()->buffer_update(voxel_gi_buffer, 0, sizeof(VoxelGIData) * MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()), voxel_gi_data, RD::BARRIER_MASK_COMPUTE); |
3715 | |
3716 | RD::get_singleton()->draw_command_end_label(); |
3717 | } |
3718 | } |
3719 | |
3720 | RID GI::RenderBuffersGI::get_voxel_gi_buffer() { |
3721 | if (voxel_gi_buffer.is_null()) { |
3722 | voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::VoxelGIData) * GI::MAX_VOXEL_GI_INSTANCES); |
3723 | } |
3724 | return voxel_gi_buffer; |
3725 | } |
3726 | |
3727 | void GI::RenderBuffersGI::free_data() { |
3728 | for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { |
3729 | if (RD::get_singleton()->uniform_set_is_valid(uniform_set[v])) { |
3730 | RD::get_singleton()->free(uniform_set[v]); |
3731 | } |
3732 | uniform_set[v] = RID(); |
3733 | } |
3734 | |
3735 | if (scene_data_ubo.is_valid()) { |
3736 | RD::get_singleton()->free(scene_data_ubo); |
3737 | scene_data_ubo = RID(); |
3738 | } |
3739 | |
3740 | if (voxel_gi_buffer.is_valid()) { |
3741 | RD::get_singleton()->free(voxel_gi_buffer); |
3742 | voxel_gi_buffer = RID(); |
3743 | } |
3744 | } |
3745 | |
3746 | void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances) { |
3747 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
3748 | RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); |
3749 | |
3750 | ERR_FAIL_COND_MSG(p_view_count > 2, "Maximum of 2 views supported for Processing GI." ); |
3751 | |
3752 | RD::get_singleton()->draw_command_begin_label("GI Render" ); |
3753 | |
3754 | ERR_FAIL_COND(p_render_buffers.is_null()); |
3755 | |
3756 | Ref<RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI); |
3757 | ERR_FAIL_COND(rbgi.is_null()); |
3758 | |
3759 | Size2i internal_size = p_render_buffers->get_internal_size(); |
3760 | |
3761 | if (rbgi->using_half_size_gi != half_resolution) { |
3762 | p_render_buffers->clear_context(RB_SCOPE_GI); |
3763 | } |
3764 | |
3765 | if (!p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) { |
3766 | Size2i size = internal_size; |
3767 | uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; |
3768 | |
3769 | if (half_resolution) { |
3770 | size.x >>= 1; |
3771 | size.y >>= 1; |
3772 | } |
3773 | |
3774 | p_render_buffers->create_texture(RB_SCOPE_GI, RB_TEX_AMBIENT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1, size); |
3775 | p_render_buffers->create_texture(RB_SCOPE_GI, RB_TEX_REFLECTION, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1, size); |
3776 | |
3777 | rbgi->using_half_size_gi = half_resolution; |
3778 | } |
3779 | |
3780 | // Setup our scene data |
3781 | { |
3782 | SceneData scene_data; |
3783 | |
3784 | if (rbgi->scene_data_ubo.is_null()) { |
3785 | rbgi->scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SceneData)); |
3786 | } |
3787 | |
3788 | for (uint32_t v = 0; v < p_view_count; v++) { |
3789 | RendererRD::MaterialStorage::store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]); |
3790 | scene_data.eye_offset[v][0] = p_eye_offsets[v].x; |
3791 | scene_data.eye_offset[v][1] = p_eye_offsets[v].y; |
3792 | scene_data.eye_offset[v][2] = p_eye_offsets[v].z; |
3793 | scene_data.eye_offset[v][3] = 0.0; |
3794 | } |
3795 | |
3796 | // Note that we will be ignoring the origin of this transform. |
3797 | RendererRD::MaterialStorage::store_transform(p_cam_transform, scene_data.cam_transform); |
3798 | |
3799 | scene_data.screen_size[0] = internal_size.x; |
3800 | scene_data.screen_size[1] = internal_size.y; |
3801 | |
3802 | RD::get_singleton()->buffer_update(rbgi->scene_data_ubo, 0, sizeof(SceneData), &scene_data, RD::BARRIER_MASK_COMPUTE); |
3803 | } |
3804 | |
3805 | // Now compute the contents of our buffers. |
3806 | RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); |
3807 | |
3808 | // Render each eye separately. |
3809 | // We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference.. |
3810 | |
3811 | // setup our push constant |
3812 | |
3813 | PushConstant push_constant; |
3814 | |
3815 | push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()); |
3816 | push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH; |
3817 | |
3818 | // these should be the same for all views |
3819 | push_constant.orthogonal = p_projections[0].is_orthogonal(); |
3820 | push_constant.z_near = p_projections[0].get_z_near(); |
3821 | push_constant.z_far = p_projections[0].get_z_far(); |
3822 | |
3823 | // these are only used if we have 1 view, else we use the projections in our scene data |
3824 | push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].columns[0][0]); |
3825 | push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].columns[1][1]); |
3826 | push_constant.proj_info[2] = (1.0f - p_projections[0].columns[0][2]) / p_projections[0].columns[0][0]; |
3827 | push_constant.proj_info[3] = (1.0f + p_projections[0].columns[1][2]) / p_projections[0].columns[1][1]; |
3828 | |
3829 | bool use_sdfgi = p_render_buffers->has_custom_data(RB_SCOPE_SDFGI); |
3830 | bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0; |
3831 | |
3832 | Ref<SDFGI> sdfgi; |
3833 | if (use_sdfgi) { |
3834 | sdfgi = p_render_buffers->get_custom_data(RB_SCOPE_SDFGI); |
3835 | } |
3836 | |
3837 | uint32_t pipeline_specialization = 0; |
3838 | if (rbgi->using_half_size_gi) { |
3839 | pipeline_specialization |= SHADER_SPECIALIZATION_HALF_RES; |
3840 | } |
3841 | if (p_view_count > 1) { |
3842 | pipeline_specialization |= SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX; |
3843 | } |
3844 | bool has_vrs_texture = p_render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE); |
3845 | if (has_vrs_texture) { |
3846 | pipeline_specialization |= SHADER_SPECIALIZATION_USE_VRS; |
3847 | } |
3848 | |
3849 | Mode mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI); |
3850 | |
3851 | for (uint32_t v = 0; v < p_view_count; v++) { |
3852 | push_constant.view_index = v; |
3853 | |
3854 | // setup our uniform set |
3855 | if (rbgi->uniform_set[v].is_null() || !RD::get_singleton()->uniform_set_is_valid(rbgi->uniform_set[v])) { |
3856 | Vector<RD::Uniform> uniforms; |
3857 | { |
3858 | RD::Uniform u; |
3859 | u.binding = 1; |
3860 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3861 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
3862 | if (use_sdfgi && j < sdfgi->cascades.size()) { |
3863 | u.append_id(sdfgi->cascades[j].sdf_tex); |
3864 | } else { |
3865 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
3866 | } |
3867 | } |
3868 | uniforms.push_back(u); |
3869 | } |
3870 | { |
3871 | RD::Uniform u; |
3872 | u.binding = 2; |
3873 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3874 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
3875 | if (use_sdfgi && j < sdfgi->cascades.size()) { |
3876 | u.append_id(sdfgi->cascades[j].light_tex); |
3877 | } else { |
3878 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
3879 | } |
3880 | } |
3881 | uniforms.push_back(u); |
3882 | } |
3883 | { |
3884 | RD::Uniform u; |
3885 | u.binding = 3; |
3886 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3887 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
3888 | if (use_sdfgi && j < sdfgi->cascades.size()) { |
3889 | u.append_id(sdfgi->cascades[j].light_aniso_0_tex); |
3890 | } else { |
3891 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
3892 | } |
3893 | } |
3894 | uniforms.push_back(u); |
3895 | } |
3896 | { |
3897 | RD::Uniform u; |
3898 | u.binding = 4; |
3899 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3900 | for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { |
3901 | if (use_sdfgi && j < sdfgi->cascades.size()) { |
3902 | u.append_id(sdfgi->cascades[j].light_aniso_1_tex); |
3903 | } else { |
3904 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
3905 | } |
3906 | } |
3907 | uniforms.push_back(u); |
3908 | } |
3909 | { |
3910 | RD::Uniform u; |
3911 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3912 | u.binding = 5; |
3913 | if (use_sdfgi) { |
3914 | u.append_id(sdfgi->occlusion_texture); |
3915 | } else { |
3916 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE)); |
3917 | } |
3918 | uniforms.push_back(u); |
3919 | } |
3920 | { |
3921 | RD::Uniform u; |
3922 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
3923 | u.binding = 6; |
3924 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
3925 | uniforms.push_back(u); |
3926 | } |
3927 | { |
3928 | RD::Uniform u; |
3929 | u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; |
3930 | u.binding = 7; |
3931 | u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); |
3932 | uniforms.push_back(u); |
3933 | } |
3934 | { |
3935 | RD::Uniform u; |
3936 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
3937 | u.binding = 9; |
3938 | u.append_id(p_render_buffers->get_texture_slice(RB_SCOPE_GI, RB_TEX_AMBIENT, v, 0)); |
3939 | uniforms.push_back(u); |
3940 | } |
3941 | |
3942 | { |
3943 | RD::Uniform u; |
3944 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
3945 | u.binding = 10; |
3946 | u.append_id(p_render_buffers->get_texture_slice(RB_SCOPE_GI, RB_TEX_REFLECTION, v, 0)); |
3947 | uniforms.push_back(u); |
3948 | } |
3949 | |
3950 | { |
3951 | RD::Uniform u; |
3952 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3953 | u.binding = 11; |
3954 | if (use_sdfgi) { |
3955 | u.append_id(sdfgi->lightprobe_texture); |
3956 | } else { |
3957 | u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); |
3958 | } |
3959 | uniforms.push_back(u); |
3960 | } |
3961 | { |
3962 | RD::Uniform u; |
3963 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3964 | u.binding = 12; |
3965 | u.append_id(p_render_buffers->get_depth_texture(v)); |
3966 | uniforms.push_back(u); |
3967 | } |
3968 | { |
3969 | RD::Uniform u; |
3970 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3971 | u.binding = 13; |
3972 | u.append_id(p_normal_roughness_slices[v]); |
3973 | uniforms.push_back(u); |
3974 | } |
3975 | { |
3976 | RD::Uniform u; |
3977 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
3978 | u.binding = 14; |
3979 | RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); |
3980 | u.append_id(buffer); |
3981 | uniforms.push_back(u); |
3982 | } |
3983 | { |
3984 | RD::Uniform u; |
3985 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
3986 | u.binding = 15; |
3987 | u.append_id(sdfgi_ubo); |
3988 | uniforms.push_back(u); |
3989 | } |
3990 | { |
3991 | RD::Uniform u; |
3992 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
3993 | u.binding = 16; |
3994 | u.append_id(rbgi->get_voxel_gi_buffer()); |
3995 | uniforms.push_back(u); |
3996 | } |
3997 | { |
3998 | RD::Uniform u; |
3999 | u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; |
4000 | u.binding = 17; |
4001 | for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { |
4002 | u.append_id(rbgi->voxel_gi_textures[i]); |
4003 | } |
4004 | uniforms.push_back(u); |
4005 | } |
4006 | { |
4007 | RD::Uniform u; |
4008 | u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; |
4009 | u.binding = 18; |
4010 | u.append_id(rbgi->scene_data_ubo); |
4011 | uniforms.push_back(u); |
4012 | } |
4013 | if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) { |
4014 | RD::Uniform u; |
4015 | u.uniform_type = RD::UNIFORM_TYPE_IMAGE; |
4016 | u.binding = 19; |
4017 | RID buffer = has_vrs_texture ? p_render_buffers->get_texture_slice(RB_SCOPE_VRS, RB_TEXTURE, v, 0) : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_VRS); |
4018 | u.append_id(buffer); |
4019 | uniforms.push_back(u); |
4020 | } |
4021 | |
4022 | rbgi->uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0); |
4023 | } |
4024 | |
4025 | RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[pipeline_specialization][mode]); |
4026 | RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rbgi->uniform_set[v], 0); |
4027 | RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); |
4028 | |
4029 | if (rbgi->using_half_size_gi) { |
4030 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, internal_size.x >> 1, internal_size.y >> 1, 1); |
4031 | } else { |
4032 | RD::get_singleton()->compute_list_dispatch_threads(compute_list, internal_size.x, internal_size.y, 1); |
4033 | } |
4034 | } |
4035 | |
4036 | //do barrier later to allow oeverlap |
4037 | //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time |
4038 | RD::get_singleton()->draw_command_end_label(); |
4039 | } |
4040 | |
4041 | RID GI::voxel_gi_instance_create(RID p_base) { |
4042 | VoxelGIInstance voxel_gi; |
4043 | voxel_gi.gi = this; |
4044 | voxel_gi.probe = p_base; |
4045 | RID rid = voxel_gi_instance_owner.make_rid(voxel_gi); |
4046 | return rid; |
4047 | } |
4048 | |
4049 | void GI::voxel_gi_instance_free(RID p_rid) { |
4050 | GI::VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_rid); |
4051 | voxel_gi->free_resources(); |
4052 | voxel_gi_instance_owner.free(p_rid); |
4053 | } |
4054 | |
4055 | void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { |
4056 | VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe); |
4057 | ERR_FAIL_COND(!voxel_gi); |
4058 | |
4059 | voxel_gi->transform = p_xform; |
4060 | } |
4061 | |
4062 | bool GI::voxel_gi_needs_update(RID p_probe) const { |
4063 | VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe); |
4064 | ERR_FAIL_COND_V(!voxel_gi, false); |
4065 | |
4066 | return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe); |
4067 | } |
4068 | |
4069 | void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { |
4070 | VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe); |
4071 | ERR_FAIL_COND(!voxel_gi); |
4072 | |
4073 | voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects); |
4074 | } |
4075 | |
4076 | void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { |
4077 | VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi); |
4078 | ERR_FAIL_COND(!voxel_gi); |
4079 | |
4080 | voxel_gi->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha); |
4081 | } |
4082 | |