summaryrefslogtreecommitdiff
path: root/drivers/gles3/storage
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2022-04-29 15:34:01 -0700
committerclayjohn <claynjohn@gmail.com>2022-05-11 21:00:21 -0700
commit3bb8e6a9feb22049310ae0111e57113c08d3292c (patch)
tree9dea569402d9e973ae8b470d09dc049661facab2 /drivers/gles3/storage
parent516ec892b43a89ac19dfa608b9d754f630a646cc (diff)
SkyShaders working
Diffstat (limited to 'drivers/gles3/storage')
-rw-r--r--drivers/gles3/storage/material_storage.cpp239
-rw-r--r--drivers/gles3/storage/material_storage.h49
-rw-r--r--drivers/gles3/storage/mesh_storage.h9
3 files changed, 288 insertions, 9 deletions
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index d14d26346c..0641b4e87b 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1278,13 +1278,13 @@ MaterialStorage::MaterialStorage() {
shader_data_request_func[RS::SHADER_SPATIAL] = nullptr;
shader_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_shader_func;
shader_data_request_func[RS::SHADER_PARTICLES] = nullptr;
- shader_data_request_func[RS::SHADER_SKY] = nullptr;
+ shader_data_request_func[RS::SHADER_SKY] = _create_sky_shader_func;
shader_data_request_func[RS::SHADER_FOG] = nullptr;
material_data_request_func[RS::SHADER_SPATIAL] = nullptr;
material_data_request_func[RS::SHADER_CANVAS_ITEM] = _create_canvas_material_func;
material_data_request_func[RS::SHADER_PARTICLES] = nullptr;
- material_data_request_func[RS::SHADER_SKY] = nullptr;
+ material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func;
material_data_request_func[RS::SHADER_FOG] = nullptr;
static_assert(sizeof(GlobalVariables::Value) == 16);
@@ -1365,7 +1365,7 @@ MaterialStorage::MaterialStorage() {
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["light_only"] = "#define MODE_LIGHT_ONLY\n";
- actions.base_texture_binding_index = 1;
+ actions.base_texture_binding_index = 0;
actions.base_uniform_string = "";
actions.global_buffer_array_variable = "";
@@ -1626,10 +1626,10 @@ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["COLOR"] = "color";
actions.renames["ALPHA"] = "alpha";
actions.renames["EYEDIR"] = "cube_normal";
- actions.renames["POSITION"] = "params.position_multiplier.xyz";
+ actions.renames["POSITION"] = "position";
actions.renames["SKY_COORDS"] = "panorama_coords";
actions.renames["SCREEN_UV"] = "uv";
- actions.renames["TIME"] = "params.time";
+ actions.renames["TIME"] = "time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
@@ -1660,15 +1660,12 @@ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
- actions.custom_samplers["RADIANCE"] = "material_samplers[3]";
actions.usage_defines["HALF_RES_COLOR"] = "\n#define USES_HALF_RES_COLOR\n";
actions.usage_defines["QUARTER_RES_COLOR"] = "\n#define USES_QUARTER_RES_COLOR\n";
actions.render_mode_defines["disable_fog"] = "#define DISABLE_FOG\n";
- actions.sampler_array_name = "material_samplers";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = 1;
- actions.base_uniform_string = "material.";
actions.base_varying_index = 10;
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
@@ -2739,7 +2736,8 @@ void MaterialStorage::material_update_dependency(RID p_material, RendererStorage
}
}
-// Canvas Shader Data
+/* Canvas Shader Data */
+
void CanvasShaderData::set_code(const String &p_code) {
// compile the shader
@@ -2982,4 +2980,227 @@ GLES3::MaterialData *GLES3::_create_canvas_material_func(ShaderData *p_shader) {
return material_data;
}
+////////////////////////////////////////////////////////////////////////////////
+// SKY SHADER
+
+void SkyShaderData::set_code(const String &p_code) {
+ //compile
+
+ code = p_code;
+ valid = false;
+ ubo_size = 0;
+ uniforms.clear();
+
+ if (code.is_empty()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT;
+
+ uses_time = false;
+ uses_half_res = false;
+ uses_quarter_res = false;
+ uses_position = false;
+ uses_light = false;
+
+ actions.render_mode_flags["use_half_res_pass"] = &uses_half_res;
+ actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res;
+
+ actions.usage_flag_pointers["TIME"] = &uses_time;
+ actions.usage_flag_pointers["POSITION"] = &uses_position;
+ actions.usage_flag_pointers["LIGHT0_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
+
+ actions.uniforms = &uniforms;
+
+ Error err = MaterialStorage::get_singleton()->shaders.compiler_sky.compile(RS::SHADER_SKY, code, &actions, path, gen_code);
+ ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
+
+ if (version.is_null()) {
+ version = MaterialStorage::get_singleton()->shaders.sky_shader.version_create();
+ }
+
+#if 0
+ print_line("**compiling shader:");
+ print_line("**defines:\n");
+ for (int i = 0; i < gen_code.defines.size(); i++) {
+ print_line(gen_code.defines[i]);
+ }
+ print_line("\n**uniforms:\n" + gen_code.uniforms);
+ // print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
+ // print_line("\n**vertex_code:\n" + gen_code.vertex);
+ print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
+ print_line("\n**fragment_code:\n" + gen_code.fragment);
+ print_line("\n**light_code:\n" + gen_code.light);
+#endif
+
+ Vector<StringName> texture_uniform_names;
+ for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
+ texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
+ }
+
+ MaterialStorage::get_singleton()->shaders.sky_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
+ ERR_FAIL_COND(!MaterialStorage::get_singleton()->shaders.sky_shader.version_is_valid(version));
+
+ ubo_size = gen_code.uniform_total_size;
+ ubo_offsets = gen_code.uniform_offsets;
+ texture_uniforms = gen_code.texture_uniforms;
+
+ valid = true;
+}
+
+void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
+ if (!p_texture.is_valid()) {
+ if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) {
+ default_texture_params[p_name].erase(p_index);
+
+ if (default_texture_params[p_name].is_empty()) {
+ default_texture_params.erase(p_name);
+ }
+ }
+ } else {
+ if (!default_texture_params.has(p_name)) {
+ default_texture_params[p_name] = Map<int, RID>();
+ }
+ default_texture_params[p_name][p_index] = p_texture;
+ }
+}
+
+void SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+ Map<int, StringName> order;
+
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
+ if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ if (E.value.texture_order >= 0) {
+ order[E.value.texture_order + 100000] = E.key;
+ } else {
+ order[E.value.order] = E.key;
+ }
+ }
+
+ for (const KeyValue<int, StringName> &E : order) {
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
+ pi.name = E.value;
+ p_param_list->push_back(pi);
+ }
+}
+
+void SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const {
+ for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RendererMaterialStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E.value);
+ p.info.name = E.key; //supply name
+ p.index = E.value.instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint);
+ p_param_list->push_back(p);
+ }
+}
+
+bool SkyShaderData::is_param_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+bool SkyShaderData::is_animated() const {
+ return false;
+}
+
+bool SkyShaderData::casts_shadows() const {
+ return false;
+}
+
+Variant SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
+ if (uniforms.has(p_parameter)) {
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint);
+ }
+ return Variant();
+}
+
+RS::ShaderNativeSourceCode SkyShaderData::get_native_source_code() const {
+ return MaterialStorage::get_singleton()->shaders.sky_shader.version_get_native_source_code(version);
+}
+
+SkyShaderData::SkyShaderData() {
+ valid = false;
+}
+
+SkyShaderData::~SkyShaderData() {
+ if (version.is_valid()) {
+ MaterialStorage::get_singleton()->shaders.sky_shader.version_free(version);
+ }
+}
+
+GLES3::ShaderData *GLES3::_create_sky_shader_func() {
+ SkyShaderData *shader_data = memnew(SkyShaderData);
+ return shader_data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Sky material
+
+void SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ return update_parameters_internal(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size);
+}
+
+SkyMaterialData::~SkyMaterialData() {
+}
+GLES3::MaterialData *GLES3::_create_sky_material_func(ShaderData *p_shader) {
+ SkyMaterialData *material_data = memnew(SkyMaterialData);
+ material_data->shader_data = static_cast<SkyShaderData *>(p_shader);
+ //update will happen later anyway so do nothing.
+ return material_data;
+}
+
+void SkyMaterialData::bind_uniforms() {
+ // Bind Material Uniforms
+ glBindBufferBase(GL_UNIFORM_BUFFER, 3, uniform_buffer);
+
+ RID *textures = texture_cache.ptrw();
+ ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_data->texture_uniforms.ptrw();
+ for (int ti = 0; ti < texture_cache.size(); ti++) {
+ Texture *texture = TextureStorage::get_singleton()->get_texture(textures[ti]);
+ glActiveTexture(GL_TEXTURE0 + ti);
+ glBindTexture(target_from_type[texture_uniforms[ti].type], texture->tex_id);
+
+ // Set sampler state here as the same texture can be used in multiple places with different flags
+ // Need to convert sampler state from ShaderLanguage::Texture* to RS::CanvasItemTexture*
+ RS::CanvasItemTextureFilter filter = RS::CanvasItemTextureFilter((int(texture_uniforms[ti].filter) + 1) % RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);
+ RS::CanvasItemTextureRepeat repeat = RS::CanvasItemTextureRepeat((int(texture_uniforms[ti].repeat) + 1) % RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
+ texture->gl_set_filter(filter);
+ texture->gl_set_repeat(repeat);
+ }
+}
+
#endif // !GLES3_ENABLED
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index cc6cbdc152..1a7452f66a 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -200,6 +200,55 @@ struct CanvasMaterialData : public MaterialData {
MaterialData *_create_canvas_material_func(ShaderData *p_shader);
+/* Sky Materials */
+
+struct SkyShaderData : public ShaderData {
+ bool valid;
+ RID version;
+
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String path;
+ String code;
+ Map<StringName, Map<int, RID>> default_texture_params;
+
+ bool uses_time;
+ bool uses_position;
+ bool uses_half_res;
+ bool uses_quarter_res;
+ bool uses_light;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const;
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+ SkyShaderData();
+ virtual ~SkyShaderData();
+};
+
+ShaderData *_create_sky_shader_func();
+
+struct SkyMaterialData : public MaterialData {
+ SkyShaderData *shader_data = nullptr;
+
+ virtual void set_render_priority(int p_priority) {}
+ virtual void set_next_pass(RID p_pass) {}
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual void bind_uniforms();
+ virtual ~SkyMaterialData();
+};
+
+MaterialData *_create_sky_material_func(ShaderData *p_shader);
+
/* Global variable structs */
struct GlobalVariables {
enum {
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index f51ec6edbe..6b0d0c83b2 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -388,6 +388,9 @@ public:
/* MESH INSTANCE API */
+ MeshInstance *get_mesh_instance(RID p_rid) { return mesh_instance_owner.get_or_null(p_rid); };
+ bool owns_mesh_instance(RID p_rid) { return mesh_instance_owner.owns(p_rid); };
+
virtual RID mesh_instance_create(RID p_base) override;
virtual void mesh_instance_free(RID p_rid) override;
virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override;
@@ -431,6 +434,9 @@ public:
/* MULTIMESH API */
+ MultiMesh *get_multimesh(RID p_rid) { return multimesh_owner.get_or_null(p_rid); };
+ bool owns_multimesh(RID p_rid) { return multimesh_owner.owns(p_rid); };
+
virtual RID multimesh_allocate() override;
virtual void multimesh_initialize(RID p_rid) override;
virtual void multimesh_free(RID p_rid) override;
@@ -483,6 +489,9 @@ public:
/* SKELETON API */
+ Skeleton *get_skeleton(RID p_rid) { return skeleton_owner.get_or_null(p_rid); };
+ bool owns_skeleton(RID p_rid) { return skeleton_owner.owns(p_rid); };
+
virtual RID skeleton_allocate() override;
virtual void skeleton_initialize(RID p_rid) override;
virtual void skeleton_free(RID p_rid) override;