Browse Source

Merge pull request #64167 from clayjohn/screen-texture-hint

Add shader uniform hints for screen textures
Max Hilbrunner 3 years ago
parent
commit
019d6584ee

+ 3 - 1
drivers/gles3/rasterizer_canvas_gles3.cpp

@@ -201,6 +201,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
 	bool material_screen_texture_found = false;
 	bool material_screen_texture_found = false;
 	Rect2 back_buffer_rect;
 	Rect2 back_buffer_rect;
 	bool backbuffer_copy = false;
 	bool backbuffer_copy = false;
+	bool backbuffer_gen_mipmaps = false;
 
 
 	Item *ci = p_item_list;
 	Item *ci = p_item_list;
 	Item *canvas_group_owner = nullptr;
 	Item *canvas_group_owner = nullptr;
@@ -225,6 +226,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
 					if (!material_screen_texture_found) {
 					if (!material_screen_texture_found) {
 						backbuffer_copy = true;
 						backbuffer_copy = true;
 						back_buffer_rect = Rect2();
 						back_buffer_rect = Rect2();
+						backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps;
 					}
 					}
 				}
 				}
 
 
@@ -282,7 +284,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
 			item_count = 0;
 			item_count = 0;
 
 
-			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true);
+			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
 
 
 			backbuffer_copy = false;
 			backbuffer_copy = false;
 			material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies
 			material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies

+ 41 - 21
drivers/gles3/storage/material_storage.cpp

