Skip to playerSkip to main content
  • 6 months ago
In your shaders, you’ve likely used functions like length() and distance(), which calculate Euclidean distance.

But did you know there are other fascinating distance metrics that can create unique effects in your projects? In this tutorial, we’ll explore various distance algorithms, including Euclidean distance, Euclidean squared distance, Manhattan distance, Chebyshev distance, and Minkowski distance.

Join me to deepen your understanding of these mathematical concepts and learn how to apply them effectively in your work! You could use the concept in any popular game engines like Unreal, Unity, Godot etc.

👉 Fence pattern video! https://www.youtube.com/watch?v=e4vZDQEocOQ&list=PLaE0_uENxXqsETsgZn5ZhSGxA1ZESk24n&index=1

👉 Do you want to support my work? The best way to support this channel is to buy my game on Steam. https://store.steampowered.com/app/2527340/Cosmic_roads/

👉 Alternate ways to support!
https://github.com/sponsors/DigvijaysinhGohil
https://www.patreon.com/DigvijaysinhG

Category

📚
Learning
Transcript
00:00If you have been creating shaders for some time, chances are high you have often used
00:04length or distance functions, which will return the distance from point A to point B.
00:09But did you know there are other fascinating distance metrics that can create unique visual
00:14effects? Let's see what these distance algorithms are and how you can calculate them.
00:19You can call me the gujay and now without any further ado, let's get this party started.
00:25Let's start with Euclidean distance. The concept was introduced by the Greek mathematician Euclid,
00:31which is why it is called Euclidean distance. Let's plot a graph. Imagine that we are sitting
00:37at the origin 0,0 and we have to go to this point P. So the idea is to simply measure the closest
00:43distance from the origin to point P. And because the distance will always be a straight line,
00:49it is also called as the crow flies distance. And this is basically Pythagoras. Hence,
00:55it is also referred to as Pythagorean distance. We can simply calculate the distance d with the
01:01square root of x square plus y square. But most programming languages already have a built-in
01:08function for this. Length function, which returns the distance from origin to the point. Or distance
01:13function, which will return the distance between two specified points. Then there is another distance
01:19called Euclidean squared. Let's take our previous scenario once again. And here the idea is, instead
01:25of calculating this distance, we will calculate the square of that, which is pure Pythagoras,
01:31c square equals a square plus b square. To calculate the distance d, we can simply omit the square root
01:38and go x square plus y square. Now let's see how this works in the shader. Alright, so I'm on a website
01:46called shaded.org, which is similar to shader toy, but it allows you to write shaders in HLSL. And I was
01:53feeling my HLSL is getting rusty, so here I am, just for the practice. Alright, so my UVs are going from
02:0300 up to 11 here. Now the very first thing is, I want my UVs urgent in the middle. So here I can
02:12subtract my half the resolution from the fragment coordinates. So I can simply go
02:21minus 0.5, multiply my resolution, and then divide
02:28resolution.y to compensate for the aspect ratio. So now my UVs y-coordinate will go from 0.5 to minus 0.5,
02:44but the x-coordinate could go beyond that range. Alright, now let me plot my Euclidean squared distance.
02:52So I'll go load Euclidean squared. And it will take vector 2 as an input. So load 2 p. So this function
03:06will return the squared length of the p vector from the origin. But if you want the squared length from
03:13point a to point b, you can just pass in a minus b when calling this function. Okay, that's
03:20easy enough. Then here I'll simply go return x square plus y square.
03:33Or I can simply go dot product of p and p. And that's basically the same thing that I brought earlier.
03:43So it will do. Then instead of visualizing our UV, let's go length of UV.
03:55So this is the Euclidean distance by the way. And it will give me this nice fading circle.
04:02Now instead of Euclidean, let's use our Euclidean squared. And it will just basically darken the
04:08values which are less than 0 and brightens the value which are greater than 1. But obviously we
04:14cannot see that because the final output will be clamped between 0 and 1. Let's see.
04:21And that's our Euclidean squared distance. Next, let's discuss another distance metric known as
04:27Manhattan distance. And the idea is, in a city like Manhattan where the streets are laid out as a grid,
04:34you cannot simply fly from point A to point B. You have to follow the roads or street blocks.
04:40Hence, it is also known as taxicab distance. And the idea is first suggested by the German mathematician
04:47Hermann Mankowski. Let's plot a graph. And again, we are at the origin 00. Let's think of the grid lines
04:54as roads. And we have destination point P. So to reach here, we can either go horizontal or vertical.
05:02Let's say I go 1 unit horizontally, then 1 unit vertically, and currently I've covered 2 units
05:09of distance. Then again, let's move horizontal, vertical, and horizontal again to reach the
05:15destination P. I've covered total distance of 5 units, which can be calculated by just adding the
05:21vector components together, 3 plus 2. Now obviously, the path I've traveled is not the only shortest path.
05:29I can travel like this as well, where I go 1 unit horizontally, then 2 units vertically,
05:35and 2 units horizontally again. Or I can travel like this, where I go 1 unit vertically,
05:40then 3 units horizontally, and then 1 unit vertically once again. But the total distance to travel will
05:46always be 5 units. To calculate the distance d, we can simply add x and y components together. However,
05:54they can be negative as well, but it would still count as distance. So we will simply use absolute
06:00of them. Okay, let's see this in action. Alright, now let me plot my Manhattan distance function. So
06:08float Manhattan, and it will again take vector 2 as an input. So float to P.
06:15and here I can simply go return absolute of P dot x plus absolute of P dot y. And I'm dealing with 2d,
06:26but this will work in 3d as well. You can simply go plus absolute of P dot z, and it will work just fine.
06:34Alright, now let's call our Manhattan distance here instead of Euclidean squared. So
06:39Manhattan, and this is our Manhattan distance. Then we have another distance metric, Chebyshev distance.
06:49And the idea is given by the Russian mathematician Pachnuti Chebyshev, hence the name. The idea behind
06:56Chebyshev distance is how a king moves in chess. It can move in any direction one square. Horizontally,
07:02vertically, or diagonally. In total, king can move in a direction one square. And because the distance
07:09is based on chessboard, it is also known as chessboard distance. Shocker. Let's plot the graph,
07:17and again, I'm at the origin zero zero. My destination is point P, and I can move just like
07:23a king from chess. So I will move one unit diagonally. Now in reality, if we measure the distance,
07:29it will be more than one unit, but we will consider it one unit regardless. Then I can move one unit
07:36horizontally. And finally I can reach the destination P by moving one unit diagonally again. So here I've
07:43traveled total of three units, which is just the largest component of my vector P. Now again, this
07:50is not the only shortest path. I can go like this, where I move two units diagonally and one unit
07:56horizontally. Or I can move like this, where I move one unit horizontally and two units diagonally. But the
08:02distance will always be three units. We can calculate the distance d by simply getting the maximum of x and
08:09y. Again, they can be negative, so we will use absolute of them. Now let's see this in shader real quick.
08:17All right, so let me create the shabyshev distance function. So float shabyshev. It will again take
08:26vector 2 as an input. So P. And here I will return maximum between absolute of P.x and absolute of P.y.
08:43And let's call our shabyshev distance here.
08:47So this is our shabyshev distance. Or chessboard distance.
08:55Next we have Minkowski distance. Again, named after the German mathematician Hermann Minkowski.
09:02This distance metric is essentially a generalized version of Euclidean,
09:06Manhattan and Shabyshev distances. It will have an exponent value. Then we will simply use the absolute
09:13of our P vector. Then go P raised to our exponent value. Then to calculate the distance d,
09:19we will add all components together. And then take the entire thing raised to 1 divided by E.
09:26Now let's see this in action. Okay, so I will create a function for Minkowski distance. So float
09:32Minkowski and it will take float 2 as input and another float E for exponent value.
09:47And here I will go P equals power of absolute of P and E. Then I'll just return
09:58P dot X plus P dot Y. And then take the entire thing and raise it with 1 divided by E.
10:17And let's call Minkowski distance here. So
10:21Let me pass in 1. So if I pass in 1, it is Manhattan distance. If I pass in 2,
10:34it is Euclidean distance. And if I pass in 3, it moves to Shabyshev distance. Okay, so this is
10:43just the generalization between Shabyshev, Manhattan and Euclidean. Alright, now let me animate this.
10:50Selgo sign off view time. And this will go from minus 1 to 1. I want it to go from let's say 1 to 4.
11:03So I can multiply it with 1.5 and add 2.5.
11:12So yeah, it looks something like this. Pretty cool. So next time when you use length or distance
11:25function in your shaders, maybe give these ones a try. And let me quickly show you a one real life
11:33example. So maybe I can quickly plot a Voronoi noise. And I will go over it a bit faster because
11:41this video is not about Voronoi. But still, if you're interested, Martin Steindruckens aka the
11:47Art of Code has a nice video about it. But still, if you want me to cover Voronoi in details, let me
11:53know in the comments below. Alright, so for Voronoi, first I need a function that returns a random vector 2.
12:01So I'll go float2 random2 and it will take vector2 as an input to seed.
12:10And here, let me create a 3 by 3 matrix. M equals 3 by 3. And here, I will pass in some number
12:29and some other number and zero. Then again, I will pass in some number.
12:40and some other number and zero. Then pass in some bigger number and another bigger number and one.
12:57Then let's go seed equals m multiply load 3 of seed and one. So here I've just arbitrarily scaled,
13:17rotated and translated the seed vector. Then I will simply go return fraction of seed.
13:27So it will return the vector 2 that can go from 0 0 up to 1 1. Right now, let me just
13:40go like this to make some room here. And here I'll go float Voronoi. And it will take
13:49uv as an input and another float for angle offset.
14:00Right now here I need grid uv. So I'll go float2 grid equals fraction of uv. And I need id for each grid
14:10box. So again float to id equals flora of uv. Then I'll go float minimum distance.
14:20And pass in some bigger value. Then let's create two for loops. So 4 float x equals minus 1 x less than equals 1
14:35x plus plus. Then again for the y I'll go for float y equals minus 1 y less than equals 1 y plus plus.
14:53And this is the same technique we have used in my fence procedural pattern video. So go check that out.
15:05Then here I'll first create a vector to offset vector. So offs equals just float 2 of x and y.
15:13Then I'll go float 2 in for normal vector. And I'll just call in my random 2. And pass in id plus offset.
15:29And just add angle offset on top.
15:35Then here I'll calculate the point in my grid box. So id plus
15:43float 2 of sine of n dot x. And cosine of n dot y. And this vector can go from minus 1 to 1.
15:56So let's make it so it only goes from 0 to 1. So multiply by 0.5 plus 0.5. And then let's calculate
16:06the distance d equals length of p. And it will only give me the distance or the length of my vector p from
16:17the origin. But I want the distance between p and my grid uv. So grid. Then let's check if
16:25d is less than minimum distance. If so we will just update the minimum distance. So
16:35mendist equals d. And outside the loop let's simply return our minimum distance. Let's save and that
16:45compiles. All right. So let's visualize over Voronoi here. So I'll go Voronoi. Pass in new v. Multiply
16:584 let's say. And for angle offset let's pass in 4. And it seems like I messed something up.
17:06All right. Let's try mall.
17:20Would that change anything? I changed something but didn't pick the issue.
17:25Yes. Point. Oh yeah. I got it. Instead of id you have to go offset. And yep that's our Voronoi.
17:48Now here we are using Euclidean distance you know. Now let's try to use
17:55our other distance matrix. So let's go Euclidean squared. And this will just darken our Voronoi noise overall.
18:04Just like that.
18:08And if I go Manhattan it would look something like this. If I go shabby shell it would look something
18:18like this. But of course we will use Minkowski. And we will animate it. So sign off view time.
18:29Let's go multiply. 1.5 and plus 2.5. And that's how you can use different distance
18:42metrics in your own shader effects. I hope you found this exploration helpful and inspiring for
18:47your shader creation. If you enjoyed the video please give it a thumbs up. And if you're new here
18:53consider subscribing for more videos like this. And don't forget to hit that notification bell so
18:58you never miss an update. If you have any questions or you want to share your own experiences with distance
19:04algorithms. Write me down in the comments below. I would love to hear from you. That's it from me.
19:10And I'll see you in the next one.
Be the first to comment
Add your comment

Recommended