From 813f6a5d57be7c5003cc25521556c11215907a55 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 14 Aug 2021 18:29:52 +0200 Subject: [PATCH] Add `hint_transparent` to use a transparent black placeholder texture This can be used in shaders to avoid the need to supply a transparent placeholder texture manually. --- doc/classes/VisualShaderNodeTextureUniform.xml | 9 ++++++--- drivers/gles3/storage/material_storage.cpp | 3 +++ drivers/gles3/storage/texture_storage.cpp | 11 +++++++++++ drivers/gles3/storage/texture_storage.h | 1 + scene/resources/visual_shader_nodes.cpp | 7 ++++++- scene/resources/visual_shader_nodes.h | 1 + .../storage_rd/material_storage.cpp | 3 +++ .../renderer_rd/storage_rd/texture_storage.cpp | 18 ++++++++++++++++++ .../renderer_rd/storage_rd/texture_storage.h | 1 + servers/rendering/shader_language.cpp | 9 +++++++++ servers/rendering/shader_language.h | 2 ++ 11 files changed, 61 insertions(+), 4 deletions(-) diff --git a/doc/classes/VisualShaderNodeTextureUniform.xml b/doc/classes/VisualShaderNodeTextureUniform.xml index bff6f2015dd..9014f79f54c 100644 --- a/doc/classes/VisualShaderNodeTextureUniform.xml +++ b/doc/classes/VisualShaderNodeTextureUniform.xml @@ -39,12 +39,15 @@ Represents the size of the [enum TextureType] enum. - Defaults to white color. + Defaults to fully opaque white color. - Defaults to black color. + Defaults to fully opaque black color. - + + Defaults to fully transparent black color. + + Represents the size of the [enum ColorDefault] enum. diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index ac2f4f00197..24791b94d0f 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1156,6 +1156,9 @@ void MaterialData::update_textures(const HashMap &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; diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index c05f516548b..543638e8ff0 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/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.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.instantiate(); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 77ec1da6f52..71f713bc9fd 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/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, diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index b8667f07fe3..5cc2073ca51 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/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); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 1eb7b7240f4..f770156d148 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/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, }; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 8297e722604..88ce6c261cc 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -1125,6 +1125,9 @@ void MaterialStorage::MaterialData::update_textures(const HashMaptexture_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; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 17a6ad57f9a..e20a04ff2ac 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -96,6 +96,7 @@ TextureStorage::TextureStorage() { Vector 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> 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); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index f07f7647617..682c951f634 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/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, diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 2dd0f7006b3..7de175647b9 100644 --- a/servers/rendering/shader_language.cpp +++ b/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 &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"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 09160e29492..bfec6e1df6a 100644 --- a/servers/rendering/shader_language.h +++ b/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 };