@@ -1083,6 +1083,12 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
 
 
 		Vector<RID> textures;
 		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) {
 		if (p_texture_uniforms[i].global) {
 			uses_global_textures = true;
 			uses_global_textures = true;
 
 
@@ -1492,9 +1498,9 @@ MaterialStorage::MaterialStorage() {
 		actions.renames["POINT_COORD"] = "gl_PointCoord";
 		actions.renames["POINT_COORD"] = "gl_PointCoord";
 		actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
 		actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
 		actions.renames["SCREEN_UV"] = "screen_uv";
 		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["DEPTH"] = "gl_FragDepth";
 		actions.renames["OUTPUT_IS_SRGB"] = "true";
 		actions.renames["OUTPUT_IS_SRGB"] = "true";
 		actions.renames["FOG"] = "fog";
 		actions.renames["FOG"] = "fog";
@@ -2789,6 +2795,7 @@ void CanvasShaderData::set_code(const String &p_code) {
 	ubo_size = 0;
 	ubo_size = 0;
 	uniforms.clear();
 	uniforms.clear();
 	uses_screen_texture = false;
 	uses_screen_texture = false;
+	uses_screen_texture_mipmaps = false;
 	uses_sdf = false;
 	uses_sdf = false;
 	uses_time = false;
 	uses_time = false;
 
 
@@ -2799,7 +2806,6 @@ void CanvasShaderData::set_code(const String &p_code) {
 	ShaderCompiler::GeneratedCode gen_code;
 	ShaderCompiler::GeneratedCode gen_code;
 
 
 	int blend_modei = BLEND_MODE_MIX;
 	int blend_modei = BLEND_MODE_MIX;
-	uses_screen_texture = false;
 
 
 	ShaderCompiler::IdentifierActions actions;
 	ShaderCompiler::IdentifierActions actions;
 	actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
 	actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
@@ -2826,6 +2832,7 @@ void CanvasShaderData::set_code(const String &p_code) {
 	}
 	}
 
 
 	blend_mode = BlendMode(blend_modei);
 	blend_mode = BlendMode(blend_modei);
+	uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
 
 
 #if 0
 #if 0
 	print_line("**compiling shader:");
 	print_line("**compiling shader:");
@@ -2833,12 +2840,16 @@ void CanvasShaderData::set_code(const String &p_code) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 		print_line(gen_code.defines[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**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
 #endif
 
 
 	Vector<StringName> texture_uniform_names;
 	Vector<StringName> texture_uniform_names;
@@ -2877,7 +2888,10 @@ void CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list)
 	HashMap<int, StringName> order;
 	HashMap<int, StringName> order;
 
 
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
 	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;
 			continue;
 		}
 		}
 		if (E.value.texture_order >= 0) {
 		if (E.value.texture_order >= 0) {
@@ -3070,12 +3084,16 @@ void SkyShaderData::set_code(const String &p_code) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 		print_line(gen_code.defines[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**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
 #endif
 
 
 	Vector<StringName> texture_uniform_names;
 	Vector<StringName> texture_uniform_names;
@@ -3253,7 +3271,6 @@ void SceneShaderData::set_code(const String &p_code) {
 	valid = false;
 	valid = false;
 	ubo_size = 0;
 	ubo_size = 0;
 	uniforms.clear();
 	uniforms.clear();
-	uses_screen_texture = false;
 
 
 	if (code.is_empty()) {
 	if (code.is_empty()) {
 		return; //just invalid, but no error
 		return; //just invalid, but no error
@@ -3378,6 +3395,7 @@ void SceneShaderData::set_code(const String &p_code) {
 	vertex_input_mask |= uses_custom3 << 8;
 	vertex_input_mask |= uses_custom3 << 8;
 	vertex_input_mask |= uses_bones << 9;
 	vertex_input_mask |= uses_bones << 9;
 	vertex_input_mask |= uses_weights << 10;
 	vertex_input_mask |= uses_weights << 10;
+	uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
 
 
 #if 0
 #if 0
 	print_line("**compiling shader:");
 	print_line("**compiling shader:");
@@ -3386,11 +3404,10 @@ void SceneShaderData::set_code(const String &p_code) {
 		print_line(gen_code.defines[i]);
 		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) {
 	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);
 	print_line("\n**uniforms:\n" + gen_code.uniforms);
@@ -3439,7 +3456,10 @@ void SceneShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list)
 	RBMap<int, StringName> order;
 	RBMap<int, StringName> order;
 
 
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
 	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;
 			continue;
 		}
 		}
 
 

+ 2 - 0
drivers/gles3/storage/material_storage.h

@@ -159,6 +159,7 @@ struct CanvasShaderData : public ShaderData {
 	HashMap<StringName, HashMap<int, RID>> default_texture_params;
 	HashMap<StringName, HashMap<int, RID>> default_texture_params;
 
 
 	bool uses_screen_texture = false;
 	bool uses_screen_texture = false;
+	bool uses_screen_texture_mipmaps = false;
 	bool uses_sdf = false;
 	bool uses_sdf = false;
 	bool uses_time = false;
 	bool uses_time = false;
 
 
@@ -312,6 +313,7 @@ struct SceneShaderData : public ShaderData {
 	bool uses_sss;
 	bool uses_sss;
 	bool uses_transmittance;
 	bool uses_transmittance;
 	bool uses_screen_texture;
 	bool uses_screen_texture;
+	bool uses_screen_texture_mipmaps;
 	bool uses_depth_texture;
 	bool uses_depth_texture;
 	bool uses_normal_texture;
 	bool uses_normal_texture;
 	bool uses_time;
 	bool uses_time;

+ 9 - 5
servers/rendering/renderer_rd/environment/sky.cpp

@@ -114,12 +114,16 @@ void SkyRD::SkyShaderData::set_code(const String &p_code) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 		print_line(gen_code.defines[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**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
 #endif
 
 
 	scene_singleton->sky.sky_shader.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);
 	scene_singleton->sky.sky_shader.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);

+ 9 - 5
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp

@@ -150,6 +150,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
 	depth_draw = DepthDraw(depth_drawi);
 	depth_draw = DepthDraw(depth_drawi);
 	depth_test = DepthTest(depth_testi);
 	depth_test = DepthTest(depth_testi);
 	cull_mode = Cull(cull_modei);
 	cull_mode = Cull(cull_modei);
+	uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
 
 
 #if 0
 #if 0
 	print_line("**compiling shader:");
 	print_line("**compiling shader:");
@@ -158,11 +159,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
 		print_line(gen_code.defines[i]);
 		print_line(gen_code.defines[i]);
 	}
 	}
 
 
-	RBMap<String, String>::Element *el = gen_code.code.front();
+	HashMap<String, String>::Iterator el = gen_code.code.begin();
 	while (el) {
 	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);
 	print_line("\n**uniforms:\n" + gen_code.uniforms);
@@ -396,7 +396,11 @@ void SceneShaderForwardClustered::ShaderData::get_shader_uniform_list(List<Prope
 	HashMap<int, StringName> order;
 	HashMap<int, StringName> order;
 
 
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
 	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) {
+			// Don't expose any of these.
 			continue;
 			continue;
 		}
 		}
 
 

+ 1 - 0
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h

@@ -174,6 +174,7 @@ public:
 		bool uses_time = false;
 		bool uses_time = false;
 		bool writes_modelview_or_projection = false;
 		bool writes_modelview_or_projection = false;
 		bool uses_world_coordinates = false;
 		bool uses_world_coordinates = false;
+		bool uses_screen_texture_mipmaps = false;
 		Cull cull_mode = CULL_DISABLED;
 		Cull cull_mode = CULL_DISABLED;
 
 
 		uint64_t last_pass = 0;
 		uint64_t last_pass = 0;

+ 7 - 5
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp

@@ -158,11 +158,10 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
 		print_line(gen_code.defines[i]);
 		print_line(gen_code.defines[i]);
 	}
 	}
 
 
-	RBMap<String, String>::Element * el = gen_code.code.front();
+	HashMap<String, String>::Iterator el = gen_code.code.begin();
 	while (el) {
 	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);
 	print_line("\n**uniforms:\n" + gen_code.uniforms);
@@ -353,7 +352,10 @@ void SceneShaderForwardMobile::ShaderData::get_shader_uniform_list(List<Property
 	HashMap<int, StringName> order;
 	HashMap<int, StringName> order;
 
 
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
 	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;
 			continue;
 		}
 		}
 
 

+ 21 - 8
servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp

@@ -1361,6 +1361,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 	Item *ci = p_item_list;
 	Item *ci = p_item_list;
 	Rect2 back_buffer_rect;
 	Rect2 back_buffer_rect;
 	bool backbuffer_copy = false;
 	bool backbuffer_copy = false;
+	bool backbuffer_gen_mipmaps = false;
 
 
 	Item *canvas_group_owner = nullptr;
 	Item *canvas_group_owner = nullptr;
 
 
@@ -1389,6 +1390,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 					if (!material_screen_texture_found) {
 					if (!material_screen_texture_found) {
 						backbuffer_copy = true;
 						backbuffer_copy = true;
 						back_buffer_rect = Rect2();
 						back_buffer_rect = Rect2();
+						backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps;
 					}
 					}
 				}
 				}
 
 
@@ -1474,9 +1476,10 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
 			_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
 			item_count = 0;
 			item_count = 0;
 
 
-			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true);
+			texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
 
 
 			backbuffer_copy = false;
 			backbuffer_copy = false;
+			backbuffer_gen_mipmaps = false;
 			material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies
 			material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies
 		}
 		}
 
 
