diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index a19e13c35348..8f410b42ff02 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -173,6 +173,14 @@
Sets camera to use perspective projection. Objects on the screen becomes smaller when they are far away.
+
+
+
+
+
+ Set camera scale, modifying aspect ratio.
+
+
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 0c84348b6991..9adfea51de69 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -106,6 +106,15 @@ void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p
camera->zfar = p_z_far;
}
+void RendererSceneCull::camera_set_scale(RID p_camera, Vector2 p_scale) {
+ Camera *camera = camera_owner.get_or_null(p_camera);
+ ERR_FAIL_NULL(camera);
+ ERR_FAIL_COND(p_scale.is_zero_approx());
+ ERR_FAIL_COND(p_scale.x < 0.0 || p_scale.y < 0.0);
+ camera->scale = p_scale;
+ camera->use_scale = (p_scale != Vector2(1.0, 1.0));
+}
+
void RendererSceneCull::camera_set_transform(RID p_camera, const Transform3D &p_transform) {
Camera *camera = camera_owner.get_or_null(p_camera);
ERR_FAIL_NULL(camera);
@@ -2654,7 +2663,10 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu
is_frustum = true;
} break;
}
-
+ if (camera->use_scale) {
+ projection.columns[0][0] *= camera->scale.x;
+ projection.columns[1][1] *= camera->scale.y;
+ }
camera_data.set_camera(transform, projection, is_orthogonal, is_frustum, vaspect, jitter, taa_frame_count, camera->visible_layers);
#ifndef XR_DISABLED
} else {
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index 6f7c303ff081..aa0763e869d9 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -81,12 +81,15 @@ class RendererSceneCull : public RenderingMethod {
float znear, zfar;
float size;
Vector2 offset;
+ Vector2 scale = Vector2(1.0, 1.0);
uint32_t visible_layers;
bool vaspect;
+ bool use_scale = false;
RID env;
RID attributes;
RID compositor;
+ Projection projection;
Transform3D transform;
Camera() {
@@ -109,6 +112,7 @@ class RendererSceneCull : public RenderingMethod {
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far);
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far);
+ virtual void camera_set_scale(RID p_camera, Vector2 p_scale);
virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform);
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers);
virtual void camera_set_environment(RID p_camera, RID p_env);
diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h
index 38e173bf48f2..e4558c8d762a 100644
--- a/servers/rendering/rendering_method.h
+++ b/servers/rendering/rendering_method.h
@@ -49,6 +49,7 @@ class RenderingMethod {
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0;
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0;
virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0;
+ virtual void camera_set_scale(RID p_camera, Vector2 p_scale) = 0;
virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform) = 0;
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
virtual void camera_set_environment(RID p_camera, RID p_env) = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 3c198652b23b..1e521663915c 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -672,6 +672,7 @@ class RenderingServerDefault : public RenderingServer {
FUNC4(camera_set_perspective, RID, float, float, float)
FUNC4(camera_set_orthogonal, RID, float, float, float)
FUNC5(camera_set_frustum, RID, float, Vector2, float, float)
+ FUNC2(camera_set_scale, RID, Vector2)
FUNC2(camera_set_transform, RID, const Transform3D &)
FUNC2(camera_set_cull_mask, RID, uint32_t)
FUNC2(camera_set_environment, RID, RID)
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 8202dff8cbe2..97d7cd405990 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2811,6 +2811,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("camera_set_perspective", "camera", "fovy_degrees", "z_near", "z_far"), &RenderingServer::camera_set_perspective);
ClassDB::bind_method(D_METHOD("camera_set_orthogonal", "camera", "size", "z_near", "z_far"), &RenderingServer::camera_set_orthogonal);
ClassDB::bind_method(D_METHOD("camera_set_frustum", "camera", "size", "offset", "z_near", "z_far"), &RenderingServer::camera_set_frustum);
+ ClassDB::bind_method(D_METHOD("camera_set_scale", "camera", "scale"), &RenderingServer::camera_set_scale);
ClassDB::bind_method(D_METHOD("camera_set_transform", "camera", "transform"), &RenderingServer::camera_set_transform);
ClassDB::bind_method(D_METHOD("camera_set_cull_mask", "camera", "layers"), &RenderingServer::camera_set_cull_mask);
ClassDB::bind_method(D_METHOD("camera_set_environment", "camera", "env"), &RenderingServer::camera_set_environment);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index a5a62b9653f4..ecbf71742363 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -913,6 +913,7 @@ class RenderingServer : public Object {
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0;
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0;
virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0;
+ virtual void camera_set_scale(RID p_camera, Vector2 p_scale) = 0;
virtual void camera_set_transform(RID p_camera, const Transform3D &p_transform) = 0;
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
virtual void camera_set_environment(RID p_camera, RID p_env) = 0;