|
@@ -308,14 +308,30 @@ Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
|
|
return panorama;
|
|
return panorama;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void PanoramaSkyMaterial::set_filtering_enabled(bool p_enabled) {
|
|
|
|
+ filter = p_enabled;
|
|
|
|
+ notify_property_list_changed();
|
|
|
|
+ _update_shader();
|
|
|
|
+ // Only set if shader already compiled
|
|
|
|
+ if (shader_set) {
|
|
|
|
+ RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(filter)]);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool PanoramaSkyMaterial::is_filtering_enabled() const {
|
|
|
|
+ return filter;
|
|
|
|
+}
|
|
|
|
+
|
|
Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
|
|
Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
|
|
return Shader::MODE_SKY;
|
|
return Shader::MODE_SKY;
|
|
}
|
|
}
|
|
|
|
|
|
RID PanoramaSkyMaterial::get_rid() const {
|
|
RID PanoramaSkyMaterial::get_rid() const {
|
|
_update_shader();
|
|
_update_shader();
|
|
|
|
+ // Don't compile shaders until first use, then compile both
|
|
if (!shader_set) {
|
|
if (!shader_set) {
|
|
- RS::get_singleton()->material_set_shader(_get_material(), shader);
|
|
|
|
|
|
+ RS::get_singleton()->material_set_shader(_get_material(), shader_cache[1 - int(filter)]);
|
|
|
|
+ RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(filter)]);
|
|
shader_set = true;
|
|
shader_set = true;
|
|
}
|
|
}
|
|
return _get_material();
|
|
return _get_material();
|
|
@@ -323,42 +339,47 @@ RID PanoramaSkyMaterial::get_rid() const {
|
|
|
|
|
|
RID PanoramaSkyMaterial::get_shader_rid() const {
|
|
RID PanoramaSkyMaterial::get_shader_rid() const {
|
|
_update_shader();
|
|
_update_shader();
|
|
- return shader;
|
|
|
|
|
|
+ return shader_cache[int(filter)];
|
|
}
|
|
}
|
|
|
|
|
|
void PanoramaSkyMaterial::_bind_methods() {
|
|
void PanoramaSkyMaterial::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
|
|
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
|
|
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
|
|
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
|
|
|
|
|
|
|
|
+ ClassDB::bind_method(D_METHOD("set_filtering_enabled", "enabled"), &PanoramaSkyMaterial::set_filtering_enabled);
|
|
|
|
+ ClassDB::bind_method(D_METHOD("is_filtering_enabled"), &PanoramaSkyMaterial::is_filtering_enabled);
|
|
|
|
+
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama");
|
|
|
|
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter"), "set_filtering_enabled", "is_filtering_enabled");
|
|
}
|
|
}
|
|
|
|
|
|
Mutex PanoramaSkyMaterial::shader_mutex;
|
|
Mutex PanoramaSkyMaterial::shader_mutex;
|
|
-RID PanoramaSkyMaterial::shader;
|
|
|
|
|
|
+RID PanoramaSkyMaterial::shader_cache[2];
|
|
|
|
|
|
void PanoramaSkyMaterial::cleanup_shader() {
|
|
void PanoramaSkyMaterial::cleanup_shader() {
|
|
- if (shader.is_valid()) {
|
|
|
|
- RS::get_singleton()->free(shader);
|
|
|
|
|
|
+ if (shader_cache[0].is_valid()) {
|
|
|
|
+ RS::get_singleton()->free(shader_cache[0]);
|
|
|
|
+ RS::get_singleton()->free(shader_cache[1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PanoramaSkyMaterial::_update_shader() {
|
|
void PanoramaSkyMaterial::_update_shader() {
|
|
shader_mutex.lock();
|
|
shader_mutex.lock();
|
|
- if (shader.is_null()) {
|
|
|
|
- shader = RS::get_singleton()->shader_create();
|
|
|
|
|
|
+ if (shader_cache[0].is_null()) {
|
|
|
|
+ for (int i = 0; i < 2; i++) {
|
|
|
|
+ shader_cache[i] = RS::get_singleton()->shader_create();
|
|
|
|
|
|
- // Add a comment to describe the shader origin (useful when converting to ShaderMaterial).
|
|
|
|
- RS::get_singleton()->shader_set_code(shader, R"(
|
|
|
|
|
|
+ // Add a comment to describe the shader origin (useful when converting to ShaderMaterial).
|
|
|
|
+ RS::get_singleton()->shader_set_code(shader_cache[i], vformat(R"(
|
|
// NOTE: Shader automatically converted from )" VERSION_NAME " " VERSION_FULL_CONFIG R"('s PanoramaSkyMaterial.
|
|
// NOTE: Shader automatically converted from )" VERSION_NAME " " VERSION_FULL_CONFIG R"('s PanoramaSkyMaterial.
|
|
-
|
|
|
|
shader_type sky;
|
|
shader_type sky;
|
|
-
|
|
|
|
-uniform sampler2D source_panorama : filter_linear, hint_albedo;
|
|
|
|
-
|
|
|
|
|
|
+uniform sampler2D source_panorama : %s, hint_albedo;
|
|
void sky() {
|
|
void sky() {
|
|
COLOR = texture(source_panorama, SKY_COORDS).rgb;
|
|
COLOR = texture(source_panorama, SKY_COORDS).rgb;
|
|
}
|
|
}
|
|
-)");
|
|
|
|
|
|
+)",
|
|
|
|
+ i ? "filter_linear" : "filter_nearest"));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
shader_mutex.unlock();
|
|
shader_mutex.unlock();
|