Browse Source

Merge pull request #53914 from Chaosus/shader_default_texture_param

Rémi Verschelde 3 years ago
parent
commit
a54bd6e868
28 changed files with 199 additions and 106 deletions
  1. 4 0
      doc/classes/RenderingServer.xml
  2. 4 0
      doc/classes/Shader.xml
  3. 21 13
      drivers/gles3/rasterizer_storage_gles3.cpp
  4. 3 3
      drivers/gles3/rasterizer_storage_gles3.h
  5. 3 1
      editor/plugins/visual_shader_editor_plugin.cpp
  6. 21 13
      scene/resources/shader.cpp
  7. 3 3
      scene/resources/shader.h
  8. 3 1
      scene/resources/visual_shader.cpp
  9. 1 1
      scene/resources/visual_shader.h
  10. 6 6
      scene/resources/visual_shader_nodes.cpp
  11. 2 2
      scene/resources/visual_shader_particle_nodes.cpp
  12. 2 2
      servers/rendering/rasterizer_dummy.h
  13. 12 3
      servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
  14. 2 2
      servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
  15. 12 3
      servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
  16. 2 2
      servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
  17. 12 3
      servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
  18. 2 2
      servers/rendering/renderer_rd/renderer_canvas_render_rd.h
  19. 12 3
      servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
  20. 2 2
      servers/rendering/renderer_rd/renderer_scene_render_rd.h
  21. 12 3
      servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
  22. 2 2
      servers/rendering/renderer_rd/renderer_scene_sky_rd.h
  23. 40 20
      servers/rendering/renderer_rd/renderer_storage_rd.cpp
  24. 8 8
      servers/rendering/renderer_rd/renderer_storage_rd.h
  25. 2 2
      servers/rendering/renderer_storage.h
  26. 2 2
      servers/rendering/rendering_server_default.h
  27. 2 2
      servers/rendering_server.cpp
  28. 2 2
      servers/rendering_server.h

+ 4 - 0
doc/classes/RenderingServer.xml

@@ -2661,8 +2661,10 @@
 			<return type="RID" />
 			<argument index="0" name="shader" type="RID" />
 			<argument index="1" name="param" type="StringName" />
+			<argument index="2" name="index" type="int" default="0" />
 			<description>
 				Returns a default texture from a shader searched by name.
+				[b]Note:[/b] If the sampler array is used use [code]index[/code] to access the specified texture.
 			</description>
 		</method>
 		<method name="shader_get_param_default" qualifiers="const">
@@ -2684,8 +2686,10 @@
 			<argument index="0" name="shader" type="RID" />
 			<argument index="1" name="param" type="StringName" />
 			<argument index="2" name="texture" type="RID" />
+			<argument index="3" name="index" type="int" default="0" />
 			<description>
 				Sets a shader's default texture. Overwrites the texture given by name.
+				[b]Note:[/b] If the sampler array is used use [code]index[/code] to access the specified texture.
 			</description>
 		</method>
 		<method name="shadows_quality_set">

+ 4 - 0
doc/classes/Shader.xml

@@ -13,9 +13,11 @@
 		<method name="get_default_texture_param" qualifiers="const">
 			<return type="Texture2D" />
 			<argument index="0" name="param" type="StringName" />
+			<argument index="1" name="index" type="int" default="0" />
 			<description>
 				Returns the texture that is set as default for the specified parameter.
 				[b]Note:[/b] [code]param[/code] must match the name of the uniform in the code exactly.
+				[b]Note:[/b] If the sampler array is used use [code]index[/code] to access the specified texture.
 			</description>
 		</method>
 		<method name="get_mode" qualifiers="const">
@@ -36,9 +38,11 @@
 			<return type="void" />
 			<argument index="0" name="param" type="StringName" />
 			<argument index="1" name="texture" type="Texture2D" />
