mirror of
https://github.com/godotengine/godot.git
synced 2025-01-30 21:33:18 +08:00
Make Sky initialize shaders only once
* Create the shader on demand. * Makes sure compilation happens only once, then shader is cached. * Speeds up scene loading times. * Speeds up editor initialization.
This commit is contained in:
parent
71f8253579
commit
67e5715dbf
@ -1085,6 +1085,10 @@ void unregister_scene_types() {
|
|||||||
BaseMaterial3D::finish_shaders();
|
BaseMaterial3D::finish_shaders();
|
||||||
#endif // _3D_DISABLED
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
|
PhysicalSkyMaterial::cleanup_shader();
|
||||||
|
PanoramaSkyMaterial::cleanup_shader();
|
||||||
|
ProceduralSkyMaterial::cleanup_shader();
|
||||||
|
|
||||||
ParticlesMaterial::finish_shaders();
|
ParticlesMaterial::finish_shaders();
|
||||||
CanvasItemMaterial::finish_shaders();
|
CanvasItemMaterial::finish_shaders();
|
||||||
ColorPicker::finish_shaders();
|
ColorPicker::finish_shaders();
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
#include "sky_material.h"
|
#include "sky_material.h"
|
||||||
|
|
||||||
|
Mutex ProceduralSkyMaterial::shader_mutex;
|
||||||
|
RID ProceduralSkyMaterial::shader;
|
||||||
|
|
||||||
void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
|
void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
|
||||||
sky_top_color = p_sky_top;
|
sky_top_color = p_sky_top;
|
||||||
RS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
|
RS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
|
||||||
@ -128,7 +131,17 @@ Shader::Mode ProceduralSkyMaterial::get_shader_mode() const {
|
|||||||
return Shader::MODE_SKY;
|
return Shader::MODE_SKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID ProceduralSkyMaterial::get_rid() const {
|
||||||
|
_update_shader();
|
||||||
|
if (!shader_set) {
|
||||||
|
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||||
|
shader_set = true;
|
||||||
|
}
|
||||||
|
return _get_material();
|
||||||
|
}
|
||||||
|
|
||||||
RID ProceduralSkyMaterial::get_shader_rid() const {
|
RID ProceduralSkyMaterial::get_shader_rid() const {
|
||||||
|
_update_shader();
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,10 +193,18 @@ void ProceduralSkyMaterial::_bind_methods() {
|
|||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
|
||||||
}
|
}
|
||||||
|
|
||||||
ProceduralSkyMaterial::ProceduralSkyMaterial() {
|
void ProceduralSkyMaterial::cleanup_shader() {
|
||||||
shader = RS::get_singleton()->shader_create();
|
if (shader.is_valid()) {
|
||||||
|
RS::get_singleton()->free(shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RS::get_singleton()->shader_set_code(shader, R"(
|
void ProceduralSkyMaterial::_update_shader() {
|
||||||
|
shader_mutex.lock();
|
||||||
|
if (shader.is_null()) {
|
||||||
|
shader = RS::get_singleton()->shader_create();
|
||||||
|
|
||||||
|
RS::get_singleton()->shader_set_code(shader, R"(
|
||||||
shader_type sky;
|
shader_type sky;
|
||||||
|
|
||||||
uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);
|
uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);
|
||||||
@ -250,9 +271,11 @@ void sky() {
|
|||||||
COLOR = mix(ground, sky, step(0.0, EYEDIR.y));
|
COLOR = mix(ground, sky, step(0.0, EYEDIR.y));
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
}
|
||||||
|
shader_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
ProceduralSkyMaterial::ProceduralSkyMaterial() {
|
||||||
|
|
||||||
set_sky_top_color(Color(0.35, 0.46, 0.71));
|
set_sky_top_color(Color(0.35, 0.46, 0.71));
|
||||||
set_sky_horizon_color(Color(0.55, 0.69, 0.81));
|
set_sky_horizon_color(Color(0.55, 0.69, 0.81));
|
||||||
set_sky_curve(0.09);
|
set_sky_curve(0.09);
|
||||||
@ -268,7 +291,6 @@ void sky() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProceduralSkyMaterial::~ProceduralSkyMaterial() {
|
ProceduralSkyMaterial::~ProceduralSkyMaterial() {
|
||||||
RS::get_singleton()->free(shader);
|
|
||||||
RS::get_singleton()->material_set_shader(_get_material(), RID());
|
RS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +315,17 @@ Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
|
|||||||
return Shader::MODE_SKY;
|
return Shader::MODE_SKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID PanoramaSkyMaterial::get_rid() const {
|
||||||
|
_update_shader();
|
||||||
|
if (!shader_set) {
|
||||||
|
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||||
|
shader_set = true;
|
||||||
|
}
|
||||||
|
return _get_material();
|
||||||
|
}
|
||||||
|
|
||||||
RID PanoramaSkyMaterial::get_shader_rid() const {
|
RID PanoramaSkyMaterial::get_shader_rid() const {
|
||||||
|
_update_shader();
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,10 +336,21 @@ void PanoramaSkyMaterial::_bind_methods() {
|
|||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
PanoramaSkyMaterial::PanoramaSkyMaterial() {
|
Mutex PanoramaSkyMaterial::shader_mutex;
|
||||||
shader = RS::get_singleton()->shader_create();
|
RID PanoramaSkyMaterial::shader;
|
||||||
|
|
||||||
RS::get_singleton()->shader_set_code(shader, R"(
|
void PanoramaSkyMaterial::cleanup_shader() {
|
||||||
|
if (shader.is_valid()) {
|
||||||
|
RS::get_singleton()->free(shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanoramaSkyMaterial::_update_shader() {
|
||||||
|
shader_mutex.lock();
|
||||||
|
if (shader.is_null()) {
|
||||||
|
shader = RS::get_singleton()->shader_create();
|
||||||
|
|
||||||
|
RS::get_singleton()->shader_set_code(shader, R"(
|
||||||
shader_type sky;
|
shader_type sky;
|
||||||
|
|
||||||
uniform sampler2D source_panorama : filter_linear;
|
uniform sampler2D source_panorama : filter_linear;
|
||||||
@ -316,12 +359,15 @@ void sky() {
|
|||||||
COLOR = texture(source_panorama, SKY_COORDS).rgb;
|
COLOR = texture(source_panorama, SKY_COORDS).rgb;
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
shader_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
PanoramaSkyMaterial::PanoramaSkyMaterial() {
|
||||||
}
|
}
|
||||||
|
|
||||||
PanoramaSkyMaterial::~PanoramaSkyMaterial() {
|
PanoramaSkyMaterial::~PanoramaSkyMaterial() {
|
||||||
RS::get_singleton()->free(shader);
|
|
||||||
RS::get_singleton()->material_set_shader(_get_material(), RID());
|
RS::get_singleton()->material_set_shader(_get_material(), RID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,10 +482,23 @@ Shader::Mode PhysicalSkyMaterial::get_shader_mode() const {
|
|||||||
return Shader::MODE_SKY;
|
return Shader::MODE_SKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID PhysicalSkyMaterial::get_rid() const {
|
||||||
|
_update_shader();
|
||||||
|
if (!shader_set) {
|
||||||
|
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
||||||
|
shader_set = true;
|
||||||
|
}
|
||||||
|
return _get_material();
|
||||||
|
}
|
||||||
|
|
||||||
RID PhysicalSkyMaterial::get_shader_rid() const {
|
RID PhysicalSkyMaterial::get_shader_rid() const {
|
||||||
|
_update_shader();
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mutex PhysicalSkyMaterial::shader_mutex;
|
||||||
|
RID PhysicalSkyMaterial::shader;
|
||||||
|
|
||||||
void PhysicalSkyMaterial::_bind_methods() {
|
void PhysicalSkyMaterial::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_rayleigh_coefficient", "rayleigh"), &PhysicalSkyMaterial::set_rayleigh_coefficient);
|
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("get_rayleigh_coefficient"), &PhysicalSkyMaterial::get_rayleigh_coefficient);
|
||||||
@ -491,10 +550,18 @@ void PhysicalSkyMaterial::_bind_methods() {
|
|||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "night_sky", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_night_sky", "get_night_sky");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "night_sky", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_night_sky", "get_night_sky");
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalSkyMaterial::PhysicalSkyMaterial() {
|
void PhysicalSkyMaterial::cleanup_shader() {
|
||||||
shader = RS::get_singleton()->shader_create();
|
if (shader.is_valid()) {
|
||||||
|
RS::get_singleton()->free(shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RS::get_singleton()->shader_set_code(shader, R"(
|
void PhysicalSkyMaterial::_update_shader() {
|
||||||
|
shader_mutex.lock();
|
||||||
|
if (shader.is_null()) {
|
||||||
|
shader = RS::get_singleton()->shader_create();
|
||||||
|
|
||||||
|
RS::get_singleton()->shader_set_code(shader, R"(
|
||||||
shader_type sky;
|
shader_type sky;
|
||||||
|
|
||||||
uniform float rayleigh : hint_range(0, 64) = 2.0;
|
uniform float rayleigh : hint_range(0, 64) = 2.0;
|
||||||
@ -588,9 +655,12 @@ void sky() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
RS::get_singleton()->material_set_shader(_get_material(), shader);
|
shader_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicalSkyMaterial::PhysicalSkyMaterial() {
|
||||||
set_rayleigh_coefficient(2.0);
|
set_rayleigh_coefficient(2.0);
|
||||||
set_rayleigh_color(Color(0.056, 0.14, 0.3));
|
set_rayleigh_color(Color(0.056, 0.14, 0.3));
|
||||||
set_mie_coefficient(0.005);
|
set_mie_coefficient(0.005);
|
||||||
@ -604,5 +674,4 @@ void sky() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PhysicalSkyMaterial::~PhysicalSkyMaterial() {
|
PhysicalSkyMaterial::~PhysicalSkyMaterial() {
|
||||||
RS::get_singleton()->free(shader);
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,10 @@ private:
|
|||||||
float sun_angle_max;
|
float sun_angle_max;
|
||||||
float sun_curve;
|
float sun_curve;
|
||||||
|
|
||||||
RID shader;
|
static Mutex shader_mutex;
|
||||||
|
static RID shader;
|
||||||
|
static void _update_shader();
|
||||||
|
mutable bool shader_set = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -90,6 +93,9 @@ public:
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
static void cleanup_shader();
|
||||||
|
|
||||||
ProceduralSkyMaterial();
|
ProceduralSkyMaterial();
|
||||||
~ProceduralSkyMaterial();
|
~ProceduralSkyMaterial();
|
||||||
@ -103,7 +109,11 @@ class PanoramaSkyMaterial : public Material {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<Texture2D> panorama;
|
Ref<Texture2D> panorama;
|
||||||
RID shader;
|
|
||||||
|
static Mutex shader_mutex;
|
||||||
|
static RID shader;
|
||||||
|
static void _update_shader();
|
||||||
|
mutable bool shader_set = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -115,6 +125,9 @@ public:
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
static void cleanup_shader();
|
||||||
|
|
||||||
PanoramaSkyMaterial();
|
PanoramaSkyMaterial();
|
||||||
~PanoramaSkyMaterial();
|
~PanoramaSkyMaterial();
|
||||||
@ -127,7 +140,8 @@ class PhysicalSkyMaterial : public Material {
|
|||||||
GDCLASS(PhysicalSkyMaterial, Material);
|
GDCLASS(PhysicalSkyMaterial, Material);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RID shader;
|
static Mutex shader_mutex;
|
||||||
|
static RID shader;
|
||||||
|
|
||||||
float rayleigh;
|
float rayleigh;
|
||||||
Color rayleigh_color;
|
Color rayleigh_color;
|
||||||
@ -140,6 +154,8 @@ private:
|
|||||||
float exposure;
|
float exposure;
|
||||||
float dither_strength;
|
float dither_strength;
|
||||||
Ref<Texture2D> night_sky;
|
Ref<Texture2D> night_sky;
|
||||||
|
static void _update_shader();
|
||||||
|
mutable bool shader_set = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@ -182,6 +198,9 @@ public:
|
|||||||
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;
|
||||||
|
|
||||||
|
static void cleanup_shader();
|
||||||
|
virtual RID get_rid() const override;
|
||||||
|
|
||||||
PhysicalSkyMaterial();
|
PhysicalSkyMaterial();
|
||||||
~PhysicalSkyMaterial();
|
~PhysicalSkyMaterial();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user