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!
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
.
After obtaining the source code (e.g. by cloning from our GitHub repository) you can build the project with cmake
.
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.
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.
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.
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:
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.
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.
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:
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
).
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.
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.
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 mean
and 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:
If you find any problem or wish to contribute, please open an issue or a pull request on our GitHub repository. Thank you!
image-renderer is free software, and it is released under version 3 of the GNU General Public License.
...and many more to come!