2
0
Эх сурвалжийг харах

Merge pull request #35406 from lawnjelly/ortho-shadow

Replace CameraMatrix::get_viewport_size with get_viewport_half_extents, shadow culling with ortho camera and other affected issues
Rémi Verschelde 5 жил өмнө
parent
commit
37897dba80

+ 4 - 6
core/math/camera_matrix.cpp

@@ -247,7 +247,7 @@ real_t CameraMatrix::get_z_near() const {
 	return new_plane.d;
 }
 
-void CameraMatrix::get_viewport_size(real_t &r_width, real_t &r_height) const {
+Vector2 CameraMatrix::get_viewport_half_extents() const {
 
 	const real_t *matrix = (const real_t *)this->matrix;
 	///////--- Near Plane ---///////
@@ -273,8 +273,7 @@ void CameraMatrix::get_viewport_size(real_t &r_width, real_t &r_height) const {
 	Vector3 res;
 	near_plane.intersect_3(right_plane, top_plane, &res);
 
-	r_width = res.x;
-	r_height = res.y;
+	return Vector2(res.x, res.y);
 }
 
 bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
@@ -563,9 +562,8 @@ CameraMatrix::operator String() const {
 
 real_t CameraMatrix::get_aspect() const {
 
-	real_t w, h;
-	get_viewport_size(w, h);
-	return w / h;
+	Vector2 vp_he = get_viewport_half_extents();
+	return vp_he.x / vp_he.y;
 }
 
 int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const {

+ 1 - 1
core/math/camera_matrix.h

@@ -73,7 +73,7 @@ struct CameraMatrix {
 	Vector<Plane> get_projection_planes(const Transform &p_transform) const;
 
 	bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const;
-	void get_viewport_size(real_t &r_width, real_t &r_height) const;
+	Vector2 get_viewport_half_extents() const;
 
 	void invert();
 	CameraMatrix inverse() const;

+ 4 - 4
drivers/gles2/rasterizer_scene_gles2.cpp

@@ -2658,14 +2658,14 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
 	};
 
 	if (!asymmetrical) {
-		float vw, vh, zn;
-		camera.get_viewport_size(vw, vh);
+		Vector2 vp_he = camera.get_viewport_half_extents();
+		float zn;
 		zn = p_projection.get_z_near();
 
 		for (int i = 0; i < 4; i++) {
 			Vector3 uv = vertices[i * 2 + 1];
-			uv.x = (uv.x * 2.0 - 1.0) * vw;
-			uv.y = -(uv.y * 2.0 - 1.0) * vh;
+			uv.x = (uv.x * 2.0 - 1.0) * vp_he.x;
+			uv.y = -(uv.y * 2.0 - 1.0) * vp_he.y;
 			uv.z = -zn;
 			vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
 			vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;

+ 11 - 7
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -2497,14 +2497,14 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
 	};
 
 	if (!asymmetrical) {
-		float vw, vh, zn;
-		camera.get_viewport_size(vw, vh);
+		Vector2 vp_he = camera.get_viewport_half_extents();
+		float zn;
 		zn = p_projection.get_z_near();
 
 		for (int i = 0; i < 4; i++) {
 			Vector3 uv = vertices[i * 2 + 1];
-			uv.x = (uv.x * 2.0 - 1.0) * vw;
-			uv.y = -(uv.y * 2.0 - 1.0) * vh;
+			uv.x = (uv.x * 2.0 - 1.0) * vp_he.x;
+			uv.y = -(uv.y * 2.0 - 1.0) * vp_he.y;
 			uv.z = -zn;
 			vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
 			vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
@@ -4130,11 +4130,15 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
 	state.ubo_data.shadow_dual_paraboloid_render_zfar = 0;
 	state.ubo_data.opaque_prepass_threshold = 0.99;
 
-	p_cam_projection.get_viewport_size(state.ubo_data.viewport_size[0], state.ubo_data.viewport_size[1]);
+	int viewport_width_pixels = storage->frame.current_rt->width;
+	int viewport_height_pixels = storage->frame.current_rt->height;
+
+	state.ubo_data.viewport_size[0] = viewport_width_pixels;
+	state.ubo_data.viewport_size[1] = viewport_height_pixels;
 
 	if (storage->frame.current_rt) {
-		state.ubo_data.screen_pixel_size[0] = 1.0 / storage->frame.current_rt->width;
-		state.ubo_data.screen_pixel_size[1] = 1.0 / storage->frame.current_rt->height;
+		state.ubo_data.screen_pixel_size[0] = 1.0 / viewport_width_pixels;
+		state.ubo_data.screen_pixel_size[1] = 1.0 / viewport_height_pixels;
 	}
 
 	_setup_environment(env, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());

+ 2 - 3
editor/plugins/spatial_editor_plugin.cpp

@@ -428,8 +428,7 @@ Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
 	} else {
 		cm.set_perspective(get_fov(), get_size().aspect(), get_znear() + p_vector3.z, get_zfar());
 	}
-	float screen_w, screen_h;
-	cm.get_viewport_size(screen_w, screen_h);
+	Vector2 screen_he = cm.get_viewport_half_extents();
 
 	Transform camera_transform;
 	camera_transform.translate(cursor.pos);
@@ -437,7 +436,7 @@ Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
 	camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
 	camera_transform.translate(0, 0, cursor.distance);
 
-	return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_w, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_h, -(get_znear() + p_vector3.z)));
+	return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_he.y, -(get_znear() + p_vector3.z)));
 }
 
 void SpatialEditorViewport::_select_region() {

+ 4 - 6
scene/3d/arvr_nodes.cpp

@@ -85,9 +85,8 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const {
 	Vector3 ray;
 
 	CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
-	float screen_w, screen_h;
-	cm.get_viewport_size(screen_w, screen_h);
-	ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_w, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_h, -get_znear()).normalized();
+	Vector2 screen_he = cm.get_viewport_half_extents();
+	ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized();
 
 	return ray;
 };
@@ -138,13 +137,12 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con
 
 	CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
 
-	Size2 vp_size;
-	cm.get_viewport_size(vp_size.x, vp_size.y);
+	Vector2 vp_he = cm.get_viewport_half_extents();
 
 	Vector2 point;
 	point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
 	point.y = (1.0 - (p_point.y / viewport_size.y)) * 2.0 - 1.0;
-	point *= vp_size;
+	point *= vp_he;
 
 	Vector3 p(point.x, point.y, -p_z_depth);
 

+ 4 - 6
scene/3d/camera.cpp

@@ -291,9 +291,8 @@ Vector3 Camera::project_local_ray_normal(const Point2 &p_pos) const {
 	} else {
 		CameraMatrix cm;
 		cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
-		float screen_w, screen_h;
-		cm.get_viewport_size(screen_w, screen_h);
-		ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_w, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_h, -near).normalized();
+		Vector2 screen_he = cm.get_viewport_half_extents();
+		ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -near).normalized();
 	}
 
 	return ray;
@@ -402,13 +401,12 @@ Vector3 Camera::project_position(const Point2 &p_point, float p_z_depth) const {
 	else
 		cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
 
-	Size2 vp_size;
-	cm.get_viewport_size(vp_size.x, vp_size.y);
+	Vector2 vp_he = cm.get_viewport_half_extents();
 
 	Vector2 point;
 	point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
 	point.y = (1.0 - (p_point.y / viewport_size.y)) * 2.0 - 1.0;
-	point *= vp_size;
+	point *= vp_he;
 
 	Vector3 p(point.x, point.y, -p_z_depth);
 

+ 7 - 7
servers/visual/visual_server_scene.cpp

@@ -1400,9 +1400,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();
@@ -2090,8 +2090,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)) {
 
@@ -2117,7 +2117,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: {
 
@@ -2146,7 +2146,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: {