How to transform the position of a CanvasItem in a SubViewport to the position of a CanvasItem in a CanvasLayer

Godot Version

Godot_v4.2.2-stable_win64

Question

I’m working on a pixel art game, because the pixel font is too large in the small viewport, so I set the root viewport size to 640 * 360 to display the UI, and the SubViewport size to 320 * 180 to display the main game scene, so the scale of the SubViewportContainer is 2

Here’s a simple scene tree example
Godot_v4.2.2-stable_win64_we5WpAyAFo
The World is the main game scene, the Player can move around, and the Camera2D is the child node of the Player. The Player moves in the SubViewport, while the CanvasLayer remains in position in the root viewport

ItemDebugInfoLabel is used to display the debugging information of the Item, and the following picture is a simple display of the effect.
Godot_v4.2.2-stable_win64_GV1OLfMB8I

I want the ItemDebugInfoLabel to remain in the same relative position with the Item in the CanvasLayer when the Player moves, but I don’t know how to transform the position

I’ve looked up some documentation, like Viewport and canvas transforms, but still don’t have a clue, please help me

I am not sure of the exact details of your game, but I don’t think you need a SubViewport at all. Instead, you could just set the zoom of your camera to 2. That would effectively scale up the game while keeping the UI at the higher resolution.

If you do that, you can transform from world coordinates to your CanvasLayer coordinates by doing something like this:

Node2D targetNode; // Node from the world you want to label
Label itemDebugInfoLabel; // Debug label from the UI

Transform2D transform = targetNode.GetCanvasTransform() * GetCanvasTransform().AffineInverse();
itemDebugInfoLabel.GlobalPosition = transform * targetNode.GlobalPosition;

Hopefully that helps. I am also new to these transforms so it may not be the best solution.