1 | /**************************************************************************/ |
2 | /* renderer_scene_render_rd.cpp */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #include "renderer_scene_render_rd.h" |
32 | |
33 | #include "core/config/project_settings.h" |
34 | #include "core/os/os.h" |
35 | #include "renderer_compositor_rd.h" |
36 | #include "servers/rendering/renderer_rd/environment/fog.h" |
37 | #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" |
38 | #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" |
39 | #include "servers/rendering/rendering_server_default.h" |
40 | #include "servers/rendering/storage/camera_attributes_storage.h" |
41 | |
42 | void get_vogel_disk(float *r_kernel, int p_sample_count) { |
43 | const float golden_angle = 2.4; |
44 | |
45 | for (int i = 0; i < p_sample_count; i++) { |
46 | float r = Math::sqrt(float(i) + 0.5) / Math::sqrt(float(p_sample_count)); |
47 | float theta = float(i) * golden_angle; |
48 | |
49 | r_kernel[i * 4] = Math::cos(theta) * r; |
50 | r_kernel[i * 4 + 1] = Math::sin(theta) * r; |
51 | } |
52 | } |
53 | |
54 | RID RendererSceneRenderRD::sky_allocate() { |
55 | return sky.allocate_sky_rid(); |
56 | } |
57 | void RendererSceneRenderRD::sky_initialize(RID p_rid) { |
58 | sky.initialize_sky_rid(p_rid); |
59 | } |
60 | |
61 | void RendererSceneRenderRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { |
62 | sky.sky_set_radiance_size(p_sky, p_radiance_size); |
63 | } |
64 | |
65 | void RendererSceneRenderRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { |
66 | sky.sky_set_mode(p_sky, p_mode); |
67 | } |
68 | |
69 | void RendererSceneRenderRD::sky_set_material(RID p_sky, RID p_material) { |
70 | sky.sky_set_material(p_sky, p_material); |
71 | } |
72 | |
73 | Ref<Image> RendererSceneRenderRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { |
74 | return sky.sky_bake_panorama(p_sky, p_energy, p_bake_irradiance, p_size); |
75 | } |
76 | |
77 | void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) { |
78 | glow_bicubic_upscale = p_enable; |
79 | } |
80 | |
81 | void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { |
82 | volumetric_fog_size = p_size; |
83 | volumetric_fog_depth = p_depth; |
84 | } |
85 | |
86 | void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) { |
87 | volumetric_fog_filter_active = p_enable; |
88 | } |
89 | |
90 | void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { |
91 | gi.sdfgi_ray_count = p_ray_count; |
92 | } |
93 | |
94 | void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) { |
95 | gi.sdfgi_frames_to_converge = p_frames; |
96 | } |
97 | void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) { |
98 | gi.sdfgi_frames_to_update_light = p_update; |
99 | } |
100 | |
101 | Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { |
102 | ERR_FAIL_COND_V(p_env.is_null(), Ref<Image>()); |
103 | |
104 | RS::EnvironmentBG environment_background = environment_get_background(p_env); |
105 | |
106 | if (environment_background == RS::ENV_BG_CAMERA_FEED || environment_background == RS::ENV_BG_CANVAS || environment_background == RS::ENV_BG_KEEP) { |
107 | return Ref<Image>(); //nothing to bake |
108 | } |
109 | |
110 | RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_env); |
111 | |
112 | bool use_ambient_light = false; |
113 | bool use_cube_map = false; |
114 | if (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && (environment_background == RS::ENV_BG_CLEAR_COLOR || environment_background == RS::ENV_BG_COLOR)) { |
115 | use_ambient_light = true; |
116 | } else { |
117 | use_cube_map = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && environment_background == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY; |
118 | use_ambient_light = use_cube_map || ambient_source == RS::ENV_AMBIENT_SOURCE_COLOR; |
119 | } |
120 | use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && environment_get_sky(p_env).is_valid()); |
121 | |
122 | Color ambient_color; |
123 | float ambient_color_sky_mix = 0.0; |
124 | if (use_ambient_light) { |
125 | ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_env); |
126 | const float ambient_energy = environment_get_ambient_light_energy(p_env); |
127 | ambient_color = environment_get_ambient_light(p_env); |
128 | ambient_color = ambient_color.srgb_to_linear(); |
129 | ambient_color.r *= ambient_energy; |
130 | ambient_color.g *= ambient_energy; |
131 | ambient_color.b *= ambient_energy; |
132 | } |
133 | |
134 | if (use_cube_map) { |
135 | Ref<Image> panorama = sky_bake_panorama(environment_get_sky(p_env), environment_get_bg_energy_multiplier(p_env), p_bake_irradiance, p_size); |
136 | if (use_ambient_light) { |
137 | for (int x = 0; x < p_size.width; x++) { |
138 | for (int y = 0; y < p_size.height; y++) { |
139 | panorama->set_pixel(x, y, ambient_color.lerp(panorama->get_pixel(x, y), ambient_color_sky_mix)); |
140 | } |
141 | } |
142 | } |
143 | return panorama; |
144 | } else { |
145 | const float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_env); |
146 | Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : environment_get_bg_color(p_env)); |
147 | panorama_color = panorama_color.srgb_to_linear(); |
148 | panorama_color.r *= bg_energy_multiplier; |
149 | panorama_color.g *= bg_energy_multiplier; |
150 | panorama_color.b *= bg_energy_multiplier; |
151 | |
152 | if (use_ambient_light) { |
153 | panorama_color = ambient_color.lerp(panorama_color, ambient_color_sky_mix); |
154 | } |
155 | |
156 | Ref<Image> panorama = Image::create_empty(p_size.width, p_size.height, false, Image::FORMAT_RGBAF); |
157 | panorama->fill(panorama_color); |
158 | return panorama; |
159 | } |
160 | } |
161 | |
162 | /* REFLECTION PROBE */ |
163 | |
164 | RID RendererSceneRenderRD::reflection_probe_create_framebuffer(RID p_color, RID p_depth) { |
165 | Vector<RID> fb; |
166 | fb.push_back(p_color); |
167 | fb.push_back(p_depth); |
168 | return RD::get_singleton()->framebuffer_create(fb); |
169 | } |
170 | |
171 | /* FOG VOLUME INSTANCE */ |
172 | |
173 | RID RendererSceneRenderRD::fog_volume_instance_create(RID p_fog_volume) { |
174 | return RendererRD::Fog::get_singleton()->fog_volume_instance_create(p_fog_volume); |
175 | } |
176 | |
177 | void RendererSceneRenderRD::fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) { |
178 | RendererRD::Fog::get_singleton()->fog_volume_instance_set_transform(p_fog_volume_instance, p_transform); |
179 | } |
180 | |
181 | void RendererSceneRenderRD::fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) { |
182 | RendererRD::Fog::get_singleton()->fog_volume_instance_set_active(p_fog_volume_instance, p_active); |
183 | } |
184 | |
185 | RID RendererSceneRenderRD::fog_volume_instance_get_volume(RID p_fog_volume_instance) const { |
186 | return RendererRD::Fog::get_singleton()->fog_volume_instance_get_volume(p_fog_volume_instance); |
187 | } |
188 | |
189 | Vector3 RendererSceneRenderRD::fog_volume_instance_get_position(RID p_fog_volume_instance) const { |
190 | return RendererRD::Fog::get_singleton()->fog_volume_instance_get_position(p_fog_volume_instance); |
191 | } |
192 | |
193 | /* VOXEL GI */ |
194 | |
195 | RID RendererSceneRenderRD::voxel_gi_instance_create(RID p_base) { |
196 | return gi.voxel_gi_instance_create(p_base); |
197 | } |
198 | |
199 | void RendererSceneRenderRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { |
200 | if (!is_dynamic_gi_supported()) { |
201 | return; |
202 | } |
203 | |
204 | gi.voxel_gi_instance_set_transform_to_data(p_probe, p_xform); |
205 | } |
206 | |
207 | bool RendererSceneRenderRD::voxel_gi_needs_update(RID p_probe) const { |
208 | if (!is_dynamic_gi_supported()) { |
209 | return false; |
210 | } |
211 | |
212 | return gi.voxel_gi_needs_update(p_probe); |
213 | } |
214 | |
215 | void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { |
216 | if (!is_dynamic_gi_supported()) { |
217 | return; |
218 | } |
219 | |
220 | gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects); |
221 | } |
222 | |
223 | void RendererSceneRenderRD::_debug_sdfgi_probes(Ref<RenderSceneBuffersRD> p_render_buffers, 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) { |
224 | ERR_FAIL_COND(p_render_buffers.is_null()); |
225 | |
226 | if (!p_render_buffers->has_custom_data(RB_SCOPE_SDFGI)) { |
227 | return; //nothing to debug |
228 | } |
229 | |
230 | Ref<RendererRD::GI::SDFGI> sdfgi = p_render_buffers->get_custom_data(RB_SCOPE_SDFGI); |
231 | |
232 | sdfgi->debug_probes(p_framebuffer, p_view_count, p_camera_with_transforms, p_will_continue_color, p_will_continue_depth); |
233 | } |
234 | |
235 | //////////////////////////////// |
236 | Ref<RenderSceneBuffers> RendererSceneRenderRD::render_buffers_create() { |
237 | Ref<RenderSceneBuffersRD> rb; |
238 | rb.instantiate(); |
239 | |
240 | rb->set_can_be_storage(_render_buffers_can_be_storage()); |
241 | rb->set_max_cluster_elements(max_cluster_elements); |
242 | rb->set_base_data_format(_render_buffers_get_color_format()); |
243 | if (vrs) { |
244 | rb->set_vrs(vrs); |
245 | } |
246 | |
247 | setup_render_buffer_data(rb); |
248 | |
249 | return rb; |
250 | } |
251 | |
252 | void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) { |
253 | Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; |
254 | ERR_FAIL_COND(rb.is_null()); |
255 | |
256 | if (!rb->has_internal_texture()) { |
257 | // We're likely rendering reflection probes where we can't use our backbuffers. |
258 | return; |
259 | } |
260 | |
261 | RD::get_singleton()->draw_command_begin_label("Copy screen texture" ); |
262 | |
263 | rb->allocate_blur_textures(); |
264 | |
265 | bool can_use_storage = _render_buffers_can_be_storage(); |
266 | Size2i size = rb->get_internal_size(); |
267 | |
268 | for (uint32_t v = 0; v < rb->get_view_count(); v++) { |
269 | RID texture = rb->get_internal_texture(v); |
270 | int mipmaps = int(rb->get_texture_format(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0).mipmaps); |
271 | RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, 0); |
272 | |
273 | if (can_use_storage) { |
274 | copy_effects->copy_to_rect(texture, dest, Rect2i(0, 0, size.x, size.y)); |
275 | } else { |
276 | RID fb = FramebufferCacheRD::get_singleton()->get_cache(dest); |
277 | copy_effects->copy_to_fb_rect(texture, fb, Rect2i(0, 0, size.x, size.y)); |
278 | } |
279 | |
280 | for (int i = 1; i < mipmaps; i++) { |
281 | RID source = dest; |
282 | dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i); |
283 | Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, i); |
284 | |
285 | if (can_use_storage) { |
286 | copy_effects->make_mipmap(source, dest, msize); |
287 | } else { |
288 | copy_effects->make_mipmap_raster(source, dest, msize); |
289 | } |
290 | } |
291 | } |
292 | |
293 | RD::get_singleton()->draw_command_end_label(); |
294 | } |
295 | |
296 | void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data) { |
297 | Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; |
298 | ERR_FAIL_COND(rb.is_null()); |
299 | |
300 | if (!rb->has_depth_texture()) { |
301 | // We're likely rendering reflection probes where we can't use our backbuffers. |
302 | return; |
303 | } |
304 | |
305 | RD::get_singleton()->draw_command_begin_label("Copy depth texture" ); |
306 | |
307 | // note, this only creates our back depth texture if we haven't already created it. |
308 | uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; |
309 | usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; |
310 | usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; // set this as color attachment because we're copying data into it, it's not actually used as a depth buffer |
311 | |
312 | rb->create_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, RD::DATA_FORMAT_R32_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1); |
313 | |
314 | bool can_use_storage = _render_buffers_can_be_storage(); |
315 | Size2i size = rb->get_internal_size(); |
316 | for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) { |
317 | RID depth_texture = rb->get_depth_texture(v); |
318 | RID depth_back_texture = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, v, 0); |
319 | |
320 | if (can_use_storage) { |
321 | copy_effects->copy_to_rect(depth_texture, depth_back_texture, Rect2i(0, 0, size.x, size.y)); |
322 | } else { |
323 | RID depth_back_fb = FramebufferCacheRD::get_singleton()->get_cache(depth_back_texture); |
324 | copy_effects->copy_to_fb_rect(depth_texture, depth_back_fb, Rect2i(0, 0, size.x, size.y)); |
325 | } |
326 | } |
327 | |
328 | RD::get_singleton()->draw_command_end_label(); |
329 | } |
330 | |
331 | void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) { |
332 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
333 | |
334 | ERR_FAIL_NULL(p_render_data); |
335 | |
336 | Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; |
337 | ERR_FAIL_COND(rb.is_null()); |
338 | |
339 | ERR_FAIL_COND_MSG(p_render_data->reflection_probe.is_valid(), "Post processes should not be applied on reflection probes." ); |
340 | |
341 | // Glow, auto exposure and DoF (if enabled). |
342 | |
343 | Size2i internal_size = rb->get_internal_size(); |
344 | Size2i target_size = rb->get_target_size(); |
345 | |
346 | bool can_use_effects = target_size.x >= 8 && target_size.y >= 8; // FIXME I think this should check internal size, we do all our post processing at this size... |
347 | bool can_use_storage = _render_buffers_can_be_storage(); |
348 | |
349 | RID render_target = rb->get_render_target(); |
350 | RID internal_texture = rb->get_internal_texture(); |
351 | |
352 | if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_dof(p_render_data->camera_attributes)) { |
353 | RENDER_TIMESTAMP("Depth of Field" ); |
354 | RD::get_singleton()->draw_command_begin_label("DOF" ); |
355 | |
356 | rb->allocate_blur_textures(); |
357 | |
358 | RendererRD::BokehDOF::BokehBuffers buffers; |
359 | |
360 | // Textures we use |
361 | buffers.base_texture_size = rb->get_internal_size(); |
362 | buffers.secondary_texture = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, 0, 0); |
363 | buffers.half_texture[0] = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0, 0); |
364 | buffers.half_texture[1] = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, 0, 1); |
365 | |
366 | if (can_use_storage) { |
367 | for (uint32_t i = 0; i < rb->get_view_count(); i++) { |
368 | buffers.base_texture = rb->get_internal_texture(i); |
369 | buffers.depth_texture = rb->get_depth_texture(i); |
370 | |
371 | // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustum. |
372 | float z_near = p_render_data->scene_data->view_projection[i].get_z_near(); |
373 | float z_far = p_render_data->scene_data->view_projection[i].get_z_far(); |
374 | bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal); |
375 | }; |
376 | } else { |
377 | // Set framebuffers. |
378 | buffers.secondary_fb = rb->weight_buffers[1].fb; |
379 | buffers.half_fb[0] = rb->weight_buffers[2].fb; |
380 | buffers.half_fb[1] = rb->weight_buffers[3].fb; |
381 | buffers.weight_texture[0] = rb->weight_buffers[0].weight; |
382 | buffers.weight_texture[1] = rb->weight_buffers[1].weight; |
383 | buffers.weight_texture[2] = rb->weight_buffers[2].weight; |
384 | buffers.weight_texture[3] = rb->weight_buffers[3].weight; |
385 | |
386 | // Set weight buffers. |
387 | buffers.base_weight_fb = rb->weight_buffers[0].fb; |
388 | |
389 | for (uint32_t i = 0; i < rb->get_view_count(); i++) { |
390 | buffers.base_texture = rb->get_internal_texture(i); |
391 | buffers.depth_texture = rb->get_depth_texture(i); |
392 | buffers.base_fb = FramebufferCacheRD::get_singleton()->get_cache(buffers.base_texture); // TODO move this into bokeh_dof_raster, we can do this internally |
393 | |
394 | // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustum. |
395 | float z_near = p_render_data->scene_data->view_projection[i].get_z_near(); |
396 | float z_far = p_render_data->scene_data->view_projection[i].get_z_far(); |
397 | bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal); |
398 | } |
399 | } |
400 | RD::get_singleton()->draw_command_end_label(); |
401 | } |
402 | |
403 | float auto_exposure_scale = 1.0; |
404 | |
405 | if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes)) { |
406 | RENDER_TIMESTAMP("Auto exposure" ); |
407 | |
408 | RD::get_singleton()->draw_command_begin_label("Auto exposure" ); |
409 | |
410 | Ref<RendererRD::Luminance::LuminanceBuffers> luminance_buffers = luminance->get_luminance_buffers(rb); |
411 | |
412 | uint64_t auto_exposure_version = RSG::camera_attributes->camera_attributes_get_auto_exposure_version(p_render_data->camera_attributes); |
413 | bool set_immediate = auto_exposure_version != rb->get_auto_exposure_version(); |
414 | rb->set_auto_exposure_version(auto_exposure_version); |
415 | |
416 | double step = RSG::camera_attributes->camera_attributes_get_auto_exposure_adjust_speed(p_render_data->camera_attributes) * time_step; |
417 | float auto_exposure_min_sensitivity = RSG::camera_attributes->camera_attributes_get_auto_exposure_min_sensitivity(p_render_data->camera_attributes); |
418 | float auto_exposure_max_sensitivity = RSG::camera_attributes->camera_attributes_get_auto_exposure_max_sensitivity(p_render_data->camera_attributes); |
419 | luminance->luminance_reduction(internal_texture, internal_size, luminance_buffers, auto_exposure_min_sensitivity, auto_exposure_max_sensitivity, step, set_immediate); |
420 | |
421 | // Swap final reduce with prev luminance. |
422 | |
423 | auto_exposure_scale = RSG::camera_attributes->camera_attributes_get_auto_exposure_scale(p_render_data->camera_attributes); |
424 | |
425 | RenderingServerDefault::redraw_request(); // Redraw all the time if auto exposure rendering is on. |
426 | RD::get_singleton()->draw_command_end_label(); |
427 | } |
428 | |
429 | int max_glow_level = -1; |
430 | |
431 | if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { |
432 | RENDER_TIMESTAMP("Glow" ); |
433 | RD::get_singleton()->draw_command_begin_label("Gaussian Glow" ); |
434 | |
435 | rb->allocate_blur_textures(); |
436 | |
437 | for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { |
438 | if (environment_get_glow_levels(p_render_data->environment)[i] > 0.0) { |
439 | int mipmaps = int(rb->get_texture_format(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1).mipmaps); |
440 | if (i >= mipmaps) { |
441 | max_glow_level = mipmaps - 1; |
442 | } else { |
443 | max_glow_level = i; |
444 | } |
445 | } |
446 | } |
447 | |
448 | float luminance_multiplier = _render_buffers_get_luminance_multiplier(); |
449 | for (uint32_t l = 0; l < rb->get_view_count(); l++) { |
450 | for (int i = 0; i < (max_glow_level + 1); i++) { |
451 | Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, i); |
452 | |
453 | if (i == 0) { |
454 | RID luminance_texture; |
455 | if (RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes)) { |
456 | luminance_texture = luminance->get_current_luminance_buffer(rb); // this will return and empty RID if we don't have an auto exposure buffer |
457 | } |
458 | RID source = rb->get_internal_texture(l); |
459 | RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i); |
460 | if (can_use_storage) { |
461 | copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment), true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale); |
462 | } else { |
463 | RID half = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, 0, i); // we can reuse this for each view |
464 | copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment), true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, auto_exposure_scale); |
465 | } |
466 | } else { |
467 | RID source = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i - 1); |
468 | RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i); |
469 | |
470 | if (can_use_storage) { |
471 | copy_effects->gaussian_glow(source, dest, vp_size, environment_get_glow_strength(p_render_data->environment)); |
472 | } else { |
473 | RID half = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, 0, i); // we can reuse this for each view |
474 | copy_effects->gaussian_glow_raster(source, half, dest, luminance_multiplier, vp_size, environment_get_glow_strength(p_render_data->environment)); |
475 | } |
476 | } |
477 | } |
478 | } |
479 | |
480 | RD::get_singleton()->draw_command_end_label(); |
481 | } |
482 | |
483 | { |
484 | RENDER_TIMESTAMP("Tonemap" ); |
485 | RD::get_singleton()->draw_command_begin_label("Tonemap" ); |
486 | |
487 | RendererRD::ToneMapper::TonemapSettings tonemap; |
488 | |
489 | tonemap.exposure_texture = luminance->get_current_luminance_buffer(rb); |
490 | if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes) && tonemap.exposure_texture.is_valid()) { |
491 | tonemap.use_auto_exposure = true; |
492 | tonemap.auto_exposure_scale = auto_exposure_scale; |
493 | } else { |
494 | tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); |
495 | } |
496 | |
497 | if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { |
498 | tonemap.use_glow = true; |
499 | tonemap.glow_mode = RendererRD::ToneMapper::TonemapSettings::GlowMode(environment_get_glow_blend_mode(p_render_data->environment)); |
500 | tonemap.glow_intensity = environment_get_glow_blend_mode(p_render_data->environment) == RS::ENV_GLOW_BLEND_MODE_MIX ? environment_get_glow_mix(p_render_data->environment) : environment_get_glow_intensity(p_render_data->environment); |
501 | for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { |
502 | tonemap.glow_levels[i] = environment_get_glow_levels(p_render_data->environment)[i]; |
503 | } |
504 | |
505 | Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0); |
506 | tonemap.glow_texture_size.x = msize.width; |
507 | tonemap.glow_texture_size.y = msize.height; |
508 | tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; |
509 | tonemap.glow_texture = rb->get_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1); |
510 | if (environment_get_glow_map(p_render_data->environment).is_valid()) { |
511 | tonemap.glow_map_strength = environment_get_glow_map_strength(p_render_data->environment); |
512 | tonemap.glow_map = texture_storage->texture_get_rd_texture(environment_get_glow_map(p_render_data->environment)); |
513 | } else { |
514 | tonemap.glow_map_strength = 0.0f; |
515 | tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); |
516 | } |
517 | |
518 | } else { |
519 | tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); |
520 | tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); |
521 | } |
522 | |
523 | if (rb->get_screen_space_aa() == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { |
524 | tonemap.use_fxaa = true; |
525 | } |
526 | |
527 | tonemap.use_debanding = rb->get_use_debanding(); |
528 | tonemap.texture_size = Vector2i(rb->get_internal_size().x, rb->get_internal_size().y); |
529 | |
530 | if (p_render_data->environment.is_valid()) { |
531 | tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); |
532 | tonemap.white = environment_get_white(p_render_data->environment); |
533 | tonemap.exposure = environment_get_exposure(p_render_data->environment); |
534 | } |
535 | |
536 | tonemap.use_color_correction = false; |
537 | tonemap.use_1d_color_correction = false; |
538 | tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); |
539 | |
540 | if (can_use_effects && p_render_data->environment.is_valid()) { |
541 | tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); |
542 | tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); |
543 | tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); |
544 | tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); |
545 | if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { |
546 | tonemap.use_color_correction = true; |
547 | tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); |
548 | tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); |
549 | } |
550 | } |
551 | |
552 | tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); |
553 | tonemap.view_count = rb->get_view_count(); |
554 | |
555 | tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(render_target); |
556 | |
557 | RID dest_fb; |
558 | if (fsr && can_use_effects && rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_FSR) { |
559 | // If we use FSR to upscale we need to write our result into an intermediate buffer. |
560 | // Note that this is cached so we only create the texture the first time. |
561 | RID dest_texture = rb->create_texture(SNAME("Tonemapper" ), SNAME("destination" ), _render_buffers_get_color_format(), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); |
562 | dest_fb = FramebufferCacheRD::get_singleton()->get_cache(dest_texture); |
563 | } else { |
564 | // If we do a bilinear upscale we just render into our render target and our shader will upscale automatically. |
565 | // Target size in this case is lying as we never get our real target size communicated. |
566 | // Bit nasty but... |
567 | dest_fb = texture_storage->render_target_get_rd_framebuffer(render_target); |
568 | } |
569 | |
570 | tone_mapper->tonemapper(internal_texture, dest_fb, tonemap); |
571 | |
572 | RD::get_singleton()->draw_command_end_label(); |
573 | } |
574 | |
575 | if (fsr && can_use_effects && rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_FSR) { |
576 | RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale" ); |
577 | |
578 | for (uint32_t v = 0; v < rb->get_view_count(); v++) { |
579 | RID source_texture = rb->get_texture_slice(SNAME("Tonemapper" ), SNAME("destination" ), v, 0); |
580 | RID dest_texture = texture_storage->render_target_get_rd_texture_slice(render_target, v); |
581 | |
582 | fsr->fsr_upscale(rb, source_texture, dest_texture); |
583 | } |
584 | |
585 | RD::get_singleton()->draw_command_end_label(); |
586 | } |
587 | |
588 | texture_storage->render_target_disable_clear_request(render_target); |
589 | } |
590 | |
591 | void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) { |
592 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
593 | RD::get_singleton()->draw_command_begin_label("Post Process Subpass" ); |
594 | |
595 | Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; |
596 | ERR_FAIL_COND(rb.is_null()); |
597 | |
598 | // FIXME: Our input it our internal_texture, shouldn't this be using internal_size ?? |
599 | // Seeing we don't support FSR in our mobile renderer right now target_size = internal_size... |
600 | Size2i target_size = rb->get_target_size(); |
601 | bool can_use_effects = target_size.x >= 8 && target_size.y >= 8; |
602 | |
603 | RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass(); |
604 | |
605 | RendererRD::ToneMapper::TonemapSettings tonemap; |
606 | |
607 | if (p_render_data->environment.is_valid()) { |
608 | tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); |
609 | tonemap.exposure = environment_get_exposure(p_render_data->environment); |
610 | tonemap.white = environment_get_white(p_render_data->environment); |
611 | } |
612 | |
613 | // We don't support glow or auto exposure here, if they are needed, don't use subpasses! |
614 | // The problem is that we need to use the result so far and process them before we can |
615 | // apply this to our results. |
616 | if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { |
617 | ERR_FAIL_MSG("Glow is not supported when using subpasses." ); |
618 | } |
619 | |
620 | if (can_use_effects && RSG::camera_attributes->camera_attributes_uses_auto_exposure(p_render_data->camera_attributes)) { |
621 | ERR_FAIL_MSG("Auto Exposure is not supported when using subpasses." ); |
622 | } |
623 | |
624 | tonemap.use_glow = false; |
625 | tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); |
626 | tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); |
627 | tonemap.use_auto_exposure = false; |
628 | tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE); |
629 | |
630 | tonemap.use_color_correction = false; |
631 | tonemap.use_1d_color_correction = false; |
632 | tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE); |
633 | |
634 | if (can_use_effects && p_render_data->environment.is_valid()) { |
635 | tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); |
636 | tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); |
637 | tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); |
638 | tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); |
639 | if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { |
640 | tonemap.use_color_correction = true; |
641 | tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); |
642 | tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); |
643 | } |
644 | } |
645 | |
646 | tonemap.use_debanding = rb->get_use_debanding(); |
647 | tonemap.texture_size = Vector2i(target_size.x, target_size.y); |
648 | |
649 | tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); |
650 | tonemap.view_count = rb->get_view_count(); |
651 | |
652 | tonemap.convert_to_srgb = !texture_storage->render_target_is_using_hdr(rb->get_render_target()); |
653 | |
654 | tone_mapper->tonemapper(draw_list, p_source_texture, RD::get_singleton()->framebuffer_get_format(p_framebuffer), tonemap); |
655 | |
656 | RD::get_singleton()->draw_command_end_label(); |
657 | } |
658 | |
659 | void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_data) { |
660 | ERR_FAIL_COND(p_render_data->render_buffers.is_null()); |
661 | |
662 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
663 | texture_storage->render_target_disable_clear_request(p_render_data->render_buffers->get_render_target()); |
664 | } |
665 | |
666 | void RendererSceneRenderRD::_render_buffers_debug_draw(const RenderDataRD *p_render_data) { |
667 | RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); |
668 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
669 | |
670 | Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; |
671 | ERR_FAIL_COND(rb.is_null()); |
672 | |
673 | RID render_target = rb->get_render_target(); |
674 | |
675 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS) { |
676 | if (p_render_data->shadow_atlas.is_valid()) { |
677 | RID shadow_atlas_texture = RendererRD::LightStorage::get_singleton()->shadow_atlas_get_texture(p_render_data->shadow_atlas); |
678 | |
679 | if (shadow_atlas_texture.is_null()) { |
680 | shadow_atlas_texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK); |
681 | } |
682 | |
683 | Size2 rtsize = texture_storage->render_target_get_size(render_target); |
684 | copy_effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize / 2), false, true); |
685 | } |
686 | } |
687 | |
688 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS) { |
689 | if (RendererRD::LightStorage::get_singleton()->directional_shadow_get_texture().is_valid()) { |
690 | RID shadow_atlas_texture = RendererRD::LightStorage::get_singleton()->directional_shadow_get_texture(); |
691 | Size2i rtsize = texture_storage->render_target_get_size(render_target); |
692 | RID dest_fb = texture_storage->render_target_get_rd_framebuffer(render_target); |
693 | |
694 | // Determine our display size, try and keep square by using the smallest edge. |
695 | Size2i size = 2 * rtsize / 3; |
696 | if (size.x < size.y) { |
697 | size.y = size.x; |
698 | } else if (size.y < size.x) { |
699 | size.x = size.y; |
700 | } |
701 | |
702 | copy_effects->copy_to_fb_rect(shadow_atlas_texture, dest_fb, Rect2i(Vector2(), size), false, true); |
703 | |
704 | // Visualize our view frustum to show coverage. |
705 | for (int i = 0; i < p_render_data->render_shadow_count; i++) { |
706 | RID light = p_render_data->render_shadows[i].light; |
707 | RID base = light_storage->light_instance_get_base_light(light); |
708 | |
709 | if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) { |
710 | debug_effects->draw_shadow_frustum(light, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, dest_fb, Rect2(Size2(), size)); |
711 | } |
712 | } |
713 | } |
714 | } |
715 | |
716 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) { |
717 | RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture(); |
718 | |
719 | if (decal_atlas.is_valid()) { |
720 | Size2i rtsize = texture_storage->render_target_get_size(render_target); |
721 | |
722 | copy_effects->copy_to_fb_rect(decal_atlas, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize / 2), false, false, true); |
723 | } |
724 | } |
725 | |
726 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE) { |
727 | RID luminance_texture = luminance->get_current_luminance_buffer(rb); |
728 | if (luminance_texture.is_valid()) { |
729 | Size2i rtsize = texture_storage->render_target_get_size(render_target); |
730 | |
731 | copy_effects->copy_to_fb_rect(luminance_texture, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize / 8), false, true); |
732 | } |
733 | } |
734 | |
735 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(rb).is_valid()) { |
736 | Size2 rtsize = texture_storage->render_target_get_size(render_target); |
737 | copy_effects->copy_to_fb_rect(_render_buffers_get_normal_texture(rb), texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false); |
738 | } |
739 | |
740 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) { |
741 | if (p_render_data->occluder_debug_tex.is_valid()) { |
742 | Size2i rtsize = texture_storage->render_target_get_size(render_target); |
743 | copy_effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_render_data->occluder_debug_tex), texture_storage->render_target_get_rd_framebuffer(render_target), Rect2i(Vector2(), rtsize), true, false); |
744 | } |
745 | } |
746 | |
747 | if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS && _render_buffers_get_velocity_texture(rb).is_valid()) { |
748 | debug_effects->draw_motion_vectors(_render_buffers_get_velocity_texture(rb), texture_storage->render_target_get_rd_framebuffer(render_target), rb->get_internal_size()); |
749 | } |
750 | } |
751 | |
752 | RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { |
753 | return gi.default_voxel_gi_buffer; |
754 | } |
755 | |
756 | float RendererSceneRenderRD::_render_buffers_get_luminance_multiplier() { |
757 | return 1.0; |
758 | } |
759 | |
760 | RD::DataFormat RendererSceneRenderRD::_render_buffers_get_color_format() { |
761 | return RD::DATA_FORMAT_R16G16B16A16_SFLOAT; |
762 | } |
763 | |
764 | bool RendererSceneRenderRD::_render_buffers_can_be_storage() { |
765 | return true; |
766 | } |
767 | |
768 | void RendererSceneRenderRD::gi_set_use_half_resolution(bool p_enable) { |
769 | gi.half_resolution = p_enable; |
770 | } |
771 | |
772 | void RendererSceneRenderRD::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) { |
773 | ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum" ); |
774 | |
775 | if (shadows_quality != p_quality) { |
776 | shadows_quality = p_quality; |
777 | |
778 | switch (shadows_quality) { |
779 | case RS::SHADOW_QUALITY_HARD: { |
780 | penumbra_shadow_samples = 4; |
781 | soft_shadow_samples = 0; |
782 | shadows_quality_radius = 1.0; |
783 | } break; |
784 | case RS::SHADOW_QUALITY_SOFT_VERY_LOW: { |
785 | penumbra_shadow_samples = 4; |
786 | soft_shadow_samples = 1; |
787 | shadows_quality_radius = 1.5; |
788 | } break; |
789 | case RS::SHADOW_QUALITY_SOFT_LOW: { |
790 | penumbra_shadow_samples = 8; |
791 | soft_shadow_samples = 4; |
792 | shadows_quality_radius = 2.0; |
793 | } break; |
794 | case RS::SHADOW_QUALITY_SOFT_MEDIUM: { |
795 | penumbra_shadow_samples = 12; |
796 | soft_shadow_samples = 8; |
797 | shadows_quality_radius = 2.0; |
798 | } break; |
799 | case RS::SHADOW_QUALITY_SOFT_HIGH: { |
800 | penumbra_shadow_samples = 24; |
801 | soft_shadow_samples = 16; |
802 | shadows_quality_radius = 3.0; |
803 | } break; |
804 | case RS::SHADOW_QUALITY_SOFT_ULTRA: { |
805 | penumbra_shadow_samples = 32; |
806 | soft_shadow_samples = 32; |
807 | shadows_quality_radius = 4.0; |
808 | } break; |
809 | case RS::SHADOW_QUALITY_MAX: |
810 | break; |
811 | } |
812 | get_vogel_disk(penumbra_shadow_kernel, penumbra_shadow_samples); |
813 | get_vogel_disk(soft_shadow_kernel, soft_shadow_samples); |
814 | } |
815 | |
816 | _update_shader_quality_settings(); |
817 | } |
818 | |
819 | void RendererSceneRenderRD::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) { |
820 | ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum" ); |
821 | |
822 | if (directional_shadow_quality != p_quality) { |
823 | directional_shadow_quality = p_quality; |
824 | |
825 | switch (directional_shadow_quality) { |
826 | case RS::SHADOW_QUALITY_HARD: { |
827 | directional_penumbra_shadow_samples = 4; |
828 | directional_soft_shadow_samples = 0; |
829 | directional_shadow_quality_radius = 1.0; |
830 | } break; |
831 | case RS::SHADOW_QUALITY_SOFT_VERY_LOW: { |
832 | directional_penumbra_shadow_samples = 4; |
833 | directional_soft_shadow_samples = 1; |
834 | directional_shadow_quality_radius = 1.5; |
835 | } break; |
836 | case RS::SHADOW_QUALITY_SOFT_LOW: { |
837 | directional_penumbra_shadow_samples = 8; |
838 | directional_soft_shadow_samples = 4; |
839 | directional_shadow_quality_radius = 2.0; |
840 | } break; |
841 | case RS::SHADOW_QUALITY_SOFT_MEDIUM: { |
842 | directional_penumbra_shadow_samples = 12; |
843 | directional_soft_shadow_samples = 8; |
844 | directional_shadow_quality_radius = 2.0; |
845 | } break; |
846 | case RS::SHADOW_QUALITY_SOFT_HIGH: { |
847 | directional_penumbra_shadow_samples = 24; |
848 | directional_soft_shadow_samples = 16; |
849 | directional_shadow_quality_radius = 3.0; |
850 | } break; |
851 | case RS::SHADOW_QUALITY_SOFT_ULTRA: { |
852 | directional_penumbra_shadow_samples = 32; |
853 | directional_soft_shadow_samples = 32; |
854 | directional_shadow_quality_radius = 4.0; |
855 | } break; |
856 | case RS::SHADOW_QUALITY_MAX: |
857 | break; |
858 | } |
859 | get_vogel_disk(directional_penumbra_shadow_kernel, directional_penumbra_shadow_samples); |
860 | get_vogel_disk(directional_soft_shadow_kernel, directional_soft_shadow_samples); |
861 | } |
862 | |
863 | _update_shader_quality_settings(); |
864 | } |
865 | |
866 | void RendererSceneRenderRD::decals_set_filter(RenderingServer::DecalFilter p_filter) { |
867 | if (decals_filter == p_filter) { |
868 | return; |
869 | } |
870 | decals_filter = p_filter; |
871 | _update_shader_quality_settings(); |
872 | } |
873 | void RendererSceneRenderRD::light_projectors_set_filter(RenderingServer::LightProjectorFilter p_filter) { |
874 | if (light_projectors_filter == p_filter) { |
875 | return; |
876 | } |
877 | light_projectors_filter = p_filter; |
878 | _update_shader_quality_settings(); |
879 | } |
880 | |
881 | int RendererSceneRenderRD::get_roughness_layers() const { |
882 | return sky.roughness_layers; |
883 | } |
884 | |
885 | bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const { |
886 | return sky.sky_use_cubemap_array; |
887 | } |
888 | |
889 | void RendererSceneRenderRD::_update_vrs(Ref<RenderSceneBuffersRD> p_render_buffers) { |
890 | if (p_render_buffers.is_null()) { |
891 | return; |
892 | } |
893 | |
894 | RID render_target = p_render_buffers->get_render_target(); |
895 | if (render_target.is_null()) { |
896 | // must be rendering reflection probes |
897 | return; |
898 | } |
899 | |
900 | if (vrs) { |
901 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
902 | |
903 | RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(render_target); |
904 | if (vrs_mode != RS::VIEWPORT_VRS_DISABLED) { |
905 | RID vrs_texture = p_render_buffers->get_texture(RB_SCOPE_VRS, RB_TEXTURE); |
906 | |
907 | // We use get_cache_multipass instead of get_cache_multiview because the default behavior is for |
908 | // our vrs_texture to be used as the VRS attachment. In this particular case we're writing to it |
909 | // so it needs to be set as our color attachment |
910 | |
911 | Vector<RID> textures; |
912 | textures.push_back(vrs_texture); |
913 | |
914 | Vector<RD::FramebufferPass> passes; |
915 | RD::FramebufferPass pass; |
916 | pass.color_attachments.push_back(0); |
917 | passes.push_back(pass); |
918 | |
919 | RID vrs_fb = FramebufferCacheRD::get_singleton()->get_cache_multipass(textures, passes, p_render_buffers->get_view_count()); |
920 | |
921 | vrs->update_vrs_texture(vrs_fb, p_render_buffers->get_render_target()); |
922 | } |
923 | } |
924 | } |
925 | |
926 | bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { |
927 | if (p_render_data->render_buffers.is_valid()) { |
928 | if (p_render_data->render_buffers->has_custom_data(RB_SCOPE_SDFGI)) { |
929 | return true; |
930 | } |
931 | } |
932 | return false; |
933 | } |
934 | |
935 | void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { |
936 | if (p_render_data->render_buffers.is_valid() && p_use_gi) { |
937 | if (!p_render_data->render_buffers->has_custom_data(RB_SCOPE_SDFGI)) { |
938 | return; |
939 | } |
940 | |
941 | Ref<RendererRD::GI::SDFGI> sdfgi = p_render_data->render_buffers->get_custom_data(RB_SCOPE_SDFGI); |
942 | sdfgi->update_probes(p_render_data->environment, sky.sky_owner.get_or_null(environment_get_sky(p_render_data->environment))); |
943 | } |
944 | } |
945 | |
946 | void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi) { |
947 | if (p_render_data->render_buffers.is_valid()) { |
948 | if (p_use_gi) { |
949 | RD::get_singleton()->compute_list_end(); |
950 | } |
951 | } |
952 | } |
953 | |
954 | void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) { |
955 | RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); |
956 | RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); |
957 | |
958 | // getting this here now so we can direct call a bunch of things more easily |
959 | ERR_FAIL_COND(p_render_buffers.is_null()); |
960 | Ref<RenderSceneBuffersRD> rb = p_render_buffers; |
961 | ERR_FAIL_COND(rb.is_null()); |
962 | |
963 | // setup scene data |
964 | RenderSceneDataRD scene_data; |
965 | { |
966 | // Our first camera is used by default |
967 | scene_data.cam_transform = p_camera_data->main_transform; |
968 | scene_data.cam_projection = p_camera_data->main_projection; |
969 | scene_data.cam_orthogonal = p_camera_data->is_orthogonal; |
970 | scene_data.camera_visible_layers = p_camera_data->visible_layers; |
971 | scene_data.taa_jitter = p_camera_data->taa_jitter; |
972 | |
973 | scene_data.view_count = p_camera_data->view_count; |
974 | for (uint32_t v = 0; v < p_camera_data->view_count; v++) { |
975 | scene_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin; |
976 | scene_data.view_projection[v] = p_camera_data->view_projection[v]; |
977 | } |
978 | |
979 | scene_data.prev_cam_transform = p_prev_camera_data->main_transform; |
980 | scene_data.prev_cam_projection = p_prev_camera_data->main_projection; |
981 | scene_data.prev_taa_jitter = p_prev_camera_data->taa_jitter; |
982 | |
983 | for (uint32_t v = 0; v < p_camera_data->view_count; v++) { |
984 | scene_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v]; |
985 | } |
986 | |
987 | scene_data.z_near = p_camera_data->main_projection.get_z_near(); |
988 | scene_data.z_far = p_camera_data->main_projection.get_z_far(); |
989 | |
990 | // this should be the same for all cameras.. |
991 | const float lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier(); |
992 | |
993 | // Also, take into account resolution scaling for the multiplier, since we have more leeway with quality |
994 | // degradation visibility. Conversely, allow upwards scaling, too, for increased mesh detail at high res. |
995 | const float scaling_3d_scale = GLOBAL_GET("rendering/scaling_3d/scale" ); |
996 | scene_data.lod_distance_multiplier = lod_distance_multiplier * (1.0 / scaling_3d_scale); |
997 | |
998 | if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { |
999 | scene_data.screen_mesh_lod_threshold = 0.0; |
1000 | } else { |
1001 | scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; |
1002 | } |
1003 | |
1004 | if (p_shadow_atlas.is_valid()) { |
1005 | int shadow_atlas_size = light_storage->shadow_atlas_get_size(p_shadow_atlas); |
1006 | scene_data.shadow_atlas_pixel_size.x = 1.0 / shadow_atlas_size; |
1007 | scene_data.shadow_atlas_pixel_size.y = 1.0 / shadow_atlas_size; |
1008 | } |
1009 | { |
1010 | int directional_shadow_size = light_storage->directional_shadow_get_size(); |
1011 | scene_data.directional_shadow_pixel_size.x = 1.0 / directional_shadow_size; |
1012 | scene_data.directional_shadow_pixel_size.y = 1.0 / directional_shadow_size; |
1013 | } |
1014 | |
1015 | scene_data.time = time; |
1016 | scene_data.time_step = time_step; |
1017 | } |
1018 | |
1019 | //assign render data |
1020 | RenderDataRD render_data; |
1021 | { |
1022 | render_data.render_buffers = rb; |
1023 | render_data.scene_data = &scene_data; |
1024 | |
1025 | render_data.instances = &p_instances; |
1026 | render_data.lights = &p_lights; |
1027 | render_data.reflection_probes = &p_reflection_probes; |
1028 | render_data.voxel_gi_instances = &p_voxel_gi_instances; |
1029 | render_data.decals = &p_decals; |
1030 | render_data.lightmaps = &p_lightmaps; |
1031 | render_data.fog_volumes = &p_fog_volumes; |
1032 | render_data.environment = p_environment; |
1033 | render_data.camera_attributes = p_camera_attributes; |
1034 | render_data.shadow_atlas = p_shadow_atlas; |
1035 | render_data.occluder_debug_tex = p_occluder_debug_tex; |
1036 | render_data.reflection_atlas = p_reflection_atlas; |
1037 | render_data.reflection_probe = p_reflection_probe; |
1038 | render_data.reflection_probe_pass = p_reflection_probe_pass; |
1039 | |
1040 | render_data.render_shadows = p_render_shadows; |
1041 | render_data.render_shadow_count = p_render_shadow_count; |
1042 | render_data.render_sdfgi_regions = p_render_sdfgi_regions; |
1043 | render_data.render_sdfgi_region_count = p_render_sdfgi_region_count; |
1044 | render_data.sdfgi_update_data = p_sdfgi_update_data; |
1045 | |
1046 | render_data.render_info = r_render_info; |
1047 | } |
1048 | |
1049 | PagedArray<RID> empty; |
1050 | |
1051 | if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { |
1052 | render_data.lights = ∅ |
1053 | render_data.reflection_probes = ∅ |
1054 | render_data.voxel_gi_instances = ∅ |
1055 | } |
1056 | |
1057 | Color clear_color; |
1058 | if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) { |
1059 | clear_color = texture_storage->render_target_get_clear_request_color(rb->get_render_target()); |
1060 | } else { |
1061 | clear_color = RSG::texture_storage->get_default_clear_color(); |
1062 | } |
1063 | |
1064 | //calls _pre_opaque_render between depth pre-pass and opaque pass |
1065 | _render_scene(&render_data, clear_color); |
1066 | } |
1067 | |
1068 | void RendererSceneRenderRD::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) { |
1069 | _render_material(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_instances, p_framebuffer, p_region, 1.0); |
1070 | } |
1071 | |
1072 | void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { |
1073 | RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); |
1074 | |
1075 | ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider)); |
1076 | Vector3 extents = particles_storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); |
1077 | Projection cm; |
1078 | cm.set_orthogonal(-extents.x, extents.x, -extents.z, extents.z, 0, extents.y * 2.0); |
1079 | |
1080 | Vector3 cam_pos = p_transform.origin; |
1081 | cam_pos.y += extents.y; |
1082 | |
1083 | Transform3D cam_xform; |
1084 | cam_xform.set_look_at(cam_pos, cam_pos - p_transform.basis.get_column(Vector3::AXIS_Y), -p_transform.basis.get_column(Vector3::AXIS_Z).normalized()); |
1085 | |
1086 | RID fb = particles_storage->particles_collision_get_heightfield_framebuffer(p_collider); |
1087 | |
1088 | _render_particle_collider_heightfield(fb, cam_xform, cm, p_instances); |
1089 | } |
1090 | |
1091 | bool RendererSceneRenderRD::free(RID p_rid) { |
1092 | if (is_environment(p_rid)) { |
1093 | environment_free(p_rid); |
1094 | } else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) { |
1095 | RSG::camera_attributes->camera_attributes_free(p_rid); |
1096 | } else if (gi.voxel_gi_instance_owns(p_rid)) { |
1097 | gi.voxel_gi_instance_free(p_rid); |
1098 | } else if (sky.sky_owner.owns(p_rid)) { |
1099 | sky.update_dirty_skys(); |
1100 | sky.free_sky(p_rid); |
1101 | } else if (RendererRD::Fog::get_singleton()->owns_fog_volume_instance(p_rid)) { |
1102 | RendererRD::Fog::get_singleton()->fog_instance_free(p_rid); |
1103 | } else { |
1104 | return false; |
1105 | } |
1106 | |
1107 | return true; |
1108 | } |
1109 | |
1110 | void RendererSceneRenderRD::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) { |
1111 | debug_draw = p_debug_draw; |
1112 | } |
1113 | |
1114 | void RendererSceneRenderRD::update() { |
1115 | sky.update_dirty_skys(); |
1116 | } |
1117 | |
1118 | void RendererSceneRenderRD::set_time(double p_time, double p_step) { |
1119 | time = p_time; |
1120 | time_step = p_step; |
1121 | } |
1122 | |
1123 | void RendererSceneRenderRD::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) { |
1124 | screen_space_roughness_limiter = p_enable; |
1125 | screen_space_roughness_limiter_amount = p_amount; |
1126 | screen_space_roughness_limiter_limit = p_limit; |
1127 | } |
1128 | |
1129 | bool RendererSceneRenderRD::screen_space_roughness_limiter_is_active() const { |
1130 | return screen_space_roughness_limiter; |
1131 | } |
1132 | |
1133 | float RendererSceneRenderRD::screen_space_roughness_limiter_get_amount() const { |
1134 | return screen_space_roughness_limiter_amount; |
1135 | } |
1136 | |
1137 | float RendererSceneRenderRD::screen_space_roughness_limiter_get_limit() const { |
1138 | return screen_space_roughness_limiter_limit; |
1139 | } |
1140 | |
1141 | TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) { |
1142 | ERR_FAIL_COND_V_MSG(p_image_size.width <= 0, TypedArray<Image>(), "Image width must be greater than 0." ); |
1143 | ERR_FAIL_COND_V_MSG(p_image_size.height <= 0, TypedArray<Image>(), "Image height must be greater than 0." ); |
1144 | RD::TextureFormat tf; |
1145 | tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; |
1146 | tf.width = p_image_size.width; // Always 64x64 |
1147 | tf.height = p_image_size.height; |
1148 | tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; |
1149 | |
1150 | RID albedo_alpha_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
1151 | RID normal_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
1152 | RID orm_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
1153 | |
1154 | tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; |
1155 | RID emission_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
1156 | |
1157 | tf.format = RD::DATA_FORMAT_R32_SFLOAT; |
1158 | RID depth_write_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
1159 | |
1160 | tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; |
1161 | tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; |
1162 | RID depth_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); |
1163 | |
1164 | Vector<RID> fb_tex; |
1165 | fb_tex.push_back(albedo_alpha_tex); |
1166 | fb_tex.push_back(normal_tex); |
1167 | fb_tex.push_back(orm_tex); |
1168 | fb_tex.push_back(emission_tex); |
1169 | fb_tex.push_back(depth_write_tex); |
1170 | fb_tex.push_back(depth_tex); |
1171 | |
1172 | RID fb = RD::get_singleton()->framebuffer_create(fb_tex); |
1173 | |
1174 | //RID sampled_light; |
1175 | |
1176 | RenderGeometryInstance *gi_inst = geometry_instance_create(p_base); |
1177 | ERR_FAIL_NULL_V(gi_inst, TypedArray<Image>()); |
1178 | |
1179 | uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base); |
1180 | Vector<RID> materials; |
1181 | materials.resize(sc); |
1182 | |
1183 | for (uint32_t i = 0; i < sc; i++) { |
1184 | if (i < (uint32_t)p_material_overrides.size()) { |
1185 | materials.write[i] = p_material_overrides[i]; |
1186 | } |
1187 | } |
1188 | |
1189 | gi_inst->set_surface_materials(materials); |
1190 | |
1191 | if (cull_argument.size() == 0) { |
1192 | cull_argument.push_back(nullptr); |
1193 | } |
1194 | cull_argument[0] = gi_inst; |
1195 | _render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height)); |
1196 | |
1197 | geometry_instance_free(gi_inst); |
1198 | |
1199 | TypedArray<Image> ret; |
1200 | |
1201 | { |
1202 | PackedByteArray data = RD::get_singleton()->texture_get_data(albedo_alpha_tex, 0); |
1203 | Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); |
1204 | RD::get_singleton()->free(albedo_alpha_tex); |
1205 | ret.push_back(img); |
1206 | } |
1207 | |
1208 | { |
1209 | PackedByteArray data = RD::get_singleton()->texture_get_data(normal_tex, 0); |
1210 | Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); |
1211 | RD::get_singleton()->free(normal_tex); |
1212 | ret.push_back(img); |
1213 | } |
1214 | |
1215 | { |
1216 | PackedByteArray data = RD::get_singleton()->texture_get_data(orm_tex, 0); |
1217 | Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); |
1218 | RD::get_singleton()->free(orm_tex); |
1219 | ret.push_back(img); |
1220 | } |
1221 | |
1222 | { |
1223 | PackedByteArray data = RD::get_singleton()->texture_get_data(emission_tex, 0); |
1224 | Ref<Image> img = Image::create_from_data(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data); |
1225 | RD::get_singleton()->free(emission_tex); |
1226 | ret.push_back(img); |
1227 | } |
1228 | |
1229 | RD::get_singleton()->free(depth_write_tex); |
1230 | RD::get_singleton()->free(depth_tex); |
1231 | |
1232 | return ret; |
1233 | } |
1234 | |
1235 | void RendererSceneRenderRD::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) { |
1236 | gi.sdfgi_debug_probe_pos = p_position; |
1237 | gi.sdfgi_debug_probe_dir = p_dir; |
1238 | } |
1239 | |
1240 | RendererSceneRenderRD *RendererSceneRenderRD::singleton = nullptr; |
1241 | |
1242 | bool RendererSceneRenderRD::is_vrs_supported() const { |
1243 | return RD::get_singleton()->has_feature(RD::SUPPORTS_ATTACHMENT_VRS); |
1244 | } |
1245 | |
1246 | bool RendererSceneRenderRD::is_dynamic_gi_supported() const { |
1247 | // usable by default (unless low end = true) |
1248 | return true; |
1249 | } |
1250 | |
1251 | bool RendererSceneRenderRD::is_volumetric_supported() const { |
1252 | // usable by default (unless low end = true) |
1253 | return true; |
1254 | } |
1255 | |
1256 | uint32_t RendererSceneRenderRD::get_max_elements() const { |
1257 | return GLOBAL_GET("rendering/limits/cluster_builder/max_clustered_elements" ); |
1258 | } |
1259 | |
1260 | RendererSceneRenderRD::RendererSceneRenderRD() { |
1261 | singleton = this; |
1262 | } |
1263 | |
1264 | void RendererSceneRenderRD::init() { |
1265 | max_cluster_elements = get_max_elements(); |
1266 | RendererRD::LightStorage::get_singleton()->set_max_cluster_elements(max_cluster_elements); |
1267 | |
1268 | /* Forward ID */ |
1269 | forward_id_storage = create_forward_id_storage(); |
1270 | |
1271 | /* SKY SHADER */ |
1272 | |
1273 | sky.init(); |
1274 | |
1275 | /* GI */ |
1276 | |
1277 | if (is_dynamic_gi_supported()) { |
1278 | gi.init(&sky); |
1279 | } |
1280 | |
1281 | { //decals |
1282 | RendererRD::TextureStorage::get_singleton()->set_max_decals(max_cluster_elements); |
1283 | } |
1284 | |
1285 | { //lights |
1286 | } |
1287 | |
1288 | if (is_volumetric_supported()) { |
1289 | RendererRD::Fog::get_singleton()->init_fog_shader(RendererRD::LightStorage::get_singleton()->get_max_directional_lights(), get_roughness_layers(), is_using_radiance_cubemap_array()); |
1290 | } |
1291 | |
1292 | RSG::camera_attributes->camera_attributes_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape" )))); |
1293 | RSG::camera_attributes->camera_attributes_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality" ))), GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_use_jitter" )); |
1294 | use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units" ); |
1295 | |
1296 | screen_space_roughness_limiter = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/enabled" ); |
1297 | screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount" ); |
1298 | screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit" ); |
1299 | glow_bicubic_upscale = int(GLOBAL_GET("rendering/environment/glow/upscale_mode" )) > 0; |
1300 | |
1301 | directional_penumbra_shadow_kernel = memnew_arr(float, 128); |
1302 | directional_soft_shadow_kernel = memnew_arr(float, 128); |
1303 | penumbra_shadow_kernel = memnew_arr(float, 128); |
1304 | soft_shadow_kernel = memnew_arr(float, 128); |
1305 | positional_soft_shadow_filter_set_quality(RS::ShadowQuality(int(GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality" )))); |
1306 | directional_soft_shadow_filter_set_quality(RS::ShadowQuality(int(GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality" )))); |
1307 | |
1308 | environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size" ), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth" )); |
1309 | environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter" )); |
1310 | |
1311 | decals_set_filter(RS::DecalFilter(int(GLOBAL_GET("rendering/textures/decals/filter" )))); |
1312 | light_projectors_set_filter(RS::LightProjectorFilter(int(GLOBAL_GET("rendering/textures/light_projectors/filter" )))); |
1313 | |
1314 | cull_argument.set_page_pool(&cull_argument_pool); |
1315 | |
1316 | bool can_use_storage = _render_buffers_can_be_storage(); |
1317 | bool can_use_vrs = is_vrs_supported(); |
1318 | bokeh_dof = memnew(RendererRD::BokehDOF(!can_use_storage)); |
1319 | copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage)); |
1320 | debug_effects = memnew(RendererRD::DebugEffects); |
1321 | luminance = memnew(RendererRD::Luminance(!can_use_storage)); |
1322 | tone_mapper = memnew(RendererRD::ToneMapper); |
1323 | if (can_use_vrs) { |
1324 | vrs = memnew(RendererRD::VRS); |
1325 | } |
1326 | if (can_use_storage) { |
1327 | fsr = memnew(RendererRD::FSR); |
1328 | } |
1329 | } |
1330 | |
1331 | RendererSceneRenderRD::~RendererSceneRenderRD() { |
1332 | if (forward_id_storage) { |
1333 | memdelete(forward_id_storage); |
1334 | } |
1335 | |
1336 | if (bokeh_dof) { |
1337 | memdelete(bokeh_dof); |
1338 | } |
1339 | if (copy_effects) { |
1340 | memdelete(copy_effects); |
1341 | } |
1342 | if (debug_effects) { |
1343 | memdelete(debug_effects); |
1344 | } |
1345 | if (luminance) { |
1346 | memdelete(luminance); |
1347 | } |
1348 | if (tone_mapper) { |
1349 | memdelete(tone_mapper); |
1350 | } |
1351 | if (vrs) { |
1352 | memdelete(vrs); |
1353 | } |
1354 | if (fsr) { |
1355 | memdelete(fsr); |
1356 | } |
1357 | |
1358 | if (sky.sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky.sky_scene_state.uniform_set)) { |
1359 | RD::get_singleton()->free(sky.sky_scene_state.uniform_set); |
1360 | } |
1361 | |
1362 | if (is_dynamic_gi_supported()) { |
1363 | gi.free(); |
1364 | } |
1365 | |
1366 | if (is_volumetric_supported()) { |
1367 | RendererRD::Fog::get_singleton()->free_fog_shader(); |
1368 | } |
1369 | |
1370 | memdelete_arr(directional_penumbra_shadow_kernel); |
1371 | memdelete_arr(directional_soft_shadow_kernel); |
1372 | memdelete_arr(penumbra_shadow_kernel); |
1373 | memdelete_arr(soft_shadow_kernel); |
1374 | |
1375 | RSG::light_storage->directional_shadow_atlas_set_size(0); |
1376 | cull_argument.reset(); //avoid exit error |
1377 | } |
1378 | |