diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/color_ramp.cpp | 56 | ||||
-rw-r--r-- | scene/resources/color_ramp.h | 10 | ||||
-rw-r--r-- | scene/resources/sky_box.cpp | 391 | ||||
-rw-r--r-- | scene/resources/sky_box.h | 112 | ||||
-rw-r--r-- | scene/resources/world.cpp | 17 | ||||
-rw-r--r-- | scene/resources/world.h | 5 |
6 files changed, 546 insertions, 45 deletions
diff --git a/scene/resources/color_ramp.cpp b/scene/resources/color_ramp.cpp index 3c58a76998..3cf8845189 100644 --- a/scene/resources/color_ramp.cpp +++ b/scene/resources/color_ramp.cpp @@ -36,7 +36,7 @@ #define COLOR_RAMP_SET_OFFSETS "set_offsets" #define COLOR_RAMP_SET_COLORS "set_colors" -ColorRamp::ColorRamp() { +Gradient::Gradient() { //Set initial color ramp transition from black to white points.resize(2); points[0].color = Color(0, 0, 0, 1); @@ -46,35 +46,35 @@ ColorRamp::ColorRamp() { is_sorted = true; } -ColorRamp::~ColorRamp() { +Gradient::~Gradient() { } -void ColorRamp::_bind_methods() { +void Gradient::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &ColorRamp::add_point); - ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &ColorRamp::remove_point); + ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &Gradient::add_point); + ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &Gradient::remove_point); - ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &ColorRamp::set_offset); - ClassDB::bind_method(D_METHOD("get_offset", "point"), &ColorRamp::get_offset); + ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &Gradient::set_offset); + ClassDB::bind_method(D_METHOD("get_offset", "point"), &Gradient::get_offset); - ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &ColorRamp::set_color); - ClassDB::bind_method(D_METHOD("get_color", "point"), &ColorRamp::get_color); + ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &Gradient::set_color); + ClassDB::bind_method(D_METHOD("get_color", "point"), &Gradient::get_color); - ClassDB::bind_method(D_METHOD("interpolate", "offset"), &ColorRamp::get_color_at_offset); + ClassDB::bind_method(D_METHOD("interpolate", "offset"), &Gradient::get_color_at_offset); - ClassDB::bind_method(D_METHOD("get_point_count"), &ColorRamp::get_points_count); + ClassDB::bind_method(D_METHOD("get_point_count"), &Gradient::get_points_count); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &ColorRamp::set_offsets); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &ColorRamp::get_offsets); + ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &Gradient::set_offsets); + ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &Gradient::get_offsets); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &ColorRamp::set_colors); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &ColorRamp::get_colors); + ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &Gradient::set_colors); + ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &Gradient::get_colors); ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS); ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS); } -Vector<float> ColorRamp::get_offsets() const { +Vector<float> Gradient::get_offsets() const { Vector<float> offsets; offsets.resize(points.size()); for (int i = 0; i < points.size(); i++) { @@ -83,7 +83,7 @@ Vector<float> ColorRamp::get_offsets() const { return offsets; } -Vector<Color> ColorRamp::get_colors() const { +Vector<Color> Gradient::get_colors() const { Vector<Color> colors; colors.resize(points.size()); for (int i = 0; i < points.size(); i++) { @@ -92,7 +92,7 @@ Vector<Color> ColorRamp::get_colors() const { return colors; } -void ColorRamp::set_offsets(const Vector<float> &p_offsets) { +void Gradient::set_offsets(const Vector<float> &p_offsets) { points.resize(p_offsets.size()); for (int i = 0; i < points.size(); i++) { points[i].offset = p_offsets[i]; @@ -101,7 +101,7 @@ void ColorRamp::set_offsets(const Vector<float> &p_offsets) { emit_signal(CoreStringNames::get_singleton()->changed); } -void ColorRamp::set_colors(const Vector<Color> &p_colors) { +void Gradient::set_colors(const Vector<Color> &p_colors) { if (points.size() < p_colors.size()) is_sorted = false; points.resize(p_colors.size()); @@ -111,11 +111,11 @@ void ColorRamp::set_colors(const Vector<Color> &p_colors) { emit_signal(CoreStringNames::get_singleton()->changed); } -Vector<ColorRamp::Point> &ColorRamp::get_points() { +Vector<Gradient::Point> &Gradient::get_points() { return points; } -void ColorRamp::add_point(float p_offset, const Color &p_color) { +void Gradient::add_point(float p_offset, const Color &p_color) { Point p; p.offset = p_offset; @@ -126,7 +126,7 @@ void ColorRamp::add_point(float p_offset, const Color &p_color) { emit_signal(CoreStringNames::get_singleton()->changed); } -void ColorRamp::remove_point(int p_index) { +void Gradient::remove_point(int p_index) { ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_COND(points.size() <= 2); @@ -134,13 +134,13 @@ void ColorRamp::remove_point(int p_index) { emit_signal(CoreStringNames::get_singleton()->changed); } -void ColorRamp::set_points(Vector<ColorRamp::Point> &p_points) { +void Gradient::set_points(Vector<Gradient::Point> &p_points) { points = p_points; is_sorted = false; emit_signal(CoreStringNames::get_singleton()->changed); } -void ColorRamp::set_offset(int pos, const float offset) { +void Gradient::set_offset(int pos, const float offset) { if (points.size() <= pos) points.resize(pos + 1); points[pos].offset = offset; @@ -148,13 +148,13 @@ void ColorRamp::set_offset(int pos, const float offset) { emit_signal(CoreStringNames::get_singleton()->changed); } -float ColorRamp::get_offset(int pos) const { +float Gradient::get_offset(int pos) const { if (points.size() > pos) return points[pos].offset; return 0; //TODO: Maybe throw some error instead? } -void ColorRamp::set_color(int pos, const Color &color) { +void Gradient::set_color(int pos, const Color &color) { if (points.size() <= pos) { points.resize(pos + 1); is_sorted = false; @@ -163,12 +163,12 @@ void ColorRamp::set_color(int pos, const Color &color) { emit_signal(CoreStringNames::get_singleton()->changed); } -Color ColorRamp::get_color(int pos) const { +Color Gradient::get_color(int pos) const { if (points.size() > pos) return points[pos].color; return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead? } -int ColorRamp::get_points_count() const { +int Gradient::get_points_count() const { return points.size(); } diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h index e231e9fc52..d7ec20b324 100644 --- a/scene/resources/color_ramp.h +++ b/scene/resources/color_ramp.h @@ -32,9 +32,9 @@ #include "resource.h" -class ColorRamp : public Resource { - GDCLASS(ColorRamp, Resource); - OBJ_SAVE_TYPE(ColorRamp); +class Gradient : public Resource { + GDCLASS(Gradient, Resource); + OBJ_SAVE_TYPE(Gradient); public: struct Point { @@ -54,8 +54,8 @@ protected: static void _bind_methods(); public: - ColorRamp(); - virtual ~ColorRamp(); + Gradient(); + virtual ~Gradient(); void add_point(float p_offset, const Color &p_color); void remove_point(int p_index); diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp index 59ade4a729..61aaaf8fb4 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky_box.cpp @@ -112,3 +112,394 @@ 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] = { + 256, 512, 1024, 2048 + }; + VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]); +} + +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(); +} + +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; +} + +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(); +} +float ProceduralSky::get_sun_energy() const { + + return sun_energy; +} + +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; +} + +RID ProceduralSky::get_rid() const { + return sky; +} + +void ProceduralSky::_queue_update() { + + if (update_queued) + return; + + update_queued = true; + call_deferred("_update_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); + + 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"); + + 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"); + + 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_GROUP("Texture", "texture_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "1024,2048,4096"), "set_texture_size", "get_texture_size"); +} + +ProceduralSky::ProceduralSky() { + + sky = VS::get_singleton()->sky_create(); + texture = VS::get_singleton()->texture_create(); + + update_queued = false; + + sky_top_color = Color::hex(0x4d67e8ff); + sky_horizon_color = Color::hex(0x8ed2e8ff); + sky_curve = 0.25; + sky_energy = 1; + + ground_bottom_color = Color::hex(0x322719ff); + ground_horizon_color = Color::hex(0x543610ff); + ground_curve = 0.25; + ground_energy = 1; + + 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 = 16; + + texture_size = TEXTURE_SIZE_1024; + + _queue_update(); +} + +ProceduralSky::~ProceduralSky() { + + VS::get_singleton()->free(sky); + VS::get_singleton()->free(texture); +} diff --git a/scene/resources/sky_box.h b/scene/resources/sky_box.h index afbfb3019e..7b707af3a6 100644 --- a/scene/resources/sky_box.h +++ b/scene/resources/sky_box.h @@ -62,17 +62,6 @@ VARIANT_ENUM_CAST(Sky::RadianceSize) class PanoramaSky : public Sky { GDCLASS(PanoramaSky, Sky); -public: - enum ImagePath { - IMAGE_PATH_NEGATIVE_X, - IMAGE_PATH_POSITIVE_X, - IMAGE_PATH_NEGATIVE_Y, - IMAGE_PATH_POSITIVE_Y, - IMAGE_PATH_NEGATIVE_Z, - IMAGE_PATH_POSITIVE_Z, - IMAGE_PATH_MAX - }; - private: RID sky; Ref<Texture> panorama; @@ -91,6 +80,105 @@ public: ~PanoramaSky(); }; -VARIANT_ENUM_CAST(PanoramaSky::ImagePath) +class ProceduralSky : public Sky { + GDCLASS(ProceduralSky, Sky); + +public: + enum TextureSize { + TEXTURE_SIZE_1024, + TEXTURE_SIZE_2048, + TEXTURE_SIZE_4096, + TEXTURE_SIZE_MAX + }; + +private: + Color sky_top_color; + Color sky_horizon_color; + float sky_curve; + float sky_energy; + + Color ground_bottom_color; + Color ground_horizon_color; + float ground_curve; + float ground_energy; + + Color sun_color; + float sun_latitude; + float sun_longitude; + float sun_angle_min; + float sun_angle_max; + float sun_curve; + float sun_energy; + + TextureSize texture_size; + + RID sky; + RID texture; + + bool update_queued; + +protected: + static void _bind_methods(); + virtual void _radiance_changed(); + + void _update_sky(); + void _queue_update(); + +public: + void set_sky_top_color(const Color &p_sky_top); + Color get_sky_top_color() const; + + void set_sky_horizon_color(const Color &p_sky_horizon); + Color get_sky_horizon_color() const; + + void set_sky_curve(float p_curve); + float get_sky_curve() const; + + void set_sky_energy(float p_energy); + float get_sky_energy() const; + + void set_ground_bottom_color(const Color &p_ground_bottom); + Color get_ground_bottom_color() const; + + void set_ground_horizon_color(const Color &p_ground_horizon); + Color get_ground_horizon_color() const; + + void set_ground_curve(float p_curve); + float get_ground_curve() const; + + void set_ground_energy(float p_energy); + float get_ground_energy() const; + + void set_sun_color(const Color &p_sun); + Color get_sun_color() const; + + void set_sun_latitude(float p_angle); + float get_sun_latitude() const; + + void set_sun_longitude(float p_angle); + float get_sun_longitude() const; + + void set_sun_angle_min(float p_angle); + float get_sun_angle_min() const; + + void set_sun_angle_max(float p_angle); + float get_sun_angle_max() const; + + void set_sun_curve(float p_curve); + float get_sun_curve() const; + + void set_sun_energy(float p_energy); + float get_sun_energy() const; + + void set_texture_size(TextureSize p_size); + TextureSize get_texture_size() const; + + virtual RID get_rid() const; + + ProceduralSky(); + ~ProceduralSky(); +}; + +VARIANT_ENUM_CAST(ProceduralSky::TextureSize) #endif // Sky_H diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index eab7cf6098..24551e9135 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -280,6 +280,20 @@ Ref<Environment> World::get_environment() const { return environment; } +void World::set_fallback_environment(const Ref<Environment> &p_environment) { + + fallback_environment = p_environment; + if (fallback_environment.is_valid()) + VS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid()); + else + VS::get_singleton()->scenario_set_fallback_environment(scenario, RID()); +} + +Ref<Environment> World::get_fallback_environment() const { + + return fallback_environment; +} + PhysicsDirectSpaceState *World::get_direct_space_state() { return PhysicsServer::get_singleton()->space_get_direct_state(space); @@ -291,8 +305,11 @@ void World::_bind_methods() { ClassDB::bind_method(D_METHOD("get_scenario"), &World::get_scenario); ClassDB::bind_method(D_METHOD("set_environment", "env:Environment"), &World::set_environment); ClassDB::bind_method(D_METHOD("get_environment:Environment"), &World::get_environment); + ClassDB::bind_method(D_METHOD("set_fallback_environment", "env:Environment"), &World::set_fallback_environment); + ClassDB::bind_method(D_METHOD("get_fallback_environment:Environment"), &World::get_fallback_environment); ClassDB::bind_method(D_METHOD("get_direct_space_state:PhysicsDirectSpaceState"), &World::get_direct_space_state); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment"); } World::World() { diff --git a/scene/resources/world.h b/scene/resources/world.h index f2c85f31f6..96857a577a 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -48,6 +48,7 @@ private: RID scenario; SpatialIndexer *indexer; Ref<Environment> environment; + Ref<Environment> fallback_environment; protected: static void _bind_methods(); @@ -68,9 +69,13 @@ protected: public: RID get_space() const; RID get_scenario() const; + void set_environment(const Ref<Environment> &p_environment); Ref<Environment> get_environment() const; + void set_fallback_environment(const Ref<Environment> &p_environment); + Ref<Environment> get_fallback_environment() const; + PhysicsDirectSpaceState *get_direct_space_state(); World(); |