Merge pull request #93786 from alvinhochun/viewport-pixel-snap-fix

Apply "snap 2D transforms to pixel" to viewport
This commit is contained in:
Rémi Verschelde 2024-09-25 12:39:10 +02:00
commit 73bf121ceb
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 22 additions and 1 deletions

View File

@ -83,7 +83,11 @@ void Parallax2D::_validate_property(PropertyInfo &p_property) const {
void Parallax2D::_camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset, const Point2 &p_adj_screen_pos) {
if (!ignore_camera_scroll) {
if (get_viewport() && get_viewport()->is_snap_2d_transforms_to_pixel_enabled()) {
set_screen_offset((p_adj_screen_pos + Vector2(0.5, 0.5)).floor());
Size2 vps = get_viewport_rect().size;
Vector2 offset;
offset.x = ((int)vps.width % 2) ? 0.0 : 0.5;
offset.y = ((int)vps.height % 2) ? 0.0 : 0.5;
set_screen_offset((p_adj_screen_pos + offset).floor());
} else {
set_screen_offset(p_adj_screen_pos);
}

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) {