1 | /**************************************************************************/ |
2 | /* gi.h */ |
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 | #ifndef GI_RD_H |
32 | #define GI_RD_H |
33 | |
34 | #include "core/templates/local_vector.h" |
35 | #include "core/templates/rid_owner.h" |
36 | #include "servers/rendering/environment/renderer_gi.h" |
37 | #include "servers/rendering/renderer_compositor.h" |
38 | #include "servers/rendering/renderer_rd/environment/sky.h" |
39 | #include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h" |
40 | #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h" |
41 | #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h" |
42 | #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl.gen.h" |
43 | #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl.gen.h" |
44 | #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl.gen.h" |
45 | #include "servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl.gen.h" |
46 | #include "servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl.gen.h" |
47 | #include "servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h" |
48 | #include "servers/rendering/renderer_scene_render.h" |
49 | #include "servers/rendering/rendering_device.h" |
50 | #include "servers/rendering/storage/utilities.h" |
51 | |
52 | #define RB_SCOPE_GI SNAME("rbgi") |
53 | #define RB_SCOPE_SDFGI SNAME("sdfgi") |
54 | |
55 | #define RB_TEX_AMBIENT SNAME("ambient") |
56 | #define RB_TEX_REFLECTION SNAME("reflection") |
57 | |
58 | // Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound |
59 | struct RenderDataRD; |
60 | class RendererSceneRenderRD; |
61 | |
62 | namespace RendererRD { |
63 | |
64 | class GI : public RendererGI { |
65 | public: |
66 | /* VOXEL GI STORAGE */ |
67 | |
68 | struct VoxelGI { |
69 | RID octree_buffer; |
70 | RID data_buffer; |
71 | RID sdf_texture; |
72 | |
73 | uint32_t octree_buffer_size = 0; |
74 | uint32_t data_buffer_size = 0; |
75 | |
76 | Vector<int> level_counts; |
77 | |
78 | int cell_count = 0; |
79 | |
80 | Transform3D to_cell_xform; |
81 | AABB bounds; |
82 | Vector3i octree_size; |
83 | |
84 | float dynamic_range = 2.0; |
85 | float energy = 1.0; |
86 | float baked_exposure = 1.0; |
87 | float bias = 1.4; |
88 | float normal_bias = 0.0; |
89 | float propagation = 0.5; |
90 | bool interior = false; |
91 | bool use_two_bounces = true; |
92 | |
93 | uint32_t version = 1; |
94 | uint32_t data_version = 1; |
95 | |
96 | Dependency dependency; |
97 | }; |
98 | |
99 | /* VOXEL_GI INSTANCE */ |
100 | |
101 | //@TODO VoxelGIInstance is still directly used in the render code, we'll address this when we refactor the render code itself. |
102 | |
103 | struct VoxelGIInstance { |
104 | // access to our containers |
105 | GI *gi = nullptr; |
106 | |
107 | RID probe; |
108 | RID texture; |
109 | RID write_buffer; |
110 | |
111 | struct Mipmap { |
112 | RID texture; |
113 | RID uniform_set; |
114 | RID second_bounce_uniform_set; |
115 | RID write_uniform_set; |
116 | uint32_t level; |
117 | uint32_t cell_offset; |
118 | uint32_t cell_count; |
119 | }; |
120 | Vector<Mipmap> mipmaps; |
121 | |
122 | struct DynamicMap { |
123 | RID texture; //color normally, or emission on first pass |
124 | RID fb_depth; //actual depth buffer for the first pass, float depth for later passes |
125 | RID depth; //actual depth buffer for the first pass, float depth for later passes |
126 | RID normal; //normal buffer for the first pass |
127 | RID albedo; //emission buffer for the first pass |
128 | RID orm; //orm buffer for the first pass |
129 | RID fb; //used for rendering, only valid on first map |
130 | RID uniform_set; |
131 | uint32_t size; |
132 | int mipmap; // mipmap to write to, -1 if no mipmap assigned |
133 | }; |
134 | |
135 | Vector<DynamicMap> dynamic_maps; |
136 | |
137 | int slot = -1; |
138 | uint32_t last_probe_version = 0; |
139 | uint32_t last_probe_data_version = 0; |
140 | |
141 | //uint64_t last_pass = 0; |
142 | uint32_t render_index = 0; |
143 | |
144 | bool has_dynamic_object_data = false; |
145 | |
146 | Transform3D transform; |
147 | |
148 | void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects); |
149 | void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); |
150 | void free_resources(); |
151 | }; |
152 | |
153 | private: |
154 | static GI *singleton; |
155 | |
156 | /* VOXEL GI STORAGE */ |
157 | |
158 | mutable RID_Owner<VoxelGI, true> voxel_gi_owner; |
159 | |
160 | /* VOXEL_GI INSTANCE */ |
161 | |
162 | mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner; |
163 | |
164 | struct VoxelGILight { |
165 | uint32_t type; |
166 | float energy; |
167 | float radius; |
168 | float attenuation; |
169 | |
170 | float color[3]; |
171 | float cos_spot_angle; |
172 | |
173 | float position[3]; |
174 | float inv_spot_attenuation; |
175 | |
176 | float direction[3]; |
177 | uint32_t has_shadow; |
178 | }; |
179 | |
180 | struct VoxelGIPushConstant { |
181 | int32_t limits[3]; |
182 | uint32_t stack_size; |
183 | |
184 | float emission_scale; |
185 | float propagation; |
186 | float dynamic_range; |
187 | uint32_t light_count; |
188 | |
189 | uint32_t cell_offset; |
190 | uint32_t cell_count; |
191 | float aniso_strength; |
192 | uint32_t pad; |
193 | }; |
194 | |
195 | struct VoxelGIDynamicPushConstant { |
196 | int32_t limits[3]; |
197 | uint32_t light_count; |
198 | int32_t x_dir[3]; |
199 | float z_base; |
200 | int32_t y_dir[3]; |
201 | float z_sign; |
202 | int32_t z_dir[3]; |
203 | float pos_multiplier; |
204 | uint32_t rect_pos[2]; |
205 | uint32_t rect_size[2]; |
206 | uint32_t prev_rect_ofs[2]; |
207 | uint32_t prev_rect_size[2]; |
208 | uint32_t flip_x; |
209 | uint32_t flip_y; |
210 | float dynamic_range; |
211 | uint32_t on_mipmap; |
212 | float propagation; |
213 | float pad[3]; |
214 | }; |
215 | |
216 | VoxelGILight *voxel_gi_lights = nullptr; |
217 | uint32_t voxel_gi_max_lights = 32; |
218 | RID voxel_gi_lights_uniform; |
219 | |
220 | enum { |
221 | VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT, |
222 | VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE, |
223 | VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP, |
224 | VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE, |
225 | VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING, |
226 | VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE, |
227 | VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT, |
228 | VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT, |
229 | VOXEL_GI_SHADER_VERSION_MAX |
230 | }; |
231 | |
232 | VoxelGiShaderRD voxel_gi_shader; |
233 | RID voxel_gi_lighting_shader_version; |
234 | RID voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_MAX]; |
235 | RID voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_MAX]; |
236 | |
237 | enum { |
238 | VOXEL_GI_DEBUG_COLOR, |
239 | VOXEL_GI_DEBUG_LIGHT, |
240 | VOXEL_GI_DEBUG_EMISSION, |
241 | VOXEL_GI_DEBUG_LIGHT_FULL, |
242 | VOXEL_GI_DEBUG_MAX |
243 | }; |
244 | |
245 | struct VoxelGIDebugPushConstant { |
246 | float projection[16]; |
247 | uint32_t cell_offset; |
248 | float dynamic_range; |
249 | float alpha; |
250 | uint32_t level; |
251 | int32_t bounds[3]; |
252 | uint32_t pad; |
253 | }; |
254 | |
255 | VoxelGiDebugShaderRD voxel_gi_debug_shader; |
256 | RID voxel_gi_debug_shader_version; |
257 | RID voxel_gi_debug_shader_version_shaders[VOXEL_GI_DEBUG_MAX]; |
258 | PipelineCacheRD voxel_gi_debug_shader_version_pipelines[VOXEL_GI_DEBUG_MAX]; |
259 | RID voxel_gi_debug_uniform_set; |
260 | |
261 | /* SDFGI */ |
262 | |
263 | struct SDFGIShader { |
264 | enum SDFGIPreprocessShaderVersion { |
265 | PRE_PROCESS_SCROLL, |
266 | PRE_PROCESS_SCROLL_OCCLUSION, |
267 | PRE_PROCESS_JUMP_FLOOD_INITIALIZE, |
268 | PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF, |
269 | PRE_PROCESS_JUMP_FLOOD, |
270 | PRE_PROCESS_JUMP_FLOOD_OPTIMIZED, |
271 | PRE_PROCESS_JUMP_FLOOD_UPSCALE, |
272 | PRE_PROCESS_OCCLUSION, |
273 | PRE_PROCESS_STORE, |
274 | PRE_PROCESS_MAX |
275 | }; |
276 | |
277 | struct PreprocessPushConstant { |
278 | int32_t scroll[3]; |
279 | int32_t grid_size; |
280 | |
281 | int32_t probe_offset[3]; |
282 | int32_t step_size; |
283 | |
284 | int32_t half_size; |
285 | uint32_t occlusion_index; |
286 | int32_t cascade; |
287 | uint32_t pad; |
288 | }; |
289 | |
290 | SdfgiPreprocessShaderRD preprocess; |
291 | RID preprocess_shader; |
292 | RID preprocess_pipeline[PRE_PROCESS_MAX]; |
293 | |
294 | struct DebugPushConstant { |
295 | float grid_size[3]; |
296 | uint32_t max_cascades; |
297 | |
298 | int32_t screen_size[2]; |
299 | float y_mult; |
300 | |
301 | float z_near; |
302 | |
303 | float inv_projection[3][4]; |
304 | float cam_basis[3][3]; |
305 | float cam_origin[3]; |
306 | }; |
307 | |
308 | SdfgiDebugShaderRD debug; |
309 | RID debug_shader; |
310 | RID debug_shader_version; |
311 | RID debug_pipeline; |
312 | |
313 | enum ProbeDebugMode { |
314 | PROBE_DEBUG_PROBES, |
315 | PROBE_DEBUG_PROBES_MULTIVIEW, |
316 | PROBE_DEBUG_VISIBILITY, |
317 | PROBE_DEBUG_VISIBILITY_MULTIVIEW, |
318 | PROBE_DEBUG_MAX |
319 | }; |
320 | |
321 | struct DebugProbesSceneData { |
322 | float projection[2][16]; |
323 | }; |
324 | |
325 | struct DebugProbesPushConstant { |
326 | uint32_t band_power; |
327 | uint32_t sections_in_band; |
328 | uint32_t band_mask; |
329 | float section_arc; |
330 | |
331 | float grid_size[3]; |
332 | uint32_t cascade; |
333 | |
334 | uint32_t pad; |
335 | float y_mult; |
336 | int32_t probe_debug_index; |
337 | int32_t probe_axis_size; |
338 | }; |
339 | |
340 | SdfgiDebugProbesShaderRD debug_probes; |
341 | RID debug_probes_shader; |
342 | RID debug_probes_shader_version; |
343 | |
344 | PipelineCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX]; |
345 | |
346 | struct Light { |
347 | float color[3]; |
348 | float energy; |
349 | |
350 | float direction[3]; |
351 | uint32_t has_shadow; |
352 | |
353 | float position[3]; |
354 | float attenuation; |
355 | |
356 | uint32_t type; |
357 | float cos_spot_angle; |
358 | float inv_spot_attenuation; |
359 | float radius; |
360 | }; |
361 | |
362 | struct DirectLightPushConstant { |
363 | float grid_size[3]; |
364 | uint32_t max_cascades; |
365 | |
366 | uint32_t cascade; |
367 | uint32_t light_count; |
368 | uint32_t process_offset; |
369 | uint32_t process_increment; |
370 | |
371 | int32_t probe_axis_size; |
372 | float bounce_feedback; |
373 | float y_mult; |
374 | uint32_t use_occlusion; |
375 | }; |
376 | |
377 | enum { |
378 | DIRECT_LIGHT_MODE_STATIC, |
379 | DIRECT_LIGHT_MODE_DYNAMIC, |
380 | DIRECT_LIGHT_MODE_MAX |
381 | }; |
382 | SdfgiDirectLightShaderRD direct_light; |
383 | RID direct_light_shader; |
384 | RID direct_light_pipeline[DIRECT_LIGHT_MODE_MAX]; |
385 | |
386 | enum { |
387 | INTEGRATE_MODE_PROCESS, |
388 | INTEGRATE_MODE_STORE, |
389 | INTEGRATE_MODE_SCROLL, |
390 | INTEGRATE_MODE_SCROLL_STORE, |
391 | INTEGRATE_MODE_MAX |
392 | }; |
393 | struct IntegratePushConstant { |
394 | enum { |
395 | SKY_MODE_DISABLED, |
396 | SKY_MODE_COLOR, |
397 | SKY_MODE_SKY, |
398 | }; |
399 | |
400 | float grid_size[3]; |
401 | uint32_t max_cascades; |
402 | |
403 | uint32_t probe_axis_size; |
404 | uint32_t cascade; |
405 | uint32_t history_index; |
406 | uint32_t history_size; |
407 | |
408 | uint32_t ray_count; |
409 | float ray_bias; |
410 | int32_t image_size[2]; |
411 | |
412 | int32_t world_offset[3]; |
413 | uint32_t sky_mode; |
414 | |
415 | int32_t scroll[3]; |
416 | float sky_energy; |
417 | |
418 | float sky_color[3]; |
419 | float y_mult; |
420 | |
421 | uint32_t store_ambient_texture; |
422 | uint32_t pad[3]; |
423 | }; |
424 | |
425 | SdfgiIntegrateShaderRD integrate; |
426 | RID integrate_shader; |
427 | RID integrate_pipeline[INTEGRATE_MODE_MAX]; |
428 | |
429 | RID integrate_default_sky_uniform_set; |
430 | |
431 | } sdfgi_shader; |
432 | |
433 | public: |
434 | static GI *get_singleton() { return singleton; } |
435 | |
436 | /* GI */ |
437 | |
438 | enum { |
439 | MAX_VOXEL_GI_INSTANCES = 8 |
440 | }; |
441 | |
442 | // Struct for use in render buffer |
443 | class RenderBuffersGI : public RenderBufferCustomDataRD { |
444 | GDCLASS(RenderBuffersGI, RenderBufferCustomDataRD) |
445 | |
446 | private: |
447 | RID voxel_gi_buffer; |
448 | |
449 | public: |
450 | RID voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; |
451 | |
452 | RID full_buffer; |
453 | RID full_dispatch; |
454 | RID full_mask; |
455 | |
456 | /* GI buffers */ |
457 | bool using_half_size_gi = false; |
458 | |
459 | RID uniform_set[RendererSceneRender::MAX_RENDER_VIEWS]; |
460 | RID scene_data_ubo; |
461 | |
462 | RID get_voxel_gi_buffer(); |
463 | |
464 | virtual void configure(RenderSceneBuffersRD *p_render_buffers) override{}; |
465 | virtual void free_data() override; |
466 | }; |
467 | |
468 | /* VOXEL GI API */ |
469 | |
470 | bool owns_voxel_gi(RID p_rid) { return voxel_gi_owner.owns(p_rid); }; |
471 | |
472 | virtual RID voxel_gi_allocate() override; |
473 | virtual void voxel_gi_free(RID p_voxel_gi) override; |
474 | virtual void voxel_gi_initialize(RID p_voxel_gi) override; |
475 | |
476 | virtual void 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) override; |
477 | |
478 | virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const override; |
479 | virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override; |
480 | virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override; |
481 | virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override; |
482 | virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override; |
483 | |
484 | virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override; |
485 | virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override; |
486 | |
487 | virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override; |
488 | virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override; |
489 | |
490 | virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override; |
491 | virtual float voxel_gi_get_propagation(RID p_voxel_gi) const override; |
492 | |
493 | virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) override; |
494 | virtual float voxel_gi_get_energy(RID p_voxel_gi) const override; |
495 | |
496 | virtual void voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) override; |
497 | virtual float voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const override; |
498 | |
499 | virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) override; |
500 | virtual float voxel_gi_get_bias(RID p_voxel_gi) const override; |
501 | |
502 | virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override; |
503 | virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const override; |
504 | |
505 | virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override; |
506 | virtual bool voxel_gi_is_interior(RID p_voxel_gi) const override; |
507 | |
508 | virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override; |
509 | virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override; |
510 | |
511 | virtual uint32_t voxel_gi_get_version(RID p_probe) const override; |
512 | uint32_t voxel_gi_get_data_version(RID p_probe); |
513 | |
514 | RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const; |
515 | RID voxel_gi_get_data_buffer(RID p_voxel_gi) const; |
516 | |
517 | RID voxel_gi_get_sdf_texture(RID p_voxel_gi); |
518 | |
519 | Dependency *voxel_gi_get_dependency(RID p_voxel_gi) const; |
520 | |
521 | /* VOXEL_GI INSTANCE */ |
522 | |
523 | _FORCE_INLINE_ RID voxel_gi_instance_get_texture(RID p_probe) { |
524 | VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe); |
525 | ERR_FAIL_COND_V(!voxel_gi, RID()); |
526 | return voxel_gi->texture; |
527 | }; |
528 | |
529 | _FORCE_INLINE_ void voxel_gi_instance_set_render_index(RID p_probe, uint32_t p_index) { |
530 | VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe); |
531 | ERR_FAIL_NULL(voxel_gi); |
532 | |
533 | voxel_gi->render_index = p_index; |
534 | }; |
535 | |
536 | bool voxel_gi_instance_owns(RID p_rid) const { |
537 | return voxel_gi_instance_owner.owns(p_rid); |
538 | } |
539 | |
540 | void voxel_gi_instance_free(RID p_rid); |
541 | |
542 | RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_LOW; |
543 | |
544 | /* SDFGI */ |
545 | |
546 | class SDFGI : public RenderBufferCustomDataRD { |
547 | GDCLASS(SDFGI, RenderBufferCustomDataRD) |
548 | |
549 | public: |
550 | enum { |
551 | MAX_CASCADES = 8, |
552 | CASCADE_SIZE = 128, |
553 | PROBE_DIVISOR = 16, |
554 | ANISOTROPY_SIZE = 6, |
555 | MAX_DYNAMIC_LIGHTS = 128, |
556 | MAX_STATIC_LIGHTS = 1024, |
557 | LIGHTPROBE_OCT_SIZE = 6, |
558 | SH_SIZE = 16 |
559 | }; |
560 | |
561 | struct Cascade { |
562 | struct UBO { |
563 | float offset[3]; |
564 | float to_cell; |
565 | int32_t probe_offset[3]; |
566 | uint32_t pad; |
567 | float pad2[4]; |
568 | }; |
569 | |
570 | //cascade blocks are full-size for volume (128^3), half size for albedo/emission |
571 | RID sdf_tex; |
572 | RID light_tex; |
573 | RID light_aniso_0_tex; |
574 | RID light_aniso_1_tex; |
575 | |
576 | RID light_data; |
577 | RID light_aniso_0_data; |
578 | RID light_aniso_1_data; |
579 | |
580 | struct SolidCell { // this struct is unused, but remains as reference for size |
581 | uint32_t position; |
582 | uint32_t albedo; |
583 | uint32_t static_light; |
584 | uint32_t static_light_aniso; |
585 | }; |
586 | |
587 | RID solid_cell_dispatch_buffer; //buffer for indirect compute dispatch |
588 | RID solid_cell_buffer; |
589 | |
590 | RID lightprobe_history_tex; |
591 | RID lightprobe_average_tex; |
592 | |
593 | float cell_size; |
594 | Vector3i position; |
595 | |
596 | static const Vector3i DIRTY_ALL; |
597 | Vector3i dirty_regions; //(0,0,0 is not dirty, negative is refresh from the end, DIRTY_ALL is refresh all. |
598 | |
599 | RID sdf_store_uniform_set; |
600 | RID sdf_direct_light_static_uniform_set; |
601 | RID sdf_direct_light_dynamic_uniform_set; |
602 | RID scroll_uniform_set; |
603 | RID scroll_occlusion_uniform_set; |
604 | RID integrate_uniform_set; |
605 | RID lights_buffer; |
606 | |
607 | float baked_exposure_normalization = 1.0; |
608 | |
609 | bool all_dynamic_lights_dirty = true; |
610 | }; |
611 | |
612 | // access to our containers |
613 | GI *gi = nullptr; |
614 | |
615 | // used for rendering (voxelization) |
616 | RID render_albedo; |
617 | RID render_emission; |
618 | RID render_emission_aniso; |
619 | RID render_occlusion[8]; |
620 | RID render_geom_facing; |
621 | |
622 | RID render_sdf[2]; |
623 | RID render_sdf_half[2]; |
624 | |
625 | // used for ping pong processing in cascades |
626 | RID sdf_initialize_uniform_set; |
627 | RID sdf_initialize_half_uniform_set; |
628 | RID jump_flood_uniform_set[2]; |
629 | RID jump_flood_half_uniform_set[2]; |
630 | RID sdf_upscale_uniform_set; |
631 | int upscale_jfa_uniform_set_index; |
632 | RID occlusion_uniform_set; |
633 | |
634 | uint32_t cascade_size = 128; |
635 | |
636 | LocalVector<Cascade> cascades; |
637 | |
638 | RID lightprobe_texture; |
639 | RID lightprobe_data; |
640 | RID occlusion_texture; |
641 | RID occlusion_data; |
642 | RID ambient_texture; //integrates with volumetric fog |
643 | |
644 | RID lightprobe_history_scroll; //used for scrolling lightprobes |
645 | RID lightprobe_average_scroll; //used for scrolling lightprobes |
646 | |
647 | uint32_t history_size = 0; |
648 | float solid_cell_ratio = 0; |
649 | uint32_t solid_cell_count = 0; |
650 | |
651 | int num_cascades = 6; |
652 | float min_cell_size = 0; |
653 | uint32_t probe_axis_count = 0; //amount of probes per axis, this is an odd number because it encloses endpoints |
654 | |
655 | RID debug_uniform_set[RendererSceneRender::MAX_RENDER_VIEWS]; |
656 | RID debug_probes_scene_data_ubo; |
657 | RID debug_probes_uniform_set; |
658 | RID cascades_ubo; |
659 | |
660 | bool uses_occlusion = false; |
661 | float bounce_feedback = 0.5; |
662 | bool reads_sky = true; |
663 | float energy = 1.0; |
664 | float normal_bias = 1.1; |
665 | float probe_bias = 1.1; |
666 | RS::EnvironmentSDFGIYScale y_scale_mode = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; |
667 | |
668 | float y_mult = 1.0; |
669 | |
670 | uint32_t render_pass = 0; |
671 | |
672 | int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically |
673 | RID integrate_sky_uniform_set; |
674 | |
675 | virtual void configure(RenderSceneBuffersRD *p_render_buffers) override{}; |
676 | virtual void free_data() override; |
677 | ~SDFGI(); |
678 | |
679 | void create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi); |
680 | void update(RID p_env, const Vector3 &p_world_position); |
681 | void update_light(); |
682 | void update_probes(RID p_env, RendererRD::SkyRD::Sky *p_sky); |
683 | void store_probes(); |
684 | int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; |
685 | void update_cascades(); |
686 | |
687 | void 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); |
688 | void 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); |
689 | |
690 | void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data); |
691 | void render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization); |
692 | void 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); |
693 | }; |
694 | |
695 | RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16; |
696 | RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_30_FRAMES; |
697 | RS::EnvironmentSDFGIFramesToUpdateLight sdfgi_frames_to_update_light = RS::ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES; |
698 | |
699 | float sdfgi_solid_cell_ratio = 0.25; |
700 | Vector3 sdfgi_debug_probe_pos; |
701 | Vector3 sdfgi_debug_probe_dir; |
702 | bool sdfgi_debug_probe_enabled = false; |
703 | Vector3i sdfgi_debug_probe_index; |
704 | |
705 | /* SDFGI UPDATE */ |
706 | |
707 | int sdfgi_get_lightprobe_octahedron_size() const { return SDFGI::LIGHTPROBE_OCT_SIZE; } |
708 | |
709 | struct SDFGIData { |
710 | float grid_size[3]; |
711 | uint32_t max_cascades; |
712 | |
713 | uint32_t use_occlusion; |
714 | int32_t probe_axis_size; |
715 | float probe_to_uvw; |
716 | float normal_bias; |
717 | |
718 | float lightprobe_tex_pixel_size[3]; |
719 | float energy; |
720 | |
721 | float lightprobe_uv_offset[3]; |
722 | float y_mult; |
723 | |
724 | float occlusion_clamp[3]; |
725 | uint32_t pad3; |
726 | |
727 | float occlusion_renormalize[3]; |
728 | uint32_t pad4; |
729 | |
730 | float cascade_probe_size[3]; |
731 | uint32_t pad5; |
732 | |
733 | struct ProbeCascadeData { |
734 | float position[3]; //offset of (0,0,0) in world coordinates |
735 | float to_probe; // 1/bounds * grid_size |
736 | int32_t probe_world_offset[3]; |
737 | float to_cell; // 1/bounds * grid_size |
738 | float pad[3]; |
739 | float exposure_normalization; |
740 | }; |
741 | |
742 | ProbeCascadeData cascades[SDFGI::MAX_CASCADES]; |
743 | }; |
744 | |
745 | struct VoxelGIData { |
746 | float xform[16]; // 64 - 64 |
747 | |
748 | float bounds[3]; // 12 - 76 |
749 | float dynamic_range; // 4 - 80 |
750 | |
751 | float bias; // 4 - 84 |
752 | float normal_bias; // 4 - 88 |
753 | uint32_t blend_ambient; // 4 - 92 |
754 | uint32_t mipmaps; // 4 - 96 |
755 | |
756 | float pad[3]; // 12 - 108 |
757 | float exposure_normalization; // 4 - 112 |
758 | }; |
759 | |
760 | struct SceneData { |
761 | float inv_projection[2][16]; |
762 | float cam_transform[16]; |
763 | float eye_offset[2][4]; |
764 | |
765 | int32_t screen_size[2]; |
766 | float pad1; |
767 | float pad2; |
768 | }; |
769 | |
770 | struct PushConstant { |
771 | uint32_t max_voxel_gi_instances; |
772 | uint32_t high_quality_vct; |
773 | uint32_t orthogonal; |
774 | uint32_t view_index; |
775 | |
776 | float proj_info[4]; |
777 | |
778 | float z_near; |
779 | float z_far; |
780 | float pad2; |
781 | float pad3; |
782 | }; |
783 | |
784 | RID sdfgi_ubo; |
785 | |
786 | enum Mode { |
787 | MODE_VOXEL_GI, |
788 | MODE_SDFGI, |
789 | MODE_COMBINED, |
790 | MODE_MAX |
791 | }; |
792 | |
793 | enum ShaderSpecializations { |
794 | SHADER_SPECIALIZATION_HALF_RES = 1 << 0, |
795 | SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX = 1 << 1, |
796 | SHADER_SPECIALIZATION_USE_VRS = 1 << 2, |
797 | SHADER_SPECIALIZATION_VARIATIONS = 8, |
798 | }; |
799 | |
800 | RID default_voxel_gi_buffer; |
801 | |
802 | bool half_resolution = false; |
803 | GiShaderRD shader; |
804 | RID shader_version; |
805 | RID pipelines[SHADER_SPECIALIZATION_VARIATIONS][MODE_MAX]; |
806 | |
807 | GI(); |
808 | ~GI(); |
809 | |
810 | void init(RendererRD::SkyRD *p_sky); |
811 | void free(); |
812 | |
813 | Ref<SDFGI> create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); |
814 | |
815 | void 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); |
816 | void 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); |
817 | |
818 | RID voxel_gi_instance_create(RID p_base); |
819 | void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); |
820 | bool voxel_gi_needs_update(RID p_probe) const; |
821 | void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects); |
822 | void 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); |
823 | }; |
824 | |
825 | } // namespace RendererRD |
826 | |
827 | #endif // GI_RD_H |
828 | |