From 1ddb85e9949e52c1e420e14f30f74566135a0e5e Mon Sep 17 00:00:00 2001 From: Adam Scott Date: Sun, 31 Dec 2023 13:29:51 -0500 Subject: [PATCH] Fix sprite crunch at half-pixels --- drivers/gles3/rasterizer_canvas_gles3.cpp | 17 ++++++++++++++++- .../renderer_rd/renderer_canvas_render_rd.cpp | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 5d6cef6e056b..8e2da69808a8 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -849,7 +849,22 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend if (c->type != Item::Command::TYPE_MESH) { // For Meshes, this gets updated below. - _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world); + Transform2D final_transform = base_transform * draw_transform; + + // Make sure to round nearest filtered textures to avoid sprite "crunching". + // We don't round linear filtered textures because it would look identical to nearest filtering. + switch (p_item->texture_filter) { + case RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST: + case RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: + case RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: { + final_transform.set_origin(final_transform.get_origin().round()); + } break; + default: { + // Do nothing. + } + } + + _update_transform_2d_to_mat2x3(final_transform, state.instance_data_array[r_index].world); } // Zero out most fields. diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 657628111ae0..ec12edad9c39 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -425,6 +425,20 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend PushConstant push_constant; Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform; + + // Make sure to round nearest filtered textures to avoid sprite "crunching". + // We don't round linear filtered textures because it would look identical to nearest filtering. + switch (p_item->texture_filter) { + case RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST: + case RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: + case RS::CanvasItemTextureFilter::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: { + base_transform.set_origin(base_transform.get_origin().round()); + } break; + default: { + // Do nothing. + } + } + Transform2D draw_transform; _update_transform_2d_to_mat2x3(base_transform, push_constant.world);