summaryrefslogtreecommitdiffstats
path: root/drivers/gles3/storage/material_storage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/storage/material_storage.cpp')
-rw-r--r--drivers/gles3/storage/material_storage.cpp478
1 files changed, 371 insertions, 107 deletions
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index 26441fc726..d413c2b00e 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -34,6 +34,7 @@
#include "config.h"
#include "material_storage.h"
+#include "particles_storage.h"
#include "texture_storage.h"
#include "drivers/gles3/rasterizer_canvas_gles3.h"
@@ -89,7 +90,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored
}
} else {
- int v = value;
+ uint32_t v = value;
gui[0] = v & 1 ? 1 : 0;
gui[1] = v & 2 ? 1 : 0;
}
@@ -116,7 +117,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[j + 3] = 0; // ignored
}
} else {
- int v = value;
+ uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0;
@@ -145,7 +146,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
}
} else {
- int v = value;
+ uint32_t v = value;
gui[0] = (v & 1) ? 1 : 0;
gui[1] = (v & 2) ? 1 : 0;
gui[2] = (v & 4) ? 1 : 0;
@@ -714,7 +715,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
Projection v = value;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- gui[i * 4 + j] = v.matrix[i][j];
+ gui[i * 4 + j] = v.columns[i][j];
}
}
}
@@ -728,7 +729,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data;
- *gui = value[0].boolean ? 1 : 0;
+ gui[0] = value[0].boolean ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC2: {
uint32_t *gui = (uint32_t *)data;
@@ -897,7 +898,9 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
case ShaderLanguage::TYPE_BVEC3:
case ShaderLanguage::TYPE_IVEC3:
case ShaderLanguage::TYPE_UVEC3:
- case ShaderLanguage::TYPE_VEC3:
+ case ShaderLanguage::TYPE_VEC3: {
+ memset(data, 0, 12 * p_array_size);
+ } break;
case ShaderLanguage::TYPE_BVEC4:
case ShaderLanguage::TYPE_IVEC4:
case ShaderLanguage::TYPE_UVEC4:
@@ -978,7 +981,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag
if (gv) {
index = gv->buffer_index;
} else {
- WARN_PRINT("Shader uses global uniform '" + E.key + "', but it was removed at some point. Material will not display correctly.");
+ WARN_PRINT("Shader uses global parameter '" + E.key + "', but it was removed at some point. Material will not display correctly.");
}
uint32_t offset = p_uniform_offsets[E.value.order];
@@ -1083,13 +1086,19 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
Vector<RID> textures;
+ if (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
+ p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
+ p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+ continue;
+ }
+
if (p_texture_uniforms[i].global) {
uses_global_textures = true;
GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name);
if (v) {
if (v->buffer_index >= 0) {
- WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!.");
+ WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!.");
} else {
HashMap<StringName, uint64_t>::Iterator E = used_global_textures.find(uniform_name);
@@ -1104,7 +1113,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
}
} else {
- WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly.");
+ WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly.");
}
} else {
HashMap<StringName, Variant>::ConstIterator V = p_parameters.find(uniform_name);
@@ -1334,13 +1343,13 @@ MaterialStorage::MaterialStorage() {
shader_data_request_func[RS::SHADER_SPATIAL] = _create_scene_shader_func;
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_PARTICLES] = _create_particles_shader_func;
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] = _create_scene_material_func;
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_PARTICLES] = _create_particles_material_func;
material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func;
material_data_request_func[RS::SHADER_FOG] = nullptr;
@@ -1373,9 +1382,9 @@ MaterialStorage::MaterialStorage() {
actions.renames["POINT_SIZE"] = "gl_PointSize";
actions.renames["MODEL_MATRIX"] = "model_matrix";
- actions.renames["CANVAS_MATRIX"] = "canvas_data.canvas_transform";
- actions.renames["SCREEN_MATRIX"] = "canvas_data.screen_transform";
- actions.renames["TIME"] = "canvas_data.time";
+ actions.renames["CANVAS_MATRIX"] = "canvas_transform";
+ actions.renames["SCREEN_MATRIX"] = "screen_transform";
+ actions.renames["TIME"] = "time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
@@ -1387,19 +1396,21 @@ MaterialStorage::MaterialStorage() {
actions.renames["NORMAL_MAP"] = "normal_map";
actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions.renames["TEXTURE"] = "color_texture";
- actions.renames["TEXTURE_PIXEL_SIZE"] = "draw_data.color_texture_pixel_size";
+ actions.renames["TEXTURE_PIXEL_SIZE"] = "color_texture_pixel_size";
actions.renames["NORMAL_TEXTURE"] = "normal_texture";
actions.renames["SPECULAR_SHININESS_TEXTURE"] = "specular_texture";
actions.renames["SPECULAR_SHININESS"] = "specular_shininess";
actions.renames["SCREEN_UV"] = "screen_uv";
actions.renames["SCREEN_TEXTURE"] = "screen_texture";
- actions.renames["SCREEN_PIXEL_SIZE"] = "canvas_data.screen_pixel_size";
+ actions.renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size";
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["POINT_COORD"] = "gl_PointCoord";
actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
actions.renames["VERTEX_ID"] = "gl_VertexIndex";
actions.renames["LIGHT_POSITION"] = "light_position";
+ actions.renames["LIGHT_DIRECTION"] = "light_direction";
+ actions.renames["LIGHT_IS_DIRECTIONAL"] = "is_directional";
actions.renames["LIGHT_COLOR"] = "light_color";
actions.renames["LIGHT_ENERGY"] = "light_energy";
actions.renames["LIGHT"] = "light";
@@ -1450,8 +1461,8 @@ MaterialStorage::MaterialStorage() {
actions.renames["UV2"] = "uv2_interp";
actions.renames["COLOR"] = "color_interp";
actions.renames["POINT_SIZE"] = "gl_PointSize";
- actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
- actions.renames["VERTEX_ID"] = "gl_VertexIndex";
+ actions.renames["INSTANCE_ID"] = "gl_InstanceID";
+ actions.renames["VERTEX_ID"] = "gl_VertexID";
actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold";
actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale";
@@ -1492,9 +1503,9 @@ MaterialStorage::MaterialStorage() {
actions.renames["POINT_COORD"] = "gl_PointCoord";
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "color_buffer";
- actions.renames["DEPTH_TEXTURE"] = "depth_buffer";
- actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
+ //actions.renames["SCREEN_TEXTURE"] = "color_buffer"; //Not implemented in 3D yet.
+ //actions.renames["DEPTH_TEXTURE"] = "depth_buffer"; // Not implemented in 3D yet.
+ //actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; // Not implemented in 3D yet
actions.renames["DEPTH"] = "gl_FragDepth";
actions.renames["OUTPUT_IS_SRGB"] = "true";
actions.renames["FOG"] = "fog";
@@ -1603,32 +1614,32 @@ MaterialStorage::MaterialStorage() {
{
// Setup Particles compiler
- /*
-ShaderCompiler::DefaultIdentifierActions actions;
- actions.renames["COLOR"] = "PARTICLE.color";
- actions.renames["VELOCITY"] = "PARTICLE.velocity";
+ ShaderCompiler::DefaultIdentifierActions actions;
+
+ actions.renames["COLOR"] = "out_color";
+ actions.renames["VELOCITY"] = "out_velocity_flags.xyz";
//actions.renames["MASS"] = "mass"; ?
actions.renames["ACTIVE"] = "particle_active";
actions.renames["RESTART"] = "restart";
- actions.renames["CUSTOM"] = "PARTICLE.custom";
- for (int i = 0; i < ParticlesShader::MAX_USERDATAS; i++) {
+ actions.renames["CUSTOM"] = "out_custom";
+ for (int i = 0; i < PARTICLES_MAX_USERDATAS; i++) {
String udname = "USERDATA" + itos(i + 1);
- actions.renames[udname] = "PARTICLE.userdata" + itos(i + 1);
+ actions.renames[udname] = "out_userdata" + itos(i + 1);
actions.usage_defines[udname] = "#define USERDATA" + itos(i + 1) + "_USED\n";
}
- actions.renames["TRANSFORM"] = "PARTICLE.xform";
- actions.renames["TIME"] = "frame_history.data[0].time";
+ actions.renames["TRANSFORM"] = "xform";
+ actions.renames["TIME"] = "time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
- actions.renames["LIFETIME"] = "params.lifetime";
+ actions.renames["LIFETIME"] = "lifetime";
actions.renames["DELTA"] = "local_delta";
actions.renames["NUMBER"] = "particle_number";
actions.renames["INDEX"] = "index";
//actions.renames["GRAVITY"] = "current_gravity";
- actions.renames["EMISSION_TRANSFORM"] = "FRAME.emission_transform";
- actions.renames["RANDOM_SEED"] = "FRAME.random_seed";
+ actions.renames["EMISSION_TRANSFORM"] = "emission_transform";
+ actions.renames["RANDOM_SEED"] = "random_seed";
actions.renames["FLAG_EMIT_POSITION"] = "EMISSION_FLAG_HAS_POSITION";
actions.renames["FLAG_EMIT_ROT_SCALE"] = "EMISSION_FLAG_HAS_ROTATION_SCALE";
actions.renames["FLAG_EMIT_VELOCITY"] = "EMISSION_FLAG_HAS_VELOCITY";
@@ -1648,20 +1659,12 @@ ShaderCompiler::DefaultIdentifierActions actions;
actions.render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n";
actions.render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n";
actions.render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n";
- actions.render_mode_defines["collision_use_scale"] = "#define USE_COLLISON_SCALE\n";
-
- actions.sampler_array_name = "material_samplers";
- actions.base_texture_binding_index = 1;
- actions.texture_layout_set = 3;
- actions.base_uniform_string = "material.";
- actions.base_varying_index = 10;
+ actions.render_mode_defines["collision_use_scale"] = "#define USE_COLLISION_SCALE\n";
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
- actions.global_buffer_array_variable = "global_shader_uniforms.data";
- particles_shader.compiler.initialize(actions);
- */
+ shaders.compiler_particles.initialize(actions);
}
{
@@ -1709,6 +1712,7 @@ ShaderCompiler::DefaultIdentifierActions actions;
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.render_mode_defines["use_debanding"] = "#define USE_DEBANDING\n";
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
@@ -1756,7 +1760,7 @@ int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) {
return -1;
}
-void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) {
+void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderParameterType p_type, const Variant &p_value) {
switch (p_type) {
case RS::GLOBAL_VAR_TYPE_BOOL: {
GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index];
@@ -2049,7 +2053,7 @@ void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index,
}
}
-void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) {
+void MaterialStorage::global_shader_parameter_add(const StringName &p_name, RS::GlobalShaderParameterType p_type, const Variant &p_value) {
ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name));
GlobalShaderUniforms::Variable gv;
gv.type = p_type;
@@ -2087,7 +2091,7 @@ void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::Gl
global_shader_uniforms.variables[p_name] = gv;
}
-void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) {
+void MaterialStorage::global_shader_parameter_remove(const StringName &p_name) {
if (!global_shader_uniforms.variables.has(p_name)) {
return;
}
@@ -2103,7 +2107,7 @@ void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) {
global_shader_uniforms.variables.erase(p_name);
}
-Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const {
+Vector<StringName> MaterialStorage::global_shader_parameter_get_list() const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
}
@@ -2116,7 +2120,7 @@ Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const {
return names;
}
-void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) {
+void MaterialStorage::global_shader_parameter_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name));
GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name];
gv.value = p_value;
@@ -2137,7 +2141,7 @@ void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const
}
}
-void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) {
+void MaterialStorage::global_shader_parameter_set_override(const StringName &p_name, const Variant &p_value) {
if (!global_shader_uniforms.variables.has(p_name)) {
return; //variable may not exist
}
@@ -2168,7 +2172,7 @@ void MaterialStorage::global_shader_uniform_set_override(const StringName &p_nam
}
}
-Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const {
+Variant MaterialStorage::global_shader_parameter_get(const StringName &p_name) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance.");
}
@@ -2180,7 +2184,7 @@ Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) con
return global_shader_uniforms.variables[p_name].value;
}
-RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const {
+RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type_internal(const StringName &p_name) const {
if (!global_shader_uniforms.variables.has(p_name)) {
return RS::GLOBAL_VAR_TYPE_MAX;
}
@@ -2188,22 +2192,22 @@ RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_inte
return global_shader_uniforms.variables[p_name].type;
}
-RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const {
+RS::GlobalShaderParameterType MaterialStorage::global_shader_parameter_get_type(const StringName &p_name) const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance.");
}
- return global_shader_uniform_get_type_internal(p_name);
+ return global_shader_parameter_get_type_internal(p_name);
}
-void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) {
+void MaterialStorage::global_shader_parameters_load_settings(bool p_load_textures) {
List<PropertyInfo> settings;
ProjectSettings::get_singleton()->get_property_list(&settings);
for (const PropertyInfo &E : settings) {
if (E.name.begins_with("shader_globals/")) {
StringName name = E.name.get_slice("/", 1);
- Dictionary d = ProjectSettings::get_singleton()->get(E.name);
+ Dictionary d = GLOBAL_GET(E.name);
ERR_CONTINUE(!d.has("type"));
ERR_CONTINUE(!d.has("value"));
@@ -2241,11 +2245,11 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures)
"samplerCube",
};
- RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
+ RS::GlobalShaderParameterType gvtype = RS::GLOBAL_VAR_TYPE_MAX;
for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) {
if (global_var_type_names[i] == type) {
- gvtype = RS::GlobalShaderUniformType(i);
+ gvtype = RS::GlobalShaderParameterType(i);
break;
}
}
@@ -2269,23 +2273,23 @@ void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures)
if (global_shader_uniforms.variables.has(name)) {
//has it, update it
- global_shader_uniform_set(name, value);
+ global_shader_parameter_set(name, value);
} else {
- global_shader_uniform_add(name, gvtype, value);
+ global_shader_parameter_add(name, gvtype, value);
}
}
}
}
-void MaterialStorage::global_shader_uniforms_clear() {
+void MaterialStorage::global_shader_parameters_clear() {
global_shader_uniforms.variables.clear();
}
-GLuint MaterialStorage::global_shader_uniforms_get_uniform_buffer() const {
+GLuint MaterialStorage::global_shader_parameters_get_uniform_buffer() const {
return global_shader_uniforms.buffer;
}
-int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) {
+int32_t MaterialStorage::global_shader_parameters_instance_allocate(RID p_instance) {
ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1);
int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway
@@ -2294,7 +2298,7 @@ int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance
return pos;
}
-void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) {
+void MaterialStorage::global_shader_parameters_instance_free(RID p_instance) {
ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance));
int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance];
if (pos >= 0) {
@@ -2303,7 +2307,7 @@ void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) {
global_shader_uniforms.instance_buffer_pos.erase(p_instance);
}
-void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+void MaterialStorage::global_shader_parameters_instance_update(RID p_instance, int p_index, const Variant &p_value, int p_flags_count) {
if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
@@ -2313,7 +2317,9 @@ void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int
return; //again, not allocated, ignore
}
ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES);
- ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
+
+ Variant::Type value_type = p_value.get_type();
+ ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = {
ShaderLanguage::TYPE_MAX, //nil
@@ -2339,9 +2345,24 @@ void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int
ShaderLanguage::TYPE_VEC4 //color
};
- ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()];
+ ShaderLanguage::DataType datatype = ShaderLanguage::TYPE_MAX;
+ if (value_type == Variant::INT && p_flags_count > 0) {
+ switch (p_flags_count) {
+ case 1:
+ datatype = ShaderLanguage::TYPE_BVEC2;
+ break;
+ case 2:
+ datatype = ShaderLanguage::TYPE_BVEC3;
+ break;
+ case 3:
+ datatype = ShaderLanguage::TYPE_BVEC4;
+ break;
+ }
+ } else {
+ datatype = datatype_from_value[value_type];
+ }
- ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported
+ ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(value_type)); //anything greater not supported
pos += p_index;
@@ -2442,8 +2463,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
RS::ShaderMode new_mode;
if (mode_string == "canvas_item") {
new_mode = RS::SHADER_CANVAS_ITEM;
- //} else if (mode_string == "particles") {
- // new_mode = RS::SHADER_PARTICLES;
+ } else if (mode_string == "particles") {
+ new_mode = RS::SHADER_PARTICLES;
} else if (mode_string == "spatial") {
new_mode = RS::SHADER_SPATIAL;
} else if (mode_string == "sky") {
@@ -2492,7 +2513,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
if (shader->data) {
for (const KeyValue<StringName, HashMap<int, RID>> &E : shader->default_texture_parameter) {
for (const KeyValue<int, RID> &E2 : E.value) {
- shader->data->set_default_texture_param(E.key, E2.value, E2.key);
+ shader->data->set_default_texture_parameter(E.key, E2.value, E2.key);
}
}
}
@@ -2514,6 +2535,9 @@ void MaterialStorage::shader_set_path_hint(RID p_shader, const String &p_path) {
ERR_FAIL_COND(!shader);
shader->path_hint = p_path;
+ if (shader->data) {
+ shader->data->set_path_hint(p_path);
+ }
}
String MaterialStorage::shader_get_code(RID p_shader) const {
@@ -2522,7 +2546,7 @@ String MaterialStorage::shader_get_code(RID p_shader) const {
return shader->code;
}
-void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
+void MaterialStorage::get_shader_parameter_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
GLES3::Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
if (shader->data) {
@@ -2530,7 +2554,7 @@ void MaterialStorage::shader_get_shader_uniform_list(RID p_shader, List<Property
}
}
-void MaterialStorage::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
+void MaterialStorage::shader_set_default_texture_parameter(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
GLES3::Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND(!shader);
@@ -2549,7 +2573,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin
}
}
if (shader->data) {
- shader->data->set_default_texture_param(p_name, p_texture, p_index);
+ shader->data->set_default_texture_parameter(p_name, p_texture, p_index);
}
for (Material *E : shader->owners) {
Material *material = E;
@@ -2557,7 +2581,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin
}
}
-RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
+RID MaterialStorage::shader_get_default_texture_parameter(RID p_shader, const StringName &p_name, int p_index) const {
const GLES3::Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, RID());
if (shader->default_texture_parameter.has(p_name) && shader->default_texture_parameter[p_name].has(p_index)) {
@@ -2567,7 +2591,7 @@ RID MaterialStorage::shader_get_default_texture_param(RID p_shader, const String
return RID();
}
-Variant MaterialStorage::shader_get_param_default(RID p_shader, const StringName &p_param) const {
+Variant MaterialStorage::shader_get_parameter_default(RID p_shader, const StringName &p_param) const {
Shader *shader = shader_owner.get_or_null(p_shader);
ERR_FAIL_COND_V(!shader, Variant());
if (shader->data) {
@@ -2687,7 +2711,7 @@ void MaterialStorage::material_set_param(RID p_material, const StringName &p_par
}
if (material->shader && material->shader->data) { //shader is valid
- bool is_texture = material->shader->data->is_param_texture(p_param);
+ bool is_texture = material->shader->data->is_parameter_texture(p_param);
_material_queue_update(material, !is_texture, is_texture);
} else {
_material_queue_update(material, true, true);
@@ -2758,14 +2782,14 @@ bool MaterialStorage::material_casts_shadows(RID p_material) {
return true; //by default everything casts shadows
}
-void MaterialStorage::material_get_instance_shader_uniforms(RID p_material, List<InstanceShaderParam> *r_parameters) {
+void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
GLES3::Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
if (material->shader && material->shader->data) {
material->shader->data->get_instance_param_list(r_parameters);
if (material->next_pass.is_valid()) {
- material_get_instance_shader_uniforms(material->next_pass, r_parameters);
+ material_get_instance_shader_parameters(material->next_pass, r_parameters);
}
}
}
@@ -2781,6 +2805,10 @@ void MaterialStorage::material_update_dependency(RID p_material, DependencyTrack
/* Canvas Shader Data */
+void CanvasShaderData::set_path_hint(const String &p_path) {
+ path = p_path;
+}
+
void CanvasShaderData::set_code(const String &p_code) {
// compile the shader
@@ -2789,6 +2817,7 @@ void CanvasShaderData::set_code(const String &p_code) {
ubo_size = 0;
uniforms.clear();
uses_screen_texture = false;
+ uses_screen_texture_mipmaps = false;
uses_sdf = false;
uses_time = false;
@@ -2799,7 +2828,6 @@ void CanvasShaderData::set_code(const String &p_code) {
ShaderCompiler::GeneratedCode gen_code;
int blend_modei = BLEND_MODE_MIX;
- uses_screen_texture = false;
ShaderCompiler::IdentifierActions actions;
actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
@@ -2826,6 +2854,7 @@ void CanvasShaderData::set_code(const String &p_code) {
}
blend_mode = BlendMode(blend_modei);
+ uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
#if 0
print_line("**compiling shader:");
@@ -2833,12 +2862,16 @@ void CanvasShaderData::set_code(const String &p_code) {
for (int i = 0; i < gen_code.defines.size(); i++) {
print_line(gen_code.defines[i]);
}
+
+ HashMap<String, String>::Iterator el = gen_code.code.begin();
+ while (el) {
+ print_line("\n**code " + el->key + ":\n" + el->value);
+ ++el;
+ }
+
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);
+ print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
+ print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
Vector<StringName> texture_uniform_names;
@@ -2856,7 +2889,7 @@ void CanvasShaderData::set_code(const String &p_code) {
valid = true;
}
-void CanvasShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
+void CanvasShaderData::set_default_texture_parameter(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);
@@ -2877,7 +2910,10 @@ void CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list)
HashMap<int, StringName> order;
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
- if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL ||
+ E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
+ E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
+ E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
continue;
}
if (E.value.texture_order >= 0) {
@@ -2924,7 +2960,7 @@ void CanvasShaderData::get_instance_param_list(List<RendererMaterialStorage::Ins
}
}
-bool CanvasShaderData::is_param_texture(const StringName &p_param) const {
+bool CanvasShaderData::is_parameter_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -2971,7 +3007,7 @@ GLES3::ShaderData *GLES3::_create_canvas_shader_func() {
}
void CanvasMaterialData::update_parameters(const HashMap<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);
+ 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);
}
void CanvasMaterialData::bind_uniforms() {
@@ -3007,6 +3043,10 @@ GLES3::MaterialData *GLES3::_create_canvas_material_func(ShaderData *p_shader) {
////////////////////////////////////////////////////////////////////////////////
// SKY SHADER
+void SkyShaderData::set_path_hint(const String &p_path) {
+ path = p_path;
+}
+
void SkyShaderData::set_code(const String &p_code) {
//compile
@@ -3070,12 +3110,16 @@ void SkyShaderData::set_code(const String &p_code) {
for (int i = 0; i < gen_code.defines.size(); i++) {
print_line(gen_code.defines[i]);
}
+
+ HashMap<String, String>::Iterator el = gen_code.code.begin();
+ while (el) {
+ print_line("\n**code " + el->key + ":\n" + el->value);
+ ++el;
+ }
+
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);
+ print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
+ print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
Vector<StringName> texture_uniform_names;
@@ -3093,7 +3137,7 @@ void SkyShaderData::set_code(const String &p_code) {
valid = true;
}
-void SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
+void SkyShaderData::set_default_texture_parameter(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);
@@ -3162,7 +3206,7 @@ void SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::Instan
}
}
-bool SkyShaderData::is_param_texture(const StringName &p_param) const {
+bool SkyShaderData::is_parameter_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -3211,7 +3255,7 @@ GLES3::ShaderData *GLES3::_create_sky_shader_func() {
void SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
uniform_set_updated = true;
- 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);
+ 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() {
@@ -3246,6 +3290,10 @@ void SkyMaterialData::bind_uniforms() {
////////////////////////////////////////////////////////////////////////////////
// Scene SHADER
+void SceneShaderData::set_path_hint(const String &p_path) {
+ path = p_path;
+}
+
void SceneShaderData::set_code(const String &p_code) {
//compile
@@ -3253,7 +3301,6 @@ void SceneShaderData::set_code(const String &p_code) {
valid = false;
ubo_size = 0;
uniforms.clear();
- uses_screen_texture = false;
if (code.is_empty()) {
return; //just invalid, but no error
@@ -3319,6 +3366,9 @@ void SceneShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip;
+ // Use alpha clip pipeline for alpha hash/dither.
+ // This prevents sorting issues inherent to alpha blending and allows such materials to cast shadows.
+ actions.usage_flag_pointers["ALPHA_HASH_SCALE"] = &uses_alpha_clip;
actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
@@ -3378,6 +3428,9 @@ void SceneShaderData::set_code(const String &p_code) {
vertex_input_mask |= uses_custom3 << 8;
vertex_input_mask |= uses_bones << 9;
vertex_input_mask |= uses_weights << 10;
+ uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+ uses_vertex_time = gen_code.uses_vertex_time;
+ uses_fragment_time = gen_code.uses_fragment_time;
#if 0
print_line("**compiling shader:");
@@ -3386,11 +3439,10 @@ void SceneShaderData::set_code(const String &p_code) {
print_line(gen_code.defines[i]);
}
- Map<String, String>::Element *el = gen_code.code.front();
+ HashMap<String, String>::Iterator el = gen_code.code.begin();
while (el) {
- print_line("\n**code " + el->key() + ":\n" + el->value());
-
- el = el->next();
+ print_line("\n**code " + el->key + ":\n" + el->value);
+ ++el;
}
print_line("\n**uniforms:\n" + gen_code.uniforms);
@@ -3418,7 +3470,7 @@ void SceneShaderData::set_code(const String &p_code) {
valid = true;
}
-void SceneShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
+void SceneShaderData::set_default_texture_parameter(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);
@@ -3439,7 +3491,10 @@ void SceneShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list)
RBMap<int, StringName> order;
for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
- if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
+ if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL ||
+ E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
+ E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
+ E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
continue;
}
@@ -3487,7 +3542,7 @@ void SceneShaderData::get_instance_param_list(List<RendererMaterialStorage::Inst
}
}
-bool SceneShaderData::is_param_texture(const StringName &p_param) const {
+bool SceneShaderData::is_parameter_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -3496,11 +3551,15 @@ bool SceneShaderData::is_param_texture(const StringName &p_param) const {
}
bool SceneShaderData::is_animated() const {
- return false;
+ return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex);
}
bool SceneShaderData::casts_shadows() const {
- return false;
+ bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture;
+ bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha;
+ bool has_alpha = has_base_alpha || uses_blend_alpha;
+
+ return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED));
}
Variant SceneShaderData::get_default_parameter(const StringName &p_parameter) const {
@@ -3541,7 +3600,7 @@ void SceneMaterialData::set_next_pass(RID p_pass) {
}
void SceneMaterialData::update_parameters(const HashMap<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);
+ 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);
}
SceneMaterialData::~SceneMaterialData() {
@@ -3574,4 +3633,209 @@ void SceneMaterialData::bind_uniforms() {
}
}
+/* Particles SHADER */
+
+void ParticlesShaderData::set_path_hint(const String &p_path) {
+ path = p_path;
+}
+
+void ParticlesShaderData::set_code(const String &p_code) {
+ //compile
+
+ code = p_code;
+ valid = false;
+ ubo_size = 0;
+ uniforms.clear();
+ uses_collision = false;
+
+ if (code.is_empty()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["start"] = ShaderCompiler::STAGE_VERTEX;
+ actions.entry_point_stages["process"] = ShaderCompiler::STAGE_VERTEX;
+
+ actions.usage_flag_pointers["COLLIDED"] = &uses_collision;
+
+ userdata_count = 0;
+ for (uint32_t i = 0; i < PARTICLES_MAX_USERDATAS; i++) {
+ userdatas_used[i] = false;
+ actions.usage_flag_pointers["USERDATA" + itos(i + 1)] = &userdatas_used[i];
+ }
+
+ actions.uniforms = &uniforms;
+
+ Error err = MaterialStorage::get_singleton()->shaders.compiler_particles.compile(RS::SHADER_PARTICLES, code, &actions, path, gen_code);
+ ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
+
+ if (version.is_null()) {
+ version = MaterialStorage::get_singleton()->shaders.particles_process_shader.version_create();
+ }
+
+ for (uint32_t i = 0; i < PARTICLES_MAX_USERDATAS; i++) {
+ if (userdatas_used[i]) {
+ userdata_count++;
+ }
+ }
+
+ 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.particles_process_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.particles_process_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 ParticlesShaderData::set_default_texture_parameter(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] = HashMap<int, RID>();
+ }
+ default_texture_params[p_name][p_index] = p_texture;
+ }
+}
+
+void ParticlesShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) const {
+ HashMap<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;
+ }
+ }
+
+ String last_group;
+ for (const KeyValue<int, StringName> &E : order) {
+ String group = uniforms[E.value].group;
+ if (!uniforms[E.value].subgroup.is_empty()) {
+ group += "::" + uniforms[E.value].subgroup;
+ }
+
+ if (group != last_group) {
+ PropertyInfo pi;
+ pi.usage = PROPERTY_USAGE_GROUP;
+ pi.name = group;
+ p_param_list->push_back(pi);
+
+ last_group = group;
+ }
+
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]);
+ pi.name = E.value;
+ p_param_list->push_back(pi);
+ }
+}
+
+void ParticlesShaderData::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 ParticlesShaderData::is_parameter_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+bool ParticlesShaderData::is_animated() const {
+ return false;
+}
+
+bool ParticlesShaderData::casts_shadows() const {
+ return false;
+}
+
+Variant ParticlesShaderData::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 ParticlesShaderData::get_native_source_code() const {
+ return MaterialStorage::get_singleton()->shaders.particles_process_shader.version_get_native_source_code(version);
+}
+
+ParticlesShaderData::~ParticlesShaderData() {
+ if (version.is_valid()) {
+ MaterialStorage::get_singleton()->shaders.particles_process_shader.version_free(version);
+ }
+}
+
+GLES3::ShaderData *GLES3::_create_particles_shader_func() {
+ ParticlesShaderData *shader_data = memnew(ParticlesShaderData);
+ return shader_data;
+}
+
+void ParticleProcessMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ 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);
+}
+
+ParticleProcessMaterialData::~ParticleProcessMaterialData() {
+}
+
+GLES3::MaterialData *GLES3::_create_particles_material_func(ShaderData *p_shader) {
+ ParticleProcessMaterialData *material_data = memnew(ParticleProcessMaterialData);
+ material_data->shader_data = static_cast<ParticlesShaderData *>(p_shader);
+ //update will happen later anyway so do nothing.
+ return material_data;
+}
+
+void ParticleProcessMaterialData::bind_uniforms() {
+ // Bind Material Uniforms
+ glBindBufferBase(GL_UNIFORM_BUFFER, GLES3::PARTICLES_MATERIAL_UNIFORM_LOCATION, 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_TEXTURE1 + ti); // Start at GL_TEXTURE1 becuase texture slot 0 is reserved for the heightmap texture.
+ 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