Add shader cache and filter variable to PanoramaSkyMaterial

This commit is contained in:
Brennen Green 2022-01-14 20:42:25 -05:00
parent c1e78f749e
commit 0695440124
3 changed files with 44 additions and 15 deletions

View File

@ -11,6 +11,9 @@
<tutorials>
</tutorials>
<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">
[Texture2D] to be applied to the [PanoramaSkyMaterial].
</member>

View File

@ -308,14 +308,30 @@ Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
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 {
return Shader::MODE_SKY;
}
RID PanoramaSkyMaterial::get_rid() const {
_update_shader();
// Don't compile shaders until first use, then compile both
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;
}
return _get_material();
@ -323,42 +339,47 @@ RID PanoramaSkyMaterial::get_rid() const {
RID PanoramaSkyMaterial::get_shader_rid() const {
_update_shader();
return shader;
return shader_cache[int(filter)];
}
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);
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::BOOL, "filter"), "set_filtering_enabled", "is_filtering_enabled");
}
Mutex PanoramaSkyMaterial::shader_mutex;
RID PanoramaSkyMaterial::shader;
RID PanoramaSkyMaterial::shader_cache[2];
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() {
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.
shader_type sky;
uniform sampler2D source_panorama : filter_linear, hint_albedo;
uniform sampler2D source_panorama : %s, hint_albedo;
void sky() {
COLOR = texture(source_panorama, SKY_COORDS).rgb;
}
)");
)",
i ? "filter_linear" : "filter_nearest"));
}
}
shader_mutex.unlock();

View File

@ -110,10 +110,12 @@ private:
Ref<Texture2D> panorama;
static Mutex shader_mutex;
static RID shader;
static RID shader_cache[2];
static void _update_shader();
mutable bool shader_set = false;
bool filter = true;
protected:
static void _bind_methods();
@ -121,6 +123,9 @@ public:
void set_panorama(const Ref<Texture2D> &p_panorama);
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 RID get_shader_rid() const override;
virtual RID get_rid() const override;