1 /*************************************************************************/
2 /* sky.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #include "sky.h"
32
33 #include "core/io/image_loader.h"
34
set_radiance_size(RadianceSize p_size)35 void Sky::set_radiance_size(RadianceSize p_size) {
36 ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX);
37
38 radiance_size = p_size;
39 _radiance_changed();
40 }
41
get_radiance_size() const42 Sky::RadianceSize Sky::get_radiance_size() const {
43
44 return radiance_size;
45 }
46
_bind_methods()47 void Sky::_bind_methods() {
48
49 ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
50 ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
51
52 ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
53
54 BIND_ENUM_CONSTANT(RADIANCE_SIZE_32);
55 BIND_ENUM_CONSTANT(RADIANCE_SIZE_64);
56 BIND_ENUM_CONSTANT(RADIANCE_SIZE_128);
57 BIND_ENUM_CONSTANT(RADIANCE_SIZE_256);
58 BIND_ENUM_CONSTANT(RADIANCE_SIZE_512);
59 BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024);
60 BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048);
61 BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX);
62 }
63
Sky()64 Sky::Sky() {
65 radiance_size = RADIANCE_SIZE_128;
66 }
67
68 /////////////////////////////////////////
69
_radiance_changed()70 void PanoramaSky::_radiance_changed() {
71
72 if (panorama.is_valid()) {
73 static const int size[RADIANCE_SIZE_MAX] = {
74 32, 64, 128, 256, 512, 1024, 2048
75 };
76 VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]);
77 }
78 }
79
set_panorama(const Ref<Texture> & p_panorama)80 void PanoramaSky::set_panorama(const Ref<Texture> &p_panorama) {
81
82 panorama = p_panorama;
83
84 if (panorama.is_valid()) {
85
86 _radiance_changed();
87
88 } else {
89 VS::get_singleton()->sky_set_texture(sky, RID(), 0);
90 }
91 }
92
get_panorama() const93 Ref<Texture> PanoramaSky::get_panorama() const {
94
95 return panorama;
96 }
97
get_rid() const98 RID PanoramaSky::get_rid() const {
99
100 return sky;
101 }
102
_bind_methods()103 void PanoramaSky::_bind_methods() {
104
105 ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama);
106 ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSky::get_panorama);
107
108 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_panorama", "get_panorama");
109 }
110
PanoramaSky()111 PanoramaSky::PanoramaSky() {
112
113 sky = VS::get_singleton()->sky_create();
114 }
115
~PanoramaSky()116 PanoramaSky::~PanoramaSky() {
117
118 VS::get_singleton()->free(sky);
119 }
120 //////////////////////////////////
121
_radiance_changed()122 void ProceduralSky::_radiance_changed() {
123
124 if (update_queued)
125 return; //do nothing yet
126
127 static const int size[RADIANCE_SIZE_MAX] = {
128 32, 64, 128, 256, 512, 1024, 2048
129 };
130 VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]);
131 }
132
_generate_sky()133 Ref<Image> ProceduralSky::_generate_sky() {
134
135 update_queued = false;
136
137 PoolVector<uint8_t> imgdata;
138
139 static const int size[TEXTURE_SIZE_MAX] = {
140 256, 512, 1024, 2048, 4096
141 };
142
143 int w = size[texture_size];
144 int h = w / 2;
145
146 imgdata.resize(w * h * 4); //RGBE
147
148 {
149 PoolVector<uint8_t>::Write dataw = imgdata.write();
150
151 uint32_t *ptr = (uint32_t *)dataw.ptr();
152
153 Color sky_top_linear = sky_top_color.to_linear();
154 Color sky_horizon_linear = sky_horizon_color.to_linear();
155
156 Color ground_bottom_linear = ground_bottom_color.to_linear();
157 Color ground_horizon_linear = ground_horizon_color.to_linear();
158
159 Color sun_linear;
160 sun_linear.r = sun_color.r * sun_energy;
161 sun_linear.g = sun_color.g * sun_energy;
162 sun_linear.b = sun_color.b * sun_energy;
163
164 Vector3 sun(0, 0, -1);
165
166 sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun);
167 sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun);
168
169 sun.normalize();
170
171 for (int i = 0; i < w; i++) {
172
173 float u = float(i) / (w - 1);
174 float phi = u * 2.0 * Math_PI;
175
176 for (int j = 0; j < h; j++) {
177
178 float v = float(j) / (h - 1);
179 float theta = v * Math_PI;
180
181 Vector3 normal(
182 Math::sin(phi) * Math::sin(theta) * -1.0,
183 Math::cos(theta),
184 Math::cos(phi) * Math::sin(theta) * -1.0);
185
186 normal.normalize();
187
188 float v_angle = Math::acos(CLAMP(normal.y, -1.0, 1.0));
189
190 Color color;
191
192 if (normal.y < 0) {
193 //ground
194
195 float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5);
196 color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve));
197 color.r *= ground_energy;
198 color.g *= ground_energy;
199 color.b *= ground_energy;
200 } else {
201 float c = v_angle / (Math_PI * 0.5);
202 color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve));
203 color.r *= sky_energy;
204 color.g *= sky_energy;
205 color.b *= sky_energy;
206
207 float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0)));
208
209 if (sun_angle < sun_angle_min) {
210 color = color.blend(sun_linear);
211 } else if (sun_angle < sun_angle_max) {
212
213 float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);
214 c2 = Math::ease(c2, sun_curve);
215
216 color = color.blend(sun_linear).linear_interpolate(color, c2);
217 }
218 }
219
220 ptr[j * w + i] = color.to_rgbe9995();
221 }
222 }
223 }
224
225 Ref<Image> image;
226 image.instance();
227 image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata);
228
229 return image;
230 }
231
set_sky_top_color(const Color & p_sky_top)232 void ProceduralSky::set_sky_top_color(const Color &p_sky_top) {
233
234 sky_top_color = p_sky_top;
235 _queue_update();
236 }
237
get_sky_top_color() const238 Color ProceduralSky::get_sky_top_color() const {
239
240 return sky_top_color;
241 }
242
set_sky_horizon_color(const Color & p_sky_horizon)243 void ProceduralSky::set_sky_horizon_color(const Color &p_sky_horizon) {
244
245 sky_horizon_color = p_sky_horizon;
246 _queue_update();
247 }
get_sky_horizon_color() const248 Color ProceduralSky::get_sky_horizon_color() const {
249
250 return sky_horizon_color;
251 }
252
set_sky_curve(float p_curve)253 void ProceduralSky::set_sky_curve(float p_curve) {
254
255 sky_curve = p_curve;
256 _queue_update();
257 }
get_sky_curve() const258 float ProceduralSky::get_sky_curve() const {
259
260 return sky_curve;
261 }
262
set_sky_energy(float p_energy)263 void ProceduralSky::set_sky_energy(float p_energy) {
264
265 sky_energy = p_energy;
266 _queue_update();
267 }
get_sky_energy() const268 float ProceduralSky::get_sky_energy() const {
269
270 return sky_energy;
271 }
272
set_ground_bottom_color(const Color & p_ground_bottom)273 void ProceduralSky::set_ground_bottom_color(const Color &p_ground_bottom) {
274
275 ground_bottom_color = p_ground_bottom;
276 _queue_update();
277 }
get_ground_bottom_color() const278 Color ProceduralSky::get_ground_bottom_color() const {
279
280 return ground_bottom_color;
281 }
282
set_ground_horizon_color(const Color & p_ground_horizon)283 void ProceduralSky::set_ground_horizon_color(const Color &p_ground_horizon) {
284
285 ground_horizon_color = p_ground_horizon;
286 _queue_update();
287 }
get_ground_horizon_color() const288 Color ProceduralSky::get_ground_horizon_color() const {
289
290 return ground_horizon_color;
291 }
292
set_ground_curve(float p_curve)293 void ProceduralSky::set_ground_curve(float p_curve) {
294
295 ground_curve = p_curve;
296 _queue_update();
297 }
get_ground_curve() const298 float ProceduralSky::get_ground_curve() const {
299
300 return ground_curve;
301 }
302
set_ground_energy(float p_energy)303 void ProceduralSky::set_ground_energy(float p_energy) {
304
305 ground_energy = p_energy;
306 _queue_update();
307 }
get_ground_energy() const308 float ProceduralSky::get_ground_energy() const {
309
310 return ground_energy;
311 }
312
set_sun_color(const Color & p_sun)313 void ProceduralSky::set_sun_color(const Color &p_sun) {
314
315 sun_color = p_sun;
316 _queue_update();
317 }
get_sun_color() const318 Color ProceduralSky::get_sun_color() const {
319
320 return sun_color;
321 }
322
set_sun_latitude(float p_angle)323 void ProceduralSky::set_sun_latitude(float p_angle) {
324
325 sun_latitude = p_angle;
326 _queue_update();
327 }
get_sun_latitude() const328 float ProceduralSky::get_sun_latitude() const {
329
330 return sun_latitude;
331 }
332
set_sun_longitude(float p_angle)333 void ProceduralSky::set_sun_longitude(float p_angle) {
334
335 sun_longitude = p_angle;
336 _queue_update();
337 }
get_sun_longitude() const338 float ProceduralSky::get_sun_longitude() const {
339
340 return sun_longitude;
341 }
342
set_sun_angle_min(float p_angle)343 void ProceduralSky::set_sun_angle_min(float p_angle) {
344
345 sun_angle_min = p_angle;
346 _queue_update();
347 }
get_sun_angle_min() const348 float ProceduralSky::get_sun_angle_min() const {
349
350 return sun_angle_min;
351 }
352
set_sun_angle_max(float p_angle)353 void ProceduralSky::set_sun_angle_max(float p_angle) {
354
355 sun_angle_max = p_angle;
356 _queue_update();
357 }
get_sun_angle_max() const358 float ProceduralSky::get_sun_angle_max() const {
359
360 return sun_angle_max;
361 }
362
set_sun_curve(float p_curve)363 void ProceduralSky::set_sun_curve(float p_curve) {
364
365 sun_curve = p_curve;
366 _queue_update();
367 }
get_sun_curve() const368 float ProceduralSky::get_sun_curve() const {
369
370 return sun_curve;
371 }
372
set_sun_energy(float p_energy)373 void ProceduralSky::set_sun_energy(float p_energy) {
374
375 sun_energy = p_energy;
376 _queue_update();
377 }
get_sun_energy() const378 float ProceduralSky::get_sun_energy() const {
379
380 return sun_energy;
381 }
382
set_texture_size(TextureSize p_size)383 void ProceduralSky::set_texture_size(TextureSize p_size) {
384 ERR_FAIL_INDEX(p_size, TEXTURE_SIZE_MAX);
385
386 texture_size = p_size;
387 _queue_update();
388 }
get_texture_size() const389 ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
390 return texture_size;
391 }
392
get_rid() const393 RID ProceduralSky::get_rid() const {
394 return sky;
395 }
396
_update_sky()397 void ProceduralSky::_update_sky() {
398
399 bool use_thread = true;
400 if (first_time) {
401 use_thread = false;
402 first_time = false;
403 }
404 #ifdef NO_THREADS
405 use_thread = false;
406 #endif
407 if (use_thread) {
408
409 if (!sky_thread) {
410 sky_thread = Thread::create(_thread_function, this);
411 regen_queued = false;
412 } else {
413 regen_queued = true;
414 }
415
416 } else {
417 Ref<Image> image = _generate_sky();
418 VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
419 VS::get_singleton()->texture_set_data(texture, image);
420 _radiance_changed();
421 }
422 }
423
_queue_update()424 void ProceduralSky::_queue_update() {
425
426 if (update_queued)
427 return;
428
429 update_queued = true;
430 call_deferred("_update_sky");
431 }
432
_thread_done(const Ref<Image> & p_image)433 void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
434
435 VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
436 VS::get_singleton()->texture_set_data(texture, p_image);
437 _radiance_changed();
438 Thread::wait_to_finish(sky_thread);
439 memdelete(sky_thread);
440 sky_thread = NULL;
441 if (regen_queued) {
442 sky_thread = Thread::create(_thread_function, this);
443 regen_queued = false;
444 }
445 }
446
_thread_function(void * p_ud)447 void ProceduralSky::_thread_function(void *p_ud) {
448
449 ProceduralSky *psky = (ProceduralSky *)p_ud;
450 psky->call_deferred("_thread_done", psky->_generate_sky());
451 }
452
_bind_methods()453 void ProceduralSky::_bind_methods() {
454
455 ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky);
456
457 ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSky::set_sky_top_color);
458 ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSky::get_sky_top_color);
459
460 ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSky::set_sky_horizon_color);
461 ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSky::get_sky_horizon_color);
462
463 ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSky::set_sky_curve);
464 ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSky::get_sky_curve);
465
466 ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSky::set_sky_energy);
467 ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSky::get_sky_energy);
468
469 ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSky::set_ground_bottom_color);
470 ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSky::get_ground_bottom_color);
471
472 ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSky::set_ground_horizon_color);
473 ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSky::get_ground_horizon_color);
474
475 ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSky::set_ground_curve);
476 ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSky::get_ground_curve);
477
478 ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSky::set_ground_energy);
479 ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSky::get_ground_energy);
480
481 ClassDB::bind_method(D_METHOD("set_sun_color", "color"), &ProceduralSky::set_sun_color);
482 ClassDB::bind_method(D_METHOD("get_sun_color"), &ProceduralSky::get_sun_color);
483
484 ClassDB::bind_method(D_METHOD("set_sun_latitude", "degrees"), &ProceduralSky::set_sun_latitude);
485 ClassDB::bind_method(D_METHOD("get_sun_latitude"), &ProceduralSky::get_sun_latitude);
486
487 ClassDB::bind_method(D_METHOD("set_sun_longitude", "degrees"), &ProceduralSky::set_sun_longitude);
488 ClassDB::bind_method(D_METHOD("get_sun_longitude"), &ProceduralSky::get_sun_longitude);
489
490 ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSky::set_sun_angle_min);
491 ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSky::get_sun_angle_min);
492
493 ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSky::set_sun_angle_max);
494 ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSky::get_sun_angle_max);
495
496 ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSky::set_sun_curve);
497 ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSky::get_sun_curve);
498
499 ClassDB::bind_method(D_METHOD("set_sun_energy", "energy"), &ProceduralSky::set_sun_energy);
500 ClassDB::bind_method(D_METHOD("get_sun_energy"), &ProceduralSky::get_sun_energy);
501
502 ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size);
503 ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size);
504
505 ClassDB::bind_method(D_METHOD("_thread_done", "image"), &ProceduralSky::_thread_done);
506
507 ADD_GROUP("Sky", "sky_");
508 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
509 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
510 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
511 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
512
513 ADD_GROUP("Ground", "ground_");
514 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
515 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
516 ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
517 ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
518
519 ADD_GROUP("Sun", "sun_");
520 ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color");
521 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude");
522 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude");
523 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
524 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
525 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
526 ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
527
528 ADD_GROUP("Texture", "texture_");
529 ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_texture_size", "get_texture_size");
530
531 BIND_ENUM_CONSTANT(TEXTURE_SIZE_256);
532 BIND_ENUM_CONSTANT(TEXTURE_SIZE_512);
533 BIND_ENUM_CONSTANT(TEXTURE_SIZE_1024);
534 BIND_ENUM_CONSTANT(TEXTURE_SIZE_2048);
535 BIND_ENUM_CONSTANT(TEXTURE_SIZE_4096);
536 BIND_ENUM_CONSTANT(TEXTURE_SIZE_MAX);
537 }
538
ProceduralSky(bool p_desaturate)539 ProceduralSky::ProceduralSky(bool p_desaturate) {
540
541 sky = VS::get_singleton()->sky_create();
542 texture = VS::get_singleton()->texture_create();
543
544 update_queued = false;
545 sky_top_color = Color::hex(0xa5d6f1ff);
546 sky_horizon_color = Color::hex(0xd6eafaff);
547 sky_curve = 0.09;
548 sky_energy = 1;
549
550 ground_bottom_color = Color::hex(0x282f36ff);
551 ground_horizon_color = Color::hex(0x6c655fff);
552 ground_curve = 0.02;
553 ground_energy = 1;
554
555 if (p_desaturate) {
556 sky_top_color.set_hsv(sky_top_color.get_h(), 0, sky_top_color.get_v());
557 sky_horizon_color.set_hsv(sky_horizon_color.get_h(), 0, sky_horizon_color.get_v());
558 ground_bottom_color.set_hsv(ground_bottom_color.get_h(), 0, ground_bottom_color.get_v());
559 ground_horizon_color.set_hsv(ground_horizon_color.get_h(), 0, ground_horizon_color.get_v());
560 }
561 sun_color = Color(1, 1, 1);
562 sun_latitude = 35;
563 sun_longitude = 0;
564 sun_angle_min = 1;
565 sun_angle_max = 100;
566 sun_curve = 0.05;
567 sun_energy = 1;
568
569 texture_size = TEXTURE_SIZE_1024;
570 sky_thread = NULL;
571 regen_queued = false;
572 first_time = true;
573
574 _queue_update();
575 }
576
~ProceduralSky()577 ProceduralSky::~ProceduralSky() {
578
579 if (sky_thread) {
580 Thread::wait_to_finish(sky_thread);
581 memdelete(sky_thread);
582 sky_thread = NULL;
583 }
584 VS::get_singleton()->free(sky);
585 VS::get_singleton()->free(texture);
586 }
587