Category: Game Dev

Integrating 3D elements into a 2D game

Integrating 3D elements into a 2D game

As you maybe have noticed, Without Escape is a 2D game. All its graphics are pre-rendered 2D images with 2D UI elements on top. However, when you get an item, you can see this nice rotation animation:

Rotating Item

Since everything is pre-rendered, you might think that those item animations are some kind of pre-rendered video or something like that. Wrong! They are actually real-time 3D models with their own textures, materials, lighting and reflections.

Rotating items are a common thing in games in order to see in detail the shape of the item. You can see them in games series like Resident Evil and Silent Hill. So I thought it would be nice to have them in Without Escape too.

The problem

I needed to solve two small problems in order have those 3D items nicely integrated into the 2D:

  • The items appear inside a 2D window. That window has a moving and fading animation when it opens and closes. So the items need to move and fade along with the window. But it would be problematic because of perspective and some tricky things that happen when dealing with transparencies in real-time 3D graphics.
  • I wanted the items to integrate with the environment, to be affected by their lights and the objects that surround it. It’s a subtle thing, but I wanted to increase the feeling that you are getting the item in that specific room.

The solution

For the first problem, the best way to have that 3D object to behave correctly and without complications in a 2D window is to actually convert it into a 2D element. This can be easily done with render textures. A render texture is a special kind of texture that can be updated dynamically. They are used for a lot of things in video games and you can render whatever you want in real-time onto them.

In my case, I did a small lighting setup with the rotating item in the middle, a main orange light in the front, a secondary blue light in the back to have some backlighting, and a camera. All these elements are actually outside of the screen while you play, but you are never going to see them.

Item Setup

The lights obviously provide some nice lighting to the object. And the camera films all that. Everything that the camera sees is stored into a render texture. You can see that in the bottom right corner of the screenshot. And since that is a 2d texture, I can actually use it however I want, in my case as another 2D element in the 2D window that can fade and move along with it. As the item rotates, the camera will see that and will update the render texture in order for you to see a magnificent 60fps animation.

But what about the second problem? We already have two lights that light the item, but they are used to make the 3D model to pop out more. How do we make a 3D object to reflect the environment? It is a 2D background, so you can’t do proper reflections with that. So I pre-rendered a low resolution HDR 360º panorama of the room:

Room Environment Map

If you wrap around this texture around a sphere, you can create an effect like in Google Street View. You can rotate the camera and see the environment in 360 degrees.

Rotating Environment Map

So this is kind of 3D, right? In my case I used it as an environment map so I can generate real-time reflections of the environment! This is how the key would look if you could obtain it in a different environment:

Key in lava room

And look! You can even see the bed reflected on the battery.

Battery reflections


So that’s it. Hopefully you find these small tricks interesting, maybe you can learn something from it, or maybe you can give me feedback if you see something wrong. Now, if you’ll excuse me, I’ll keep workig on Without Escape.

Have a nice day!

Adding dynamism to static backgrounds (Part 2)

Adding dynamism to static backgrounds (Part 2)

If you want to check the first post of this series of posts, check this link.

As mentioned in the previous article, my game is all made with static pre-rendered backgrounds. So I wanted to apply some tricks and effects in order to provide some animation to them. Here’s another trick I’ve used in order to have flickering lights. I’ll talk about this room with candles:

Corridor Background

The process

I wanted to add some subtle flickering to those candles. The easiest way would be to change the brightness of the image. The problem with that is that I would get an unrealistic change of intensity in the whole image. The ideal thing would be to be able to apply different animations to each light source and try to affect realistically to the lighting and shadows of the room. Since the whole room is one static image, I need more information to know how each light affects to the room. And that information comes in form of this image I rendered:

Corridor Lights Combined

Cool! But wait, what is the purpose of those multicolored lights? This actually isn’t an image with colored lights. These are actually three grayscale images packed into one. Let me explain:

A color image is composed by three channels: red, green and blue. The combination of different amounts of these three primary colors is what forms any possible color and generates a full color image. In games, you sometimes need several grayscale textures to store whatever. If you have three of them, they would take some space and the game would have to load those three textures. BUT, what if we store those three images inside the red, green and blue channels of a single texture? We would have only one texture to load and it would take in total 1/3 of disk space compared to having three separate textures!

This is a very common technique called channel packing (maybe it has other names too). So as I said, in the previous color image I actually store three different grayscale images in order to optimize and save space and loading times. In a shader, I can separate those three images again and do whatever I want with each one:

Corridor Lights Separated

Each image contains the whole room being lit only by different groups of lights. This lets me know how each group of lights affects to the room. So knowing that information, I basically apply different animations to each group of lights by changing their brightness of each image and then overlay that on top of the static background image. And this is the final result! (Note: the effect has been exaggerated in order to be more easily perceived. In the game it is actually more subtle).

Corridor Animated


This tricks are helping to provide more dynamism to Without Escape, making the environments feel more real and “alive”. Some other day I’ll write another part of this series of blog posts with the best trick of all!

Stay tuned!

Adding dynamism to static backgrounds

Adding dynamism to static backgrounds


Let’s talk a little bit about one of the tricks I’ve used in Without Escape to add some dynamism to its static backgrounds.

As you’ve probably have seen, the game relies on interacting with pre-rendered backgrounds. That makes everything a little bit too static. It’s always nice to have something moving, even if it is a subtle light flickering, that helps to provide a specific mood to that particular room. But yeah, pre-rendered backgrounds makes things a little bit difficult. Of course I could render looping videos instead of static images as backgrounds, but it would take too much render time given my CPU, render engine and quality of the backgrounds. So I’ve been working on some real time effects in order to spice up a little bit some of the rooms. Besides, real time effects have the benefit of being able to run at 60fps or whatever framerate without having to render more animation frames.

The process

Let’s take into consideration this room:

Room filled with lava

As you can see, it is a room filled with lava. So it should be pretty hot in there, right? Those hanging bodies must be sweating like crazy inside those body bags! So what can I do in order to make the player feel that heat better? Let’s add some heat waves! But there are some properties that are hard to recreate with static 2D backgrounds. For example, heat waves should be more visible the larger the distance from the point of view is. But there’s not depth or distance information in a 2D background. We’ll see how we handle that.

For now, let’s create the heat waves distortion. I’ve done this with a simple shader that, based on a noise texture, it distorts the background. Without being too specific (because it would be quite a long post), I created the following texture:

Cloud Map

And inside a shader, I read the colors of this texture, and based on that pattern, I apply a distortion to the background. And if apply some movement to the noise texture, that distortion on the background will also move, like this:

Background with distortion

Nice, the heat waves are there! But they can be seen with the same intensity through all the background. The closest parts to the point of view should not have distortion. As I said before, I don’t have any kind of depth information in that 2D background. So one thing that can be done is to render from the 3D application another background containing a depth map. It’s easy and quick to do. That depth map looks like this:

Depth map

This gray scale image represents depth. The larger the distance from the point of view, the lighter the color is, so I used this information to know where the heat waves effect should be more or less intense (white = intense effect, black = no effect). I also painted a black gradient at the top of the image so the effect is more intense at the bottom of the room (where the lava is) and more subtle at the top (the heat waves start to fade). When I apply it to the distortion, this is the final result!

Background with correct distortion


So this is one of the tricks I’ve used in some of the backgrounds from Without Escape. I’ve also used it to animate blood in one of them.

Hopefully you find this interesting. Have a nice day!