LovePosted by Eskil Steenberg Fri, June 26, 2009 19:09:00

This is a very technical post, but for people who are interested, I will now give you an overview of the rendering engine powering LOVE.

The rendring engine used for LOVE is a custom built highly optimized OpenGL engine that tops out at around 200FPS running in 1920 by 1080 on a 100USD graphics card. While performance have always been important so has visual quality, compatibility, and most of all dynamic content. I try to use as few GL extensions as possible and beyond GL 1.2 the only ones i use are Cubemapps, FBOs, GLSL_100 and VBOs (Optional) giving me a very high degree of compatibility and portability.

Writing a good graphics engine is as much an art as it is a science, often there are many conflicting goals and optimization advice to follow. Sort front to back or state sort? CPU PVS or brute force GPU? Few state changes while avoiding uber shaders? Geometry or texturing? Looks vs Performance? Here are some of the choices i have made.

Terrain engine

The terrain engine is the by far biggest part of the engine and it also spends almost all graphics cycles. The world is build up out grids of blocks, and 8 by 8 blocks form a group. Each groups polygon mesh is generated by the engine and put in to a very large Vertex Buffer Object (VBO). By keeping all groups in a single large VBO I can bind the buffer once, then set up my vertex pointers (I use a interleaved vertex format for size and cashing reasons) at the beginning of the array once and then make a number of ranged draw calls for the groups that are inside the view frustum. Reducing state changes like this gives a massive boost to performance (especialy not having to reset the vertex pointers for each draw call), and i try to do it across the engines. The polygon array for each group starts with all walls, then objects, then floors and then finally edges and grass. This way I can draw different ranges depending on how far away the group is. If the group is far enough away i only draw walls (the ground wont be visible due to the curvature of the planet) as it gets closer a draw more and more of the array until i draw the smallest details like the grass. Keeping everything in a single VBO does force me to do my own memory management to defragmentate the VBO. Given the size of the world I only store groups that are close to the camera in the VBO, so when the player moves new groups have to be added and old ones removed. All this however forces me to draw all terrain with a single shader, and the little texture mapping I do (i mainly flat map polygons with single colors for artistic and art budget reasons), is done by UV mapping around one very large texture. 

To make my geometry more organic i add a quad that protrudes out from each polygon edge. This quad is then given a rounded profile using a alpha test texture. By lighting it and shading it the same way as the polygon it nicely blends and extends the surface. Normal engines have a lot of detail on the surface, with little edge detail where as I go in the opposite direction. The majority of the "Look" of LOVE comes from these very simple tricks rather then and complicated screen space computations. 


The surface shader is a fairly simple one that uses normal texturing and lighting for local light sources. The sun light and ambient light are look-up in to two cube maps. These cube maps allows me to precisely control the color of each angle, and lately I have added a bit of colored noise in them to give some life to the environment. I refrain from filtering any of the qubemaps to create some extra banding that help establish the painterly look. The shadows are done with a simple shadow map. The complexity of the terrain unfortunately requires me to draw it in its entirety during the shadow pass, making cascading shadow maps a little too expensive. Finally I add a four color fog, with a near and far color, for the direction towards and away from the sun. This fog algorithm is then replicated in the sky box to match.


The game employs a lot of FX and they are all based on two primitives, sprites and quads expanded along a axis (lines). Both these are expanded and aligned towards the camera inside the vertex shader. A major problem with FX work is that you end up with very many draw calls, sometimes only containing a single polygon. Therefor i consolidate all sprites and lines in to two draw calls by accumulating them in to large arrays. Again this means they need to map around large textures rather then giving each sprite and line type its own texture. Objects are collected in a similar way so that they can be drawn all at once. The only FX not done using these arrays is the mist. The mist is made up by large sprites that travel over the surface of the terrain. To get thick enough  mist I end up with a lot of overdraw, especially if many mist sprites get so close to the camera that they cover the entire screen. To combat this i have special shader that fades out the sprites as they get closer to the camera, and if they are close enough, it simply doesn't expansion the sprite, and the rasterizer ends up rasterizing an infinitely small polygon. 


