Rendering a 2D game in 3D

Tom Leys
9 min readOct 15, 2019

--

When I began working on The Recall Singularity my imagination contained a tile-based game rendered 2D isometric style. I was considering a look like Diablo 2 or XCom: Terror from the deep.

Sorry if you were surprised to find a link to my Twitter account there, no official homepage yet!

What I have settled on is a sort of realistic / low poly pseudo-isometric game rendered in real-time 3D in Godot. Despite all those complex terms, I think that this is actually a very simple approach — more creators should be doing it.

How The Recall Singularity looks today

Brief foray into “Pre-Rendered Art”

My initial screenshots were pretty embarrassing. We can look back and laugh now — we can all agree that things have come a long way. I was testing my conveyors using 2D tile-maps, with lava textures being my only available source of “art.” I knew it sucked, but I thought it was critical to get “ink on the page” because it is terrifying to stare at a blank canvas.

“Space Factory” as at 27 Nov 2018

The screenshot you see here is merely a proof of concept that I can populate the tiles of a 2D tilemap from data which lives in Rust. Here we see in the lower left a storage container (looks like a +) connected to another through a series of conveyors.

On the right you see 3 more storage containers linked by conveyors. There is even a button “Press Me” which has Rust say “Hello World!” in the console. I’ve shown the console here, with debug output (a list of conveyor and storage modules) produced from Rust.

Perhaps you’d like more info on how to use Godot and Rust yourself?

I initially thought I would need to scrounge up various 2D pixel tile art from various sources. I’m no artist so I don’t want to try to make bad Pixel art. The apparent destructive / repetitive nature of pixel art improvement also put me off. I’m was worried about the time investment of doing this myself enough to get the shaded and realistic look I was going for.

Prerender 2D Assets from simple 3D Models

So I was ready to begin finding suitable free art to use when it struck me that I could just begin rendering the art I needed using Blender. It helped of course that I’d just done some contracting (to pay the bills) involving rendering in Blender. I’d never really used blender before that. So I suddenly realized that I had the skill-set to do this myself.

To be clear, I thought my art would still suck. My expectation was that I would block out some assets and then get them professionally re-done. I was certian that having bad (but working) assets already in game would make working with an artist much easier for both of us later. I’m looking forward to sharing the Godot Editor with collaborators so they can jump in and fix things with no code.

So, I promptly rendered a box using blender and followed tutorials such as how to create perspective Architectural renders or similar tutorials for Factorio.

1 Apr 2019 — Stretched cube, floating cube. On a 1x1 Plane. You could make this!

Soon, my 2D Pre-Rendered workflow looked like this:

  1. Create a tile in blender — 1 unit by 1 unit.
  2. Add a plane under the tile, and a larger one to catch shadows
  3. Animate the whole lot to turn through 360 degrees in 8 steps
  4. Render the animation of the tile rotating from a fixed perspective
  5. Import images into Godot on an isometric TileMap

This actually worked pretty well. I was seriously tempted to stick with this approach and ship the game with tiles exactly like this. This is exactly what Factorio does — they just do it WAY better than me. Have you seen their art? It is GORGEOUS. Oh, also go buy Factorio!

What I observe about the setup above is that all the appeal of these 3D assets is coming from a really nice lighting model provided by Blender. If you look closely I just picked 4 RGB values. White, Grey, Blue and light blue. But all the subtle shading, shadowing and global illumination really adds a lot of free detail.

Screenshot from Jul 2019, before I began using 3D in Godot

A test render of The Recall Singularity eventually looked like this. Note that this game was interactive at this point — you could place conveyors and Storage units. However the walls were fixed in place. I just placed those using the Godot Editor.

Look closer - you’ll spot issues from rendering a 3D model as 2D sprites:

  • Lighting from tile to tile is flat, fixing this is possible but non-standard
  • All those pre-baked shadows can have issues (look especially at the walls)
  • Needs a lot of tilemaps and has fixed perspectives.
  • How would I handle Characters? Animation?
  • I would like to zoom out and rotate the camera for later spaceflight features.

These doubts would take some thinking to resolve and would culminate on my move to full 3D in June 2019.

But first, a brief history in the Recall Singularity:

The first year (briefly) on The Recall Singularity

Note: I work about 3 hours a night about 5 days a week on TRS. I have lovely kids which means I get some extra time on weekends but not much.

  • Oct 2018 — My very dear friend tells me that my Space Game Idea is a winner and I should believe in myself and take a shot on this.
  • Nov 2018 — Rust and Godot working, simple 2D demo as shown
  • Dec 2018 — A fixed 2D ship can be moved using controls, mostly coded in GDScript. You can shoot.
  • Jan, Feb, Mar 2019 — Some time on parallax backgrounds and flight. All my time really was creating a new Chess engine (in Rust, integrated with Unity) for Four Kings one War
  • Apr 2019 — Moved to Isometric grid system mentioned above. Also began work on Networking
  • May 2019 —Custom Lockstep networking over UDP and moved to Specs for Rust code
  • Jun 2019 — A transition from 2D to full 3D. Migrate existing assets and rewrite parts of UI
  • Jul 2019 — Add 3D Cursor, floor meshes and figure out how to build a floor from a 2D map. I also freaked out and almost quit Godot when I realized how nice Substance support in Unity is. Joined Twitter
  • Aug 2019 — Networking for floor changes, Deletion of floors, Pretty rendering of walls based on floor. Began to feel less like an imposter as a game developer.
  • Sep 2019 — Conveyor Joining works as modules are added to a conveyor, including preserving contents. Render boxes on a conveyor. Bones for refinement structures. Discord.
  • Oct 2019 — Start a blog (10k reads, yay!), Gorgeous space rocks and now ingots to render on conveyors.

Quick Plug: Please do join me on the Discord Server. Or if more occasional updates are your thing, I’d love to see you on Twitter.

The Transition to full 3D Rendering

In June 2019 I realized that I would be making life harder for myself by using 2D compositing and lots of custom shadow management. Reading the FFF series there are constant posts about how much work they are doing to blend shadows for various things when rendering in 2D.

A very quick experiment (took me about 1 day) had me exporting my existing blender assets into Godot (tutorials) and creating flat-shaded (no texture) materials. I was snapping components together in a 3D editor but in increments of +/- 1 whole unit per tile and y = 0 (y is up in Godot).

First rendering experiment — Orthogonal Isometric 12 June 2019

I very quickly had a rendered result that while simple looked far superior to the very uniform lighting from before.

Here for example I was testing various spot lighting choices and using a dark blue color as the ambient light to give a “cold night-time” feel.

It’s really really easy to do this…seriously — just set up an isometric camera and put your 1x1 models only on whole values of X, Z and always set Y to 0. Done!

I thought it was now time to experiment with a floor. I created a cube, made it flat. Some loop cuts and four extrusions later I had a simple repeating panel I could use. Having brought Substance Painter, Designer and B2M on a 50% discount on steam I was itching to use it for this new floor mesh. About 4 hours of mucking around later and I had a totally adequate textured floor with mesh to work with.

Thanks to Godot’s standard spatial material and shader I had access to SSAO (Screen Space Ambient Occlusion). This is the shading you can see on the conveyor itself and the shadows around the conveyor and on the floor. I now had a high degree of hope that I could myself create art worthy of my title. I still find that rather shocking actually!

Here’s more on how I position models and similar in Godot if you want more nitty-gritty. Otherwise, carry on…

Lighting pass, cursor light, directional light. New textured floor. 10 July 2019
Realtime lighting and animation (lerping on Y) is fun to play with

Flash forward to today and I’ve made a lot of progress on the state of the game in various domains. It became time to have something worthy to put on the conveyors and so I’ve been exploring a…

Full PBR workflow in Substance Designer

As a programmer I am a very technical guy. So point me at a method where I just need to master some rules and I’m a very happy person. Turns out that some amazing rendering talents (initially at Pixar) have done just that for us and created Physically Based Rendering and Shading.

In July I followed a Creating your first Substance Material and it was frankly amazing what came out. The process totally blew me away — from a software design and “understanding your customer” point of view this product is flat out amazing. It fits me perfectly — the ability to create realistic textures with little effort, using reference gradients… AMAZING.

So this month I’ve been experimenting with fancy space rocks and more. Once I’ve figured this out I’m sure I’ll have more to write about it. But excuse me… I’ve got a lot more rocks, ingots and space machines to make. I’d love to tell you more on Twitter!

In the meantime, why don’t you read How I use Rust and Godot to explore Space. Or perhaps a tutorial on Godot and Rust together?

Gold Ore PBR Materials created and rendered in Substance Designer

Thanks for reading to the bottom! Please do join me on the Discord Server. Or if more occasional updates are your thing, I’d love to see you on Twitter.

--

--