One naive approach would be to measure the distance from the scanner origin to the Position of the point, normalize that, clamp between 0 and 1, subtract from 1, add a Power operator for the bias, and output the result as Selection, defining the probability for deletion using a Krakatoa Delete set to Soft-Selection. This does not take into account the neighbors, just how far the point is from the origin. The closer to the origin, the more likely each point is to be deleted, with farther points not being deleted at all.
I tested it, but it may produce some larger holes in case multiple points in the same vicinity decide they should be gone.
A better approach would be to search for the number of neighbors within a given distance using ParticleSumRadius, and again calculating a probability for deletion based on that - the more the neighbors, the higher the probability for each one of them to be deleted. It has two issues - you need a proxy copy of the original point cloud (so two PRT Loaders instead of one), and you cannot easily control the number of points per unit volume to be left with, because each point decides for itself.
A more advanced and similar to the Recap approach method would be to use a Stoke Field Magma (if you have Stoke) to create a grid around the point cloud and register the actual count in each voxel. Again, make a copy of the PRT Loader (the first is used as the source for the grid), and on the copy add a Magma which looks up the value in the Field Magma grid, and set a probability for every point inside that voxel based on its volume and the number of points in it.
If you don’t have Stoke, you can set up something similar by creating a Box primitive around the point cloud, and generating a PRT Volume with Jitter off to represent the grid. Use a Magma with ParticleSumRadius and collect counts from the first PRT Loader in a custom channel. This won’t be exactly correct because we are using a sphere radius to search instead of a cubic voxel, but it would be close enough. Then use the second PRT Loader to read the counts from the nearest PRT Volume point (representing the voxel grid), and set the Selection using the same logic as in the previous example.
For example, if you want 10 particles per cubic unit, and your voxel has the volume, but you got a point count of 20 in it, you need to delete 50% of the points. Setting a Selection channel value to 0.5 will tell the Krakatoa Delete operator to delete each point with a probability of 50%. You might not get exactly 10 after the Delete modifier, but it will be close. If the voxel has a different volume than an unit volume, you can easily adjust the requested density to the actual density of the voxel, get the actual count, and figure out the necessary deletion probability for the Selection channel.
I will see if I can set up and post some test…