Terrain rendering in fewer than 20 lines of code

9 years ago (github.com)

I stumbled upon this very good explanation (and demo) of the Comanche Voxel 2.5D engine reimplemented in JS and thought it might interest some HNers. I did not had the pleasure to play Comanche though I have fond memories of playing Apache in 1996.

I've been investigating the terrain generation / rendering quite a bit for the past ten days and have started to play with https://threejs.org/, webgl and shaders, the current result (https://twitter.com/maxmre/status/933860624773283842) is quite humbling when I see how nicely the Comanche engine works :)

  • Pretty neat, but I'm confused. You say it's in JS, and the demo certainly is, but the repo is in Python plus some extractors written in C, a few shell scripts, and Markdown docs. No JS in sight. At the same time, Github claims the project is 100% HTML ... I don't know what or who to believe!

    • The project is originally a fan page about the game Comanche and the Voxel Space engine. The web demo is just one part and contains mainly JavaScript. The tools directory contain the code which was used to generate the gif animations and the tools to extract the maps from the Comanche games. So you can ignore the python and shell scripts.

  • Well, the magic of this algorithm lies in the prerendered color map. Use the height maps and color maps from this engine and your result will also look much better.

  • I'm gonna try this out for myself. I love graphics projects like these and the algorithm is straightforward to implement. Most of the additional work is boilerplate, setting up canvas and resource management of images.

Yeah, but imagine doing fractal landscapes on an 8-bit 6502 in 1984:

https://www.youtube.com/watch?v=FbZ-chrOgGg

That is not 20 lines, that's 300+! Here is terrain rendered in 30 lines, with no textures either. https://www.shadertoy.com/view/lslBz7

  • Author here

    The main algorithm fits easily in 20 lines. However, the JavaScript code is optimized and contains also the initializing routines and input device logic.

    It is also a little bit unfair to compare this with shadertoy. He doesn't have to include the render algorithm but relies on a GPU. The Voxel Space engine just draws vertical lines and doesn't need a GPU.

    • Shadertoy shaders _do_ include the render algorithm. That shader is completely ray-traced, so the only real input that is used for that shader is the x, y coordinates and time. It's not using any of the GPU's polygon rasterization. It's stateless and is generating the terrain while it ray-traces it.

    • Firstly - this is really nice. I don't want to derogate the work itself in any way (and I don't think the gp did either) - I'm just really quite curious about what exactly the post title is referring to.

      If I extract the code and delete what I can see might be extraneous setup boilerplate (event handling, camera navigation, init function, image download helper utility, various config object initialisations), it still comes in at around 150-200 lines. The render function alone is 38 lines, not including the external dependencies of that function (DrawVerticalLine, screen, camera).

      Again, not a criticism of the work, just querying the title.

Just a few years after Comanche was released I was sitting in a high school C++ class, content to explore the language with text adventures and RPGs. 3D graphics seemed vaguely mystical to me.

Next to me, however, was someone who seemed light years ahead of me. He had programmed his own voxel terrain rendering just like this. I had no earthly idea at the time how that was even possible.

