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 | |