This document presents a new implementation of our Precomputed Atmospheric Scattering paper. This new implementation is motivated by the fact that the original implementation:
The sections below explain how this new implementation can be used, present its structure and its documentation and give more details about its tests.
Our new
implementation can be used in C++ / OpenGL applications as explained
in model.h, and as demonstrated in the
demo in atmosphere/demo
. To run this demo, simply type make
demo
in the main directory. A WebGL2 version of this demo is also
available online.
The default settings of this demo use the real solar spectrum, with an ozone layer. To simulate the settings of the original implementation, set the solar spectrum to "constant", and turn off the ozone layer.
The source code is organized as follows:
The most important files are the 5 files in the atmosphere
directory. They contain the GLSL shaders that implement our atmosphere model,
and provide a C++ API to precompute the atmosphere textures and to use them in
an OpenGL application. This code does not depend on the content of the other
directories, and is the only piece which is needed in order to use our
atmosphere model on GPU.
The other directories provide examples and tests:
atmosphere/demo
directory shows how the API provided in
atmosphere
can be used in practice, using a small C++/OpenGL
demo application. A WebGL2 version of this demo is also available, in the
webgl
subdirectory.
atmosphere/reference
directory provides a way to execute
our GLSL code on CPU. Its main purpose is to provide unit tests for the GLSL
shaders, and to statically check the dimensional homogeneity of all the expressions. This process is
explained in more details in the Tests section.
This code is also used to compute reference images on CPU using full
spectral rendering, in order to evaluate the accuracy of the approximate
"radiance to RGB luminance" conversion performed by the GPU shaders. It
depends on external libraries such as dimensional_types
(to check the dimensional homogeneity) and
minpng.
The documentation consists of a set of web pages, generated from the
extensive comments in each source code file:
To reduce the risk of implementation errors, two kinds of verifications are performed:
The main issue to implement this is that a GLSL compiler cannot check the dimensional homogeneity, unlike a C++ compiler (see for instance Boost.Units). Our solution to this problem is to write our GLSL code in such a way that it can be compiled both by a GLSL compiler and by a C++ compiler. For this:
OUT(x)
as out x
in GLSL,
and as x&
in C++, and declare output variables as
OUT(SomeType) someName
in our shaders.
float
,
gl_FragCoord
only in the main
functions, which we reduce to the minimum
(e.g. main() { gl_FragColor = Main(gl_FragCoord); }
) and
exclude from the C++ compilation.
Thanks to this double GLSL and C++ compilation, the unit tests for the GLSL code can then be implemented either in GLSL or in C++. We chose C++ because it is much more practical. Indeed, a C++ unit test does not need to send data to the GPU and to read back the test result, unlike a GLSL unit test.