In retrospect, he was not so much farther along, but he was passionate enough about game development to read books about these techniques and work out the details. I've always wondered what happened to him, and if he ever followed his passion to become a game developer...

  • Never get tired of writing this but people probably get tired of reading it - I played Gunship on the C64 when it came out, and about 20 years later I worked with one of the guys who helped write it, and he was IIRC 16 years old at the time he worked on Gunship (which humbling enough was my age when I was playing it).

  • Ha I was waiting for you to say that guys name was 'John Carmack'

    Could probably search for him on LinkedIn maybe it is ha

  • C++ in high school in the 90s? We had Turing taught by our gym teacher ;(

    • We had Turbo Pascal taught by a math teacher, who read to us straight from a course binder and admitted to literally drawing the short straw in the teacher's lounge when they were figuring out who had to teach the computer class..

      4 replies →

    • I did c++ in high school in the late 90s. No teacher, just a textbook. The "teacher" for the computer lab just handed each of us a book and told us to show him something cool every day.

      So I ended up doing bits of QBasic, Visual Basic, and C++ (since all three books were in the room, and QB was easier to generate flashy visuals with, as a beginner).

    • Our school actually had a pretty good programming curriculum for the time: Basic, Pascal, and C++. Unfortunately the instructor for all three progressed through the topics at an utterly glacial pace. As a result I would finish the assignment in the first 10 minutes and alternate between helping others and surreptitiously playing Master of Orion from my homework diskette.

      1 reply →

    • My high school had a single programming class led by our Physics teacher. UCSD Pascal running on ancient IBM PCs. Having already taught myself Pascal 1+ year prior, it was kind of a waste, but I thought it would be a better elective than metal shop. I did all the exercises and the exam after the first week, so the teacher agreed to let me do whatever I wanted to on the computers the rest of the term as long as I wasn't disruptive.

      On a side note, fast forward to today, I've taken up metal working as a hobby and kind of wished I had taken metal shop instead. Except for the fact that the highlight of metal shop in my year was when a bunch of knuckleheads ground another kid's teeth down in the grinder while the teacher wasn't looking. So, actually, yea I'm glad I opted for computer lab.

    • We had the art teacher teaching us how to fill a form on a Thomson MO5. He screamed when I entered some random data instead of the ones he told us to write because it could brick the computer. :(

    • i started out with c++ freshman year, got the basics down, then the class switched over to turbo pascal the following year. i was bummed, but the math teacher did actually code!

Flashbacks to playing Delta Force in the 1990s as a kid. Looking through the binoculars at a long open distance (say 3500 metres), only to realise that the same hill repeats 3 times :-)

Delta Force 2, released in 1999, still used a voxel engine which could already be hardware-accelerated, supporting "stretched voxels" which were able to simulate high grass.

  • Came to say the same thing. DF and DF 2 are still some of the best multiplayer experiences I've had.

  • Oh, the memories! Delta Force 2 over multiplayer, with, I think, 30 players or more, on 56K was surprisingly fun! Advanced voxel engines are quite impressive.

    • I played both (1 and 2) almost exclusively in single player, completing every mission. SP missions in DF2 were much, much harder by comparison. Unlike the helicopters in DF1, the MIL Mi-24 Hind helicopters in DF2 were able to shoot at you and you were only able to eliminate them either with an anti-tank missile or with the grenade launcher. No matter how many magazines you emptied at a vehicle, it stayed there and didn't explode :-(

  • Oh I so loved delta force. We had some russian version where whole menu was cyrillic and I had no idea what it means but it was still great.

Reminds me of this classic 4k demo which blew my mind back in 1993

http://www.pouet.net/prod.php?which=4662

https://www.youtube.com/watch?v=_zSjpIyMt0k

Neat, great readme.

Everyone seems to be in flashback mode, so I'll add mine: I remember getting a good grade in my multiprocessing class by making a voxel terrain generator using mpi and with the same technique, but also with clouds (just think of upside down white mountains). But I just randomly generate them, without any lighting. The color of the voxels were determined by their height. Using (nice) color and height textures adds a lot indeed! It's a shame I didn't know that trick on that time, I remember playing with vistapro[1] or terragen[2].

[1] http://www.creative-3d.net/images/vistaprointerface.jpg (I had an older, ms-dos based version)

[2] http://planetside.co.uk/ (It's great to see that it's still alive after so many years..)

Here's my (old) take on a terrain renderer (more than 20 LOC, oh well):

http://lou.wtf/earf-html5/

For anyone who wants a refreshing/fun code project, strongly recommend implementing some kind of software renderer. A raytracer or raycasting engine like this one, or something more fundamental like a polygon renderer.

I love it!

How's the rolling in comanche done? The lines are no longer vertical then, so seems trickier.

Roll means the horizon is no longer horizontal by the way, what is labeled roll in the demo is actually pitch :)

This is fantastic! I really enjoyed playing with the web demo. Thanks for open-sourcing it, and for the excellent explanation!

I have a bit of a fetish for old-school 3D tricks, I'm currently working on a 3D project for the Sega Saturn using jo-engine.

Hasn't Outcast (1999) used the same/similar techniques for terrain rendering.

The re-released it on GOG last year, and remade it this year with a Unity engine (all polygons now).

  • We had interpolation to "blur" the rendering + some other optimizations (mostly stemming from the fact that the engine inner loops where super heavily optimized (think VTune level optimizations)) (note that I didn't work on the voxel engine, it was a colleague; I just worked on optimizing the 3D triangle pipeline)

    (edited for more clarity and info)

  • Indeed, Outcast used the same technique. However, not as simple as this algorithm. They included interpolation for the terrain and polygon rendering for the parts, which are not terrain.

Would love to see a C++ implementation of this of this code, whether it's a test project or an example already available in open source.

This would also be a cool thing to give an example of across programming languages. Sort of like how https://github.com/drujensen/fib does it.

Very well and concisely explained, kind of an eyeopener for someone who has never done any game/3D programming.

Where's the 20 lines of code? The code base is small, but looks like hundreds of lines, not dozens.

  • I counted 20 in the body of the README's Render function. I count it as one line if the block is a single line that uses a simple test to execute conditionally (for/if).

    Once you understand the algorithm, it's conceptually even simpler than 20 lines.

  • What you look at, is the whole engine and not just the rendering part. This contains, HTML, CSS, loading and initialization of the maps, clear and flip screen code and especially input device logic. The rendering part in the JavaScript is still rather small. However, the code is optimized and therefore larger. For example the drawing of the vertical line is done manually.

    Read the explanation of this algorithm and you will see how the 20 lines are meant.

The difference between Comanche and Game Gunship 2000 is remarkable. Very good write-up of the techniques.

My only problem with this demo is that it is almost too realistic. It makes me uncomfortable to view something like this and not be able to decide if I'm looking at a computer render or if I'm actually in an airplane flying over real terrain.

there are literally thousands of lines of code in this repo. This is bull shit.

  • The 20 lines refer to the pure rendering algorithm. Please read the description of the algorithm.

    The repo contains also the scripts, to generate the GIF animations on the start page and the tools to extract the maps from the Comanche computer games.