# How does one make a 3D background in a 2D game?

I am trying to figure out how to make a background that looks 3D in a game that is 2D. Below there is a video of the game "Under The Lotus." I am trying to get a background with similar effect (it looks like a 3D environment, while the game runs basically in the X and Y axis).

Can anyone give me an idea how to do that? Or point me in some direction on what to read to be able to figure this out?

I am planning on using SDL for this game. If I could avoid using OpenGL that would be better, but it is not a real requirement.

• That (assuming you mean clouds) looks like it's a pre-rendered background (a video), i don't see it reacting to the players position or the game in general. – George Duckett Oct 12 '11 at 10:47
• Well, it seems to me those clouds are generated during runtime. Perhaps I am wrong, but what I am looking for is actually being able to have this effect of clouds (that I could generate during runtime), and not necessarily have the background react to the player position (at least no yet). Any suggestions on that? – Gilgamesh Oct 12 '11 at 12:04
• Not familiar with SDL myself, but could you have several layers of differently sized transparent sprites scrolling small ones faster than large ones. – George Duckett Oct 12 '11 at 12:25
• I guess I could do that, but I think it might be too slow. Might need to try out and see... There is not a specific design for that in the SDL API (not that I know at least), so I would have to blit in a specific order to the same surface (I can create an object with a Z-index for example, and bind from index 1 to index X). – Gilgamesh Oct 12 '11 at 12:38
• I need to go to bed, but my answer would include using homogeneous co-ordinates (X, Y, Z, W) for the center position of each cloud particle; but also reusing the W component of the position co-ordinate for the size of each particle. – Jonathan Dickinson Oct 12 '11 at 22:35

Like chrish said, I would recommend writing a game in a 3D engine or with a 3D framework than working with a 2D engine or framework and trying to add in 3D just for a single effect. OpenGL can do it, and so can many other game engines, like Unity (I would assume) and the BGE.

A lot of 2D games are actually written using OpenGL (which is still a good option with SDL, actually); you can take advantage of the 3D hardware for creating very nice special effects without impacting your draw performance.

In a case like this, you'd draw your 3D background, switch to an orthographic projection, then draw your 2D bits on top. If I remember correctly, glOrtho() sets up the projection you want, and should be enough info to get you going (finding ortho tutorials is as simple as hitting up the Google). For example, NeHe's Tutorial 21 shows you how to use glOrtho() for drawing 2D objects.

• Great I will have a look into that. Perhaps it might clear some things up for me, and I can progress a bit with the result I want to get. Thanks! :) – Gilgamesh Oct 12 '11 at 16:05

As others have said, using OpenGL/DirectX will give you more options and better performance for most things. It's definitely a lot more complex than SDL, but it will pay off.

The particular effect looks a pixel shader that uses noise (probably multiple times - first to find the coordinates in the noise, then to find the value). I was able to achieve a similar effect with this (HLSL, sorry):

sampler sNoise = sampler_state { texture = <_noise>; magfilter = ANISOTROPIC; minfilter = ANISOTROPIC; mipfilter = ANISOTROPIC; AddressU = MIRROR; AddressV = MIRROR; };
sampler sColors = sampler_state { texture = <_colors>; magfilter = ANISOTROPIC; minfilter = ANISOTROPIC; mipfilter = ANISOTROPIC; AddressU = BORDER; AddressV = BORDER; };

float4 background(PixelInfo p) : COLOR0
{
float3 ofs = _time * _velocity + _ofs;
float3 spos = float3((p.uv - ofs.xy) * 512 / _screenSize, ofs.z);

float3 vpos;
vpos.x = tex3D(sNoise, spos + 0.0000).r - 0.5;
vpos.y = tex3D(sNoise, spos + 0.3333).r - 0.5;
vpos.z = tex3D(sNoise, spos + 0.6667).r - 0.5;

float v = tex3D(sNoise, vpos).r;
return tex1D(sColors, pow(v, _density));
}

• If it is not much to ask... is there a way you could share the whole source for that example? I am very interested on trying to compile and run it, and play around a bit to try to get the hang of this. – Gilgamesh Oct 12 '11 at 17:56
• It's from an overly-ambitious XNA project of mine 2 years ago... If I can get it to compile, I will upload it later today. – Robert Fraser Oct 12 '11 at 20:19