+			<argument index="2" name="index" type="int" default="0" />
 			<description>
 				Sets the default texture to be used with a texture uniform. The default is used if a texture is not set in the [ShaderMaterial].
 				[b]Note:[/b] [code]param[/code] must match the name of the uniform in the code exactly.
+				[b]Note:[/b] If the sampler array is used use [code]index[/code] to access the specified texture.
 			</description>
 		</method>
 	</methods>

+ 21 - 13
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -1871,31 +1871,38 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
 	}
 }
 
-void RasterizerStorageGLES3::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
+void RasterizerStorageGLES3::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
 	Shader *shader = shader_owner.get_or_null(p_shader);
 	ERR_FAIL_COND(!shader);
 	ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture));
 
-	if (p_texture.is_valid()) {
-		shader->default_textures[p_name] = p_texture;
+	if (!p_texture.is_valid()) {
+		if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
+			shader->default_textures[p_name].erase(p_index);
+
+			if (shader->default_textures[p_name].is_empty()) {
+				shader->default_textures.erase(p_name);
+			}
+		}
 	} else {
-		shader->default_textures.erase(p_name);
+		if (!shader->default_textures.has(p_name)) {
+			shader->default_textures[p_name] = Map<int, RID>();
+		}
+		shader->default_textures[p_name][p_index] = p_texture;
 	}
 
 	_shader_make_dirty(shader);
 }
 
-RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const {
+RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
 	const Shader *shader = shader_owner.get_or_null(p_shader);
 	ERR_FAIL_COND_V(!shader, RID());
 
-	const Map<StringName, RID>::Element *E = shader->default_textures.find(p_name);
-
-	if (!E) {
-		return RID();
+	if (shader->default_textures.has(p_name) && shader->default_textures[p_name].has(p_index)) {
+		return shader->default_textures[p_name][p_index];
 	}
 
-	return E->get();
+	return RID();
 }
 
 void RasterizerStorageGLES3::shader_add_custom_define(RID p_shader, const String &p_define) {
@@ -2195,10 +2202,11 @@ void RasterizerStorageGLES3::_update_material(Material *p_material) {
 			}
 
 			if (!texture.is_valid()) {
-				Map<StringName, RID>::Element *W = p_material->shader->default_textures.find(E->key());
+				Map<StringName, Map<int, RID>>::Element *W = p_material->shader->default_textures.find(E->key());
 
-				if (W) {
-					texture = W->get();
+				// TODO: make texture uniform array properly works with GLES3
+				if (W && W->get().has(0)) {
+					texture = W->get()[0];
 				}
 			}
 

+ 3 - 3
drivers/gles3/rasterizer_storage_gles3.h

@@ -580,7 +580,7 @@ public:
 
 		SelfList<Shader> dirty_list;
 
-		Map<StringName, RID> default_textures;
+		Map<StringName, Map<int, RID>> default_textures;
 
 		Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
 
@@ -706,8 +706,8 @@ public:
 	String shader_get_code(RID p_shader) const override;
 	void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override;
 
-	void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) override;
-	RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const override;
+	void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override;
+	RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override;
 
 	RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
 

+ 3 - 1
editor/plugins/visual_shader_editor_plugin.cpp

@@ -5217,7 +5217,9 @@ void VisualShaderNodePortPreview::_shader_changed() {
 	preview_shader.instantiate();
 	preview_shader->set_code(shader_code);
 	for (int i = 0; i < default_textures.size(); i++) {
-		preview_shader->set_default_texture_param(default_textures[i].name, default_textures[i].param);
+		for (int j = 0; j < default_textures[i].params.size(); j++) {
+			preview_shader->set_default_texture_param(default_textures[i].name, default_textures[i].params[j], j);
+		}
 	}
 
 	Ref<ShaderMaterial> material;

+ 21 - 13
scene/resources/shader.cpp

@@ -97,28 +97,36 @@ RID Shader::get_rid() const {
 	return shader;
 }
 
-void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture) {
+void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index) {
 	if (p_texture.is_valid()) {
-		default_textures[p_param] = p_texture;
-		RS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid());
+		if (!default_textures.has(p_param)) {
+			default_textures[p_param] = Map<int, Ref<Texture2D>>();
+		}
+		default_textures[p_param][p_index] = p_texture;
+		RS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid(), p_index);
 	} else {
-		default_textures.erase(p_param);
-		RS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID());
+		if (default_textures.has(p_param) && default_textures[p_param].has(p_index)) {
+			default_textures[p_param].erase(p_index);
+
+			if (default_textures[p_param].is_empty()) {
+				default_textures.erase(p_param);
+			}
+		}
+		RS::get_singleton()->shader_set_default_texture_param(shader, p_param, RID(), p_index);
 	}
 
 	emit_changed();
 }
 
-Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) const {
-	if (default_textures.has(p_param)) {
-		return default_textures[p_param];
-	} else {
-		return Ref<Texture2D>();
+Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param, int p_index) const {
+	if (default_textures.has(p_param) && default_textures[p_param].has(p_index)) {
+		return default_textures[p_param][p_index];
 	}
+	return Ref<Texture2D>();
 }
 
 void Shader::get_default_texture_param_list(List<StringName> *r_textures) const {
-	for (const KeyValue<StringName, Ref<Texture2D>> &E : default_textures) {
+	for (const KeyValue<StringName, Map<int, Ref<Texture2D>>> &E : default_textures) {
 		r_textures->push_back(E.key);
 	}
 }
@@ -140,8 +148,8 @@ void Shader::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_code", "code"), &Shader::set_code);
 	ClassDB::bind_method(D_METHOD("get_code"), &Shader::get_code);
 
-	ClassDB::bind_method(D_METHOD("set_default_texture_param", "param", "texture"), &Shader::set_default_texture_param);
-	ClassDB::bind_method(D_METHOD("get_default_texture_param", "param"), &Shader::get_default_texture_param);
+	ClassDB::bind_method(D_METHOD("set_default_texture_param", "param", "texture", "index"), &Shader::set_default_texture_param, DEFVAL(0));
+	ClassDB::bind_method(D_METHOD("get_default_texture_param", "param", "index"), &Shader::get_default_texture_param, DEFVAL(0));
 
 	ClassDB::bind_method(D_METHOD("has_param", "name"), &Shader::has_param);
 

+ 3 - 3
scene/resources/shader.h

@@ -59,7 +59,7 @@ private:
 	// conversion fast and save memory.
 	mutable bool params_cache_dirty = true;
 	mutable Map<StringName, StringName> params_cache; //map a shader param to a material param..
-	Map<StringName, Ref<Texture2D>> default_textures;
+	Map<StringName, Map<int, Ref<Texture2D>>> default_textures;
 
 	virtual void _update_shader() const; //used for visual shader
 protected:
@@ -75,8 +75,8 @@ public:
 	void get_param_list(List<PropertyInfo> *p_params) const;
 	bool has_param(const StringName &p_param) const;
 
-	void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture);
-	Ref<Texture2D> get_default_texture_param(const StringName &p_param) const;
+	void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index = 0);
+	Ref<Texture2D> get_default_texture_param(const StringName &p_param, int p_index = 0) const;
 	void get_default_texture_param_list(List<StringName> *r_textures) const;
 
 	virtual bool is_text_shader() const;

+ 3 - 1
scene/resources/visual_shader.cpp

