Home Game Development opengl – GLSL 9-Slice (or 9-Patch) working with single texture, but not with atlas texture

opengl – GLSL 9-Slice (or 9-Patch) working with single texture, but not with atlas texture

0
opengl – GLSL 9-Slice (or 9-Patch) working with single texture, but not with atlas texture

[ad_1]

I’ve been able to implement 9Slice for textures when the texture is just itself, that means, it does not contain any subtexture except itself. This is the code I’m using:

#version 330 core

in vec2 uv;
in vec4 color;
in vec2 size;
in vec4 nine_slice;

uniform sampler2D tex;
uniform float dt;
uniform vec2 mouse_position;
uniform vec2 texture_size;

layout(location = 0) out vec4 out_color;

vec2 uv9slice(vec2 uv, vec2 s, vec4 b) {
    vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0., 1.);
        return mix(uv * s, 1. - s * (1. - uv), t);
}

vec4 draw_nine_slice() {
    vec2 _s = size.xy / texture_size;
    vec4 _b = nine_slice / texture_size.xxyy;
    vec2 _uv = uv9slice(uv, _s, _b);
    vec3 _col = vec3(texture(tex, _uv).x);
    return vec4(_col, 1.0);
}

void main(void) {
        out_color = draw_nine_slice();
}

Where vars are:

  • size: Size of the nine patch (the imgui window shown on the second image)
  • nine_slice: These are the paddings vec4(left, right, bottom, top)
  • texture_size: This is the size of the texture, which will be fixed. If it is a non-atlas texture, the size is the size of the whole image, if it is a subtexture from an atlas, the size will be the size of the subtexture inside the atlas. This is the texture:

Single texture panel

And this is how it looks with the 9-Slice:

Working example

Working example of single texture 9-Slice

So as you can see, it expands nicely. The problem comes when I use my texture atlas (change the white color of the sub textures with gray, as they could not be seen on this site white background):

Texture Atlas

I have a way in my program to get the texture coordinates, size and everything from each subtexture in the atlas, and when I render them as a non-9Slice it works great, the problem is the shader. If I try to run the engine with a subtexture from the atlas, the shader I posted before won’t work, as it takes the whole texture as if it was a single one (which works on the previuos case but not this one). This is what happens when running with the shader:

Wrong behaviour

Which make sense (don’t mind the transparency not working). I know I have to change how the coordinates are calculated in the shader to be relative to the sub-texture coordinates, but I cannot really seem to understand how to do it, this is what I tried:

#version 330 core

in vec2 uv;
in vec4 color;
in vec2 size;
in vec4 nine_slice;

uniform sampler2D tex;
uniform float dt;
uniform vec2 mouse_position;
uniform vec2 texture_size; // If drawing a subtexture from an atlas, this is the size of the subtexture

layout(location = 0) out vec4 out_color;

vec2 uv9slice(vec2 _uv, vec2 _s, vec4 _b) {
    vec2 _t = clamp((_s * _uv - _b.xz) / (_s - _b.xz - _b.yw), 0.0, 1.0);
    vec2 _t_0 = _uv * _s;
    vec2 _t_1 = 1.0 - _s * (1.0 - _uv);
    return clamp(mix(_t_0, _t_1, _t), vec2(0, 0.75), vec2(0.25, 1.0));
}

vec4 draw_nine_slice() {
    vec2 _s = size.xy / texture_size;
    vec4 _b = nine_slice / texture_size.xxyy;
    vec2 _uv = uv9slice(uv, _s, _b);
    vec3 _col = vec3(texture(tex, _uv).x);
    return vec4(_col, 1.0);
}

void main(void) {
    out_color = draw_nine_slice()
}

Values are hardcoded in here, because I’m doing a test. Bottom-Left coord of the texture in the atlas is (0.0, 0.75) and Top-Right is (0.25, 1.0).

I thought clamping the values within the sub-texture range would work, but it does not. I tried also other combinations but noting seems to be working, does anyone have an idea on how to achieve the first behaviour with the single texture on the second scenario with an atlas?

Tried different ways to convert from whole image coordinates to a sub-space of the image, one of the attempts is in the description of the issue, no success with any of them.

[ad_2]

Previous article Square Enix’s Messiest RPG Series Deserves A Comeback
Next article Modern Warfare 3 best guns at launch
Hello there! My name is YoleeTeam, and I am thrilled to welcome you to AmazonianGames.com. As the premier destination for all things related to Amazon Games' universe, we are dedicated to providing you with the most exciting and immersive gaming experiences out there. From captivating visuals to exhilarating gameplay, our website is packed with comprehensive insights, updates, and reviews to keep you ahead of the game. Whether you're a seasoned gamer or new to the scene, I am here to guide you through this virtual frontier. If you have any questions or suggestions, feel free to reach out to me at john@yoleesolutions.com. Embark on your Amazon gaming journey today with AmazonianGames.com and let the adventure begin!