浏览代码

Merge pull request #51672 from Calinou/shader-add-hint-transparent-texture

Add `hint_transparent` to use a transparent black placeholder texture
Rémi Verschelde 3 年之前
父节点
当前提交
8cce479c01

+ 6 - 3
doc/classes/VisualShaderNodeTextureUniform.xml

@@ -39,12 +39,15 @@
 			Represents the size of the [enum TextureType] enum.
 		</constant>
 		<constant name="COLOR_DEFAULT_WHITE" value="0" enum="ColorDefault">
-			Defaults to white color.
+			Defaults to fully opaque white color.
 		</constant>
 		<constant name="COLOR_DEFAULT_BLACK" value="1" enum="ColorDefault">
-			Defaults to black color.
+			Defaults to fully opaque black color.
 		</constant>
-		<constant name="COLOR_DEFAULT_MAX" value="2" enum="ColorDefault">
+		<constant name="COLOR_DEFAULT_TRANSPARENT" value="2" enum="ColorDefault">
+			Defaults to fully transparent black color.
+		</constant>
+		<constant name="COLOR_DEFAULT_MAX" value="3" enum="ColorDefault">
 			Represents the size of the [enum ColorDefault] enum.
 		</constant>
 		<constant name="FILTER_DEFAULT" value="0" enum="TextureFilter">

+ 3 - 0
drivers/gles3/storage/material_storage.cpp

@@ -1156,6 +1156,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
 						case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
 							gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_BLACK);
 						} break;
+						case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: {
+							gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_TRANSPARENT);
+						} break;
 						case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
 							gl_texture = texture_storage->texture_gl_get_default(DEFAULT_GL_TEXTURE_ANISO);
 						} break;

+ 11 - 0
drivers/gles3/storage/texture_storage.cpp

@@ -115,6 +115,17 @@ TextureStorage::TextureStorage() {
 			texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP);
 		}
 
+		{ // transparent black
+			Ref<Image> image;
+			image.instantiate();
+			image->create(4, 4, true, Image::FORMAT_RGBA8);
+			image->fill(Color(0, 0, 0, 0));
+			image->generate_mipmaps();
+
+			default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate();
+			texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image);
+		}
+
 		{
 			Ref<Image> image;
 			image.instantiate();

+ 1 - 0
drivers/gles3/storage/texture_storage.h

@@ -103,6 +103,7 @@ namespace GLES3 {
 enum DefaultGLTexture {
 	DEFAULT_GL_TEXTURE_WHITE,
 	DEFAULT_GL_TEXTURE_BLACK,
+	DEFAULT_GL_TEXTURE_TRANSPARENT,
 	DEFAULT_GL_TEXTURE_NORMAL,
 	DEFAULT_GL_TEXTURE_ANISO,
 	DEFAULT_GL_TEXTURE_DEPTH,

+ 6 - 1
scene/resources/visual_shader_nodes.cpp

@@ -5581,12 +5581,16 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty
 			case VisualShaderNodeTextureUniform::TYPE_DATA:
 				if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) {
 					type_code = "hint_default_black";
+				} else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) {
+					type_code = "hint_default_transparent";
 				}
 				break;
 			case VisualShaderNodeTextureUniform::TYPE_COLOR:
 				type_code = "source_color";
 				if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) {
 					type_code += ", hint_default_black";
+				} else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) {
+					type_code += ", hint_default_transparent";
 				}
 				break;
 			case VisualShaderNodeTextureUniform::TYPE_NORMAL_MAP:
@@ -5812,7 +5816,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat);
 
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type");
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black"), "set_color_default", "get_color_default");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat");
 
@@ -5824,6 +5828,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() {
 
 	BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE);
 	BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK);
+	BIND_ENUM_CONSTANT(COLOR_DEFAULT_TRANSPARENT);
 	BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX);
 
 	BIND_ENUM_CONSTANT(FILTER_DEFAULT);

+ 1 - 0
scene/resources/visual_shader_nodes.h

@@ -2131,6 +2131,7 @@ public:
 	enum ColorDefault {
 		COLOR_DEFAULT_WHITE,
 		COLOR_DEFAULT_BLACK,
+		COLOR_DEFAULT_TRANSPARENT,
 		COLOR_DEFAULT_MAX,
 	};
 

+ 3 - 0
servers/rendering/renderer_rd/storage_rd/material_storage.cpp

@@ -1125,6 +1125,9 @@ void MaterialStorage::MaterialData::update_textures(const HashMap<StringName, Va
 						case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
 							rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_BLACK);
 						} break;
+						case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: {
+							rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_TRANSPARENT);
+						} break;
 						case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
 							rd_texture = texture_storage->texture_rd_get_default(TextureStorage::DEFAULT_RD_TEXTURE_ANISO);
 						} break;

+ 18 - 0
servers/rendering/renderer_rd/storage_rd/texture_storage.cpp

