Jump to content

Isometric tile engine : about speed & perfs


Moen
 Share

Recommended Posts

Hi everybody !

 

First of all sorry for my poor english it's not my mother tongue, so please apologize the mistakes.

 

I work on an isometric tile engine, based on pixi.js (Yeah!) for a little rpg.

 

My tryout work fine, except the performances, I dont understand what i'm doing wrong.

Here my source code (scroll.7z.txt (remove the .txt to use, the forum refuse me to upload 7z file) just unzip somewhere and open 'scroll2.html' (tested with firefox)

It's a big area, covered with tiles who scroll from left to right to simulate a movement (later it's can scroll up & down to, it's a very big world)

Currently I pick texture randomly.

 

 

Algorith détails :

In fact I load about 1500 sprites in a DisplayObjectContainer just once.

Each sprite width is 64px, the textures are cached in a structure (so they are only calculated once)

 

then I move the Container for step*64 pixel, when the movement is done I switch all the sprite texture like

 

sprite[j].setTexture(sprite[j-step].texture);

 

And its work !....

...but with or without passing in my scrolling function I have only 30-40 fps.

 

Is it the fault of the sprite number ?  Maybe the TextureRenderer can help me but all my tries are big failures, I may not understand how it work.

 

My biggest problem is that in the bunny jumping example (http://www.goodboydigital.com/pixijs/bunnymark/) my computer still have 60fps with 5000+ bunnies, a lot more than in my code. Maybe it's because of the size of the sprite ?

 

So what I've missed in my code ?

How can I improve my code ?

 

Thank you for reading, I hope someone can help me :P

Link to comment
Share on other sites

Isometric rendering is really hard to optimise, and loading the whole area is not a good idea.

I'm working on an isometric engine too and after testing many rendering engines I finished writing my own.

basically I split the world into small maps (32x32 tiles each) and attach them togetehr, only 9 maps data is loaded at a time, and only tiles in the view ports are renderd (this is important).

 

next you'll have to deal with z-indexes and here where things get complicated, because you'll no more be able to use standard optimisations such as drawing only changing parts of your canvas (the whole scene is allways moving and z-index becomes invalide)

 

updating z-index continuously = maintaining a stack with all visible objects and sorting those objects each frame (well almost each frame :) ) ... and here is what most of performance will be lost.

 

that being said, I'm still planing to use Pixi later with some custom optimisations for isometric rendering.;; but presently I'm using a custom dumb canvas renderer with a z-indexs stack and the above maps optimisations :)

 

 

to get an idea of what I obtain with the above optimisation here is a small world example (4 maps)  http://labs.ezelia.com/engine/demo-4map.html

and a bigger world (50 maps ) : http://demo.ezelia.com/ (for this one you need to choose a player name to start testing)

Link to comment
Share on other sites

Thank you for the example and your tricks !! (your work is really nice by the way!)

 

But after some tests my problem seems to be linked with the render stack of pixi.js, and not really the core of my algorith. Maybe i dont understand something while using pixi.js.

 

Obviously, I dont load everything at a time, but only the display screen and 2 lines of sprite left and right / up and down for preloading (50*30 tiles = 1500sprites)

In this example the map is infinite, randomly generated.

 

For the z-index i know it break a lot of optimisation trick. but my current engine is not optimised neither

Link to comment
Share on other sites

...

that being said, I'm still planing to use Pixi later with some custom optimisations for isometric rendering.;; but presently I'm using a custom dumb canvas renderer with a z-indexs stack and the above maps optimisations :)

 ...

 

Make sure to contribute any optimizations back, we would love to have them!!

Link to comment
Share on other sites

If you can use webgl, then render isometric map using it (z-culling). Canvas 2d doesn't store depth value so you have to sort your map objects by some algorithm, which can be very complicated if your objects have fancy shapes. Read this https://en.wikipedia.org/wiki/Z-buffering. Unfortunately I can't use webgl because imo still too many devices doesn't support it, so I'm looking for walkaround.

Link to comment
Share on other sites

I use pixi.js, it render with webgl but I dont know how, actually I use pixi.js to avoid having to go deep in the WebGl ;)

 

My real question is : why 1500 sprites in my example kill my computer while 5000 sprites+ in the benchmarkbunny dont drop the framerate .

 

I used to develop isometric engine using SDL, but it's different with Pixi.js and I cant use the same optimisation tricks. So I'm curious to know how to optimise my use of pixi.js

Link to comment
Share on other sites

@Moen, what Quetzacotl want to say is to use 3D scenes with isometric camera to simulate isometric, Pixi use WebGL but for 2D rendering :)

 

now about your performance issue, best way to know what's going wrong is to profile your code using chrome dev tools.

but from your description I think the problems comes from memory and garbage collection.

in the bunnymark example, objects number is almost stable objects move around but never get deleted.

in your scrolling example, when sprites become invisible they are no more referenced then the garbage collector need to clean them so it can reuse that memory.

this is the difference between the two cases.

 

I also started isometric coding in SDL :) , if you want good performance in isometric rendering with javascript just translate your C/C++/py code to JS but try to avoid garbage collection by using an object pool instead of just allocating and freeing JS objects.

Link to comment
Share on other sites

To be more precise: Ortho projection with camera angle 45/-30 or somehing like that. This will give you isometric view where you don't need additional depth sorting.

 

Right, but what Moen is looking for I think is really 2D isometric. and he should have reasons for that :)

Link to comment
Share on other sites

In fact Ezelia I use the same pool of sprite all the time, I just change their texture. So I may enconter a garbage problem, but not about the sprites. I create them one time at the beginning of the script and never destroy them, they are always displayed.

But changing or not the texture dont impact the poor performances, if I comment my 'switch' function the result is the same.

 

This evening i'll try to understand (again) how to use renderTexture :') Maybe it's a key of my problem.

 

 

NB : I just tried my code now at work and I dont encounter any framerate drop..... I think i'll kill myself in an orgy of dead pixel ! :angry:

Link to comment
Share on other sites

I tried with
 var renderer = new PIXI.CanvasRenderer(1700, 748);

post-4016-0-60946500-1371481120.png

 

and

 var renderer = new PIXI.WebGLRenderer(1700, 748);

post-4016-0-36600300-1371480922.png

 

It's quite the same, but this is my work computer, i'll try at home this evening.

 

NB : I notice that my code dont work on chrome with WebGL (chrome is up to date)

Uncaught Error: SecurityError: DOM Exception 18 pixi.js:2632

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...