|
@@ -665,6 +665,23 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
|
|
|
|
_pre_opaque_render(p_render_data, false, false, RID(), RID());
|
|
|
|
|
|
+ uint32_t spec_constant_base_flags = 0;
|
|
|
+
|
|
|
+ {
|
|
|
+ //figure out spec constants
|
|
|
+
|
|
|
+ if (p_render_data->directional_light_count > 0) {
|
|
|
+ if (p_render_data->directional_light_soft_shadows) {
|
|
|
+ spec_constant_base_flags |= 1 << SPEC_CONSTANT_USING_DIRECTIONAL_SOFT_SHADOWS;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!is_environment(p_render_data->environment) || environment_is_fog_enabled(p_render_data->environment)) {
|
|
|
+ spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG;
|
|
|
+ }
|
|
|
+ }
|
|
|
{
|
|
|
if (render_buffer) {
|
|
|
RD::get_singleton()->draw_command_begin_label("Render 3D Pass");
|
|
@@ -707,7 +724,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
|
}
|
|
|
|
|
|
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
|
|
- RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
|
|
+ RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
|
|
render_list_params.framebuffer_format = fb_format;
|
|
|
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
|
|
|
// secondary command buffers need more testing at this time
|
|
@@ -771,7 +788,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
|
|
|
|
if (using_subpass_transparent) {
|
|
|
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
|
|
- RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
|
|
+ RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
|
|
render_list_params.framebuffer_format = fb_format;
|
|
|
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
|
|
|
// secondary command buffers need more testing at this time
|
|
@@ -808,7 +825,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
|
|
// _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
|
|
|
|
|
|
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
|
|
- RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
|
|
+ RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
|
|
|
render_list_params.framebuffer_format = fb_format;
|
|
|
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
|
|
|
// secondary command buffers need more testing at this time
|
|
@@ -935,7 +952,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) {
|
|
|
|
|
|
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
|
|
|
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
|
|
|
- RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
|
|
|
+ RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, 0, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
|
|
|
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
|
|
|
}
|
|
|
|
|
@@ -975,7 +992,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
|
|
|
RENDER_TIMESTAMP("Render Material");
|
|
|
|
|
|
{
|
|
|
- RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set);
|
|
|
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, 0);
|
|
|
//regular forward for now
|
|
|
Vector<Color> clear;
|
|
|
clear.push_back(Color(0, 0, 0, 0));
|
|
@@ -1016,7 +1033,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in
|
|
|
RENDER_TIMESTAMP("Render Material");
|
|
|
|
|
|
{
|
|
|
- RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true);
|
|
|
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, 0);
|
|
|
//regular forward for now
|
|
|
Vector<Color> clear;
|
|
|
clear.push_back(Color(0, 0, 0, 0));
|
|
@@ -1090,7 +1107,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
|
|
|
|
|
|
{
|
|
|
//regular forward for now
|
|
|
- RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, rp_uniform_set);
|
|
|
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, rp_uniform_set, 0);
|
|
|
_render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
|
|
|
}
|
|
|
RD::get_singleton()->draw_command_end_label();
|
|
@@ -1733,7 +1750,7 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, const GeometryInstanceForwardMobile *p_instance) {
|
|
|
+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;
|
|
@@ -1748,6 +1765,19 @@ void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceF
|
|
|
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;
|
|
@@ -1795,6 +1825,8 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|
|
const RenderElementInfo &element_info = p_params->element_info[i];
|
|
|
const GeometryInstanceForwardMobile *inst = surf->owner;
|
|
|
|
|
|
+ uint32_t base_spec_constants = p_params->spec_constant_base_flags;
|
|
|
+
|
|
|
// GeometryInstanceForwardMobile::PushConstant push_constant = inst->push_constant;
|
|
|
GeometryInstanceForwardMobile::PushConstant push_constant;
|
|
|
|
|
@@ -1830,7 +1862,13 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|
|
mesh_surface = surf->surface_shadow;
|
|
|
|
|
|
} else {
|
|
|
- _fill_push_constant_instance_indices(&push_constant, inst);
|
|
|
+ if (inst->use_projector) {
|
|
|
+ base_spec_constants |= 1 << SPEC_CONSTANT_USING_PROJECTOR;
|
|
|
+ }
|
|
|
+ if (inst->use_soft_shadow) {
|
|
|
+ base_spec_constants |= 1 << SPEC_CONSTANT_USING_SOFT_SHADOWS;
|
|
|
+ }
|
|
|
+ _fill_push_constant_instance_indices(&push_constant, base_spec_constants, inst);
|
|
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
|
|
@@ -1922,7 +1960,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
|
|
prev_index_array_rd = index_array_rd;
|
|
|
}
|
|
|
|
|
|
- RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe, p_params->subpass);
|
|
|
+ RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe, p_params->subpass, base_spec_constants);
|
|
|
|
|
|
if (pipeline_rd != prev_pipeline_rd) {
|
|
|
// checking with prev shader does not make so much sense, as
|
|
@@ -2181,6 +2219,11 @@ void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInst
|
|
|
}
|
|
|
|
|
|
void RenderForwardMobile::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) {
|
|
|
+ GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance);
|
|
|
+ ERR_FAIL_COND(!ginstance);
|
|
|
+
|
|
|
+ ginstance->use_projector = p_projector;
|
|
|
+ ginstance->use_soft_shadow = p_softshadow;
|
|
|
}
|
|
|
|
|
|
void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
|
|
@@ -2559,12 +2602,12 @@ void RenderForwardMobile::_update_shader_quality_settings() {
|
|
|
spec_constants.push_back(sc);
|
|
|
|
|
|
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
|
|
|
- sc.constant_id = SPEC_CONSTANT_DECAL_FILTER;
|
|
|
+ sc.constant_id = SPEC_CONSTANT_DECAL_USE_MIPMAPS;
|
|
|
sc.bool_value = decals_get_filter() == RS::DECAL_FILTER_NEAREST_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS || decals_get_filter() == RS::DECAL_FILTER_LINEAR_MIPMAPS_ANISOTROPIC;
|
|
|
|
|
|
spec_constants.push_back(sc);
|
|
|
|
|
|
- sc.constant_id = SPEC_CONSTANT_PROJECTOR_FILTER;
|
|
|
+ sc.constant_id = SPEC_CONSTANT_PROJECTOR_USE_MIPMAPS;
|
|
|
sc.bool_value = light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS || light_projectors_get_filter() == RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC;
|
|
|
|
|
|
spec_constants.push_back(sc);
|