@@ -96,6 +96,7 @@ TextureStorage::TextureStorage() {
 		Vector<uint8_t> pv;
 		pv.resize(16 * 4);
 		for (int i = 0; i < 16; i++) {
+			// Opaque white.
 			pv.set(i * 4 + 0, 255);
 			pv.set(i * 4 + 1, 255);
 			pv.set(i * 4 + 2, 255);
@@ -109,6 +110,7 @@ TextureStorage::TextureStorage() {
 		}
 
 		for (int i = 0; i < 16; i++) {
+			// Opaque black.
 			pv.set(i * 4 + 0, 0);
 			pv.set(i * 4 + 1, 0);
 			pv.set(i * 4 + 2, 0);
@@ -122,6 +124,21 @@ TextureStorage::TextureStorage() {
 		}
 
 		for (int i = 0; i < 16; i++) {
+			// Transparent black.
+			pv.set(i * 4 + 0, 0);
+			pv.set(i * 4 + 1, 0);
+			pv.set(i * 4 + 2, 0);
+			pv.set(i * 4 + 3, 0);
+		}
+
+		{
+			Vector<Vector<uint8_t>> vpv;
+			vpv.push_back(pv);
+			default_rd_textures[DEFAULT_RD_TEXTURE_TRANSPARENT] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+		}
+
+		for (int i = 0; i < 16; i++) {
+			// Opaque normal map "flat" color.
 			pv.set(i * 4 + 0, 128);
 			pv.set(i * 4 + 1, 128);
 			pv.set(i * 4 + 2, 255);
@@ -135,6 +152,7 @@ TextureStorage::TextureStorage() {
 		}
 
 		for (int i = 0; i < 16; i++) {
+			// Opaque flowmap "flat" color.
 			pv.set(i * 4 + 0, 255);
 			pv.set(i * 4 + 1, 128);
 			pv.set(i * 4 + 2, 255);

+ 1 - 0
servers/rendering/renderer_rd/storage_rd/texture_storage.h

@@ -46,6 +46,7 @@ public:
 	enum DefaultRDTexture {
 		DEFAULT_RD_TEXTURE_WHITE,
 		DEFAULT_RD_TEXTURE_BLACK,
+		DEFAULT_RD_TEXTURE_TRANSPARENT,
 		DEFAULT_RD_TEXTURE_NORMAL,
 		DEFAULT_RD_TEXTURE_ANISO,
 		DEFAULT_RD_TEXTURE_DEPTH,

+ 9 - 0
servers/rendering/shader_language.cpp

@@ -195,6 +195,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
 	"SOURCE_COLOR",
 	"HINT_DEFAULT_WHITE_TEXTURE",
 	"HINT_DEFAULT_BLACK_TEXTURE",
+	"HINT_DEFAULT_TRANSPARENT_TEXTURE",
 	"HINT_NORMAL_TEXTURE",
 	"HINT_ANISOTROPY_TEXTURE",
 	"HINT_RANGE",
@@ -354,6 +355,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
 	{ TK_HINT_NORMAL_TEXTURE, "hint_normal", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_DEFAULT_WHITE_TEXTURE, "hint_default_white", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_DEFAULT_BLACK_TEXTURE, "hint_default_black", CF_UNSPECIFIED, {}, {} },
+	{ TK_HINT_DEFAULT_TRANSPARENT_TEXTURE, "hint_default_transparent", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ANISOTROPY_TEXTURE, "hint_anisotropy", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_R, "hint_roughness_r", CF_UNSPECIFIED, {}, {} },
 	{ TK_HINT_ROUGHNESS_G, "hint_roughness_g", CF_UNSPECIFIED, {}, {} },
@@ -1088,6 +1090,9 @@ String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) {
 		case ShaderNode::Uniform::HINT_DEFAULT_WHITE: {
 			result = "hint_default_white";
 		} break;
+		case ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: {
+			result = "hint_default_transparent";
+		} break;
 		case ShaderNode::Uniform::HINT_ANISOTROPY: {
 			result = "hint_anisotropy";
 		} break;
@@ -8410,6 +8415,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 								case TK_HINT_DEFAULT_WHITE_TEXTURE: {
 									new_hint = ShaderNode::Uniform::HINT_DEFAULT_WHITE;
 								} break;
+								case TK_HINT_DEFAULT_TRANSPARENT_TEXTURE: {
+									new_hint = ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT;
+								} break;
 								case TK_HINT_NORMAL_TEXTURE: {
 									new_hint = ShaderNode::Uniform::HINT_NORMAL;
 								} break;
@@ -10248,6 +10256,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 					options.push_back("hint_anisotropy");
 					options.push_back("hint_default_black");
 					options.push_back("hint_default_white");
+					options.push_back("hint_default_transparent");
 					options.push_back("hint_normal");
 					options.push_back("hint_roughness_a");
 					options.push_back("hint_roughness_b");

+ 2 - 0
servers/rendering/shader_language.h

@@ -164,6 +164,7 @@ public:
 		TK_RENDER_MODE,
 		TK_HINT_DEFAULT_WHITE_TEXTURE,
 		TK_HINT_DEFAULT_BLACK_TEXTURE,
+		TK_HINT_DEFAULT_TRANSPARENT_TEXTURE,
 		TK_HINT_NORMAL_TEXTURE,
 		TK_HINT_ROUGHNESS_NORMAL_TEXTURE,
 		TK_HINT_ROUGHNESS_R,
@@ -664,6 +665,7 @@ public:
 				HINT_ROUGHNESS_GRAY,
 				HINT_DEFAULT_BLACK,
 				HINT_DEFAULT_WHITE,
+				HINT_DEFAULT_TRANSPARENT,
 				HINT_ANISOTROPY,
 				HINT_MAX
 			};