diff options
Diffstat (limited to 'servers')
5 files changed, 110 insertions, 44 deletions
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index e5467ea72d..2397249ca5 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1739,7 +1739,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _setup_voxelgis(*p_render_data->voxel_gi_instances); _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false); - _update_render_base_uniform_set(rb->get_samplers()); // May have changed due to the above (light buffer enlarged, as an example). + // May have changed due to the above (light buffer enlarged, as an example). + if (is_reflection_probe) { + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); + } else { + _update_render_base_uniform_set(rb->get_samplers(), BASE_UNIFORM_SET_CACHE_VIEWPORT); + } _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi, using_motion_pass); render_list[RENDER_LIST_OPAQUE].sort_by_key(); @@ -1970,7 +1975,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co p_render_data->scene_data->opaque_prepass_threshold = 0.0f; // Shadow pass can change the base uniform set samplers. - _update_render_base_uniform_set(rb->get_samplers()); + if (is_reflection_probe) { + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); + } else { + _update_render_base_uniform_set(rb->get_samplers(), BASE_UNIFORM_SET_CACHE_VIEWPORT); + } _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, true, using_motion_pass); @@ -2495,7 +2504,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas void RenderForwardClustered::_render_shadow_begin() { scene_state.shadow_passes.clear(); RD::get_singleton()->draw_command_begin_label("Shadow Setup"); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); render_list[RENDER_LIST_SECONDARY].clear(); scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); @@ -2619,7 +2628,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con render_data.cluster_max_elements = 32; render_data.instances = &p_instances; - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false, false); @@ -2665,7 +2674,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform scene_shader.enable_advanced_shader_group(); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -2716,7 +2725,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance scene_shader.enable_advanced_shader_group(); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); _setup_environment(&render_data, true, Vector2(1, 1), false, Color()); @@ -2785,7 +2794,7 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu render_data.cluster_max_elements = 32; render_data.instances = &p_instances; - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); PassMode pass_mode = PASS_MODE_SDF; _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); @@ -2859,21 +2868,23 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu } void RenderForwardClustered::base_uniforms_changed() { - 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); + for (int i = 0; i < BASE_UNIFORM_SET_CACHE_MAX; i++) { + if (!render_base_uniform_set_cache[i].is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set_cache[i])) { + RD::get_singleton()->free(render_base_uniform_set_cache[i]); + } + render_base_uniform_set_cache[i] = RID(); } - render_base_uniform_set = RID(); } -void RenderForwardClustered::_update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers) { +void RenderForwardClustered::_update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers, BaseUniformSetCache p_cache_index) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); - if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) { - if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { - RD::get_singleton()->free(render_base_uniform_set); + if (render_base_uniform_set_cache[p_cache_index].is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set_cache[p_cache_index]) || (lightmap_texture_array_version_cache[p_cache_index] != light_storage->lightmap_array_get_version())) { + if (render_base_uniform_set_cache[p_cache_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set_cache[p_cache_index])) { + RD::get_singleton()->free(render_base_uniform_set_cache[p_cache_index]); } - lightmap_texture_array_version = light_storage->lightmap_array_get_version(); + lightmap_texture_array_version_cache[p_cache_index] = light_storage->lightmap_array_get_version(); Vector<RD::Uniform> uniforms; @@ -3030,8 +3041,9 @@ void RenderForwardClustered::_update_render_base_uniform_set(const RendererRD::M uniforms.append_array(p_samplers.get_uniforms(SAMPLERS_BINDING_FIRST_INDEX)); - render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET); + render_base_uniform_set_cache[p_cache_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET); } + render_base_uniform_set = render_base_uniform_set_cache[p_cache_index]; } RID RenderForwardClustered::_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) { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 6077fb4bde..bedf119210 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -158,11 +158,20 @@ class RenderForwardClustered : public RendererSceneRenderRD { virtual void setup_render_buffer_data(Ref<RenderSceneBuffersRD> p_render_buffers) override; + enum BaseUniformSetCache { + BASE_UNIFORM_SET_CACHE_VIEWPORT, + BASE_UNIFORM_SET_CACHE_DEFAULT, + BASE_UNIFORM_SET_CACHE_MAX + }; + RID render_base_uniform_set; + // One for custom samplers, one for default samplers. + // Need to switch between them as default is needed for probes, shadows, materials, etc. + RID render_base_uniform_set_cache[BASE_UNIFORM_SET_CACHE_MAX]; - uint64_t lightmap_texture_array_version = 0xFFFFFFFF; + uint64_t lightmap_texture_array_version_cache[BASE_UNIFORM_SET_CACHE_MAX] = { 0xFFFFFFFF, 0xFFFFFFFF }; - void _update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers); + void _update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers, BaseUniformSetCache p_cache_index); RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture); RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 99b416d575..462fc4b524 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -763,7 +763,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_data->cam_transform); _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, false); - _update_render_base_uniform_set(rb->get_samplers()); //may have changed due to the above (light buffer enlarged, as an example) + // May have changed due to the above (light buffer enlarged, as an example). + if (is_reflection_probe) { + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); + } else { + _update_render_base_uniform_set(rb->get_samplers(), BASE_UNIFORM_SET_CACHE_VIEWPORT); + } RD::get_singleton()->draw_command_end_label(); // Render Setup @@ -902,7 +907,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count; // Shadow pass can change the base uniform set samplers. - _update_render_base_uniform_set(rb->get_samplers()); + if (is_reflection_probe) { + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); + } else { + _update_render_base_uniform_set(rb->get_samplers(), BASE_UNIFORM_SET_CACHE_VIEWPORT); + } _setup_environment(p_render_data, is_reflection_probe, screen_size, !is_reflection_probe, p_default_bg_color, p_render_data->render_buffers.is_valid()); @@ -1264,7 +1273,7 @@ void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, i void RenderForwardMobile::_render_shadow_begin() { scene_state.shadow_passes.clear(); RD::get_singleton()->draw_command_begin_label("Shadow Setup"); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); render_list[RENDER_LIST_SECONDARY].clear(); } @@ -1371,7 +1380,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c RD::get_singleton()->draw_command_begin_label("Render 3D Material"); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); RenderSceneDataRD scene_data; scene_data.cam_projection = p_cam_projection; @@ -1422,7 +1431,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *> RD::get_singleton()->draw_command_begin_label("Render UV2"); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); RenderSceneDataRD scene_data; scene_data.dual_paraboloid_side = 0; @@ -1496,7 +1505,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); - _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + _update_render_base_uniform_set(RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), BASE_UNIFORM_SET_CACHE_DEFAULT); RenderSceneDataRD scene_data; scene_data.cam_projection = p_cam_projection; @@ -1534,23 +1543,23 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const } void RenderForwardMobile::base_uniforms_changed() { - 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); + for (int i = 0; i < BASE_UNIFORM_SET_CACHE_MAX; i++) { + if (!render_base_uniform_set_cache[i].is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set_cache[i])) { + RD::get_singleton()->free(render_base_uniform_set_cache[i]); + } + render_base_uniform_set_cache[i] = RID(); } - render_base_uniform_set = RID(); } -void RenderForwardMobile::_update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers) { +void RenderForwardMobile::_update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers, BaseUniformSetCache p_cache_index) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); - if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != light_storage->lightmap_array_get_version())) { - if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { - RD::get_singleton()->free(render_base_uniform_set); + if (render_base_uniform_set_cache[p_cache_index].is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set_cache[p_cache_index]) || (lightmap_texture_array_version_cache[p_cache_index] != light_storage->lightmap_array_get_version())) { + if (render_base_uniform_set_cache[p_cache_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set_cache[p_cache_index])) { + RD::get_singleton()->free(render_base_uniform_set_cache[p_cache_index]); } - // This is all loaded into set 0 - - lightmap_texture_array_version = light_storage->lightmap_array_get_version(); + lightmap_texture_array_version_cache[p_cache_index] = light_storage->lightmap_array_get_version(); Vector<RD::Uniform> uniforms; @@ -1699,8 +1708,9 @@ void RenderForwardMobile::_update_render_base_uniform_set(const RendererRD::Mate uniforms.append_array(p_samplers.get_uniforms(SAMPLERS_BINDING_FIRST_INDEX)); - render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET); + render_base_uniform_set_cache[p_cache_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET); } + render_base_uniform_set = render_base_uniform_set_cache[p_cache_index]; } RID RenderForwardMobile::_render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index c8e42e2cf1..f10d3c1568 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -198,9 +198,19 @@ private: RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0); void _pre_opaque_render(RenderDataRD *p_render_data); - uint64_t lightmap_texture_array_version = 0xFFFFFFFF; + enum BaseUniformSetCache { + BASE_UNIFORM_SET_CACHE_VIEWPORT, + BASE_UNIFORM_SET_CACHE_DEFAULT, + BASE_UNIFORM_SET_CACHE_MAX + }; + + // One for custom samplers, one for default samplers. + // Need to switch between them as default is needed for probes, shadows, materials, etc. + RID render_base_uniform_set_cache[BASE_UNIFORM_SET_CACHE_MAX]; + + uint64_t lightmap_texture_array_version_cache[BASE_UNIFORM_SET_CACHE_MAX] = { 0xFFFFFFFF, 0xFFFFFFFF }; - void _update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers); + void _update_render_base_uniform_set(const RendererRD::MaterialStorage::Samplers &p_samplers, BaseUniformSetCache p_cache_index); void _update_instance_data_buffer(RenderListType p_render_list); void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 620262f30e..43615f0d7e 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -635,7 +635,8 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint // If using compression we store tangent while storing vertices. if (!(p_format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES)) { Variant::Type type = p_arrays[ai].get_type(); - ERR_FAIL_COND_V(type != Variant::PACKED_FLOAT32_ARRAY && type != Variant::PACKED_FLOAT64_ARRAY, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(type != Variant::PACKED_FLOAT32_ARRAY && type != Variant::PACKED_FLOAT64_ARRAY && type != Variant::NIL, ERR_INVALID_PARAMETER); + if (type == Variant::PACKED_FLOAT32_ARRAY) { Vector<float> array = p_arrays[ai]; ERR_FAIL_COND_V(array.size() != p_vertex_array_len * 4, ERR_INVALID_PARAMETER); @@ -657,7 +658,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint memcpy(&vw[p_offsets[ai] + i * p_normal_stride], vector, 4); } - } else { // PACKED_FLOAT64_ARRAY + } else if (type == Variant::PACKED_FLOAT64_ARRAY) { Vector<double> array = p_arrays[ai]; ERR_FAIL_COND_V(array.size() != p_vertex_array_len * 4, ERR_INVALID_PARAMETER); const double *src_ptr = array.ptr(); @@ -678,6 +679,30 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint memcpy(&vw[p_offsets[ai] + i * p_normal_stride], vector, 4); } + } else { // No tangent array. + ERR_FAIL_COND_V(p_arrays[RS::ARRAY_NORMAL].get_type() != Variant::PACKED_VECTOR3_ARRAY, ERR_INVALID_PARAMETER); + + Vector<Vector3> normal_array = p_arrays[RS::ARRAY_NORMAL]; + ERR_FAIL_COND_V(normal_array.size() != p_vertex_array_len, ERR_INVALID_PARAMETER); + const Vector3 *normal_src = normal_array.ptr(); + // Set data for tangent. + for (int i = 0; i < p_vertex_array_len; i++) { + // Generate an arbitrary vector that is tangential to normal. + Vector3 tan = Vector3(0.0, 1.0, 0.0).cross(normal_src[i].normalized()); + Vector2 res = tan.octahedron_tangent_encode(1.0); + uint16_t vector[2] = { + (uint16_t)CLAMP(res.x * 65535, 0, 65535), + (uint16_t)CLAMP(res.y * 65535, 0, 65535), + }; + + if (vector[0] == 0 && vector[1] == 65535) { + // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection. + // So we sanitize here. + vector[0] = 65535; + } + + memcpy(&vw[p_offsets[ai] + i * p_normal_stride], vector, 4); + } } } } break; @@ -1172,6 +1197,11 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } break; } ERR_FAIL_COND_V(array_len == 0, ERR_INVALID_DATA); + } else if (i == RS::ARRAY_NORMAL) { + if (p_arrays[RS::ARRAY_TANGENT].get_type() == Variant::NIL) { + // We must use tangents if using normals. + format |= (1ULL << RS::ARRAY_TANGENT); + } } else if (i == RS::ARRAY_BONES) { switch (p_arrays[i].get_type()) { case Variant::PACKED_INT32_ARRAY: { @@ -1242,11 +1272,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa ERR_FAIL_COND_V_MSG(!(format & RS::ARRAY_FORMAT_NORMAL), ERR_INVALID_PARAMETER, "Can't use compression flag 'ARRAY_FLAG_COMPRESS_ATTRIBUTES' while using tangents without normal array."); } - if ((format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && !(format & RS::ARRAY_FORMAT_TANGENT)) { - // If no tangent array provided, we will generate one. - format |= RS::ARRAY_FORMAT_TANGENT; - } - int vertex_array_size = (vertex_element_size + normal_element_size) * array_len; int attrib_array_size = attrib_element_size * array_len; int skin_array_size = skin_element_size * array_len; |
