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;