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
37RID RenderSceneDataRD::create_uniform_buffer() {
38 return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA));
39}
40
41void 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
257RID RenderSceneDataRD::get_uniform_buffer() {
258 return uniform_buffer;
259}
260