From 1b628eb9f2feebaec2eede4b193fc864fc15dfe1 Mon Sep 17 00:00:00 2001 From: Chaosus Date: Sat, 20 Apr 2019 18:06:11 +0300 Subject: [PATCH] Geometry shader support --- drivers/gles2/shader_compiler_gles2.cpp | 2 +- drivers/gles3/rasterizer_scene_gles3.cpp | 2 +- drivers/gles3/rasterizer_storage_gles3.cpp | 11 +- drivers/gles3/rasterizer_storage_gles3.h | 3 + drivers/gles3/shader_compiler_gles3.cpp | 88 +++++- drivers/gles3/shader_compiler_gles3.h | 6 + drivers/gles3/shader_gles3.cpp | 301 +++++++++++++++++---- drivers/gles3/shader_gles3.h | 18 +- drivers/gles3/shaders/canvas.glsl | 103 +++++++ drivers/gles3/shaders/scene.glsl | 170 +++++++++++- editor/plugins/shader_editor_plugin.cpp | 9 +- gles_builders.py | 24 ++ main/tests/test_shader_lang.cpp | 3 +- servers/visual/shader_language.cpp | 60 +++- servers/visual/shader_language.h | 7 +- servers/visual/shader_types.cpp | 89 +++++- servers/visual/shader_types.h | 2 + 17 files changed, 814 insertions(+), 84 deletions(-) diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index d00b03fb8a6c..1b88807a6bf4 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -731,7 +731,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener Error ShaderCompilerGLES2::compile(VS::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()); + Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_ranges(p_mode), ShaderTypes::get_singleton()->get_types()); if (err != OK) { diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 56a6c51460fc..b2e91c0b5900 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2361,7 +2361,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test) return; //bye - if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_geometry && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { //shader does not use discard and does not write a vertex position, use generic material if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) { p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index be44d62efcb3..0c8de7f498a6 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -2107,9 +2107,12 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->spatial.uses_screen_texture = false; p_shader->spatial.uses_depth_texture = false; p_shader->spatial.uses_vertex = false; + p_shader->spatial.uses_geometry = false; p_shader->spatial.writes_modelview_or_projection = false; p_shader->spatial.uses_world_coordinates = false; + shaders.actions_scene.render_mode_values["geometry_max_vertices"] = Pair(&p_shader->spatial.max_vertices, 0); + shaders.actions_scene.render_mode_values["blend_add"] = Pair(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD); shaders.actions_scene.render_mode_values["blend_mix"] = Pair(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX); shaders.actions_scene.render_mode_values["blend_sub"] = Pair(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_SUB); @@ -2143,6 +2146,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex; + shaders.actions_scene.write_flag_pointers["OUT_VERTEX"] = &p_shader->spatial.uses_geometry; actions = &shaders.actions_scene; actions->uniforms = &p_shader->uniforms; @@ -2161,7 +2165,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { ERR_FAIL_COND(err != OK); - p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.defines); + p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.geometry, gen_code.geometry_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.defines); p_shader->ubo_size = gen_code.uniform_total_size; p_shader->ubo_offsets = gen_code.uniform_offsets; @@ -2170,6 +2174,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->texture_types = gen_code.texture_types; p_shader->uses_vertex_time = gen_code.uses_vertex_time; + p_shader->uses_geometry_time = gen_code.uses_geometry_time; p_shader->uses_fragment_time = gen_code.uses_fragment_time; //all materials using this shader will have to be invalidated, unfortunately @@ -2999,6 +3004,10 @@ void RasterizerStorageGLES3::_update_material(Material *material) { is_animated = true; } + if (material->shader->spatial.uses_geometry && material->shader->uses_geometry_time) { + is_animated = true; + } + if (material->shader->spatial.uses_vertex && material->shader->uses_vertex_time) { is_animated = true; } diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 92916ed8084e..626a3593924a 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -479,12 +479,14 @@ class RasterizerStorageGLES3 : public RasterizerStorage { }; int cull_mode; + int max_vertices; bool uses_alpha; bool uses_alpha_scissor; bool unshaded; bool no_depth_test; bool uses_vertex; + bool uses_geometry; bool uses_discard; bool uses_sss; bool uses_screen_texture; @@ -501,6 +503,7 @@ class RasterizerStorageGLES3 : public RasterizerStorage { } particles; bool uses_vertex_time; + bool uses_geometry_time; bool uses_fragment_time; Shader() : diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index ad26294527d6..e177ca8b327d 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -343,6 +343,24 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener } } + for (Map::Element *E = pnode->render_ranges.front(); E; E = E->next()) { + + if (p_default_actions.render_mode_defines.has(E->key()) && !used_rmode_defines.has(E->key())) { + + r_gen_code.defines.push_back((p_default_actions.render_mode_defines[E->key()] + itos(E->get()) + String("\n")).utf8()); + used_rmode_defines.insert(E->key()); + } + + if (p_actions.render_mode_flags.has(E->key())) { + *p_actions.render_mode_flags[E->key()] = true; + } + + if (p_actions.render_mode_values.has(E->key())) { + Pair &p = p_actions.render_mode_values[E->key()]; + *p.first = p.second; + } + } + int max_texture_uniforms = 0; int max_uniforms = 0; @@ -379,6 +397,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener ucode += ";\n"; if (SL::is_sampler_type(E->get().type)) { r_gen_code.vertex_global += ucode; + r_gen_code.geometry_global += ucode; r_gen_code.fragment_global += ucode; r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key()); r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint; @@ -467,8 +486,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener vcode += _prestr(E->get().precision); vcode += _typestr(E->get().type); vcode += " " + _mkid(E->key()); + varyings.insert(E->key()); + String gcode = vcode + "[];"; vcode += ";\n"; r_gen_code.vertex_global += interp_mode + "out " + vcode; + r_gen_code.geometry_global += interp_mode + "in " + gcode; r_gen_code.fragment_global += interp_mode + "in " + vcode; } @@ -484,6 +506,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener //place functions in actual code Set added_vtx; + Set added_geometry; Set added_fragment; //share for light for (int i = 0; i < pnode->functions.size(); i++) { @@ -498,6 +521,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.vertex = function_code[vertex_name]; } + if (fnode->name == geometry_name) { + _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.geometry_global, added_geometry); + r_gen_code.geometry = function_code[geometry_name]; + } + if (fnode->name == fragment_name) { _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); @@ -581,13 +609,19 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener if (p_default_actions.renames.has(vnode->name)) code = p_default_actions.renames[vnode->name]; - else - code = _mkid(vnode->name); - + else { + if (current_func_name == geometry_name && varyings.has(vnode->name)) + code = _mkid(vnode->name) + "[index]"; + else + code = _mkid(vnode->name); + } if (vnode->name == time_name) { if (current_func_name == vertex_name) { r_gen_code.uses_vertex_time = true; } + if (current_func_name == geometry_name) { + r_gen_code.uses_geometry_time = true; + } if (current_func_name == fragment_name || current_func_name == light_name) { r_gen_code.uses_fragment_time = true; } @@ -742,7 +776,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener Error ShaderCompilerGLES3::compile(VS::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()); + Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_ranges(p_mode), ShaderTypes::get_singleton()->get_types()); if (err != OK) { @@ -758,15 +792,19 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code, r_gen_code.defines.clear(); r_gen_code.vertex = String(); r_gen_code.vertex_global = String(); + r_gen_code.geometry = String(); + r_gen_code.geometry_global = String(); r_gen_code.fragment = String(); r_gen_code.fragment_global = String(); r_gen_code.light = String(); r_gen_code.uses_fragment_time = false; + r_gen_code.uses_geometry_time = false; r_gen_code.uses_vertex_time = false; used_name_defines.clear(); used_rmode_defines.clear(); used_flag_pointers.clear(); + varyings.clear(); _dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false); @@ -796,6 +834,13 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass"; actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom"; + actions[VS::SHADER_CANVAS_ITEM].renames["LENGTH"] = "gl_in.length()"; + actions[VS::SHADER_CANVAS_ITEM].renames["INDEX"] = "index"; + actions[VS::SHADER_CANVAS_ITEM].renames["IN_VERTEX"] = "gl_in[index].gl_Position"; + actions[VS::SHADER_CANVAS_ITEM].renames["OUT_VERTEX"] = "gl_Position"; + actions[VS::SHADER_CANVAS_ITEM].renames["OUT_COLOR"] = "color_interp"; + actions[VS::SHADER_CANVAS_ITEM].renames["OUT_UV"] = "uv_interp"; + actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map"; @@ -825,6 +870,15 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_max_vertices"] = "#define GEOMETRY_MAX_VERTICES "; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_in_points"] = "#define GEOMETRY_IN_MODE 0\n"; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_in_lines"] = "#define GEOMETRY_IN_MODE 1\n"; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_in_triangles"] = "#define GEOMETRY_IN_MODE 2\n"; + + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_out_points"] = "#define GEOMETRY_OUT_MODE 0\n"; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_out_lines"] = "#define GEOMETRY_OUT_MODE 1\n"; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["geometry_out_triangles"] = "#define GEOMETRY_OUT_MODE 2\n"; + /** SPATIAL SHADER **/ actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform"; @@ -845,6 +899,17 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "gl_InstanceID"; + actions[VS::SHADER_SPATIAL].renames["LENGTH"] = "gl_in.length()"; + actions[VS::SHADER_SPATIAL].renames["INDEX"] = "index"; + actions[VS::SHADER_SPATIAL].renames["IN_VERTEX"] = "gl_in[index].gl_Position"; + actions[VS::SHADER_SPATIAL].renames["OUT_VERTEX"] = "gl_Position"; + actions[VS::SHADER_SPATIAL].renames["OUT_NORMAL"] = "normal_interp"; + actions[VS::SHADER_SPATIAL].renames["OUT_COLOR"] = "color_interp"; + actions[VS::SHADER_SPATIAL].renames["OUT_UV"] = "uv_interp"; + actions[VS::SHADER_SPATIAL].renames["OUT_UV2"] = "uv2_interp"; + actions[VS::SHADER_SPATIAL].renames["OUT_TANGENT"] = "tangent_interp"; + actions[VS::SHADER_SPATIAL].renames["OUT_BINORMAL"] = "binormal_interp"; + //builtins actions[VS::SHADER_SPATIAL].renames["TIME"] = "time"; @@ -888,7 +953,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["OUT_TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; + actions[VS::SHADER_SPATIAL].usage_defines["OUT_BINORMAL"] = "@TANGENT"; actions[VS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n"; actions[VS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM"; actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n"; @@ -898,10 +965,13 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n"; actions[VS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n"; actions[VS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["OUT_UV"] = "#define ENABLE_UV_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["OUT_UV2"] = "#define ENABLE_UV2_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n"; actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP"; actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["OUT_COLOR"] = "#define ENABLE_COLOR_INTERP\n"; actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; actions[VS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; @@ -920,6 +990,15 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_max_vertices"] = "#define GEOMETRY_MAX_VERTICES "; + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_in_points"] = "#define GEOMETRY_IN_MODE 0\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_in_lines"] = "#define GEOMETRY_IN_MODE 1\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_in_triangles"] = "#define GEOMETRY_IN_MODE 2\n"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_out_points"] = "#define GEOMETRY_OUT_MODE 0\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_out_lines"] = "#define GEOMETRY_OUT_MODE 1\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["geometry_out_triangles"] = "#define GEOMETRY_OUT_MODE 2\n"; + bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley"); if (!force_lambert) { @@ -969,6 +1048,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { vertex_name = "vertex"; fragment_name = "fragment"; + geometry_name = "geometry"; light_name = "light"; time_name = "TIME"; diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h index 79f5c50f8866..930e0afbdff0 100644 --- a/drivers/gles3/shader_compiler_gles3.h +++ b/drivers/gles3/shader_compiler_gles3.h @@ -41,6 +41,7 @@ class ShaderCompilerGLES3 { struct IdentifierActions { Map > render_mode_values; + Map render_mode_ranges; Map render_mode_flags; Map usage_flag_pointers; Map write_flag_pointers; @@ -60,11 +61,14 @@ class ShaderCompilerGLES3 { String uniforms; String vertex_global; String vertex; + String geometry_global; + String geometry; String fragment_global; String fragment; String light; bool uses_fragment_time; + bool uses_geometry_time; bool uses_vertex_time; }; @@ -84,6 +88,7 @@ class ShaderCompilerGLES3 { StringName current_func_name; StringName vertex_name; StringName fragment_name; + StringName geometry_name; StringName light_name; StringName time_name; @@ -91,6 +96,7 @@ class ShaderCompilerGLES3 { Set used_flag_pointers; Set used_rmode_defines; Set internal_functions; + Set varyings; DefaultIdentifierActions actions[VS::SHADER_MAX]; diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index fa7cc00230b5..1746a41fa644 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -193,6 +193,11 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { if (v.ok) { //bye bye shaders glDeleteShader(v.vert_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.frag_id); glDeleteProgram(v.id); v.id = 0; @@ -344,6 +349,92 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { //_display_error_with_code("pepo", strings); + has_geometry = false; + +#ifdef GLES_OVER_GL + /* GEOMETRY SHADER */ + + strings.resize(strings_base_size); + //vertex precision is high + strings.push_back("precision highp float;\n"); + strings.push_back("precision highp int;\n"); + + strings.push_back(geometry_code0.get_data()); + + if (cc) { + material_string = cc->uniforms.ascii(); + strings.push_back(material_string.get_data()); + } + + strings.push_back(geometry_code1.get_data()); + + if (cc) { + code_globals = cc->geometry_globals.ascii(); + strings.push_back(code_globals.get_data()); + } + + strings.push_back(geometry_code2.get_data()); + + if (cc) { + code_string = cc->geometry.ascii(); + strings.push_back(code_string.get_data()); + } + + has_geometry = !String(code_string.get_data()).empty(); + + strings.push_back(geometry_code3.get_data()); +#ifdef DEBUG_SHADER + + DEBUG_PRINT("\Geometry Code:\n\n" + String(code_string.get_data())); + for (int i = 0; i < strings.size(); i++) { + + //print_line("vert strings "+itos(i)+":"+String(strings[i])); + } +#endif + if (has_geometry) { + v.geom_id = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(v.geom_id, strings.size(), &strings[0], NULL); + glCompileShader(v.geom_id); + + glGetShaderiv(v.geom_id, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + // error compiling + GLsizei iloglen; + glGetShaderiv(v.geom_id, GL_INFO_LOG_LENGTH, &iloglen); + + if (iloglen < 0) { + + glDeleteShader(v.geom_id); + glDeleteProgram(v.id); + v.id = 0; + + ERR_PRINT("Geometry shader compilation failed with empty log"); + } else { + + if (iloglen == 0) { + + iloglen = 4096; //buggy driver (Adreno 220+....) + } + + char *ilogmem = (char *)memalloc(iloglen + 1); + ilogmem[iloglen] = 0; + glGetShaderInfoLog(v.geom_id, iloglen, &iloglen, ilogmem); + + String err_string = get_shader_name() + ": Geometry Program Compilation Failed:\n"; + + err_string += ilogmem; + _display_error_with_code(err_string, strings); + memfree(ilogmem); + glDeleteShader(v.geom_id); + glDeleteProgram(v.id); + v.id = 0; + } + + ERR_FAIL_V(NULL); + } + } +#endif + /* FRAGMENT SHADER */ strings.resize(strings_base_size); @@ -407,6 +498,11 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { if (iloglen < 0) { glDeleteShader(v.frag_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; @@ -429,6 +525,11 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { ERR_PRINT(err_string.ascii().get_data()); memfree(ilogmem); glDeleteShader(v.frag_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; @@ -438,6 +539,11 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { } glAttachShader(v.id, v.frag_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glAttachShader(v.id, v.geom_id); + } +#endif glAttachShader(v.id, v.vert_id); // bind attributes before linking @@ -475,6 +581,11 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { if (iloglen < 0) { glDeleteShader(v.frag_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; @@ -497,6 +608,11 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { ERR_PRINT(err_string.ascii().get_data()); Memory::free_static(ilogmem); glDeleteShader(v.frag_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.vert_id); glDeleteProgram(v.id); v.id = 0; @@ -572,12 +688,8 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co conditional_count = p_conditional_count; conditional_defines = p_conditional_defines; uniform_names = p_uniform_names; - vertex_code = p_vertex_code; - fragment_code = p_fragment_code; texunit_pairs = p_texunit_pairs; texunit_pair_count = p_texunit_pair_count; - vertex_code_start = p_vertex_code_start; - fragment_code_start = p_fragment_code_start; attribute_pairs = p_attribute_pairs; attribute_pair_count = p_attribute_count; ubo_pairs = p_ubo_pairs; @@ -585,84 +697,138 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co feedbacks = p_feedback; feedback_count = p_feedback_count; - //split vertex and shader code (thank you, shader compiler programmers from you know what company). - { - String globals_tag = "\nVERTEX_SHADER_GLOBALS"; - String material_tag = "\nMATERIAL_UNIFORMS"; - String code_tag = "\nVERTEX_SHADER_CODE"; - String code = vertex_code; - int cpos = code.find(material_tag); + setup_vertex(p_vertex_code, p_vertex_code_start); + setup_fragment(p_fragment_code, p_fragment_code_start); +} + +void ShaderGLES3::setup_vertex(const char *p_vertex_code, int p_vertex_code_start) { + + vertex_code = p_vertex_code; + vertex_code_start = p_vertex_code_start; + + String globals_tag = "\nVERTEX_SHADER_GLOBALS"; + String material_tag = "\nMATERIAL_UNIFORMS"; + String code_tag = "\nVERTEX_SHADER_CODE"; + String code = vertex_code; + int 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_code0 = code.ascii(); + vertex_code1 = code.ascii(); } else { - vertex_code0 = code.substr(0, cpos).ascii(); - code = code.substr(cpos + material_tag.length(), code.length()); - cpos = code.find(globals_tag); + 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_code1 = code.ascii(); + vertex_code2 = code2.ascii(); } else { - vertex_code1 = code.substr(0, cpos).ascii(); - String code2 = code.substr(cpos + globals_tag.length(), code.length()); + vertex_code2 = code2.substr(0, cpos).ascii(); + vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); + } + } + } +} - cpos = code2.find(code_tag); - if (cpos == -1) { - vertex_code2 = code2.ascii(); - } else { +void ShaderGLES3::setup_geometry(const char *p_geometry_code, int p_geometry_code_start) { - vertex_code2 = code2.substr(0, cpos).ascii(); - vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); - } + geometry_code = p_geometry_code; + geometry_code_start = p_geometry_code_start; + + String globals_tag = "\nGEOMETRY_SHADER_GLOBALS"; + String material_tag = "\nMATERIAL_UNIFORMS"; + String code_tag = "\nGEOMETRY_SHADER_CODE"; + String code = geometry_code; + + int cpos = code.find(material_tag); + if (cpos == -1) { + geometry_code0 = code.ascii(); + } else { + geometry_code0 = code.substr(0, cpos).ascii(); + //print_line("CODE0:\n"+String(geometry_code0.get_data())); + + code = code.substr(cpos + material_tag.length(), code.length()); + + cpos = code.find(globals_tag); + + if (cpos == -1) { + geometry_code1 = code.ascii(); + } else { + + geometry_code1 = code.substr(0, cpos).ascii(); + //print_line("CODE1:\n"+String(geometry_code1.get_data())); + + String code2 = code.substr(cpos + globals_tag.length(), code.length()); + cpos = code2.find(code_tag); + + if (cpos == -1) { + geometry_code2 = code2.ascii(); + } else { + geometry_code2 = code2.substr(0, cpos).ascii(); + //print_line("CODE2:\n" + String(geometry_code2.get_data())); + + geometry_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); + //print_line("CODE3:\n" + String(geometry_code3.get_data())); } } } +} + +void ShaderGLES3::setup_fragment(const char *p_fragment_code, int p_fragment_code_start) { + + fragment_code = p_fragment_code; + fragment_code_start = p_fragment_code_start; + + 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 = fragment_code; + int 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); - { - 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 = fragment_code; - int cpos = code.find(material_tag); if (cpos == -1) { - fragment_code0 = code.ascii(); + fragment_code1 = 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); + + 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_code1 = code.ascii(); + fragment_code2 = code2.ascii(); } else { - fragment_code1 = code.substr(0, cpos).ascii(); - //print_line("CODE1:\n"+String(fragment_code1.get_data())); + fragment_code2 = code2.substr(0, cpos).ascii(); + //print_line("CODE2:\n"+String(fragment_code2.get_data())); - String code2 = code.substr(cpos + globals_tag.length(), code.length()); - cpos = code2.find(light_code_tag); + String code3 = code2.substr(cpos + light_code_tag.length(), code2.length()); + cpos = code3.find(code_tag); if (cpos == -1) { - fragment_code2 = code2.ascii(); + fragment_code3 = code3.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())); - } + 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())); } } } @@ -678,6 +844,11 @@ void ShaderGLES3::finish() { Version &v = version_map[*V]; glDeleteShader(v.vert_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.frag_id); glDeleteProgram(v.id); memdelete_arr(v.uniform_location); @@ -691,6 +862,11 @@ void ShaderGLES3::clear_caches() { Version &v = version_map[*V]; glDeleteShader(v.vert_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.frag_id); glDeleteProgram(v.id); memdelete_arr(v.uniform_location); @@ -711,13 +887,15 @@ uint32_t ShaderGLES3::create_custom_shader() { return last_custom_code++; } -void ShaderGLES3::set_custom_shader_code(uint32_t p_code_id, const String &p_vertex, const String &p_vertex_globals, const String &p_fragment, const String &p_light, const String &p_fragment_globals, const String &p_uniforms, const Vector &p_texture_uniforms, const Vector &p_custom_defines) { +void ShaderGLES3::set_custom_shader_code(uint32_t p_code_id, const String &p_vertex, const String &p_vertex_globals, const String &p_geometry, const String &p_geometry_globals, const String &p_fragment, const String &p_light, const String &p_fragment_globals, const String &p_uniforms, const Vector &p_texture_uniforms, const Vector &p_custom_defines) { ERR_FAIL_COND(!custom_code_map.has(p_code_id)); CustomCode *cc = &custom_code_map[p_code_id]; cc->vertex = p_vertex; cc->vertex_globals = p_vertex_globals; + cc->geometry = p_geometry; + cc->geometry_globals = p_geometry_globals; cc->fragment = p_fragment; cc->fragment_globals = p_fragment_globals; cc->light = p_light; @@ -748,6 +926,11 @@ void ShaderGLES3::free_custom_shader(uint32_t p_code_id) { Version &v = version_map[key]; glDeleteShader(v.vert_id); +#ifdef GLES_OVER_GL + if (has_geometry) { + glDeleteShader(v.geom_id); + } +#endif glDeleteShader(v.frag_id); glDeleteProgram(v.id); memdelete_arr(v.uniform_location); diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index be2c34ba0796..6ac21bbed4d3 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -103,6 +103,7 @@ class ShaderGLES3 { int ubo_count; int feedback_count; int vertex_code_start; + int geometry_code_start; int fragment_code_start; int attribute_pair_count; @@ -110,10 +111,13 @@ class ShaderGLES3 { String vertex; String vertex_globals; + String geometry; + String geometry_globals; String fragment; String fragment_globals; String light; String uniforms; + bool has_geometry; uint32_t version; Vector texture_uniforms; Vector custom_defines; @@ -124,6 +128,7 @@ class ShaderGLES3 { GLuint id; GLuint vert_id; + GLuint geom_id; GLuint frag_id; GLint *uniform_location; Vector texture_uniform_locations; @@ -132,6 +137,7 @@ class ShaderGLES3 { Version() : id(0), vert_id(0), + geom_id(0), frag_id(0), uniform_location(NULL), code_version(0), @@ -174,6 +180,7 @@ class ShaderGLES3 { const UBOPair *ubo_pairs; const Feedback *feedbacks; const char *vertex_code; + const char *geometry_code; const char *fragment_code; CharString fragment_code0; CharString fragment_code1; @@ -186,6 +193,12 @@ class ShaderGLES3 { CharString vertex_code2; CharString vertex_code3; + CharString geometry_code0; + CharString geometry_code1; + CharString geometry_code2; + CharString geometry_code3; + bool has_geometry; + Vector custom_defines; int base_material_tex_index; @@ -303,6 +316,9 @@ class ShaderGLES3 { _FORCE_INLINE_ void _set_conditional(int p_which, bool p_value); void setup(const char **p_conditional_defines, int p_conditional_count, const char **p_uniform_names, int p_uniform_count, const AttributePair *p_attribute_pairs, int p_attribute_count, const TexUnitPair *p_texunit_pairs, int p_texunit_pair_count, const UBOPair *p_ubo_pairs, int p_ubo_pair_count, const Feedback *p_feedback, int p_feedback_count, const char *p_vertex_code, const char *p_fragment_code, int p_vertex_code_start, int p_fragment_code_start); + void setup_vertex(const char *p_vertex_code, int p_vertex_code_start); + void setup_geometry(const char *p_geometry_code, int p_geometry_code_start); + void setup_fragment(const char *p_fragment_code, int p_fragment_code_start); ShaderGLES3(); @@ -324,7 +340,7 @@ class ShaderGLES3 { void clear_caches(); uint32_t create_custom_shader(); - void set_custom_shader_code(uint32_t p_code_id, const String &p_vertex, const String &p_vertex_globals, const String &p_fragment, const String &p_light, const String &p_fragment_globals, const String &p_uniforms, const Vector &p_texture_uniforms, const Vector &p_custom_defines); + void set_custom_shader_code(uint32_t p_code_id, const String &p_vertex, const String &p_vertex_globals, const String &p_geometry, const String &p_geometry_globals, const String &p_fragment, const String &p_light, const String &p_fragment_globals, const String &p_uniforms, const Vector &p_texture_uniforms, const Vector &p_custom_defines); void set_custom_shader(uint32_t p_code_id); void free_custom_shader(uint32_t p_code_id); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 0d1e7ee4a1dd..6405e4467c57 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -248,6 +248,109 @@ VERTEX_SHADER_CODE #endif } +/* clang-format off */ +[geometry] + +/* geometry shader settings */ + +#ifndef GEOMETRY_IN_MODE +#define GEOMETRY_IN_MODE 2 +#endif + +#ifndef GEOMETRY_OUT_MODE +#define GEOMETRY_OUT_MODE 2 +#endif + +#if GEOMETRY_IN_MODE == 0 +layout (points) in; +#elif GEOMETRY_IN_MODE == 1 +layout (lines) in; +#elif GEOMETRY_IN_MODE == 2 +layout (triangles) in; +#endif + +#if GEOMETRY_OUT_MODE == 0 +layout (points) out; +#elif GEOMETRY_OUT_MODE == 1 +layout (line_strip) out; +#elif GEOMETRY_OUT_MODE == 2 +layout (triangle_strip) out; +#endif + +#ifndef GEOMETRY_MAX_VERTICES +#define GEOMETRY_MAX_VERTICES 0 +#endif + +layout (max_vertices = GEOMETRY_MAX_VERTICES) out; + +/* clang-format on */ + +layout(std140) uniform CanvasItemData { //ubo:0 + + highp mat4 projection_matrix; + highp float time; +}; + +uniform highp mat4 modelview_matrix; +uniform highp mat4 extra_matrix; + +out highp vec2 uv_interp; +out mediump vec4 color_interp; + +#if defined(USE_MATERIAL) + +/* clang-format off */ +layout(std140) uniform UniformData { //ubo:1 + +MATERIAL_UNIFORMS + +}; +/* clang-format on */ + +#endif + +/* clang-format off */ + +GEOMETRY_SHADER_GLOBALS + +/* clang-format on */ + +vec4 tpos(float x, float y) { + return projection_matrix * modelview_matrix * vec4(x, y, 0, 0); +} + +vec4 tpos(vec2 v) { + return projection_matrix * modelview_matrix * vec4(v.x, v.y, 0, 0); +} + +vec4 tpos(float x, float y, float z) { + return projection_matrix * modelview_matrix * vec4(x, y, z, 0); +} + +vec4 tpos(vec3 v) { + return projection_matrix * modelview_matrix * vec4(v.x, v.y, v.z, 0); +} + +vec4 tpos(float x, float y, float z, float w) { + return projection_matrix * modelview_matrix * vec4(x, y, z, w); +} + +vec4 tpos(vec4 v) { + return projection_matrix * modelview_matrix * vec4(v.x, v.y, v.z, v.w); +} + +void main() { + int index = 0; + + { + /* clang-format off */ + +GEOMETRY_SHADER_CODE + + /* clang-format on */ + } +} + /* clang-format off */ [fragment] diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 630e1c2089cb..b2278564b05a 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -444,9 +444,10 @@ void main() { #endif highp mat4 modelview = camera_inverse_matrix * world_matrix; + { /* clang-format off */ - + VERTEX_SHADER_CODE /* clang-format on */ @@ -577,6 +578,173 @@ VERTEX_SHADER_CODE #endif // USE_VERTEX_LIGHTING } +/* clang-format off */ +[geometry] + +/* geometry shader settings */ + +#ifndef GEOMETRY_IN_MODE +#define GEOMETRY_IN_MODE 2 +#endif + +#ifndef GEOMETRY_OUT_MODE +#define GEOMETRY_OUT_MODE 2 +#endif + +#if GEOMETRY_IN_MODE == 0 +layout (points) in; +#elif GEOMETRY_IN_MODE == 1 +layout (lines) in; +#elif GEOMETRY_IN_MODE == 2 +layout (triangles) in; +#endif + +#if GEOMETRY_OUT_MODE == 0 +layout (points) out; +#elif GEOMETRY_OUT_MODE == 1 +layout (line_strip) out; +#elif GEOMETRY_OUT_MODE == 2 +layout (triangle_strip) out; +#endif + +#ifndef GEOMETRY_MAX_VERTICES +#define GEOMETRY_MAX_VERTICES 0 +#endif + +layout (max_vertices = GEOMETRY_MAX_VERTICES) out; + +/* clang-format on */ + +layout(std140) uniform SceneData { // ubo:0 + + highp mat4 projection_matrix; + highp mat4 inv_projection_matrix; + highp mat4 camera_inverse_matrix; + highp mat4 camera_matrix; + + mediump vec4 ambient_light_color; + mediump vec4 bg_color; + + mediump vec4 fog_color_enabled; + mediump vec4 fog_sun_color_amount; + + mediump float ambient_energy; + mediump float bg_energy; + + mediump float z_offset; + mediump float z_slope_scale; + highp float shadow_dual_paraboloid_render_zfar; + highp float shadow_dual_paraboloid_render_side; + + highp vec2 viewport_size; + highp vec2 screen_pixel_size; + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; + + highp float time; + highp float z_far; + mediump float reflection_multiplier; + mediump float subsurface_scatter_width; + mediump float ambient_occlusion_affect_light; + mediump float ambient_occlusion_affect_ao_channel; + mediump float opaque_prepass_threshold; + + bool fog_depth_enabled; + highp float fog_depth_begin; + highp float fog_depth_end; + mediump float fog_density; + highp float fog_depth_curve; + bool fog_transmit_enabled; + highp float fog_transmit_curve; + bool fog_height_enabled; + highp float fog_height_min; + highp float fog_height_max; + highp float fog_height_curve; +}; + +uniform highp mat4 world_transform; + +/* Varyings */ + +out vec3 normal_interp; + +#if defined(ENABLE_COLOR_INTERP) +out vec4 color_interp; +#endif + +#if defined(ENABLE_UV_INTERP) +out vec2 uv_interp; +#endif + +#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP) +out vec2 uv2_interp; +#endif + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) +out vec3 tangent_interp; +out vec3 binormal_interp; +#endif + +/* Material Uniforms */ + +#if defined(USE_MATERIAL) + +/* clang-format off */ +layout(std140) uniform UniformData { // ubo:1 + +MATERIAL_UNIFORMS + +}; +/* clang-format on */ + +#endif + +/* clang-format off */ + +GEOMETRY_SHADER_GLOBALS + +/* clang-format on */ + +vec4 tpos(float x, float y) { + return projection_matrix * (camera_inverse_matrix * world_transform) * vec4(x, y, 0, 0); +} + +vec4 tpos(vec2 v) { + return projection_matrix * (camera_inverse_matrix * world_transform) * vec4(v.x, v.y, 0, 0); +} + +vec4 tpos(float x, float y, float z) { + return projection_matrix * (camera_inverse_matrix * world_transform) * vec4(x, y, z, 0); +} + +vec4 tpos(vec3 v) { + return projection_matrix * (camera_inverse_matrix * world_transform) * vec4(v.x, v.y, v.z, 0); +} + +vec4 tpos(float x, float y, float z, float w) { + return projection_matrix * (camera_inverse_matrix * world_transform) * vec4(x, y, z, w); +} + +vec4 tpos(vec4 v) { + return projection_matrix * (camera_inverse_matrix * world_transform) * vec4(v.x, v.y, v.z, v.w); +} + +void main() { + int index = 0; + + highp mat4 world_matrix = world_transform; + + highp mat4 modelview = camera_inverse_matrix * world_matrix; + + { + /* clang-format off */ + +GEOMETRY_SHADER_CODE + + /* clang-format on */ + } +} + /* clang-format off */ [fragment] diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index d39e52111351..2c0a15593843 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -134,6 +134,11 @@ void ShaderTextEditor::_load_theme_settings() { keywords.push_back(ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode()))[i]); } + + for (int i = 0; i < ShaderTypes::get_singleton()->get_ranges(VisualServer::ShaderMode(shader->get_mode())).size(); i++) { + + keywords.push_back(ShaderTypes::get_singleton()->get_ranges(VisualServer::ShaderMode(shader->get_mode()))[i]); + } } for (List::Element *E = keywords.front(); E; E = E->next()) { @@ -173,7 +178,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List ShaderLanguage sl; String calltip; - Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip); + Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_ranges(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip); if (err != OK) ERR_PRINT("Shaderlang complete failed"); @@ -192,7 +197,7 @@ void ShaderTextEditor::_validate_script() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types()); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_ranges(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types()); if (err != OK) { String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); diff --git a/gles_builders.py b/gles_builders.py index e56ccc443161..421ff0ffb0bc 100644 --- a/gles_builders.py +++ b/gles_builders.py @@ -10,6 +10,7 @@ class LegacyGLHeaderStruct: def __init__(self): self.vertex_lines = [] + self.geometry_lines = [] self.fragment_lines = [] self.uniforms = [] self.attributes = [] @@ -28,6 +29,7 @@ def __init__(self): self.reading = "" self.line_offset = 0 self.vertex_offset = 0 + self.geometry_offset = 0 self.fragment_offset = 0 @@ -44,6 +46,13 @@ def include_file_in_legacygl_header(filename, header_data, depth): header_data.vertex_offset = header_data.line_offset continue + if line.find("[geometry]") != -1: + header_data.reading = "geometry" + line = fs.readline() + header_data.line_offset += 1 + header_data.geometry_offset = header_data.line_offset + continue + if line.find("[fragment]") != -1: header_data.reading = "fragment" line = fs.readline() @@ -177,6 +186,8 @@ def include_file_in_legacygl_header(filename, header_data, depth): if header_data.reading == "vertex": header_data.vertex_lines += [line] + if header_data.reading == "geometry": + header_data.geometry_lines += [line] if header_data.reading == "fragment": header_data.fragment_lines += [line] @@ -454,6 +465,17 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2 fd.write("\t\tstatic const int _vertex_code_start=" + str(header_data.vertex_offset) + ";\n") + if not gles2: + fd.write("\t\tstatic const char _geometry_code[]={\n") + for x in header_data.geometry_lines: + for c in x: + fd.write(str(ord(c)) + ",") + + fd.write(str(ord('\n')) + ",") + fd.write("\t\t0};\n\n") + + fd.write("\t\tstatic const int _geometry_code_start=" + str(header_data.geometry_offset) + ";\n") + fd.write("\t\tstatic const char _fragment_code[]={\n") for x in header_data.fragment_lines: for c in x: @@ -472,6 +494,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2 fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_attribute_pairs," + str( len(header_data.attributes)) + ", _texunit_pairs," + str(len(header_data.texunits)) + ",_ubo_pairs," + str(len(header_data.ubos)) + ",_feedbacks," + str( feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") + fd.write("\t\tsetup_geometry(_geometry_code, _geometry_code_start);\n") else: if gles2: fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_texunit_pairs," + str( @@ -481,6 +504,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2 fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_texunit_pairs," + str( len(header_data.texunits)) + ",_enums," + str(len(header_data.enums)) + ",_enum_values," + str(enum_value_count) + ",_ubo_pairs," + str(len(header_data.ubos)) + ",_feedbacks," + str( feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") + fd.write("\t\tsetup_geometry(_geometry_code, _geometry_code_start);\n") fd.write("\t}\n\n") diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp index dcb19b7df7d7..3d72a0926acc 100644 --- a/main/tests/test_shader_lang.cpp +++ b/main/tests/test_shader_lang.cpp @@ -328,8 +328,9 @@ MainLoop *test() { rm.push_back("popo"); Set types; types.insert("spatial"); + Vector rr; - Error err = sl.compile(code, dt, rm, types); + Error err = sl.compile(code, dt, rm, rr, types); if (err) { diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 33714a79b2fa..ca9d79f66335 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2034,6 +2034,18 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, + // geometry shader + + { "tpos", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, + { "tpos", TYPE_VEC4, { TYPE_VEC2, TYPE_VOID } }, + { "tpos", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, + { "tpos", TYPE_VEC4, { TYPE_VEC3, TYPE_VOID } }, + { "tpos", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, + { "tpos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, + + { "EmitVertex", TYPE_VOID, { TYPE_VOID } }, + { "EndPrimitive", TYPE_VOID, { TYPE_VOID } }, + { NULL, TYPE_VOID, { TYPE_VOID } } }; @@ -4008,7 +4020,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map &p_functions, const Vector &p_render_modes, const Set &p_shader_types) { +Error ShaderLanguage::_parse_shader(const Map &p_functions, const Vector &p_render_modes, const Vector &p_ranges, const Set &p_shader_types) { Token tk = _get_token(); @@ -4067,19 +4079,47 @@ Error ShaderLanguage::_parse_shader(const Map &p_funct return ERR_PARSE_ERROR; } - if (p_render_modes.find(mode) == -1) { + if (p_render_modes.find(mode) == -1 && p_ranges.find(mode) == -1) { _set_error("Invalid render mode: '" + String(mode) + "'"); return ERR_PARSE_ERROR; } - if (shader->render_modes.find(mode) != -1) { + if (shader->render_modes.find(mode) != -1 || shader->render_ranges.has(mode)) { _set_error("Duplicate render mode: '" + String(mode) + "'"); return ERR_PARSE_ERROR; } - shader->render_modes.push_back(mode); + bool is_range = false; + + if (p_ranges.find(mode) != -1) { + is_range = true; + } else { + shader->render_modes.push_back(mode); + } tk = _get_token(); + if (is_range) { + if (tk.type == TK_PARENTHESIS_OPEN) { + tk = _get_token(); + if (tk.type == TK_INT_CONSTANT) { + shader->render_ranges[mode] = (int)tk.constant; + } else { + _set_error("Expected integer constant"); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + if (tk.type != TK_PARENTHESIS_CLOSE) { + _set_error("Expected ')' after expression"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); + } else { + _set_error("Expected '(' after range name"); + return ERR_PARSE_ERROR; + } + } + if (tk.type == TK_COMMA) { //all good, do nothing } else if (tk.type == TK_SEMICOLON) { @@ -4572,7 +4612,7 @@ String ShaderLanguage::get_shader_type(const String &p_code) { return String(); } -Error ShaderLanguage::compile(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Set &p_shader_types) { +Error ShaderLanguage::compile(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Vector &p_ranges, const Set &p_shader_types) { clear(); @@ -4581,7 +4621,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map(); - Error err = _parse_shader(p_functions, p_render_modes, p_shader_types); + Error err = _parse_shader(p_functions, p_render_modes, p_ranges, p_shader_types); if (err != OK) { return err; @@ -4589,7 +4629,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Set &p_shader_types, List *r_options, String &r_call_hint) { +Error ShaderLanguage::complete(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Vector &p_ranges, const Set &p_shader_types, List *r_options, String &r_call_hint) { clear(); @@ -4598,7 +4638,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map(); - Error err = _parse_shader(p_functions, p_render_modes, p_shader_types); + Error err = _parse_shader(p_functions, p_render_modes, p_ranges, p_shader_types); if (err != OK) ERR_PRINT("Failed to parse shader"); @@ -4613,6 +4653,10 @@ Error ShaderLanguage::complete(const String &p_code, const Mappush_back(p_render_modes[i]); } + for (int i = 0; i < p_ranges.size(); i++) { + + r_options->push_back(p_ranges[i]); + } return OK; } break; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 67c273d26725..58c79feca8ba 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -495,6 +495,7 @@ class ShaderLanguage { Map varyings; Map uniforms; Vector render_modes; + Map render_ranges; Vector functions; @@ -670,7 +671,7 @@ class ShaderLanguage { Node *_parse_and_reduce_expression(BlockNode *p_block, const Map &p_builtin_types); Error _parse_block(BlockNode *p_block, const Map &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); - Error _parse_shader(const Map &p_functions, const Vector &p_render_modes, const Set &p_shader_types); + Error _parse_shader(const Map &p_functions, const Vector &p_render_modes, const Vector &p_ranges, const Set &p_shader_types); public: //static void get_keyword_list(ShaderType p_type,List *p_keywords); @@ -678,8 +679,8 @@ class ShaderLanguage { void clear(); static String get_shader_type(const String &p_code); - Error compile(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Set &p_shader_types); - Error complete(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Set &p_shader_types, List *r_options, String &r_call_hint); + Error compile(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Vector &p_ranges, const Set &p_shader_types); + Error complete(const String &p_code, const Map &p_functions, const Vector &p_render_modes, const Vector &p_ranges, const Set &p_shader_types, List *r_options, String &r_call_hint); String get_error_text(); int get_error_line(); diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index 7a42bc475eb0..5150b537c1ed 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -40,6 +40,11 @@ const Vector &ShaderTypes::get_modes(VS::ShaderMode p_mode) { return shader_modes[p_mode].modes; } +const Vector &ShaderTypes::get_ranges(VS::ShaderMode p_mode) { + + return shader_modes[p_mode].ranges; +} + const Set &ShaderTypes::get_types() { return shader_types; } @@ -56,6 +61,8 @@ ShaderTypes::ShaderTypes() { /*************** SPATIAL ***********************/ + // SPATIAL-VERTEX + shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3; @@ -81,6 +88,44 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); + // SPATIAL-GEOMETRY + + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["LENGTH"] = constt(ShaderLanguage::TYPE_INT); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["INDEX"] = ShaderLanguage::TYPE_INT; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["IN_VERTEX"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_VERTEX"] = ShaderLanguage::TYPE_VEC4; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_NORMAL"] = ShaderLanguage::TYPE_VEC3; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_TANGENT"] = ShaderLanguage::TYPE_VEC3; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_BINORMAL"] = ShaderLanguage::TYPE_VEC3; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_UV"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_UV2"] = ShaderLanguage::TYPE_VEC2; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUT_COLOR"] = ShaderLanguage::TYPE_VEC4; + + //builtins + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4; + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); + shader_modes[VS::SHADER_SPATIAL].functions["geometry"].can_discard = false; + + //ranges + shader_modes[VS::SHADER_SPATIAL].ranges.push_back("geometry_max_vertices"); + + //modes + shader_modes[VS::SHADER_SPATIAL].modes.push_back("geometry_in_points"); + shader_modes[VS::SHADER_SPATIAL].modes.push_back("geometry_in_lines"); + shader_modes[VS::SHADER_SPATIAL].modes.push_back("geometry_in_triangles"); + shader_modes[VS::SHADER_SPATIAL].modes.push_back("geometry_out_points"); + shader_modes[VS::SHADER_SPATIAL].modes.push_back("geometry_out_lines"); + shader_modes[VS::SHADER_SPATIAL].modes.push_back("geometry_out_triangles"); + + // SPATIAL-FRAGMENT + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRONT_FACING"] = constt(ShaderLanguage::TYPE_BOOL); @@ -116,8 +161,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); - + //builtins shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); @@ -125,8 +169,11 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[VS::SHADER_SPATIAL].functions["fragment"].can_discard = true; + // SPATIAL-LIGHT + shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); @@ -135,6 +182,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); + //builtins shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["NORMAL"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3); @@ -150,6 +198,8 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["light"].can_discard = true; + // RENDER_MODES + //order used puts first enum mode (default) first shader_modes[VS::SHADER_SPATIAL].modes.push_back("blend_mix"); shader_modes[VS::SHADER_SPATIAL].modes.push_back("blend_add"); @@ -192,6 +242,8 @@ ShaderTypes::ShaderTypes() { /************ CANVAS ITEM **************************/ + // CANVAS-ITEM-VERTEX + shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; @@ -206,6 +258,35 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2); shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].can_discard = false; + // CANVAS-ITEM-GEOMETRY + + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["LENGTH"] = constt(ShaderLanguage::TYPE_INT); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["INDEX"] = ShaderLanguage::TYPE_INT; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["IN_VERTEX"] = constt(ShaderLanguage::TYPE_VEC4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["OUT_VERTEX"] = ShaderLanguage::TYPE_VEC4; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["OUT_COLOR"] = ShaderLanguage::TYPE_VEC4; + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["OUT_UV"] = ShaderLanguage::TYPE_VEC2; + + //builtins + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["EXTRA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[VS::SHADER_CANVAS_ITEM].functions["geometry"].can_discard = false; + + //ranges + shader_modes[VS::SHADER_CANVAS_ITEM].ranges.push_back("geometry_max_vertices"); + + //modes + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("geometry_in_points"); + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("geometry_in_lines"); + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("geometry_in_triangles"); + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("geometry_out_points"); + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("geometry_out_lines"); + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("geometry_out_triangles"); + + // CANVAS-ITEM-FRAGMENT + shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3; @@ -223,6 +304,8 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["SCREEN_TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D); shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].can_discard = true; + // CANVAS-ITEM-LIGHT + shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["NORMAL"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2); @@ -240,6 +323,8 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].can_discard = true; + // RENDER_MODES + shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("skip_vertex_transform"); shader_modes[VS::SHADER_CANVAS_ITEM].modes.push_back("blend_mix"); diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h index 149c9b5e1f5d..9229f72b62d5 100644 --- a/servers/visual/shader_types.h +++ b/servers/visual/shader_types.h @@ -41,6 +41,7 @@ class ShaderTypes { Map functions; Vector modes; + Vector ranges; }; Map shader_modes; @@ -54,6 +55,7 @@ class ShaderTypes { const Map &get_functions(VS::ShaderMode p_mode); const Vector &get_modes(VS::ShaderMode p_mode); + const Vector &get_ranges(VS::ShaderMode p_mode); const Set &get_types(); ShaderTypes();