Advertisement

9 Slicing in OpenGL, want to have the center of the texture repeat instead of stretch

Started by July 20, 2024 04:25 PM
11 comments, last by LorenzoGatti 1 month, 2 weeks ago

After some more experimentation, I was able to make the following changes to the mapInside function

float mapInside(float val, float min, float innerStart, float innerSize, float uDimensions, float uBorder) {
    float scale = uBorder / uDimensions;
    if(fract(val * scale) < uBorder)
    {
        return fract(min*scale);
    }
    if(fract(val*scale) > innerStart + innerSize)
    {
        return fract(min*scale);
    }
    return mod((val - min) * scale, innerSize) + innerStart; 
}

I noticed by dividing the original size by the new size I could get the scale. When I did that it was repeating the center section, but it was repeating it at the edge of my central section. So, if my central section was 18 pixels, this would repeat it every 18 pixels. When resizing to 96, this meant it was drawn 5 times, instead of the three that I wanted. If I account for values outside of the range I want and just draw the value I want at those places, it seems to fix my problem. Here is my example sprite resized to 96x96

And here it is resized to 56x32. You can see the interior pattern is cut off as it cannot be completed.

This works well enough for me. If anyone comes across this, note my use of fract(min*scale) for the values outside of the central parts I want is fairly arbitrary, I just happen to know that the results there are going to be the colors I want. Were that not the case, if my shape instead looked like this

you end up with something that looks like this

There's probably a simpler way to do this, but it works for me, so I'll call this solved.

I dont see what this program has to do with shaders or opengl.

Use multiple polygons for your boxes, not just 4 edges…. each polygon should have the proper UV to avoid distortion on the edges.

Advertisement

You can only accomodate arbitrary sizes with one 9-slices asset by allowing some stretching of the border and/or of the repeated interior. If your tolerance for stretching is low you might need variant assets to use with different output sizes.

For example, suppose the initial and final border in your asset are 13 pixels each and the tileable middle section is 36 pixels (total image size 62 pixels) and you need to fit a 420 pixels space.

With borders at their natural size you'd need 10.9444 repeats of the middle section to fill 394 pixels: you can round that to 11 repeats reduced by a 394/396 factor or 10 repeats expanded by a 394/360 factor (a worse approximation, but might look better).

Squeezing the borders by a 12/13 factor instead (to get 396 pixels of tiled middle section) you could place 11 copies of the middle texture at their natural size.

You can also stretch border and middle equally: if you choose 11 repeats in the example (13+396+13=422 pixels at natural size) you can then reduce all texture coordinates by a 420/422 factor to draw 420 pixels.

Omae Wa Mou Shindeiru

This topic is closed to new replies.

Advertisement