您好我正在尝试使用快速圆角矩形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;
}
我一直试图找到一个这样做的边界而不是填充的版本,甚至试图拿出一个,但没有运气。有人有解决方案吗?
答案 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
答案 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示例,展示了这一点: