void ProceduralSky::_update_sky() { bool use_thread = true; if (first_time) { use_thread = false; first_time = false; } #ifdef NO_THREADS use_thread = false; #endif if (use_thread) { if (!sky_thread) { sky_thread = Thread::create(_thread_function, this); regen_queued = false; } else { regen_queued = true; } } else { Ref<Image> image = _generate_sky(); 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); VS::get_singleton()->texture_set_data(texture, image); _radiance_changed(); } }
void PanoramaSky::set_panorama(const Ref<Texture> &p_panorama) { panorama = p_panorama; if (panorama.is_valid()) { _radiance_changed(); } else { VS::get_singleton()->sky_set_texture(sky, RID(), 0); } }
void ProceduralSky::_thread_done(const Ref<Image> &p_image) { 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); VS::get_singleton()->texture_set_data(texture, p_image); _radiance_changed(); Thread::wait_to_finish(sky_thread); memdelete(sky_thread); sky_thread = NULL; if (regen_queued) { sky_thread = Thread::create(_thread_function, this); regen_queued = false; } }
void Sky::set_radiance_size(RadianceSize p_size) { ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX); radiance_size = p_size; _radiance_changed(); }
void ProceduralSky::_update_sky() { update_queued = false; PoolVector<uint8_t> imgdata; static const int size[TEXTURE_SIZE_MAX] = { 1024, 2048, 4096 }; int w = size[texture_size]; int h = w / 2; imgdata.resize(w * h * 4); //RGBE { PoolVector<uint8_t>::Write dataw = imgdata.write(); uint32_t *ptr = (uint32_t *)dataw.ptr(); Color sky_top_linear = sky_top_color.to_linear(); Color sky_horizon_linear = sky_horizon_color.to_linear(); Color ground_bottom_linear = ground_bottom_color.to_linear(); Color ground_horizon_linear = ground_horizon_color.to_linear(); //Color sun_linear = sun_color.to_linear(); Vector3 sun(0, 0, -1); sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun); sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun); sun.normalize(); for (int i = 0; i < w; i++) { float u = float(i) / (w - 1); float phi = u * 2.0 * Math_PI; for (int j = 0; j < h; j++) { float v = float(j) / (h - 1); float theta = v * Math_PI; Vector3 normal( Math::sin(phi) * Math::sin(theta) * -1.0, Math::cos(theta), Math::cos(phi) * Math::sin(theta) * -1.0); normal.normalize(); float v_angle = Math::acos(normal.y); Color color; if (normal.y < 0) { //ground float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5); color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve)); } else { float c = v_angle / (Math_PI * 0.5); color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve)); float sun_angle = Math::rad2deg(Math::acos(sun.dot(normal))); if (sun_angle < sun_angle_min) { color = color.blend(sun_color); } else if (sun_angle < sun_angle_max) { float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min); c2 = Math::ease(c2, sun_curve); color = color.blend(sun_color).linear_interpolate(color, c2); } } ptr[j * w + i] = color.to_rgbe9995(); } } } Ref<Image> image; image.instance(); image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata); VS::get_singleton()->texture_allocate(texture, w, h, Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); VS::get_singleton()->texture_set_data(texture, image); _radiance_changed(); }