|
@@ -39,7 +39,7 @@
|
|
|
|
|
|
using namespace RendererSceneRenderImplementation;
|
|
using namespace RendererSceneRenderImplementation;
|
|
|
|
|
|
-RenderForwardMobile::ForwardID RenderForwardMobile::_allocate_forward_id(ForwardIDType p_type) {
|
|
|
|
|
|
+RendererRD::ForwardID RenderForwardMobile::ForwardIDStorageMobile::allocate_forward_id(RendererRD::ForwardIDType p_type) {
|
|
int32_t index = -1;
|
|
int32_t index = -1;
|
|
for (uint32_t i = 0; i < forward_id_allocators[p_type].allocations.size(); i++) {
|
|
for (uint32_t i = 0; i < forward_id_allocators[p_type].allocations.size(); i++) {
|
|
if (forward_id_allocators[p_type].allocations[i] == false) {
|
|
if (forward_id_allocators[p_type].allocations[i] == false) {
|
|
@@ -58,15 +58,66 @@ RenderForwardMobile::ForwardID RenderForwardMobile::_allocate_forward_id(Forward
|
|
|
|
|
|
return index;
|
|
return index;
|
|
}
|
|
}
|
|
-void RenderForwardMobile::_free_forward_id(ForwardIDType p_type, ForwardID p_id) {
|
|
|
|
- ERR_FAIL_INDEX(p_id, (ForwardID)forward_id_allocators[p_type].allocations.size());
|
|
|
|
|
|
+void RenderForwardMobile::ForwardIDStorageMobile::free_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id) {
|
|
|
|
+ ERR_FAIL_INDEX(p_id, (RendererRD::ForwardID)forward_id_allocators[p_type].allocations.size());
|
|
forward_id_allocators[p_type].allocations[p_id] = false;
|
|
forward_id_allocators[p_type].allocations[p_id] = false;
|
|
}
|
|
}
|
|
|
|
|
|
-void RenderForwardMobile::_map_forward_id(ForwardIDType p_type, ForwardID p_id, uint32_t p_index) {
|
|
|
|
|
|
+void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index) {
|
|
forward_id_allocators[p_type].map[p_id] = p_index;
|
|
forward_id_allocators[p_type].map[p_id] = p_index;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void RenderForwardMobile::ForwardIDStorageMobile::fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) {
|
|
|
|
+ // first zero out our indices
|
|
|
|
+
|
|
|
|
+ p_push_constant->omni_lights[0] = 0xFFFF;
|
|
|
|
+ p_push_constant->omni_lights[1] = 0xFFFF;
|
|
|
|
+
|
|
|
|
+ p_push_constant->spot_lights[0] = 0xFFFF;
|
|
|
|
+ p_push_constant->spot_lights[1] = 0xFFFF;
|
|
|
|
+
|
|
|
|
+ p_push_constant->decals[0] = 0xFFFF;
|
|
|
|
+ p_push_constant->decals[1] = 0xFFFF;
|
|
|
|
+
|
|
|
|
+ p_push_constant->reflection_probes[0] = 0xFFFF;
|
|
|
|
+ p_push_constant->reflection_probes[1] = 0xFFFF;
|
|
|
|
+
|
|
|
|
+ if (p_instance->omni_light_count == 0) {
|
|
|
|
+ spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS;
|
|
|
|
+ }
|
|
|
|
+ if (p_instance->spot_light_count == 0) {
|
|
|
|
+ spec_constants |= 1 << SPEC_CONSTANT_DISABLE_SPOT_LIGHTS;
|
|
|
|
+ }
|
|
|
|
+ if (p_instance->reflection_probe_count == 0) {
|
|
|
|
+ spec_constants |= 1 << SPEC_CONSTANT_DISABLE_REFLECTION_PROBES;
|
|
|
|
+ }
|
|
|
|
+ if (p_instance->decals_count == 0) {
|
|
|
|
+ spec_constants |= 1 << SPEC_CONSTANT_DISABLE_DECALS;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (uint32_t i = 0; i < MAX_RDL_CULL; i++) {
|
|
|
|
+ uint32_t ofs = i < 4 ? 0 : 1;
|
|
|
|
+ uint32_t shift = (i & 0x3) << 3;
|
|
|
|
+ uint32_t mask = ~(0xFF << shift);
|
|
|
|
+ if (i < p_instance->omni_light_count) {
|
|
|
|
+ p_push_constant->omni_lights[ofs] &= mask;
|
|
|
|
+ p_push_constant->omni_lights[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
|
|
|
|
+ }
|
|
|
|
+ if (i < p_instance->spot_light_count) {
|
|
|
|
+ p_push_constant->spot_lights[ofs] &= mask;
|
|
|
|
+ p_push_constant->spot_lights[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
|
|
|
|
+ }
|
|
|
|
+ if (i < p_instance->decals_count) {
|
|
|
|
+ p_push_constant->decals[ofs] &= mask;
|
|
|
|
+ p_push_constant->decals[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
|
|
|
|
+ }
|
|
|
|
+ if (i < p_instance->reflection_probe_count) {
|
|
|
|
+ p_push_constant->reflection_probes[ofs] &= mask;
|
|
|
|
+ p_push_constant->reflection_probes[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/* Render buffer */
|
|
/* Render buffer */
|
|
|
|
|
|
void RenderForwardMobile::RenderBufferDataForwardMobile::free_data() {
|
|
void RenderForwardMobile::RenderBufferDataForwardMobile::free_data() {
|
|
@@ -300,6 +351,7 @@ bool RenderForwardMobile::_render_buffers_can_be_storage() {
|
|
}
|
|
}
|
|
|
|
|
|
RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
|
|
RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
|
|
|
|
+ RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
|
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
|
|
|
|
|
//there should always be enough uniform buffers for render passes, otherwise bugs
|
|
//there should always be enough uniform buffers for render passes, otherwise bugs
|
|
@@ -340,7 +392,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
|
}
|
|
}
|
|
|
|
|
|
{
|
|
{
|
|
- RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID();
|
|
|
|
|
|
+ RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? light_storage->reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID();
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 3;
|
|
u.binding = 3;
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
@@ -358,7 +410,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
RID texture;
|
|
RID texture;
|
|
if (p_render_data && p_render_data->shadow_atlas.is_valid()) {
|
|
if (p_render_data && p_render_data->shadow_atlas.is_valid()) {
|
|
- texture = shadow_atlas_get_texture(p_render_data->shadow_atlas);
|
|
|
|
|
|
+ texture = light_storage->shadow_atlas_get_texture(p_render_data->shadow_atlas);
|
|
}
|
|
}
|
|
if (!texture.is_valid()) {
|
|
if (!texture.is_valid()) {
|
|
texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH);
|
|
texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH);
|
|
@@ -370,8 +422,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 5;
|
|
u.binding = 5;
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
|
- if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) {
|
|
|
|
- u.append_id(directional_shadow_get_texture());
|
|
|
|
|
|
+ if (p_use_directional_shadow_atlas && light_storage->directional_shadow_get_texture().is_valid()) {
|
|
|
|
+ u.append_id(light_storage->directional_shadow_get_texture());
|
|
} else {
|
|
} else {
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH));
|
|
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH));
|
|
}
|
|
}
|
|
@@ -387,8 +439,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
|
RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
|
|
RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
|
|
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
|
|
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
|
|
if (p_render_data && i < p_render_data->lightmaps->size()) {
|
|
if (p_render_data && i < p_render_data->lightmaps->size()) {
|
|
- RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
|
|
|
|
- RID texture = RendererRD::LightStorage::get_singleton()->lightmap_get_texture(base);
|
|
|
|
|
|
+ RID base = light_storage->lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
|
|
|
|
+ RID texture = light_storage->lightmap_get_texture(base);
|
|
RID rd_texture = texture_storage->texture_get_rd_texture(texture);
|
|
RID rd_texture = texture_storage->texture_get_rd_texture(texture);
|
|
u.append_id(rd_texture);
|
|
u.append_id(rd_texture);
|
|
} else {
|
|
} else {
|
|
@@ -467,6 +519,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
|
}
|
|
}
|
|
|
|
|
|
void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) {
|
|
void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) {
|
|
|
|
+ RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
|
|
+
|
|
// This probably needs to change...
|
|
// This probably needs to change...
|
|
scene_state.lightmaps_used = 0;
|
|
scene_state.lightmaps_used = 0;
|
|
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
|
|
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
|
|
@@ -474,20 +528,20 @@ void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, co
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- RID lightmap = lightmap_instance_get_lightmap(p_lightmaps[i]);
|
|
|
|
|
|
+ RID lightmap = light_storage->lightmap_instance_get_lightmap(p_lightmaps[i]);
|
|
|
|
|
|
- Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
|
|
|
|
|
|
+ Basis to_lm = light_storage->lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
|
|
to_lm = to_lm.inverse().transposed(); //will transform normals
|
|
to_lm = to_lm.inverse().transposed(); //will transform normals
|
|
RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
|
|
RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
|
|
scene_state.lightmaps[i].exposure_normalization = 1.0;
|
|
scene_state.lightmaps[i].exposure_normalization = 1.0;
|
|
if (p_render_data->camera_attributes.is_valid()) {
|
|
if (p_render_data->camera_attributes.is_valid()) {
|
|
- float baked_exposure = RendererRD::LightStorage::get_singleton()->lightmap_get_baked_exposure_normalization(lightmap);
|
|
|
|
|
|
+ float baked_exposure = light_storage->lightmap_get_baked_exposure_normalization(lightmap);
|
|
float enf = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
|
float enf = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
|
scene_state.lightmaps[i].exposure_normalization = enf / baked_exposure;
|
|
scene_state.lightmaps[i].exposure_normalization = enf / baked_exposure;
|
|
}
|
|
}
|
|
|
|
|
|
scene_state.lightmap_ids[i] = p_lightmaps[i];
|
|
scene_state.lightmap_ids[i] = p_lightmaps[i];
|
|
- scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
|
|
|
|
|
|
+ scene_state.lightmap_has_sh[i] = light_storage->lightmap_uses_spherical_harmonics(lightmap);
|
|
|
|
|
|
scene_state.lightmaps_used++;
|
|
scene_state.lightmaps_used++;
|
|
}
|
|
}
|
|
@@ -496,12 +550,103 @@ void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, co
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
|
|
|
|
+ RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
|
|
+ RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
|
|
|
+
|
|
|
|
+ p_render_data->cube_shadows.clear();
|
|
|
|
+ p_render_data->shadows.clear();
|
|
|
|
+ p_render_data->directional_shadows.clear();
|
|
|
|
+
|
|
|
|
+ Plane camera_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin);
|
|
|
|
+ float lod_distance_multiplier = p_render_data->scene_data->cam_projection.get_lod_multiplier();
|
|
|
|
+ {
|
|
|
|
+ for (int i = 0; i < p_render_data->render_shadow_count; i++) {
|
|
|
|
+ RID li = p_render_data->render_shadows[i].light;
|
|
|
|
+ RID base = light_storage->light_instance_get_base_light(li);
|
|
|
|
+
|
|
|
|
+ if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {
|
|
|
|
+ p_render_data->directional_shadows.push_back(i);
|
|
|
|
+ } else if (light_storage->light_get_type(base) == RS::LIGHT_OMNI && light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {
|
|
|
|
+ p_render_data->cube_shadows.push_back(i);
|
|
|
|
+ } else {
|
|
|
|
+ p_render_data->shadows.push_back(i);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //cube shadows are rendered in their own way
|
|
|
|
+ for (uint32_t i = 0; i < p_render_data->cube_shadows.size(); i++) {
|
|
|
|
+ _render_shadow_pass(p_render_data->render_shadows[p_render_data->cube_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->cube_shadows[i]].pass, p_render_data->render_shadows[p_render_data->cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (p_render_data->directional_shadows.size()) {
|
|
|
|
+ //open the pass for directional shadows
|
|
|
|
+ light_storage->update_directional_shadow_atlas();
|
|
|
|
+ RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE);
|
|
|
|
+ RD::get_singleton()->draw_list_end();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bool render_shadows = p_render_data->directional_shadows.size() || p_render_data->shadows.size();
|
|
|
|
+
|
|
|
|
+ if (render_shadows) {
|
|
|
|
+ RENDER_TIMESTAMP("Render Shadows");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //prepare shadow rendering
|
|
|
|
+ if (render_shadows) {
|
|
|
|
+ _render_shadow_begin();
|
|
|
|
+
|
|
|
|
+ //render directional shadows
|
|
|
|
+ for (uint32_t i = 0; i < p_render_data->directional_shadows.size(); i++) {
|
|
|
|
+ _render_shadow_pass(p_render_data->render_shadows[p_render_data->directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->directional_shadows[i]].pass, p_render_data->render_shadows[p_render_data->directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == p_render_data->directional_shadows.size() - 1, false, p_render_data->render_info);
|
|
|
|
+ }
|
|
|
|
+ //render positional shadows
|
|
|
|
+ for (uint32_t i = 0; i < p_render_data->shadows.size(); i++) {
|
|
|
|
+ _render_shadow_pass(p_render_data->render_shadows[p_render_data->shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->shadows[i]].pass, p_render_data->render_shadows[p_render_data->shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == p_render_data->shadows.size() - 1, true, p_render_data->render_info);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _render_shadow_process();
|
|
|
|
+
|
|
|
|
+ _render_shadow_end(RD::BARRIER_MASK_NO_BARRIER);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //full barrier here, we need raster, transfer and compute and it depends from the previous work
|
|
|
|
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
|
|
|
|
+
|
|
|
|
+ bool using_shadows = true;
|
|
|
|
+
|
|
|
|
+ if (p_render_data->reflection_probe.is_valid()) {
|
|
|
|
+ if (!RSG::light_storage->reflection_probe_renders_shadows(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
|
|
|
+ using_shadows = false;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ //do not render reflections when rendering a reflection probe
|
|
|
|
+ light_storage->update_reflection_probe_buffer(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ uint32_t directional_light_count = 0;
|
|
|
|
+ uint32_t positional_light_count = 0;
|
|
|
|
+ light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
|
|
|
|
+ texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform.affine_inverse());
|
|
|
|
+
|
|
|
|
+ p_render_data->directional_light_count = directional_light_count;
|
|
|
|
+}
|
|
|
|
+
|
|
void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
|
|
void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
|
|
|
|
+ RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
|
|
+
|
|
|
|
+ Ref<RenderSceneBuffersRD> rb;
|
|
Ref<RenderBufferDataForwardMobile> rb_data;
|
|
Ref<RenderBufferDataForwardMobile> rb_data;
|
|
if (p_render_data->render_buffers.is_valid()) {
|
|
if (p_render_data->render_buffers.is_valid()) {
|
|
- rb_data = p_render_data->render_buffers->get_custom_data(RB_SCOPE_MOBILE);
|
|
|
|
|
|
+ rb = p_render_data->render_buffers;
|
|
|
|
+ rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ RENDER_TIMESTAMP("Prepare 3D Scene");
|
|
|
|
+
|
|
|
|
+ _update_vrs(rb);
|
|
|
|
+
|
|
RENDER_TIMESTAMP("Setup 3D Scene");
|
|
RENDER_TIMESTAMP("Setup 3D Scene");
|
|
|
|
|
|
/* TODO
|
|
/* TODO
|
|
@@ -532,9 +677,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
bool using_subpass_transparent = true;
|
|
bool using_subpass_transparent = true;
|
|
bool using_subpass_post_process = true;
|
|
bool using_subpass_post_process = true;
|
|
|
|
|
|
- bool using_ssr = false; // I don't think we support this in our mobile renderer so probably should phase it out
|
|
|
|
- bool using_sss = false; // I don't think we support this in our mobile renderer so probably should phase it out
|
|
|
|
-
|
|
|
|
// fill our render lists early so we can find out if we use various features
|
|
// fill our render lists early so we can find out if we use various features
|
|
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
|
|
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
|
|
render_list[RENDER_LIST_OPAQUE].sort_by_key();
|
|
render_list[RENDER_LIST_OPAQUE].sort_by_key();
|
|
@@ -559,7 +701,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
using_subpass_post_process = false;
|
|
using_subpass_post_process = false;
|
|
}
|
|
}
|
|
|
|
|
|
- if (using_ssr || using_sss || scene_state.used_screen_texture || scene_state.used_depth_texture) {
|
|
|
|
|
|
+ if (scene_state.used_screen_texture || scene_state.used_depth_texture) {
|
|
// can't use our last two subpasses
|
|
// can't use our last two subpasses
|
|
using_subpass_transparent = false;
|
|
using_subpass_transparent = false;
|
|
using_subpass_post_process = false;
|
|
using_subpass_post_process = false;
|
|
@@ -576,13 +718,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_TWO_SUBPASSES);
|
|
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_TWO_SUBPASSES);
|
|
}
|
|
}
|
|
} else if (p_render_data->reflection_probe.is_valid()) {
|
|
} else if (p_render_data->reflection_probe.is_valid()) {
|
|
- uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
|
|
|
|
|
|
+ uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
|
|
screen_size.x = resolution;
|
|
screen_size.x = resolution;
|
|
screen_size.y = resolution;
|
|
screen_size.y = resolution;
|
|
|
|
|
|
- framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
|
|
|
|
|
+ framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
|
|
|
|
|
- if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
|
|
|
|
|
+ if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
|
p_render_data->environment = RID(); //no environment on interiors
|
|
p_render_data->environment = RID(); //no environment on interiors
|
|
}
|
|
}
|
|
|
|
|
|
@@ -713,8 +855,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
|
|
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
|
|
}
|
|
}
|
|
|
|
|
|
- RID nullrids[RendererSceneRender::MAX_RENDER_VIEWS];
|
|
|
|
- _pre_opaque_render(p_render_data, false, false, false, nullrids, RID());
|
|
|
|
|
|
+ _pre_opaque_render(p_render_data);
|
|
|
|
|
|
uint32_t spec_constant_base_flags = 0;
|
|
uint32_t spec_constant_base_flags = 0;
|
|
|
|
|
|
@@ -758,8 +899,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
|
|
|
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true);
|
|
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true);
|
|
|
|
|
|
- bool can_continue_color = !using_subpass_transparent && !scene_state.used_screen_texture && !using_ssr && !using_sss;
|
|
|
|
- bool can_continue_depth = !using_subpass_transparent && !scene_state.used_depth_texture && !using_ssr && !using_sss;
|
|
|
|
|
|
+ bool can_continue_color = !using_subpass_transparent && !scene_state.used_screen_texture;
|
|
|
|
+ bool can_continue_depth = !using_subpass_transparent && !scene_state.used_depth_texture;
|
|
|
|
|
|
{
|
|
{
|
|
// regular forward for now
|
|
// regular forward for now
|
|
@@ -917,10 +1058,190 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
if (rb_data.is_valid()) {
|
|
if (rb_data.is_valid()) {
|
|
_disable_clear_request(p_render_data);
|
|
_disable_clear_request(p_render_data);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (rb.is_valid()) {
|
|
|
|
+ _render_buffers_debug_draw(rb, p_render_data->shadow_atlas, p_render_data->occluder_debug_tex);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/* these are being called from RendererSceneRenderRD::_pre_opaque_render */
|
|
/* these are being called from RendererSceneRenderRD::_pre_opaque_render */
|
|
|
|
|
|
|
|
+void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info) {
|
|
|
|
+ RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
|
|
|
+
|
|
|
|
+ ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));
|
|
|
|
+
|
|
|
|
+ RID base = light_storage->light_instance_get_base_light(p_light);
|
|
|
|
+
|
|
|
|
+ Rect2i atlas_rect;
|
|
|
|
+ uint32_t atlas_size = 1;
|
|
|
|
+ RID atlas_fb;
|
|
|
|
+
|
|
|
|
+ bool using_dual_paraboloid = false;
|
|
|
|
+ bool using_dual_paraboloid_flip = false;
|
|
|
|
+ Vector2i dual_paraboloid_offset;
|
|
|
|
+ RID render_fb;
|
|
|
|
+ RID render_texture;
|
|
|
|
+ float zfar;
|
|
|
|
+
|
|
|
|
+ bool use_pancake = false;
|
|
|
|
+ bool render_cubemap = false;
|
|
|
|
+ bool finalize_cubemap = false;
|
|
|
|
+
|
|
|
|
+ bool flip_y = false;
|
|
|
|
+
|
|
|
|
+ Projection light_projection;
|
|
|
|
+ Transform3D light_transform;
|
|
|
|
+
|
|
|
|
+ if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {
|
|
|
|
+ //set pssm stuff
|
|
|
|
+ uint64_t last_scene_shadow_pass = light_storage->light_instance_get_shadow_pass(p_light);
|
|
|
|
+ if (last_scene_shadow_pass != get_scene_pass()) {
|
|
|
|
+ light_storage->light_instance_set_directional_rect(p_light, light_storage->get_directional_shadow_rect());
|
|
|
|
+ light_storage->directional_shadow_increase_current_light();
|
|
|
|
+ light_storage->light_instance_set_shadow_pass(p_light, get_scene_pass());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ use_pancake = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;
|
|
|
|
+ light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);
|
|
|
|
+ light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);
|
|
|
|
+
|
|
|
|
+ atlas_rect = light_storage->light_instance_get_directional_rect(p_light);
|
|
|
|
+
|
|
|
|
+ if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
|
|
|
|
+ atlas_rect.size.width /= 2;
|
|
|
|
+ atlas_rect.size.height /= 2;
|
|
|
|
+
|
|
|
|
+ if (p_pass == 1) {
|
|
|
|
+ atlas_rect.position.x += atlas_rect.size.width;
|
|
|
|
+ } else if (p_pass == 2) {
|
|
|
|
+ atlas_rect.position.y += atlas_rect.size.height;
|
|
|
|
+ } else if (p_pass == 3) {
|
|
|
|
+ atlas_rect.position += atlas_rect.size;
|
|
|
|
+ }
|
|
|
|
+ } else if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
|
|
|
|
+ atlas_rect.size.height /= 2;
|
|
|
|
+
|
|
|
|
+ if (p_pass == 0) {
|
|
|
|
+ } else {
|
|
|
|
+ atlas_rect.position.y += atlas_rect.size.height;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int directional_shadow_size = light_storage->directional_shadow_get_size();
|
|
|
|
+ atlas_rect.position /= directional_shadow_size;
|
|
|
|
+ atlas_rect.size /= directional_shadow_size;
|
|
|
|
+
|
|
|
|
+ light_storage->light_instance_set_directional_shadow_atlas_rect(p_light, p_pass, atlas_rect);
|
|
|
|
+
|
|
|
|
+ zfar = RSG::light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);
|
|
|
|
+
|
|
|
|
+ render_fb = light_storage->direction_shadow_get_fb();
|
|
|
|
+ render_texture = RID();
|
|
|
|
+ flip_y = true;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ //set from shadow atlas
|
|
|
|
+
|
|
|
|
+ ERR_FAIL_COND(!light_storage->owns_shadow_atlas(p_shadow_atlas));
|
|
|
|
+ ERR_FAIL_COND(!light_storage->shadow_atlas_owns_light_instance(p_shadow_atlas, p_light));
|
|
|
|
+
|
|
|
|
+ RSG::light_storage->shadow_atlas_update(p_shadow_atlas);
|
|
|
|
+
|
|
|
|
+ uint32_t key = light_storage->shadow_atlas_get_light_instance_key(p_shadow_atlas, p_light);
|
|
|
|
+
|
|
|
|
+ uint32_t quadrant = (key >> RendererRD::LightStorage::QUADRANT_SHIFT) & 0x3;
|
|
|
|
+ uint32_t shadow = key & RendererRD::LightStorage::SHADOW_INDEX_MASK;
|
|
|
|
+ uint32_t subdivision = light_storage->shadow_atlas_get_quadrant_subdivision(p_shadow_atlas, quadrant);
|
|
|
|
+
|
|
|
|
+ ERR_FAIL_INDEX((int)shadow, light_storage->shadow_atlas_get_quadrant_shadow_size(p_shadow_atlas, quadrant));
|
|
|
|
+
|
|
|
|
+ uint32_t shadow_atlas_size = light_storage->shadow_atlas_get_size(p_shadow_atlas);
|
|
|
|
+ uint32_t quadrant_size = shadow_atlas_size >> 1;
|
|
|
|
+
|
|
|
|
+ atlas_rect.position.x = (quadrant & 1) * quadrant_size;
|
|
|
|
+ atlas_rect.position.y = (quadrant >> 1) * quadrant_size;
|
|
|
|
+
|
|
|
|
+ uint32_t shadow_size = (quadrant_size / subdivision);
|
|
|
|
+ atlas_rect.position.x += (shadow % subdivision) * shadow_size;
|
|
|
|
+ atlas_rect.position.y += (shadow / subdivision) * shadow_size;
|
|
|
|
+
|
|
|
|
+ atlas_rect.size.width = shadow_size;
|
|
|
|
+ atlas_rect.size.height = shadow_size;
|
|
|
|
+
|
|
|
|
+ zfar = light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);
|
|
|
|
+
|
|
|
|
+ if (light_storage->light_get_type(base) == RS::LIGHT_OMNI) {
|
|
|
|
+ bool wrap = (shadow + 1) % subdivision == 0;
|
|
|
|
+ dual_paraboloid_offset = wrap ? Vector2i(1 - subdivision, 1) : Vector2i(1, 0);
|
|
|
|
+
|
|
|
|
+ if (light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {
|
|
|
|
+ render_texture = light_storage->get_cubemap(shadow_size / 2);
|
|
|
|
+ render_fb = light_storage->get_cubemap_fb(shadow_size / 2, p_pass);
|
|
|
|
+
|
|
|
|
+ light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);
|
|
|
|
+ light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);
|
|
|
|
+ render_cubemap = true;
|
|
|
|
+ finalize_cubemap = p_pass == 5;
|
|
|
|
+ atlas_fb = light_storage->shadow_atlas_get_fb(p_shadow_atlas);
|
|
|
|
+
|
|
|
|
+ atlas_size = shadow_atlas_size;
|
|
|
|
+
|
|
|
|
+ if (p_pass == 0) {
|
|
|
|
+ _render_shadow_begin();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ atlas_rect.position.x += 1;
|
|
|
|
+ atlas_rect.position.y += 1;
|
|
|
|
+ atlas_rect.size.x -= 2;
|
|
|
|
+ atlas_rect.size.y -= 2;
|
|
|
|
+
|
|
|
|
+ atlas_rect.position += p_pass * atlas_rect.size * dual_paraboloid_offset;
|
|
|
|
+
|
|
|
|
+ light_projection = light_storage->light_instance_get_shadow_camera(p_light, 0);
|
|
|
|
+ light_transform = light_storage->light_instance_get_shadow_transform(p_light, 0);
|
|
|
|
+
|
|
|
|
+ using_dual_paraboloid = true;
|
|
|
|
+ using_dual_paraboloid_flip = p_pass == 1;
|
|
|
|
+ render_fb = light_storage->shadow_atlas_get_fb(p_shadow_atlas);
|
|
|
|
+ flip_y = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else if (light_storage->light_get_type(base) == RS::LIGHT_SPOT) {
|
|
|
|
+ light_projection = light_storage->light_instance_get_shadow_camera(p_light, 0);
|
|
|
|
+ light_transform = light_storage->light_instance_get_shadow_transform(p_light, 0);
|
|
|
|
+
|
|
|
|
+ render_fb = light_storage->shadow_atlas_get_fb(p_shadow_atlas);
|
|
|
|
+
|
|
|
|
+ flip_y = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (render_cubemap) {
|
|
|
|
+ //rendering to cubemap
|
|
|
|
+ _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info);
|
|
|
|
+ if (finalize_cubemap) {
|
|
|
|
+ _render_shadow_process();
|
|
|
|
+ _render_shadow_end();
|
|
|
|
+ //reblit
|
|
|
|
+ Rect2 atlas_rect_norm = atlas_rect;
|
|
|
|
+ atlas_rect_norm.position /= float(atlas_size);
|
|
|
|
+ atlas_rect_norm.size /= float(atlas_size);
|
|
|
|
+ copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false);
|
|
|
|
+ atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size;
|
|
|
|
+ copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true);
|
|
|
|
+
|
|
|
|
+ //restore transform so it can be properly used
|
|
|
|
+ light_storage->light_instance_set_shadow_transform(p_light, Projection(), light_storage->light_instance_get_base_transform(p_light), zfar, 0, 0, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ //render shadow
|
|
|
|
+ _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void RenderForwardMobile::_render_shadow_begin() {
|
|
void RenderForwardMobile::_render_shadow_begin() {
|
|
scene_state.shadow_passes.clear();
|
|
scene_state.shadow_passes.clear();
|
|
RD::get_singleton()->draw_command_begin_label("Shadow Setup");
|
|
RD::get_singleton()->draw_command_begin_label("Shadow Setup");
|
|
@@ -1146,7 +1467,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *>
|
|
}
|
|
}
|
|
|
|
|
|
void RenderForwardMobile::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) {
|
|
void RenderForwardMobile::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) {
|
|
- // we don't do GI in low end..
|
|
|
|
|
|
+ // we don't do SDFGI in low end..
|
|
}
|
|
}
|
|
|
|
|
|
void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) {
|
|
void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) {
|
|
@@ -1189,7 +1510,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
|
|
RD::get_singleton()->draw_command_end_label();
|
|
RD::get_singleton()->draw_command_end_label();
|
|
}
|
|
}
|
|
|
|
|
|
-void RenderForwardMobile::_base_uniforms_changed() {
|
|
|
|
|
|
+void RenderForwardMobile::base_uniforms_changed() {
|
|
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
|
|
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
|
|
RD::get_singleton()->free(render_base_uniform_set);
|
|
RD::get_singleton()->free(render_base_uniform_set);
|
|
}
|
|
}
|
|
@@ -1305,14 +1626,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 5;
|
|
u.binding = 5;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
- u.append_id(get_omni_light_buffer());
|
|
|
|
|
|
+ u.append_id(RendererRD::LightStorage::get_singleton()->get_omni_light_buffer());
|
|
uniforms.push_back(u);
|
|
uniforms.push_back(u);
|
|
}
|
|
}
|
|
{
|
|
{
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 6;
|
|
u.binding = 6;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
- u.append_id(get_spot_light_buffer());
|
|
|
|
|
|
+ u.append_id(RendererRD::LightStorage::get_singleton()->get_spot_light_buffer());
|
|
uniforms.push_back(u);
|
|
uniforms.push_back(u);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1320,14 +1641,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 7;
|
|
u.binding = 7;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
- u.append_id(get_reflection_probe_buffer());
|
|
|
|
|
|
+ u.append_id(RendererRD::LightStorage::get_singleton()->get_reflection_probe_buffer());
|
|
uniforms.push_back(u);
|
|
uniforms.push_back(u);
|
|
}
|
|
}
|
|
{
|
|
{
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 8;
|
|
u.binding = 8;
|
|
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
|
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
|
- u.append_id(get_directional_light_buffer());
|
|
|
|
|
|
+ u.append_id(RendererRD::LightStorage::get_singleton()->get_directional_light_buffer());
|
|
uniforms.push_back(u);
|
|
uniforms.push_back(u);
|
|
}
|
|
}
|
|
{
|
|
{
|
|
@@ -1364,7 +1685,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
|
RD::Uniform u;
|
|
RD::Uniform u;
|
|
u.binding = 13;
|
|
u.binding = 13;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
|
- u.append_id(get_decal_buffer());
|
|
|
|
|
|
+ u.append_id(RendererRD::TextureStorage::get_singleton()->get_decal_buffer());
|
|
uniforms.push_back(u);
|
|
uniforms.push_back(u);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1584,7 +1905,7 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
|
|
void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
|
|
void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
|
|
Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers;
|
|
Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers;
|
|
RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID();
|
|
RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID();
|
|
- RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
|
|
|
|
|
|
+ RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? RendererRD::LightStorage::get_singleton()->reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
|
|
|
|
|
|
// May do this earlier in RenderSceneRenderRD::render_scene
|
|
// May do this earlier in RenderSceneRenderRD::render_scene
|
|
if (p_index >= (int)scene_state.uniform_buffers.size()) {
|
|
if (p_index >= (int)scene_state.uniform_buffers.size()) {
|
|
@@ -1665,57 +1986,6 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) {
|
|
|
|
- // first zero out our indices
|
|
|
|
-
|
|
|
|
- p_push_constant->omni_lights[0] = 0xFFFF;
|
|
|
|
- p_push_constant->omni_lights[1] = 0xFFFF;
|
|
|
|
-
|
|
|
|
- p_push_constant->spot_lights[0] = 0xFFFF;
|
|
|
|
- p_push_constant->spot_lights[1] = 0xFFFF;
|
|
|
|
-
|
|
|
|
- p_push_constant->decals[0] = 0xFFFF;
|
|
|
|
- p_push_constant->decals[1] = 0xFFFF;
|
|
|
|
-
|
|
|
|
- p_push_constant->reflection_probes[0] = 0xFFFF;
|
|
|
|
- p_push_constant->reflection_probes[1] = 0xFFFF;
|
|
|
|
-
|
|
|
|
- if (p_instance->omni_light_count == 0) {
|
|
|
|
- spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS;
|
|
|
|
- }
|
|
|
|
- if (p_instance->spot_light_count == 0) {
|
|
|
|
- spec_constants |= 1 << SPEC_CONSTANT_DISABLE_SPOT_LIGHTS;
|
|
|
|
- }
|
|
|
|
- if (p_instance->reflection_probe_count == 0) {
|
|
|
|
- spec_constants |= 1 << SPEC_CONSTANT_DISABLE_REFLECTION_PROBES;
|
|
|
|
- }
|
|
|
|
- if (p_instance->decals_count == 0) {
|
|
|
|
- spec_constants |= 1 << SPEC_CONSTANT_DISABLE_DECALS;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (uint32_t i = 0; i < MAX_RDL_CULL; i++) {
|
|
|
|
- uint32_t ofs = i < 4 ? 0 : 1;
|
|
|
|
- uint32_t shift = (i & 0x3) << 3;
|
|
|
|
- uint32_t mask = ~(0xFF << shift);
|
|
|
|
- if (i < p_instance->omni_light_count) {
|
|
|
|
- p_push_constant->omni_lights[ofs] &= mask;
|
|
|
|
- p_push_constant->omni_lights[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
|
|
|
|
- }
|
|
|
|
- if (i < p_instance->spot_light_count) {
|
|
|
|
- p_push_constant->spot_lights[ofs] &= mask;
|
|
|
|
- p_push_constant->spot_lights[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
|
|
|
|
- }
|
|
|
|
- if (i < p_instance->decals_count) {
|
|
|
|
- p_push_constant->decals[ofs] &= mask;
|
|
|
|
- p_push_constant->decals[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
|
|
|
|
- }
|
|
|
|
- if (i < p_instance->reflection_probe_count) {
|
|
|
|
- p_push_constant->reflection_probes[ofs] &= mask;
|
|
|
|
- p_push_constant->reflection_probes[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
template <RenderForwardMobile::PassMode p_pass_mode>
|
|
template <RenderForwardMobile::PassMode p_pass_mode>
|
|
void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
|
|
void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
|
|
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
|
|
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
|
|
@@ -1797,7 +2067,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|
if (inst->use_soft_shadow) {
|
|
if (inst->use_soft_shadow) {
|
|
base_spec_constants |= 1 << SPEC_CONSTANT_USING_SOFT_SHADOWS;
|
|
base_spec_constants |= 1 << SPEC_CONSTANT_USING_SOFT_SHADOWS;
|
|
}
|
|
}
|
|
- _fill_push_constant_instance_indices(&push_constant, base_spec_constants, inst);
|
|
|
|
|
|
+ forward_id_storage_mobile->fill_push_constant_instance_indices(&push_constant, base_spec_constants, inst);
|
|
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
#ifdef DEBUG_ENABLED
|
|
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
|
|
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
|
|
@@ -1989,17 +2259,17 @@ void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(co
|
|
spot_light_count = 0;
|
|
spot_light_count = 0;
|
|
|
|
|
|
for (uint32_t i = 0; i < p_light_instance_count; i++) {
|
|
for (uint32_t i = 0; i < p_light_instance_count; i++) {
|
|
- RS::LightType type = RenderForwardMobile::get_singleton()->light_instance_get_type(p_light_instances[i]);
|
|
|
|
|
|
+ RS::LightType type = RendererRD::LightStorage::get_singleton()->light_instance_get_type(p_light_instances[i]);
|
|
switch (type) {
|
|
switch (type) {
|
|
case RS::LIGHT_OMNI: {
|
|
case RS::LIGHT_OMNI: {
|
|
if (omni_light_count < (uint32_t)MAX_RDL_CULL) {
|
|
if (omni_light_count < (uint32_t)MAX_RDL_CULL) {
|
|
- omni_lights[omni_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
|
|
|
|
|
+ omni_lights[omni_light_count] = RendererRD::LightStorage::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
|
omni_light_count++;
|
|
omni_light_count++;
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
case RS::LIGHT_SPOT: {
|
|
case RS::LIGHT_SPOT: {
|
|
if (spot_light_count < (uint32_t)MAX_RDL_CULL) {
|
|
if (spot_light_count < (uint32_t)MAX_RDL_CULL) {
|
|
- spot_lights[spot_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
|
|
|
|
|
+ spot_lights[spot_light_count] = RendererRD::LightStorage::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
|
spot_light_count++;
|
|
spot_light_count++;
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
@@ -2012,14 +2282,14 @@ void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(co
|
|
void RenderForwardMobile::GeometryInstanceForwardMobile::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
|
|
void RenderForwardMobile::GeometryInstanceForwardMobile::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
|
|
reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL;
|
|
reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL;
|
|
for (uint32_t i = 0; i < reflection_probe_count; i++) {
|
|
for (uint32_t i = 0; i < reflection_probe_count; i++) {
|
|
- reflection_probes[i] = RenderForwardMobile::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]);
|
|
|
|
|
|
+ reflection_probes[i] = RendererRD::LightStorage::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void RenderForwardMobile::GeometryInstanceForwardMobile::pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) {
|
|
void RenderForwardMobile::GeometryInstanceForwardMobile::pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) {
|
|
decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL;
|
|
decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL;
|
|
for (uint32_t i = 0; i < decals_count; i++) {
|
|
for (uint32_t i = 0; i < decals_count; i++) {
|
|
- decals[i] = RenderForwardMobile::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]);
|
|
|
|
|
|
+ decals[i] = RendererRD::TextureStorage::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2387,10 +2657,6 @@ bool RenderForwardMobile::is_dynamic_gi_supported() const {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
-bool RenderForwardMobile::is_clustered_enabled() const {
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
bool RenderForwardMobile::is_volumetric_supported() const {
|
|
bool RenderForwardMobile::is_volumetric_supported() const {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -2446,7 +2712,7 @@ void RenderForwardMobile::_update_shader_quality_settings() {
|
|
|
|
|
|
scene_shader.set_default_specialization_constants(spec_constants);
|
|
scene_shader.set_default_specialization_constants(spec_constants);
|
|
|
|
|
|
- _base_uniforms_changed(); //also need this
|
|
|
|
|
|
+ base_uniforms_changed(); //also need this
|
|
}
|
|
}
|
|
|
|
|
|
RenderForwardMobile::RenderForwardMobile() {
|
|
RenderForwardMobile::RenderForwardMobile() {
|
|
@@ -2495,7 +2761,7 @@ RenderForwardMobile::RenderForwardMobile() {
|
|
}
|
|
}
|
|
|
|
|
|
RenderForwardMobile::~RenderForwardMobile() {
|
|
RenderForwardMobile::~RenderForwardMobile() {
|
|
- directional_shadow_atlas_set_size(0);
|
|
|
|
|
|
+ RSG::light_storage->directional_shadow_atlas_set_size(0);
|
|
|
|
|
|
//clear base uniform set if still valid
|
|
//clear base uniform set if still valid
|
|
for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) {
|
|
for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) {
|