Bounding rounded rectangle in glsl

Hello, I'm trying to get a glsl shader quick rounded rectangle, but I was only able to do it for the filled rectangle with this function ( 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;
}

      

I am trying to find a version of this that does a border and not a fill, even tried to come up with one but no luck. Anyone have a solution?

+3


source to share


3 answers


Since you are using signed distance functions, the easiest way to do this is probably using the subtract operator to subtract the smaller rounded rectangle from the original.

It will look like this:

// 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

should be a value in [0:1]

, the larger it is, the smaller the border will be.

Here's a ShaderToy example to demonstrate this: enter image description here

+1


source


I think here what you are looking for ...

//---------------------------------------------------------
// 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);
}

      



Take a look at my shadertoy examples https://www.shadertoy.com/view/MssyRN screen shot example .

+4


source


Using a secondary block to extrude the first is a bad idea as it will degrade performance. Instead of calculating one object, you are calculating two objects. SDF performance is usually related to the number of objects that you add to your remote function; this is the reason the mod / gender functions are so useful when creating SDFs. You can add an infinite number of objects for (almost) no added value.

Use a square function, signed exactly here http://iquilezles.org/www/articles/distfunctions/distfunctions.htm If you want to write it yourself, try to figure out a way to get the closest point in the field, then return the distance to that point.

You can get a rounded box by subtracting the term by the distance, but you already figured that out (r in your example).

You can get the border using the absolute value of the distance. Abs (de) will basically remove the interior of the object (negative distance), making it positive. This creates an object with an "empty" border. If you want to make the border larger, just subtract another term to increase its size, just as you did to create a rounded border.

This works for any shape as long as the distance estimate is correct. SDFs are great for small tricks.

+2


source







All Articles