The entire frame is drawn in to a off screen buffer (Using FBOs) and then drawn with a color correcting and filtering shader to the screen. To improve the performance and soften the image i draw the off buffer at slightly lower resolution then the screen resolution, this has however very little impact on performance since I'm almost completely vertex bandwidth bound.

When writing a custom engine like this, and especially when you do non-photorealistic rendering you need to spend a lot of time experimenting and trying things out. Some parts of the graphics pipeline has been totally rewritten from scratch four or five times. As for the future there are some things i am still considering adding is a image space distortion map, but there are too few reasons to use it and the cost of switching FBO state is unfortunately a bit high. Other possible additions is to use a float buffer for the off screen rendering but again the bandwidth cost is far to high for the added quality. I would consider having these things optional, but it has been along standing goal of mine to present good visual quality even on low end rigs, and avoid the feeling that you are not experiencing the game it was meant to be.

  • Comments(31)

Fill in only if you are not real

The following XHTML tags are allowed: <b>, <br/>, <em>, <i>, <strong>, <u>. CSS styles and Javascript are not permitted.
Posted by Gustav Mon, July 20, 2009 02:58:00

thanks for the telling us this

måste säga du är så grym eskil ;)

Posted by Tode, or is it? Sat, July 18, 2009 17:17:03

I would really like to know what programs you/he is using. Could anyone give me a list? I saw that video that he only uses free openSource programs. So... :D Give!

Posted by Vrocas Wed, July 15, 2009 18:48:02

I think he is on Holidays :O

Posted by Dan Wed, July 15, 2009 17:55:28

Lol at stickboybob..... Vrocas and Me are friends over msn.... not Eskil and me or Eskil and Vrocas :)

Btw Eskil... do you really check your mail and comments ???

Posted by Vrocas Mon, July 13, 2009 11:08:03

Every beta/Alpha have some little Bugs ;)

Posted by squiz Sun, July 12, 2009 23:08:30

I love the look of this game and i'm so very eager to play it.
I've been following it's progress on and off ever since I saw it mentioned on
I just watched the tool video, and the intro to the game video, and im blown away.
Keep up the good work my friend, you can count on my subscription when it's finally released.

(to all the people asking about betas)
Seriously, i'm prepared to wait, i'd rather play a well made game than a rushed buggy one.

Posted by stickboybob Sun, July 12, 2009 22:59:59

yes i have already decided your name is now dan, not eskil.

Posted by stickboybob Sun, July 12, 2009 22:58:41

howdy dan! i just made bratwurst! mmm mmm they are so good.
you game is neat too.

Posted by Vrocas Sun, July 12, 2009 15:22:25

Hey Dan! I think, I have you in MSN!!! :D
Yeah, release the Alpha, plsssssssssssss! :D

Posted by Dan Sun, July 12, 2009 00:04:36

You should really release a alpha/beta soon or else peoples will get tired of waiting :/
The ingame video you created looks like a full game so what's missing ??

Posted by Travis Fri, July 10, 2009 08:05:41

When does the alpha/beta start? I'd pay for even an alpha, many people would. Looking at the game it seems fairly far along

Posted by Vrocas Wed, July 08, 2009 11:35:45

When comes the Beta?
Wanna play it :D

To youre Technologie Post, I am very, very very very surprised!

Posted by Sun, July 05, 2009 14:15:10


Posted by lobotony Fri, July 03, 2009 19:50:08

hey Eskil,

how often do you update the geometry in the VBOs, and when you do, do you mirror the data in CPU RAM and subData parts of the buffer, or do you use map/unmap and modify the buffer directly?

Thanks for sharing!

Posted by goshki Tue, June 30, 2009 12:41:33

Interesting read. It's a pity however that you focused on the gfx issues. Any possibility that you'll elaborate more about level generation algorithms in the future?

Posted by benporter Tue, June 30, 2009 01:46:41

interesting notes, thanks! looking forward to the release.

Posted by mring Tue, June 30, 2009 00:54:05

of course copy and paste doesn't work, it's just a figure of speech ;)

Posted by mring Tue, June 30, 2009 00:53:05

you can use all the fancy stuff where available.
just do an extension check like Quake3, and only enable the stuff available.
i am pretty sure you can copy-paste it from Quake3, as it's under GPL.

