I think those inaccurate results are caused by invalid ViewportSize. You can use the following script as a workaround.
local worldToScreenPoint = function(viewportFrame, worldPoint)
local camera = viewportFrame.CurrentCamera
local halfWidth = viewportFrame.AbsoluteSize.X / 2
local halfHeight = viewportFrame.AbsoluteSize.Y / 2
local pCamSpace = camera.CFrame:PointToObjectSpace(worldPoint)
local planeDistance = -halfHeight / math.tan(camera.FieldOfView * math.pi / 360)
local nPlaneY = pCamSpace.Y / pCamSpace.Z * planeDistance;
local nPlaneX = pCamSpace.X / pCamSpace.Z * planeDistance;
local visible = pCamSpace.Z < 0 and math.abs(nPlaneX) < halfWidth and math.abs(nPlaneY) < halfHeight
return Vector3.new(halfWidth + nPlaneX, halfHeight - nPlaneY, -pCamSpace.Z), visible
end