vtkHardwareSelector - without GPU?

Hi guys,

I have the function below that returns all visible points in the renderer from a mesh obj. Its fast and it is accurate but my understanding is that it requires a GPU. This has been fine as locally there is a GPU but I am moving the application to the cloud and I need to remove the requirement of having to use a GPU as they are very expensive to run 24/7.

So what options are available to me? Is there an alternative that is fast and offers similar results in Paraview but does not require a GPU

    def _project_points_with_hardware_selector(self, renderer, render_window, polydata, width, height):                

        selector = vtkHardwareSelector()
        selector.SetRenderer(renderer)
        selector.SetArea(0, 0, width - 1, height - 1)
        selector.SetFieldAssociation(vtkDataObject.FIELD_ASSOCIATION_POINTS)

        render_window.Render()  # must render before selecting

        selection = selector.Select()
        if not selection:
            print("❌ No selection returned.")
            return [], []

        selected_points = []
        projected_pixels = []

        for node_idx in range(selection.GetNumberOfNodes()):
            node = selection.GetNode(node_idx)
            if not node:
                continue

            id_array = node.GetSelectionList()
            if id_array is None:
                continue

            ids = vtk_to_numpy(id_array)
            for pt_id in ids:
                if 0 <= pt_id < polydata.GetNumberOfPoints():
                    world_pt = polydata.GetPoint(pt_id)
                    selected_points.append(world_pt)                

                    x_ref = vtk.reference(world_pt[0])
                    y_ref = vtk.reference(world_pt[1])
                    z_ref = vtk.reference(world_pt[2])

                    renderer.WorldToDisplay(x_ref, y_ref, z_ref)
                    x2d = x_ref.get()
                    y2d = y_ref.get()
                    flipped_y2d = int(round(height - 1 - y2d))
                    projected_pixels.append((int(round(x2d)), flipped_y2d))                    


        print(f"✅ Selected {len(selected_points)} visible points")
        return projected_pixels, selected_points