This is a problem with many possible approaches, so maybe someone else will come with a better/easier solution. But I will describe two possible approaches that I can think of, and that I might explore if I were you.
Option 1: Rejection sampling
- Pick a random point anywhere on the canvas / bowtie bounding box / any area you choose that contains the bowtie texture
- Pick randomly a size and colour according to your application
- Check if the generated point is OK(fits within the bowtie, eventual overlaps with other points etc). If yes, you've got a point: return.
- If not, then repeat step 1.
This might be sufficient if you can consider your texture as somewhat flat and can just draw your points on top of it, as you seem to be doing in your example image here. You need to be careful with your limits though to not get stuck in an infinite loop.
Option 2: Correct surface sapling
- Pick a triangle on your bowtie mesh randomly. If you want to be mathematically correct, then make sure the probability is proportional to the area (you can do this e.g. by creating a cumulative array of the triangle areas and running a binary search over it)
- Randomly pick a point inside that triangle (some math to help with this)
- Give it an area and colour according to your app
- Map it back to your texture. The point will be guaranteed to be on the tie, but you can check if its radius also fits
- If you wish, you can then still check for overlaps with other points, and perform rejection sampling
This option sounds like overkill for your application, but if you want the distribution to better follow the curvature of your bowtie, then this would give you a probabilistically more correct result. It also allows you to texture map the points correctly, if you want to get into that math.
Rendering them in GLSL:
As for GLSL shaders, you can certainly render random circles on GLSL and it will be more performant almost for sure. However, this seems like a one-time computation that you can precompute for your various bowties and dot frequencies, after which your current solution will be perfectly fast. Your solution will also give you more power over the point generation, as you said yourself. Rendering random circles on a flat surface in a GLSL fragment shader should not be very hard, but doing it on a complex surface like these bowties might make it a bit trickier. If you want to know how this could be done, consider posting a new question.