@@ -1962,7 +1962,9 @@ void VisualShader::_update_shader() const {
 
 	const_cast<VisualShader *>(this)->set_code(final_code);
 	for (int i = 0; i < default_tex_params.size(); i++) {
-		const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param);
+		for (int j = 0; j < default_tex_params[i].params.size(); j++) {
+			const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].params[j], j);
+		}
 	}
 	if (previous_code != final_code) {
 		const_cast<VisualShader *>(this)->emit_signal(SNAME("changed"));

+ 1 - 1
scene/resources/visual_shader.h

@@ -70,7 +70,7 @@ public:
 
 	struct DefaultTextureParam {
 		StringName name;
-		Ref<Texture2D> param;
+		List<Ref<Texture2D>> params;
 	};
 
 private:

+ 6 - 6
scene/resources/visual_shader_nodes.cpp

@@ -497,7 +497,7 @@ String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const {
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp;
 	dtp.name = make_unique_id(p_type, p_id, "tex");
-	dtp.param = texture;
+	dtp.params[0] = texture;
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp);
 	return ret;
@@ -895,7 +895,7 @@ String VisualShaderNodeCurveTexture::generate_code(Shader::Mode p_mode, VisualSh
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp;
 	dtp.name = make_unique_id(p_type, p_id, "curve");
-	dtp.param = texture;
+	dtp.params[0] = texture;
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp);
 	return ret;
@@ -980,7 +980,7 @@ String VisualShaderNodeCurveXYZTexture::generate_code(Shader::Mode p_mode, Visua
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveXYZTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp;
 	dtp.name = make_unique_id(p_type, p_id, "curve3d");
-	dtp.param = texture;
+	dtp.params[0] = texture;
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp);
 	return ret;
@@ -1162,7 +1162,7 @@ String VisualShaderNodeTexture2DArray::get_input_port_name(int p_port) const {
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture2DArray::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp;
 	dtp.name = make_unique_id(p_type, p_id, "tex3d");
-	dtp.param = texture_array;
+	dtp.params[0] = texture_array;
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp);
 	return ret;
@@ -1219,7 +1219,7 @@ String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const {
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp;
 	dtp.name = make_unique_id(p_type, p_id, "tex3d");
-	dtp.param = texture;
+	dtp.params[0] = texture;
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp);
 	return ret;
@@ -1318,7 +1318,7 @@ bool VisualShaderNodeCubemap::is_output_port_expandable(int p_port) const {
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp;
 	dtp.name = make_unique_id(p_type, p_id, "cube");
-	dtp.param = cube_map;
+	dtp.params[0] = cube_map;
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp);
 	return ret;

+ 2 - 2
scene/resources/visual_shader_particle_nodes.cpp

@@ -351,11 +351,11 @@ String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, V
 Vector<VisualShader::DefaultTextureParam> VisualShaderNodeParticleMeshEmitter::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
 	VisualShader::DefaultTextureParam dtp_vx;
 	dtp_vx.name = make_unique_id(p_type, p_id, "mesh_vx");
-	dtp_vx.param = position_texture;
+	dtp_vx.params[0] = position_texture;
 
 	VisualShader::DefaultTextureParam dtp_nm;
 	dtp_nm.name = make_unique_id(p_type, p_id, "mesh_nm");
-	dtp_nm.param = normal_texture;
+	dtp_nm.params[0] = normal_texture;
 
 	Vector<VisualShader::DefaultTextureParam> ret;
 	ret.push_back(dtp_vx);

+ 2 - 2
servers/rendering/rasterizer_dummy.h

@@ -293,8 +293,8 @@ public:
 	String shader_get_code(RID p_shader) const override { return ""; }
 	void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {}
 
-	void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) override {}
-	RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const override { return RID(); }
+	void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) override {}
+	RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const override { return RID(); }
 	Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
 
 	RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };

+ 12 - 3
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp

@@ -336,11 +336,20 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
-		default_texture_params.erase(p_name);
+		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 {
-		default_texture_params[p_name] = p_texture;
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = Map<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
 	}
 }
 

+ 2 - 2
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h

@@ -135,7 +135,7 @@ public:
 		uint32_t ubo_size;
 
 		String code;
-		Map<StringName, RID> default_texture_params;
+		Map<StringName, Map<int, RID>> default_texture_params;
 
 		DepthDraw depth_draw;
 		DepthTest depth_test;
@@ -166,7 +166,7 @@ public:
 		uint32_t index = 0;
 
 		virtual void set_code(const String &p_Code);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+		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;
 		void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
 

