summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2020-03-19 17:32:19 -0700
committerclayjohn <claynjohn@gmail.com>2020-03-21 20:43:44 -0700
commit61a74739ca2d201e7e057d85aa99ae68f0500c33 (patch)
tree73f170a76bb138f01d2df825798d6c4109b81cc8 /scene
parentc3fee7ba6cdefd285255b9e1198bc1fdf585b1ac (diff)
Working sky shader implementation
Diffstat (limited to 'scene')
-rw-r--r--scene/register_scene_types.cpp9
-rw-r--r--scene/resources/environment.cpp31
-rw-r--r--scene/resources/environment.h5
-rw-r--r--scene/resources/sky.cpp509
-rw-r--r--scene/resources/sky.h130
-rw-r--r--scene/resources/sky_material.cpp619
-rw-r--r--scene/resources/sky_material.h213
7 files changed, 691 insertions, 825 deletions
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index c152bb7e97..f15911b0e2 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -610,8 +610,9 @@ void register_scene_types() {
SceneTree::add_idle_callback(ParticlesMaterial::flush_changes);
ParticlesMaterial::init_shaders();
- ClassDB::register_class<SkyMaterial>();
- SkyMaterial::init_shaders();
+ ClassDB::register_class<ProceduralSkyMaterial>();
+ ClassDB::register_class<PanoramaSkyMaterial>();
+ ClassDB::register_class<PhysicalSkyMaterial>();
ClassDB::register_virtual_class<Mesh>();
ClassDB::register_class<ArrayMesh>();
@@ -663,9 +664,7 @@ void register_scene_types() {
ClassDB::register_class<World2D>();
ClassDB::register_virtual_class<Texture>();
ClassDB::register_virtual_class<Texture2D>();
- ClassDB::register_virtual_class<Sky>();
- ClassDB::register_class<PanoramaSky>();
- ClassDB::register_class<ProceduralSky>();
+ ClassDB::register_class<Sky>();
ClassDB::register_class<StreamTexture>();
ClassDB::register_class<ImageTexture>();
ClassDB::register_class<AtlasTexture>();
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index b5a182ed5a..d407dd3722 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -56,17 +56,6 @@ void Environment::set_sky(const Ref<Sky> &p_sky) {
VS::get_singleton()->environment_set_sky(environment, sb_rid);
}
-void Environment::set_bg_material(const Ref<Material> &p_material) {
-
- bg_material = p_material;
-
- RID mb_rid;
- if (bg_material.is_valid())
- mb_rid = bg_material->get_rid();
-
- VS::get_singleton()->environment_set_bg_material(environment, mb_rid);
-}
-
void Environment::set_sky_custom_fov(float p_scale) {
bg_sky_custom_fov = p_scale;
@@ -151,11 +140,6 @@ Vector3 Environment::get_sky_rotation() const {
return sky_rotation;
}
-Ref<Material> Environment::get_bg_material() const {
-
- return bg_material;
-}
-
Color Environment::get_bg_color() const {
return bg_color;
@@ -322,13 +306,6 @@ Ref<Texture2D> Environment::get_adjustment_color_correction() const {
void Environment::_validate_property(PropertyInfo &property) const {
- if (property.name == "background_material") {
- if (bg_mode != BG_SKY) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- }
- }
-
- // TODO: We are retiring sky in favour of a background material that implements the sky. These properties will become part of the sky material
if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") {
if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -357,7 +334,7 @@ void Environment::_validate_property(PropertyInfo &property) const {
if (property.name == "background_camera_feed_id") {
if (bg_mode != BG_CAMERA_FEED) {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
@@ -862,7 +839,6 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky);
ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov);
ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation);
- ClassDB::bind_method(D_METHOD("set_bg_material", "material"), &Environment::set_bg_material);
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color);
ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy);
ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer);
@@ -877,7 +853,6 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky);
ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov);
ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation);
- ClassDB::bind_method(D_METHOD("get_bg_material"), &Environment::get_bg_material);
ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy);
ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer);
@@ -896,14 +871,10 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SkyMaterial"), "set_bg_material", "get_bg_material");
-
- // TODO: We are retiring sky in favour of a background material that implements the sky. These properties will become part of the sky material
ADD_GROUP("Sky", "sky_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation"), "set_sky_rotation", "get_sky_rotation");
-
ADD_GROUP("Ambient Light", "ambient_light_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Color,Sky"), "set_ambient_source", "get_ambient_source");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color");
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 9ee0cc312c..f9fe26f792 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -34,7 +34,6 @@
#include "core/resource.h"
#include "scene/resources/sky.h"
#include "scene/resources/texture.h"
-#include "scene/resources/material.h"
#include "servers/visual_server.h"
class Environment : public Resource {
@@ -93,8 +92,6 @@ private:
BGMode bg_mode;
Ref<Sky> bg_sky;
- //@TODO for now introducing material but once it works we'll be replacing the current sky classes with material classes
- Ref<Material> bg_material;
float bg_sky_custom_fov;
Vector3 sky_rotation;
Color bg_color;
@@ -183,7 +180,6 @@ public:
void set_sky(const Ref<Sky> &p_sky);
void set_sky_custom_fov(float p_scale);
void set_sky_rotation(const Vector3 &p_rotation);
- void set_bg_material(const Ref<Material> &p_material);
void set_bg_color(const Color &p_color);
void set_bg_energy(float p_energy);
void set_canvas_max_layer(int p_max_layer);
@@ -200,7 +196,6 @@ public:
Ref<Sky> get_sky() const;
float get_sky_custom_fov() const;
Vector3 get_sky_rotation() const;
- Ref<Material> get_bg_material() const;
Color get_bg_color() const;
float get_bg_energy() const;
int get_canvas_max_layer() const;
diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp
index 54648e8af7..1185b693b7 100644
--- a/scene/resources/sky.cpp
+++ b/scene/resources/sky.cpp
@@ -56,6 +56,18 @@ Sky::ProcessMode Sky::get_process_mode() const {
return mode;
}
+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();
+ VS::get_singleton()->sky_set_material(sky, material_rid);
+}
+
+Ref<Material> Sky::get_material() const {
+ return sky_material;
+}
+
RID Sky::get_rid() const {
return sky;
@@ -69,6 +81,10 @@ void Sky::_bind_methods() {
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);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &Sky::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &Sky::get_material);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,PanoramaSkyMaterial,ProceduralSkyMaterial,PhysicalSkyMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "HighQuality,RealTime"), "set_process_mode", "get_process_mode");
@@ -87,500 +103,11 @@ void Sky::_bind_methods() {
Sky::Sky() {
mode = PROCESS_MODE_QUALITY;
- radiance_size = RADIANCE_SIZE_128;
+ radiance_size = RADIANCE_SIZE_256;
sky = VS::get_singleton()->sky_create();
}
Sky::~Sky() {
VS::get_singleton()->free(sky);
-}
-
-/////////////////////////////////////////
-
-void PanoramaSky::set_panorama(const Ref<Texture2D> &p_panorama) {
-
- panorama = p_panorama;
-
- RID rid = p_panorama.is_valid() ? p_panorama->get_rid() : RID();
- VS::get_singleton()->sky_set_texture(get_rid(), rid);
-}
-
-Ref<Texture2D> PanoramaSky::get_panorama() const {
-
- return panorama;
-}
-
-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, "Texture2D"), "set_panorama", "get_panorama");
-}
-
-PanoramaSky::PanoramaSky() {
-}
-
-PanoramaSky::~PanoramaSky() {
-}
-//////////////////////////////////
-
-Ref<Image> ProceduralSky::_generate_sky() {
-
- update_queued = false;
-
- Vector<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
-
- {
- uint8_t *dataw = imgdata.ptrw();
-
- uint32_t *ptr = (uint32_t *)dataw;
-
- 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;
-}
-
-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;
-}
-
-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();
- if (texture.is_valid()) {
- RID new_texture = VS::get_singleton()->texture_2d_create(image);
- VS::get_singleton()->texture_replace(texture, new_texture);
- } else {
- texture = VS::get_singleton()->texture_2d_create(image);
- }
- VS::get_singleton()->sky_set_texture(get_rid(), texture);
- }
-}
-
-void ProceduralSky::_queue_update() {
-
- if (update_queued)
- return;
-
- update_queued = true;
- call_deferred("_update_sky");
-}
-
-void ProceduralSky::_thread_done(const Ref<Image> &p_image) {
-
- if (texture.is_valid()) {
- RID new_texture = VS::get_singleton()->texture_2d_create(p_image);
- VS::get_singleton()->texture_replace(texture, new_texture);
- } else {
- texture = VS::get_singleton()->texture_2d_create(p_image);
- }
-
- VS::get_singleton()->sky_set_texture(get_rid(), texture);
-
- 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());
-}
-
-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);
-
- 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::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "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::FLOAT, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "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::FLOAT, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
-
- ADD_GROUP("Texture2D", "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(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);
-}
-
-ProceduralSky::ProceduralSky(bool p_desaturate) {
-
- 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();
-}
-
-ProceduralSky::~ProceduralSky() {
-
- if (sky_thread) {
- Thread::wait_to_finish(sky_thread);
- memdelete(sky_thread);
- sky_thread = NULL;
- }
- if (texture.is_valid()) {
- VS::get_singleton()->free(texture);
- }
-}
+} \ No newline at end of file
diff --git a/scene/resources/sky.h b/scene/resources/sky.h
index 09ebbd88a0..37f0a589f9 100644
--- a/scene/resources/sky.h
+++ b/scene/resources/sky.h
@@ -32,6 +32,7 @@
#define SKY_H
#include "core/os/thread.h"
+#include "scene/resources/material.h"
#include "scene/resources/texture.h"
class Sky : public Resource {
@@ -58,6 +59,7 @@ private:
RID sky;
ProcessMode mode;
RadianceSize radiance_size;
+ Ref<Material> sky_material;
protected:
static void _bind_methods();
@@ -69,6 +71,9 @@ public:
void set_process_mode(ProcessMode p_mode);
ProcessMode get_process_mode() const;
+ void set_material(const Ref<Material> &p_material);
+ Ref<Material> get_material() const;
+
virtual RID get_rid() const;
Sky();
@@ -78,129 +83,4 @@ public:
VARIANT_ENUM_CAST(Sky::RadianceSize)
VARIANT_ENUM_CAST(Sky::ProcessMode)
-class PanoramaSky : public Sky {
- GDCLASS(PanoramaSky, Sky);
-
-private:
- Ref<Texture2D> panorama;
-
-protected:
- static void _bind_methods();
-
-public:
- void set_panorama(const Ref<Texture2D> &p_panorama);
- Ref<Texture2D> get_panorama() const;
-
- PanoramaSky();
- ~PanoramaSky();
-};
-
-class ProceduralSky : public Sky {
- GDCLASS(ProceduralSky, Sky);
-
-public:
- enum TextureSize {
- TEXTURE_SIZE_256,
- TEXTURE_SIZE_512,
- TEXTURE_SIZE_1024,
- TEXTURE_SIZE_2048,
- TEXTURE_SIZE_4096,
- TEXTURE_SIZE_MAX
- };
-
-private:
- Thread *sky_thread;
- 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 texture;
-
- bool update_queued;
- bool regen_queued;
-
- bool first_time;
-
- void _thread_done(const Ref<Image> &p_image);
- static void _thread_function(void *p_ud);
-
-protected:
- static void _bind_methods();
-
- Ref<Image> _generate_sky();
- 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;
-
- ProceduralSky(bool p_desaturate = false);
- ~ProceduralSky();
-};
-
-VARIANT_ENUM_CAST(ProceduralSky::TextureSize)
-
#endif // SKY_H
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 8c2b339015..5d8ceacbf2 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -30,162 +30,597 @@
#include "sky_material.h"
-Mutex *SkyMaterial::material_mutex = NULL;
-SelfList<SkyMaterial>::List *SkyMaterial::dirty_materials = NULL;
-Map<SkyMaterial::MaterialKey, SkyMaterial::ShaderData> SkyMaterial::shader_map;
-SkyMaterial::ShaderNames *SkyMaterial::shader_names = NULL;
+void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
-void SkyMaterial::init_shaders() {
+ sky_top_color = p_sky_top;
+ VS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
+}
-#ifndef NO_THREADS
- material_mutex = Mutex::create();
-#endif
+Color ProceduralSkyMaterial::get_sky_top_color() const {
- dirty_materials = memnew(SelfList<SkyMaterial>::List);
+ return sky_top_color;
+}
- shader_names = memnew(ShaderNames);
+void ProceduralSkyMaterial::set_sky_horizon_color(const Color &p_sky_horizon) {
- shader_names->placeholder = "placeholder";
+ sky_horizon_color = p_sky_horizon;
+ VS::get_singleton()->material_set_param(_get_material(), "sky_horizon_color", sky_horizon_color.to_linear());
}
+Color ProceduralSkyMaterial::get_sky_horizon_color() const {
-void SkyMaterial::finish_shaders() {
+ return sky_horizon_color;
+}
-#ifndef NO_THREADS
- memdelete(material_mutex);
-#endif
+void ProceduralSkyMaterial::set_sky_curve(float p_curve) {
- memdelete(dirty_materials);
- dirty_materials = NULL;
+ sky_curve = p_curve;
+ VS::get_singleton()->material_set_param(_get_material(), "sky_curve", sky_curve);
+}
+float ProceduralSkyMaterial::get_sky_curve() const {
- memdelete(shader_names);
+ return sky_curve;
}
-void SkyMaterial::_update_shader() {
+void ProceduralSkyMaterial::set_sky_energy(float p_energy) {
- dirty_materials->remove(&element);
+ sky_energy = p_energy;
+ VS::get_singleton()->material_set_param(_get_material(), "sky_energy", sky_energy);
+}
+float ProceduralSkyMaterial::get_sky_energy() const {
+
+ return sky_energy;
+}
- MaterialKey mk = _compute_key();
- if (mk.key == current_key.key)
- return; //no update required in the end
+void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) {
- if (shader_map.has(current_key)) {
- shader_map[current_key].users--;
- if (shader_map[current_key].users == 0) {
- //deallocate shader, as it's no longer in use
- VS::get_singleton()->free(shader_map[current_key].shader);
- shader_map.erase(current_key);
- }
- }
+ ground_bottom_color = p_ground_bottom;
+ VS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color.to_linear());
+}
+Color ProceduralSkyMaterial::get_ground_bottom_color() const {
- current_key = mk;
+ return ground_bottom_color;
+}
- if (shader_map.has(mk)) {
+void ProceduralSkyMaterial::set_ground_horizon_color(const Color &p_ground_horizon) {
- VS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
- shader_map[mk].users++;
- return;
- }
+ ground_horizon_color = p_ground_horizon;
+ VS::get_singleton()->material_set_param(_get_material(), "ground_horizon_color", ground_horizon_color.to_linear());
+}
+Color ProceduralSkyMaterial::get_ground_horizon_color() const {
- //must create a shader!
+ return ground_horizon_color;
+}
- String code = "shader_type sky;\n";
+void ProceduralSkyMaterial::set_ground_curve(float p_curve) {
- ShaderData shader_data;
- shader_data.shader = VS::get_singleton()->shader_create();
- shader_data.users = 1;
+ ground_curve = p_curve;
+ VS::get_singleton()->material_set_param(_get_material(), "ground_curve", ground_curve);
+}
+float ProceduralSkyMaterial::get_ground_curve() const {
- VS::get_singleton()->shader_set_code(shader_data.shader, code);
+ return ground_curve;
+}
- shader_map[mk] = shader_data;
+void ProceduralSkyMaterial::set_ground_energy(float p_energy) {
- VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
+ ground_energy = p_energy;
+ VS::get_singleton()->material_set_param(_get_material(), "ground_energy", ground_energy);
}
+float ProceduralSkyMaterial::get_ground_energy() const {
-void SkyMaterial::flush_changes() {
+ return ground_energy;
+}
- if (material_mutex)
- material_mutex->lock();
+void ProceduralSkyMaterial::set_sun_angle_min(float p_angle) {
- while (dirty_materials->first()) {
+ sun_angle_min = p_angle;
+ VS::get_singleton()->material_set_param(_get_material(), "sun_angle_min", Math::deg2rad(sun_angle_min));
+}
+float ProceduralSkyMaterial::get_sun_angle_min() const {
- dirty_materials->first()->self()->_update_shader();
- }
+ return sun_angle_min;
+}
- if (material_mutex)
- material_mutex->unlock();
+void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) {
+
+ sun_angle_max = p_angle;
+ VS::get_singleton()->material_set_param(_get_material(), "sun_angle_max", Math::deg2rad(sun_angle_max));
+}
+float ProceduralSkyMaterial::get_sun_angle_max() const {
+
+ return sun_angle_max;
}
-void SkyMaterial::_queue_shader_change() {
+void ProceduralSkyMaterial::set_sun_curve(float p_curve) {
- if (material_mutex)
- material_mutex->lock();
+ sun_curve = p_curve;
+ VS::get_singleton()->material_set_param(_get_material(), "sun_curve", sun_curve);
+}
+float ProceduralSkyMaterial::get_sun_curve() const {
- if (!element.in_list()) {
- dirty_materials->add(&element);
- }
+ return sun_curve;
+}
- if (material_mutex)
- material_mutex->unlock();
+bool ProceduralSkyMaterial::_can_do_next_pass() const {
+ return false;
}
-bool SkyMaterial::_is_shader_dirty() const {
+Shader::Mode ProceduralSkyMaterial::get_shader_mode() const {
+
+ return Shader::MODE_SKY;
+}
+
+RID ProceduralSkyMaterial::get_shader_rid() const {
+
+ return shader;
+}
+
+void ProceduralSkyMaterial::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSkyMaterial::set_sky_top_color);
+ ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSkyMaterial::get_sky_top_color);
+
+ ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSkyMaterial::set_sky_horizon_color);
+ ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSkyMaterial::get_sky_horizon_color);
+
+ ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSkyMaterial::set_sky_curve);
+ ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSkyMaterial::get_sky_curve);
- bool dirty = false;
+ ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSkyMaterial::set_sky_energy);
+ ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSkyMaterial::get_sky_energy);
- if (material_mutex)
- material_mutex->lock();
+ ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSkyMaterial::set_ground_bottom_color);
+ ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSkyMaterial::get_ground_bottom_color);
- dirty = element.in_list();
+ ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSkyMaterial::set_ground_horizon_color);
+ ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSkyMaterial::get_ground_horizon_color);
- if (material_mutex)
- material_mutex->unlock();
+ ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSkyMaterial::set_ground_curve);
+ ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSkyMaterial::get_ground_curve);
- return dirty;
+ ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy);
+ ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy);
+
+ ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSkyMaterial::set_sun_angle_min);
+ ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSkyMaterial::get_sun_angle_min);
+
+ ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max);
+ ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max);
+
+ ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSkyMaterial::set_sun_curve);
+ ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSkyMaterial::get_sun_curve);
+
+ 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::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "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::FLOAT, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
+
+ ADD_GROUP("Sun", "sun_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
}
+ProceduralSkyMaterial::ProceduralSkyMaterial() {
+
+ String code = "shader_type sky;\n\n";
+
+ code += "uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);\n";
+ code += "uniform vec4 sky_horizon_color : hint_color = vec4(0.55, 0.69, 0.81, 1.0);\n";
+ code += "uniform float sky_curve : hint_range(0, 1) = 0.09;\n";
+ code += "uniform float sky_energy = 1.0;\n\n";
+ code += "uniform vec4 ground_bottom_color : hint_color = vec4(0.12, 0.12, 0.13, 1.0);\n";
+ code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n";
+ code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n";
+ code += "uniform float ground_energy = 1.0;\n\n";
+ code += "uniform float sun_angle_min = 0.01;\n";
+ code += "uniform float sun_angle_max = 1.0;\n";
+ code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n";
+ code += "const float PI = 3.1415926535897932384626433833;\n\n";
+ code += "void fragment() {\n";
+ code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n";
+ code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n";
+ code += "\tvec3 sky = mix(sky_horizon_color.rgb, sky_top_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / sky_curve), 0.0, 1.0));\n";
+ code += "\tsky *= sky_energy;\n";
+ code += "\tif (LIGHT0_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tif (LIGHT1_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tif (LIGHT2_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tif (LIGHT3_ENABLED) {\n";
+ code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n";
+ code += "\t\tif (sun_angle < sun_angle_min) {\n";
+ code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n";
+ code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
+ code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+ code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
+ code += "\t\t}\n";
+ code += "\t}\n";
+ code += "\tc = (v_angle - (PI * 0.5)) / (PI * 0.5);\n";
+ code += "\tvec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0));\n";
+ code += "\tground *= ground_energy;\n";
+ code += "\tCOLOR = mix(ground, sky, step(0.0, EYEDIR.y));\n";
+ code += "}\n";
+
+ shader = VS::get_singleton()->shader_create();
+
+ VS::get_singleton()->shader_set_code(shader, code);
+
+ VS::get_singleton()->material_set_shader(_get_material(), shader);
+
+ set_sky_top_color(Color(0.35, 0.46, 0.71));
+ set_sky_horizon_color(Color(0.55, 0.69, 0.81));
+ set_sky_curve(0.09);
+ set_sky_energy(1.0);
+
+ set_ground_bottom_color(Color(0.12, 0.12, 0.13));
+ set_ground_horizon_color(Color(0.37, 0.33, 0.31));
+ set_ground_curve(0.02);
+ set_ground_energy(1.0);
+
+ set_sun_angle_min(1.0);
+ set_sun_angle_max(100.0);
+ set_sun_curve(0.05);
+}
-RID SkyMaterial::get_shader_rid() const {
+ProceduralSkyMaterial::~ProceduralSkyMaterial() {
+}
- ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
- return shader_map[current_key].shader;
+/////////////////////////////////////////
+/* PanoramaSkyMaterial */
+
+void PanoramaSkyMaterial::set_panorama(const Ref<Texture2D> &p_panorama) {
+
+ panorama = p_panorama;
+ VS::get_singleton()->material_set_param(_get_material(), "source_panorama", panorama);
}
-void SkyMaterial::_validate_property(PropertyInfo &property) const {
+Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
+
+ return panorama;
+}
+bool PanoramaSkyMaterial::_can_do_next_pass() const {
+ return false;
}
-Shader::Mode SkyMaterial::get_shader_mode() const {
+Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
return Shader::MODE_SKY;
}
-void SkyMaterial::_bind_methods() {
+RID PanoramaSkyMaterial::get_shader_rid() const {
+
+ return shader;
+}
+
+void PanoramaSkyMaterial::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
+ ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
+}
+
+PanoramaSkyMaterial::PanoramaSkyMaterial() {
+ String code = "shader_type sky;\n\n";
+
+ code += "uniform sampler2D source_panorama : filter_linear;\n";
+ code += "void fragment() {\n";
+ code += "\tCOLOR = texture(source_panorama, SKY_COORDS).rgb;\n";
+ code += "}";
+
+ shader = VS::get_singleton()->shader_create();
+
+ VS::get_singleton()->shader_set_code(shader, code);
+
+ VS::get_singleton()->material_set_shader(_get_material(), shader);
+}
+
+PanoramaSkyMaterial::~PanoramaSkyMaterial() {
+ VS::get_singleton()->free(shader);
+ VS::get_singleton()->material_set_shader(_get_material(), RID());
+}
+//////////////////////////////////
+/* PhysicalSkyMaterial */
+
+void PhysicalSkyMaterial::set_rayleigh_coefficient(float p_rayleigh) {
+
+ rayleigh = p_rayleigh;
+ VS::get_singleton()->material_set_param(_get_material(), "rayleigh", rayleigh);
+}
+float PhysicalSkyMaterial::get_rayleigh_coefficient() const {
+
+ return rayleigh;
+}
+
+void PhysicalSkyMaterial::set_rayleigh_color(Color p_rayleigh_color) {
+
+ rayleigh_color = p_rayleigh_color;
+ VS::get_singleton()->material_set_param(_get_material(), "rayleigh_color", rayleigh_color);
+}
+Color PhysicalSkyMaterial::get_rayleigh_color() const {
+
+ return rayleigh_color;
+}
+
+void PhysicalSkyMaterial::set_mie_coefficient(float p_mie) {
+
+ mie = p_mie;
+ VS::get_singleton()->material_set_param(_get_material(), "mie", mie);
+}
+float PhysicalSkyMaterial::get_mie_coefficient() const {
+
+ return mie;
+}
+
+void PhysicalSkyMaterial::set_mie_eccentricity(float p_eccentricity) {
+ mie_eccentricity = p_eccentricity;
+ VS::get_singleton()->material_set_param(_get_material(), "mie_eccentricity", mie_eccentricity);
}
+float PhysicalSkyMaterial::get_mie_eccentricity() const {
-SkyMaterial::SkyMaterial() :
- element(this) {
+ return mie_eccentricity;
+}
+void PhysicalSkyMaterial::set_mie_color(Color p_mie_color) {
- _queue_shader_change();
+ mie_color = p_mie_color;
+ VS::get_singleton()->material_set_param(_get_material(), "mie_color", mie_color);
+}
+Color PhysicalSkyMaterial::get_mie_color() const {
+ return mie_color;
}
-SkyMaterial::~SkyMaterial() {
+void PhysicalSkyMaterial::set_turbidity(float p_turbidity) {
- if (material_mutex)
- material_mutex->lock();
+ turbidity = p_turbidity;
+ VS::get_singleton()->material_set_param(_get_material(), "turbidity", turbidity);
+}
+float PhysicalSkyMaterial::get_turbidity() const {
- if (shader_map.has(current_key)) {
- shader_map[current_key].users--;
- if (shader_map[current_key].users == 0) {
- //deallocate shader, as it's no longer in use
- VS::get_singleton()->free(shader_map[current_key].shader);
- shader_map.erase(current_key);
- }
+ return turbidity;
+}
+
+void PhysicalSkyMaterial::set_sun_disk_scale(float p_sun_disk_scale) {
+
+ sun_disk_scale = p_sun_disk_scale;
+ VS::get_singleton()->material_set_param(_get_material(), "sun_disk_scale", sun_disk_scale);
+}
+float PhysicalSkyMaterial::get_sun_disk_scale() const {
+
+ return sun_disk_scale;
+}
+
+void PhysicalSkyMaterial::set_ground_color(Color p_ground_color) {
+
+ ground_color = p_ground_color;
+ VS::get_singleton()->material_set_param(_get_material(), "ground_color", ground_color);
+}
+Color PhysicalSkyMaterial::get_ground_color() const {
+
+ return ground_color;
+}
+
+void PhysicalSkyMaterial::set_exposure(float p_exposure) {
+
+ exposure = p_exposure;
+ VS::get_singleton()->material_set_param(_get_material(), "exposure", exposure);
+}
+float PhysicalSkyMaterial::get_exposure() const {
+
+ return exposure;
+}
- VS::get_singleton()->material_set_shader(_get_material(), RID());
- }
+void PhysicalSkyMaterial::set_dither_strength(float p_dither_strength) {
+
+ dither_strength = p_dither_strength;
+ VS::get_singleton()->material_set_param(_get_material(), "dither_strength", dither_strength);
+}
+float PhysicalSkyMaterial::get_dither_strength() const {
+
+ return dither_strength;
+}
+
+bool PhysicalSkyMaterial::_can_do_next_pass() const {
+ return false;
+}
+
+Shader::Mode PhysicalSkyMaterial::get_shader_mode() const {
+
+ return Shader::MODE_SKY;
+}
+
+RID PhysicalSkyMaterial::get_shader_rid() const {
+
+ return shader;
+}
+
+void PhysicalSkyMaterial::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_rayleigh_coefficient", "rayleigh"), &PhysicalSkyMaterial::set_rayleigh_coefficient);
+ ClassDB::bind_method(D_METHOD("get_rayleigh_coefficient"), &PhysicalSkyMaterial::get_rayleigh_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_rayleigh_color", "color"), &PhysicalSkyMaterial::set_rayleigh_color);
+ ClassDB::bind_method(D_METHOD("get_rayleigh_color"), &PhysicalSkyMaterial::get_rayleigh_color);
+
+ ClassDB::bind_method(D_METHOD("set_mie_coefficient", "mie"), &PhysicalSkyMaterial::set_mie_coefficient);
+ ClassDB::bind_method(D_METHOD("get_mie_coefficient"), &PhysicalSkyMaterial::get_mie_coefficient);
+
+ ClassDB::bind_method(D_METHOD("set_mie_eccentricity", "eccentricity"), &PhysicalSkyMaterial::set_mie_eccentricity);
+ ClassDB::bind_method(D_METHOD("get_mie_eccentricity"), &PhysicalSkyMaterial::get_mie_eccentricity);
+
+ ClassDB::bind_method(D_METHOD("set_mie_color", "color"), &PhysicalSkyMaterial::set_mie_color);
+ ClassDB::bind_method(D_METHOD("get_mie_color"), &PhysicalSkyMaterial::get_mie_color);
+
+ ClassDB::bind_method(D_METHOD("set_turbidity", "turbidity"), &PhysicalSkyMaterial::set_turbidity);
+ ClassDB::bind_method(D_METHOD("get_turbidity"), &PhysicalSkyMaterial::get_turbidity);
+
+ ClassDB::bind_method(D_METHOD("set_sun_disk_scale", "scale"), &PhysicalSkyMaterial::set_sun_disk_scale);
+ ClassDB::bind_method(D_METHOD("get_sun_disk_scale"), &PhysicalSkyMaterial::get_sun_disk_scale);
+
+ ClassDB::bind_method(D_METHOD("set_ground_color", "color"), &PhysicalSkyMaterial::set_ground_color);
+ ClassDB::bind_method(D_METHOD("get_ground_color"), &PhysicalSkyMaterial::get_ground_color);
+
+ ClassDB::bind_method(D_METHOD("set_exposure", "exposure"), &PhysicalSkyMaterial::set_exposure);
+ ClassDB::bind_method(D_METHOD("get_exposure"), &PhysicalSkyMaterial::get_exposure);
+
+ ClassDB::bind_method(D_METHOD("set_dither_strength", "strength"), &PhysicalSkyMaterial::set_dither_strength);
+ ClassDB::bind_method(D_METHOD("get_dither_strength"), &PhysicalSkyMaterial::get_dither_strength);
+
+ ADD_GROUP("Rayleigh", "rayleigh_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rayleigh_coefficient", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_rayleigh_coefficient", "get_rayleigh_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "rayleigh_color"), "set_rayleigh_color", "get_rayleigh_color");
+
+ ADD_GROUP("Mie", "mie_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mie_coefficient", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_mie_coefficient", "get_mie_coefficient");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mie_eccentricity", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_mie_eccentricity", "get_mie_eccentricity");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "mie_color"), "set_mie_color", "get_mie_color");
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbidity", PROPERTY_HINT_RANGE, "0,1000,0.01"), "set_turbidity", "get_turbidity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_disk_scale", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_disk_scale", "get_sun_disk_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_color"), "set_ground_color", "get_ground_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "exposure", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_exposure", "get_exposure");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dither_strength", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_dither_strength", "get_dither_strength");
+}
+
+PhysicalSkyMaterial::PhysicalSkyMaterial() {
+ String code = "shader_type sky;\n\n";
+
+ code += "uniform float rayleigh : hint_range(0, 64) = 2.0;\n";
+ code += "uniform vec4 rayleigh_color : hint_color = vec4(0.056, 0.14, 0.3, 1.0);\n";
+ code += "uniform float mie : hint_range(0, 1) = 0.005;\n";
+ code += "uniform float mie_eccentricity : hint_range(-1, 1) = 0.8;\n";
+ code += "uniform vec4 mie_color : hint_color = vec4(0.36, 0.56, 0.82, 1.0);\n\n";
+
+ code += "uniform float turbidity : hint_range(0, 1000) = 10.0;\n";
+ code += "uniform float sun_disk_scale : hint_range(0, 360) = 1.0;\n";
+ code += "uniform vec4 ground_color : hint_color = vec4(1.0);\n";
+ code += "uniform float exposure : hint_range(0, 128) = 0.1;\n";
+ code += "uniform float dither_strength : hint_range(0, 10) = 1.0;\n\n";
+
+ code += "const float PI = 3.141592653589793238462643383279502884197169;\n";
+ code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
+
+ code += "// Sun constants\n";
+ code += "const float SOL_SIZE = 0.00872663806;\n";
+ code += "const float SUN_ENERGY = 1000.0;\n\n";
+
+ code += "// optical length at zenith for molecules\n";
+ code += "const float rayleigh_zenith_size = 8.4e3;\n";
+ code += "const float mie_zenith_size = 1.25e3;\n\n";
+
+ code += "float henyey_greenstein(float cos_theta, float g) {\n";
+ code += "\tconst float k = 0.0795774715459;\n";
+ code += "\treturn k * (1.0 - g * g) / (pow(1.0 + g * g - 2.0 * g * cos_theta, 1.5));\n";
+ code += "}\n\n";
+
+ code += "// From: https://www.shadertoy.com/view/4sfGzS credit to iq\n";
+ code += "float hash(vec3 p) {\n";
+ code += "\tp = fract( p * 0.3183099 + 0.1 );\n";
+ code += "\tp *= 17.0;\n";
+ code += "\treturn fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n";
+ code += "}\n\n";
+
+ code += "void fragment() {\n";
+ code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
+ code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
+ code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
+
+ code += "\t// rayleigh coefficients\n";
+ code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
+ code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
+ code += "\t// mie coefficients from Preetham\n";
+ code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
+
+ code += "\t// optical length\n";
+ code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
+ code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
+ code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
+ code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
+
+ code += "\t// light extinction based on thickness of atmosphere\n";
+ code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
+
+ code += "\t// in scattering\n";
+ code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
+
+ code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
+ code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
+
+ code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
+ code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
+
+ code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
+ code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
+ code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
+
+ code += "\t// Hack in the ground color\n";
+ code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
+
+ code += "\t// Solar disk and out-scattering\n";
+ code += "\tfloat sunAngularDiameterCos = cos(SOL_SIZE * sun_disk_scale);\n";
+ code += "\tfloat sunAngularDiameterCos2 = cos(SOL_SIZE * sun_disk_scale*0.5);\n";
+ code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
+ code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
+ code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n";
+
+ code += "\tvec3 color = (Lin + L0) * 0.04;\n";
+ code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
+ code += "\tCOLOR *= exposure;\n";
+ code += "\t// Make optional, eliminates banding\n";
+ code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.008 * dither_strength;\n";
+ code += "}\n";
+
+ shader = VS::get_singleton()->shader_create();
+
+ VS::get_singleton()->shader_set_code(shader, code);
+
+ VS::get_singleton()->material_set_shader(_get_material(), shader);
+
+ set_rayleigh_coefficient(2.0);
+ set_rayleigh_color(Color(0.056, 0.14, 0.3));
+ set_mie_coefficient(0.005);
+ set_mie_eccentricity(0.8);
+ set_mie_color(Color(0.36, 0.56, 0.82));
+ set_turbidity(10.0);
+ set_sun_disk_scale(1.0);
+ set_ground_color(Color(1.0, 1.0, 1.0));
+ set_exposure(0.1);
+ set_dither_strength(1.0);
+}
- if (material_mutex)
- material_mutex->unlock();
+PhysicalSkyMaterial::~PhysicalSkyMaterial() {
+ VS::get_singleton()->free(shader);
+ VS::get_singleton()->material_set_shader(_get_material(), RID());
}
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index 5c8cddb10e..2d0a62e0f6 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -34,98 +34,157 @@
#ifndef SKY_MATERIAL_H
#define SKY_MATERIAL_H
-class SkyMaterial : public Material {
+class ProceduralSkyMaterial : public Material {
- GDCLASS(SkyMaterial, Material);
+ GDCLASS(ProceduralSkyMaterial, Material);
+
+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;
+
+ float sun_angle_min;
+ float sun_angle_max;
+ float sun_curve;
+
+ RID shader;
+
+protected:
+ static void _bind_methods();
+ virtual bool _can_do_next_pass() const;
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_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;
+
+ virtual Shader::Mode get_shader_mode() const;
+ RID get_shader_rid() const;
+
+ ProceduralSkyMaterial();
+ ~ProceduralSkyMaterial();
+};
+
+//////////////////////////////////////////////////////
+/* PanoramaSkyMaterial */
+
+class PanoramaSkyMaterial : public Material {
+ GDCLASS(PanoramaSkyMaterial, Material);
private:
- union MaterialKey {
-
- struct {
- uint32_t texture_mask : 16;
- uint32_t texture_color : 1;
- uint32_t flags : 4;
- uint32_t emission_shape : 2;
- uint32_t trail_size_texture : 1;
- uint32_t trail_color_texture : 1;
- uint32_t invalid_key : 1;
- uint32_t has_emission_color : 1;
- };
-
- uint32_t key;
-
- bool operator<(const MaterialKey &p_key) const {
- return key < p_key.key;
- }
- };
-
- struct ShaderData {
- RID shader;
- int users;
- };
-
- static Map<MaterialKey, ShaderData> shader_map;
-
- MaterialKey current_key;
-
- _FORCE_INLINE_ MaterialKey _compute_key() const {
-
- MaterialKey mk;
- mk.key = 0;
- /*
- for (int i = 0; i < PARAM_MAX; i++) {
- if (tex_parameters[i].is_valid()) {
- mk.texture_mask |= (1 << i);
- }
- }
- for (int i = 0; i < FLAG_MAX; i++) {
- if (flags[i]) {
- mk.flags |= (1 << i);
- }
- }
-
- mk.texture_color = color_ramp.is_valid() ? 1 : 0;
- mk.emission_shape = emission_shape;
- mk.trail_color_texture = trail_color_modifier.is_valid() ? 1 : 0;
- mk.trail_size_texture = trail_size_modifier.is_valid() ? 1 : 0;
- mk.has_emission_color = emission_shape >= EMISSION_SHAPE_POINTS && emission_color_texture.is_valid();
- */
-
- return mk;
- }
-
- static Mutex *material_mutex;
- static SelfList<SkyMaterial>::List *dirty_materials;
-
- struct ShaderNames {
- StringName placeholder;
- };
-
- static ShaderNames *shader_names;
-
- SelfList<SkyMaterial> element;
-
- void _update_shader();
- _FORCE_INLINE_ void _queue_shader_change();
- _FORCE_INLINE_ bool _is_shader_dirty() const;
+ Ref<Texture2D> panorama;
+ RID shader;
protected:
static void _bind_methods();
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual bool _can_do_next_pass() const;
public:
- static void init_shaders();
- static void finish_shaders();
- static void flush_changes();
+ void set_panorama(const Ref<Texture2D> &p_panorama);
+ Ref<Texture2D> get_panorama() const;
+ virtual Shader::Mode get_shader_mode() const;
RID get_shader_rid() const;
+ PanoramaSkyMaterial();
+ ~PanoramaSkyMaterial();
+};
+
+//////////////////////////////////////////////////////
+/* PanoramaSkyMaterial */
+
+class PhysicalSkyMaterial : public Material {
+ GDCLASS(PhysicalSkyMaterial, Material);
+
+private:
+ RID shader;
+
+ float rayleigh;
+ Color rayleigh_color;
+ float mie;
+ float mie_eccentricity;
+ Color mie_color;
+ float turbidity;
+ float sun_disk_scale;
+ Color ground_color;
+ float exposure;
+ float dither_strength;
+
+protected:
+ static void _bind_methods();
+ virtual bool _can_do_next_pass() const;
+
+public:
+ void set_rayleigh_coefficient(float p_rayleigh);
+ float get_rayleigh_coefficient() const;
+
+ void set_rayleigh_color(Color p_rayleigh_color);
+ Color get_rayleigh_color() const;
+
+ void set_turbidity(float p_turbidity);
+ float get_turbidity() const;
+
+ void set_mie_coefficient(float p_mie);
+ float get_mie_coefficient() const;
+
+ void set_mie_eccentricity(float p_eccentricity);
+ float get_mie_eccentricity() const;
+
+ void set_mie_color(Color p_mie_color);
+ Color get_mie_color() const;
+
+ void set_sun_disk_scale(float p_sun_disk_scale);
+ float get_sun_disk_scale() const;
+
+ void set_ground_color(Color p_ground_color);
+ Color get_ground_color() const;
+
+ void set_exposure(float p_exposure);
+ float get_exposure() const;
+
+ void set_dither_strength(float p_dither_strength);
+ float get_dither_strength() const;
+
virtual Shader::Mode get_shader_mode() const;
+ RID get_shader_rid() const;
- SkyMaterial();
- ~SkyMaterial();
+ PhysicalSkyMaterial();
+ ~PhysicalSkyMaterial();
};
#endif /* !SKY_MATERIAL_H */