Odd tilemap rendering behaviour on mobile browsers (vertical line bleeds)


#1

I’m experimenting with making an RPG engine using the NPM version of OpenFL and have been having a lot of fun with it; the hot reloading has definitely sped up the development process. When testing it on a mobile browser however, I noticed the following behaviour:

Using a png bitmap asset of ~5kB with tileset sizes of 16px, the rendering causes vertical lines to appear when viewed on a mobile browser:

With the following code that looks something like:

    ...
    var tilesize = 16;
    var bitmapData = Assets.getBitmapData("zz-openfl.png");
    var tileset = new Tileset(bitmapData);
    var L = tileset.addRect(new Rectangle(11 * tilesize, 0, tilesize, tilesize));
    var S = tileset.addRect(new Rectangle(10 * tilesize, 0, tilesize, tilesize));

    var map = [
      [L, L, L, L, L, L, L, L, L, L, L, L],
      [L, L, S, S, S, L, L, S, S, S, L, L],
      [L, S, S, S, S, S, S, S, S, S, S, L],
      [L, S, S, S, S, S, S, S, S, S, S, L],
      [L, S, S, S, S, S, S, S, S, S, S, L],
      [L, L, S, S, S, S, S, S, S, S, L, L],
      [L, L, L, S, S, S, S, S, S, L, L, L],
      [L, L, L, L, S, S, S, S, L, L, L, L],
      [L, L, L, L, L, S, S, L, L, L, L, L],
      [L, L, L, L, L, L, L, L, L, L, L, L]
    ];

    var numTiles = 15;

    tilemap = new Tilemap(Math.round(myRoot.width), Math.round(myRoot.height), tileset, false);
    tilemap.scaleX = myRoot.scaleFactor;
    tilemap.scaleY = myRoot.scaleFactor;

    for (row in 0...map.length) {
      for (col in 0...map[row].length) {
        tilemap.addTile(new Tile(map[row][col], tilesize * col, tilesize * row));
      }
    }
    
    addChild(tilemap);
    ...

What’s weird is that if I use smaller x coordinates (containing the those same pixels for the tiles):

var L = tilesetLarge.addRect(new Rectangle(0 * tilesize, 12 * tilesize, tilesize, tilesize));
var S = tilesetLarge.addRect(new Rectangle(1 * tilesize, 12 * tilesize, tilesize, tilesize));

I get better rendering:

And this problem seems to be exacerbated whenever I make the Tilemap scroll across the screen (vertical lines flicker whenever it moves).

Any advice on going about how to debug/fix this issue would be greatly appreciated; I have an inkling it’s got to do with the size of the bitmap (e.g. this issue isn’t there when testing with an 32px * 16px png of 2 tiles), but I’m not sure why the coordinates of the Rectangle matter when using the same bitmap. I can post some sample code as well if that is helpful.

I’ve been using Chrome on Galaxy Note 4 and Safari on an iPhone 6 to test, with Haxe 4.1.0 and OpenFL 8.4.1 in package.json.


#2
tilemap = new Tilemap(Math.round(myRoot.width), Math.round(myRoot.height), tileset, false);
tilemap.scaleX = myRoot.scaleFactor;
tilemap.scaleY = myRoot.scaleFactor;

Do you know what the Tilemap width, height, scaleX and scaleY end up being in this sample on the mobile device?

Do you know if the device is using WebGL, or if it is falling back to canvas? Using Lime 7, you could trace (stage.window.context.type); and see if it is canvas or WebGL


#3

Hi singmajesty thanks for your reply! Testing it on the Note 4, these are the values:

TilemapTest.hx:117: Math.round(myRoot.width):,980
TilemapTest.hx:118: Math.round(myRoot.height):,980
TilemapTest.hx:119: myRoot.scaleFactor:,4.083333333333333
App.hx:47: stage.window.context.type: ,webgl (using trace("stage.window.context.type: ", (cast stage).window.context.type));

Oddly, I tried adding the canvas flag to the build.xml file so that it looks like:

-main App
-js src/app.js
-cp node_modules/openfl/lib
-cp node_modules/actuate/lib
-cp src
-D source-map
-D canvas

but stage.window.context.type remained webgl.


#4

You can give lime test html5 -Dcanvas a try, or if you’re using NPM releases instead of Haxelib, you can do { renderer: "canvas" } when creating the Stage.

I’m guessing it might be the unusual scale value. See what happens if the scale is 4? We might be able to do more to round positions to limit seams, but see if that helps at all?


#5

Thanks for the {renderer: "canvas"} on NPM tip; I added that configuration to the Stage constructor and it now renders on canvas, and best of all the vertical lines have gone and the scrolling happens without vertical line flickering as well!!

I had also tried changing the scale value to 4 (the odd scale value was because it was calculating to fit 15 tiles onto the width of the screen); I think it’s a bit better but there are still vertical lines present, so I guess the issue has to do with WebGL.

Thanks so much again, I guess I’ll use canvas then for when building for the web. If you need someone to test anything out when doing the WebGL improvements for the seams though, let me know :slight_smile:


#6

On further inspection when I tried running this on the iPhone 6 with original scaling, no scaling, integer scaling (4) on the iPhone 6, I still get those vertical lines, even with canvas enabled for the stage (verified using the Safari remote web inspector) so the issue might be elsewhere! Any other ideas to try?


#7

Maybe let it run on WebGL, but scale everything by an extra 0.5 pixel or so just to try and cover the seams


#8

Hey singmajesty, scaling it didn’t work but I tried adding a bit of padding to the tiles (see the image - using the circled 2 * 2 square areas as the tiles and another 8px of padding around them) - turns out it was actually because the cutting made the pixels from the next tile bleed into the specified one (the green and the blue tile originally were next to each other, which would explain the presense of vertical lines but no horizontal lines).

36

Thanks for your help and suggestions though, I learnt a lot debugging this issue :slight_smile: