Taps can be unreliable inside this app's built-in browser. For the full experience, use its menu to open this page in your browser.
Skip to content

Three Ways To Fake Depth In A Browser

A devlog by Neeraj Kotwani, who builds every game on Elipar.

Critter Roll is an endless runner with three lanes, obstacles rushing toward you and a jump. It reads as a 3D game. There is no 3D library anywhere in its folder — the whole thing is one HTML file drawing on a 2D canvas.

Counting this one, there are now three genuinely different ways of faking depth across this catalogue, and the interesting part is that each is the right answer for a different reason.

The three approaches

A real 3D library. Most of the 3D games here vendor a single Three.js build locally — a proper scene graph, cameras, lights, shadows and meshes. That is what you want when the camera moves freely, when geometry is complex, or when you need real lighting. It is also several hundred kilobytes and a whole coordinate system to reason about.

CSS 3D transforms. One game here tilts a plain div with perspective and rotateX to make a receding grid road, and layers 2D sprites on top. No canvas, no library. The browser's own compositor does the perspective.

A hand-rolled projection. This game. Objects have a depth, and drawing one is: divide a focal length by the depth to get a scale, multiply the lane offset by that scale to get a screen x, and shift the vertical position toward a horizon as depth increases. About four lines of arithmetic, running on a 2D canvas.

Why the arithmetic wins here

The thing that makes this viable is that the camera never moves. It sits behind the critter looking down the track, forever. Nothing orbits, nothing pans, there is no second viewpoint.

Once the camera is fixed, almost everything a 3D library gives you is machinery you are not using. The projection collapses to one divide. There are no arbitrary rotations, so nothing needs a matrix. There is no lighting, because the art is flat shapes. And the draw order is simply "far to near", which is one sort rather than a depth buffer.

What you get for that is a game that is a single file with no dependency at all, loads instantly on a phone, and can be reasoned about completely by reading one function. For an endless runner with three lanes, the library would have been carrying weight for features the game does not have.

I would not make the same call for an exploration game where the player looks around. That is exactly the case the projection cannot do, and the adventure games here use the real library for that reason.

Two numbers do all the tuning

A hand-rolled projection has one genuine advantage over a real camera, which is that you can lie.

The focal length and the far distance are just constants. Raise the focal length and the track feels longer and flatter; lower it and obstacles rush at you with more drama. Pull the far distance in and you see less road, which is harder. None of that has to be physically coherent — there is no real lens being modelled, so you tune it until the game feels right rather than until the maths is correct.

With a real camera the same adjustments fight each other: changing the field of view to make things rush also changes how much track is visible, which changes the difficulty, which means re-tuning the spawn rate. Here they are separate dials.

That is a genuine reason to prefer the fake over the real one in a game this simple, and not one I expected going in.

The part the library would have handled

Being fair about the cost. Writing your own projection means owning some things that are free in a scene graph.

Draw order is yours — forget to sort and a far obstacle paints over a near one, which looks like a glitch rather than a bug. The scale factor appears in every single draw call, so forgetting it in one place leaves one object the wrong size at depth. And anything that should be hidden behind something else is not, because there is no occlusion at all, only overdraw.

For three lanes of simple shapes that is a short list and it stays short. In a scene with any real geometry it would not, and that is the line where the library starts paying for itself.

The deciding question is not "does this look 3D". It is "does the camera move".

Critter Roll is free in a browser, no account, no download, and no 3D engine.

We use cookies to keep games running and, once ads are live, to show relevant content. See our Privacy Policy for details.