@@ -1980,6 +1983,7 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
 	ubo_size = 0;
 	ubo_size = 0;
 	uniforms.clear();
 	uniforms.clear();
 	uses_screen_texture = false;
 	uses_screen_texture = false;
+	uses_screen_texture_mipmaps = false;
 	uses_sdf = false;
 	uses_sdf = false;
 	uses_time = false;
 	uses_time = false;
 
 
@@ -1990,7 +1994,6 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
 	ShaderCompiler::GeneratedCode gen_code;
 	ShaderCompiler::GeneratedCode gen_code;
 
 
 	int blend_mode = BLEND_MODE_MIX;
 	int blend_mode = BLEND_MODE_MIX;
-	uses_screen_texture = false;
 
 
 	ShaderCompiler::IdentifierActions actions;
 	ShaderCompiler::IdentifierActions actions;
 	actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
 	actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
@@ -2015,6 +2018,8 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
 	Error err = canvas_singleton->shader.compiler.compile(RS::SHADER_CANVAS_ITEM, code, &actions, path, gen_code);
 	Error err = canvas_singleton->shader.compiler.compile(RS::SHADER_CANVAS_ITEM, code, &actions, path, gen_code);
 	ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
 	ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed.");
 
 
+	uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+
 	if (version.is_null()) {
 	if (version.is_null()) {
 		version = canvas_singleton->shader.canvas_shader.version_create();
 		version = canvas_singleton->shader.canvas_shader.version_create();
 	}
 	}
