summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/color_ramp.cpp56
-rw-r--r--scene/resources/color_ramp.h10
-rw-r--r--scene/resources/sky_box.cpp391
-rw-r--r--scene/resources/sky_box.h112
-rw-r--r--scene/resources/world.cpp17
-rw-r--r--scene/resources/world.h5
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();