Scrolling (vertically, horizontally) a sprite's texture who's size is not a power of 2, only with shaders - possible in Defold?

Sprite Shader Scroll Test.zip (1.4 MB)

Hi,

I’m writing this post to both ask help with scrolling a sprite ((its texture inside the sprite bounds)) of arbitrary size (not necessarily sizes that are power of 2 ) and to clarify if this is even possible, without resorting to adding a 3D plane hack, which, for a 2D game, seems unnecessarily complex and can potential introduce other issues that have to be dealt with (like adding a camera in the scene, having to fiddle with it and so on).

This is the demo project using the 3D plane - GitHub - FlexYourBrain/Texture_Scrolling_Example: Scrolling texture in a shader example

I tried scrolling a sprite with a custom material, fragment and vertex program/shader (all 3 were copies of the builtin sprite ones) - unsuccessfully.

I tried all day yesterday with Claude Opus 4.1, Sonnet 4 Agent, chatGPT 5, chatGPT-Codex, they ground for hours, fetching all possible online official docs, forum posts etc. trying all possible techniques, but to no avail.

The closest I got was vertically scrolling the texture of the sprite, but as the sprite was disappearing at the bottom edge, it left a dark area in the top edge. Eventually I figured out that the issue was that the whole atlas was being scrolled and since the sprite was just a random cat sprite I quickly grabbed from the internet and which had an arbitrary size (473 × 600), it doesn’t fully cover the atlas’ size (which is always the power of 2), and thus the black area I was seeing was the transparent (alpha) part of the atlas page. Then I tried forcing the atlas page to match the size of the png, but shaders/materials don’t seem to support this approach.

I know that another way of achieving, for example a seamless sprite scroll (vertically or horizontally) is to add 2 sprites on top of each other or side by side and just animate their positions in tandem, reseting their positions once they are fully offscreen, but, again, in my opinion this adds unnecessary complexity, having to worry about more events, positions, callbacks etc. (especially since there is no way to lock positions in the editor for nodes, and sometimes you accidentally move something and then you have to spend time figuring out why stuff doesn’t align anymore).

Furthermore, in my particular case, all I wanted was to vertically scroll a checkerboard png, so just doubling the sprite and scrolling both in tandem was not going to work out of the box, since the top part of the sprite matched precisely with the bottom part, so I got double the vertical size of the cell of the checkerboard pattern, which means there is even more complexity to deal with - make another mirror checkerboard image, increasing the game’s size, dealing with double the assets, positions, events, callbacks etc. Also, I wanted to achieve a small sideways parallax effect such that when the player moves sideways the texture would slightly translate to the left or to the right, but for this you have to increase the horizontal size of the sprite (further increasing the game’s size) and then you have to deal with how to hide the vertical parts of the sprite such that they are not visible and only reveal themselves as they are being offset/scrolled sideways.

I really love Defold’s simplicity (recently it feels even faster, snappier - although I haven’t used it in a couple of years, so that’s a great improvement), but some basic functionality that can be achieved in Godot with a single shader file and 5-ish lines of code (as opposed to 3 files like in Defold), is missing and spending time with workarounds and hacks kind of discourages me (and probably a lot of other beginner developers) to fully settle and commit to this engine, even though it feels like it should be a no brainer for anyone doing small(ish) 2D games, especially for Web. Could be just me, but I feel like I am spending more time researching workarounds, quirks and limitations than actually developing the projects.

I uploaded a basic Defold project with a random cat image (473 × 600 - not power of 2 size, obviously ), I copied the builtin sprite material, vertex and fragment, and applied them to the sprite. If somebody can either help me figure out how to vertically and horizontally scroll the sprite’s texture only with shaders or at least help understand that this is impossible in Defold so I can move on, I would greatly appreciate it.

Thank you!

Yes it is possible as @Dragosha has done here:

1 Like

Thanks for the response!

I’m actually looking for a solution for regular sprites (attached to Game Objects), not GUI nodes - since GUI nodes are rendered above everything else afaik and it will not work for a scrolling repeating background.

Hi @dragos_margu!

It seems to me that the solution in the link provided by @MasterMind can do what you’re asking for. There are two separate points there, first one for sprites (as you need) and only the second one for GUI nodes…

Here’s the link to the right part of the README.md: https://github.com/Dragosha/defold-sprite-repeat?tab=readme-ov-file#sprite-texture-repeat-shader-or-tiling

By the way, @Dragosha, a cool thing! I may be using one day, thank you!

Hi, @robotiger,

I checked out the project and indeed it does repeat sprites, but what I’m really looking for is to have a single sprite component attached to a game object and have that sprite (sprite texture’s, maybe?) scroll, not repeat. Essentially, as each sprite’s row of pixels gets shifted downwards (if we’re talking vertical scrolling)and the very bottom row disappears, it should reappear as the top row of pixels seamlessly. And this effect can be achieved but only if you have a sprite who’s size is a power of two (1024x512, for example) because only this way you can fill an atlas page, otherwise the atlas will have transparent parts and those will appear as black parts inside the sprite as the pixels are being scrolled.

If you have a sprite that seamlessly repeats around the edges you can create an infinite seamless scrolling background in any direction.

Here is a Godot example of what I mean, scrolling in any arbitrary direction with a single shader file and 5 lines of code or so, regardless of the sprite’s size: https://www.youtube.com/watch?v=3RkRzyPiFvE

Added the ability to scroll texture to GitHub - Dragosha/defold-sprite-repeat: Texture repeat (tiling) shader. For Sprites and GUI box nodes.

9 Likes

Also, related to this, I think this ticket is something we want to do to help with this.

5 Likes

Thanks, @Dragosha ! You have achieved what I thought was impossible, amazing! The sprite scrolling now works for sprites with arbitrary sizes and with multiple sprites in the same atlas.

I took your project played around with it and now the sprite scrolling works great in any direction.

I added some runtime controls:

  • to change the sprite from a random cat image to a seamless pattern image (checkerboard).
  • to increase/decrease the scroll speed.
  • to activate/deactivate independent x and y scrolling.
  • reset the sprite’s position.

I think this could be a great starting project for someone looking to implement advanced sprite scrolling,.

There is one remaining BIG ISSUE (that I know of) - when the sprite wraps (at the seams) there is a little bit of flicker. If this could be solved then the sprite scrolling mechanic would be bulletproof.

In the future, if Defold would get the ability to scroll sprites with shaders in a much simpler way (closer to Godot’s approach) that would be preferable, since in this test project there is a LOT of code just to achieve basic sprite scrolling functionality.

Defold Sprite Scroll Example.zip (1.6 MB)