+ 12 - 3
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp

@@ -325,11 +325,20 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void SceneShaderForwardMobile::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void SceneShaderForwardMobile::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
-		default_texture_params.erase(p_name);
+		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 {
-		default_texture_params[p_name] = p_texture;
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = Map<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
 	}
 }
 

+ 2 - 2
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h

@@ -111,7 +111,7 @@ public:
 		uint32_t ubo_size;
 
 		String code;
-		Map<StringName, RID> default_texture_params;
+		Map<StringName, Map<int, RID>> default_texture_params;
 
 		DepthDraw depth_draw;
 		DepthTest depth_test;
@@ -141,7 +141,7 @@ public:
 		uint32_t index = 0;
 
 		virtual void set_code(const String &p_Code);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+		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;
 		void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
 

+ 12 - 3
servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp

@@ -2120,11 +2120,20 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
-		default_texture_params.erase(p_name);
+		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 {
-		default_texture_params[p_name] = p_texture;
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = Map<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
 	}
 }
 

+ 2 - 2
servers/rendering/renderer_rd/renderer_canvas_render_rd.h

@@ -173,14 +173,14 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
 		uint32_t ubo_size;
 
 		String code;
-		Map<StringName, RID> default_texture_params;
+		Map<StringName, Map<int, RID>> default_texture_params;
 
 		bool uses_screen_texture = false;
 		bool uses_sdf = false;
 		bool uses_time = false;
 
 		virtual void set_code(const String &p_Code);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+		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<RendererStorage::InstanceShaderParam> *p_param_list) const;
 

+ 12 - 3
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -3558,11 +3558,20 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void RendererSceneRenderRD::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererSceneRenderRD::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
-		default_texture_params.erase(p_name);
+		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 {
-		default_texture_params[p_name] = p_texture;
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = Map<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
 	}
 }
 

+ 2 - 2
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -879,12 +879,12 @@ private:
 
 		String path;
 		String code;
-		Map<StringName, RID> default_texture_params;
+		Map<StringName, Map<int, RID>> default_texture_params;
 
 		bool uses_time;
 
 		virtual void set_code(const String &p_Code);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+		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<RendererStorage::InstanceShaderParam> *p_param_list) const;
 		virtual bool is_param_texture(const StringName &p_param) const;

+ 12 - 3
servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp

@@ -137,11 +137,20 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
-		default_texture_params.erase(p_name);
+		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 {
-		default_texture_params[p_name] = p_texture;
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = Map<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
 	}
 }
 

+ 2 - 2
servers/rendering/renderer_rd/renderer_scene_sky_rd.h

@@ -118,7 +118,7 @@ private:
 
 		String path;
 		String code;
-		Map<StringName, RID> default_texture_params;
+		Map<StringName, Map<int, RID>> default_texture_params;
 
 		bool uses_time;
 		bool uses_position;
@@ -127,7 +127,7 @@ private:
 		bool uses_light;
 
 		virtual void set_code(const String &p_Code);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+		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<RendererStorage::InstanceShaderParam> *p_param_list) const;
 		virtual bool is_param_texture(const StringName &p_param) const;

+ 40 - 20
servers/rendering/renderer_rd/renderer_storage_rd.cpp

@@ -1440,8 +1440,10 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) {
 		}
 
 		if (shader->data) {
-			for (const KeyValue<StringName, RID> &E : shader->default_texture_parameter) {
-				shader->data->set_default_texture_param(E.key, E.value);
+			for (const KeyValue<StringName, Map<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);
+				}
 			}
 		}
 	}
@@ -1471,17 +1473,26 @@ void RendererStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *
 	}
 }
 
