Boosting 2D Performance with Viewport and Viewport Renderer Enhancements #7424
Replies: 3 comments
-
Maybe you can summarise what you changed, and how it sped things up. 👍 |
Beta Was this translation helpful? Give feedback.
-
I started this project by first removing all code inside #ifndef _3D_DISABLED then started to remove all the 3d releated plugins and code from the editor folder, this was the base of the project so basically comparing the 2 projects with vscode diff folders plugin will show the deleted code, if it's in between an #ifndef _3D_DISABLED then it's fine and if not then you can disable it in 2d builds and also if a file is deleted then you can tell scons to ignore it in 2d builds, now about the changes to the viewport and viewport renderer, while working on this project no performance gain was realized for nearly a week of removing 3d code and testing, until i started removing 3d related checks from the viewport and viewport_renderer then suddenly everything changed and the editor was reacting so fast in an unoptimized build which is connected to vscode debugger. here is a summary of the changes Removed: void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport)
void RendererViewport::_draw_3d(Viewport *p_viewport)
// the code inside the function was removed
void RendererViewport::_draw_viewport(Viewport *p_viewport) {
bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
int scenario_canvas_max_layer = 0;
bool force_clear_render_target = false;
if (RSG::scene->is_scenario(p_viewport->scenario)) {
RID environment = RSG::scene->scenario_get_environment(p_viewport->scenario);
if (RSG::scene->is_environment(environment)) {
if (!p_viewport->disable_2d && !viewport_is_environment_disabled(p_viewport)) {
scenario_draw_canvas_bg = RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS;
scenario_canvas_max_layer = RSG::scene->environment_get_canvas_max_layer(environment);
} else if (RSG::scene->environment_get_background(environment) == RS::ENV_BG_CANVAS) {
// The scene renderer will still copy over the last frame, so we need to clear the render target.
force_clear_render_target = true;
}
}
}
bool can_draw_3d = RSG::scene->is_camera(p_viewport->camera) && !p_viewport->disable_3d;
if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) {
//wants to draw 3D but there is no render buffer, create
p_viewport->render_buffers = RSG::scene->render_buffers_create();
_configure_3d_render_buffers(p_viewport);
}
if (!scenario_draw_canvas_bg && can_draw_3d) {
if (force_clear_render_target) {
RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
}
_draw_3d(p_viewport);
}
if (scenario_draw_canvas_bg && E.key.get_layer() >= scenario_canvas_max_layer) {
// There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
// Clear now otherwise we copy over garbage from the render target.
RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
if (!can_draw_3d) {
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
} else {
_draw_3d(p_viewport);
}
scenario_draw_canvas_bg = false;
}
if (scenario_draw_canvas_bg) {
// There may be an outstanding clear request if a clear was requested, but no 2D elements were drawn.
// Clear now otherwise we copy over garbage from the render target.
RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
if (!can_draw_3d) {
RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas);
} else {
_draw_3d(p_viewport);
}
}
}
// the code inside the function was removed
void RendererViewport::draw_viewports() {
// get our xr interface in case we need it
Ref<XRInterface> xr_interface;
XRServer *xr_server = XRServer::get_singleton();
if (xr_server != nullptr) {
// let our XR server know we're about to render our frames so we can get our frame timing
xr_server->pre_render();
// retrieve the interface responsible for rendering
xr_interface = xr_server->get_primary_interface();
}
if (vp->use_xr) {
if (xr_interface.is_valid()) {
// Ignore update mode we have to commit frames to our XR interface
visible = true;
// Override our size, make sure it matches our required size and is created as a stereo target
Size2 xr_size = xr_interface->get_render_target_size();
_viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count());
} else {
// don't render anything
visible = false;
vp->size = Size2();
}
}
if (vp->use_xr && xr_interface.is_valid()) {
// Inform XR interface we're about to render its viewport,
// if this returns false we don't render.
// This usually is a result of the player taking off their headset and OpenXR telling us to skip
// rendering frames.
if (xr_interface->pre_draw_viewport(vp->render_target)) {
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());
// render...
RSG::scene->set_debug_draw_mode(vp->debug_draw);
// and draw viewport
_draw_viewport(vp);
// commit our eyes
Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) {
if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") {
if (blits.size() > 0) {
RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size());
}
RSG::rasterizer->end_frame(true);
} else if (blits.size() > 0) {
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
}
for (int b = 0; b < blits.size(); b++) {
blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
}
}
}
}
}
viewport->fsr_enabled = !RSG::rasterizer->is_low_end() && !viewport->disable_3d;
}
void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr)
void RendererViewport::viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode)
void RendererViewport::viewport_set_fsr_sharpness(RID p_viewport, float p_sharpness)
void RendererViewport::viewport_set_texture_mipmap_bias(RID p_viewport, float p_mipmap_bias)
void RendererViewport::viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale)
// the code inside the function was removed
void RendererViewport::_viewport_set_size(Viewport *p_viewport, int p_width, int p_height, uint32_t p_view_count) {
_configure_3d_render_buffers(p_viewport);
p_viewport->occlusion_buffer_dirty = true;
}
// the code inside the function was removed
void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
viewport->occlusion_buffer_dirty = true;
}
RID RendererViewport::viewport_get_occluder_debug_texture(RID p_viewport) const
void RendererViewport::viewport_set_prev_camera_data(RID p_viewport, const RendererSceneRender::CameraData *p_camera_data)
const RendererSceneRender::CameraData *RendererViewport::viewport_get_prev_camera_data(RID p_viewport)
void RendererViewport::viewport_set_environment_mode(RID p_viewport, RS::ViewportEnvironmentMode p_mode)
bool RendererViewport::viewport_is_environment_disabled(Viewport *viewport)
void RendererViewport::viewport_set_disable_3d(RID p_viewport, bool p_disable)
void RendererViewport::viewport_set_scenario(RID p_viewport, RID p_scenario)
void RendererViewport::viewport_set_msaa_3d(RID p_viewport, RS::ViewportMSAA p_msaa)
void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode)
void RendererViewport::viewport_set_use_taa(RID p_viewport, bool p_use_taa)
void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding)
void RendererViewport::viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling)
void RendererViewport::viewport_set_occlusion_rays_per_thread(int p_rays_per_thread)
void RendererViewport::viewport_set_occlusion_culling_build_quality(RS::ViewportOcclusionCullingBuildQuality p_quality)
void RendererViewport::viewport_set_mesh_lod_threshold(RID p_viewport, float p_pixels)
void RendererViewport::viewport_set_vrs_mode(RID p_viewport, RS::ViewportVRSMode p_mode)
void RendererViewport::viewport_set_vrs_texture(RID p_viewport, RID p_texture)
// the code inside the function was removed
bool RendererViewport::free(RID p_rid) {
viewport_set_scenario(p_rid, RID());
if (viewport->use_occlusion_culling) {
RendererSceneOcclusionCull::get_singleton()->remove_buffer(p_rid);
}
}
// the code inside the function was removed
RendererViewport::RendererViewport() {
occlusion_rays_per_thread = GLOBAL_GET("rendering/occlusion_culling/occlusion_rays_per_thread");
}
this code is related to 3d rendering and should also goes inside #ifndef _3D_DISABLED |
Beta Was this translation helpful? Give feedback.
-
here are the files to easily compare them with current godot files |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Describe the project you are working on
During the course of my project, where my main focus was on understanding the source code and working extensively with 2D games and tools, I made an astonishing discovery. By making some changes to the viewport and viewport_renderer, I achieved a remarkable efficiency boost in 2D performance. I was amazed to witness the editor's performance skyrocket to nearly 3 times faster in an unoptimized build.
To ensure seamless integration and easy comparison with the Godot Engine repository, I made an effort to keep the project as unchanged as possible. If you're interested in incorporating these recent changes, which have not caused any issues with the editor or export templates, you can find them at this link: GitHub Repository
If anyone cares about better 2D builds of the engine please feel free to join me or to apply some of the changes to the godot engine, note that i have made it possible to build the editor with 3d_disabled.
Beta Was this translation helpful? Give feedback.
All reactions