The method above gives me inaccurate results (the ray direction seems a bit offset). I came up with the following code using the Unproject method of the GraphicsDevice.Viewport and the result is perfect. I also added the groundplane-ray-intersection stuff.
public Vector3 GetMouseWorldPosition(Point screenPosition)
{
Vector3 nearWorldPoint = GraphicsDevice.Viewport.Unproject(new Vector3(screenPosition.X, screenPosition.Y, 0), Projection, View, World);
Vector3 farWorldPoint = GraphicsDevice.Viewport.Unproject(new Vector3(screenPosition.X, screenPosition.Y, 1), Projection, View, World);
Ray ray = new(nearWorldPoint, farWorldPoint - nearWorldPoint);
Plane groundPlane = new(Vector3.Zero, Vector3.UnitZ);
if (ray.Intersects(groundPlane) is float distance)
{
Vector3 intersection = ray.Position + distance * ray.Direction;
return intersection;
}
else return Vector3.Zero;
}
Credits go to: ViewPort Unproject (...) problem.