class_name ViewUtils extends RefCounted # Computes the exact world-space rect currently visible on screen by # transforming the viewport's real screen corners through the actual canvas # transform, instead of approximating with viewport_size * camera.zoom # (which assumes a simple centered mapping - stretch/aspect="expand" doesn't # necessarily expand symmetrically around center, which was making that # approximation under/over-shoot on one side and cull content that was # actually on screen). static func get_visible_world_rect(node: Node) -> Rect2: var canvas_transform: Transform2D = node.get_viewport().get_canvas_transform() var inverse: Transform2D = canvas_transform.affine_inverse() var size: Vector2 = node.get_viewport_rect().size var corners: Array = [ inverse * Vector2(0, 0), inverse * Vector2(size.x, 0), inverse * Vector2(0, size.y), inverse * Vector2(size.x, size.y), ] var min_pt: Vector2 = corners[0] var max_pt: Vector2 = corners[0] for c in corners: min_pt.x = min(min_pt.x, c.x) min_pt.y = min(min_pt.y, c.y) max_pt.x = max(max_pt.x, c.x) max_pt.y = max(max_pt.y, c.y) return Rect2(min_pt, max_pt - min_pt)