Sub Image in Shader Tiling

So I am using a texture atlas with resolution 32x32. It is 23x21 tiles. I have generated a plane of 10x10 points for the model, and created indices and texture coordinates to match. The texture coordinates map the entire tilesheet to the plane created.

What I am doing now is taking sub images. I have done it before, but with a different, really complex and bad way (drawing a quad for each square using glDrawElements()).

So I took the map and I multiplied it by the amount of tiles. This gives me 10x10 tiles, each with a tileset texture. My problem here is I can’t manipulate these individual tiles further to isolate a specific tile from the tileset.

#version 120

in vec2 position;
in vec2 texcoord;
in float index;

out vec2 pass_texcoord;

uniform mat4 matrix_projection, matrix_transform, matrix_camera;

uniform sampler2D u_texture0;

uniform ivec2 texture_size;
uniform ivec2 stride;
uniform ivec2 map;
uniform ivec2 tiles;

void main(void) {
	
	float xratio = float(stride.x)/float(texture_size.x);
	float yratio = float(stride.y)/float(texture_size.y);
	
	float yoffset = floor(index/float(tiles.x));
	
//	pass_texcoord = vec2(texcoord.s*xratio + mod(index, tiles.x)*xratio, texcoord.t*yratio + yoffset*yratio);
	pass_texcoord = vec2(texcoord.s * map.x, texcoord.t * map.y);
	gl_Position = matrix_projection * matrix_transform * matrix_camera * vec4(position, 0, 1);
	
}

What am I missing?

So I realized that I do infact pass the texture coordinates to the fragment shader. This allows me to edit the area further. Now the goal is to figure out how to scope in from there. Researching specific topics isn’t fun :frowning:

It’s not really clear what you’re trying to do. Might want to try a drawing or something.

I’ve fixed my problem.

I was multiplying my texture coordinates so that I could have the correct amount of tiles (one tile per quad) in the vertex shader. This was correct, but I was displaying a whole image per tile tile. You can’t do anything further in the vertex shader to scope in to the very specific tile that you needed for that quad. Although, you can do this in the fragment shader.

vertex shader

#version 120

in vec2 position;
in vec2 texcoord;
in float index;

out vec2 pass_texcoord;

out float xratio;
out float yratio;
out float yoffset;
out float left;
out float right;

uniform mat4 matrix_projection, matrix_transform, matrix_camera;

uniform sampler2D u_texture0;

uniform vec2 texture_size;
uniform vec2 stride;
uniform vec2 map;
uniform vec2 tiles;

void main(void) {
	
	xratio = stride.x/texture_size.x;
	yratio = stride.y/texture_size.y;
	yoffset = floor(index/tiles.x);
	left = mod(index, tiles.x)*xratio;
	right = yoffset*yratio;
	
	pass_texcoord = vec2(texcoord.s * map.x, texcoord.t * map.y);
	gl_Position = matrix_projection * matrix_transform * matrix_camera * vec4(position, 0, 1);
	
}

fragment shader

#version 120

in vec2 pass_texcoord;

in float xratio;
in float yratio;
in float yoffset;
in float left;
in float right;

out vec4 out_Color;

uniform sampler2D u_texture0;

void main(void) {
	
	pass_texcoord = clamp(fract(pass_texcoord), 0.02, 0.96606);
	
	out_Color = texture(u_texture0, vec2(pass_texcoord.s*xratio + left, pass_texcoord.t*yratio + right));
	
}

Since there were some calculations from the vertex shader that could be passed over, I set up the exporting via out qualifier. When using texture atlases, you will get texture bleeding. This is when you look at the texture coordinate more indepth. It needs to be constrained from having some coordinate like 3.333x3.333 (such as 3rd quad in a 3x3 texture atlas) to 0.333x0.333. This is when I used fract(). This allowed me to scope into the tile, since the coordinates were good, it just had the repeat that didn’t need to be there. And this is when the bleeding officially hits. I used halfpixel calculation to fix this, but I never officially calculated it… I just put hard numbers in there which I shouldn’t.

So all in all I was able to repeat a tilesheet tile amount of times in the vertex shader, enter the fragment shader and focus that tilesheet to be drawn to only one 32x32 tile, and did some bleed correction just to draw tiles using attributes instead of separate quads drawn.