Blender  V2.93
svm_sky.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 /* Sky texture */
20 
21 ccl_device float sky_angle_between(float thetav, float phiv, float theta, float phi)
22 {
23  float cospsi = sinf(thetav) * sinf(theta) * cosf(phi - phiv) + cosf(thetav) * cosf(theta);
24  return safe_acosf(cospsi);
25 }
26 
27 /*
28  * "A Practical Analytic Model for Daylight"
29  * A. J. Preetham, Peter Shirley, Brian Smits
30  */
31 ccl_device float sky_perez_function(float *lam, float theta, float gamma)
32 {
33  float ctheta = cosf(theta);
34  float cgamma = cosf(gamma);
35 
36  return (1.0f + lam[0] * expf(lam[1] / ctheta)) *
37  (1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cgamma * cgamma);
38 }
39 
41  float3 dir,
42  float sunphi,
43  float suntheta,
44  float radiance_x,
45  float radiance_y,
46  float radiance_z,
47  float *config_x,
48  float *config_y,
49  float *config_z)
50 {
51  /* convert vector to spherical coordinates */
52  float2 spherical = direction_to_spherical(dir);
53  float theta = spherical.x;
54  float phi = spherical.y;
55 
56  /* angle between sun direction and dir */
57  float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
58 
59  /* clamp theta to horizon */
60  theta = min(theta, M_PI_2_F - 0.001f);
61 
62  /* compute xyY color space values */
63  float x = radiance_y * sky_perez_function(config_y, theta, gamma);
64  float y = radiance_z * sky_perez_function(config_z, theta, gamma);
65  float Y = radiance_x * sky_perez_function(config_x, theta, gamma);
66 
67  /* convert to RGB */
68  float3 xyz = xyY_to_xyz(x, y, Y);
69  return xyz_to_rgb(kg, xyz);
70 }
71 
72 /*
73  * "An Analytic Model for Full Spectral Sky-Dome Radiance"
74  * Lukas Hosek, Alexander Wilkie
75  */
76 ccl_device float sky_radiance_internal(float *configuration, float theta, float gamma)
77 {
78  float ctheta = cosf(theta);
79  float cgamma = cosf(gamma);
80 
81  float expM = expf(configuration[4] * gamma);
82  float rayM = cgamma * cgamma;
83  float mieM = (1.0f + rayM) / powf((1.0f + configuration[8] * configuration[8] -
84  2.0f * configuration[8] * cgamma),
85  1.5f);
86  float zenith = sqrtf(ctheta);
87 
88  return (1.0f + configuration[0] * expf(configuration[1] / (ctheta + 0.01f))) *
89  (configuration[2] + configuration[3] * expM + configuration[5] * rayM +
90  configuration[6] * mieM + configuration[7] * zenith);
91 }
92 
94  float3 dir,
95  float sunphi,
96  float suntheta,
97  float radiance_x,
98  float radiance_y,
99  float radiance_z,
100  float *config_x,
101  float *config_y,
102  float *config_z)
103 {
104  /* convert vector to spherical coordinates */
105  float2 spherical = direction_to_spherical(dir);
106  float theta = spherical.x;
107  float phi = spherical.y;
108 
109  /* angle between sun direction and dir */
110  float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
111 
112  /* clamp theta to horizon */
113  theta = min(theta, M_PI_2_F - 0.001f);
114 
115  /* compute xyz color space values */
116  float x = sky_radiance_internal(config_x, theta, gamma) * radiance_x;
117  float y = sky_radiance_internal(config_y, theta, gamma) * radiance_y;
118  float z = sky_radiance_internal(config_z, theta, gamma) * radiance_z;
119 
120  /* convert to RGB and adjust strength */
121  return xyz_to_rgb(kg, make_float3(x, y, z)) * (M_2PI_F / 683);
122 }
123 
124 /* Nishita improved sky model */
126 {
127  return make_float3(cos(lat) * cos(lon), cos(lat) * sin(lon), sin(lat));
128 }
129 
131  float3 dir,
132  float *nishita_data,
133  uint texture_id)
134 {
135  /* definitions */
136  float sun_elevation = nishita_data[6];
137  float sun_rotation = nishita_data[7];
138  float angular_diameter = nishita_data[8];
139  float sun_intensity = nishita_data[9];
140  bool sun_disc = (angular_diameter >= 0.0f);
141  float3 xyz;
142  /* convert dir to spherical coordinates */
143  float2 direction = direction_to_spherical(dir);
144 
145  /* render above the horizon */
146  if (dir.z >= 0.0f) {
147  /* definitions */
148  float3 sun_dir = geographical_to_direction(sun_elevation, sun_rotation + M_PI_2_F);
149  float sun_dir_angle = precise_angle(dir, sun_dir);
150  float half_angular = angular_diameter / 2.0f;
151  float dir_elevation = M_PI_2_F - direction.x;
152 
153  /* if ray inside sun disc render it, otherwise render sky */
154  if (sun_disc && sun_dir_angle < half_angular) {
155  /* get 2 pixels data */
156  float3 pixel_bottom = make_float3(nishita_data[0], nishita_data[1], nishita_data[2]);
157  float3 pixel_top = make_float3(nishita_data[3], nishita_data[4], nishita_data[5]);
158  float y;
159 
160  /* sun interpolation */
161  if (sun_elevation - half_angular > 0.0f) {
162  if (sun_elevation + half_angular > 0.0f) {
163  y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5f;
164  xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
165  }
166  }
167  else {
168  if (sun_elevation + half_angular > 0.0f) {
169  y = dir_elevation / (sun_elevation + half_angular);
170  xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
171  }
172  }
173  /* limb darkening, coefficient is 0.6f */
174  float limb_darkening = (1.0f -
175  0.6f * (1.0f - sqrtf(1.0f - sqr(sun_dir_angle / half_angular))));
176  xyz *= limb_darkening;
177  }
178  /* sky */
179  else {
180  /* sky interpolation */
181  float x = (direction.y + M_PI_F + sun_rotation) / M_2PI_F;
182  /* more pixels toward horizon compensation */
183  float y = safe_sqrtf(dir_elevation / M_PI_2_F);
184  if (x > 1.0f) {
185  x -= 1.0f;
186  }
187  xyz = float4_to_float3(kernel_tex_image_interp(kg, texture_id, x, y));
188  }
189  }
190  /* ground */
191  else {
192  if (dir.z < -0.4f) {
193  xyz = make_float3(0.0f, 0.0f, 0.0f);
194  }
195  else {
196  /* black ground fade */
197  float fade = 1.0f + dir.z * 2.5f;
198  fade = sqr(fade) * fade;
199  /* interpolation */
200  float x = (direction.y + M_PI_F + sun_rotation) / M_2PI_F;
201  if (x > 1.0f) {
202  x -= 1.0f;
203  }
204  xyz = float4_to_float3(kernel_tex_image_interp(kg, texture_id, x, -0.5)) * fade;
205  }
206  }
207 
208  /* convert to RGB */
209  return xyz_to_rgb(kg, xyz);
210 }
211 
213  KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
214 {
215  /* Load data */
216  uint dir_offset = node.y;
217  uint out_offset = node.z;
218  int sky_model = node.w;
219 
220  float3 dir = stack_load_float3(stack, dir_offset);
221  float3 f;
222 
223  /* Preetham and Hosek share the same data */
224  if (sky_model == 0 || sky_model == 1) {
225  /* Define variables */
226  float sunphi, suntheta, radiance_x, radiance_y, radiance_z;
227  float config_x[9], config_y[9], config_z[9];
228 
229  float4 data = read_node_float(kg, offset);
230  sunphi = data.x;
231  suntheta = data.y;
232  radiance_x = data.z;
233  radiance_y = data.w;
234 
235  data = read_node_float(kg, offset);
236  radiance_z = data.x;
237  config_x[0] = data.y;
238  config_x[1] = data.z;
239  config_x[2] = data.w;
240 
241  data = read_node_float(kg, offset);
242  config_x[3] = data.x;
243  config_x[4] = data.y;
244  config_x[5] = data.z;
245  config_x[6] = data.w;
246 
247  data = read_node_float(kg, offset);
248  config_x[7] = data.x;
249  config_x[8] = data.y;
250  config_y[0] = data.z;
251  config_y[1] = data.w;
252 
253  data = read_node_float(kg, offset);
254  config_y[2] = data.x;
255  config_y[3] = data.y;
256  config_y[4] = data.z;
257  config_y[5] = data.w;
258 
259  data = read_node_float(kg, offset);
260  config_y[6] = data.x;
261  config_y[7] = data.y;
262  config_y[8] = data.z;
263  config_z[0] = data.w;
264 
265  data = read_node_float(kg, offset);
266  config_z[1] = data.x;
267  config_z[2] = data.y;
268  config_z[3] = data.z;
269  config_z[4] = data.w;
270 
271  data = read_node_float(kg, offset);
272  config_z[5] = data.x;
273  config_z[6] = data.y;
274  config_z[7] = data.z;
275  config_z[8] = data.w;
276 
277  /* Compute Sky */
278  if (sky_model == 0) {
280  dir,
281  sunphi,
282  suntheta,
283  radiance_x,
284  radiance_y,
285  radiance_z,
286  config_x,
287  config_y,
288  config_z);
289  }
290  else {
292  dir,
293  sunphi,
294  suntheta,
295  radiance_x,
296  radiance_y,
297  radiance_z,
298  config_x,
299  config_y,
300  config_z);
301  }
302  }
303  /* Nishita */
304  else {
305  /* Define variables */
306  float nishita_data[10];
307 
308  float4 data = read_node_float(kg, offset);
309  nishita_data[0] = data.x;
310  nishita_data[1] = data.y;
311  nishita_data[2] = data.z;
312  nishita_data[3] = data.w;
313 
314  data = read_node_float(kg, offset);
315  nishita_data[4] = data.x;
316  nishita_data[5] = data.y;
317  nishita_data[6] = data.z;
318  nishita_data[7] = data.w;
319 
320  data = read_node_float(kg, offset);
321  nishita_data[8] = data.x;
322  nishita_data[9] = data.y;
323  uint texture_id = __float_as_uint(data.z);
324 
325  /* Compute Sky */
326  f = sky_radiance_nishita(kg, dir, nishita_data, texture_id);
327  }
328 
329  stack_store_float3(stack, out_offset, f);
330 }
331 
MINLINE float safe_sqrtf(float a)
MINLINE float safe_acosf(float a)
unsigned int uint
Definition: BLI_sys_types.h:83
_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 const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_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 y
#define Y
Definition: GeomUtils.cpp:214
OperationNode * node
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(float *stack, uint a)
ccl_device_inline float4 read_node_float(KernelGlobals *kg, int *offset)
ccl_device_inline void stack_store_float3(float *stack, uint a, float3 f)
CCL_NAMESPACE_BEGIN ccl_device float3 xyz_to_rgb(KernelGlobals *kg, float3 xyz)
Definition: kernel_color.h:24
#define sinf(x)
#define cosf(x)
#define ccl_device
#define expf(x)
#define powf(x, y)
#define CCL_NAMESPACE_END
#define sqrtf(x)
#define make_float3(x, y, z)
CCL_NAMESPACE_BEGIN ccl_device float2 direction_to_spherical(float3 dir)
ShaderData
ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
color xyY_to_xyz(float x, float y, float Y)
Definition: node_color.h:59
#define min(a, b)
Definition: sort.c:51
float z
Definition: sky_float3.h:35
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
Definition: svm_noise.h:37
ccl_device void svm_node_tex_sky(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
Definition: svm_sky.h:212
ccl_device float3 geographical_to_direction(float lat, float lon)
Definition: svm_sky.h:125
CCL_NAMESPACE_BEGIN ccl_device float sky_angle_between(float thetav, float phiv, float theta, float phi)
Definition: svm_sky.h:21
ccl_device float sky_perez_function(float *lam, float theta, float gamma)
Definition: svm_sky.h:31
ccl_device float3 sky_radiance_nishita(KernelGlobals *kg, float3 dir, float *nishita_data, uint texture_id)
Definition: svm_sky.h:130
ccl_device float3 sky_radiance_hosek(KernelGlobals *kg, float3 dir, float sunphi, float suntheta, float radiance_x, float radiance_y, float radiance_z, float *config_x, float *config_y, float *config_z)
Definition: svm_sky.h:93
ccl_device float3 sky_radiance_preetham(KernelGlobals *kg, float3 dir, float sunphi, float suntheta, float radiance_x, float radiance_y, float radiance_z, float *config_x, float *config_y, float *config_z)
Definition: svm_sky.h:40
ccl_device float sky_radiance_internal(float *configuration, float theta, float gamma)
Definition: svm_sky.h:76
ccl_device_inline uint __float_as_uint(float f)
Definition: util_math.h:222
#define M_PI_2_F
Definition: util_math.h:46
ccl_device_inline float sqr(float a)
Definition: util_math.h:651
#define M_2PI_F
Definition: util_math.h:69
ccl_device_inline float precise_angle(float3 a, float3 b)
Definition: util_math.h:795
#define M_PI_F
Definition: util_math.h:43
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util_math.h:415
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)