Repeating texture?

#1

Is there a way to somehow expand the size of a sprite (or some other component) and have the texture repeat inside the expanded area?

0 Likes

#2

Yes, this is possible. Maybe someone else has a more elegant way of doing it.

You want to have an atlas per tiled texture you want to use. The important thing is that there is no gap around the tiled texture which means nothing else can be on it and it must be a power of 2.

Then you want a sprite material with wrap mode repeat.

Inside this shader you can have code such as

varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;
uniform lowp vec4 scale;

void main()
{
    // Pre-multiply alpha since all runtime textures already are
    lowp vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
    lowp vec2 uv = vec2(var_texcoord0.x * scale.x, var_texcoord0.y * scale.y);
    gl_FragColor = texture2D(texture_sampler, uv.xy) * tint_pm;
}

Then you update the scale constant with a script

function init(self)
	local scale = go.get_scale()
	sprite.set_constant("#sprite", "scale", vmath.vector4(scale.x, scale.y, 1, 1))
	
end

In editor your tiled thing will look wrong, but in engine it should look right

2019-04-13%2009_14_32-Window

2019-04-13%2009_15_49-Window

If you want like a looping repeating background which moves in some direction that is possible to add too.

function init(self)
	local scale = go.get_scale()
	sprite.set_constant("#sprite", "scale", vmath.vector4(scale.x, scale.y, 1, 1))
	self.offset = {x = 0, y = 0}
end

function update(self, dt)
	self.offset.x = self.offset.x + dt
	self.offset.y = self.offset.y + dt / 2

	sprite.set_constant("#sprite", "offset", vmath.vector4(self.offset.x, self.offset.y, 0, 0))
end

varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;
uniform lowp vec4 scale;
uniform lowp vec4 offset;

void main()
{
    // Pre-multiply alpha since all runtime textures already are
    lowp vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
    lowp vec2 uv = vec2(var_texcoord0.x * scale.x + offset.x, var_texcoord0.y * scale.y + offset.y);
    gl_FragColor = texture2D(texture_sampler, uv.xy) * tint_pm;
}

If you’ve seen pixel art games with repeating background patterns this can be a way to accomplish that. You can have multiple layers with parallax pretty easily too if your textures have transparency. When multi texturing comes it will be easier probably.

13 Likes

How to get scrolling tiled background image?
#3

Great writeup. Would this approach work with flip book animations?

0 Likes

#4

Assuming we get relative UV spaces sometime in the future that will be useful for using this method with animations. You could probably change the texture manually to animate it.

2 Likes