Godot 4: Is it possible to set a custom principal point (off-center projection) for Camera3D?

Context

I’m working on a camera-matching / AR-style overlay pipeline in Godot 4, where I need to align a virtual 3D camera with a real calibrated camera.

I have full camera calibration data coming from an external tracking system (similar to OpenCV / broadcast tracking), including:

  • Camera position (XYZ)

  • Camera rotation (Euler, ZYX order)

  • Vertical FOV

  • Image dimensions (1920×1080)

  • Principal point (cx, cy)

The goal is to overlay 3D meshes on top of real video frames pixel-perfectly.

The problem

Godot’s Camera3D seems to assume that the principal point is always at the exact center of the viewport
(i.e. cx = width/2, cy = height/2).

However, in my real camera calibration the principal point is not centered:

"dimensions": [1920, 1080],
"principal_point": [930.7445, 696.3771],
"fovy": 34.63269

This causes a very typical issue:

  • Objects near the center roughly align

  • Objects toward the edges drift and go out of frame

  • There is a visible offset toward the left and bottom of the image

In this moment, this is mi function to calibrate the virtual camera3D:

func camera_calibration(calib: Dictionary, ball: Dictionary):
	camera.fov = calib["fovy"]
	
	var pos = calib["position"]
	camera.global_position = Vector3(pos[0], pos[1], -pos[2])
	
	var rot = calib["rotation"]
	var basis = Basis(
		Vector3(1, 0, 0),   # X
		Vector3(0, 1, 0),   # Y
		Vector3(0, 0, -1)   # -Z 
	)
	basis = basis.rotated(Vector3.FORWARD, rot[2]) # Z
	basis = basis.rotated(Vector3.UP,      rot[1]) # Y
	basis = basis.rotated(Vector3.RIGHT,   rot[0]) # X
	camera.global_transform.basis = basis.orthonormalized()
	
	camera.near = 0.01
	camera.far = 10000.0
	camera.keep_aspect = Camera3D.KEEP_HEIGHT

However, the elements continue to appear in the window. I don’t know if this is a problem with the function or if it is a problem with the main point. Please help me.

Hi,

in theory, the principal point is always in the center.
Maybe there is a mistake in the real camera calibration? Could be easier to fix instead of bending the virtual camera.
Maybe this read helps:

The only option i have in mind is to shift the camera, don`t know if this helps.

func adjust_projection(camera: Camera3D, image_width: int, image_height: int, cx: float, cy: float):
	
	var cx_offset = (cx - (image_width/ 2)) / image_width
	var cy_offset = (cy - (image_height/ 2)) / image_height
	
	var offset = Vector3(cx_offset * camera.global_transform.basis.x.x, 
						cy_offset * camera.global_transform.basis.y.y, 
						0)
	camera.global_position += offset

Then the option to manipulate the projection matrix, but i guess we have no access to this in godot, as far i see from the docs. Also this need to be done every frame, could be quit expensive.

The only way to set the principal point is with Camera3D.set_frustum(). I’ve used it to construct per eye Camera3Ds for VR rendering. The code for that is here: