diff options
author | reduz <reduzio@gmail.com> | 2021-04-13 17:01:43 -0300 |
---|---|---|
committer | reduz <reduzio@gmail.com> | 2021-04-14 11:37:52 -0300 |
commit | d3b49c416ab0f2009bb41a035f8171726f892cce (patch) | |
tree | 12b9832f1840a72c886680cadd55a7b6bcf74cd3 | |
parent | 8ce0fb0a946455ed6a7bc8a54fcf90a9d5a9ae4d (diff) |
Refactor GLSL shader compilation
-Used a more consistent set of keywords for the shader
-Remove all harcoded entry points
-Re-wrote the GLSL shader parser, new system is more flexible. Allows any entry point organization.
-Entry point for sky shaders is now sky().
-Entry point for particle shaders is now process().
64 files changed, 409 insertions, 798 deletions
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 8f8a4b3054..ed3b746678 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -205,7 +205,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo ShaderLanguage sl; String calltip; - sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip); + sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip); get_text_editor()->set_code_hint(calltip); } @@ -219,7 +219,7 @@ void ShaderTextEditor::_validate_script() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); if (err != OK) { String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index b2fa9c540e..e5b8dfd464 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -3398,7 +3398,7 @@ void VisualShaderEditor::_update_preview() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); for (int i = 0; i < preview_text->get_line_count(); i++) { preview_text->set_line_as_marked(i, false); diff --git a/modules/lightmapper_rd/lm_blendseams.glsl b/modules/lightmapper_rd/lm_blendseams.glsl index e47e5fcc51..374c48082e 100644 --- a/modules/lightmapper_rd/lm_blendseams.glsl +++ b/modules/lightmapper_rd/lm_blendseams.glsl @@ -7,7 +7,7 @@ triangles = "#define MODE_TRIANGLES"; #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "lm_common_inc.glsl" @@ -74,7 +74,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "lm_common_inc.glsl" diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index eb9d817f99..3dd96893fb 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -10,7 +10,7 @@ light_probes = "#define MODE_LIGHT_PROBES"; #version 450 -VERSION_DEFINES +#VERSION_DEFINES // One 2D local group focusing in one layer at a time, though all // in parallel (no barriers) makes more sense than a 3D local group diff --git a/modules/lightmapper_rd/lm_raster.glsl b/modules/lightmapper_rd/lm_raster.glsl index 6c2904192b..55ca193cc1 100644 --- a/modules/lightmapper_rd/lm_raster.glsl +++ b/modules/lightmapper_rd/lm_raster.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "lm_common_inc.glsl" @@ -56,7 +56,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "lm_common_inc.glsl" diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 195ce070a7..6a65173176 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -289,7 +289,7 @@ void ParticlesMaterial::_update_shader() { code += "}\n"; code += "\n"; - code += "void compute() {\n"; + code += "void process() {\n"; code += " uint base_number = NUMBER;\n"; code += " uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n"; code += " float angle_rand = rand_from_seed(alt_seed);\n"; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index b2efecb1cb..f50ee9c4c8 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -194,7 +194,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "uniform float sun_angle_max = 1.74;\n"; code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n"; code += "const float PI = 3.1415926535897932384626433833;\n\n"; - code += "void fragment() {\n"; + code += "void sky() {\n"; code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n"; code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n"; code += "\tvec3 sky = mix(sky_horizon_color.rgb, sky_top_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / sky_curve), 0.0, 1.0));\n"; @@ -301,7 +301,7 @@ PanoramaSkyMaterial::PanoramaSkyMaterial() { String code = "shader_type sky;\n\n"; code += "uniform sampler2D source_panorama : filter_linear;\n"; - code += "void fragment() {\n"; + code += "void sky() {\n"; code += "\tCOLOR = texture(source_panorama, SKY_COORDS).rgb;\n"; code += "}"; @@ -521,7 +521,7 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "\treturn fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n"; code += "}\n\n"; - code += "void fragment() {\n"; + code += "void sky() {\n"; code += "\tif (LIGHT0_ENABLED) {\n"; code += "\t\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n"; code += "\t\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n"; 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 45f6384b5e..15982b4b29 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 @@ -77,6 +77,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { int depth_drawi = DEPTH_DRAW_OPAQUE; ShaderCompilerRD::IdentifierActions actions; + actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX; + actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT; + actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT; actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD); actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX); @@ -148,7 +151,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { print_line("\n**fragment_code:\n" + gen_code.fragment); print_line("\n**light_code:\n" + gen_code.light); #endif - shader_singleton->shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines); + shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 7d6e2fa8e4..3c76c91a67 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2012,6 +2012,9 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { uses_screen_texture = false; ShaderCompilerRD::IdentifierActions actions; + actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX; + actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT; + actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT; actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD); actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX); @@ -2048,7 +2051,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) { print_line("\n**fragment_code:\n" + gen_code.fragment); print_line("\n**light_code:\n" + gen_code.light); #endif - canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines); + canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 769335ac16..54c6e81110 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -50,6 +50,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { ShaderCompilerRD::GeneratedCode gen_code; ShaderCompilerRD::IdentifierActions actions; + actions.entry_point_stages["sky"] = ShaderCompilerRD::STAGE_FRAGMENT; uses_time = false; uses_half_res = false; @@ -110,7 +111,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { print_line("\n**light_code:\n" + gen_code.light); #endif - scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines); + scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines); ERR_FAIL_COND(!scene_singleton->sky.sky_shader.shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -759,7 +760,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { sky_shader.default_shader = storage->shader_allocate(); storage->shader_initialize(sky_shader.default_shader); - storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n"); + storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void sky() { COLOR = vec3(0.0); } \n"); sky_shader.default_material = storage->material_allocate(); storage->material_initialize(sky_shader.default_material); @@ -840,7 +841,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { sky_scene_state.fog_shader = storage->shader_allocate(); storage->shader_initialize(sky_scene_state.fog_shader); - storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void fragment() { COLOR = clear_color.rgb; } \n"); + storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void sky() { COLOR = clear_color.rgb; } \n"); sky_scene_state.fog_material = storage->material_allocate(); storage->material_initialize(sky_scene_state.fog_material); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index b984f850a0..92df9cc702 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -4781,6 +4781,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { ShaderCompilerRD::GeneratedCode gen_code; ShaderCompilerRD::IdentifierActions actions; + actions.entry_point_stages["process"] = ShaderCompilerRD::STAGE_COMPUTE; /* uses_time = false; @@ -4801,7 +4802,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { version = base_singleton->particles_shader.shader.version_create(); } - base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.uniforms, gen_code.compute_global, gen_code.compute, gen_code.defines); + base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines); ERR_FAIL_COND(!base_singleton->particles_shader.shader.version_is_valid(version)); ubo_size = gen_code.uniform_total_size; @@ -8824,7 +8825,6 @@ RendererStorageRD::RendererStorageRD() { sdf_versions.push_back(""); //one only giprobe_sdf_shader.initialize(sdf_versions); giprobe_sdf_shader_version = giprobe_sdf_shader.version_create(); - giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>()); giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0); giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader); } @@ -8913,7 +8913,7 @@ RendererStorageRD::RendererStorageRD() { // default material and shader for particles shader particles_shader.default_shader = shader_allocate(); shader_initialize(particles_shader.default_shader); - shader_set_code(particles_shader.default_shader, "shader_type particles; void compute() { COLOR = vec4(1.0); } \n"); + shader_set_code(particles_shader.default_shader, "shader_type particles; void process() { COLOR = vec4(1.0); } \n"); particles_shader.default_material = material_allocate(); material_initialize(particles_shader.default_material); material_set_shader(particles_shader.default_material, particles_shader.default_shader); diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 8135d388e1..24ac85bb35 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -535,9 +535,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge struct_code += "}"; struct_code += ";\n"; - r_gen_code.vertex_global += struct_code; - r_gen_code.fragment_global += struct_code; - r_gen_code.compute_global += struct_code; + for (int j = 0; j < STAGE_MAX; j++) { + r_gen_code.stage_globals[j] += struct_code; + } } int max_texture_uniforms = 0; @@ -590,9 +590,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge ucode += " " + _mkid(E->key()); ucode += ";\n"; if (SL::is_sampler_type(E->get().type)) { - r_gen_code.vertex_global += ucode; - r_gen_code.fragment_global += ucode; - r_gen_code.compute_global += ucode; + for (int j = 0; j < STAGE_MAX; j++) { + r_gen_code.stage_globals[j] += ucode; + } GeneratedCode::Texture texture; texture.name = E->key(); @@ -608,7 +608,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge r_gen_code.texture_uniforms.write[E->get().texture_order] = texture; } else { if (!uses_uniforms) { - r_gen_code.defines.push_back(String("#define USE_MATERIAL_UNIFORMS\n")); uses_uniforms = true; } uniform_defines.write[E->get().order] = ucode; @@ -707,9 +706,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge vcode += "]"; } vcode += ";\n"; - r_gen_code.vertex_global += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode; - r_gen_code.fragment_global += "layout(location=" + itos(index) + ") " + interp_mode + "in " + vcode; - r_gen_code.compute_global += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode; + + r_gen_code.stage_globals[STAGE_VERTEX] += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode; + r_gen_code.stage_globals[STAGE_FRAGMENT] += "layout(location=" + itos(index) + ") " + interp_mode + "in " + vcode; + index++; } @@ -725,7 +725,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge gcode += ";\n"; } gcode += "} frag_to_light;\n"; - r_gen_code.fragment_global += gcode; + r_gen_code.stage_globals[STAGE_FRAGMENT] += gcode; } for (int i = 0; i < pnode->vconstants.size(); i++) { @@ -747,9 +747,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge gcode += "="; gcode += _dump_node_code(cnode.initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); gcode += ";\n"; - r_gen_code.vertex_global += gcode; - r_gen_code.fragment_global += gcode; - r_gen_code.compute_global += gcode; + for (int j = 0; j < STAGE_MAX; j++) { + r_gen_code.stage_globals[j] += gcode; + } } Map<StringName, String> function_code; @@ -765,9 +765,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge //place functions in actual code - Set<StringName> added_vtx; - Set<StringName> added_fragment; //share for light - Set<StringName> added_compute; //share for light + Set<StringName> added_funcs_per_stage[STAGE_MAX]; for (int i = 0; i < pnode->functions.size(); i++) { SL::FunctionNode *fnode = pnode->functions[i].function; @@ -776,24 +774,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge current_func_name = fnode->name; - if (fnode->name == vertex_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.vertex_global, added_vtx); - r_gen_code.vertex = function_code[vertex_name]; - } - - if (fnode->name == fragment_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); - r_gen_code.fragment = function_code[fragment_name]; - } - - if (fnode->name == light_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); - r_gen_code.light = function_code[light_name]; - } - - if (fnode->name == compute_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.compute_global, added_compute); - r_gen_code.compute = function_code[compute_name]; + if (p_actions.entry_point_stages.has(fnode->name)) { + Stage stage = p_actions.entry_point_stages[fnode->name]; + _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.stage_globals[stage], added_funcs_per_stage[stage]); + r_gen_code.code[fnode->name] = function_code[fnode->name]; } function = nullptr; @@ -858,7 +842,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge SL::VariableNode *vnode = (SL::VariableNode *)p_node; bool use_fragment_varying = false; - if (current_func_name != vertex_name) { + if (!(p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX)) { if (p_assigning) { if (shader->varyings.has(vnode->name)) { use_fragment_varying = true; @@ -921,10 +905,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } if (vnode->name == time_name) { - if (current_func_name == vertex_name) { + if (p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX) { r_gen_code.uses_vertex_time = true; } - if (current_func_name == fragment_name || current_func_name == light_name) { + if (p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_FRAGMENT) { r_gen_code.uses_fragment_time = true; } } @@ -1003,7 +987,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge SL::ArrayNode *anode = (SL::ArrayNode *)p_node; bool use_fragment_varying = false; - if (current_func_name != vertex_name) { + if (!(p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX)) { if (anode->assign_expression != nullptr) { use_fragment_varying = true; } else { @@ -1059,10 +1043,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } if (anode->name == time_name) { - if (current_func_name == vertex_name) { + if (p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX) { r_gen_code.uses_vertex_time = true; } - if (current_func_name == fragment_name || current_func_name == light_name) { + if (p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_FRAGMENT) { r_gen_code.uses_fragment_time = true; } } @@ -1309,7 +1293,7 @@ ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName & } Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { - Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types(), _get_variable_type); + Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_variable_type); if (err != OK) { Vector<String> shader = p_code.split("\n"); @@ -1322,13 +1306,10 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide } r_gen_code.defines.clear(); - r_gen_code.vertex = String(); - r_gen_code.vertex_global = String(); - r_gen_code.fragment = String(); - r_gen_code.fragment_global = String(); - r_gen_code.compute = String(); - r_gen_code.compute_global = String(); - r_gen_code.light = String(); + r_gen_code.code.clear(); + for (int i = 0; i < STAGE_MAX; i++) { + r_gen_code.stage_globals[i] = String(); + } r_gen_code.uses_fragment_time = false; r_gen_code.uses_vertex_time = false; r_gen_code.uses_global_textures = false; @@ -1348,10 +1329,6 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) { actions = p_actions; - vertex_name = "vertex"; - fragment_name = "fragment"; - compute_name = "compute"; - light_name = "light"; time_name = "TIME"; List<String> func_list; diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h index 6575829e73..2da127ffa3 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.h +++ b/servers/rendering/renderer_rd/shader_compiler_rd.h @@ -38,7 +38,16 @@ class ShaderCompilerRD { public: + enum Stage { + STAGE_VERTEX, + STAGE_FRAGMENT, + STAGE_COMPUTE, + STAGE_MAX + }; + struct IdentifierActions { + Map<StringName, Stage> entry_point_stages; + Map<StringName, Pair<int *, int>> render_mode_values; Map<StringName, bool *> render_mode_flags; Map<StringName, bool *> usage_flag_pointers; @@ -63,13 +72,9 @@ public: Vector<uint32_t> uniform_offsets; uint32_t uniform_total_size; String uniforms; - String vertex_global; - String vertex; - String fragment_global; - String fragment; - String light; - String compute_global; - String compute; + String stage_globals[STAGE_MAX]; + + Map<String, String> code; bool uses_global_textures; bool uses_fragment_time; @@ -103,10 +108,6 @@ private: const ShaderLanguage::ShaderNode *shader; const ShaderLanguage::FunctionNode *function; StringName current_func_name; - StringName vertex_name; - StringName fragment_name; - StringName light_name; - StringName compute_name; StringName time_name; Set<StringName> texture_functions; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index e4a39ff813..c48a2ef48c 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -30,146 +30,83 @@ #include "shader_rd.h" -#include "core/string/string_builder.h" #include "renderer_compositor_rd.h" #include "servers/rendering/rendering_device.h" -void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) { - name = p_name; - //split vertex and shader code (thank you, shader compiler programmers from you know what company). - if (p_vertex_code) { - String defines_tag = "\nVERSION_DEFINES"; - String globals_tag = "\nVERTEX_SHADER_GLOBALS"; - String material_tag = "\nMATERIAL_UNIFORMS"; - String code_tag = "\nVERTEX_SHADER_CODE"; - String code = p_vertex_code; - - int cpos = code.find(defines_tag); - if (cpos != -1) { - vertex_codev = code.substr(0, cpos).ascii(); - code = code.substr(cpos + defines_tag.length(), code.length()); - } - - cpos = code.find(material_tag); - - if (cpos == -1) { - vertex_code0 = code.ascii(); - } else { - vertex_code0 = code.substr(0, cpos).ascii(); - code = code.substr(cpos + material_tag.length(), code.length()); - - cpos = code.find(globals_tag); - - if (cpos == -1) { - vertex_code1 = code.ascii(); - } else { - vertex_code1 = code.substr(0, cpos).ascii(); - String code2 = code.substr(cpos + globals_tag.length(), code.length()); - - cpos = code2.find(code_tag); - if (cpos == -1) { - vertex_code2 = code2.ascii(); - } else { - vertex_code2 = code2.substr(0, cpos).ascii(); - vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); +void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) { + Vector<String> lines = String(p_code).split("\n"); + + String text; + + for (int i = 0; i < lines.size(); i++) { + String l = lines[i]; + bool push_chunk = false; + + StageTemplate::Chunk chunk; + + if (l.begins_with("#VERSION_DEFINES")) { + chunk.type = StageTemplate::Chunk::TYPE_VERSION_DEFINES; + push_chunk = true; + } else if (l.begins_with("#GLOBALS")) { + switch (p_stage_type) { + case STAGE_TYPE_VERTEX: + chunk.type = StageTemplate::Chunk::TYPE_VERTEX_GLOBALS; + break; + case STAGE_TYPE_FRAGMENT: + chunk.type = StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS; + break; + case STAGE_TYPE_COMPUTE: + chunk.type = StageTemplate::Chunk::TYPE_COMPUTE_GLOBALS; + break; + default: { } } - } - } - if (p_fragment_code) { - String defines_tag = "\nVERSION_DEFINES"; - String globals_tag = "\nFRAGMENT_SHADER_GLOBALS"; - String material_tag = "\nMATERIAL_UNIFORMS"; - String code_tag = "\nFRAGMENT_SHADER_CODE"; - String light_code_tag = "\nLIGHT_SHADER_CODE"; - String code = p_fragment_code; - - int cpos = code.find(defines_tag); - if (cpos != -1) { - fragment_codev = code.substr(0, cpos).ascii(); - code = code.substr(cpos + defines_tag.length(), code.length()); + push_chunk = true; + } else if (l.begins_with("#MATERIAL_UNIFORMS")) { + chunk.type = StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS; + push_chunk = true; + } else if (l.begins_with("#CODE")) { + chunk.type = StageTemplate::Chunk::TYPE_CODE; + push_chunk = true; + chunk.code = l.replace_first("#CODE", String()).replace(":", "").strip_edges().to_upper(); + } else { + text += l + "\n"; } - cpos = code.find(material_tag); - if (cpos == -1) { - fragment_code0 = code.ascii(); - } else { - fragment_code0 = code.substr(0, cpos).ascii(); - //print_line("CODE0:\n"+String(fragment_code0.get_data())); - code = code.substr(cpos + material_tag.length(), code.length()); - cpos = code.find(globals_tag); - - if (cpos == -1) { - fragment_code1 = code.ascii(); - } else { - fragment_code1 = code.substr(0, cpos).ascii(); - //print_line("CODE1:\n"+String(fragment_code1.get_data())); - - String code2 = code.substr(cpos + globals_tag.length(), code.length()); - cpos = code2.find(light_code_tag); - - if (cpos == -1) { - fragment_code2 = code2.ascii(); - } else { - fragment_code2 = code2.substr(0, cpos).ascii(); - //print_line("CODE2:\n"+String(fragment_code2.get_data())); - - String code3 = code2.substr(cpos + light_code_tag.length(), code2.length()); - - cpos = code3.find(code_tag); - if (cpos == -1) { - fragment_code3 = code3.ascii(); - } else { - fragment_code3 = code3.substr(0, cpos).ascii(); - //print_line("CODE3:\n"+String(fragment_code3.get_data())); - fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii(); - //print_line("CODE4:\n"+String(fragment_code4.get_data())); - } - } + if (push_chunk) { + if (text != String()) { + StageTemplate::Chunk text_chunk; + text_chunk.type = StageTemplate::Chunk::TYPE_TEXT; + text_chunk.text = text.utf8(); + stage_templates[p_stage_type].chunks.push_back(text_chunk); + text = String(); } + stage_templates[p_stage_type].chunks.push_back(chunk); } } + if (text != String()) { + StageTemplate::Chunk text_chunk; + text_chunk.type = StageTemplate::Chunk::TYPE_TEXT; + text_chunk.text = text.utf8(); + stage_templates[p_stage_type].chunks.push_back(text_chunk); + text = String(); + } +} + +void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) { + name = p_name; if (p_compute_code) { + _add_stage(p_compute_code, STAGE_TYPE_COMPUTE); is_compute = true; - - String defines_tag = "\nVERSION_DEFINES"; - String globals_tag = "\nCOMPUTE_SHADER_GLOBALS"; - String material_tag = "\nMATERIAL_UNIFORMS"; - String code_tag = "\nCOMPUTE_SHADER_CODE"; - String code = p_compute_code; - - int cpos = code.find(defines_tag); - if (cpos != -1) { - compute_codev = code.substr(0, cpos).ascii(); - code = code.substr(cpos + defines_tag.length(), code.length()); + } else { + is_compute = false; + if (p_vertex_code) { + _add_stage(p_vertex_code, STAGE_TYPE_VERTEX); } - - cpos = code.find(material_tag); - - if (cpos == -1) { - compute_code0 = code.ascii(); - } else { - compute_code0 = code.substr(0, cpos).ascii(); - code = code.substr(cpos + material_tag.length(), code.length()); - - cpos = code.find(globals_tag); - - if (cpos == -1) { - compute_code1 = code.ascii(); - } else { - compute_code1 = code.substr(0, cpos).ascii(); - String code2 = code.substr(cpos + globals_tag.length(), code.length()); - - cpos = code2.find(code_tag); - if (cpos == -1) { - compute_code2 = code2.ascii(); - } else { - compute_code2 = code2.substr(0, cpos).ascii(); - compute_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); - } - } + if (p_fragment_code) { + _add_stage(p_fragment_code, STAGE_TYPE_FRAGMENT); } } } @@ -198,6 +135,49 @@ void ShaderRD::_clear_version(Version *p_version) { } } +void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template) { + for (uint32_t i = 0; i < p_template.chunks.size(); i++) { + const StageTemplate::Chunk &chunk = p_template.chunks[i]; + switch (chunk.type) { + case StageTemplate::Chunk::TYPE_VERSION_DEFINES: { + builder.append("\n"); //make sure defines begin at newline + builder.append(general_defines.get_data()); + builder.append(variant_defines[p_variant].get_data()); + for (int j = 0; j < p_version->custom_defines.size(); j++) { + builder.append(p_version->custom_defines[j].get_data()); + } + builder.append("\n"); //make sure defines begin at newline + if (p_version->uniforms.size()) { + builder.append("#define MATERIAL_UNIFORMS_USED\n"); + } + for (Map<StringName, CharString>::Element *E = p_version->code_sections.front(); E; E = E->next()) { + builder.append(String("#define ") + String(E->key()) + "_CODE_USED\n"); + } + } break; + case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: { + builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment) + } break; + case StageTemplate::Chunk::TYPE_VERTEX_GLOBALS: { + builder.append(p_version->vertex_globals.get_data()); // vertex globals + } break; + case StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS: { + builder.append(p_version->fragment_globals.get_data()); // fragment globals + } break; + case StageTemplate::Chunk::TYPE_COMPUTE_GLOBALS: { + builder.append(p_version->compute_globals.get_data()); // compute globals + } break; + case StageTemplate::Chunk::TYPE_CODE: { + if (p_version->code_sections.has(chunk.code)) { + builder.append(p_version->code_sections[chunk.code].get_data()); + } + } break; + case StageTemplate::Chunk::TYPE_TEXT: { + builder.append(chunk.text.get_data()); + } break; + } + } +} + void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (!variants_enabled[p_variant]) { return; //variant is disabled, return @@ -214,29 +194,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { //vertex stage StringBuilder builder; - - builder.append(vertex_codev.get_data()); // version info (if exists) - builder.append("\n"); //make sure defines begin at newline - builder.append(general_defines.get_data()); - builder.append(variant_defines[p_variant].get_data()); - - for (int j = 0; j < p_version->custom_defines.size(); j++) { - builder.append(p_version->custom_defines[j].get_data()); - } - - builder.append(vertex_code0.get_data()); //first part of vertex - - builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment) - - builder.append(vertex_code1.get_data()); //second part of vertex - - builder.append(p_version->vertex_globals.get_data()); // vertex globals - - builder.append(vertex_code2.get_data()); //third part of vertex - - builder.append(p_version->vertex_code.get_data()); // code - - builder.append(vertex_code3.get_data()); //fourth of vertex + _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_VERTEX]); current_source = builder.as_string(); RD::ShaderStageData stage; @@ -254,33 +212,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { current_stage = RD::SHADER_STAGE_FRAGMENT; StringBuilder builder; - - builder.append(fragment_codev.get_data()); // version info (if exists) - builder.append("\n"); //make sure defines begin at newline - - builder.append(general_defines.get_data()); - builder.append(variant_defines[p_variant].get_data()); - for (int j = 0; j < p_version->custom_defines.size(); j++) { - builder.append(p_version->custom_defines[j].get_data()); - } - - builder.append(fragment_code0.get_data()); //first part of fragment - - builder.append(p_version->uniforms.get_data()); //uniforms (same for fragment and fragment) - - builder.append(fragment_code1.get_data()); //first part of fragment - - builder.append(p_version->fragment_globals.get_data()); // fragment globals - - builder.append(fragment_code2.get_data()); //third part of fragment - - builder.append(p_version->fragment_light.get_data()); // fragment light - - builder.append(fragment_code3.get_data()); //fourth part of fragment - - builder.append(p_version->fragment_code.get_data()); // fragment code - - builder.append(fragment_code4.get_data()); //fourth part of fragment + _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT]); current_source = builder.as_string(); RD::ShaderStageData stage; @@ -298,30 +230,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { current_stage = RD::SHADER_STAGE_COMPUTE; StringBuilder builder; - - builder.append(compute_codev.get_data()); // version info (if exists) - builder.append("\n"); //make sure defines begin at newline - builder.append(base_compute_defines.get_data()); - builder.append(general_defines.get_data()); - builder.append(variant_defines[p_variant].get_data()); - - for (int j = 0; j < p_version->custom_defines.size(); j++) { - builder.append(p_version->custom_defines[j].get_data()); - } - - builder.append(compute_code0.get_data()); //first part of compute - - builder.append(p_version->uniforms.get_data()); //uniforms (same for compute and fragment) - - builder.append(compute_code1.get_data()); //second part of compute - - builder.append(p_version->compute_globals.get_data()); // compute globals - - builder.append(compute_code2.get_data()); //third part of compute - - builder.append(p_version->compute_code.get_data()); // code - - builder.append(compute_code3.get_data()); //fourth of compute + _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_COMPUTE]); current_source = builder.as_string(); RD::ShaderStageData stage; @@ -364,29 +273,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio //vertex stage StringBuilder builder; - - builder.append(vertex_codev.get_data()); // version info (if exists) - builder.append("\n"); //make sure defines begin at newline - builder.append(general_defines.get_data()); - builder.append(variant_defines[i].get_data()); - - for (int j = 0; j < version->custom_defines.size(); j++) { - builder.append(version->custom_defines[j].get_data()); - } - - builder.append(vertex_code0.get_data()); //first part of vertex - - builder.append(version->uniforms.get_data()); //uniforms (same for vertex and fragment) - - builder.append(vertex_code1.get_data()); //second part of vertex - - builder.append(version->vertex_globals.get_data()); // vertex globals - - builder.append(vertex_code2.get_data()); //third part of vertex - - builder.append(version->vertex_code.get_data()); // code - - builder.append(vertex_code3.get_data()); //fourth of vertex + _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_VERTEX]); RS::ShaderNativeSourceCode::Version::Stage stage; stage.name = "vertex"; @@ -399,32 +286,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio //fragment stage StringBuilder builder; - - builder.append(fragment_codev.get_data()); // version info (if exists) - builder.append("\n"); //make sure defines begin at newline - builder.append(general_defines.get_data()); - builder.append(variant_defines[i].get_data()); - for (int j = 0; j < version->custom_defines.size(); j++) { - builder.append(version->custom_defines[j].get_data()); - } - - builder.append(fragment_code0.get_data()); //first part of fragment - - builder.append(version->uniforms.get_data()); //uniforms (same for fragment and fragment) - - builder.append(fragment_code1.get_data()); //first part of fragment - - builder.append(version->fragment_globals.get_data()); // fragment globals - - builder.append(fragment_code2.get_data()); //third part of fragment - - builder.append(version->fragment_light.get_data()); // fragment light - - builder.append(fragment_code3.get_data()); //fourth part of fragment - - builder.append(version->fragment_code.get_data()); // fragment code - - builder.append(fragment_code4.get_data()); //fourth part of fragment + _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_FRAGMENT]); RS::ShaderNativeSourceCode::Version::Stage stage; stage.name = "fragment"; @@ -437,30 +299,7 @@ RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_versio //compute stage StringBuilder builder; - - builder.append(compute_codev.get_data()); // version info (if exists) - builder.append("\n"); //make sure defines begin at newline - builder.append(base_compute_defines.get_data()); - builder.append(general_defines.get_data()); - builder.append(variant_defines[i].get_data()); - - for (int j = 0; j < version->custom_defines.size(); j++) { - builder.append(version->custom_defines[j].get_data()); - } - - builder.append(compute_code0.get_data()); //first part of compute - - builder.append(version->uniforms.get_data()); //uniforms (same for compute and fragment) - - builder.append(compute_code1.get_data()); //second part of compute - - builder.append(version->compute_globals.get_data()); // compute globals - - builder.append(compute_code2.get_data()); //third part of compute - - builder.append(version->compute_code.get_data()); // code - - builder.append(compute_code3.get_data()); //fourth of compute + _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_COMPUTE]); RS::ShaderNativeSourceCode::Version::Stage stage; stage.name = "compute"; @@ -518,17 +357,18 @@ void ShaderRD::_compile_version(Version *p_version) { p_version->valid = true; } -void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const String &p_vertex_globals, const String &p_vertex_code, const String &p_fragment_globals, const String &p_fragment_light, const String &p_fragment_code, const Vector<String> &p_custom_defines) { +void ShaderRD::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines) { ERR_FAIL_COND(is_compute); Version *version = version_owner.getornull(p_version); ERR_FAIL_COND(!version); version->vertex_globals = p_vertex_globals.utf8(); - version->vertex_code = p_vertex_code.utf8(); - version->fragment_light = p_fragment_light.utf8(); version->fragment_globals = p_fragment_globals.utf8(); - version->fragment_code = p_fragment_code.utf8(); version->uniforms = p_uniforms.utf8(); + version->code_sections.clear(); + for (Map<String, String>::Element *E = p_code.front(); E; E = E->next()) { + version->code_sections[StringName(E->key().to_upper())] = E->get().utf8(); + } version->custom_defines.clear(); for (int i = 0; i < p_custom_defines.size(); i++) { @@ -542,15 +382,20 @@ void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const S } } -void ShaderRD::version_set_compute_code(RID p_version, const String &p_uniforms, const String &p_compute_globals, const String &p_compute_code, const Vector<String> &p_custom_defines) { +void ShaderRD::version_set_compute_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines) { ERR_FAIL_COND(!is_compute); Version *version = version_owner.getornull(p_version); ERR_FAIL_COND(!version); + version->compute_globals = p_compute_globals.utf8(); - version->compute_code = p_compute_code.utf8(); version->uniforms = p_uniforms.utf8(); + version->code_sections.clear(); + for (Map<String, String>::Element *E = p_code.front(); E; E = E->next()) { + version->code_sections[StringName(E->key().to_upper())] = E->get().utf8(); + } + version->custom_defines.clear(); for (int i = 0; i < p_custom_defines.size(); i++) { version->custom_defines.push_back(p_custom_defines[i].utf8()); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index e0f4dcf2d0..f20d539621 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -32,7 +32,9 @@ #define SHADER_RD_H #include "core/os/mutex.h" +#include "core/string/string_builder.h" #include "core/templates/hash_map.h" +#include "core/templates/local_vector.h" #include "core/templates/map.h" #include "core/templates/rid_owner.h" #include "core/variant/variant.h" @@ -52,12 +54,9 @@ class ShaderRD { struct Version { CharString uniforms; CharString vertex_globals; - CharString vertex_code; CharString compute_globals; - CharString compute_code; - CharString fragment_light; CharString fragment_globals; - CharString fragment_code; + Map<StringName, CharString> code_sections; Vector<CharString> custom_defines; RID *variants; //same size as version defines @@ -76,31 +75,44 @@ class ShaderRD { RID_Owner<Version> version_owner; - CharString fragment_codev; //for version and extensions - CharString fragment_code0; - CharString fragment_code1; - CharString fragment_code2; - CharString fragment_code3; - CharString fragment_code4; - - CharString vertex_codev; //for version and extensions - CharString vertex_code0; - CharString vertex_code1; - CharString vertex_code2; - CharString vertex_code3; + struct StageTemplate { + struct Chunk { + enum Type { + TYPE_VERSION_DEFINES, + TYPE_MATERIAL_UNIFORMS, + TYPE_VERTEX_GLOBALS, + TYPE_FRAGMENT_GLOBALS, + TYPE_COMPUTE_GLOBALS, + TYPE_CODE, + TYPE_TEXT + }; + + Type type; + StringName code; + CharString text; + }; + LocalVector<Chunk> chunks; + }; bool is_compute = false; - CharString compute_codev; //for version and extensions - CharString compute_code0; - CharString compute_code1; - CharString compute_code2; - CharString compute_code3; - const char *name; CharString base_compute_defines; + enum StageType { + STAGE_TYPE_VERTEX, + STAGE_TYPE_FRAGMENT, + STAGE_TYPE_COMPUTE, + STAGE_TYPE_MAX, + }; + + StageTemplate stage_templates[STAGE_TYPE_MAX]; + + void _build_variant_code(StringBuilder &p_builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template); + + void _add_stage(const char *p_code, StageType p_stage_type); + protected: ShaderRD(); void setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name); @@ -108,8 +120,8 @@ protected: public: RID version_create(); - void version_set_code(RID p_version, const String &p_uniforms, const String &p_vertex_globals, const String &p_vertex_code, const String &p_fragment_globals, const String &p_fragment_light, const String &p_fragment_code, const Vector<String> &p_custom_defines); - void version_set_compute_code(RID p_version, const String &p_uniforms, const String &p_compute_globals, const String &p_compute_code, const Vector<String> &p_custom_defines); + void version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines); + void version_set_compute_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines); _FORCE_INLINE_ RID version_get_shader(RID p_version, int p_variant) { ERR_FAIL_INDEX_V(p_variant, variant_defines.size(), RID()); diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl index 63f086a83d..b70e0b6bd5 100644 --- a/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl +++ b/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define BLOCK_SIZE 8 diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 3b39edc70e..8b97ec119f 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #ifdef USE_ATTRIBUTES layout(location = 0) in vec2 vertex_attrib; @@ -26,17 +26,15 @@ layout(location = 3) out vec2 pixel_size_interp; #endif -#ifdef USE_MATERIAL_UNIFORMS +#ifdef MATERIAL_UNIFORMS_USED layout(set = 1, binding = 0, std140) uniform MaterialUniforms{ - /* clang-format off */ -MATERIAL_UNIFORMS - /* clang-format on */ + +#MATERIAL_UNIFORMS + } material; #endif -/* clang-format off */ -VERTEX_SHADER_GLOBALS -/* clang-format on */ +#GLOBALS void main() { vec4 instance_custom = vec4(0.0); @@ -132,9 +130,7 @@ void main() { float point_size = 1.0; #endif { - /* clang-format off */ -VERTEX_SHADER_CODE - /* clang-format on */ +#CODE : VERTEX } #ifdef USE_NINEPATCH @@ -212,7 +208,7 @@ VERTEX_SHADER_CODE #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "canvas_uniforms_inc.glsl" @@ -228,11 +224,11 @@ layout(location = 3) in vec2 pixel_size_interp; layout(location = 0) out vec4 frag_color; -#ifdef USE_MATERIAL_UNIFORMS +#ifdef MATERIAL_UNIFORMS_USED layout(set = 1, binding = 0, std140) uniform MaterialUniforms{ - /* clang-format off */ -MATERIAL_UNIFORMS - /* clang-format on */ + +#MATERIAL_UNIFORMS + } material; #endif @@ -260,11 +256,9 @@ vec2 sdf_to_screen_uv(vec2 p_sdf) { return p_sdf * canvas_data.sdf_to_screen; } -/* clang-format off */ -FRAGMENT_SHADER_GLOBALS -/* clang-format on */ +#GLOBALS -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED vec4 light_compute( vec3 light_vertex, @@ -278,9 +272,9 @@ vec4 light_compute( vec2 uv, vec4 color, bool is_directional) { vec4 light = vec4(0.0); - /* clang-format off */ -LIGHT_SHADER_CODE - /* clang-format on */ + +#CODE : LIGHT + return light; } @@ -356,7 +350,7 @@ vec3 light_normal_compute(vec3 light_vec, vec3 normal, vec3 base_color, vec3 lig //float distance = length(shadow_pos); vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED , vec3 shadow_modulate #endif @@ -395,7 +389,7 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv } vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color); -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED shadow_color.rgb *= shadow_modulate; #endif @@ -504,11 +498,7 @@ void main() { normal_used = true; #endif - /* clang-format off */ - -FRAGMENT_SHADER_CODE - - /* clang-format on */ +#CODE : FRAGMENT #if defined(NORMAL_MAP_USED) normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_map_depth); @@ -543,7 +533,7 @@ FRAGMENT_SHADER_CODE vec2 direction = light_array.data[light_base].position; vec4 light_color = light_array.data[light_base].color; -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED vec4 shadow_modulate = vec4(1.0); light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true); @@ -561,7 +551,7 @@ FRAGMENT_SHADER_CODE vec4 shadow_uv = vec4(shadow_pos.x, light_array.data[light_base].shadow_y_ofs, shadow_pos.y * light_array.data[light_base].shadow_zfar_inv, 1.0); light_color = light_shadow_compute(light_base, light_color, shadow_uv -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED , shadow_modulate.rgb #endif @@ -599,7 +589,7 @@ FRAGMENT_SHADER_CODE vec4 light_color = textureLod(sampler2D(atlas_texture, texture_sampler), tex_uv_atlas, 0.0); vec4 light_base_color = light_array.data[light_base].color; -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED vec4 shadow_modulate = vec4(1.0); vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height); @@ -657,7 +647,7 @@ FRAGMENT_SHADER_CODE vec4 shadow_uv = vec4(tex_ofs, light_array.data[light_base].shadow_y_ofs, distance, 1.0); light_color = light_shadow_compute(light_base, light_color, shadow_uv -#ifdef LIGHT_SHADER_CODE_USED +#ifdef LIGHT_CODE_USED , shadow_modulate.rgb #endif diff --git a/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl index 5c25235c58..9f89f4b3b7 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) in highp vec3 vertex; @@ -32,7 +32,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(push_constant, binding = 0, std430) uniform Constants { mat4 projection; diff --git a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl index 302ad03b41..65a554e839 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/cluster_debug.glsl b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl index 70a875192c..40da2c6e5c 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl index ca92d2104e..da7d189281 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) in vec3 vertex_attrib; @@ -63,7 +63,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) && defined(has_GL_KHR_shader_subgroup_vote) diff --git a/servers/rendering/renderer_rd/shaders/cluster_store.glsl b/servers/rendering/renderer_rd/shaders/cluster_store.glsl index 5be0893c4f..b0606efa94 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_store.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_store.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/copy.glsl index cdd35dfb3f..4110a95ddb 100644 --- a/servers/rendering/renderer_rd/shaders/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/copy.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl index 9751e13b4e..8c68e2dc2f 100644 --- a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) out vec2 uv_interp; @@ -37,7 +37,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(push_constant, binding = 1, std430) uniform Params { vec4 section; diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index c3ac0bee57..dfbce29119 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(push_constant, binding = 1, std430) uniform Params { float z_far; @@ -26,7 +26,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) in vec2 uv_interp; diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl index 7f269b7af3..9fa84657d1 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl @@ -22,7 +22,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define BLOCK_SIZE 8 diff --git a/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl b/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl index 987545fb76..2a774b0eb4 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl @@ -22,7 +22,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define GROUP_SIZE 64 diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl index 5cbb00baa4..ce7c03c1d4 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define GROUP_SIZE 8 diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index 92a5682572..bfd5c4c88d 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl index b931461b31..49a493cdc7 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #ifdef MODE_DYNAMIC layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl b/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl index 515cc35507..7d4d72967a 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES struct CellData { uint position; // xyz 10 bits @@ -172,7 +172,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) in vec4 color_interp; layout(location = 0) out vec4 frag_color; diff --git a/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl index 5b3dec0ee7..e20b3f680d 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl index 56b3b7ccb4..5dc2d08a3b 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl index 8a11c35b78..466442b67a 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define BLOCK_SIZE 8 diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index cb6d8dc7f6..c438352c05 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; @@ -146,11 +146,11 @@ layout(set = 2, binding = 1) uniform texture2D height_field_texture; /* SET 3: MATERIAL */ -#ifdef USE_MATERIAL_UNIFORMS +#ifdef MATERIAL_UNIFORMS_USED layout(set = 3, binding = 0, std140) uniform MaterialUniforms{ - /* clang-format off */ -MATERIAL_UNIFORMS - /* clang-format on */ + +#MATERIAL_UNIFORMS + } material; #endif @@ -196,11 +196,7 @@ bool emit_subparticle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom return true; } -/* clang-format off */ - -COMPUTE_SHADER_GLOBALS - -/* clang-format on */ +#GLOBALS void main() { uint particle = gl_GlobalInvocationID.x; @@ -540,10 +536,6 @@ void main() { } if (PARTICLE.is_active) { - /* clang-format off */ - -COMPUTE_SHADER_CODE - - /* clang-format on */ +#CODE : PROCESS } } diff --git a/servers/rendering/renderer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index 6c782b6045..80adb49619 100644 --- a/servers/rendering/renderer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index e83c4ca93b..2286a26485 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl index 464895928a..7b964675ca 100644 --- a/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl +++ b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 76edec1cb6..fce17c47e8 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "scene_forward_clustered_inc.glsl" @@ -81,11 +81,11 @@ layout(location = 5) out vec3 tangent_interp; layout(location = 6) out vec3 binormal_interp; #endif -#ifdef USE_MATERIAL_UNIFORMS +#ifdef MATERIAL_UNIFORMS_USED layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ - /* clang-format off */ -MATERIAL_UNIFORMS - /* clang-format on */ + +#MATERIAL_UNIFORMS + } material; #endif @@ -99,11 +99,7 @@ layout(location = 8) out float dp_clip; layout(location = 9) out flat uint instance_index; -/* clang-format off */ - -VERTEX_SHADER_GLOBALS - -/* clang-format on */ +#GLOBALS void main() { vec4 instance_custom = vec4(0.0); @@ -230,11 +226,7 @@ void main() { mat3 modelview_normal = mat3(scene_data.inv_camera_matrix) * world_normal_matrix; { - /* clang-format off */ - -VERTEX_SHADER_CODE - - /* clang-format on */ +#CODE : VERTEX } // using local coordinates (default) @@ -325,7 +317,7 @@ VERTEX_SHADER_CODE #version 450 -VERSION_DEFINES +#VERSION_DEFINES #include "scene_forward_clustered_inc.glsl" @@ -372,19 +364,15 @@ layout(location = 9) in flat uint instance_index; #define LIGHT_TRANSMITTANCE_USED #endif -#ifdef USE_MATERIAL_UNIFORMS +#ifdef MATERIAL_UNIFORMS_USED layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ - /* clang-format off */ -MATERIAL_UNIFORMS - /* clang-format on */ -} material; -#endif -/* clang-format off */ +#MATERIAL_UNIFORMS -FRAGMENT_SHADER_GLOBALS +} material; +#endif -/* clang-format on */ +#GLOBALS #ifdef MODE_RENDER_DEPTH @@ -581,18 +569,14 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #endif inout vec3 diffuse_light, inout vec3 specular_light) { -#if defined(USE_LIGHT_SHADER_CODE) +#if defined(LIGHT_CODE_USED) // light is written by the light shader vec3 normal = N; vec3 light = L; vec3 view = V; - /* clang-format off */ - -LIGHT_SHADER_CODE - - /* clang-format on */ +#CODE : LIGHT #else @@ -794,7 +778,7 @@ LIGHT_SHADER_CODE alpha = min(alpha, clamp(1.0 - attenuation), 0.0, 1.0)); #endif -#endif //defined(USE_LIGHT_SHADER_CODE) +#endif //defined(LIGHT_CODE_USED) } #ifndef USE_NO_SHADOWS @@ -1925,11 +1909,7 @@ void main() { #endif // ALPHA_ANTIALIASING_EDGE_USED { - /* clang-format off */ - -FRAGMENT_SHADER_CODE - - /* clang-format on */ +#CODE : FRAGMENT } #ifdef LIGHT_TRANSMITTANCE_USED diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl index 06dc4b13de..78e0a85341 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl index a5afe74cb2..62d1cffb0a 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl index 218605a962..7e06516d90 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl index e4c3f3a84b..8b58796962 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl index 08da283dad..0eacbc5363 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define MAX_CASCADES 8 @@ -153,7 +153,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) out vec4 frag_color; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index dc7238abed..99db35bb34 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl deleted file mode 100644 index 69d8824d8a..0000000000 --- a/servers/rendering/renderer_rd/shaders/sdfgi_fields.glsl +++ /dev/null @@ -1,182 +0,0 @@ -/* clang-format off */ -[compute] - -#version 450 - -VERSION_DEFINES - -layout(local_size_x = OCT_RES, local_size_y = OCT_RES, local_size_z = 1) in; - -/* clang-format on */ - -#define MAX_CASCADES 8 - -layout(rgba16f, set = 0, binding = 1) uniform restrict image2DArray irradiance_texture; -layout(rg16f, set = 0, binding = 2) uniform restrict image2DArray depth_texture; - -layout(rgba32ui, set = 0, binding = 3) uniform restrict uimage2DArray irradiance_history_texture; -layout(rg32ui, set = 0, binding = 4) uniform restrict uimage2DArray depth_history_texture; - -struct CascadeData { - vec3 offset; //offset of (0,0,0) in world coordinates - float to_cell; // 1/bounds * grid_size -}; - -layout(set = 0, binding = 5, std140) uniform Cascades { - CascadeData data[MAX_CASCADES]; -} -cascades; - -#define DEPTH_HISTORY_BITS 24 -#define IRRADIANCE_HISTORY_BITS 16 - -layout(push_constant, binding = 0, std430) uniform Params { - vec3 grid_size; - uint max_cascades; - - uint probe_axis_size; - uint cascade; - uint history_size; - uint pad0; - - ivec3 scroll; //scroll in probes - uint pad1; -} -params; - -void main() { - ivec2 local = ivec2(gl_LocalInvocationID.xy); - ivec2 probe = ivec2(gl_WorkGroupID.xy); - - ivec3 probe_cell; - probe_cell.x = probe.x % int(params.probe_axis_size); - probe_cell.y = probe.y; - probe_cell.z = probe.x / int(params.probe_axis_size); - -#ifdef MODE_SCROLL_BEGIN - - ivec3 read_cell = probe_cell - params.scroll; - - uint src_layer = (params.history_size + 1) * params.cascade; - uint dst_layer = (params.history_size + 1) * params.max_cascades; - - for (uint i = 0; i <= params.history_size; i++) { - ivec3 write_pos = ivec3(probe * OCT_RES + local, int(i)); - - if (any(lessThan(read_pos, ivec3(0))) || any(greaterThanEqual(read_pos, ivec3(params.probe_axis_size)))) { - // nowhere to read from for scrolling, try finding the value from upper probes - -#ifdef MODE_IRRADIANCE - imageStore(irradiance_history_texture, write_pos, uvec4(0)); -#endif -#ifdef MODE_DEPTH - imageStore(depth_history_texture, write_pos, uvec4(0)); -#endif - } else { - ivec3 read_pos; - read_pos.xy = read_cell.xy; - read_pos.x += read_cell.z * params.probe_axis_size; - read_pos.xy = read_pos.xy * OCT_RES + local; - read_pos.z = int(i); - -#ifdef MODE_IRRADIANCE - uvec4 value = imageLoad(irradiance_history_texture, read_pos); - imageStore(irradiance_history_texture, write_pos, value); -#endif -#ifdef MODE_DEPTH - uvec2 value = imageLoad(depth_history_texture, read_pos); - imageStore(depth_history_texture, write_pos, value); -#endif - } - } - -#endif // MODE_SCROLL_BEGIN - -#ifdef MODE_SCROLL_END - - uint src_layer = (params.history_size + 1) * params.max_cascades; - uint dst_layer = (params.history_size + 1) * params.cascade; - - for (uint i = 0; i <= params.history_size; i++) { - ivec3 pos = ivec3(probe * OCT_RES + local, int(i)); - -#ifdef MODE_IRRADIANCE - uvec4 value = imageLoad(irradiance_history_texture, read_pos); - imageStore(irradiance_history_texture, write_pos, value); -#endif -#ifdef MODE_DEPTH - uvec2 value = imageLoad(depth_history_texture, read_pos); - imageStore(depth_history_texture, write_pos, value); -#endif - } - -#endif //MODE_SCROLL_END - -#ifdef MODE_STORE - - uint src_layer = (params.history_size + 1) * params.cascade + params.history_size; - ivec3 read_pos = ivec3(probe * OCT_RES + local, int(src_layer)); - - ivec3 write_pos = ivec3(probe * (OCT_RES + 2) + ivec2(1), int(params.cascade)); - - ivec3 copy_to[4] = ivec3[](write_pos, ivec3(-2, -2, -2), ivec3(-2, -2, -2), ivec3(-2, -2, -2)); - -#ifdef MODE_IRRADIANCE - uvec4 average = imageLoad(irradiance_history_texture, read_pos); - vec4 light_accum = vec4(average / params.history_size) / float(1 << IRRADIANCE_HISTORY_BITS); - -#endif -#ifdef MODE_DEPTH - uvec2 value = imageLoad(depth_history_texture, read_pos); - vec2 depth_accum = vec4(average / params.history_size) / float(1 << IRRADIANCE_HISTORY_BITS); - - float probe_cell_size = float(params.grid_size / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell; - float max_depth = length(params.grid_size / cascades.data[params.max_cascades - 1].to_cell); - max_depth /= probe_cell_size; - - depth_value = (vec2(average / params.history_size) / float(1 << DEPTH_HISTORY_BITS)) * vec2(max_depth, max_depth * max_depth); - -#endif - - /* Fill the border if required */ - - if (local == ivec2(0, 0)) { - copy_to[1] = texture_pos + ivec3(OCT_RES - 1, -1, 0); - copy_to[2] = texture_pos + ivec3(-1, OCT_RES - 1, 0); - copy_to[3] = texture_pos + ivec3(OCT_RES, OCT_RES, 0); - } else if (local == ivec2(OCT_RES - 1, 0)) { - copy_to[1] = texture_pos + ivec3(0, -1, 0); - copy_to[2] = texture_pos + ivec3(OCT_RES, OCT_RES - 1, 0); - copy_to[3] = texture_pos + ivec3(-1, OCT_RES, 0); - } else if (local == ivec2(0, OCT_RES - 1)) { - copy_to[1] = texture_pos + ivec3(-1, 0, 0); - copy_to[2] = texture_pos + ivec3(OCT_RES - 1, OCT_RES, 0); - copy_to[3] = texture_pos + ivec3(OCT_RES, -1, 0); - } else if (local == ivec2(OCT_RES - 1, OCT_RES - 1)) { - copy_to[1] = texture_pos + ivec3(0, OCT_RES, 0); - copy_to[2] = texture_pos + ivec3(OCT_RES, 0, 0); - copy_to[3] = texture_pos + ivec3(-1, -1, 0); - } else if (local.y == 0) { - copy_to[1] = texture_pos + ivec3(OCT_RES - local.x - 1, local.y - 1, 0); - } else if (local.x == 0) { - copy_to[1] = texture_pos + ivec3(local.x - 1, OCT_RES - local.y - 1, 0); - } else if (local.y == OCT_RES - 1) { - copy_to[1] = texture_pos + ivec3(OCT_RES - local.x - 1, local.y + 1, 0); - } else if (local.x == OCT_RES - 1) { - copy_to[1] = texture_pos + ivec3(local.x + 1, OCT_RES - local.y - 1, 0); - } - - for (int i = 0; i < 4; i++) { - if (copy_to[i] == ivec3(-2, -2, -2)) { - continue; - } -#ifdef MODE_IRRADIANCE - imageStore(irradiance_texture, copy_to[i], light_accum); -#endif -#ifdef MODE_DEPTH - imageStore(depth_texture, copy_to[i], vec4(depth_value, 0.0, 0.0)); -#endif - } - -#endif // MODE_STORE -} diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index 007e4c113a..bc376e9522 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl index 916c60ac89..aa4ded146f 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #ifdef MODE_JUMPFLOOD_OPTIMIZED #define GROUP_SIZE 8 diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index 680d1045cd..669ffc961d 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl index 6c985e1f5c..9924da37d5 100644 --- a/servers/rendering/renderer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/sky.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) out vec2 uv_interp; @@ -24,7 +24,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define M_PI 3.14159265359 @@ -88,13 +88,9 @@ layout(set = 0, binding = 3, std140) uniform DirectionalLights { directional_lights; -#ifdef USE_MATERIAL_UNIFORMS +#ifdef MATERIAL_UNIFORMS_USED layout(set = 1, binding = 0, std140) uniform MaterialUniforms{ - /* clang-format off */ - -MATERIAL_UNIFORMS - - /* clang-format on */ +#MATERIAL_UNIFORMS } material; #endif @@ -127,11 +123,7 @@ layout(set = 3, binding = 0) uniform texture3D volumetric_fog_texture; #define AT_QUARTER_RES_PASS false #endif -/* clang-format off */ - -FRAGMENT_SHADER_GLOBALS - -/* clang-format on */ +#GLOBALS layout(location = 0) out vec4 frag_color; @@ -202,22 +194,10 @@ void main() { #endif #endif -// unused, just here to make our compiler happy, make sure we don't execute any light code the user adds in.. -#ifndef REALLYINCLUDETHIS - { - /* clang-format off */ - -LIGHT_SHADER_CODE - - /* clang-format on */ - } -#endif { - /* clang-format off */ -FRAGMENT_SHADER_CODE +#CODE : SKY - /* clang-format on */ } frag_color.rgb = color * params.position_multiplier.w; diff --git a/servers/rendering/renderer_rd/shaders/sort.glsl b/servers/rendering/renderer_rd/shaders/sort.glsl index e5ebb9c64b..307e60dc21 100644 --- a/servers/rendering/renderer_rd/shaders/sort.glsl +++ b/servers/rendering/renderer_rd/shaders/sort.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES // Original version here: // https://github.com/GPUOpen-LibrariesAndSDKs/GPUParticles11/blob/master/gpuparticles11/src/Shaders diff --git a/servers/rendering/renderer_rd/shaders/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/specular_merge.glsl index 0b8f406213..3579c35cce 100644 --- a/servers/rendering/renderer_rd/shaders/specular_merge.glsl +++ b/servers/rendering/renderer_rd/shaders/specular_merge.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) out vec2 uv_interp; @@ -17,7 +17,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) in vec2 uv_interp; diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl index 231f8f91ec..6e945edfcd 100644 --- a/servers/rendering/renderer_rd/shaders/ssao.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao.glsl @@ -21,7 +21,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES #define SSAO_ADAPTIVE_TAP_BASE_COUNT 5 diff --git a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl index 510a777048..d9cd2b4e85 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl @@ -21,7 +21,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl b/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl index cb2d31f70d..ee0db6a6f0 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl @@ -21,7 +21,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl index 6aa7624261..687fe1e6e2 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl @@ -21,7 +21,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl index 4fdf334aa5..0907423d5d 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl @@ -20,7 +20,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl index 88a953562f..9367b641c2 100644 --- a/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl +++ b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl index 7de91fd541..86b4da6b08 100644 --- a/servers/rendering/renderer_rd/shaders/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) out vec2 uv_interp; @@ -16,7 +16,7 @@ void main() { #version 450 -VERSION_DEFINES +#VERSION_DEFINES layout(location = 0) in vec2 uv_interp; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index ce8a459b24..cace607667 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl @@ -2,7 +2,7 @@ #version 450 -VERSION_DEFINES +#VERSION_DEFINES /* Do not use subgroups here, seems there is not much advantage and causes glitches #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 4ae0eda232..f5228f9747 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -3109,20 +3109,20 @@ bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, St } switch (p_varying.stage) { case ShaderNode::Varying::STAGE_UNKNOWN: // first assign - if (current_function == String("vertex")) { + if (current_function == varying_function_names.vertex) { p_varying.stage = ShaderNode::Varying::STAGE_VERTEX; - } else if (current_function == String("fragment")) { + } else if (current_function == varying_function_names.fragment) { p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT; } break; case ShaderNode::Varying::STAGE_VERTEX: - if (current_function == String("fragment")) { + if (current_function == varying_function_names.fragment) { *r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'."); return false; } break; case ShaderNode::Varying::STAGE_FRAGMENT: - if (current_function == String("vertex")) { + if (current_function == varying_function_names.vertex) { *r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'."); return false; } @@ -3139,25 +3139,25 @@ bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, Str *r_message = RTR("Varying must be assigned before using!"); return false; case ShaderNode::Varying::STAGE_VERTEX: - if (current_function == String("fragment")) { + if (current_function == varying_function_names.fragment) { p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT; - } else if (current_function == String("light")) { + } else if (current_function == varying_function_names.light) { p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT; } break; case ShaderNode::Varying::STAGE_FRAGMENT: - if (current_function == String("light")) { + if (current_function == varying_function_names.light) { p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT; } break; case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT: - if (current_function == String("light")) { + if (current_function == varying_function_names.light) { *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); return false; } break; case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT: - if (current_function == String("fragment")) { + if (current_function == varying_function_names.fragment) { *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"); return false; } @@ -5847,7 +5847,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun //check return type BlockNode *b = p_block; - if (b && b->parent_function && (b->parent_function->name == "vertex" || b->parent_function->name == "fragment" || b->parent_function->name == "light")) { + if (b && b->parent_function && p_function_info.main_function) { _set_error(vformat("Using 'return' in '%s' processor function results in undefined behavior!", b->parent_function->name)); return ERR_PARSE_ERROR; } @@ -7246,26 +7246,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) { - if (p_functions.has("vertex")) { - if (p_functions["vertex"].built_ins.has(p_name)) { - return true; - } - } - if (p_functions.has("fragment")) { - if (p_functions["fragment"].built_ins.has(p_name)) { - return true; - } - } - if (p_functions.has("light")) { - if (p_functions["light"].built_ins.has(p_name)) { - return true; - } - } - if (p_functions.has("compute")) { - if (p_functions["compute"].built_ins.has(p_name)) { + for (Map<StringName, ShaderLanguage::FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) { + if (E->get().built_ins.has(p_name)) { return true; } } + return false; } @@ -7399,11 +7385,12 @@ String ShaderLanguage::get_shader_type(const String &p_code) { return String(); } -Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { +Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { clear(); code = p_code; global_var_get_type_func = p_global_variable_type_func; + varying_function_names = p_varying_function_names; nodes = nullptr; @@ -7416,10 +7403,11 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi return OK; } -Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { +Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { clear(); code = p_code; + varying_function_names = p_varying_function_names; nodes = nullptr; global_var_get_type_func = p_global_variable_type_func; diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 14594b039c..03327f9677 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -331,6 +331,17 @@ public: MAX_INSTANCE_UNIFORM_INDICES = 16 }; + struct VaryingFunctionNames { + StringName fragment; + StringName vertex; + StringName light; + VaryingFunctionNames() { + fragment = "fragment"; + vertex = "vertex"; + light = "light"; + } + }; + struct Node { Node *next = nullptr; @@ -769,7 +780,8 @@ public: Map<StringName, BuiltInInfo> built_ins; Map<StringName, StageFunctionInfo> stage_functions; - bool can_discard; + bool can_discard = false; + bool main_function = false; }; static bool has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name); @@ -796,6 +808,8 @@ private: StringName current_function; bool last_const = false; + VaryingFunctionNames varying_function_names; + TkPos _get_tkpos() { TkPos tkp; tkp.char_idx = char_idx; @@ -898,8 +912,8 @@ public: void clear(); static String get_shader_type(const String &p_code); - Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func); - Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint); + Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func); + Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint); String get_error_text(); int get_error_line(); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index e99b8504bb..f5f7e2e53d 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -74,6 +74,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM2"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM3"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].can_discard = false; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].main_function = true; //builtins shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; @@ -139,6 +140,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["RADIANCE"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["IRRADIANCE"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].can_discard = true; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].main_function = true; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR_THRESHOLD"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_HASH_SCALE"] = ShaderLanguage::TYPE_FLOAT; @@ -171,6 +173,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["light"].can_discard = true; + shader_modes[RS::SHADER_SPATIAL].functions["light"].main_function = true; //order used puts first enum mode (default) first shader_modes[RS::SHADER_SPATIAL].modes.push_back("blend_mix"); @@ -236,6 +239,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].can_discard = false; + shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].main_function = true; shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SHADOW_VERTEX"] = ShaderLanguage::TYPE_VEC2; @@ -257,6 +261,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].can_discard = true; + shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].main_function = true; { ShaderLanguage::StageFunctionInfo func; @@ -294,6 +299,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[RS::SHADER_CANVAS_ITEM].functions["light"].can_discard = true; + shader_modes[RS::SHADER_CANVAS_ITEM].functions["light"].main_function = true; shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("skip_vertex_transform"); @@ -310,34 +316,34 @@ ShaderTypes::ShaderTypes() { /************ PARTICLES **************************/ shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3; - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL; - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4; - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4; - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_ROT_SCALE"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_VELOCITY"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_COLOR"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["FLAG_EMIT_CUSTOM"] = constt(ShaderLanguage::TYPE_UINT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_POSITION"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_ROT_SCALE"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_VELOCITY"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_COLOR"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["RESTART_CUSTOM"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["COLLIDED"] = constt(ShaderLanguage::TYPE_BOOL); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["COLLISION_NORMAL"] = constt(ShaderLanguage::TYPE_VEC3); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["COLLISION_DEPTH"] = constt(ShaderLanguage::TYPE_FLOAT); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].built_ins["ATTRACTOR_FORCE"] = constt(ShaderLanguage::TYPE_VEC3); - shader_modes[RS::SHADER_PARTICLES].functions["compute"].can_discard = false; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_ROT_SCALE"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_VELOCITY"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_COLOR"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_CUSTOM"] = constt(ShaderLanguage::TYPE_UINT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART_POSITION"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART_ROT_SCALE"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART_VELOCITY"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART_COLOR"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART_CUSTOM"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["COLLIDED"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["COLLISION_NORMAL"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["COLLISION_DEPTH"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["ATTRACTOR_FORCE"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_PARTICLES].functions["process"].main_function = true; { ShaderLanguage::StageFunctionInfo emit_vertex_func; @@ -347,7 +353,7 @@ ShaderTypes::ShaderTypes() { emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("custom", ShaderLanguage::TYPE_VEC4)); emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("flags", ShaderLanguage::TYPE_UINT)); emit_vertex_func.return_type = ShaderLanguage::TYPE_BOOL; //whether it could emit - shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_subparticle"] = emit_vertex_func; + shader_modes[RS::SHADER_PARTICLES].functions["process"].stage_functions["emit_subparticle"] = emit_vertex_func; } shader_modes[RS::SHADER_PARTICLES].modes.push_back("collision_use_scale"); @@ -384,14 +390,15 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT); - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3; - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["EYEDIR"] = constt(ShaderLanguage::TYPE_VEC3); - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2); - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["SKY_COORDS"] = constt(ShaderLanguage::TYPE_VEC2); - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["HALF_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4); - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["QUARTER_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4); - shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["FOG"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["EYEDIR"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["SKY_COORDS"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["HALF_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["QUARTER_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["FOG"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SKY].functions["sky"].main_function = true; shader_modes[RS::SHADER_SKY].modes.push_back("use_half_res_pass"); shader_modes[RS::SHADER_SKY].modes.push_back("use_quarter_res_pass"); diff --git a/tests/test_shader_lang.cpp b/tests/test_shader_lang.cpp index a023f35506..2169350c02 100644 --- a/tests/test_shader_lang.cpp +++ b/tests/test_shader_lang.cpp @@ -344,7 +344,7 @@ MainLoop *test() { Set<String> types; types.insert("spatial"); - Error err = sl.compile(code, dt, rm, types, nullptr); + Error err = sl.compile(code, dt, rm, ShaderLanguage::VaryingFunctionNames(), types, nullptr); if (err) { print_line("Error at line: " + rtos(sl.get_error_line()) + ": " + sl.get_error_text()); |