Thursday, September 18, 2014

Superdimensional rendering - overlapping cameras in Unity

I got couple of questions how my LD30 entry "Superdimensional rendering was done. The game was made in Unity engine and the actual dimension beams should work with Unity free. I got couple of questions from co-workers and from forums asking how the rendering was set up. This is a short description. I'm assuming you know a bit of vector math and know how to generate custom meshes. 

Portal beam geometry construction


Portal geometry is constructed only from objects that are marked to be beam blocker objects. When the game starts, all these blockers and their geometry infromation is stored in a list. After that the light mesh loops through the list and builds new geometry using the method below. 

Each frame every blocker meshes' every edge is looped. For each edge we extrude a new edge away from the mouse position. The geometry has to pan far enough to cover screen. In theory it could extrude all the way to, or close to infinity. I had some issues with the code during the jam when I set it to infinity so I just set it to ”far enough” instead. For each edge you end up creating 4 more vertices and 2 new triangles.
When you do that to all blocker objects' edges the result looks something like this:

Beam rendering & camera setup


The game scene had total of 4 cameras. There was one camera for each game world. One for snow, another for water and one more for lava. These world cameras were set to only render objects that were on their worlds. So winter world objects were layered and its camera was set to only render those layers. All the cameras also had to set their culling flag to only clear depth (Clear flags: ”Depth only”).

The cameras were also set to render in particular order. In my case the water world was rendered first. This was done by setting its camera's ”depth” parameter to -0.5. Next lava camera rendered using depth of -0.4 and winter world's camera used depth of -0.3. These values are completely arbitary but the idea is to go from lowest depth to highest. In addition to these there was a final camera which just took the results from the other cameras and added some post process to their pixels. It had its depth value set to 0 to render it last.

The camera set up looks like when you look at them separately:

Now the cameras render in correct order but we need a way to mask each cameras visibility. This was done using shader from over here: That shader simply renders no new pixels (renders ”nothing”) on screen but fills the depth buffer. This shader was used on light beam's mesh. I had 2 beam meshes, 1 for lava world (rendered second) and 1 for winter world (rendered 3rd). Water world didn't need geometry because it was rendered first and should always fill whole screen. In the final step there was a main camera that just rendered some post processing effects and output the result on player's screen. 

And that was basically it. It sounds and looks more complicated than it really is. This technique could easily be used for 2D game shadows or as line of sight mesh. Just use one camera and set the beam material to black and you're done. 

Hopefully someone finds this useful. 

Wednesday, September 17, 2014

Ludum Dare #30 Post-mortem

Alrighty! The Ludum Dare #30 results are in. The ratings went much, much better than I expected. In fact it was a huge surprise to win the overall compo category. There were so many awesome entries that deserved the #1 spot!

You can play my entry here

Now since the results are in, I think its good time to put down some notes and reflect how the development process went.

The idea: This popped into my head from a discussion we had couple of days before the jam with my girlfriend. We were discussing how young babies see and understand the world around them. I had read somewhere how babies don't yet realize that an object that is hidden can still exists in this world. That's why peek-a-boo is so much fun for them. The person hiding behind hands ceases to exist in babies' mind. Their world is literally what they see at the time.

I wanted to make a game where this was actually how the world worked. So basically things that are not visible don't exist at all. Even if our grown up mind says they should still be there. From game mechanic's point of view I just had to figure out a way to hide and show alternative worlds to the player. This is where the "line of sight" mechanics came in.

What went right

- Decision to change the initial concept. I was originally making a puzzle game with 5-10 levels where you'd have to get the ball from start to goal using those “dimensional light beams”. I've found out that I personally enjoy playing these types of games but actually making them is not really my cup of tea. So I made a decision after about 8 hours of work that I want to do something else. I wanted the game to be more of an experience rather than a puzzle.

- Time management! After last year's hectic ending I felt like I had almost too much time this year! I was actually pretty much done with the game about 8 hours before the deadline. This meant that I had 8 extra hours to polish the graphics, sounds and levels. That's a luxury in a jam like this! Overall the game took about 36 hours of work.

- The game has sounds! (which were not slapped on as an afterthought) I'm no sound engineer so this was all new and exciting to me. In fact I can't really say I've ever recorded a sound to be used anywhere before. Last year sounds was the main thing that I had to save time from. I just slapped together something 30 mins before the finish line. This time I had the pleasure to do some actual recording and manipulate them into somewhat surreal or even spooky sound scheme.

What could have gone better

- Play testing! In such a short time frame there is no room to test the game on outside people. You could send a build to your friend (which I did) but you can't see how they are actually playing the game! This lead to the next point which was the main issue the game has.

- Control scheme :( Those teleports can be tricky to control. This is because I didn't anticipate how people would play the game. I designed them to work so that the player would only beam a small portion of a level just to get past a smaller obstacle in the winter world. However I found out afterwards that pretty much everyone used them to turn the whole screen into another world. This can make the game considerably more difficult to play because you can't see what is going on on the other worlds.

- Failed initial concept. Some hours were wasted during the first puzzle game iterations that I mentioned earlier. It could have been a fun game too but it just didn't feel like a game I wanted to make. It was a right decision to scrap it though.

- More particle effects and movement. Especially the lava / hot world didn't get the visual look I was after. This was due to a limitation to the way I ended up rendering the teleports. Lava level could not have any normal particles because of those limitations.

- Minor issues here and there. This was nothing critical. Just some nasty spots where you could get stuck and some stupid spelling mistakes.

Overall the process went extremely well! Almost too well. I liked my core concept and got it working pretty early in the development. After that it was pretty smooth ride to the ending. 

Alrighty, say hello to my new blog!

I've been thinking of starting a blog about random game development related topics for couple of years now. I guess I've just waited for some kind of incentive to get started. There are times when you create something you'd like to share with other game devs. This is what this blog is going to be used for - Share some relatively random game development topics. I'm mostly interested in graphics and graphics programming so the emphasis may end up being towards those topics.

I'll probably start off with the last Ludum Dare which went particularly well this time. Let's see how this goes!