geometry - 计算点和矩形之间的有符号距离

标签 geometry glsl shader euclidean-distance

我正在尝试在 GLSL 中编写一个函数,该函数返回到矩形的有符号距离。矩形是轴对齐的。我觉得有点卡住了;我只是无法理解我需要做什么才能让它发挥作用。

我想出的最好的是:

float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
    // signed distances for x and y. these work fine.
    float dx = max(tl.x - uv.x, uv.x - br.x);
    float dy = max(tl.y - uv.y, uv.y - br.y);
    dx = max(0.,dx);
    dy = max(0.,dy);
    return sqrt(dx*dx+dy*dy);
}

这会产生一个矩形,看起来像:

enter image description here

线条显示与矩形的距离。它工作正常,但仅适用于矩形外的距离。在矩形内,距离是静态的 0. .

如何使用统一公式获得矩形内的准确距离?

最佳答案

这个怎么样...

float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
    vec2 d = max(tl-uv, uv-br);
    return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
}

这是result ,其中绿色表示正距离,红色表示负距离(下面的代码):

enter image description here

分解:
  • 获取 x 和 y 边界的有符号距离。 u - leftright - u是两个 x 轴距离。取这些值中的最大值给出到最近边界的有符号距离。查看 d.xd.y在下面的图片中单独显示。
  • 组合 x 和 y:
  • 如果两个值都是负数,取最大值(即最接近边界)。这是通过 min(0.0, max(d.x, d.y)) 完成的.
  • 如果只有一个值为正,这就是我们想要的距离。
  • 如果两个值都是正数,则最近的点是一个角,在这种情况下我们需要长度。这可以通过无论如何取长度并确保两个值都是正数来与上述情况相结合:length(max(vec2(0.0), d)) .

  • 方程的这两部分是互斥的,即只有一个会产生非零值,并且可以相加。
    enter image description here enter image description here
    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        vec2 uv = fragCoord.xy / iResolution.xy;
        uv -= 0.5;
        uv *= vec2(iResolution.x/iResolution.y,1.0);
        uv += 0.5;
        float d = sdAxisAlignedRect(uv, vec2(0.3), vec2(0.7));
        float m = 1.0 - abs(d)/0.1;
        float s = sin(d*400.0) * 0.5 + 0.5;
        fragColor = vec4(s*m*(-sign(d)*0.5+0.5),s*m*(sign(d)*0.5+0.5),0,1);
    }
    

    关于geometry - 计算点和矩形之间的有符号距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30545052/

    相关文章:

    objective-c - 圆内点

    展平 3D 三角形带的算法

    javascript - 多个对象 Glsl

    ios - 如何在 SceneKit : consecutive statements on a line must be separated by ;? 中写入新的着色器文件

    javascript - 当我将位置传递给具有属性的着色器时,gl_Position 不会移动顶点吗?

    algorithm - 在 O(nlogn) 中查找平面中具有非不同 x 坐标的最近点对

    python - 寻找四边形内最大矩形拟合的简单算法

    c++ - 着色器存储 block 名称问题

    opengl - 为什么此Phong着色器起作用?

    opengl-es - OpenGL ES 中的标识符、初始化和局部变量