feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -41,14 +41,31 @@
static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, RendererCanvasCull::Canvas *p_canvas, RendererViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
Transform2D xf = p_viewport->global_transform;
Vector2 pixel_snap_offset;
if (p_viewport->snap_2d_transforms_to_pixel) {
// We use `floor(p + 0.5)` to snap canvas items, but `ceil(p - 0.5)`
// to snap viewport transform because the viewport transform is inverse
// to the camera transform. Also, if the viewport size is not divisible
// by 2, the center point is offset by 0.5 px and we need to add 0.5
// before rounding to cancel it out.
pixel_snap_offset.x = (p_viewport->size.width % 2) ? 0.0 : -0.5;
pixel_snap_offset.y = (p_viewport->size.height % 2) ? 0.0 : -0.5;
}
float scale = 1.0;
if (p_viewport->canvas_map.has(p_canvas->parent)) {
Transform2D c_xform = p_viewport->canvas_map[p_canvas->parent].transform;
if (p_viewport->snap_2d_transforms_to_pixel) {
c_xform.columns[2] = (c_xform.columns[2] * p_canvas->parent_scale + pixel_snap_offset).ceil() / p_canvas->parent_scale;
}
xf = xf * c_xform;
scale = p_canvas->parent_scale;
}
Transform2D c_xform = p_canvas_data->transform;
if (p_viewport->snap_2d_transforms_to_pixel) {
c_xform.columns[2] = (c_xform.columns[2] + pixel_snap_offset).ceil();
}
xf = xf * c_xform;
if (scale != 1.0 && !RSG::canvas->disable_scale) {
@ -113,37 +130,63 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
float scaling_3d_scale = p_viewport->scaling_3d_scale;
RS::ViewportScaling3DMode scaling_3d_mode = p_viewport->scaling_3d_mode;
bool upscaler_available = p_viewport->fsr_enabled;
RS::ViewportScaling3DType scaling_type = RS::scaling_3d_mode_type(scaling_3d_mode);
if ((!upscaler_available || scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_BILINEAR || scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) && scaling_3d_scale >= (1.0 - EPSILON) && scaling_3d_scale <= (1.0 + EPSILON)) {
// No 3D scaling on bilinear or FSR? Ignore scaling mode, this just introduces overhead.
if ((!upscaler_available || (scaling_type == RS::VIEWPORT_SCALING_3D_TYPE_SPATIAL)) && scaling_3d_scale >= (1.0 - EPSILON) && scaling_3d_scale <= (1.0 + EPSILON)) {
// No 3D scaling for spatial modes? Ignore scaling mode, this just introduces overhead.
// - Mobile can't perform optimal path
// - FSR does an extra pass (or 2 extra passes if 2D-MSAA is enabled)
// Scaling = 1.0 on FSR2 has benefits
// Scaling = 1.0 on FSR2 and MetalFX temporal has benefits
scaling_3d_scale = 1.0;
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_OFF;
}
bool scaling_3d_is_fsr = (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR) || (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2);
// Verify MetalFX upscaling support.
if (
(scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_METALFX_TEMPORAL && !RD::get_singleton()->has_feature(RD::SUPPORTS_METALFX_TEMPORAL)) ||
(scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_METALFX_SPATIAL && !RD::get_singleton()->has_feature(RD::SUPPORTS_METALFX_SPATIAL))) {
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
WARN_PRINT_ONCE("MetalFX upscaling is not supported in the current renderer. Falling back to bilinear 3D resolution scaling.");
}
RS::ViewportMSAA msaa_3d = p_viewport->msaa_3d;
// If MetalFX Temporal upscaling is supported, verify limits.
if (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_METALFX_TEMPORAL) {
double min_scale = (double)RD::get_singleton()->limit_get(RD::LIMIT_METALFX_TEMPORAL_SCALER_MIN_SCALE) / 1000'000.0;
double max_scale = (double)RD::get_singleton()->limit_get(RD::LIMIT_METALFX_TEMPORAL_SCALER_MAX_SCALE) / 1000'000.0;
if ((double)scaling_3d_scale < min_scale || (double)scaling_3d_scale > max_scale) {
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
WARN_PRINT_ONCE(vformat("MetalFX temporal upscaling scale is outside limits; scale must be between %f and %f. Falling back to bilinear 3D resolution scaling.", min_scale, max_scale));
}
if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED) {
WARN_PRINT_ONCE("MetalFX temporal upscaling does not support 3D MSAA. Disabling 3D MSAA internally.");
msaa_3d = RS::VIEWPORT_MSAA_DISABLED;
}
}
bool scaling_3d_is_not_bilinear = scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_OFF && scaling_3d_mode != RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
bool use_taa = p_viewport->use_taa;
if (scaling_3d_is_fsr && (scaling_3d_scale >= (1.0 + EPSILON))) {
if (scaling_3d_is_not_bilinear && (scaling_3d_scale >= (1.0 + EPSILON))) {
// FSR is not designed for downsampling.
// Fall back to bilinear scaling.
WARN_PRINT_ONCE("FSR 3D resolution scaling is not designed for downsampling. Falling back to bilinear 3D resolution scaling.");
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
}
if (scaling_3d_is_fsr && !upscaler_available) {
if (scaling_3d_is_not_bilinear && !upscaler_available) {
// FSR is not actually available.
// Fall back to bilinear scaling.
WARN_PRINT_ONCE("FSR 3D resolution scaling is not available. Falling back to bilinear 3D resolution scaling.");
scaling_3d_mode = RS::VIEWPORT_SCALING_3D_MODE_BILINEAR;
}
if (use_taa && scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2) {
if (use_taa && (scaling_type == RS::VIEWPORT_SCALING_3D_TYPE_TEMPORAL)) {
// FSR2 can't be used with TAA.
// Turn it off and prefer using FSR2.
WARN_PRINT_ONCE("FSR 2 is not compatible with TAA. Disabling TAA internally.");
WARN_PRINT_ONCE("FSR 2 or MetalFX Temporal is not compatible with TAA. Disabling TAA internally.");
use_taa = false;
}
@ -161,6 +204,8 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
render_width = CLAMP(target_width * scaling_3d_scale, 1, 16384);
render_height = CLAMP(target_height * scaling_3d_scale, 1, 16384);
break;
case RS::VIEWPORT_SCALING_3D_MODE_METALFX_SPATIAL:
case RS::VIEWPORT_SCALING_3D_MODE_METALFX_TEMPORAL:
case RS::VIEWPORT_SCALING_3D_MODE_FSR:
case RS::VIEWPORT_SCALING_3D_MODE_FSR2:
target_width = p_viewport->size.width;
@ -187,8 +232,9 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
}
uint32_t jitter_phase_count = 0;
if (scaling_3d_mode == RS::VIEWPORT_SCALING_3D_MODE_FSR2) {
if (scaling_type == RS::VIEWPORT_SCALING_3D_TYPE_TEMPORAL) {
// Implementation has been copied from ffxFsr2GetJitterPhaseCount.
// Also used for MetalFX Temporal scaling.
jitter_phase_count = uint32_t(8.0f * pow(float(target_width) / render_width, 2.0f));
} else if (use_taa) {
// Default jitter count for TAA.
@ -208,10 +254,11 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
rb_config.set_target_size(Size2(target_width, target_height));
rb_config.set_view_count(p_viewport->view_count);
rb_config.set_scaling_3d_mode(scaling_3d_mode);
rb_config.set_msaa_3d(p_viewport->msaa_3d);
rb_config.set_msaa_3d(msaa_3d);
rb_config.set_screen_space_aa(p_viewport->screen_space_aa);
rb_config.set_fsr_sharpness(p_viewport->fsr_sharpness);
rb_config.set_texture_mipmap_bias(texture_mipmap_bias);
rb_config.set_anisotropic_filtering_level(p_viewport->anisotropic_filtering_level);
rb_config.set_use_taa(use_taa);
rb_config.set_use_debanding(p_viewport->use_debanding);
@ -385,7 +432,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
tsize *= cl->scale;
Vector2 offset = tsize / 2.0;
cl->rect_cache = Rect2(-offset + cl->texture_offset, tsize);
Rect2 local_rect = Rect2(-offset + cl->texture_offset, tsize);
if (!RSG::canvas->_interpolation_data.interpolation_enabled || !cl->interpolated) {
cl->xform_cache = xf * cl->xform_curr;
@ -395,22 +442,24 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
cl->xform_cache = xf * cl->xform_cache;
}
if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) {
cl->rect_cache = cl->xform_cache.xform(local_rect);
if (clip_rect.intersects(cl->rect_cache)) {
cl->filter_next_ptr = lights;
lights = cl;
Transform2D scale;
scale.scale(cl->rect_cache.size);
scale.columns[2] = cl->rect_cache.position;
scale.scale(local_rect.size);
scale.columns[2] = local_rect.position;
cl->light_shader_xform = cl->xform_cache * scale;
if (cl->use_shadow) {
cl->shadows_next_ptr = lights_with_shadow;
if (lights_with_shadow == nullptr) {
shadow_rect = cl->xform_cache.xform(cl->rect_cache);
shadow_rect = cl->rect_cache;
} else {
shadow_rect = shadow_rect.merge(cl->xform_cache.xform(cl->rect_cache));
shadow_rect = shadow_rect.merge(cl->rect_cache);
}
lights_with_shadow = cl;
cl->radius_cache = cl->rect_cache.size.length();
cl->radius_cache = local_rect.size.length();
}
}
}
@ -481,7 +530,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
while (light) {
RENDER_TIMESTAMP("Render PointLight2D Shadow");
RSG::canvas_render->light_update_shadow(light->light_internal, shadow_count++, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders);
RSG::canvas_render->light_update_shadow(light->light_internal, shadow_count++, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders, light->rect_cache);
light = light->shadows_next_ptr;
}
@ -772,7 +821,18 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
RSG::texture_storage->render_target_set_override(vp->render_target,
xr_interface->get_color_texture(),
xr_interface->get_depth_texture(),
xr_interface->get_velocity_texture());
xr_interface->get_velocity_texture(),
xr_interface->get_velocity_depth_texture());
RSG::texture_storage->render_target_set_velocity_target_size(vp->render_target, xr_interface->get_velocity_target_size());
if (xr_interface->get_velocity_texture().is_valid()) {
viewport_set_force_motion_vectors(vp->self, true);
} else {
viewport_set_force_motion_vectors(vp->self, false);
}
RSG::texture_storage->render_target_set_render_region(vp->render_target, xr_interface->get_render_region());
// render...
RSG::scene->set_debug_draw_mode(vp->debug_draw);
@ -818,17 +878,17 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
blit.dst_rect.size = vp->size;
}
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
}
if (OS::get_singleton()->get_current_rendering_driver_name().begins_with("opengl3")) {
Vector<BlitToScreen> blit_to_screen_vec;
blit_to_screen_vec.push_back(blit);
RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blit_to_screen_vec.ptr(), 1);
RSG::rasterizer->gl_end_frame(p_swap_buffers);
} else {
blit_to_screen_list[vp->viewport_to_screen].push_back(blit);
Vector<BlitToScreen> *blits = blit_to_screen_list.getptr(vp->viewport_to_screen);
if (blits == nullptr) {
blits = &blit_to_screen_list.insert(vp->viewport_to_screen, Vector<BlitToScreen>())->value;
}
blits->push_back(blit);
}
}
}
@ -933,6 +993,14 @@ void RendererViewport::viewport_set_texture_mipmap_bias(RID p_viewport, float p_
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_anisotropic_filtering_level(RID p_viewport, RS::ViewportAnisotropicFiltering p_anisotropic_filtering_level) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_NULL(viewport);
viewport->anisotropic_filtering_level = p_anisotropic_filtering_level;
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_NULL(viewport);
@ -972,7 +1040,9 @@ void RendererViewport::_viewport_set_size(Viewport *p_viewport, int p_width, int
}
bool RendererViewport::_viewport_requires_motion_vectors(Viewport *p_viewport) {
return p_viewport->use_taa || p_viewport->scaling_3d_mode == RenderingServer::VIEWPORT_SCALING_3D_MODE_FSR2 || p_viewport->debug_draw == RenderingServer::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS;
return p_viewport->use_taa ||
RS::scaling_3d_mode_type(p_viewport->scaling_3d_mode) == RS::VIEWPORT_SCALING_3D_TYPE_TEMPORAL ||
p_viewport->debug_draw == RenderingServer::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS || p_viewport->force_motion_vectors;
}
void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
@ -1271,6 +1341,13 @@ void RendererViewport::viewport_set_use_hdr_2d(RID p_viewport, bool p_use_hdr_2d
RSG::texture_storage->render_target_set_use_hdr(viewport->render_target, p_use_hdr_2d);
}
bool RendererViewport::viewport_is_using_hdr_2d(RID p_viewport) const {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_NULL_V(viewport, false);
return viewport->use_hdr_2d;
}
void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_NULL(viewport);
@ -1313,6 +1390,25 @@ void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_deb
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_force_motion_vectors(RID p_viewport, bool p_force_motion_vectors) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_NULL(viewport);
if (viewport->force_motion_vectors == p_force_motion_vectors) {
return;
}
bool motion_vectors_before = _viewport_requires_motion_vectors(viewport);
viewport->force_motion_vectors = p_force_motion_vectors;
bool motion_vectors_after = _viewport_requires_motion_vectors(viewport);
if (motion_vectors_before != motion_vectors_after) {
num_viewports_with_motion_vectors += motion_vectors_after ? 1 : -1;
}
_configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_NULL(viewport);