diff options
Diffstat (limited to 'drivers/gles3')
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 157 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.h | 3 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 2 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 17 | ||||
-rw-r--r-- | drivers/gles3/shader_gles3.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 8 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas_uniforms_inc.glsl | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 22 | ||||
-rw-r--r-- | drivers/gles3/storage/light_storage.cpp | 2 | ||||
-rw-r--r-- | drivers/gles3/storage/material_storage.cpp | 66 | ||||
-rw-r--r-- | drivers/gles3/storage/material_storage.h | 3 | ||||
-rw-r--r-- | drivers/gles3/storage/mesh_storage.cpp | 42 | ||||
-rw-r--r-- | drivers/gles3/storage/mesh_storage.h | 8 |
13 files changed, 206 insertions, 129 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 83154acd51..a960fced1f 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -201,6 +201,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ bool material_screen_texture_found = false; Rect2 back_buffer_rect; bool backbuffer_copy = false; + bool backbuffer_gen_mipmaps = false; Item *ci = p_item_list; Item *canvas_group_owner = nullptr; @@ -225,6 +226,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ if (!material_screen_texture_found) { backbuffer_copy = true; back_buffer_rect = Rect2(); + backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps; } } @@ -282,7 +284,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); item_count = 0; - texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true); + texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps); backbuffer_copy = false; material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies @@ -320,6 +322,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou RID prev_material; uint32_t index = 0; GLES3::CanvasShaderData::BlendMode last_blend_mode = GLES3::CanvasShaderData::BLEND_MODE_MIX; + Color last_blend_color; GLES3::CanvasShaderData *shader_data_cache = nullptr; state.current_tex = texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE); @@ -376,8 +379,80 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX; - if (last_blend_mode != blend_mode) { - if (last_blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) { + _render_item(p_to_render_target, ci, canvas_transform_inverse, current_clip, p_lights, index, blend_mode, last_blend_mode, last_blend_color); + } + // Render last command + _render_batch(index); +} + +void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index, GLES3::CanvasShaderData::BlendMode p_blend_mode, GLES3::CanvasShaderData::BlendMode &r_last_blend_mode, Color &r_last_blend_color) { + // Used by Polygon and Mesh. + static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP }; + + RS::CanvasItemTextureFilter current_filter = state.default_filter; + RS::CanvasItemTextureRepeat current_repeat = state.default_repeat; + + if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) { + current_filter = p_item->texture_filter; + } + + if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) { + current_repeat = p_item->texture_repeat; + } + + Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform; + Transform2D draw_transform; // Used by transform command + + Color base_color = p_item->final_modulate; + + uint32_t base_flags = 0; + + bool reclip = false; + + bool skipping = false; + + const Item::Command *c = p_item->commands; + while (c) { + if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) { + c = c->next; + continue; + } + + if (c->type != Item::Command::TYPE_MESH) { + // For Meshes, this gets updated below. + _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world); + } + + for (int i = 0; i < 4; i++) { + state.instance_data_array[r_index].modulation[i] = 0.0; + state.instance_data_array[r_index].ninepatch_margins[i] = 0.0; + state.instance_data_array[r_index].src_rect[i] = 0.0; + state.instance_data_array[r_index].dst_rect[i] = 0.0; + state.instance_data_array[r_index].lights[i] = uint32_t(0); + } + state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; + state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; + + state.instance_data_array[r_index].pad[0] = 0.0; + state.instance_data_array[r_index].pad[1] = 0.0; + + state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config + + GLES3::CanvasShaderData::BlendMode blend_mode = p_blend_mode; + Color blend_color; + + if (c->type == Item::Command::TYPE_RECT) { + const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c); + if (rect->flags & CANVAS_RECT_LCD) { + blend_mode = GLES3::CanvasShaderData::BLEND_MODE_LCD; + blend_color = rect->modulate; + } + } + + if (r_last_blend_mode != blend_mode || r_last_blend_color != blend_color) { + _render_batch(r_index); + + if (r_last_blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) { // re-enable it glEnable(GL_BLEND); } else if (blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) { @@ -390,6 +465,16 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou // Nothing to do here. } break; + case GLES3::CanvasShaderData::BLEND_MODE_LCD: { + glBlendEquation(GL_FUNC_ADD); + if (state.transparent_render_target) { + glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } else { + glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE); + } + glBlendColor(blend_color.r, blend_color.g, blend_color.b, blend_color.a); + + } break; case GLES3::CanvasShaderData::BLEND_MODE_MIX: { glBlendEquation(GL_FUNC_ADD); if (state.transparent_render_target) { @@ -435,68 +520,10 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou } break; } - last_blend_mode = blend_mode; - } - - _render_item(p_to_render_target, ci, canvas_transform_inverse, current_clip, p_lights, index); - } - // Render last command - _render_batch(index); -} - -void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index) { - // Used by Polygon and Mesh. - static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP }; - - RS::CanvasItemTextureFilter current_filter = state.default_filter; - RS::CanvasItemTextureRepeat current_repeat = state.default_repeat; - - if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) { - current_filter = p_item->texture_filter; - } - - if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) { - current_repeat = p_item->texture_repeat; - } - - Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform; - Transform2D draw_transform; // Used by transform command - - Color base_color = p_item->final_modulate; - - uint32_t base_flags = 0; - - bool reclip = false; - - bool skipping = false; - - const Item::Command *c = p_item->commands; - while (c) { - if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) { - c = c->next; - continue; - } - - if (c->type != Item::Command::TYPE_MESH) { - // For Meshes, this gets updated below. - _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world); + r_last_blend_mode = blend_mode; + r_last_blend_color = blend_color; } - for (int i = 0; i < 4; i++) { - state.instance_data_array[r_index].modulation[i] = 0.0; - state.instance_data_array[r_index].ninepatch_margins[i] = 0.0; - state.instance_data_array[r_index].src_rect[i] = 0.0; - state.instance_data_array[r_index].dst_rect[i] = 0.0; - state.instance_data_array[r_index].lights[i] = uint32_t(0); - } - state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; - state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; - - state.instance_data_array[r_index].pad[0] = 0.0; - state.instance_data_array[r_index].pad[1] = 0.0; - - state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config - switch (c->type) { case Item::Command::TYPE_RECT: { const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c); @@ -567,6 +594,8 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item state.instance_data_array[r_index].msdf[1] = rect->outline; // Outline size. state.instance_data_array[r_index].msdf[2] = 0.f; // Reserved. state.instance_data_array[r_index].msdf[3] = 0.f; // Reserved. + } else if (rect->flags & CANVAS_RECT_LCD) { + state.instance_data_array[r_index].flags |= FLAGS_USE_LCD; } state.instance_data_array[r_index].modulation[0] = rect->modulate.r * base_color.r; @@ -993,7 +1022,7 @@ void RasterizerCanvasGLES3::_bind_instance_data_buffer(uint32_t p_max_index) { } glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer]); -#ifdef JAVASCRIPT_ENABLED +#ifdef WEB_ENABLED //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * p_max_index, state.instance_data_array, GL_DYNAMIC_DRAW); #else diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index f920e37130..372ac00493 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -73,6 +73,7 @@ class RasterizerCanvasGLES3 : public RendererCanvasRender { FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27), FLAGS_USE_MSDF = (1 << 28), + FLAGS_USE_LCD = (1 << 29), }; enum { @@ -249,7 +250,7 @@ public: void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override; void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false); - void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index); + void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, uint32_t &r_index, GLES3::CanvasShaderData::BlendMode p_blend_mode, GLES3::CanvasShaderData::BlendMode &r_last_blend_mode, Color &r_last_blend_color); void _render_batch(uint32_t &p_max_index); void _bind_instance_data_buffer(uint32_t p_max_index); void _allocate_instance_data_buffer(); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 33303b1e38..7537636356 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -69,7 +69,7 @@ #endif #endif -#if !defined(IOS_ENABLED) && !defined(JAVASCRIPT_ENABLED) +#if !defined(IOS_ENABLED) && !defined(WEB_ENABLED) // We include EGL below to get debug callback on GLES2 platforms, // but EGL is not available on iOS. #define CAN_DEBUG diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 7207a6efbb..cb479dda39 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -648,7 +648,7 @@ void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const Pag float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); if (angular_diameter > 0.0) { - angular_diameter = Math::tan(Math::deg2rad(angular_diameter)); + angular_diameter = Math::tan(Math::deg_to_rad(angular_diameter)); } else { angular_diameter = 0.0; } @@ -867,7 +867,6 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.matrix[2][0], cm.matrix[0][0], cm.matrix[2][1], cm.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); - // Bind a vertex array or else OpenGL complains. We won't actually use it glBindVertexArray(sky_globals.screen_triangle_array); glViewport(0, 0, sky->radiance_size, sky->radiance_size); @@ -1519,7 +1518,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b light_data.color[2] = linear_col.b; float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); - light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset + light_data.size = 1.0 - Math::cos(Math::deg_to_rad(size)); //angle to cosine offset light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR); @@ -1646,7 +1645,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b light_data.inv_spot_attenuation = 1.0f / light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION); float spot_angle = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE); - light_data.cos_spot_angle = Math::cos(Math::deg2rad(spot_angle)); + light_data.cos_spot_angle = Math::cos(Math::deg_to_rad(spot_angle)); light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0; @@ -1655,18 +1654,18 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b // TODO, to avoid stalls, should rotate between 3 buffers based on frame index. // TODO, consider mapping the buffer as in 2D + glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_OMNILIGHT_UNIFORM_LOCATION, scene_state.omni_light_buffer); if (r_omni_light_count) { - glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_OMNILIGHT_UNIFORM_LOCATION, scene_state.omni_light_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData) * r_omni_light_count, scene_state.omni_lights); } + glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_SPOTLIGHT_UNIFORM_LOCATION, scene_state.spot_light_buffer); if (r_spot_light_count) { - glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_SPOTLIGHT_UNIFORM_LOCATION, scene_state.spot_light_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData) * r_spot_light_count, scene_state.spot_lights); } + glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, scene_state.directional_light_buffer); if (r_directional_light_count) { - glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, scene_state.directional_light_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(DirectionalLightData) * r_directional_light_count, scene_state.directional_lights); } glBindBuffer(GL_UNIFORM_BUFFER, 0); @@ -2150,7 +2149,9 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, index_array_gl = mesh_storage->mesh_surface_get_index_buffer(mesh_surface, surf->lod_index); if (prev_vertex_array_gl != vertex_array_gl) { - glBindVertexArray(vertex_array_gl); + if (vertex_array_gl != 0) { + glBindVertexArray(vertex_array_gl); + } prev_vertex_array_gl = vertex_array_gl; } diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 21ccef3518..033f10dbc5 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -472,7 +472,7 @@ String ShaderGLES3::_version_get_sha1(Version *p_version) const { bool ShaderGLES3::_load_from_cache(Version *p_version) { #if 0 String sha1 = _version_get_sha1(p_version); - String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; + String path = shader_cache_dir.path_join(name).path_join(base_sha256).path_join(sha1) + ".cache"; Ref<FileAccess> f = FileAccess::open(path, FileAccess::READ); if (f.is_null()) { @@ -538,7 +538,7 @@ bool ShaderGLES3::_load_from_cache(Version *p_version) { void ShaderGLES3::_save_to_cache(Version *p_version) { #if 0 String sha1 = _version_get_sha1(p_version); - String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache"; + String path = shader_cache_dir.path_join(name).path_join(base_sha256).path_join(sha1) + ".cache"; Ref<FileAccess> f = FileAccess::open(path, FileAccess::WRITE); ERR_FAIL_COND(f.is_null()); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 4df818cd4c..5ec25327be 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -473,7 +473,13 @@ void main() { float a = clamp(d * px_size + 0.5, 0.0, 1.0); color.a = a * color.a; } - + } else if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_LCD)) { + vec4 lcd_sample = texture(color_texture, uv); + if (lcd_sample.a == 1.0) { + color.rgb = lcd_sample.rgb * color.a; + } else { + color = vec4(0.0, 0.0, 0.0, 0.0); + } } else { #else { diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl index 852dccf415..6b61fe9375 100644 --- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -25,6 +25,7 @@ #define FLAGS_DEFAULT_SPECULAR_MAP_USED uint(1 << 27) #define FLAGS_USE_MSDF uint(1 << 28) +#define FLAGS_USE_LCD uint(1 << 29) // must be always 128 bytes long struct DrawData { diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 84daf839e9..c7fdd6ebd8 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -35,8 +35,8 @@ USE_RADIANCE_MAP = true /* from RenderingServer: ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit) -ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored. -ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal. +ARRAY_NORMAL = 1, // RG16 octahedral compression +ARRAY_TANGENT = 2, // RG16 octahedral compression, sign stored in sign of G ARRAY_COLOR = 3, // RGBA8 ARRAY_TEX_UV = 4, // RG32F ARRAY_TEX_UV2 = 5, // RG32F @@ -54,11 +54,11 @@ layout(location = 0) in highp vec3 vertex_attrib; /* clang-format on */ #ifdef NORMAL_USED -layout(location = 1) in vec3 normal_attrib; +layout(location = 1) in vec2 normal_attrib; #endif #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) -layout(location = 2) in vec4 tangent_attrib; +layout(location = 2) in vec2 tangent_attrib; #endif #if defined(COLOR_USED) @@ -97,6 +97,13 @@ layout(location = 10) in uvec4 bone_attrib; layout(location = 11) in vec4 weight_attrib; #endif +vec3 oct_to_vec3(vec2 e) { + vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y)); + float t = max(-v.z, 0.0); + v.xy += t * -sign(v.xy); + return v; +} + #ifdef USE_INSTANCING layout(location = 12) in highp vec4 instance_xform0; layout(location = 13) in highp vec4 instance_xform1; @@ -209,13 +216,14 @@ void main() { #endif #ifdef NORMAL_USED - vec3 normal = normal_attrib * 2.0 - 1.0; + vec3 normal = oct_to_vec3(normal_attrib * 2.0 - 1.0); #endif highp mat3 model_normal_matrix = mat3(model_matrix); #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) - vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0; - float binormalf = tangent_attrib.a * 2.0 - 1.0; + vec2 signed_tangent_attrib = tangent_attrib * 2.0 - 1.0; + vec3 tangent = oct_to_vec3(vec2(signed_tangent_attrib.x, abs(signed_tangent_attrib.y) * 2.0 - 1.0)); + float binormalf = sign(signed_tangent_attrib.y); vec3 binormal = normalize(cross(normal, tangent) * binormalf); #endif diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index 2e4bfdc15b..e2781bfbc0 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -318,7 +318,7 @@ AABB LightStorage::light_get_aabb(RID p_light) const { switch (light->type) { case RS::LIGHT_SPOT: { float len = light->param[RS::LIGHT_PARAM_RANGE]; - float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len; + float size = Math::tan(Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); }; case RS::LIGHT_OMNI: { diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 26441fc726..a64c7f7200 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1083,6 +1083,12 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet Vector<RID> textures; + if (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + continue; + } + if (p_texture_uniforms[i].global) { uses_global_textures = true; @@ -1450,8 +1456,8 @@ MaterialStorage::MaterialStorage() { actions.renames["UV2"] = "uv2_interp"; actions.renames["COLOR"] = "color_interp"; actions.renames["POINT_SIZE"] = "gl_PointSize"; - actions.renames["INSTANCE_ID"] = "gl_InstanceIndex"; - actions.renames["VERTEX_ID"] = "gl_VertexIndex"; + actions.renames["INSTANCE_ID"] = "gl_InstanceID"; + actions.renames["VERTEX_ID"] = "gl_VertexID"; actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold"; actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale"; @@ -1492,9 +1498,9 @@ MaterialStorage::MaterialStorage() { actions.renames["POINT_COORD"] = "gl_PointCoord"; actions.renames["INSTANCE_CUSTOM"] = "instance_custom"; actions.renames["SCREEN_UV"] = "screen_uv"; - actions.renames["SCREEN_TEXTURE"] = "color_buffer"; - actions.renames["DEPTH_TEXTURE"] = "depth_buffer"; - actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; + //actions.renames["SCREEN_TEXTURE"] = "color_buffer"; //Not implemented in 3D yet. + //actions.renames["DEPTH_TEXTURE"] = "depth_buffer"; // Not implemented in 3D yet. + //actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; // Not implemented in 3D yet actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; actions.renames["FOG"] = "fog"; @@ -2789,6 +2795,7 @@ void CanvasShaderData::set_code(const String &p_code) { ubo_size = 0; uniforms.clear(); uses_screen_texture = false; + uses_screen_texture_mipmaps = false; uses_sdf = false; uses_time = false; @@ -2799,7 +2806,6 @@ void CanvasShaderData::set_code(const String &p_code) { ShaderCompiler::GeneratedCode gen_code; int blend_modei = BLEND_MODE_MIX; - uses_screen_texture = false; ShaderCompiler::IdentifierActions actions; actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX; @@ -2826,6 +2832,7 @@ void CanvasShaderData::set_code(const String &p_code) { } blend_mode = BlendMode(blend_modei); + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; #if 0 print_line("**compiling shader:"); @@ -2833,12 +2840,16 @@ void CanvasShaderData::set_code(const String &p_code) { for (int i = 0; i < gen_code.defines.size(); i++) { print_line(gen_code.defines[i]); } + + HashMap<String, String>::Iterator el = gen_code.code.begin(); + while (el) { + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; + } + print_line("\n**uniforms:\n" + gen_code.uniforms); - print_line("\n**vertex_globals:\n" + gen_code.vertex_global); - print_line("\n**vertex_code:\n" + gen_code.vertex); - print_line("\n**fragment_globals:\n" + gen_code.fragment_global); - print_line("\n**fragment_code:\n" + gen_code.fragment); - print_line("\n**light_code:\n" + gen_code.light); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif Vector<StringName> texture_uniform_names; @@ -2877,7 +2888,10 @@ void CanvasShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { continue; } if (E.value.texture_order >= 0) { @@ -3070,12 +3084,16 @@ void SkyShaderData::set_code(const String &p_code) { for (int i = 0; i < gen_code.defines.size(); i++) { print_line(gen_code.defines[i]); } + + HashMap<String, String>::Iterator el = gen_code.code.begin(); + while (el) { + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; + } + print_line("\n**uniforms:\n" + gen_code.uniforms); - // print_line("\n**vertex_globals:\n" + gen_code.vertex_global); - // print_line("\n**vertex_code:\n" + gen_code.vertex); - print_line("\n**fragment_globals:\n" + gen_code.fragment_global); - print_line("\n**fragment_code:\n" + gen_code.fragment); - print_line("\n**light_code:\n" + gen_code.light); + print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]); + print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]); #endif Vector<StringName> texture_uniform_names; @@ -3253,7 +3271,6 @@ void SceneShaderData::set_code(const String &p_code) { valid = false; ubo_size = 0; uniforms.clear(); - uses_screen_texture = false; if (code.is_empty()) { return; //just invalid, but no error @@ -3378,6 +3395,7 @@ void SceneShaderData::set_code(const String &p_code) { vertex_input_mask |= uses_custom3 << 8; vertex_input_mask |= uses_bones << 9; vertex_input_mask |= uses_weights << 10; + uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; #if 0 print_line("**compiling shader:"); @@ -3386,11 +3404,10 @@ void SceneShaderData::set_code(const String &p_code) { print_line(gen_code.defines[i]); } - Map<String, String>::Element *el = gen_code.code.front(); + HashMap<String, String>::Iterator el = gen_code.code.begin(); while (el) { - print_line("\n**code " + el->key() + ":\n" + el->value()); - - el = el->next(); + print_line("\n**code " + el->key + ":\n" + el->value); + ++el; } print_line("\n**uniforms:\n" + gen_code.uniforms); @@ -3439,7 +3456,10 @@ void SceneShaderData::get_shader_uniform_list(List<PropertyInfo> *p_param_list) RBMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE || + E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { continue; } diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 2ca47351a4..a2a7554821 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -142,6 +142,7 @@ struct CanvasShaderData : public ShaderData { BLEND_MODE_MUL, BLEND_MODE_PMALPHA, BLEND_MODE_DISABLED, + BLEND_MODE_LCD, }; bool valid; @@ -159,6 +160,7 @@ struct CanvasShaderData : public ShaderData { HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_screen_texture = false; + bool uses_screen_texture_mipmaps = false; bool uses_sdf = false; bool uses_time = false; @@ -312,6 +314,7 @@ struct SceneShaderData : public ShaderData { bool uses_sss; bool uses_transmittance; bool uses_screen_texture; + bool uses_screen_texture_mipmaps; bool uses_depth_texture; bool uses_normal_texture; bool uses_time; diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index 667ba4f5e6..ddf94af5b8 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -124,11 +124,11 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) } break; case RS::ARRAY_NORMAL: { - stride += sizeof(int32_t); + stride += sizeof(uint16_t) * 2; } break; case RS::ARRAY_TANGENT: { - stride += sizeof(int32_t); + stride += sizeof(uint16_t) * 2; } break; case RS::ARRAY_COLOR: { @@ -186,11 +186,13 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) s->format = p_surface.format; s->primitive = p_surface.primitive; - glGenBuffers(1, &s->vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer); - glBufferData(GL_ARRAY_BUFFER, p_surface.vertex_data.size(), p_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind - s->vertex_buffer_size = p_surface.vertex_data.size(); + if (p_surface.vertex_data.size()) { + glGenBuffers(1, &s->vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, p_surface.vertex_data.size(), p_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind + s->vertex_buffer_size = p_surface.vertex_data.size(); + } if (p_surface.attribute_data.size()) { glGenBuffers(1, &s->attribute_buffer); @@ -214,7 +216,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) } if (p_surface.index_count) { - bool is_index_16 = p_surface.vertex_count <= 65536; + bool is_index_16 = p_surface.vertex_count <= 65536 && p_surface.vertex_count > 0; glGenBuffers(1, &s->index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW); @@ -238,6 +240,8 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) } } + ERR_FAIL_COND_MSG(!p_surface.index_count && !p_surface.vertex_count, "Meshes must contain a vertex array, an index array, or both"); + s->aabb = p_surface.aabb; s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them. @@ -255,7 +259,10 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) mesh->bone_aabbs.resize(p_surface.bone_aabbs.size()); } for (int i = 0; i < p_surface.bone_aabbs.size(); i++) { - mesh->bone_aabbs.write[i].merge_with(p_surface.bone_aabbs[i]); + const AABB &bone = p_surface.bone_aabbs[i]; + if (!bone.has_no_volume()) { + mesh->bone_aabbs.write[i].merge_with(bone); + } } mesh->aabb.merge_with(p_surface.aabb); } @@ -337,7 +344,9 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { RS::SurfaceData sd; sd.format = s.format; - sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size); + if (s.vertex_buffer != 0) { + sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size); + } if (s.attribute_buffer != 0) { sd.attribute_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.attribute_buffer, s.attribute_buffer_size); @@ -595,17 +604,16 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V } break; case RS::ARRAY_NORMAL: { attribs[i].offset = vertex_stride; - // Will need to change to accommodate octahedral compression - attribs[i].size = 4; - attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV; - vertex_stride += sizeof(float); + attribs[i].size = 2; + attribs[i].type = GL_UNSIGNED_SHORT; + vertex_stride += sizeof(uint16_t) * 2; attribs[i].normalized = GL_TRUE; } break; case RS::ARRAY_TANGENT: { attribs[i].offset = vertex_stride; - attribs[i].size = 4; - attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV; - vertex_stride += sizeof(float); + attribs[i].size = 2; + attribs[i].type = GL_UNSIGNED_SHORT; + vertex_stride += sizeof(uint16_t) * 2; attribs[i].normalized = GL_TRUE; } break; case RS::ARRAY_COLOR: { diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index 339380b3b0..74f5800795 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -75,7 +75,7 @@ struct Mesh { // Cache vertex arrays so they can be created struct Version { uint32_t input_mask = 0; - GLuint vertex_array; + GLuint vertex_array = 0; Attrib attribs[RS::ARRAY_MAX]; }; @@ -92,7 +92,7 @@ struct Mesh { float edge_length = 0.0; uint32_t index_count = 0; uint32_t index_buffer_size = 0; - GLuint index_buffer; + GLuint index_buffer = 0; }; LOD *lods = nullptr; @@ -175,7 +175,7 @@ struct MultiMesh { bool *data_cache_dirty_regions = nullptr; uint32_t data_cache_used_dirty_regions = 0; - GLuint buffer; + GLuint buffer = 0; bool dirty = false; MultiMesh *dirty_list = nullptr; @@ -362,7 +362,7 @@ public: _FORCE_INLINE_ GLenum mesh_surface_get_index_type(void *p_surface) const { Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface); - return s->vertex_count <= 65536 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; + return (s->vertex_count <= 65536 && s->vertex_count > 0) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; } // Use this to cache Vertex Array Objects so they are only generated once |