1/**************************************************************************/
2/* render_forward_clustered.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 RENDER_FORWARD_CLUSTERED_H
32#define RENDER_FORWARD_CLUSTERED_H
33
34#include "core/templates/paged_allocator.h"
35#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
36#include "servers/rendering/renderer_rd/effects/resolve.h"
37#include "servers/rendering/renderer_rd/effects/ss_effects.h"
38#include "servers/rendering/renderer_rd/effects/taa.h"
39#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
40#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
41#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
42#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
43#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
44
45#define RB_SCOPE_FORWARD_CLUSTERED SNAME("forward_clustered")
46
47#define RB_TEX_SPECULAR SNAME("specular")
48#define RB_TEX_SPECULAR_MSAA SNAME("specular_msaa")
49#define RB_TEX_ROUGHNESS SNAME("normal_roughnesss")
50#define RB_TEX_ROUGHNESS_MSAA SNAME("normal_roughnesss_msaa")
51#define RB_TEX_VOXEL_GI SNAME("voxel_gi")
52#define RB_TEX_VOXEL_GI_MSAA SNAME("voxel_gi_msaa")
53
54namespace RendererSceneRenderImplementation {
55
56class RenderForwardClustered : public RendererSceneRenderRD {
57 friend SceneShaderForwardClustered;
58
59 enum {
60 SCENE_UNIFORM_SET = 0,
61 RENDER_PASS_UNIFORM_SET = 1,
62 TRANSFORMS_UNIFORM_SET = 2,
63 MATERIAL_UNIFORM_SET = 3,
64 };
65
66 const int SAMPLERS_BINDING_FIRST_INDEX = 16;
67
68 enum {
69 SPEC_CONSTANT_SOFT_SHADOW_SAMPLES = 6,
70 SPEC_CONSTANT_PENUMBRA_SHADOW_SAMPLES = 7,
71 SPEC_CONSTANT_DIRECTIONAL_SOFT_SHADOW_SAMPLES = 8,
72 SPEC_CONSTANT_DIRECTIONAL_PENUMBRA_SHADOW_SAMPLES = 9,
73 SPEC_CONSTANT_DECAL_FILTER = 10,
74 SPEC_CONSTANT_PROJECTOR_FILTER = 11,
75 };
76
77 enum {
78 SDFGI_MAX_CASCADES = 8,
79 MAX_VOXEL_GI_INSTANCESS = 8,
80 MAX_LIGHTMAPS = 8,
81 MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE = 2,
82 INSTANCE_DATA_BUFFER_MIN_SIZE = 4096
83 };
84
85 enum RenderListType {
86 RENDER_LIST_OPAQUE, //used for opaque objects
87 RENDER_LIST_ALPHA, //used for transparent objects
88 RENDER_LIST_SECONDARY, //used for shadows and other objects
89 RENDER_LIST_MAX
90 };
91
92 /* Scene Shader */
93
94 SceneShaderForwardClustered scene_shader;
95
96 /* Framebuffer */
97
98 class RenderBufferDataForwardClustered : public RenderBufferCustomDataRD {
99 GDCLASS(RenderBufferDataForwardClustered, RenderBufferCustomDataRD)
100
101 private:
102 RenderSceneBuffersRD *render_buffers = nullptr;
103
104 public:
105 ClusterBuilderRD *cluster_builder = nullptr;
106
107 struct SSEffectsData {
108 Projection last_frame_projections[RendererSceneRender::MAX_RENDER_VIEWS];
109 Transform3D last_frame_transform;
110
111 RendererRD::SSEffects::SSILRenderBuffers ssil;
112 RendererRD::SSEffects::SSAORenderBuffers ssao;
113 RendererRD::SSEffects::SSRRenderBuffers ssr;
114 } ss_effects_data;
115
116 enum DepthFrameBufferType {
117 DEPTH_FB,
118 DEPTH_FB_ROUGHNESS,
119 DEPTH_FB_ROUGHNESS_VOXELGI
120 };
121
122 RID render_sdfgi_uniform_set;
123
124 void ensure_specular();
125 bool has_specular() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR); }
126 RID get_specular() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR); }
127 RID get_specular(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR, p_layer, 0); }
128 RID get_specular_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR_MSAA, p_layer, 0); }
129
130 void ensure_normal_roughness_texture();
131 bool has_normal_roughness() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS); }
132 RID get_normal_roughness() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS); }
133 RID get_normal_roughness(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS, p_layer, 0); }
134 RID get_normal_roughness_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA); }
135 RID get_normal_roughness_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, p_layer, 0); }
136
137 void ensure_voxelgi();
138 bool has_voxelgi() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI); }
139 RID get_voxelgi() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI); }
140 RID get_voxelgi(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI, p_layer, 0); }
141 RID get_voxelgi_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI_MSAA, p_layer, 0); }
142
143 RID get_color_only_fb();
144 RID get_color_pass_fb(uint32_t p_color_pass_flags);
145 RID get_depth_fb(DepthFrameBufferType p_type = DEPTH_FB);
146 RID get_specular_only_fb();
147
148 virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
149 virtual void free_data() override;
150 };
151
152 virtual void setup_render_buffer_data(Ref<RenderSceneBuffersRD> p_render_buffers) override;
153
154 RID render_base_uniform_set;
155
156 uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
157
158 bool base_uniform_set_updated = false;
159 void _update_render_base_uniform_set();
160 RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
161 RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0);
162
163 enum PassMode {
164 PASS_MODE_COLOR,
165 PASS_MODE_SHADOW,
166 PASS_MODE_SHADOW_DP,
167 PASS_MODE_DEPTH,
168 PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
169 PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI,
170 PASS_MODE_DEPTH_MATERIAL,
171 PASS_MODE_SDF,
172 };
173
174 enum ColorPassFlags {
175 COLOR_PASS_FLAG_TRANSPARENT = 1 << 0,
176 COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 1,
177 COLOR_PASS_FLAG_MULTIVIEW = 1 << 2,
178 COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 3,
179 };
180
181 struct GeometryInstanceSurfaceDataCache;
182 struct RenderElementInfo;
183
184 struct RenderListParameters {
185 GeometryInstanceSurfaceDataCache **elements = nullptr;
186 RenderElementInfo *element_info = nullptr;
187 int element_count = 0;
188 bool reverse_cull = false;
189 PassMode pass_mode = PASS_MODE_COLOR;
190 uint32_t color_pass_flags = 0;
191 bool no_gi = false;
192 uint32_t view_count = 1;
193 RID render_pass_uniform_set;
194 bool force_wireframe = false;
195 Vector2 uv_offset;
196 float lod_distance_multiplier = 0.0;
197 float screen_mesh_lod_threshold = 0.0;
198 RD::FramebufferFormatID framebuffer_format = 0;
199 uint32_t element_offset = 0;
200 uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS;
201 bool use_directional_soft_shadow = false;
202
203 RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) {
204 elements = p_elements;
205 element_info = p_element_info;
206 element_count = p_element_count;
207 reverse_cull = p_reverse_cull;
208 pass_mode = p_pass_mode;
209 color_pass_flags = p_color_pass_flags;
210 no_gi = p_no_gi;
211 view_count = p_view_count;
212 render_pass_uniform_set = p_render_pass_uniform_set;
213 force_wireframe = p_force_wireframe;
214 uv_offset = p_uv_offset;
215 lod_distance_multiplier = p_lod_distance_multiplier;
216 screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
217 element_offset = p_element_offset;
218 barrier = p_barrier;
219 use_directional_soft_shadow = p_use_directional_soft_shadows;
220 }
221 };
222
223 struct LightmapData {
224 float normal_xform[12];
225 float pad[3];
226 float exposure_normalization;
227 };
228
229 struct LightmapCaptureData {
230 float sh[9 * 4];
231 };
232
233 // When changing any of these enums, remember to change the corresponding enums in the shader files as well.
234 enum {
235 INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4,
236 INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 5,
237 INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 6,
238 INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 7,
239 INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 8,
240 INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 9,
241 INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 10,
242 INSTANCE_DATA_FLAG_PARTICLES = 1 << 11,
243 INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
244 INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
245 INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
246 INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
247 INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
248 INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
249 INSTANCE_DATA_FLAGS_FADE_SHIFT = 24,
250 INSTANCE_DATA_FLAGS_FADE_MASK = 0xFFUL << INSTANCE_DATA_FLAGS_FADE_SHIFT
251 };
252
253 struct SceneState {
254 // This struct is loaded into Set 1 - Binding 1, populated at start of rendering a frame, must match with shader code
255 struct UBO {
256 uint32_t cluster_shift;
257 uint32_t cluster_width;
258 uint32_t cluster_type_size;
259 uint32_t max_cluster_element_count_div_32;
260
261 uint32_t ss_effects_flags;
262 float ssao_light_affect;
263 float ssao_ao_affect;
264 uint32_t pad1;
265
266 float sdf_to_bounds[16];
267
268 int32_t sdf_offset[3];
269 uint32_t pad2;
270
271 int32_t sdf_size[3];
272 uint32_t gi_upscale_for_msaa;
273
274 uint32_t volumetric_fog_enabled;
275 float volumetric_fog_inv_length;
276 float volumetric_fog_detail_spread;
277 uint32_t volumetric_fog_pad;
278 };
279
280 struct PushConstant {
281 uint32_t base_index; //
282 uint32_t uv_offset; //packed
283 uint32_t multimesh_motion_vectors_current_offset;
284 uint32_t multimesh_motion_vectors_previous_offset;
285 };
286
287 struct InstanceData {
288 float transform[16];
289 float prev_transform[16];
290 uint32_t flags;
291 uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables
292 uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
293 uint32_t layer_mask;
294 float lightmap_uv_scale[4];
295 };
296
297 UBO ubo;
298
299 LocalVector<RID> uniform_buffers;
300 LocalVector<RID> implementation_uniform_buffers;
301
302 LightmapData lightmaps[MAX_LIGHTMAPS];
303 RID lightmap_ids[MAX_LIGHTMAPS];
304 bool lightmap_has_sh[MAX_LIGHTMAPS];
305 uint32_t lightmaps_used = 0;
306 uint32_t max_lightmaps;
307 RID lightmap_buffer;
308
309 RID instance_buffer[RENDER_LIST_MAX];
310 uint32_t instance_buffer_size[RENDER_LIST_MAX] = { 0, 0, 0 };
311 LocalVector<InstanceData> instance_data[RENDER_LIST_MAX];
312
313 LightmapCaptureData *lightmap_captures = nullptr;
314 uint32_t max_lightmap_captures;
315 RID lightmap_capture_buffer;
316
317 RID voxelgi_ids[MAX_VOXEL_GI_INSTANCESS];
318 uint32_t voxelgis_used = 0;
319
320 bool used_screen_texture = false;
321 bool used_normal_texture = false;
322 bool used_depth_texture = false;
323 bool used_sss = false;
324 bool used_lightmap = false;
325
326 struct ShadowPass {
327 uint32_t element_from;
328 uint32_t element_count;
329 bool flip_cull;
330 PassMode pass_mode;
331
332 RID rp_uniform_set;
333 Plane camera_plane;
334 float lod_distance_multiplier;
335 float screen_mesh_lod_threshold;
336
337 RID framebuffer;
338 RD::InitialAction initial_depth_action;
339 RD::FinalAction final_depth_action;
340 Rect2i rect;
341 };
342
343 LocalVector<ShadowPass> shadow_passes;
344
345 } scene_state;
346
347 static RenderForwardClustered *singleton;
348
349 void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
350 void _setup_voxelgis(const PagedArray<RID> &p_voxelgis);
351 void _setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform);
352
353 struct RenderElementInfo {
354 enum { MAX_REPEATS = (1 << 20) - 1 };
355 uint32_t repeat : 20;
356 uint32_t uses_projector : 1;
357 uint32_t uses_softshadow : 1;
358 uint32_t uses_lightmap : 1;
359 uint32_t uses_forward_gi : 1;
360 uint32_t lod_index : 8;
361 };
362
363 template <PassMode p_pass_mode, uint32_t p_color_pass_flags = 0>
364 _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
365
366 void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
367
368 LocalVector<RD::DrawListID> thread_draw_lists;
369 void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
370 void _render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
371
372 uint32_t render_list_thread_threshold = 500;
373
374 void _update_instance_data_buffer(RenderListType p_render_list);
375 void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
376 void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false);
377
378 HashMap<Size2i, RID> sdfgi_framebuffer_size_cache;
379
380 struct GeometryInstanceData;
381 class GeometryInstanceForwardClustered;
382
383 struct GeometryInstanceLightmapSH {
384 Color sh[9];
385 };
386
387 // Cached data for drawing surfaces
388 struct GeometryInstanceSurfaceDataCache {
389 enum {
390 FLAG_PASS_DEPTH = 1,
391 FLAG_PASS_OPAQUE = 2,
392 FLAG_PASS_ALPHA = 4,
393 FLAG_PASS_SHADOW = 8,
394 FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
395 FLAG_USES_SUBSURFACE_SCATTERING = 2048,
396 FLAG_USES_SCREEN_TEXTURE = 4096,
397 FLAG_USES_DEPTH_TEXTURE = 8192,
398 FLAG_USES_NORMAL_TEXTURE = 16384,
399 FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
400 FLAG_USES_PARTICLE_TRAILS = 65536,
401 };
402
403 union {
404 struct {
405 uint64_t lod_index : 8;
406 uint64_t surface_index : 8;
407 uint64_t geometry_id : 32;
408 uint64_t material_id_low : 16;
409
410 uint64_t material_id_hi : 16;
411 uint64_t shader_id : 32;
412 uint64_t uses_softshadow : 1;
413 uint64_t uses_projector : 1;
414 uint64_t uses_forward_gi : 1;
415 uint64_t uses_lightmap : 1;
416 uint64_t depth_layer : 4;
417 uint64_t priority : 8;
418 };
419 struct {
420 uint64_t sort_key1;
421 uint64_t sort_key2;
422 };
423 } sort;
424
425 RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
426 uint32_t flags = 0;
427 uint32_t surface_index = 0;
428
429 void *surface = nullptr;
430 RID material_uniform_set;
431 SceneShaderForwardClustered::ShaderData *shader = nullptr;
432 SceneShaderForwardClustered::MaterialData *material = nullptr;
433
434 void *surface_shadow = nullptr;
435 RID material_uniform_set_shadow;
436 SceneShaderForwardClustered::ShaderData *shader_shadow = nullptr;
437
438 GeometryInstanceSurfaceDataCache *next = nullptr;
439 GeometryInstanceForwardClustered *owner = nullptr;
440 };
441
442 class GeometryInstanceForwardClustered : public RenderGeometryInstanceBase {
443 public:
444 // lightmap
445 RID lightmap_instance;
446 Rect2 lightmap_uv_scale;
447 uint32_t lightmap_slice_index;
448 GeometryInstanceLightmapSH *lightmap_sh = nullptr;
449
450 //used during rendering
451
452 uint32_t gi_offset_cache = 0;
453 bool store_transform_cache = true;
454 RID transforms_uniform_set;
455 uint32_t instance_count = 0;
456 uint32_t trail_steps = 1;
457 bool can_sdfgi = false;
458 bool using_projectors = false;
459 bool using_softshadows = false;
460
461 //used during setup
462 uint64_t prev_transform_change_frame = 0xFFFFFFFF;
463 bool prev_transform_dirty = true;
464 Transform3D prev_transform;
465 RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE];
466 GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
467 SelfList<GeometryInstanceForwardClustered> dirty_list_element;
468
469 GeometryInstanceForwardClustered() :
470 dirty_list_element(this) {}
471
472 virtual void _mark_dirty() override;
473
474 virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override;
475 virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
476 virtual void set_lightmap_capture(const Color *p_sh9) override;
477
478 virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {}
479 virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {}
480 virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {}
481 virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override;
482
483 virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override;
484 };
485
486 static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
487 static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
488
489 SelfList<GeometryInstanceForwardClustered>::List geometry_instance_dirty_list;
490
491 PagedAllocator<GeometryInstanceForwardClustered> geometry_instance_alloc;
492 PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
493 PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
494
495 void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
496 void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh);
497 void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
498 void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance);
499 void _update_dirty_geometry_instances();
500
501 /* Render List */
502
503 struct RenderList {
504 LocalVector<GeometryInstanceSurfaceDataCache *> elements;
505 LocalVector<RenderElementInfo> element_info;
506
507 void clear() {
508 elements.clear();
509 element_info.clear();
510 }
511
512 //should eventually be replaced by radix
513
514 struct SortByKey {
515 _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
516 return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
517 }
518 };
519
520 void sort_by_key() {
521 SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
522 sorter.sort(elements.ptr(), elements.size());
523 }
524
525 void sort_by_key_range(uint32_t p_from, uint32_t p_size) {
526 SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
527 sorter.sort(elements.ptr() + p_from, p_size);
528 }
529
530 struct SortByDepth {
531 _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
532 return (A->owner->depth < B->owner->depth);
533 }
534 };
535
536 void sort_by_depth() { //used for shadows
537
538 SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter;
539 sorter.sort(elements.ptr(), elements.size());
540 }
541
542 struct SortByReverseDepthAndPriority {
543 _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
544 return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
545 }
546 };
547
548 void sort_by_reverse_depth_and_priority() { //used for alpha
549
550 SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
551 sorter.sort(elements.ptr(), elements.size());
552 }
553
554 _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) {
555 elements.push_back(p_element);
556 }
557 };
558
559 RenderList render_list[RENDER_LIST_MAX];
560
561 virtual void _update_shader_quality_settings() override;
562
563 /* Effects */
564
565 RendererRD::Resolve *resolve_effects = nullptr;
566 RendererRD::TAA *taa = nullptr;
567 RendererRD::SSEffects *ss_effects = nullptr;
568
569 /* Cluster builder */
570
571 ClusterBuilderSharedDataRD cluster_builder_shared;
572 ClusterBuilderRD *current_cluster_builder = nullptr;
573
574 /* SDFGI */
575 void _update_sdfgi(RenderDataRD *p_render_data);
576
577 /* Volumetric fog */
578 RID shadow_sampler;
579
580 void _update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
581
582 /* Render shadows */
583
584 void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
585 void _render_shadow_begin();
586 void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
587 void _render_shadow_process();
588 void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
589
590 /* Render Scene */
591 void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections);
592 void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform);
593 void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers);
594 void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer);
595 void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);
596 void _process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera);
597
598 /* Debug */
599 void _debug_draw_cluster(Ref<RenderSceneBuffersRD> p_render_buffers);
600
601protected:
602 /* setup */
603
604 virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
605 virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
606
607 virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override;
608 virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override;
609 virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override;
610
611 virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override;
612 virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override;
613
614 /* Rendering */
615
616 virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
617 virtual void _render_buffers_debug_draw(const RenderDataRD *p_render_data) override;
618
619 virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) override;
620 virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
621 virtual void _render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) override;
622 virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override;
623
624public:
625 static RenderForwardClustered *get_singleton() { return singleton; }
626
627 ClusterBuilderSharedDataRD *get_cluster_builder_shared() { return &cluster_builder_shared; }
628 RendererRD::SSEffects *get_ss_effects() { return ss_effects; }
629
630 /* callback from updating our lighting UBOs, used to populate cluster builder */
631 virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_size) override;
632 virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) override;
633 virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_size) override;
634
635 virtual void base_uniforms_changed() override;
636 _FORCE_INLINE_ virtual void update_uniform_sets() override {
637 base_uniform_set_updated = true;
638 _update_render_base_uniform_set();
639 }
640
641 /* SDFGI UPDATE */
642
643 virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override;
644 virtual int sdfgi_get_pending_region_count(const Ref<RenderSceneBuffers> &p_render_buffers) const override;
645 virtual AABB sdfgi_get_pending_region_bounds(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override;
646 virtual uint32_t sdfgi_get_pending_region_cascade(const Ref<RenderSceneBuffers> &p_render_buffers, int p_region) const override;
647 RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
648
649 /* GEOMETRY INSTANCE */
650
651 virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override;
652 virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override;
653
654 virtual uint32_t geometry_instance_get_pair_mask() override;
655
656 virtual bool free(RID p_rid) override;
657
658 RenderForwardClustered();
659 ~RenderForwardClustered();
660};
661} // namespace RendererSceneRenderImplementation
662
663#endif // RENDER_FORWARD_CLUSTERED_H
664