Header image

ND2D – infinite scrolling made easy with animated UV coordinates

September 26th, 2011 | Posted by lars in Molehill / Stage3D | ND2D | Talk

One really cool thing about textures on the GPU are the different wrapmodes when sampling pixels from it. In Molehill, there are two different types available:

  • CLAMP – if UV coordinates are lower than zero or greater than one, the coordiantes are clamped to 0..1, so the edge pixels are repeated
  • REPEAT – if UV coordinates are lower than zero or greater than one, the whole texture is repeated. So for a UV of (1.2, 1.4) the pixel of (0.2, 0.4) is sampled

Simply spoken, if you set the wrapmode to REPEAT, animate the UV-coordinates and have a self repeating texture, you’ll have the most simple endless scroller you can imagine. Don’t worry, everything is built into ND2D, you don’t have to care about what I just told you. Just watch the example:

This example is included in the ND2D Examples on Github. This scene just consists of two sprites with a fixed position in the middle of the screen. The only thing that is done on the CPU in the step loop is this:

override protected function step(elapsed:Number):void {
    starfield1.material.uvOffsetX -= (stage.stageWidth * 0.5 - mouseX) * 0.00002;
    starfield1.material.uvOffsetY -= (stage.stageHeight * 0.5 - mouseY) * 0.00002;
    starfield2.material.uvOffsetX -= (stage.stageWidth * 0.5 - mouseX) * 0.00004;
    starfield2.material.uvOffsetY -= (stage.stageHeight * 0.5 - mouseY) * 0.00004;

This can become handy, if you want to animate a waterfall, waves or a space field background in your game. Have fun!

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

9 Responses

  • Tyler says:

    This looks really slick. Is it just me, or is the scrolling motion smoother than what we could get before with the display list? I’ve always had problems with moving large graphics around jerking every few seconds.

    Have you considered putting together some sort of tutorial on ND2D? I think more people might experiment with it if there was a clear place for them to get started.

  • Tyler says:

    I got so used to reading your updates here that I kind of forgot about the Wiki you already had. That certainly helps people get up to speed.

  • There is some sort of bug that prevents BitmapData created with the flash.display.BitmapData class from scrolling properly. There appears to be space between the BitmapData in the Sprite2D.

    Replacing the embedded asset in the “StarFieldTest.as” with the flash.display.BitmapData class:

    package tests {

    import de.nulldesign.nd2d.display.Scene2D;
    import de.nulldesign.nd2d.display.Sprite2D;
    import de.nulldesign.nd2d.materials.BlendModePresets;

    import flash.events.Event;
    import flash.display.BitmapData;

    public class StarFieldTest extends Scene2D {
    //(not used)
    private var starFieldTexture:Class;

    private var bmp:BitmapData = new BitmapData(400, 250, true, 0xAAFFFFFF);

    private var starFieldTexture2:Class;

    private var starfield1:Sprite2D;

    private var starfield2:Sprite2D;

    public function StarFieldTest() {

    addEventListener(Event.ADDED_TO_STAGE, addedToStage);

    //Using the BitmapData we created
    starfield1 = new Sprite2D(bmp);

  • lars says:

    That’s no bug, it’s a missing description for this property ;)

    The bitmapdata width and height has to be a power of 2 (64, 128, 256, etc.). Otherwise seamless repeating is not possible on the GPU. Change the size in your test to new BitmapData(256, 256, true, 0xAAFFFFFF) for example and it works.

  • Wajdi azar says:


    guys do you have tutorials some where in the internet :), coz i see that you did a great job doing all this but i cant fined any tuts of how to start with it.

  • lars says:

    @Wajdj: There are no explicit tutorials out yet, but have a look at the examples included in the sources. They should explain a lot.

  • Albob says:

    How would you do it on batched sprite, since they don’t have a material?

  • Albob says:

    Ok, I’ve found a way to do what I wanted. I wanted to be able to offset a sprite at a given time. This is what the property “pivot” is for. Note that it must be followed by “updateLocalMatrix()” when used on a batched sprite.

    I’m still interested in the UV scrolling in batched sprites though, if you have an answer :)

  • Pingback: onebyoneblog » UV Scrolling in Starling

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">