Blender  V2.93
sky_model.h
Go to the documentation of this file.
1 /*
2 This source is published under the following 3-clause BSD license.
3 
4 Copyright (c) 2012 - 2013, Lukas Hosek and Alexander Wilkie
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10  * Redistributions of source code must retain the above copyright
11  notice, this list of conditions and the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15  * None of the names of the contributors may be used to endorse or promote
16  products derived from this software without specific prior written
17  permission.
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 /* ============================================================================
32 
33 This file is part of a sample implementation of the analytical skylight and
34 solar radiance models presented in the SIGGRAPH 2012 paper
35 
36 
37  "An Analytic Model for Full Spectral Sky-Dome Radiance"
38 
39 and the 2013 IEEE CG&A paper
40 
41  "Adding a Solar Radiance Function to the Hosek Skylight Model"
42 
43  both by
44 
45  Lukas Hosek and Alexander Wilkie
46  Charles University in Prague, Czech Republic
47 
48 
49  Version: 1.4a, February 22nd, 2013
50 
51 Version history:
52 
53 1.4a February 22nd, 2013
54  Removed unnecessary and counter-intuitive solar radius parameters
55  from the interface of the colourspace sky dome initialisation functions.
56 
57 1.4 February 11th, 2013
58  Fixed a bug which caused the relative brightness of the solar disc
59  and the sky dome to be off by a factor of about 6. The sun was too
60  bright: this affected both normal and alien sun scenarios. The
61  coefficients of the solar radiance function were changed to fix this.
62 
63 1.3 January 21st, 2013 (not released to the public)
64  Added support for solar discs that are not exactly the same size as
65  the terrestrial sun. Also added support for suns with a different
66  emission spectrum ("Alien World" functionality).
67 
68 1.2a December 18th, 2012
69  Fixed a mistake and some inaccuracies in the solar radiance function
70  explanations found in ArHosekSkyModel.h. The actual source code is
71  unchanged compared to version 1.2.
72 
73 1.2 December 17th, 2012
74  Native RGB data and a solar radiance function that matches the turbidity
75  conditions were added.
76 
77 1.1 September 2012
78  The coefficients of the spectral model are now scaled so that the output
79  is given in physical units: W / (m^-2 * sr * nm). Also, the output of the
80  XYZ model is now no longer scaled to the range [0...1]. Instead, it is
81  the result of a simple conversion from spectral data via the CIE 2 degree
82  standard observer matching functions. Therefore, after multiplication
83  with 683 lm / W, the Y channel now corresponds to luminance in lm.
84 
85 1.0 May 11th, 2012
86  Initial release.
87 
88 
89 Please visit http://cgg.mff.cuni.cz/projects/SkylightModelling/ to check if
90 an updated version of this code has been published!
91 
92 ============================================================================ */
93 
94 /*
95 
96 This code is taken from ART, a rendering research system written in a
97 mix of C99 / Objective C. Since ART is not a small system and is intended to
98 be inter-operable with other libraries, and since C does not have namespaces,
99 the structures and functions in ART all have to have somewhat wordy
100 canonical names that begin with Ar.../ar..., like those seen in this example.
101 
102 Usage information:
103 ==================
104 
105 
106 Model initialisation
107 --------------------
108 
109 A separate ArHosekSkyModelState has to be maintained for each spectral
110 band you want to use the model for. So in a renderer with 'num_channels'
111 bands, you would need something like
112 
113  ArHosekSkyModelState * skymodel_state[num_channels];
114 
115 You then have to allocate and initialize these states. In the following code
116 snippet, we assume that 'albedo' is defined as
117 
118  double albedo[num_channels];
119 
120 with a ground albedo value between [0,1] for each channel. The solar elevation
121 is given in radians.
122 
123  for ( unsigned int i = 0; i < num_channels; i++ )
124  skymodel_state[i] =
125  arhosekskymodelstate_alloc_init(
126  turbidity,
127  albedo[i],
128  solarElevation
129  );
130 
131 Note that starting with version 1.3, there is also a second initialisation
132 function which generates skydome states for different solar emission spectra
133 and solar radii: 'arhosekskymodelstate_alienworld_alloc_init()'.
134 
135 See the notes about the "Alien World" functionality provided further down for a
136 discussion of the usefulness and limits of that second initalisation function.
137 Sky model states that have been initialized with either function behave in a
138 completely identical fashion during use and cleanup.
139 
140 Using the model to generate skydome samples
141 -------------------------------------------
142 
143 Generating a skydome radiance spectrum "skydome_result" for a given location
144 on the skydome determined via the angles theta and gamma works as follows:
145 
146  double skydome_result[num_channels];
147 
148  for ( unsigned int i = 0; i < num_channels; i++ )
149  skydome_result[i] =
150  arhosekskymodel_radiance(
151  skymodel_state[i],
152  theta,
153  gamma,
154  channel_center[i]
155  );
156 
157 The variable "channel_center" is assumed to hold the channel center wavelengths
158 for each of the num_channels samples of the spectrum we are building.
159 
160 
161 Cleanup after use
162 -----------------
163 
164 After rendering is complete, the content of the sky model states should be
165 disposed of via
166 
167  for ( unsigned int i = 0; i < num_channels; i++ )
168  arhosekskymodelstate_free( skymodel_state[i] );
169 
170 
171 CIE XYZ Version of the Model
172 ----------------------------
173 
174 Usage of the CIE XYZ version of the model is exactly the same, except that
175 num_channels is of course always 3, and that ArHosekTristimSkyModelState and
176 arhosek_tristim_skymodel_radiance() have to be used instead of their spectral
177 counterparts.
178 
179 RGB Version of the Model
180 ------------------------
181 
182 The RGB version uses sRGB primaries with a linear gamma ramp. The same set of
183 functions as with the XYZ data is used, except the model is initialized
184 by calling arhosek_rgb_skymodelstate_alloc_init.
185 
186 Solar Radiance Function
187 -----------------------
188 
189 For each position on the solar disc, this function returns the entire radiance
190 one sees - direct emission, as well as in-scattered light in the area of the
191 solar disc. The latter is important for low solar elevations - nice images of
192 the setting sun would not be possible without this. This is also the reason why
193 this function, just like the regular sky dome model evaluation function, needs
194 access to the sky dome data structures, as these provide information on
195 in-scattered radiance.
196 
197 CAVEAT #1: in this release, this function is only provided in spectral form!
198  RGB/XYZ versions to follow at a later date.
199 
200 CAVEAT #2: (fixed from release 1.3 onwards)
201 
202 CAVEAT #3: limb darkening renders the brightness of the solar disc
203  inhomogeneous even for high solar elevations - only taking a single
204  sample at the centre of the sun will yield an incorrect power
205  estimate for the solar disc! Always take multiple random samples
206  across the entire solar disc to estimate its power!
207 
208 CAVEAT #4: in this version, the limb darkening calculations still use a fairly
209  computationally expensive 5th order polynomial that was directly
210  taken from astronomical literature. For the purposes of Computer
211  Graphics, this is needlessly accurate, though, and will be replaced
212  by a cheaper approximation in a future release.
213 
214 "Alien World" functionality
215 ---------------------------
216 
217 The Hosek sky model can be used to roughly (!) predict the appearance of
218 outdoor scenes on earth-like planets, i.e. planets of a similar size and
219 atmospheric make-up. Since the spectral version of our model predicts sky dome
220 luminance patterns and solar radiance independently for each waveband, and
221 since the intensity of each waveband is solely dependent on the input radiance
222 from the star that the world in question is orbiting, it is trivial to re-scale
223 the wavebands to match a different star radiance.
224 
225 At least in theory, the spectral version of the model has always been capable
226 of this sort of thing, and the actual sky dome and solar radiance models were
227 actually not altered at all in this release. All we did was to add some support
228 functionality for doing this more easily with the existing data and functions,
229 and to add some explanations.
230 
231 Just use 'arhosekskymodelstate_alienworld_alloc_init()' to initialize the sky
232 model states (you will have to provide values for star temperature and solar
233 intensity compared to the terrestrial sun), and do everything else as you
234 did before.
235 
236 CAVEAT #1: we assume the emission of the star that illuminates the alien world
237  to be a perfect blackbody emission spectrum. This is never entirely
238  realistic - real star emission spectra are considerably more complex
239  than this, mainly due to absorption effects in the outer layers of
240  stars. However, blackbody spectra are a reasonable first assumption
241  in a usage scenario like this, where 100% accuracy is simply not
242  necessary: for rendering purposes, there are likely no visible
243  differences between a highly accurate solution based on a more
244  involved simulation, and this approximation.
245 
246 CAVEAT #2: we always use limb darkening data from our own sun to provide this
247  "appearance feature", even for suns of strongly different
248  temperature. Which is presumably not very realistic, but (as with
249  the unaltered blackbody spectrum from caveat #1) probably not a bad
250  first guess, either. If you need more accuracy than we provide here,
251  please make inquiries with a friendly astro-physicst of your choice.
252 
253 CAVEAT #3: you have to provide a value for the solar intensity of the star
254  which illuminates the alien world. For this, please bear in mind
255  that there is very likely a comparatively tight range of absolute
256  solar irradiance values for which an earth-like planet with an
257  atmosphere like the one we assume in our model can exist in the
258  first place!
259 
260  Too much irradiance, and the atmosphere probably boils off into
261  space, too little, it freezes. Which means that stars of
262  considerably different emission colour than our sun will have to be
263  fairly different in size from it, to still provide a reasonable and
264  inhabitable amount of irradiance. Red stars will need to be much
265  larger than our sun, while white or blue stars will have to be
266  comparatively tiny. The initialisation function handles this and
267  computes a plausible solar radius for a given emission spectrum. In
268  terms of absolute radiometric values, you should probably not stray
269  all too far from a solar intensity value of 1.0.
270 
271 CAVEAT #4: although we now support different solar radii for the actual solar
272  disc, the sky dome luminance patterns are *not* parameterised by
273  this value - i.e. the patterns stay exactly the same for different
274  solar radii! Which is of course not correct. But in our experience,
275  solar discs up to several degrees in diameter (! - our own sun is
276  half a degree across) do not cause the luminance patterns on the sky
277  to change perceptibly. The reason we know this is that we initially
278  used unrealistically large suns in our brute force path tracer, in
279  order to improve convergence speeds (which in the beginning were
280  abysmal). Later, we managed to do the reference renderings much
281  faster even with realistically small suns, and found that there was
282  no real difference in skydome appearance anyway.
283  Conclusion: changing the solar radius should not be over-done, so
284  close orbits around red supergiants are a no-no. But for the
285  purposes of getting a fairly credible first impression of what an
286  alien world with a reasonably sized sun would look like, what we are
287  doing here is probably still o.k.
288 
289 HINT #1: if you want to model the sky of an earth-like planet that orbits
290  a binary star, just super-impose two of these models with solar
291  intensity of ~0.5 each, and closely spaced solar positions. Light is
292  additive, after all. Tattooine, here we come... :-)
293 
294  P.S. according to Star Wars canon, Tattooine orbits a binary
295  that is made up of a G and K class star, respectively.
296  So ~5500K and ~4200K should be good first guesses for their
297  temperature. Just in case you were wondering, after reading the
298  previous paragraph.
299 */
300 
301 #ifndef __SKY_MODEL_H__
302 #define __SKY_MODEL_H__
303 
304 #ifdef __cplusplus
305 extern "C" {
306 #endif
307 
309 
310 // Spectral version of the model
311 
312 /* ----------------------------------------------------------------------------
313 
314  ArHosekSkyModelState struct
315  ---------------------------
316 
317  This struct holds the pre-computation data for one particular albedo value.
318  Most fields are self-explanatory, but users should never directly
319  manipulate any of them anyway. The only consistent way to manipulate such
320  structs is via the functions 'arhosekskymodelstate_alloc_init' and
321  'arhosekskymodelstate_free'.
322 
323  'emission_correction_factor_sky'
324  'emission_correction_factor_sun'
325 
326  The original model coefficients were fitted against the emission of
327  our local sun. If a different solar emission is desired (i.e. if the
328  model is being used to predict skydome appearance for an earth-like
329  planet that orbits a different star), these correction factors, which
330  are determined during the alloc_init step, are applied to each waveband
331  separately (they default to 1.0 in normal usage). This is the simplest
332  way to retrofit this sort of capability to the existing model. The
333  different factors for sky and sun are needed since the solar disc may
334  be of a different size compared to the terrestrial sun.
335 
336 ---------------------------------------------------------------------------- */
337 
338 typedef struct SKY_ArHosekSkyModelState {
340  double radiances[11];
341  double turbidity;
342  double solar_radius;
345  double albedo;
346  double elevation;
348 
349 /* ----------------------------------------------------------------------------
350 
351  arhosekskymodelstate_alloc_init() function
352  ------------------------------------------
353 
354  Initializes an #ArHosekSkyModelState struct for a terrestrial setting.
355 
356 ---------------------------------------------------------------------------- */
357 
359  const double atmospheric_turbidity,
360  const double ground_albedo);
361 
362 /* ----------------------------------------------------------------------------
363 
364  arhosekskymodelstate_alienworld_alloc_init() function
365  -----------------------------------------------------
366 
367  Initializes an ArHosekSkyModelState struct for an "alien world" setting
368  with a sun of a surface temperature given in 'kelvin'. The parameter
369  'solar_intensity' controls the overall brightness of the sky, relative
370  to the solar irradiance on Earth. A value of 1.0 yields a sky dome that
371  is, on average over the wavelenghts covered in the model (!), as bright
372  as the terrestrial sky in radiometric terms.
373 
374  Which means that the solar radius has to be adjusted, since the
375  emissivity of a solar surface with a given temperature is more or less
376  fixed. So hotter suns have to be smaller to be equally bright as the
377  terrestrial sun, while cooler suns have to be larger. Note that there are
378  limits to the validity of the luminance patterns of the underlying model:
379  see the discussion above for more on this. In particular, an alien sun with
380  a surface temperature of only 2000 Kelvin has to be very large if it is
381  to be as bright as the terrestrial sun - so large that the luminance
382  patterns are no longer a really good fit in that case.
383 
384  If you need information about the solar radius that the model computes
385  for a given temperature (say, for light source sampling purposes), you
386  have to query the 'solar_radius' variable of the sky model state returned
387  *after* running this function.
388 
389 ---------------------------------------------------------------------------- */
390 
392  const double solar_elevation,
393  const double solar_intensity,
394  const double solar_surface_temperature_kelvin,
395  const double atmospheric_turbidity,
396  const double ground_albedo);
397 
399 
401  double theta,
402  double gamma,
403  double wavelength);
404 
405 // CIE XYZ and RGB versions
406 
408  const double albedo,
409  const double elevation);
410 
412  const double albedo,
413  const double elevation);
414 
416  double theta,
417  double gamma,
418  int channel);
419 
420 // Delivers the complete function: sky + sun, including limb darkening.
421 // Please read the above description before using this - there are several
422 // caveats!
423 
425  double theta,
426  double gamma,
427  double wavelength);
428 
429 /* Nishita improved sky model */
430 
431 void SKY_nishita_skymodel_precompute_texture(float *pixels,
432  int stride,
433  int start_y,
434  int end_y,
435  int width,
436  int height,
437  float sun_elevation,
438  float altitude,
439  float air_density,
440  float dust_density,
441  float ozone_density);
442 
443 void SKY_nishita_skymodel_precompute_sun(float sun_elevation,
444  float angular_diameter,
445  float altitude,
446  float air_density,
447  float dust_density,
448  float *r_pixel_bottom,
449  float *r_pixel_top);
450 
451 #ifdef __cplusplus
452 }
453 #endif
454 
455 #endif // __SKY_MODEL_H__
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
static ulong state[N]
SKY_ArHosekSkyModelState * SKY_arhosekskymodelstate_alienworld_alloc_init(const double solar_elevation, const double solar_intensity, const double solar_surface_temperature_kelvin, const double atmospheric_turbidity, const double ground_albedo)
void SKY_arhosekskymodelstate_free(SKY_ArHosekSkyModelState *state)
Definition: sky_model.cpp:290
double SKY_arhosekskymodel_solar_radiance(SKY_ArHosekSkyModelState *state, double theta, double gamma, double wavelength)
void SKY_nishita_skymodel_precompute_sun(float sun_elevation, float angular_diameter, float altitude, float air_density, float dust_density, float *r_pixel_bottom, float *r_pixel_top)
struct SKY_ArHosekSkyModelState SKY_ArHosekSkyModelState
double SKY_arhosek_tristim_skymodel_radiance(SKY_ArHosekSkyModelState *state, double theta, double gamma, int channel)
double SKY_arhosekskymodel_radiance(SKY_ArHosekSkyModelState *state, double theta, double gamma, double wavelength)
Definition: sky_model.cpp:295
double SKY_ArHosekSkyModelConfiguration[9]
Definition: sky_model.h:308
SKY_ArHosekSkyModelState * SKY_arhosekskymodelstate_alloc_init(const double solar_elevation, const double atmospheric_turbidity, const double ground_albedo)
SKY_ArHosekSkyModelState * SKY_arhosek_rgb_skymodelstate_alloc_init(const double turbidity, const double albedo, const double elevation)
void SKY_nishita_skymodel_precompute_texture(float *pixels, int stride, int start_y, int end_y, int width, int height, float sun_elevation, float altitude, float air_density, float dust_density, float ozone_density)
SKY_ArHosekSkyModelState * SKY_arhosek_xyz_skymodelstate_alloc_init(const double turbidity, const double albedo, const double elevation)
Definition: sky_model.cpp:328
double emission_correction_factor_sky[11]
Definition: sky_model.h:343
SKY_ArHosekSkyModelConfiguration configs[11]
Definition: sky_model.h:339
double emission_correction_factor_sun[11]
Definition: sky_model.h:344