@@ -2025,12 +2030,16 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 	for (int i = 0; i < gen_code.defines.size(); i++) {
 		print_line(gen_code.defines[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**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
 #endif
 	canvas_singleton->shader.canvas_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);
 	canvas_singleton->shader.canvas_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);
 	ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version));
 	ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version));
@@ -2175,7 +2184,11 @@ void RendererCanvasRenderRD::CanvasShaderData::get_shader_uniform_list(List<Prop
 	HashMap<int, StringName> order;
 	HashMap<int, StringName> order;
 
 
 	for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) {
 	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) {
+			// Don't expose any of these.
 			continue;
 			continue;
 		}
 		}
 		if (E.value.texture_order >= 0) {
 		if (E.value.texture_order >= 0) {

+ 1 - 0
servers/rendering/renderer_rd/renderer_canvas_render_rd.h

@@ -174,6 +174,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
 		HashMap<StringName, HashMap<int, RID>> default_texture_params;
 		HashMap<StringName, HashMap<int, RID>> default_texture_params;
 
 
 		bool uses_screen_texture = false;
 		bool uses_screen_texture = false;
+		bool uses_screen_texture_mipmaps = false;
 		bool uses_sdf = false;
 		bool uses_sdf = false;
 		bool uses_time = false;
 		bool uses_time = false;
 
 

+ 13 - 1
servers/rendering/renderer_rd/storage_rd/material_storage.cpp

@@ -941,6 +941,12 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringNa
 			continue; //instance uniforms don't appear in the buffer
 			continue; //instance uniforms don't appear in the buffer
 		}
 		}
 
 
+		if (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.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
 		if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
 			//this is a global variable, get the index to it
 			//this is a global variable, get the index to it
 			GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key);
 			GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key);
@@ -1052,6 +1058,12 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va
 
 
 		Vector<RID> textures;
 		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) {
 		if (p_texture_uniforms[i].global) {
 			uses_global_textures = true;
 			uses_global_textures = true;
 
 
@@ -1307,7 +1319,7 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<
 		update_textures(p_parameters, p_default_texture_params, p_texture_uniforms, texture_cache.ptrw(), true);
 		update_textures(p_parameters, p_default_texture_params, p_texture_uniforms, texture_cache.ptrw(), true);
 	}
 	}
 
 
-	if (p_ubo_size == 0 && p_texture_uniforms.size() == 0) {
+	if (p_ubo_size == 0 && (p_texture_uniforms.size() == 0)) {
 		// This material does not require an uniform set, so don't create it.
 		// This material does not require an uniform set, so don't create it.
 		return false;
 		return false;
 	}
 	}

+ 42 - 1
servers/rendering/shader_compiler.cpp

