Efficient code for shortest distance inside a fragment shader

Hi!

I have a custom shader that needs to calculate a shortest distance from its every fragment and an outside set of 2d(x,y) locations (up to 32). These locations are set in real time.

The way I approached that program, is that I made a Matrix4x4 every time i needed to change position of my custom set locations, and cramp 4 of those per single matrix, kinda like this :


locationMatrix

[x1][y1][x2][y2]

[x3][y3][x4][y4]

[x5][y5][x6][y6]

[x7][y7][x8][y8]


Later on inside a shader I use that matrix to calculate distance. However it looks inefficient and messy, especially with converting from uv to world space position:


uniform float4x4 _Locations; //Location matrix that is being set via renderer.material.SetMatrix();

half _Radius, point1, point2;

point1= (distance(i.position_in_world_space, float2(_Locations[0][0],_Locations[0][1]))/1000.0);

point2= (distance(i.position_in_world_space, float2(_Locations[0][2],_Locations[0][3]))/1000.0);

point1=min(point1,point2);

point2= (distance(i.position_in_world_space, float2(_Locations[1][0],_Locations[1][1]))/1000.0);

point1=min(point1,hole2);

point2= (distance(i.position_in_world_space, float2(_Locations[1][2],_Locations[1][3]))/1000.0);

point1=min(point1,point2);


As you see it is very messy and inefficient, and I only processed 8 locations above. I was wondering if there was a streamlined version of this possible? I need to utilize all 4 of my Matrix4x4s.

Is there anything that can be done here or am I stuck with this?

For one thing, you can divide by 1000 once at the very end after you’ve done all the minimum’s. For another, you can take the minimums of all the squared distances instead, then do a single square root at the end. Using distance hides the operation sqrt(dot(b-a,b-a)) so you can optimize further. You can do the work in a loop instead of manually unrolled, that would be cleaner. You don’t have to pack into a matrix, you can pack coefficients into a vector array or whatever is easier to loop over. Many GPUs are massively threaded scalar processors nowadays so this kind of thing isn’t as bad as you’d think.