Posted by joel Mon, June 29, 2009 21:57:46

Are you going to make the engine also have a few boosts to graphical juiciness so that if someone has invested in a more costly gaming rig, they then have the option to add more details and so forth?

Posted by Smitty Mon, June 29, 2009 07:58:45

It sounds very exciting, and I love to hear this kind of detail from the developer's point of view. Best of luck!

Posted by jc Mon, June 29, 2009 03:46:25

Re: using OpenGL 1.2 + extensions, if you're using GLSL, you've already edged out the Intel integrated chipsets. All of the nVidia and AMD cards whose drivers support GLSL, VBOs, and FBOs also support OpenGL 2.0, so you'd save yourself some pain just targeting OpenGL 2.

Posted by Tony Sun, June 28, 2009 18:06:21

This game is based on a lot of philosophies that make sense. More than any other game I've seen. What you have here is quite deep, Mr. Steenberg. I've definitely felt the same way about memory management, that instead of sharply adding and deleting objects, that they progressively fade out of the experience, but then I would delete them (of course, the mist keeps track of the wind, so it's necessary). When you look at Call of Duty 3, you can see that the soldiers clearly automatically spawn and they disappear if too many carcasses appear. Having enemies spawn over and over and over again when the simple goal of reaching point B is there is like mixing stale bread with cottage cheese. They're weird/unpleasant on their own and are worse together.

Posted by CroMag Sun, June 28, 2009 06:47:09

Have you made the game beta yet?

Posted by AlbeyAmakiir Sun, June 28, 2009 05:25:09

"it has been along standing goal of mine to present good visual quality even on low end rigs, and avoid the feeling that you are not experiencing the game it was meant to be."

An admirable goal. I love games that scale well. Pity they're far to rare. Funny how developers usually do the latest and greatest graphics, because that can sell well, but not everyone can see those graphics. Yet they still do it in a way that makes it very ugly if you lower the graphics even a little.

Posted by Yakri Sat, June 27, 2009 05:38:16

I agree that your very good at explaining technical stuff in simple terms, I've barely gotten into coding but almost all of that made sense to me.

I too think it'd be interesting if you told us something of how the physics in LOVE work. ^_^

Posted by Francisco Ortiz Sat, June 27, 2009 01:49:47


Please say something to us about how you are handling physics :P

Thank you!

Posted by Eskil Steenberg Sat, June 27, 2009 00:02:35


Buffer switching is somewhat expensive, but setting up the vertex format is very expensive so that is what you want to avoid.

Posted by Orange Fri, June 26, 2009 21:44:58

I too was suprised how much of that i understood. you are really good at explaining tecnical things.

" tops out at around 200FPS running in 1920 by 1080 on a 100USD graphics card" that is very impressive, i wonder how well it will work on my compurter.

by the way, (you may have said this somewhere else in the comments) for the beta will we need to be in the same loacation as your server for the game to run well? and if so, where is the server(s)

Posted by tonic Fri, June 26, 2009 21:15:52

Great, thanks for the explanation. This was interesting reading.

However I wonder have you thought the hardware base which is selling a lot currently - mini laptops, which tend to have Intel GMA950 gfx adaptor or so. No GLSL there. :(

Posted by Coded One Fri, June 26, 2009 19:53:49

I was surprised how much of this I actually understood. I'm also very glad that you are focusing on these older graphics cards, many games just have scary visuals but then crappy options to play the game on older rigs. Video Games are not only about gameplay, or only about graphics and sound, Video Games are about the entire experience, and it's a damn shame that new games are allowing no one to get the full experience.

"tops out at around 200FPS running in 1920 by 1080 on a 100USD graphics card"

That really stunned me. My natural resolution is 1680 x 1050, and if I ever want to run a game at that resolution, I have to turn down ALL graphics settings.

The more I hear about LOVE the more I can't wait to try it. Keep up the good work, I'm really looking forward to that beta!

Posted by swiftcoder Fri, June 26, 2009 19:26:59

A very interesting contrast to mainstream rendering engines. I wonder whether all that VBO packing actually pays off on high-end cards? I know it represents a major performance increase on older cards, but I have a feeling that driver optimisations have lower the cost of VBO binds to the point that you aren't saving that much.