Texture Atlases and Repeating UVs

Godot Version

4.2.2

Question

I’m trying to get a texture atlas to repeat a single texture. Currently, I am able to use a texture atlas to make the face of each brush the correct texture but with greedy meshing the texture gets stretched, I can fix the stretching by multiplying the UV by the face width when making the mesh but then the texture repeats to the rest of the textures in the atlas. Everything I find says to use shaders, but I don’t really understand how, and I could not find any provided examples.

Without corrected UVs

With corrected UVs

Thanks to this

I was able to correctly mod so it repeats the single texture across the whole face

But currently I’m manually adding the offset of the texture. I don’t know how to get the offset from the base uv. Here’s my current shader code:

shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;

uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_nearest,repeat_enable;

uniform vec2 atlas_size;

void fragment() {
	
	vec2 base_uv = UV;
	
	// Mod the uv and add offset
	vec2 mod_uv = vec2(mod(base_uv, vec2(1.000, 1.000) / atlas_size)) + (vec2(1.0, 0.0) / atlas_size);
	
	vec4 albedo_tex = texture(texture_albedo,mod_uv);
	ALBEDO = albedo.rgb * albedo_tex.rgb;

}

Anyway, I figured it out. Godot right now doesn’t seem to support any sort of custom vertex data from what I could find outside the 4 built in CUSTOM0 - CUSTOM3 vertex colors. So I passed the row and column index through CUSTOM0 as a color and read it in the vertex function. Tada!

Here is my shader code for anyone interested.

shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;

uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_nearest,repeat_enable;

uniform vec2 atlas_size;
varying vec2 offset;

void vertex() {
	offset = CUSTOM0.xy;
}

void fragment() {
	vec2 base_uv = UV;
	
	// Mod the uv and add offset
	vec2 mod_uv = vec2(mod(base_uv, vec2(1.000, 1.000) / atlas_size)) + (offset / atlas_size);
	
	vec4 albedo_tex = texture(texture_albedo,mod_uv);
	ALBEDO = albedo.rgb * albedo_tex.rgb;
}


TBH I don’t really like this as a solution and wish Godot 4 had more options when it comes to SurfaceTool and custom vertex data for shaders but what can I do