| 1 | /**************************************************************************/ |
| 2 | /* render_scene_data_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 "render_scene_data_rd.h" |
| 32 | #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" |
| 33 | #include "servers/rendering/renderer_rd/storage_rd/light_storage.h" |
| 34 | #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" |
| 35 | #include "servers/rendering/rendering_server_default.h" |
| 36 | |
| 37 | RID RenderSceneDataRD::create_uniform_buffer() { |
| 38 | return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA)); |
| 39 | } |
| 40 | |
| 41 | void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers) { |
| 42 | RendererSceneRenderRD *render_scene_render = RendererSceneRenderRD::get_singleton(); |
| 43 | |
| 44 | UBODATA ubo_data; |
| 45 | memset(&ubo_data, 0, sizeof(UBODATA)); |
| 46 | |
| 47 | // just for easy access.. |
| 48 | UBO &ubo = ubo_data.ubo; |
| 49 | UBO &prev_ubo = ubo_data.prev_ubo; |
| 50 | |
| 51 | Projection correction; |
| 52 | correction.set_depth_correction(p_flip_y); |
| 53 | correction.add_jitter_offset(taa_jitter); |
| 54 | Projection projection = correction * cam_projection; |
| 55 | |
| 56 | //store camera into ubo |
| 57 | RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix); |
| 58 | RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix); |
| 59 | RendererRD::MaterialStorage::store_transform(cam_transform, ubo.inv_view_matrix); |
| 60 | RendererRD::MaterialStorage::store_transform(cam_transform.affine_inverse(), ubo.view_matrix); |
| 61 | |
| 62 | #ifdef REAL_T_IS_DOUBLE |
| 63 | RendererRD::MaterialStorage::split_double(-cam_transform.origin.x, &ubo.inv_view_matrix[12], &ubo.inv_view_matrix[3]); |
| 64 | RendererRD::MaterialStorage::split_double(-cam_transform.origin.y, &ubo.inv_view_matrix[13], &ubo.inv_view_matrix[7]); |
| 65 | RendererRD::MaterialStorage::split_double(-cam_transform.origin.z, &ubo.inv_view_matrix[14], &ubo.inv_view_matrix[11]); |
| 66 | #endif |
| 67 | |
| 68 | for (uint32_t v = 0; v < view_count; v++) { |
| 69 | projection = correction * view_projection[v]; |
| 70 | RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix_view[v]); |
| 71 | RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix_view[v]); |
| 72 | |
| 73 | ubo.eye_offset[v][0] = view_eye_offset[v].x; |
| 74 | ubo.eye_offset[v][1] = view_eye_offset[v].y; |
| 75 | ubo.eye_offset[v][2] = view_eye_offset[v].z; |
| 76 | ubo.eye_offset[v][3] = 0.0; |
| 77 | } |
| 78 | |
| 79 | ubo.taa_jitter[0] = taa_jitter.x; |
| 80 | ubo.taa_jitter[1] = taa_jitter.y; |
| 81 | |
| 82 | ubo.z_far = z_far; |
| 83 | ubo.z_near = z_near; |
| 84 | |
| 85 | ubo.pancake_shadows = p_pancake_shadows; |
| 86 | |
| 87 | RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_penumbra_shadow_kernel_get(), ubo.directional_penumbra_shadow_kernel); |
| 88 | RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel); |
| 89 | RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel); |
| 90 | RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel); |
| 91 | ubo.camera_visible_layers = camera_visible_layers; |
| 92 | |
| 93 | ubo.viewport_size[0] = p_screen_size.x; |
| 94 | ubo.viewport_size[1] = p_screen_size.y; |
| 95 | |
| 96 | Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size); |
| 97 | ubo.screen_pixel_size[0] = screen_pixel_size.x; |
| 98 | ubo.screen_pixel_size[1] = screen_pixel_size.y; |
| 99 | |
| 100 | ubo.shadow_atlas_pixel_size[0] = shadow_atlas_pixel_size.x; |
| 101 | ubo.shadow_atlas_pixel_size[1] = shadow_atlas_pixel_size.y; |
| 102 | |
| 103 | ubo.directional_shadow_pixel_size[0] = directional_shadow_pixel_size.x; |
| 104 | ubo.directional_shadow_pixel_size[1] = directional_shadow_pixel_size.y; |
| 105 | |
| 106 | ubo.time = time; |
| 107 | |
| 108 | ubo.directional_light_count = directional_light_count; |
| 109 | ubo.dual_paraboloid_side = dual_paraboloid_side; |
| 110 | ubo.opaque_prepass_threshold = opaque_prepass_threshold; |
| 111 | ubo.material_uv2_mode = material_uv2_mode; |
| 112 | |
| 113 | ubo.fog_enabled = false; |
| 114 | |
| 115 | if (p_debug_mode == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { |
| 116 | ubo.use_ambient_light = true; |
| 117 | ubo.ambient_light_color_energy[0] = 1; |
| 118 | ubo.ambient_light_color_energy[1] = 1; |
| 119 | ubo.ambient_light_color_energy[2] = 1; |
| 120 | ubo.ambient_light_color_energy[3] = 1.0; |
| 121 | ubo.use_ambient_cubemap = false; |
| 122 | ubo.use_reflection_cubemap = false; |
| 123 | } else if (p_env.is_valid()) { |
| 124 | RS::EnvironmentBG env_bg = render_scene_render->environment_get_background(p_env); |
| 125 | RS::EnvironmentAmbientSource ambient_src = render_scene_render->environment_get_ambient_source(p_env); |
| 126 | |
| 127 | float bg_energy_multiplier = render_scene_render->environment_get_bg_energy_multiplier(p_env); |
| 128 | |
| 129 | ubo.ambient_light_color_energy[3] = bg_energy_multiplier; |
| 130 | |
| 131 | ubo.ambient_color_sky_mix = render_scene_render->environment_get_ambient_sky_contribution(p_env); |
| 132 | |
| 133 | //ambient |
| 134 | if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { |
| 135 | Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : render_scene_render->environment_get_bg_color(p_env); |
| 136 | color = color.srgb_to_linear(); |
| 137 | |
| 138 | ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; |
| 139 | ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; |
| 140 | ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; |
| 141 | ubo.use_ambient_light = true; |
| 142 | ubo.use_ambient_cubemap = false; |
| 143 | } else { |
| 144 | float energy = render_scene_render->environment_get_ambient_light_energy(p_env); |
| 145 | Color color = render_scene_render->environment_get_ambient_light(p_env); |
| 146 | color = color.srgb_to_linear(); |
| 147 | ubo.ambient_light_color_energy[0] = color.r * energy; |
| 148 | ubo.ambient_light_color_energy[1] = color.g * energy; |
| 149 | ubo.ambient_light_color_energy[2] = color.b * energy; |
| 150 | |
| 151 | Basis sky_transform = render_scene_render->environment_get_sky_orientation(p_env); |
| 152 | sky_transform = sky_transform.inverse() * cam_transform.basis; |
| 153 | RendererRD::MaterialStorage::store_transform_3x3(sky_transform, ubo.radiance_inverse_xform); |
| 154 | |
| 155 | ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; |
| 156 | ubo.use_ambient_light = ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; |
| 157 | } |
| 158 | |
| 159 | //specular |
| 160 | RS::EnvironmentReflectionSource ref_src = render_scene_render->environment_get_reflection_source(p_env); |
| 161 | if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { |
| 162 | ubo.use_reflection_cubemap = true; |
| 163 | } else { |
| 164 | ubo.use_reflection_cubemap = false; |
| 165 | } |
| 166 | |
| 167 | ubo.fog_enabled = render_scene_render->environment_get_fog_enabled(p_env); |
| 168 | ubo.fog_density = render_scene_render->environment_get_fog_density(p_env); |
| 169 | ubo.fog_height = render_scene_render->environment_get_fog_height(p_env); |
| 170 | ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env); |
| 171 | ubo.fog_aerial_perspective = render_scene_render->environment_get_fog_aerial_perspective(p_env); |
| 172 | |
| 173 | Color fog_color = render_scene_render->environment_get_fog_light_color(p_env).srgb_to_linear(); |
| 174 | float fog_energy = render_scene_render->environment_get_fog_light_energy(p_env); |
| 175 | |
| 176 | ubo.fog_light_color[0] = fog_color.r * fog_energy; |
| 177 | ubo.fog_light_color[1] = fog_color.g * fog_energy; |
| 178 | ubo.fog_light_color[2] = fog_color.b * fog_energy; |
| 179 | |
| 180 | ubo.fog_sun_scatter = render_scene_render->environment_get_fog_sun_scatter(p_env); |
| 181 | } else { |
| 182 | if (p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance)) { |
| 183 | ubo.use_ambient_light = false; |
| 184 | } else { |
| 185 | ubo.use_ambient_light = true; |
| 186 | Color clear_color = p_default_bg_color; |
| 187 | clear_color = clear_color.srgb_to_linear(); |
| 188 | ubo.ambient_light_color_energy[0] = clear_color.r; |
| 189 | ubo.ambient_light_color_energy[1] = clear_color.g; |
| 190 | ubo.ambient_light_color_energy[2] = clear_color.b; |
| 191 | ubo.ambient_light_color_energy[3] = 1.0; |
| 192 | } |
| 193 | |
| 194 | ubo.use_ambient_cubemap = false; |
| 195 | ubo.use_reflection_cubemap = false; |
| 196 | } |
| 197 | |
| 198 | if (p_camera_attributes.is_valid()) { |
| 199 | ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes); |
| 200 | ubo.IBL_exposure_normalization = 1.0; |
| 201 | if (p_env.is_valid()) { |
| 202 | RID sky_rid = render_scene_render->environment_get_sky(p_env); |
| 203 | if (sky_rid.is_valid()) { |
| 204 | float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes) * render_scene_render->environment_get_bg_intensity(p_env) / p_luminance_multiplier; |
| 205 | ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, render_scene_render->get_sky()->sky_get_baked_exposure(sky_rid)); |
| 206 | } |
| 207 | } |
| 208 | } else if (emissive_exposure_normalization > 0.0) { |
| 209 | // This branch is triggered when using render_material(). |
| 210 | // Emissive is set outside the function. |
| 211 | ubo.emissive_exposure_normalization = emissive_exposure_normalization; |
| 212 | // IBL isn't used don't set it. |
| 213 | } else { |
| 214 | ubo.emissive_exposure_normalization = 1.0; |
| 215 | ubo.IBL_exposure_normalization = 1.0; |
| 216 | } |
| 217 | |
| 218 | ubo.roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active(); |
| 219 | ubo.roughness_limiter_amount = render_scene_render->screen_space_roughness_limiter_get_amount(); |
| 220 | ubo.roughness_limiter_limit = render_scene_render->screen_space_roughness_limiter_get_limit(); |
| 221 | |
| 222 | if (calculate_motion_vectors) { |
| 223 | // Q : Should we make a complete copy or should we define a separate UBO with just the components we need? |
| 224 | memcpy(&prev_ubo, &ubo, sizeof(UBO)); |
| 225 | |
| 226 | Projection prev_correction; |
| 227 | prev_correction.set_depth_correction(true); |
| 228 | prev_correction.add_jitter_offset(prev_taa_jitter); |
| 229 | Projection prev_projection = prev_correction * prev_cam_projection; |
| 230 | |
| 231 | //store camera into ubo |
| 232 | RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix); |
| 233 | RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix); |
| 234 | RendererRD::MaterialStorage::store_transform(prev_cam_transform, prev_ubo.inv_view_matrix); |
| 235 | RendererRD::MaterialStorage::store_transform(prev_cam_transform.affine_inverse(), prev_ubo.view_matrix); |
| 236 | |
| 237 | #ifdef REAL_T_IS_DOUBLE |
| 238 | RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.x, &prev_ubo.inv_view_matrix[12], &prev_ubo.inv_view_matrix[3]); |
| 239 | RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.y, &prev_ubo.inv_view_matrix[13], &prev_ubo.inv_view_matrix[7]); |
| 240 | RendererRD::MaterialStorage::split_double(-prev_cam_transform.origin.z, &prev_ubo.inv_view_matrix[14], &prev_ubo.inv_view_matrix[11]); |
| 241 | #endif |
| 242 | |
| 243 | for (uint32_t v = 0; v < view_count; v++) { |
| 244 | prev_projection = prev_correction * view_projection[v]; |
| 245 | RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix_view[v]); |
| 246 | RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix_view[v]); |
| 247 | } |
| 248 | prev_ubo.taa_jitter[0] = prev_taa_jitter.x; |
| 249 | prev_ubo.taa_jitter[1] = prev_taa_jitter.y; |
| 250 | prev_ubo.time -= time_step; |
| 251 | } |
| 252 | |
| 253 | uniform_buffer = p_uniform_buffer; |
| 254 | RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo, RD::BARRIER_MASK_RASTER); |
| 255 | } |
| 256 | |
| 257 | RID RenderSceneDataRD::get_uniform_buffer() { |
| 258 | return uniform_buffer; |
| 259 | } |
| 260 | |