diff options
author | clayjohn <claynjohn@gmail.com> | 2022-08-09 12:29:49 -0400 |
---|---|---|
committer | clayjohn <claynjohn@gmail.com> | 2022-08-09 12:29:49 -0400 |
commit | 028ef2edc863811318b75f43a23cbb2f0ee94910 (patch) | |
tree | 499d64c3b5f2fdd26a4cd871988ad025e2f795c4 | |
parent | ea4b8de2b4c06e6f18bf0470d716f787bddfecc3 (diff) |
Add shader uniform hints for screen textures so users can specify custom filter and repeat modes.
At this time, it works best in the Vulkan Renderers as they support using multiple samplers with the same texture.
In GLES3 this feature really only allows you to use the screen texture without mipmaps if you want to save the cost of generating them.
14 files changed, 189 insertions, 51 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index d4ac3c993a..f548cb4310 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/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; Rect2 back_buffer_rect; bool backbuffer_copy = false; + bool backbuffer_gen_mipmaps = false; Item *ci = p_item_list; 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) { backbuffer_copy = true; 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); 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; material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 9440a3a0ae..7a52b0520e 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1083,6 +1083,12 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet Vector<RID> textures; + if (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + continue; + } + if (p_texture_uniforms[i].global) { uses_global_textures = true; @@ -1492,9 +1498,9 @@ MaterialStorage::MaterialStorage() { actions.renames["POINT_COORD"] = "gl_PointCoord"; actions.renames["INSTANCE_CUSTOM"] = "instance_custom"; actions.renames["SCREEN_UV"] = "screen_uv"; - actions.renames["SCREEN_TEXTURE"] = "color_buffer"; - actions.renames["DEPTH_TEXTURE"] = "depth_buffer"; - actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; + //actions.renames["SCREEN_TEXTURE"] = "color_buffer"; //Not implemented in 3D yet. + //actions.renames["DEPTH_TEXTURE"] = "depth_buffer"; // Not implemented in 3D yet. + //actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; // Not implemented in 3D yet actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; actions.renames["FOG"] = "fog"; @@ -2789,6 +2795,7 @@ void CanvasShaderData::set_code(const String &p_code) { ubo_size = 0; uniforms.clear(); uses_screen_texture = false; + uses_screen_texture_mipmaps = false; uses_sdf = false; uses_time = false; @@ -2799,7 +2806,6 @@ void CanvasShaderData::set_code(const String &p_code) { ShaderCompiler::GeneratedCode gen_code; int blend_modei = BLEND_MODE_MIX; - uses_screen_texture = false; ShaderCompiler::IdentifierActions actions; actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX; @@ -2826,6 +2832,7 @@ void CanvasShaderData::set_code(const String &p_code) { } blend_mode = BlendMode(blend_modei); + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; #if 0 print_line("**compiling shader:"); @@ -2833,12 +2840,16 @@ void CanvasShaderData::set_code(const String &p_code) { for (int i = 0; i < gen_code.defines.size(); i++) { print_line(gen_code.defines[i]); } + + HashMap<String, String>::Iterator el = gen_code.code.begin(); + while (el) { + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; + } + print_line("\n**uniforms:\n" + gen_code.uniforms); - print_line("\n**vertex_globals:\n" + gen_code.vertex_global); - print_line("\n**vertex_code:\n" + gen_code.vertex); - print_line("\n**fragment_globals:\n" + gen_code.fragment_global); - print_line("\n**fragment_code:\n" + gen_code.fragment); - print_line("\n**light_code:\n" + gen_code.light); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif Vector<StringName> texture_uniform_names; @@ -2877,7 +2888,10 @@ void CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { continue; } if (E.value.texture_order >= 0) { @@ -3070,12 +3084,16 @@ void SkyShaderData::set_code(const String &p_code) { for (int i = 0; i < gen_code.defines.size(); i++) { print_line(gen_code.defines[i]); } + + HashMap<String, String>::Iterator el = gen_code.code.begin(); + while (el) { + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; + } + print_line("\n**uniforms:\n" + gen_code.uniforms); - // print_line("\n**vertex_globals:\n" + gen_code.vertex_global); - // print_line("\n**vertex_code:\n" + gen_code.vertex); - print_line("\n**fragment_globals:\n" + gen_code.fragment_global); - print_line("\n**fragment_code:\n" + gen_code.fragment); - print_line("\n**light_code:\n" + gen_code.light); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif Vector<StringName> texture_uniform_names; @@ -3253,7 +3271,6 @@ void SceneShaderData::set_code(const String &p_code) { valid = false; ubo_size = 0; uniforms.clear(); - uses_screen_texture = false; if (code.is_empty()) { return; //just invalid, but no error @@ -3378,6 +3395,7 @@ void SceneShaderData::set_code(const String &p_code) { vertex_input_mask |= uses_custom3 << 8; vertex_input_mask |= uses_bones << 9; vertex_input_mask |= uses_weights << 10; + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; #if 0 print_line("**compiling shader:"); @@ -3386,11 +3404,10 @@ void SceneShaderData::set_code(const String &p_code) { print_line(gen_code.defines[i]); } - Map<String, String>::Element *el = gen_code.code.front(); + HashMap<String, String>::Iterator el = gen_code.code.begin(); while (el) { - print_line("\n**code " + el->key() + ":\n" + el->value()); - - el = el->next(); + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; } print_line("\n**uniforms:\n" + gen_code.uniforms); @@ -3439,7 +3456,10 @@ void SceneShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { RBMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { continue; } diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 8fc15ddcba..64e0e2d8c1 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -159,6 +159,7 @@ struct CanvasShaderData : public ShaderData { HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_screen_texture = false; + bool uses_screen_texture_mipmaps = false; bool uses_sdf = false; bool uses_time = false; @@ -312,6 +313,7 @@ struct SceneShaderData : public ShaderData { bool uses_sss; bool uses_transmittance; bool uses_screen_texture; + bool uses_screen_texture_mipmaps; bool uses_depth_texture; bool uses_normal_texture; bool uses_time; diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 147658bea9..bef288a13b 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/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++) { print_line(gen_code.defines[i]); } + + HashMap<String, String>::Iterator el = gen_code.code.begin(); + while (el) { + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; + } + print_line("\n**uniforms:\n" + gen_code.uniforms); - // print_line("\n**vertex_globals:\n" + gen_code.vertex_global); - // print_line("\n**vertex_code:\n" + gen_code.vertex); - print_line("\n**fragment_globals:\n" + gen_code.fragment_global); - print_line("\n**fragment_code:\n" + gen_code.fragment); - print_line("\n**light_code:\n" + gen_code.light); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif 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); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 50ac08b57a..6f8b70d181 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/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_test = DepthTest(depth_testi); cull_mode = Cull(cull_modei); + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; #if 0 print_line("**compiling shader:"); @@ -158,11 +159,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { 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) { - 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); @@ -396,7 +396,11 @@ void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + // Don't expose any of these. continue; } diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index d4fc70cada..579a252298 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -174,6 +174,7 @@ public: bool uses_time = false; bool writes_modelview_or_projection = false; bool uses_world_coordinates = false; + bool uses_screen_texture_mipmaps = false; Cull cull_mode = CULL_DISABLED; uint64_t last_pass = 0; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index ed5399a3af..8abfe5640a 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/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]); } - RBMap<String, String>::Element * el = gen_code.code.front(); + HashMap<String, String>::Iterator el = gen_code.code.begin(); while (el) { - print_line("\n**code " + el->key() + ":\n" + el->value()); - - el = el->next(); + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; } print_line("\n**uniforms:\n" + gen_code.uniforms); @@ -353,7 +352,10 @@ void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_ HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { continue; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 27399298b3..50e60f4677 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/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; Rect2 back_buffer_rect; bool backbuffer_copy = false; + bool backbuffer_gen_mipmaps = false; 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) { backbuffer_copy = true; 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); 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_gen_mipmaps = false; 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; uniforms.clear(); uses_screen_texture = false; + uses_screen_texture_mipmaps = false; uses_sdf = false; uses_time = false; @@ -1990,7 +1994,6 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) { ShaderCompiler::GeneratedCode gen_code; int blend_mode = BLEND_MODE_MIX; - uses_screen_texture = false; ShaderCompiler::IdentifierActions actions; 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); ERR_FAIL_COND_MSG(err != OK, "Shader compilation failed."); + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; + if (version.is_null()) { 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++) { print_line(gen_code.defines[i]); } + + HashMap<String, String>::Iterator el = gen_code.code.begin(); + while (el) { + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; + } + print_line("\n**uniforms:\n" + gen_code.uniforms); - print_line("\n**vertex_globals:\n" + gen_code.vertex_global); - print_line("\n**vertex_code:\n" + gen_code.vertex); - print_line("\n**fragment_globals:\n" + gen_code.fragment_global); - print_line("\n**fragment_code:\n" + gen_code.fragment); - print_line("\n**light_code:\n" + gen_code.light); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif 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)); @@ -2175,7 +2184,11 @@ void RendererCanvasRenderRD::CanvasShaderData::get_param_list(List<PropertyInfo> HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + // Don't expose any of these. continue; } if (E.value.texture_order >= 0) { diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index f96d4686ff..e915c7861f 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/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; bool uses_screen_texture = false; + bool uses_screen_texture_mipmaps = false; bool uses_sdf = false; bool uses_time = false; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index 88ce6c261c..e120424bbb 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/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 } + 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) { //this is a global variable, get the index to it 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; + if (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + continue; + } + if (p_texture_uniforms[i].global) { uses_global_textures = true; @@ -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); } - 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. return false; } diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 7637eae4a6..5653d6bfe2 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/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) { 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++; } else { 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); 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)) { // Texture layouts are different for OpenGL GLSL and Vulkan GLSL 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)) { code = p_default_actions.renames[vnode->name]; + if (vnode->name == "SCREEN_TEXTURE") { + r_gen_code.uses_screen_texture_mipmaps = true; + } } else { if (shader->uniforms.has(vnode->name)) { //its a uniform! const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name]; 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 { //a scalar or vector 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) { + //TODO Needs to detect screen_texture hint as well is_screen_texture = (texture_uniform == "SCREEN_TEXTURE"); 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_vertex_time = false; r_gen_code.uses_global_textures = false; + r_gen_code.uses_screen_texture_mipmaps = false; used_name_defines.clear(); used_rmode_defines.clear(); diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h index 06f42e9f0f..1ad43daf5f 100644 --- a/servers/rendering/shader_compiler.h +++ b/servers/rendering/shader_compiler.h @@ -80,6 +80,7 @@ public: bool uses_global_textures; bool uses_fragment_time; bool uses_vertex_time; + bool uses_screen_texture_mipmaps; }; struct DefaultIdentifierActions { diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 019f10fe38..36e644c1b1 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -200,6 +200,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "HINT_ANISOTROPY_TEXTURE", "HINT_RANGE", "HINT_INSTANCE_INDEX", + "HINT_SCREEN_TEXTURE", + "HINT_NORMAL_ROUGHNESS_TEXTURE", + "HINT_DEPTH_TEXTURE", "FILTER_NEAREST", "FILTER_LINEAR", "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_NORMAL_TEXTURE, "hint_roughness_normal", 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_LINEAR, "filter_linear", 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: { result = "hint_anisotropy"; } 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: break; } @@ -8563,6 +8579,15 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f return ERR_PARSE_ERROR; } } 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: { new_filter = FILTER_NEAREST; } break; @@ -8587,6 +8612,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f case TK_REPEAT_ENABLE: { new_repeat = REPEAT_ENABLE; } break; + default: break; } @@ -8611,9 +8637,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f if (new_filter != FILTER_DEFAULT) { if (uniform.filter != FILTER_DEFAULT) { 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 { - _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; } else { @@ -8624,9 +8650,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f if (new_repeat != REPEAT_DEFAULT) { if (uniform.repeat != REPEAT_DEFAULT) { 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 { - _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; } else { @@ -10267,6 +10293,9 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ options.push_back("hint_roughness_gray"); options.push_back("hint_roughness_normal"); 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("repeat_enable"); options.push_back("repeat_disable"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index bfec6e1df6..75b713d167 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -176,6 +176,9 @@ public: TK_HINT_SOURCE_COLOR, TK_HINT_RANGE, TK_HINT_INSTANCE_INDEX, + TK_HINT_SCREEN_TEXTURE, + TK_HINT_NORMAL_ROUGHNESS_TEXTURE, + TK_HINT_DEPTH_TEXTURE, TK_FILTER_NEAREST, TK_FILTER_LINEAR, TK_FILTER_NEAREST_MIPMAP, @@ -667,6 +670,9 @@ public: HINT_DEFAULT_WHITE, HINT_DEFAULT_TRANSPARENT, HINT_ANISOTROPY, + HINT_SCREEN_TEXTURE, + HINT_NORMAL_ROUGHNESS_TEXTURE, + HINT_DEPTH_TEXTURE, HINT_MAX }; |