Skip to content

image-renderer is a C++ tool to generate photo-realistic images from a scene description input file..

License

Notifications You must be signed in to change notification settings

teozec/image-renderer

Repository files navigation

image-renderer

Operating Systems License Pulls CI Top Language Version Commits Size

image-renderer is a C++ tool to generate photo-realistic images. It is based on the lectures of the Numerical tecniques for photorealistic image generation course (EN, IT), held by Prof. Maurizio Tomasi in 2021. A nice presentation of our work is available here!

Table of contents

Requirements

The following software is required to build the project:

This project also uses the header-only Argh! library, which is already included in this repository in include/argh.h. Therefore, you do not need to install it on your system to compile image-renderer.

Building

After obtaining the source code (e.g. by cloning from our GitHub repository) you can build the project with cmake.

Standard Unix and Windows

Run the following shell commands from the project directory:

mkdir build
cd build
cmake ..
make

The executable files are generated in the build directory.

If you use bash, you can enable autocompletion for the program running

source ../tools/bash-completion.bash

To make it permanent, you can add it to your ~/.bashrc file.

macOS (Xcode)

If you wish to use Xcode on your macOS, you can build the project using:

mkdir build
cd build
cmake -G "Xcode" ..

Now that it is all set you can open up the Xcode project built in the build directory and compile it from within the IDE.

If you use bash, you can enable autocompletion for the program running (from the build directory)

source ../tools/bash-completion.bash

To make it permanent, you can add it to your ~/.bashrc file.

Basic tutorial

A demo image

For a quick test, run the following commands from the build directory:

chmod +x ../examples/demo-image.sh
../examples/demo-image.sh

and enjoy the demo.png file.

demo

The script you have just run contains two of the four actions provided by the program: demo and pfm2ldr. The first one renders an example scene, and allows you to conifgure it a bit. For example,

./image-renderer demo --width=500 --height=500 --antialiasing=9 --angleDeg=30 --nMax=5 --roulette=3

will render a 500x500 example scene sampling 9 rays per pixel, rotating the camera by 30 degrees on the z axis and considering at most 5 collisions per ray, starting with the Russian roulette algorithm at 3 collisions. The antialiasing option is useful to sample each pixel properly, avoiding aliasing. Here an example:

antialiasing

Another example of the demo action is

./image-renderer demo -p orthogonal -R flat -o output.pfm

It will generate the output.pfm image using an orthogonal camera and a flat rendering algorithm. As you can see, you can use both long and short options: for a list of all supported arguments, you can always use the --help flag.

Converting a PFM file to a LDR image with pfm2ldr

The demo action, as well as the render and stack that we will see later, outputs a pfm file. However, we would like to convert it to a LDR image format, such ar png or bmp. This is the purpose of the pfm2ldr action. A quick usage example:

./image-renderer pfm2ldr --gamma=1.4 demo.pfm

will convert demo.pfm to the demo.png image, using a correction gamma factor of 1.4. Of course, you can use a different format if you want: supported formats are bmp, gif, jpeg, png, tiff, webp.

./image-renderer pfm2ldr --format=webp --outfile=output.webp --luminosity=2.0 --quality=50 input.pfm

The previous command will convert input.pfm to the output.webp image, with a total luminosity of 2.0 and a webp compression quality of 50. In particular, the compression quality is a format-dependent argument (different image formats can be configured differently, so make sure to run ./image-renderer pfm2ldr --help to get all the details). The luminosity instead is a tricky parameter: it is what the program should consider as the total brightness of the scene. This means that if a higher value is passed, single pixels will be less bright with respect to the total luminosity, making the scene darker! In general, you should let the renderer calculate and use the real total luminosity; however, in some cases the results may not be optimal and this parameter might be needed.

rendering custom scenes

We have seen how to render a demo image. However, that can soon get boring: this is why we have also provided a render action. To see it at work, you can use

chmod +x ../examples/cornell.sh
../examples/cornell.sh

If you have GNU Parallel installed, you can also use the faster ../examples/cornell-parallel.sh. Depending on your PC, this script may take some hours, but the result is worth the wait:

cornell

The first command in the script makes use of the render action, which is used to parse a file describing a scene (aka scenefile) and generate a corresponding pfm file. Many arguments are in common with the demo action (except for those about the camera, which is now described in the scenefile). Here is an example:

./image-renderer render ../examples/scene.txt --float="red:0.3"

renders the scene described in ../examples/scene.txt assigning a custom value to the red variable that appears in the file. The --float option is very useful to render custom animations: if you have FFmpeg installed, you can try it with ../examples/animation.sh (or ../examples/animation-parallel.sh).

animation

If you wish to learn how to make your own scenefiles, scene.txt contains a basic tutorial. Don't forget to :source ../tools/scenefile.vim for syntax highlighting, if you use vim.

Image stacking

Finally, you'd have surely noticed that there is another action in the cornell.sh script: stack. It is used to stack many noisy images to get a better looking one by increasing the signal to noise ratio.

stack

For example, if you want to stack 10 images saved as image00.pfm, image01.pfm and so on, you can simply run:

image-renderer stack image*.pfm

This way you will get a stack.pfm image in current directory. You can choose between meanand median stacking, and also apply sigma-clipping providing a alpha factor: for more info please run image-renderer stack --help. This action is very powerful: as a matter of fact it is not only used to get a better signal to noise ratio, but also for rendering blurry images. Here an example:

blurry

Contributing

If you find any problem or wish to contribute, please open an issue or a pull request on our GitHub repository. Thank you!

License

image-renderer is free software, and it is released under version 3 of the GNU General Public License.

Acknowledgements

...and many more to come!