From 028ef2edc863811318b75f43a23cbb2f0ee94910 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Tue, 9 Aug 2022 12:29:49 -0400 Subject: [PATCH] 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. --- drivers/gles3/rasterizer_canvas_gles3.cpp | 4 +- drivers/gles3/storage/material_storage.cpp | 62 ++++++++++++------- drivers/gles3/storage/material_storage.h | 2 + .../rendering/renderer_rd/environment/sky.cpp | 14 +++-- .../scene_shader_forward_clustered.cpp | 14 +++-- .../scene_shader_forward_clustered.h | 1 + .../scene_shader_forward_mobile.cpp | 12 ++-- .../renderer_rd/renderer_canvas_render_rd.cpp | 29 ++++++--- .../renderer_rd/renderer_canvas_render_rd.h | 1 + .../storage_rd/material_storage.cpp | 14 ++++- servers/rendering/shader_compiler.cpp | 43 ++++++++++++- servers/rendering/shader_compiler.h | 1 + servers/rendering/shader_language.cpp | 37 +++++++++-- servers/rendering/shader_language.h | 6 ++ 14 files changed, 189 insertions(+), 51 deletions(-) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index d4ac3c993ad..f548cb43103 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 9440a3a0ae0..7a52b0520e1 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 &p_paramet Vector 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::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 texture_uniform_names; @@ -2877,7 +2888,10 @@ void CanvasShaderData::get_param_list(List *p_param_list) const { HashMap order; for (const KeyValue &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::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 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::Element *el = gen_code.code.front(); + HashMap::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 *p_param_list) const { RBMap order; for (const KeyValue &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 8fc15ddcba4..64e0e2d8c17 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -159,6 +159,7 @@ struct CanvasShaderData : public ShaderData { HashMap> 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 147658bea9e..bef288a13b8 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::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 50ac08b57a8..6f8b70d1819 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::Element *el = gen_code.code.front(); + HashMap::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 HashMap order; for (const KeyValue &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 d4fc70cadad..579a2522989 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 ed5399a3afa..8abfe5640a5 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::Element * el = gen_code.code.front(); + HashMap::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 *p_ HashMap order; for (const KeyValue &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 27399298b3d..50e60f46771 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::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 HashMap order; for (const KeyValue &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 f96d4686ffd..e915c7861f1 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> 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 88ce6c261cc..e120424bbbe 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 HashMapglobal_shader_uniforms.variables.getptr(E.key); @@ -1052,6 +1058,12 @@ void MaterialStorage::MaterialData::update_textures(const HashMap 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 7637eae4a68..5653d6bfe26 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 &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 06f42e9f0f0..1ad43daf5fc 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 019f10fe38f..36e644c1b11 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 &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 &p_f case TK_REPEAT_ENABLE: { new_repeat = REPEAT_ENABLE; } break; + default: break; } @@ -8611,9 +8637,9 @@ Error ShaderLanguage::_parse_shader(const HashMap &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 &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 bfec6e1df6a..75b713d167f 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 };