diff options
Diffstat (limited to 'scene/resources/sky.cpp')
-rw-r--r-- | scene/resources/sky.cpp | 566 |
1 files changed, 46 insertions, 520 deletions
diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp index c20fbb4129..7e32516f94 100644 --- a/scene/resources/sky.cpp +++ b/scene/resources/sky.cpp @@ -36,551 +36,77 @@ void Sky::set_radiance_size(RadianceSize p_size) { ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX); radiance_size = p_size; - _radiance_changed(); -} - -Sky::RadianceSize Sky::get_radiance_size() const { - - return radiance_size; -} - -void Sky::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size); - ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size"); - - BIND_ENUM_CONSTANT(RADIANCE_SIZE_32); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_64); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_128); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_256); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_512); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048); - BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX); -} - -Sky::Sky() { - radiance_size = RADIANCE_SIZE_128; -} - -///////////////////////////////////////// - -void PanoramaSky::_radiance_changed() { - - if (panorama.is_valid()) { - static const int size[RADIANCE_SIZE_MAX] = { - 32, 64, 128, 256, 512, 1024, 2048 - }; - VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]); - } -} - -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); - } -} - -Ref<Texture> PanoramaSky::get_panorama() const { - - return panorama; -} - -RID PanoramaSky::get_rid() const { - - return sky; -} - -void PanoramaSky::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama); - ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSky::get_panorama); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_panorama", "get_panorama"); -} - -PanoramaSky::PanoramaSky() { - - sky = VS::get_singleton()->sky_create(); -} - -PanoramaSky::~PanoramaSky() { - - VS::get_singleton()->free(sky); -} -////////////////////////////////// - -void ProceduralSky::_radiance_changed() { - - if (update_queued) - return; //do nothing yet - static const int size[RADIANCE_SIZE_MAX] = { 32, 64, 128, 256, 512, 1024, 2048 }; - VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]); -} - -Ref<Image> ProceduralSky::_generate_sky() { - - update_queued = false; - - PoolVector<uint8_t> imgdata; - - static const int size[TEXTURE_SIZE_MAX] = { - 256, 512, 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_linear.r = sun_color.r * sun_energy; - sun_linear.g = sun_color.g * sun_energy; - sun_linear.b = sun_color.b * sun_energy; - - 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(CLAMP(normal.y, -1.0, 1.0)); - - 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)); - color.r *= ground_energy; - color.g *= ground_energy; - color.b *= ground_energy; - } 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)); - color.r *= sky_energy; - color.g *= sky_energy; - color.b *= sky_energy; - - float sun_angle = Math::rad2deg(Math::acos(CLAMP(sun.dot(normal), -1.0, 1.0))); - - if (sun_angle < sun_angle_min) { - color = color.blend(sun_linear); - } 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_linear).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); - - return image; -} - -void ProceduralSky::set_sky_top_color(const Color &p_sky_top) { - - sky_top_color = p_sky_top; - _queue_update(); -} - -Color ProceduralSky::get_sky_top_color() const { - - return sky_top_color; + RS::get_singleton()->sky_set_radiance_size(sky, size[radiance_size]); } -void ProceduralSky::set_sky_horizon_color(const Color &p_sky_horizon) { - - sky_horizon_color = p_sky_horizon; - _queue_update(); -} -Color ProceduralSky::get_sky_horizon_color() const { - - return sky_horizon_color; -} - -void ProceduralSky::set_sky_curve(float p_curve) { - - sky_curve = p_curve; - _queue_update(); -} -float ProceduralSky::get_sky_curve() const { - - return sky_curve; -} - -void ProceduralSky::set_sky_energy(float p_energy) { - - sky_energy = p_energy; - _queue_update(); -} -float ProceduralSky::get_sky_energy() const { - - return sky_energy; -} - -void ProceduralSky::set_ground_bottom_color(const Color &p_ground_bottom) { - - ground_bottom_color = p_ground_bottom; - _queue_update(); -} -Color ProceduralSky::get_ground_bottom_color() const { - - return ground_bottom_color; -} - -void ProceduralSky::set_ground_horizon_color(const Color &p_ground_horizon) { - - ground_horizon_color = p_ground_horizon; - _queue_update(); -} -Color ProceduralSky::get_ground_horizon_color() const { - - return ground_horizon_color; -} - -void ProceduralSky::set_ground_curve(float p_curve) { - - ground_curve = p_curve; - _queue_update(); -} -float ProceduralSky::get_ground_curve() const { - - return ground_curve; -} - -void ProceduralSky::set_ground_energy(float p_energy) { - - ground_energy = p_energy; - _queue_update(); -} -float ProceduralSky::get_ground_energy() const { - - return ground_energy; -} - -void ProceduralSky::set_sun_color(const Color &p_sun) { - - sun_color = p_sun; - _queue_update(); -} -Color ProceduralSky::get_sun_color() const { - - return sun_color; -} - -void ProceduralSky::set_sun_latitude(float p_angle) { - - sun_latitude = p_angle; - _queue_update(); -} -float ProceduralSky::get_sun_latitude() const { - - return sun_latitude; -} - -void ProceduralSky::set_sun_longitude(float p_angle) { - - sun_longitude = p_angle; - _queue_update(); -} -float ProceduralSky::get_sun_longitude() const { - - return sun_longitude; -} - -void ProceduralSky::set_sun_angle_min(float p_angle) { - - sun_angle_min = p_angle; - _queue_update(); -} -float ProceduralSky::get_sun_angle_min() const { - - return sun_angle_min; -} - -void ProceduralSky::set_sun_angle_max(float p_angle) { - - sun_angle_max = p_angle; - _queue_update(); -} -float ProceduralSky::get_sun_angle_max() const { - - return sun_angle_max; -} - -void ProceduralSky::set_sun_curve(float p_curve) { - - sun_curve = p_curve; - _queue_update(); -} -float ProceduralSky::get_sun_curve() const { - - return sun_curve; -} - -void ProceduralSky::set_sun_energy(float p_energy) { - - sun_energy = p_energy; - _queue_update(); +Sky::RadianceSize Sky::get_radiance_size() const { + return radiance_size; } -float ProceduralSky::get_sun_energy() const { - return sun_energy; +void Sky::set_process_mode(ProcessMode p_mode) { + mode = p_mode; + RS::get_singleton()->sky_set_mode(sky, RS::SkyMode(mode)); } -void ProceduralSky::set_texture_size(TextureSize p_size) { - ERR_FAIL_INDEX(p_size, TEXTURE_SIZE_MAX); - - texture_size = p_size; - _queue_update(); -} -ProceduralSky::TextureSize ProceduralSky::get_texture_size() const { - return texture_size; +Sky::ProcessMode Sky::get_process_mode() const { + return mode; } -RID ProceduralSky::get_rid() const { - return sky; -} - -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 Sky::set_material(const Ref<Material> &p_material) { + sky_material = p_material; + RID material_rid; + if (sky_material.is_valid()) { + material_rid = sky_material->get_rid(); } + RS::get_singleton()->sky_set_material(sky, material_rid); } -void ProceduralSky::_queue_update() { - - if (update_queued) - return; - - update_queued = true; - call_deferred("_update_sky"); +Ref<Material> Sky::get_material() const { + return sky_material; } -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 ProceduralSky::_thread_function(void *p_ud) { - - ProceduralSky *psky = (ProceduralSky *)p_ud; - psky->call_deferred("_thread_done", psky->_generate_sky()); +RID Sky::get_rid() const { + return sky; } -void ProceduralSky::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky); - - ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSky::set_sky_top_color); - ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSky::get_sky_top_color); - - ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSky::set_sky_horizon_color); - ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSky::get_sky_horizon_color); - - ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSky::set_sky_curve); - ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSky::get_sky_curve); - - ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSky::set_sky_energy); - ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSky::get_sky_energy); - - ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSky::set_ground_bottom_color); - ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSky::get_ground_bottom_color); - - ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSky::set_ground_horizon_color); - ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSky::get_ground_horizon_color); - - ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSky::set_ground_curve); - ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSky::get_ground_curve); - - ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSky::set_ground_energy); - ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSky::get_ground_energy); - - ClassDB::bind_method(D_METHOD("set_sun_color", "color"), &ProceduralSky::set_sun_color); - ClassDB::bind_method(D_METHOD("get_sun_color"), &ProceduralSky::get_sun_color); - - ClassDB::bind_method(D_METHOD("set_sun_latitude", "degrees"), &ProceduralSky::set_sun_latitude); - ClassDB::bind_method(D_METHOD("get_sun_latitude"), &ProceduralSky::get_sun_latitude); - - ClassDB::bind_method(D_METHOD("set_sun_longitude", "degrees"), &ProceduralSky::set_sun_longitude); - ClassDB::bind_method(D_METHOD("get_sun_longitude"), &ProceduralSky::get_sun_longitude); - - ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSky::set_sun_angle_min); - ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSky::get_sun_angle_min); - - ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSky::set_sun_angle_max); - ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSky::get_sun_angle_max); - - ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSky::set_sun_curve); - ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSky::get_sun_curve); - - ClassDB::bind_method(D_METHOD("set_sun_energy", "energy"), &ProceduralSky::set_sun_energy); - ClassDB::bind_method(D_METHOD("get_sun_energy"), &ProceduralSky::get_sun_energy); - - ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size); - ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size); - - ClassDB::bind_method(D_METHOD("_thread_done", "image"), &ProceduralSky::_thread_done); +void Sky::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size); + ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size); - ADD_GROUP("Sky", "sky_"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy"); + ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Sky::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"), &Sky::get_process_mode); - ADD_GROUP("Ground", "ground_"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy"); + ClassDB::bind_method(D_METHOD("set_material", "material"), &Sky::set_material); + ClassDB::bind_method(D_METHOD("get_material"), &Sky::get_material); - ADD_GROUP("Sun", "sun_"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,PanoramaSkyMaterial,ProceduralSkyMaterial,PhysicalSkyMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Automatic,HighQuality,HighQualityIncremental,RealTime"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size"); - ADD_GROUP("Texture", "texture_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_texture_size", "get_texture_size"); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_32); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_64); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_128); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_256); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_512); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048); + BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX); - BIND_ENUM_CONSTANT(TEXTURE_SIZE_256); - BIND_ENUM_CONSTANT(TEXTURE_SIZE_512); - BIND_ENUM_CONSTANT(TEXTURE_SIZE_1024); - BIND_ENUM_CONSTANT(TEXTURE_SIZE_2048); - BIND_ENUM_CONSTANT(TEXTURE_SIZE_4096); - BIND_ENUM_CONSTANT(TEXTURE_SIZE_MAX); + BIND_ENUM_CONSTANT(PROCESS_MODE_AUTOMATIC); + BIND_ENUM_CONSTANT(PROCESS_MODE_QUALITY); + BIND_ENUM_CONSTANT(PROCESS_MODE_INCREMENTAL); + BIND_ENUM_CONSTANT(PROCESS_MODE_REALTIME); } -ProceduralSky::ProceduralSky(bool p_desaturate) { - - sky = VS::get_singleton()->sky_create(); - texture = VS::get_singleton()->texture_create(); - - update_queued = false; - sky_top_color = Color::hex(0xa5d6f1ff); - sky_horizon_color = Color::hex(0xd6eafaff); - sky_curve = 0.09; - sky_energy = 1; - - ground_bottom_color = Color::hex(0x282f36ff); - ground_horizon_color = Color::hex(0x6c655fff); - ground_curve = 0.02; - ground_energy = 1; - - if (p_desaturate) { - sky_top_color.set_hsv(sky_top_color.get_h(), 0, sky_top_color.get_v()); - sky_horizon_color.set_hsv(sky_horizon_color.get_h(), 0, sky_horizon_color.get_v()); - ground_bottom_color.set_hsv(ground_bottom_color.get_h(), 0, ground_bottom_color.get_v()); - ground_horizon_color.set_hsv(ground_horizon_color.get_h(), 0, ground_horizon_color.get_v()); - } - sun_color = Color(1, 1, 1); - sun_latitude = 35; - sun_longitude = 0; - sun_angle_min = 1; - sun_angle_max = 100; - sun_curve = 0.05; - sun_energy = 1; - - texture_size = TEXTURE_SIZE_1024; - sky_thread = NULL; - regen_queued = false; - first_time = true; - - _queue_update(); +Sky::Sky() { + mode = PROCESS_MODE_AUTOMATIC; + radiance_size = RADIANCE_SIZE_256; + sky = RS::get_singleton()->sky_create(); } -ProceduralSky::~ProceduralSky() { - - if (sky_thread) { - Thread::wait_to_finish(sky_thread); - memdelete(sky_thread); - sky_thread = NULL; - } - VS::get_singleton()->free(sky); - VS::get_singleton()->free(texture); +Sky::~Sky() { + RS::get_singleton()->free(sky); } |