Skip to content

A ray marcher for heightmap images or any images with a real time freely moving camera.


Notifications You must be signed in to change notification settings


Folders and files

Last commit message
Last commit date

Latest commit



52 Commits

Repository files navigation

Heightmap Ray Marcher

A ray marcher for heightmap images (or any images) with a real time freely moving camera.

Move the camera with WASD and the mouse. Hold space to raise the camera and hold Q to lower it.
Switch the projection mode with the number keys:

  1. Perspective
  2. Spherical
  3. Orthographic


  • Ctrl+Q to exit.
  • Zoom in/out with scroll wheel.
  • Press F1 to toggle showing the frames per second.
  • Press F11 to toggle fullscreen.
  • Press F12 to save a screenshot in screenshots directory.
  • Press backtick (left of 1) to toggle the console for changing configuration at runtime.
  • Parsing the console input is the same as the parsing for the config file.
  • Press Ctrl+Shift+R to begin recording (saving frames out to image files) or to stop recording early (otherwise recording will stop after recording_frame_count number of frames).
  • You can freely resize the window.

For each pixel, a ray is cast and intersection is checked with an axis aligned bounding box (AABB) around the heightmap. If the ray collides with the AABB, then ray marching begins at the collision point.

Feel free to ask a question by opening an issue.

What it can do

These three images were created with the same camera position and direction, but different projection modes.

Man (perspective)

Man (spherical)

Man (orthographic)
Original image

White tiger
Original image

Face (close)
Face (overview)
Original image

Face in leaves (close)
Face in leaves (overview)
Original image

Configuration file

  • The program is launched from the command line with a configuration file argument: ./hmap path/to/config.txt
  • The config file is a sequence of whitespace-separated values.
  • Consider starting each line in the config with an identifier, followed by its appropriate arguments.
  • Options can be specified in any order.
  • All config file options are optional except heightmap and colormap
  • Input to many options is not validated and handling parsing is not robust.
  • Do NOT use file paths that include spaces.

See sample_config.txt for an example.


Identifier Parameter(s) Description
heightmap path/to/img.png A path to an image. The image does NOT have to be greyscale. The luminance of the image's pixels determines the heights. The image can be any format supported by stb_image.h: JPEG, PNG, TGA, BMP, PSD, GIF, HDR, PIC, PNM. See vendor/stb_image.h for details and exceptions. The image must have the same resolution as the image for colormap. This option must be specified.
colormap path/to/img.png Similar to heightmap but for determining colors. The easiest choice will be the same image as for heightmap. The specified image must have the same resolution as the image for heightmap. This option must be specified.
print [No parameters] Print current values of all options.
resolution <int x> <int y> The x and y dimensions (in pixels) of the window content.
hfov <double degrees> Set the horizontal field of view (in degrees). You will likely experience issues if this is not in the range (0, 180).
hang <double degrees> Horizontal angle of camera. 0 is looking in direction of positive x axis. 90 is looking in direction of positive y axis,
vang <double degrees> Vertical angle of camera. 0 is looking straight up (with positive z axis). 90 is looking parallel to xy plane.
pos <double x> <double y> <double z> Set position of camera.
pos_x <double x> Set x coordinate of camera.
pos_y <double y> Set y coordinate of camera.
pos_z <double z> Set z coordinate of camera.
min_height <double z> The minimum world space height in the height map. Values are normalized between the min and max.
max_height <double z> The maximum world space height in the height map.
lum <double r> <double g> <double b> For each pixel in the heightmap image with components RGB, the pixel's heightmap value is (rR + gG + bB), clamped to range [0.0, 255.0], then scaled to range [min_height, max_height]
lum_norm <double r> <double g> <double b> lum but the 3 components are normalized so that they sum to 1.
lum_r <double r> lum but only setting R component.
lum_g <double g> lum but only setting G component.
lum_b <double b> lum but only setting B component.
grid_width <double val> The world space grid square size of the heightmap.
ortho_width <double val> The world space grid spacing of rays when using orthographic projection.
step_dist <double val> How far in world space to step when ray marching.
bg_color <int red> <int green> <int blue> The background color. Values should be in range [0, 255].
cycle <int num> A full image will be rendered across num frames.
mouse_sens <double val> Horizontal and vertical mouse sensitivity for rotating camera.
scroll_sens <double val> Sensitivity when zooming in/out with scroll wheel.
move <double val> Movement speed multiplier.
recording_frame_count <int count> The number of frames to render when recording (saving frames out to image files).

Build and run on Linux

  1. Clone the repo
  2. Install the dependencies e.g. pamac install sdl2 sdl2_ttf glm
  1. make build
  2. Run with ./hmap path/to/config.txt

Building for other platforms will follow a similar approach.


Files original to this repo are under the BSD 2-Clause License. See file LICENSE.txt.

Files under vendor and fonts have their own licenses. See those directories for details.


Not currently accepting contributions. Feel free to create an issue.