From eaf8e5ce52331d05ee117c21e114ab0990dd3a9b Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Tue, 21 Jan 2020 18:39:16 +0000 Subject: Change CameraMatrix::get_viewport_size to get_viewport_half_extents Fixes #26637. Fixes #19900. The viewport_size returned by get_viewport_size was previously incorrect, being half the correct value. The function is renamed to get_viewport_half_extents, and now returns a Vector2. Code which called this function has also been modified accordingly. This PR also fixes shadow culling when using ortho cameras, because the correct input for CameraMatrix::set_orthogonal should be the full HEIGHT from get_viewport_half_extents, and not half the width. It also fixes state.ubo_data.viewport_size in rasterizer_scene_gles3.cpp to be the width and the height of the viewport in pixels as stated in the documentation, rather than the current value which is half the viewport extents in worldspace, presumed to be a bug. --- servers/visual/visual_server_scene.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'servers/visual') diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index bf9db616e4..ede906bf06 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -1398,9 +1398,9 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons if (p_cam_orthogonal) { - float w, h; - p_cam_projection.get_viewport_size(w, h); - camera_matrix.set_orthogonal(w, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); + + camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } else { float fov = p_cam_projection.get_fov(); @@ -2088,8 +2088,8 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca float zn = p_cam_projection.get_z_near(); Plane p(cam_xf.origin + cam_xf.basis.get_axis(2) * -zn, -cam_xf.basis.get_axis(2)); //camera near plane - float vp_w, vp_h; //near plane size in screen coordinates - p_cam_projection.get_viewport_size(vp_w, vp_h); + // near plane half width and height + Vector2 vp_half_extents = p_cam_projection.get_viewport_half_extents(); switch (VSG::storage->light_get_type(ins->base)) { @@ -2115,7 +2115,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca } float screen_diameter = points[0].distance_to(points[1]) * 2; - coverage = screen_diameter / (vp_w + vp_h); + coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y); } break; case VS::LIGHT_SPOT: { @@ -2144,7 +2144,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca } float screen_diameter = points[0].distance_to(points[1]) * 2; - coverage = screen_diameter / (vp_w + vp_h); + coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y); } break; default: { -- cgit v1.2.3