https://github.com/s-macke/VoxelSpace Skip to content Navigation Menu Toggle navigation Sign in * Product + GitHub Copilot Write better code with AI + Security Find and fix vulnerabilities + Actions Automate any workflow + Codespaces Instant dev environments + Issues Plan and track work + Code Review Manage code changes + Discussions Collaborate outside of code + Code Search Find more, search less Explore + All features + Documentation + GitHub Skills + Blog * Solutions By company size + Enterprises + Small and medium teams + Startups By use case + DevSecOps + DevOps + CI/CD + View all use cases By industry + Healthcare + Financial services + Manufacturing + Government + View all industries View all solutions * Resources Topics + AI + DevOps + Security + Software Development + View all Explore + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners + Executive Insights * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Enterprise + Enterprise platform AI-powered developer platform Available add-ons + Advanced Security Enterprise-grade security features + GitHub Copilot Enterprise-grade AI features + Premium Support Enterprise-grade 24/7 support * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up Reseting focus You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} s-macke / VoxelSpace Public * Notifications You must be signed in to change notification settings * Fork 270 * Star 6.3k Terrain rendering algorithm in less than 20 lines of code s-macke.github.io/voxelspace/voxelspace.html License MIT license 6.3k stars 270 forks Branches Tags Activity Star Notifications You must be signed in to change notification settings * Code * Issues 4 * Pull requests 3 * Actions * Projects 0 * Security * Insights Additional navigation options * Code * Issues * Pull requests * Actions * Projects * Security * Insights s-macke/VoxelSpace master BranchesTags [ ] Go to file Code Folders and files Name Name Last commit message Last commit date Latest commit History 78 Commits images images maps maps tools tools LICENSE LICENSE README.md README.md VoxelSpace.html VoxelSpace.html View all files Repository files navigation * README * MIT license Voxel Space web demonstration Web Demo of the Voxel Space Engine History Let us go back to the year 1992. The CPUs were 1000 times slower than today and the acceleration via a GPU was unknown or unaffordable. 3D games were calculated exclusively on the CPU and the rendering engine rendered filled polygons with a single color. Game Gunship 2000 in 1991 Game Gunship 2000 published by MicroProse in 1991 It was during that year NovaLogic published the game Comanche. Game Comanche in 1992 Game Comanche published by NovaLogic in 1992 The graphics were breathtaking for the time being and in my opinion 3 years ahead of its time. You see many more details such as textures on mountains and valleys, and for the first time a neat shading and even shadows. Sure, it's pixelated, but all games in those years were pixelated. Render algorithm Comanche uses a technique called Voxel Space, which is based on the same ideas like ray casting. Hence the Voxel Space engine is a 2.5D engine, it doesn't have all the levels of freedom that a regular 3D engine offers. Height map and color map The easiest way to represent a terrain is through a height map and color map. For the game Comanche a 1024 * 1024 one byte height map and a 1024 * 1024 one byte color map is used which you can download on this site. These maps are periodic: periodic map Such maps limit the terrain to "one height per position on the map" - Complex geometries such as buildings or trees are not possible to represent. However, a great advantage of the colormap is, that it already contains the shading and shadows. The Voxel Space engine just takes the color and doesn't have to compute illumination during the render process. Basic algorithm For a 3D engine the rendering algorithm is amazingly simple. The Voxel Space engine rasters the height and color map and draws vertical lines. The following figure demonstrate this technique. Line by line * Clear Screen. * To guarantee occlusion start from the back and render to the front. This is called painter algorithm. * Determine the line on the map, which corresponds to the same optical distance from the observer. Consider the field of view and the perspective projection (Objects are smaller farther away) * Raster the line so that it matches the number of columns of the screen. * Retrieve the height and color from the 2D maps corresponding of the segment of the line. * Perform the perspective projection for the height coordinate. * Draw a vertical line with the corresponding color with the height retrieved from the perspective projection. The core algorithm contains in its simplest form only a few lines of code (python syntax): def Render(p, height, horizon, scale_height, distance, screen_width, screen_height): # Draw from back to the front (high z coordinate to low z coordinate) for z in range(distance, 1, -1): # Find line on map. This calculation corresponds to a field of view of 90deg pleft = Point(-z + p.x, -z + p.y) pright = Point( z + p.x, -z + p.y) # segment the line dx = (pright.x - pleft.x) / screen_width # Raster line and draw a vertical line for each segment for i in range(0, screen_width): height_on_screen = (height - heightmap[pleft.x, pleft.y]) / z * scale_height. + horizon DrawVerticalLine(i, height_on_screen, screen_height, colormap[pleft.x, pleft.y]) pleft.x += dx # Call the render function with the camera parameters: # position, height, horizon line position, # scaling factor for the height, the largest distance, # screen width and the screen height parameter Render( Point(0, 0), 50, 120, 120, 300, 800, 600 ) Add rotation With the algorithm above we can only view to the north. A different angle needs a few more lines of code to rotate the coordinates. rotation def Render(p, phi, height, horizon, scale_height, distance, screen_width, screen_height): # precalculate viewing angle parameters var sinphi = math.sin(phi); var cosphi = math.cos(phi); # Draw from back to the front (high z coordinate to low z coordinate) for z in range(distance, 1, -1): # Find line on map. This calculation corresponds to a field of view of 90deg pleft = Point( (-cosphi*z - sinphi*z) + p.x, ( sinphi*z - cosphi*z) + p.y) pright = Point( ( cosphi*z - sinphi*z) + p.x, (-sinphi*z - cosphi*z) + p.y) # segment the line dx = (pright.x - pleft.x) / screen_width dy = (pright.y - pleft.y) / screen_width # Raster line and draw a vertical line for each segment for i in range(0, screen_width): height_on_screen = (height - heightmap[pleft.x, pleft.y]) / z * scale_height. + horizon DrawVerticalLine(i, height_on_screen, screen_height, colormap[pleft.x, pleft.y]) pleft.x += dx pleft.y += dy # Call the render function with the camera parameters: # position, viewing angle, height, horizon line position, # scaling factor for the height, the largest distance, # screen width and the screen height parameter Render( Point(0, 0), 0, 50, 120, 120, 300, 800, 600 ) More performance There are of course a lot of tricks to achieve higher performance. * Instead of drawing from back to the front we can draw from front to back. The advantage is, the we don't have to draw lines to the bottom of the screen every time because of occlusion. However, to guarantee occlusion we need an additional y-buffer. For every column, the highest y position is stored. Because we are drawing from the front to back, the visible part of the next line can only be larger then the highest line previously drawn. * Level of Detail. Render more details in front but less details far away. front to back rendering def Render(p, phi, height, horizon, scale_height, distance, screen_width, screen_height): # precalculate viewing angle parameters var sinphi = math.sin(phi); var cosphi = math.cos(phi); # initialize visibility array. Y position for each column on screen ybuffer = np.zeros(screen_width) for i in range(0, screen_width): ybuffer[i] = screen_height # Draw from front to the back (low z coordinate to high z coordinate) dz = 1. z = 1. while z < distance # Find line on map. This calculation corresponds to a field of view of 90deg pleft = Point( (-cosphi*z - sinphi*z) + p.x, ( sinphi*z - cosphi*z) + p.y) pright = Point( ( cosphi*z - sinphi*z) + p.x, (-sinphi*z - cosphi*z) + p.y) # segment the line dx = (pright.x - pleft.x) / screen_width dy = (pright.y - pleft.y) / screen_width # Raster line and draw a vertical line for each segment for i in range(0, screen_width): height_on_screen = (height - heightmap[pleft.x, pleft.y]) / z * scale_height. + horizon DrawVerticalLine(i, height_on_screen, ybuffer[i], colormap[pleft.x, pleft.y]) if height_on_screen < ybuffer[i]: ybuffer[i] = height_on_screen pleft.x += dx pleft.y += dy # Go to next line and increase step size when you are far away z += dz dz += 0.2 # Call the render function with the camera parameters: # position, viewing angle, height, horizon line position, # scaling factor for the height, the largest distance, # screen width and the screen height parameter Render( Point(0, 0), 0, 50, 120, 120, 300, 800, 600 ) Links Web Project demo page Voxel terrain engine - an introduction Personal website Maps color, height C1W.png D1.png color, height C2W.png D2.png color, height C3.png D3.png color, height C4.png D4.png color, height C5W.png D5.png color, height C6W.png D6.png color, height C7W.png D7.png color, height C8.png D6.png color, height C9W.png D9.png color, height C10W.png D10.png color, height C11W.png D11.png color, height C12W.png D11.png color, height C13.png D13.png color, height C14.png D14.png color, height C14W.png D14.png color, height C15.png D15.png color, height C16W.png D16.png color, height C17W.png D17.png color, height C18W.png D18.png color, height C19W.png D19.png color, height C20W.png D20.png color, height C21.png D21.png color, height C22W.png D22.png color, height C23W.png D21.png color, height C24W.png D24.png color, height C25W.png D25.png color, height C26W.png D18.png color, height C27W.png D15.png color, height C28W.png D25.png color, height C29W.png D16.png License The software part of the repository is under the MIT license. Please read the license file for more information. Please keep in mind, that the Voxel Space technology might be still patented in some countries. The color and height maps are reverse engineered from the game Comanche and are therefore excluded from the license. About Terrain rendering algorithm in less than 20 lines of code s-macke.github.io/VoxelSpace/VoxelSpace.html Topics voxel rendering-engine voxel-engine 3d-engine rendering-algorithms voxel-space-engine game-comanche comanche Resources Readme License MIT license Activity Stars 6.3k stars Watchers 109 watching Forks 270 forks Report repository Releases No releases published Packages 0 No packages published Contributors 6 * @s-macke * @sirrah23 * @garrettw * @gingerbeardman * @jbn * @ryan-haskell Languages * C 39.2% * HTML 38.1% * Python 21.2% * Shell 1.5% Footer (c) 2025 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact * Manage cookies * Do not share my personal information You can't perform that action at this time.