Merge pull request #55551 from brennengreen/panorama-sky-filtering
Add filtering property to PanoramaSkyMaterial and switch from static shader to shader cache
This commit is contained in:
commit
1cff9a2e49
|
@ -11,6 +11,9 @@
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="filter" type="bool" setter="set_filtering_enabled" getter="is_filtering_enabled" default="true">
|
||||||
|
A boolean value to determine if the background texture should be filtered or not.
|
||||||
|
</member>
|
||||||
<member name="panorama" type="Texture2D" setter="set_panorama" getter="get_panorama">
|
<member name="panorama" type="Texture2D" setter="set_panorama" getter="get_panorama">
|
||||||
[Texture2D] to be applied to the [PanoramaSkyMaterial].
|
[Texture2D] to be applied to the [PanoramaSkyMaterial].
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -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()) {
|
if (shader_cache[0].is_valid()) {
|
||||||
RS::get_singleton()->free(shader);
|
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()) {
|
if (shader_cache[0].is_null()) {
|
||||||
shader = RS::get_singleton()->shader_create();
|
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).
|
// Add a comment to describe the shader origin (useful when converting to ShaderMaterial).
|
||||||
RS::get_singleton()->shader_set_code(shader, R"(
|
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 : %s, hint_albedo;
|
||||||
uniform sampler2D source_panorama : filter_linear, 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();
|
||||||
|
|
|
@ -110,10 +110,12 @@ private:
|
||||||
Ref<Texture2D> panorama;
|
Ref<Texture2D> panorama;
|
||||||
|
|
||||||
static Mutex shader_mutex;
|
static Mutex shader_mutex;
|
||||||
static RID shader;
|
static RID shader_cache[2];
|
||||||
static void _update_shader();
|
static void _update_shader();
|
||||||
mutable bool shader_set = false;
|
mutable bool shader_set = false;
|
||||||
|
|
||||||
|
bool filter = true;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
@ -121,6 +123,9 @@ public:
|
||||||
void set_panorama(const Ref<Texture2D> &p_panorama);
|
void set_panorama(const Ref<Texture2D> &p_panorama);
|
||||||
Ref<Texture2D> get_panorama() const;
|
Ref<Texture2D> get_panorama() const;
|
||||||
|
|
||||||
|
void set_filtering_enabled(bool p_enabled);
|
||||||
|
bool is_filtering_enabled() const;
|
||||||
|
|
||||||
virtual Shader::Mode get_shader_mode() const override;
|
virtual Shader::Mode get_shader_mode() const override;
|
||||||
virtual RID get_shader_rid() const override;
|
virtual RID get_shader_rid() const override;
|
||||||
virtual RID get_rid() const override;
|
virtual RID get_rid() const override;
|
||||||
|
|
Loading…
Reference in New Issue