Scrolling Textures in XNA
Update: I wrote a more advanced version of this article now, which does the same thing but allows the camera to be scaled and rotated too. You can check it out here

To begin my series of XNA related articles, I’ve decided to start small and describe a simple technique to scroll textures infinitely in any direction. This technique can be used, for instance, to create an infinite layer of moving clouds for a top-down 2D game with a single texture and draw call. As long as the texture you’re drawing is seamless, you can scroll it anyway you want and give the impression of being on an infinite plane. Also, since both the scroll direction and scroll speed are controllable, you can even go ahead as stacking several layers on top of each other and updating them independently to give the feel of parallax scrolling.

Looking at the picture above should give you a clear image of what it means to scroll a texture (note that the texture in the example is not seamless intentionally in order to make the scrolling coordinates more apparent).The texture on the left side is unscrolled, while the texture on the right side has been scrolled x units to the right and y units down. So, how does one implement this? The main reason I’m writing this article is because I’ve used this technique on two games already, and without realizing it took a route that was much harder and error-prone than the one presented here.

The Bad Way

Let me start by explaining what I did wrong. Look back at the scrolled texture above. It should be apparent that when a texture has been scrolled diagonally, it ends up splitted in four different sections. My first idea was then to draw the texture four different times, and adjust the source rectangles and positions for each of them based on the scroll coordinates. Here’s an example:

It works, but there’s also a caveat – in order to ensure proper behavior you need to guarantee that the scroll coordinates never go beyond the image’s boundries, otherwise the results end up looking messed up. For instance, you could validate your scroll coordinates before drawing by doing:

 The Good Way

Fortunately, there’s a much easier way to do this! I’m sure many of you already know this, and might find it pretty obvious, but sometimes we overly complicate things when there’s a much simpler solution right under our noses. This one occurred to me out of nowhere today, and I had quite a laugh when I realized it actually worked, produced the exact same effect as before, didn’t require any validation of the scrolling coordinates, and the best part of all: it only needed three lines of code!

That’s it! The trick here is to ensure that you’re using an addressing mode that is set to “wrap” (using SamplerState.LinearWrap fits this requirement perfectly) and then make some clever use of SpriteBatch’s source rectangle to simulate the scrolling by passing it the negative of the scrolling position as a starting point. All the wrapping is done automatically by the texture’s addressing mode.

This technique is in a way extremely similar to the tiling technique described by David Amador to create large tiled backgrounds with a single draw call. The only difference is that in the tiling technique you set the source rectangle to (0, 0, somethingLargerThanWidth, somethingLargerThanHeight) while in the scrolling technique you set it to (-scrollX, -scrollY, width, height). But you can also go ahead and mix both of the techniques and create a tiled scrolling texture simply by passing it both the scroll position and a size larger than the original image at the same time.

Note for Windows Phone 7 users: If you’re developing for Windows Phone 7 then your scrolling texture needs to be a power of 2 (e.g. 512×512, 1024×1024, 2048×2048). That is one of the many limitations imposed by using the Reach profile in XNA 4.0 (which is the only one supported by the Windows Phone 7) in order to use the wrap addressing mode. More information here

Finally, here’s a small video showing texture scrolling in action. The demo has two cloud textures being scrolled at slightly different rates on top of a static background, and as you can see from the source code below, this is extremely easy to do. For something that you can achieve with hardly any changes to your existing code, I think this is quite a nice technique to have in your arsenal. I hope you enjoyed the article, and until next time!

Source Code
4 Comments.
  1. wapy says:

    :D Incredible! The result looks pretty neat (the idea of using clouds for the example was really nice too).

    And it’s so much simple. Because yeah, when we’re coding we tend to miss the obvious answer right under our noses.

  2. Coder X says:

    Great information but scrollX and scrollY will eventually overflow in a matter of time..

    • Hello there. You’re right :) But that’s because the focus of the article was on the technique (using texture wrapping to achieve scrolling) and not how the user should interpolate the scroll values. The sample was built with that in mind so I purposely kept it simple. Another “problem” with the sample is that my scrolling is framerate dependent too. Once again I did that for the sake of simplicity.

      In a real world example, you should probably make scrolling framerate independent by multiplying the scroll factor by the time elapsed since the previous frame, and wrap the scroll values by multiples of the image’s dimensions, to prevent a future overflow or underflow. For instance, you could use the validation that I show just before the “The Good Way” header to perform the wrapping.

  3. weaver says:

    Thank you so much! I was searching for awhile for how to do this. I was coming from LibGDX to XNA, and was having a heck of a time figuring out how to do this in XNA, I have a game due to be released in the Windows Store in 2 days, and am running out of time, this may have saved me!

  1. [...] textures, then the easiest way is to use the technique described in my earlier article called Scrolling Textures in XNA. This is useful for instance to create starfields or 2D skies, but not as useful for games where [...]

  2. By Scrolling Textures with Zoom and Rotation | David Gouveia on September 20, 2011 at 12:36 am

    [...] already written twice before (here and here) about a way to make a texture seem to repeat itself infinitely in every direction as you [...]

Leave a Reply