Skip to content

177. 3D Dungeon – Tips for performance

October 25, 2014

One of the big things about 3D is making it run fast, because it is much more complex than 2D. This can involve all sorts of design decisions and tradeoffs, and you need to measure the effect of anything you add to your project.

I am currently getting 50+ frames per second in my dungeon, and I thought I’d explain what I’ve done so far to achieve that. (Suggestions and improvements are always welcome, because I do NOT claim to be a 3D graphics expert).

First, it’s easy to think that all the talk of shaders and meshes means it’s too hard, but 18 months ago, I had never seen either, and I believe that if you are smart enough to program, you can learn this stuff too, if you want to..

Tiling the dungeon

I keep saying this, but using a shader to tile a texture across a large mesh is just wonderful. This is at least partly because speed is closely related to the number of mesh vertices in your scene.

To give you some idea – my dungeon is roughly 1000 x 1000 pixels, with about 900,000 pixels in total. I have 29 rooms connected by corridors. I have to draw a floor and roof across the whole surface, and then I need to draw all the walls, 20 pixels high. I calculated the whole scene is about 5 million pixels in total.

But I have only 1,350 vertices. For the floor and roof, comprising nearly 2 million pixels, I have only 12 vertices in total, since each of them is just two enormous triangles. The shader tiles my texture across the whole surface, very efficiently.

Similarly, I have broken up the walls into segments, each segment being a straight stretch of wall. Each segment is also made up of just two triangles.

The speed in the empty dungeon is 59 frames per second, very nearly full speed.

Setting a fixed distance limit for visible objects

I have kept my lighting very simple – basically, it reduces to nil at a set distance (100 pixels) from the camera, varying a bit to give a flicker effect. This is done with a shader, and has some great benefits.

  • it looks nice, like flickering lamplight
  • it is as simple as lighting can get
  • the fragment shader only has 4 lines of code in total, despite handling both the the tiling and lighting, making it extremely fast
  • I don’t need to draw anything that is outside the light radius. So when I loop through all the objects in the dungeon, I check the distance and ignore them if they are out of sight
  • I can set the “far clipping plane” of the camera to ignore anything outside the light radius. This is done in the perspective command, which has 4 parameters, the last one being the furthest distance the camera can see. It makes quite a difference in a case like this.

Keeping the object models small

I usually look for 3D models with downloads that are smaller than 1mb in total, to get the right balance between quality and speed. Some models have 10-20 times the vertices in my whole dungeon, and the detail just isn’t worth it when it’s all semi-dark anyway.

Keeping it simple

I am deliberately building for high performance, and skipping any fancy effects until the whole thing is done. It is much easier to add frills later, than throwing everything in at the beginning and continually fighting performance issues.

Measuring

I know what every effect costs, because I measure it.

That is important. So I add things one at a time and test them.

Anything with a high performance cost has to justify its inclusion. For example, my game starts with the player in a cage. This drops the frame speed to under 30, but it doesn’t matter, because the player will leave the cage straight away, never to return.

Advertisement
Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: