When using ShaderToy I often see people using something like:
vec2 uv = fragCoord / iResolution;
vec2 centerPoint = vec2(0.5);
vec2 distanceVector = uv - centerPoint;
float dist = sqrt(dot(distanceVector, distanceVector));
over OpenGL's distance
function:
vec2 uv = fragCoord / iResolution;
vec2 centerPoint = vec2(0.5);
float dist = distance(uv, centerPoint);
I'm just curious why this is (my guess is that it has something to do with speed or support for distance
).
I loosely understand that if the arguments are the same, the square root of a dot product equals the length of the vector: the distance?
Doing essentially the same thing, people often choose the sqrt option for one of two reasons: 1. They don't know about/remember the distance function 2. They are trusting themselves and their own math to prove that is not a problem to cause a bug (avoiding OpenGL problems)
Sometimes to optimize early exits as for light volumes for example:
float distSquared( vec3 A, vec3 B )
{
vec3 C = A - B;
return dot( C, C );
}
// Early escape when the distance between the fragment and the light
// is smaller than the light volume/sphere threshold.
//float dist = length(lights[i].Position - FragPos);
//if(dist < lights[i].Radius)
// Let's optimize by skipping the expensive square root calculation
// for when it's necessary.
float dist = distSquared( lights[i].Position, FragPos );
if( dist < lights[i].Radius * lights[i].Radius )
{
// Do expensive calculations.
If you need the distance
later on simply:
dist = sqrt( dist )
EDIT: Another example.
Another use case that I've recently learnt, suppose that you want to have two positions: vec3 posOne
and vec3 posTwo
and you want the distance to each of those. The naive way would be to compute them independently: float distanceOne = distance( posOne, otherPos )
and float distanceTwo = distance( posTwo, otherPos )
. But you want to exploit SIMD! So you do: posOne -= otherPos; posTwo -= otherPos
so you are ready to compute the euclidean distance by SIMD: vec2 SIMDDistance = vec2( dot( posOne ), dot( posTwo ) );
and you can then use SIMD for the square root: SIMDDistance = sqrt( SIMDDistance );
where the distance to posOne is on the .x component of the SIMDDistance variable and the .y component contains the distance to posTwo.
Using dot gives you a quick way to experiment with quadratic/linear function of distance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With