Draw circle within UV islands on Canvas texture

Hello, I need to draw the exact number of circles with different size on a bowtie model, I have exported the model from blender with unwrapped UV:

I am using canvas texture to draw the circles, but how can I draw the circle only within a UV islands avoiding drawing outside the model (I need to draw exactly 1-100 circles within the bowtie)

Screenshot 2022-12-04 at 23.33.06

I also get these stretch circles so I believe I need to come up with UV island edge detection algorithm that will avoid placing the circle too close to the edge
Screenshot 2022-12-04 at 23.29.26

I was trying to draw using glsl shaders:

varying vec2 vectorUV;
varying vec3 vectorNormal;
uniform vec2 u_resolution; 
uniform vec2 coords[400];

vec3 get_circle(vec2 position, vec3 color, float size) {
  float circle = sqrt(pow(position.x, 2.0)+pow(position.y, 2.0));
  circle = smoothstep(size, size + 0.00003 , 1.0-circle);

  return circle * color; 

float random (vec2 st) {
  return fract(sin(dot(st.xy,vec2(12.9898,78.233))) * 43758.5453123);

void main() {
  vec2 st = vectorUV;
  vec3 canvas = vec3(0.0);
  for (int j = 0; j < 400; j += 1){
    float s = float(j);
    float x = coords[j].x;
    float y = coords[j].y;
    canvas += get_circle(st - vec2(x , y), vec3(0.384, 0.847, 0.603), 0.998);
  gl_FragColor = vec4(canvas, 1.0);

it gives me glowing circles, but the material doesn’t represents a model (it is just black texture in form of bowtie without any details) and it renders much slower probably because of the loop in shaders
Screenshot 2022-12-04 at 23.41.06

Not probably, but exactly because of that loop for 400 iterations per pixel.
Maybe makes sense to use randomness in shader. :thinking:

Each user will see their own version of bowties, but every time user reloads the page the circles must be on the same spots, that’s why I need to send the information about the circle coordinates from JS side to glsl. I think I will use canvas method but I am not really sure how to avoid stretching and make algorithm that draws inside the UV islands. I was thinking about manually paint non uv areas and then using pixel sampling determine is the point is suitable for drawing a circle or not. But I wanted to ask first, maybe you guys know some better methods

btw, don’t you know how can I achieve more saturated colors of canvas texture? shader texture has more bright colors than canvas for some reason

Is it an option to use MeshSurfaceSampler from @donmccurdy?

PS If you’re still looking for randomness in fragment shader, here is an option: https://codepen.io/prisoner849/pen/dyKQEVj?editors=0010

1 Like

Roughly speaking your islands can be put into boxes.
What is stopping you from measuring uv range of each box on the first image you provided and then creating your canvas texture with circles within those boxes?

Better yet, if you have computational time, you could take your first image and paint the area, you want to make circles across, with some color, say red.

Then, run the circle creation routine across a new image of the same size and make circles only if corresponding circle center is in red on the first image. Will also allow you not to get too close to the edge.

1 Like