-void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
+void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) {
 	Shader *shader = shader_owner.get_or_null(p_shader);
 	ERR_FAIL_COND(!shader);
 
 	if (p_texture.is_valid() && texture_owner.owns(p_texture)) {
-		shader->default_texture_parameter[p_name] = p_texture;
+		if (!shader->default_texture_parameter.has(p_name)) {
+			shader->default_texture_parameter[p_name] = Map<int, RID>();
+		}
+		shader->default_texture_parameter[p_name][p_index] = p_texture;
 	} else {
-		shader->default_texture_parameter.erase(p_name);
+		if (shader->default_texture_parameter.has(p_name) && shader->default_texture_parameter[p_name].has(p_index)) {
+			shader->default_texture_parameter[p_name].erase(p_index);
+
+			if (shader->default_texture_parameter[p_name].is_empty()) {
+				shader->default_texture_parameter.erase(p_name);
+			}
+		}
 	}
 	if (shader->data) {
-		shader->data->set_default_texture_param(p_name, p_texture);
+		shader->data->set_default_texture_param(p_name, p_texture, p_index);
 	}
 	for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
 		Material *material = E->get();
@@ -1489,11 +1500,11 @@ void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const Str
 	}
 }
 
-RID RendererStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const {
+RID RendererStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const {
 	Shader *shader = shader_owner.get_or_null(p_shader);
 	ERR_FAIL_COND_V(!shader, RID());
-	if (shader->default_texture_parameter.has(p_name)) {
-		return shader->default_texture_parameter[p_name];
+	if (shader->default_texture_parameter.has(p_name) && shader->default_texture_parameter[p_name].has(p_index)) {
+		return shader->default_texture_parameter[p_name][p_index];
 	}
 
 	return RID();
@@ -2610,7 +2621,7 @@ RendererStorageRD::MaterialData::~MaterialData() {
 	}
 }
 
-void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
+void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
 	RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton;
 #ifdef TOOLS_ENABLED
 	Texture *roughness_detect_texture = nullptr;
@@ -2673,19 +2684,19 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
 
 			if (uniform_array_size > 0) {
 				if (textures.size() < uniform_array_size) {
-					const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name);
+					const Map<StringName, Map<int, RID>>::Element *W = p_default_textures.find(uniform_name);
 					for (int j = textures.size(); j < uniform_array_size; j++) {
-						if (W) {
-							textures.push_back(W->get());
+						if (W && W->get().has(j)) {
+							textures.push_back(W->get()[j]);
 						} else {
 							textures.push_back(RID());
 						}
 					}
 				}
 			} else if (textures.is_empty()) {
-				const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name);
-				if (W) {
-					textures.push_back(W->get());
+				const Map<StringName, Map<int, RID>>::Element *W = p_default_textures.find(uniform_name);
+				if (W && W->get().has(0)) {
+					textures.push_back(W->get()[0]);
 				}
 			}
 		}
@@ -2833,7 +2844,7 @@ void RendererStorageRD::MaterialData::free_parameters_uniform_set(RID p_uniform_
 	}
 }
 
-bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, RID> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
+bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
 	if ((uint32_t)ubo_data.size() != p_ubo_size) {
 		p_uniform_dirty = true;
 		if (uniform_buffer.is_valid()) {
@@ -5748,11 +5759,20 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
 	valid = true;
 }
 
-void RendererStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererStorageRD::ParticlesShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) {
 	if (!p_texture.is_valid()) {
-		default_texture_params.erase(p_name);
+		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 {
-		default_texture_params[p_name] = p_texture;
+		if (!default_texture_params.has(p_name)) {
+			default_texture_params[p_name] = Map<int, RID>();
+		}
+		default_texture_params[p_name][p_index] = p_texture;
 	}
 }
 

+ 8 - 8
servers/rendering/renderer_rd/renderer_storage_rd.h

@@ -135,7 +135,7 @@ public:
 
 	struct ShaderData {
 		virtual void set_code(const String &p_Code) = 0;
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture) = 0;
+		virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0;
 		virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0;
 
 		virtual void get_instance_param_list(List<InstanceShaderParam> *p_param_list) const = 0;
@@ -152,7 +152,7 @@ public:
 
 	struct MaterialData {
 		void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
-		void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
+		void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
 
 		virtual void set_render_priority(int p_priority) = 0;
 		virtual void set_next_pass(RID p_pass) = 0;
@@ -160,7 +160,7 @@ public:
 		virtual ~MaterialData();
 
 		//to be used internally by update_parameters, in the most common configuration of material parameters
-		bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, RID> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+		bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
 		void free_parameters_uniform_set(RID p_uniform_set);
 
 	private:
@@ -374,7 +374,7 @@ private:
 		ShaderData *data;
 		String code;
 		ShaderType type;
-		Map<StringName, RID> default_texture_parameter;
+		Map<StringName, Map<int, RID>> default_texture_parameter;
 		Set<Material *> owners;
 	};
 
@@ -883,14 +883,14 @@ private:
 
 		String path;
 		String code;
-		Map<StringName, RID> default_texture_params;
+		Map<StringName, Map<int, RID>> default_texture_params;
 
 		RID pipeline;
 
 		bool uses_time;
 
 		virtual void set_code(const String &p_Code);
-		virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+		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<RendererStorage::InstanceShaderParam> *p_param_list) const;
 		virtual bool is_param_texture(const StringName &p_param) const;
@@ -1414,8 +1414,8 @@ public:
 	String shader_get_code(RID p_shader) const;
 	void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const;
 
-	void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture);
-	RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const;
+	void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index);
+	RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const;
 	Variant shader_get_param_default(RID p_shader, const StringName &p_param) const;
 	void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function);
 

+ 2 - 2
servers/rendering/renderer_storage.h

@@ -183,8 +183,8 @@ public:
 	virtual String shader_get_code(RID p_shader) const = 0;
 	virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
 
-	virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0;
-	virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
+	virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index) = 0;
+	virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index) const = 0;
 	virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0;
 
 	virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0;

+ 2 - 2
servers/rendering/rendering_server_default.h

@@ -223,8 +223,8 @@ public:
 
 	FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *)
 
-	FUNC3(shader_set_default_texture_param, RID, const StringName &, RID)
-	FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &)
+	FUNC4(shader_set_default_texture_param, RID, const StringName &, RID, int)
+	FUNC3RC(RID, shader_get_default_texture_param, RID, const StringName &, int)
 	FUNC2RC(Variant, shader_get_param_default, RID, const StringName &)
 
 	FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID)

+ 2 - 2
servers/rendering_server.cpp

@@ -1716,8 +1716,8 @@ void RenderingServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("shader_get_param_list", "shader"), &RenderingServer::_shader_get_param_list);
 	ClassDB::bind_method(D_METHOD("shader_get_param_default", "shader", "param"), &RenderingServer::shader_get_param_default);
 
-	ClassDB::bind_method(D_METHOD("shader_set_default_texture_param", "shader", "param", "texture"), &RenderingServer::shader_set_default_texture_param);
-	ClassDB::bind_method(D_METHOD("shader_get_default_texture_param", "shader", "param"), &RenderingServer::shader_get_default_texture_param);
+	ClassDB::bind_method(D_METHOD("shader_set_default_texture_param", "shader", "param", "texture", "index"), &RenderingServer::shader_set_default_texture_param, DEFVAL(0));
+	ClassDB::bind_method(D_METHOD("shader_get_default_texture_param", "shader", "param", "index"), &RenderingServer::shader_get_default_texture_param, DEFVAL(0));
 
 	BIND_ENUM_CONSTANT(SHADER_SPATIAL);
 	BIND_ENUM_CONSTANT(SHADER_CANVAS_ITEM);

+ 2 - 2
servers/rendering_server.h

@@ -172,8 +172,8 @@ public:
 	virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
 	virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const = 0;
 
-	virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0;
-	virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
+	virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture, int p_index = 0) = 0;
+	virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name, int p_index = 0) const = 0;
 
 	struct ShaderNativeSourceCode {
 		struct Version {