@@ -498,6 +498,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 
 
 			for (const KeyValue<StringName, SL::ShaderNode::Uniform> &E : pnode->uniforms) {
 			for (const KeyValue<StringName, SL::ShaderNode::Uniform> &E : pnode->uniforms) {
 				if (SL::is_sampler_type(E.value.type)) {
 				if (SL::is_sampler_type(E.value.type)) {
+					if (E.value.hint == SL::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
+							E.value.hint == SL::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
+							E.value.hint == SL::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+						continue; // Don't create uniforms in the generated code for these.
+					}
 					max_texture_uniforms++;
 					max_texture_uniforms++;
 				} else {
 				} else {
 					if (E.value.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) {
 					if (E.value.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) {
@@ -537,6 +542,13 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 					p_actions.uniforms->insert(uniform_name, uniform);
 					p_actions.uniforms->insert(uniform_name, uniform);
 					continue; // Instances are indexed directly, don't need index uniforms.
 					continue; // Instances are indexed directly, don't need index uniforms.
 				}
 				}
+
+				if (uniform.hint == SL::ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
+						uniform.hint == SL::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
+						uniform.hint == SL::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+					continue; // Don't create uniforms in the generated code for these.
+				}
+
 				if (SL::is_sampler_type(uniform.type)) {
 				if (SL::is_sampler_type(uniform.type)) {
 					// Texture layouts are different for OpenGL GLSL and Vulkan GLSL
 					// Texture layouts are different for OpenGL GLSL and Vulkan GLSL
 					if (!RS::get_singleton()->is_low_end()) {
 					if (!RS::get_singleton()->is_low_end()) {
@@ -892,12 +904,39 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 
 
 			if (p_default_actions.renames.has(vnode->name)) {
 			if (p_default_actions.renames.has(vnode->name)) {
 				code = p_default_actions.renames[vnode->name];
 				code = p_default_actions.renames[vnode->name];
+				if (vnode->name == "SCREEN_TEXTURE") {
+					r_gen_code.uses_screen_texture_mipmaps = true;
+				}
 			} else {
 			} else {
 				if (shader->uniforms.has(vnode->name)) {
 				if (shader->uniforms.has(vnode->name)) {
 					//its a uniform!
 					//its a uniform!
 					const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name];
 					const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name];
 					if (u.texture_order >= 0) {
 					if (u.texture_order >= 0) {
-						code = _mkid(vnode->name); //texture, use as is
+						StringName name = vnode->name;
+						if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
+							name = "SCREEN_TEXTURE";
+							if (u.filter >= ShaderLanguage::FILTER_NEAREST_MIPMAP) {
+								r_gen_code.uses_screen_texture_mipmaps = true;
+							}
+						} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
+							name = "NORMAL_ROUGHNESS_TEXTURE";
+						} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+							name = "DEPTH_TEXTURE";
+						} else {
+							name = _mkid(vnode->name); //texture, use as is
+						}
+
+						if (p_default_actions.renames.has(name)) {
+							code = p_default_actions.renames[name];
+						} else {
+							code = name;
+						}
+
+						if (p_actions.usage_flag_pointers.has(name) && !used_flag_pointers.has(name)) {
+							*p_actions.usage_flag_pointers[name] = true;
+							used_flag_pointers.insert(name);
+						}
+
 					} else {
 					} else {
 						//a scalar or vector
 						//a scalar or vector
 						if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
 						if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) {
@@ -1155,6 +1194,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 							}
 							}
 
 
 							if (correct_texture_uniform) {
 							if (correct_texture_uniform) {
+								//TODO Needs to detect screen_texture hint as well
 								is_screen_texture = (texture_uniform == "SCREEN_TEXTURE");
 								is_screen_texture = (texture_uniform == "SCREEN_TEXTURE");
 
 
 								String sampler_name;
 								String sampler_name;
@@ -1404,6 +1444,7 @@ Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, Ident
 	r_gen_code.uses_fragment_time = false;
 	r_gen_code.uses_fragment_time = false;
 	r_gen_code.uses_vertex_time = false;
 	r_gen_code.uses_vertex_time = false;
 	r_gen_code.uses_global_textures = false;
 	r_gen_code.uses_global_textures = false;
+	r_gen_code.uses_screen_texture_mipmaps = false;
 
 
 	used_name_defines.clear();
 	used_name_defines.clear();
 	used_rmode_defines.clear();
 	used_rmode_defines.clear();

+ 1 - 0
servers/rendering/shader_compiler.h

@@ -80,6 +80,7 @@ public:
 		bool uses_global_textures;
 		bool uses_global_textures;
 		bool uses_fragment_time;
 		bool uses_fragment_time;
 		bool uses_vertex_time;
 		bool uses_vertex_time;
+		bool uses_screen_texture_mipmaps;
 	};
 	};
 
 
 	struct DefaultIdentifierActions {
 	struct DefaultIdentifierActions {

+ 33 - 4
servers/rendering/shader_language.cpp

@@ -200,6 +200,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
 	"HINT_ANISOTROPY_TEXTURE",
 	"HINT_ANISOTROPY_TEXTURE",
 	"HINT_RANGE",
 	"HINT_RANGE",
 	"HINT_INSTANCE_INDEX",
 	"HINT_INSTANCE_INDEX",
+	"HINT_SCREEN_TEXTURE",
+	"HINT_NORMAL_ROUGHNESS_TEXTURE",
+	"HINT_DEPTH_TEXTURE",
 	"FILTER_NEAREST",
 	"FILTER_NEAREST",
 	"FILTER_LINEAR",
 	"FILTER_LINEAR",
 	"FILTER_NEAREST_MIPMAP",
 	"FILTER_NEAREST_MIPMAP",
@@ -363,6 +366,10 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
 	{ TK_HINT_ROUGHNESS_A, "hint_roughness_a", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_A, "hint_roughness_a", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_NORMAL_TEXTURE, "hint_roughness_normal", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_NORMAL_TEXTURE, "hint_roughness_normal", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_GRAY, "hint_roughness_gray", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_GRAY, "hint_roughness_gray", CF_UNSPECIFIED, {}, {} },
+	{ TK_HINT_SCREEN_TEXTURE, "hint_screen_texture", CF_UNSPECIFIED, {}, {} },
+	{ TK_HINT_NORMAL_ROUGHNESS_TEXTURE, "hint_normal_roughness_texture", CF_UNSPECIFIED, {}, {} },
+	{ TK_HINT_DEPTH_TEXTURE, "hint_depth_texture", CF_UNSPECIFIED, {}, {} },
+
 	{ TK_FILTER_NEAREST, "filter_nearest", CF_UNSPECIFIED, {}, {} },
 	{ TK_FILTER_NEAREST, "filter_nearest", CF_UNSPECIFIED, {}, {} },
 	{ TK_FILTER_LINEAR, "filter_linear", CF_UNSPECIFIED, {}, {} },
 	{ TK_FILTER_LINEAR, "filter_linear", CF_UNSPECIFIED, {}, {} },
 	{ TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap", CF_UNSPECIFIED, {}, {} },
 	{ TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap", CF_UNSPECIFIED, {}, {} },
@@ -1096,6 +1103,15 @@ String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) {
 		case ShaderNode::Uniform::HINT_ANISOTROPY: {
 		case ShaderNode::Uniform::HINT_ANISOTROPY: {
 			result = "hint_anisotropy";
 			result = "hint_anisotropy";
 		} break;
 		} break;
+		case ShaderNode::Uniform::HINT_SCREEN_TEXTURE: {
+			result = "hint_screen_texture";
+		} break;
+		case ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE: {
+			result = "hint_normal_roughness_texture";
+		} break;
+		case ShaderNode::Uniform::HINT_DEPTH_TEXTURE: {
+			result = "hint_depth_texture";
+		} break;
 		default:
 		default:
 			break;
 			break;
 	}
 	}
@@ -8605,6 +8621,15 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 										return ERR_PARSE_ERROR;
 										return ERR_PARSE_ERROR;
 									}
 									}
 								} break;
 								} break;
+								case TK_HINT_SCREEN_TEXTURE: {
+									new_hint = ShaderNode::Uniform::HINT_SCREEN_TEXTURE;
+								} break;
+								case TK_HINT_NORMAL_ROUGHNESS_TEXTURE: {
+									new_hint = ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE;
+								} break;
+								case TK_HINT_DEPTH_TEXTURE: {
+									new_hint = ShaderNode::Uniform::HINT_DEPTH_TEXTURE;
+								} break;
 								case TK_FILTER_NEAREST: {
 								case TK_FILTER_NEAREST: {
 									new_filter = FILTER_NEAREST;
 									new_filter = FILTER_NEAREST;
 								} break;
 								} break;
@@ -8629,6 +8654,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 								case TK_REPEAT_ENABLE: {
 								case TK_REPEAT_ENABLE: {
 									new_repeat = REPEAT_ENABLE;
 									new_repeat = REPEAT_ENABLE;
 								} break;
 								} break;
+
 								default:
 								default:
 									break;
 									break;
 							}
 							}
@@ -8653,9 +8679,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 							if (new_filter != FILTER_DEFAULT) {
 							if (new_filter != FILTER_DEFAULT) {
 								if (uniform.filter != FILTER_DEFAULT) {
 								if (uniform.filter != FILTER_DEFAULT) {
 									if (uniform.filter == new_filter) {
 									if (uniform.filter == new_filter) {
-										_set_error(vformat(RTR("Duplicated hint: '%s'."), get_texture_filter_name(new_filter)));
+										_set_error(vformat(RTR("Duplicated filter mode: '%s'."), get_texture_filter_name(new_filter)));
 									} else {
 									} else {
-										_set_error(vformat(RTR("Redefinition of hint: '%s'. The filter mode has already been set to '%s'."), get_texture_filter_name(new_filter), get_texture_filter_name(uniform.filter)));
+										_set_error(vformat(RTR("Redefinition of filter mode: '%s'. The filter mode has already been set to '%s'."), get_texture_filter_name(new_filter), get_texture_filter_name(uniform.filter)));
 									}
 									}
 									return ERR_PARSE_ERROR;
 									return ERR_PARSE_ERROR;
 								} else {
 								} else {
@@ -8666,9 +8692,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 							if (new_repeat != REPEAT_DEFAULT) {
 							if (new_repeat != REPEAT_DEFAULT) {
 								if (uniform.repeat != REPEAT_DEFAULT) {
 								if (uniform.repeat != REPEAT_DEFAULT) {
 									if (uniform.repeat == new_repeat) {
 									if (uniform.repeat == new_repeat) {
-										_set_error(vformat(RTR("Duplicated hint: '%s'."), get_texture_repeat_name(new_repeat)));
+										_set_error(vformat(RTR("Duplicated repeat mode: '%s'."), get_texture_repeat_name(new_repeat)));
 									} else {
 									} else {
-										_set_error(vformat(RTR("Redefinition of hint: '%s'. The repeat mode has already been set to '%s'."), get_texture_repeat_name(new_repeat), get_texture_repeat_name(uniform.repeat)));
+										_set_error(vformat(RTR("Redefinition of repeat mode: '%s'. The repeat mode has already been set to '%s'."), get_texture_repeat_name(new_repeat), get_texture_repeat_name(uniform.repeat)));
 									}
 									}
 									return ERR_PARSE_ERROR;
 									return ERR_PARSE_ERROR;
 								} else {
 								} else {
@@ -10309,6 +10335,9 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 					options.push_back("hint_roughness_gray");
 					options.push_back("hint_roughness_gray");
 					options.push_back("hint_roughness_normal");
 					options.push_back("hint_roughness_normal");
 					options.push_back("hint_roughness_r");
 					options.push_back("hint_roughness_r");
+					options.push_back("hint_screen_texture");
+					options.push_back("hint_normal_roughness_texture");
+					options.push_back("hint_depth_texture");
 					options.push_back("source_color");
 					options.push_back("source_color");
 					options.push_back("repeat_enable");
 					options.push_back("repeat_enable");
 					options.push_back("repeat_disable");
 					options.push_back("repeat_disable");

+ 6 - 0
servers/rendering/shader_language.h

@@ -176,6 +176,9 @@ public:
 		TK_HINT_SOURCE_COLOR,
 		TK_HINT_SOURCE_COLOR,
 		TK_HINT_RANGE,
 		TK_HINT_RANGE,
 		TK_HINT_INSTANCE_INDEX,
 		TK_HINT_INSTANCE_INDEX,
+		TK_HINT_SCREEN_TEXTURE,
+		TK_HINT_NORMAL_ROUGHNESS_TEXTURE,
+		TK_HINT_DEPTH_TEXTURE,
 		TK_FILTER_NEAREST,
 		TK_FILTER_NEAREST,
 		TK_FILTER_LINEAR,
 		TK_FILTER_LINEAR,
 		TK_FILTER_NEAREST_MIPMAP,
 		TK_FILTER_NEAREST_MIPMAP,
@@ -667,6 +670,9 @@ public:
 				HINT_DEFAULT_WHITE,
 				HINT_DEFAULT_WHITE,
 				HINT_DEFAULT_TRANSPARENT,
 				HINT_DEFAULT_TRANSPARENT,
 				HINT_ANISOTROPY,
 				HINT_ANISOTROPY,
+				HINT_SCREEN_TEXTURE,
+				HINT_NORMAL_ROUGHNESS_TEXTURE,
+				HINT_DEPTH_TEXTURE,
 				HINT_MAX
 				HINT_MAX
 			};
 			};