I am trying to achieve a special texture stretching effect in my shader. Here is how I define my uv before sampling my texture, nothing really special.

// uv_ST contains the tiling and offset values
uv.xy = uv.xy * uv_ST.xy + uv_ST.zw

This gives the standard tiling/stretching and offset behaviour when you tile/stretche a clamped texture as you can see in the image below. First is normal, second is offset and last is stretching.

enter image description here

But I want to avoid the deformation behaviour when stretching, I want to keep margins when stretching my texture or simply cut it in the middle and stretching it. Here is an illustration below.

enter image description here

How could I do that inside my shader when defining my uvs before sampling the texture ?

  • $\begingroup$ It looks like you're stretching the texture rather than tiling. Tiling wouldn't deform the rounded corners, but it would give you multiple copies of the rounded corners, and you wouldn't be able to fix it the way you propose. $\endgroup$
    – Dan Hulme
    Apr 21 '17 at 15:32
  • $\begingroup$ @DanHulme Yeah my bad, I misspoke. Instead of increasing the tiling, I am lowering it, that's why I am having the stretch effect. But this is the expected effect behaviour. I just want to avoid the deformation caused by the stretching. $\endgroup$
    – MaT
    Apr 21 '17 at 15:38
  • $\begingroup$ I edited my question. Sorry about that. $\endgroup$
    – MaT
    Apr 21 '17 at 15:40
  • 1
    $\begingroup$ I realise your example textures are quite simple, but if you ever have to do something more complex and still want to avoid the "distortion", Seam Carving might be of interest: When I saw it presented it almost seemed like magic. $\endgroup$
    – Simon F
    Apr 21 '17 at 17:01
  • 2
    $\begingroup$ User interfaces like Android use something call 'nine patches' which breaks the texture into a 3x3 grid with different scaling rules such that the corners are preserved and only the interiors are scaled in 1 or both axis. Further reading here: en.miui.com/thread-26099-1-1.html $\endgroup$
    – PaulHK
    Apr 24 '17 at 5:24

The Nine Patches algorithm is a really nice and powerful solution if you are using textures but I ended up by using a fully procedural solution.

I am just drawing a round box like this.

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

You can simply avoid the 3rd dimension if you don't need it. This method comes from the Distance function article from Inigo Quilez.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.