为什么人们使用sqrt(dot(distanceVector,distanceVector))而不是OpenGL的距离函数?

bra*_*ith 10 opengl shader glsl webgl

对于OpenGL和GLSL,我是一个完全新手.也就是说,当使用ShaderToy时,我经常会看到人们使用类似的东西:

vec2 uv = fragCoord / iResolution;
vec2 centerPoint = vec2(0.5);

vec2 distanceVector = uv - centerPoint;
float dist = sqrt(dot(distanceVector, distanceVector));
Run Code Online (Sandbox Code Playgroud)

通过OpenGL的distance功能:

vec2 uv = fragCoord / iResolution;
vec2 centerPoint = vec2(0.5);

float dist = distance(uv, centerPoint);
Run Code Online (Sandbox Code Playgroud)

我只是好奇为什么会这样(我的猜测是它与速度或支持有关distance).

我松散地理解,如果参数相同,点积的平方根等于向量的长度:距离?

Jac*_*ack 8

基本上做同样的事情,人们经常选择sqrt选项有两个原因:1.他们不知道/记住距离函数2.他们相信自己和他们自己的数学证明这不是一个问题导致一个bug(避免OpenGL问题)

  • 它更快吗?或者你能比较两个功能周期吗? (2认同)

Fel*_*rez 7

有时为了优化早期退出,例如光量:

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.
Run Code Online (Sandbox Code Playgroud)

如果您需要distance稍后,只需:

dist = sqrt( dist )
Run Code Online (Sandbox Code Playgroud)

编辑:另一个例子。

我最近学到的另一个用例,假设您想要有两个位置:vec3 posOne并且vec3 posTwo您想要到每个位置的距离。最简单的方法是独立计算它们:float distanceOne = distance( posOne, otherPos )float distanceTwo = distance( posTwo, otherPos )。但您想利用 SIMD!所以你这样做了:posOne -= otherPos; posTwo -= otherPos这样你就准备好通过 SIMD 计算欧几里德距离了:vec2 SIMDDistance = vec2( dot( posOne ), dot( posTwo ) );然后你可以使用 SIMD 求平方根:SIMDDistance = sqrt( SIMDDistance );其中到 posOne 的距离位于 SIMDDistance 变量的 .x 分量上,而 .y 分量包含该距离到后二。