glsl中带边框的圆角矩形

时间:2017-05-15 00:46:56

标签: glsl opengl-es-2.0

您好我正在尝试使用快速圆角矩形glsl着色器,但我只是设法使用此函数(https://github.com/marklundin/glsl-sdf-primitives/blob/master/udRoundBox.glsl)为填充矩形执行此操作:

float udRoundBox( vec3 p, vec3 b, float r )
{
  return length(max(abs(p)-b,0.0))-r;
}

我一直试图找到一个这样做的边界而不是填充的版本,甚至试图拿出一个,但没有运气。有人有解决方案吗?

3 个答案:

答案 0 :(得分:4)

我想这就是你要找的......

//---------------------------------------------------------
// draw rectangle frame with rounded edges
//---------------------------------------------------------
float roundedFrame (vec2 pos, vec2 size, float radius, float thickness)
{
  float d = length(max(abs(uv - pos),size) - size) - radius;
  return smoothstep(0.55, 0.45, abs(d / thickness) * 5.0);
}

看一看我的shartrtoy示例https://www.shadertoy.com/view/MssyRN screen shot example

答案 1 :(得分:2)

使用辅助盒挤出第一个盒子是个坏主意,因为它会导致性能下降。您可以计算两个对象,而不是计算单个对象。 SDF的性能通常受您在距离函数中添加的对象数量的限制;这就是为什么mod / floor功能在制作SDF时非常有用的原因。您可以添加无限数量的对象(几乎)无需增加成本。

使用此处签名的确切函数框http://iquilezles.org/www/articles/distfunctions/distfunctions.htm如果您想自己编写,请尝试找出获取框上最近点的方法,然后将距离返回到此点。

你可以通过将一个术语减去距离得到一个圆角框,但你已经把它想出来了(在你的例子中为r)。

您可以使用距离的绝对值来获取边框。 Abs(de)将基本上移除对象的内部(负距离)。这使得对象具有“空”边框。如果你想让边框更大,只需减去另一个术语来增加它的大小,就像你做一个圆角框一样。

只要距离估计正确,这适用于任何形状。 SDF非常适合这样的小动作。

答案 2 :(得分:1)

由于您使用的是有符号距离函数,最简单的方法是使用减法运算符从初始值中减去一个较小的圆角框。

看起来像这样:

// unsigned round box
float udRoundBox( vec3 p, vec3 b, float r )
{
  return length(max(abs(p)-b,0.0))-r;
}

// substracts shape d1 from shape d2
float opS( float d1, float d2 )
{
    return max(-d1,d2);
}

// to get the border of a udRoundBox, simply substract a smaller udRoundBox !
float udRoundBoxBorder( vec3 p, vec3 b, float r, float borderFactor )
{
  return opS(udRoundBox(p, b*borderFactor, r), udRoundBox(p, b, r));
}

borderFactor需要是[0:1]中的值,值越大,边界越小。

这是一个ShaderToy示例,展示了这一点: enter image description here