diff options
Diffstat (limited to 'drivers')
26 files changed, 1304 insertions, 481 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index b32d540380..4e6739e8c0 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -31,7 +31,7 @@ #ifdef ALSA_ENABLED -#include "global_config.h" +#include "project_settings.h" #include <errno.h> diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 3c543365f0..2abdbe9d0a 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -31,8 +31,8 @@ #include "rasterizer_gles2.h" #include "gl_context/context_gl.h" -#include "global_config.h" #include "os/os.h" +#include "project_settings.h" #include "servers/visual/particle_system_sw.h" #include "servers/visual/shader_language.h" #include <stdio.h> @@ -3941,8 +3941,8 @@ void RasterizerGLES2::begin_frame() { //fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting"); #ifdef TOOLS_ENABLED - canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("display/use_2d_pixel_snap", false)); - shadow_filter = ShadowFilterTechnique(int(GlobalConfig::get_singleton()->get("rasterizer/shadow_filter"))); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/use_2d_pixel_snap", false)); + shadow_filter = ShadowFilterTechnique(int(ProjectSettings::get_singleton()->get("rasterizer/shadow_filter"))); #endif canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF5, shadow_filter == SHADOW_FILTER_PCF5); @@ -4199,7 +4199,7 @@ void RasterizerGLES2::set_camera(const Transform &p_world, const CameraMatrix &p void RasterizerGLES2::add_light(RID p_light_instance) { -#define LIGHT_FADE_TRESHOLD 0.05 +#define LIGHT_FADE_THRESHOLD 0.05 ERR_FAIL_COND(light_instance_count >= MAX_SCENE_LIGHTS); @@ -6481,7 +6481,7 @@ void RasterizerGLES2::_process_glow_bloom() { copy_shader.bind(); copy_shader.set_uniform(CopyShaderGLES2::BLOOM, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM])); - copy_shader.set_uniform(CopyShaderGLES2::BLOOM_TRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD])); + copy_shader.set_uniform(CopyShaderGLES2::BLOOM_THRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_THRESHOLD])); glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0); if (current_vd && current_env->fx_enabled[VS::ENV_FX_HDR]) { @@ -6491,7 +6491,7 @@ void RasterizerGLES2::_process_glow_bloom() { copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE])); copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE])); //copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,1.0); - copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_TRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD])); + copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_THRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_THRESHOLD])); copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_SCALE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE])); glActiveTexture(GL_TEXTURE0); @@ -6819,7 +6819,7 @@ void RasterizerGLES2::end_scene() { if (current_env->bg_mode == VS::ENV_BG_COLOR) bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR]; else - bgcolor = GlobalConfig::get_singleton()->get("render/default_clear_color"); + bgcolor = ProjectSettings::get_singleton()->get("render/default_clear_color"); bgcolor = _convert_color(bgcolor); float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0; glClearColor(bgcolor.r, bgcolor.g, bgcolor.b, a); @@ -10386,7 +10386,7 @@ void RasterizerGLES2::init() { copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR, !use_fp16_fb); canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS, read_depth_supported); - canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("display/use_2d_pixel_snap", false)); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/use_2d_pixel_snap", false)); npo2_textures_available = true; //fragment_lighting=false; @@ -10718,7 +10718,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays, bool p_keep_ram_copy, b fragment_lighting = GLOBAL_DEF("rasterizer/use_fragment_lighting", true); read_depth_supported = true; //todo check for extension shadow_filter = ShadowFilterTechnique((int)(GLOBAL_DEF("rasterizer/shadow_filter", SHADOW_FILTER_PCF5))); - GlobalConfig::get_singleton()->set_custom_property_info("rasterizer/shadow_filter", PropertyInfo(Variant::INT, "rasterizer/shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13,ESM")); + ProjectSettings::get_singleton()->set_custom_property_info("rasterizer/shadow_filter", PropertyInfo(Variant::INT, "rasterizer/shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13,ESM")); use_fp16_fb = bool(GLOBAL_DEF("rasterizer/fp16_framebuffer", true)); use_shadow_mapping = true; use_fast_texture_filter = !bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter", true)); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index e6b76a4e92..e86d3ba298 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -689,14 +689,14 @@ class RasterizerGLES2 : public Rasterizer { fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH] = 1.0; fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE] = 0; fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM] = 0.0; - fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD] = 0.5; + fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_THRESHOLD] = 0.5; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_PASSES] = 1; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_BEGIN] = 100.0; fx_param[VS::ENV_FX_PARAM_DOF_BLUR_RANGE] = 10.0; fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER] = VS::ENV_FX_HDR_TONE_MAPPER_LINEAR; fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE] = 0.4; fx_param[VS::ENV_FX_PARAM_HDR_WHITE] = 1.0; - fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD] = 0.95; + fx_param[VS::ENV_FX_PARAM_HDR_GLOW_THRESHOLD] = 0.95; fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE] = 0.2; fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE] = 0.4; fx_param[VS::ENV_FX_PARAM_HDR_MAX_LUMINANCE] = 8.0; diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index cb42970921..23680ffe91 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -16,6 +16,7 @@ attribute vec2 uv_in; // attrib:4 #endif attribute vec2 uv2_in; // attrib:5 + #ifdef USE_CUBEMAP varying vec3 cube_interp; #else @@ -58,7 +59,9 @@ float sRGB_gamma_correct(float c){ #define LUM_RANGE 4.0 -#ifdef USE_CUBEMAP +#ifdef USE_ARRAY +uniform sampler2DArray source; +#elif defined(USE_CUBEMAP) varying vec3 cube_interp; uniform samplerCube source_cube; #else @@ -84,7 +87,7 @@ uniform sampler2D glow_source; #if defined(USE_HDR) && defined(USE_GLOW_COPY) -uniform highp float hdr_glow_treshold; +uniform highp float hdr_glow_threshold; uniform highp float hdr_glow_scale; #endif @@ -104,7 +107,7 @@ uniform vec3 bcs; #ifdef USE_GLOW_COPY uniform float bloom; -uniform float bloom_treshold; +uniform float bloom_threshold; #endif @@ -145,23 +148,17 @@ uniform float custom_alpha; void main() { //vec4 color = color_interp; -#ifdef USE_HIGHP_SOURCE -#ifdef USE_CUBEMAP + +#ifdef USE_ARRAY + highp vec4 color = textureLod( source, vec3(uv_interp,0.0),0.0 ); +#elif defined(USE_CUBEMAP) highp vec4 color = textureCube( source_cube, normalize(cube_interp) ); #else highp vec4 color = texture2D( source, uv_interp ); #endif -#else - -#ifdef USE_CUBEMAP - vec4 color = textureCube( source_cube, normalize(cube_interp) ); - -#else - vec4 color = texture2D( source, uv_interp ); -#endif #endif @@ -377,11 +374,11 @@ void main() { #ifdef USE_GLOW_COPY - highp vec3 glowcol = color.rgb*color.a+step(bloom_treshold,dot(vec3(0.3333,0.3333,0.3333),color.rgb))*bloom*color.rgb; + highp vec3 glowcol = color.rgb*color.a+step(bloom_threshold,dot(vec3(0.3333,0.3333,0.3333),color.rgb))*bloom*color.rgb; #ifdef USE_HDR highp float collum = max(color.r,max(color.g,color.b)); - glowcol+=color.rgb*max(collum-hdr_glow_treshold,0.0)*hdr_glow_scale; + glowcol+=color.rgb*max(collum-hdr_glow_threshold,0.0)*hdr_glow_scale; #endif color.rgb=glowcol; color.a=0.0; @@ -503,7 +500,7 @@ void main() { //lum_accum=exp(lum_accum); -#ifdef USE_8BIT_HDR +#ifdef USE_8BIT_HDR highp float vd_lum = dot(texture2D( source_vd_lum, vec2(0.0) ), _multcv ); lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance*(1.0/LUM_RANGE),max_luminance*(1.0/LUM_RANGE)); @@ -558,4 +555,3 @@ void main() { #endif } - diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 8c3569bec0..56d9f2cc47 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "rasterizer_canvas_gles3.h" -#include "global_config.h" #include "os/os.h" +#include "project_settings.h" #include "rasterizer_scene_gles3.h" #include "servers/visual/visual_server_raster.h" #ifndef GLES_OVER_GL @@ -348,6 +348,53 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun glBindVertexArray(0); } +void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { + + glBindVertexArray(data.polygon_buffer_pointer_array); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + + uint32_t buffer_ofs = 0; + + //vertex + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices); + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + //color + + if (p_singlecolor) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + Color m = *p_colors; + glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a); + } else if (!p_colors) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + } else { + + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); + glEnableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Color) * p_vertex_count; + } + + if (p_uvs) { + + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + + } else { + glDisableVertexAttribArray(VS::ARRAY_TEX_UV); + } + + glDrawArrays(p_primitive, 0, p_vertex_count); + + storage->frame.canvas_draw_commands++; + + glBindVertexArray(0); +} + void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) { static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN }; @@ -425,22 +472,83 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur glVertexAttrib4f(VS::ARRAY_COLOR, line->color.r, line->color.g, line->color.b, line->color.a); - Vector2 verts[2] = { - Vector2(line->from.x, line->from.y), - Vector2(line->to.x, line->to.y) - }; + if (line->width <= 1) { + Vector2 verts[2] = { + Vector2(line->from.x, line->from.y), + Vector2(line->to.x, line->to.y) + }; #ifdef GLES_OVER_GL - if (line->antialiased) - glEnable(GL_LINE_SMOOTH); + if (line->antialiased) + glEnable(GL_LINE_SMOOTH); #endif - //glLineWidth(line->width); - _draw_gui_primitive(2, verts, NULL, NULL); + //glLineWidth(line->width); + _draw_gui_primitive(2, verts, NULL, NULL); #ifdef GLES_OVER_GL - if (line->antialiased) + if (line->antialiased) + glDisable(GL_LINE_SMOOTH); +#endif + } else { + //thicker line + + Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5; + + Vector2 verts[4] = { + line->from - t, + line->from + t, + line->to + t, + line->to - t, + }; + + //glLineWidth(line->width); + _draw_gui_primitive(4, verts, NULL, NULL); +#ifdef GLES_OVER_GL + if (line->antialiased) { + glEnable(GL_LINE_SMOOTH); + for (int i = 0; i < 4; i++) { + Vector2 vertsl[2] = { + verts[i], + verts[(i + 1) % 4], + }; + _draw_gui_primitive(2, vertsl, NULL, NULL); + } + glDisable(GL_LINE_SMOOTH); + } +#endif + } + + } break; + case Item::Command::TYPE_POLYLINE: { + + Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(c); + _set_texture_rect_mode(false); + + _bind_canvas_texture(RID(), RID()); + + if (pline->triangles.size()) { + + _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1); +#ifdef GLES_OVER_GL + glEnable(GL_LINE_SMOOTH); + if (pline->lines.size()) { + _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + } glDisable(GL_LINE_SMOOTH); #endif + } else { + +#ifdef GLES_OVER_GL + if (pline->antialiased) + glEnable(GL_LINE_SMOOTH); +#endif + _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + +#ifdef GLES_OVER_GL + if (pline->antialiased) + glDisable(GL_LINE_SMOOTH); +#endif + } } break; case Item::Command::TYPE_RECT: { @@ -1550,7 +1658,7 @@ void RasterizerCanvasGLES3::initialize() { } { - uint32_t poly_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_buffer_size_kb", 128); + uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128); poly_size *= 1024; //kb poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float)); glGenBuffers(1, &data.polygon_buffer); @@ -1596,7 +1704,7 @@ void RasterizerCanvasGLES3::initialize() { glGenVertexArrays(1, &data.polygon_buffer_pointer_array); - uint32_t index_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_index_buffer_size_kb", 128); + uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128); index_size *= 1024; //kb glGenBuffers(1, &data.polygon_index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index ee018e15ea..c0af22b5e8 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -121,6 +121,8 @@ public: _FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs); _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); + _FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); + _FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip); _FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 0cfa8a7d6e..bb7b85e653 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -30,8 +30,8 @@ #include "rasterizer_gles3.h" #include "gl_context/context_gl.h" -#include "global_config.h" #include "os/os.h" +#include "project_settings.h" #include <string.h> RasterizerStorage *RasterizerGLES3::get_storage() { @@ -186,6 +186,9 @@ void RasterizerGLES3::initialize() { GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello"); */ + + const GLubyte *renderer = glGetString(GL_RENDERER); + print_line("OpenGL ES 3.0 Renderer: " + String((const char *)renderer)); storage->initialize(); canvas->initialize(); scene->initialize(); @@ -336,6 +339,10 @@ void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target, const Re glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, rt->color); + //glBindTexture(GL_TEXTURE_2D, rt->effects.mip_maps[0].color); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1)); glBindTexture(GL_TEXTURE_2D, 0); canvas->canvas_end(); @@ -400,10 +407,8 @@ void RasterizerGLES3::make_current() { void RasterizerGLES3::register_config() { - GLOBAL_DEF("rendering/gles3/render_architecture", 0); - GlobalConfig::get_singleton()->set_custom_property_info("rendering/gles3/render_architecture", PropertyInfo(Variant::INT, "", PROPERTY_HINT_ENUM, "Desktop,Mobile")); - GLOBAL_DEF("rendering/quality/use_nearest_mipmap_filter", false); - GLOBAL_DEF("rendering/quality/anisotropic_filter_level", 4.0); + GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false); + GLOBAL_DEF("rendering/quality/filters/anisotropic_filter_level", 4.0); } RasterizerGLES3::RasterizerGLES3() { diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 96c3da99f0..cd74c450f5 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "rasterizer_scene_gles3.h" -#include "global_config.h" #include "os/os.h" +#include "project_settings.h" #include "rasterizer_canvas_gles3.h" #ifndef GLES_OVER_GL @@ -521,13 +521,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size glBindTexture(GL_TEXTURE_2D, reflection_atlas->color); int mmsize = reflection_atlas->size; - - for (int i = 0; i < 6; i++) { - glTexImage2D(GL_TEXTURE_2D, i, internal_format, mmsize, mmsize, 0, - format, type, NULL); - - mmsize >>= 1; - } + glTexStorage2DCustom(GL_TEXTURE_2D, 6, internal_format, mmsize, mmsize, format, type); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -537,8 +531,6 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5); - mmsize = reflection_atlas->size; - for (int i = 0; i < 6; i++) { glGenFramebuffers(1, &reflection_atlas->fbo[i]); glBindFramebuffer(GL_FRAMEBUFFER, reflection_atlas->fbo[i]); @@ -761,7 +753,7 @@ bool RasterizerSceneGLES3::reflection_probe_instance_postprocess_step(RID p_inst storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, rpi->probe_ptr->update_mode == VS::REFLECTION_PROBE_UPDATE_ALWAYS); for (int i = 0; i < 2; i++) { - storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0); + storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i == 0); storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, rpi->render_step / 5.0); uint32_t local_width = width, local_height = height; @@ -869,7 +861,7 @@ void RasterizerSceneGLES3::environment_set_dof_blur_near(RID p_env, bool p_enabl env->dof_blur_near_amount = p_amount; env->dof_blur_near_quality = p_quality; } -void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) { +void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -878,9 +870,9 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_ env->glow_levels = p_level_flags; env->glow_intensity = p_intensity; env->glow_strength = p_strength; - env->glow_bloom = p_bloom_treshold; + env->glow_bloom = p_bloom_threshold; env->glow_blend_mode = p_blend_mode; - env->glow_hdr_bleed_treshold = p_hdr_bleed_treshold; + env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold; env->glow_hdr_bleed_scale = p_hdr_bleed_scale; env->glow_bicubic_upscale = p_bicubic_upscale; } @@ -1251,36 +1243,36 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m if (t->render_target) t->render_target->used_in_frame = true; - if (storage->config.srgb_decode_supported) { - //if SRGB decode extension is present, simply switch the texture to whathever is needed - bool must_srgb = false; + target = t->target; + tex = t->tex_id; + } + + glBindTexture(target, tex); - if (t->srgb && (texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO)) { - must_srgb = true; - } + if (t && storage->config.srgb_decode_supported) { + //if SRGB decode extension is present, simply switch the texture to whathever is needed + bool must_srgb = false; + + if (t->srgb && (texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO)) { + must_srgb = true; + } - if (t->using_srgb != must_srgb) { - if (must_srgb) { - glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _DECODE_EXT); + if (t->using_srgb != must_srgb) { + if (must_srgb) { + glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _DECODE_EXT); #ifdef TOOLS_ENABLED - if (t->detect_srgb) { - t->detect_srgb(t->detect_srgb_ud); - } + if (t->detect_srgb) { + t->detect_srgb(t->detect_srgb_ud); + } #endif - } else { - glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _SKIP_DECODE_EXT); - } - t->using_srgb = must_srgb; + } else { + glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _SKIP_DECODE_EXT); } + t->using_srgb = must_srgb; } - - target = t->target; - tex = t->tex_id; } - glBindTexture(target, tex); - if (i == 0) { state.current_main_tex = tex; } @@ -1834,12 +1826,14 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]); + float bias_scale = e->instance->baked_light ? 1 : 0; glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9); glBindTexture(GL_TEXTURE_3D, gipi->tex_cache); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_MULTIPLIER1, gipi->probe ? gipi->probe->dynamic_range * gipi->probe->energy : 0.0); - state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS1, gipi->probe ? gipi->probe->bias : 0.0); + state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS1, gipi->probe ? gipi->probe->bias * bias_scale : 0.0); + state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_NORMAL_BIAS1, gipi->probe ? gipi->probe->normal_bias * bias_scale : 0.0); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BLEND_AMBIENT1, gipi->probe ? !gipi->probe->interior : false); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE1, gipi->cell_size_cache); if (gi_probe_count > 1) { @@ -1852,7 +1846,8 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE2, gipi2->cell_size_cache); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_MULTIPLIER2, gipi2->probe ? gipi2->probe->dynamic_range * gipi2->probe->energy : 0.0); - state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS2, gipi2->probe ? gipi2->probe->bias : 0.0); + state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS2, gipi2->probe ? gipi2->probe->bias * bias_scale : 0.0); + state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_NORMAL_BIAS2, gipi2->probe ? gipi2->probe->normal_bias * bias_scale : 0.0); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BLEND_AMBIENT2, gipi2->probe ? !gipi2->probe->interior : false); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, true); } else { @@ -1879,19 +1874,29 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.scene_ubo); //bind globals ubo + bool use_radiance_map = false; if (!p_shadow && !p_directional_add) { glBindBufferBase(GL_UNIFORM_BUFFER, 2, state.env_radiance_ubo); //bind environment radiance info if (p_base_env) { glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2); - glBindTexture(GL_TEXTURE_2D, p_base_env); + if (storage->config.use_texture_array_environment) { + glBindTexture(GL_TEXTURE_2D_ARRAY, p_base_env); + } else { + glBindTexture(GL_TEXTURE_2D, p_base_env); + } + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, true); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, storage->config.use_texture_array_environment); + use_radiance_map = true; } else { state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, false); } } else { state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, false); } state.cull_front = false; @@ -1949,6 +1954,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, true); state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, false); @@ -1958,6 +1964,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false); //state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true); } else { @@ -1965,7 +1973,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, e->instance->gi_probe_instances.size() > 0); state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING, !p_directional_add); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, (e->sort_key & SORT_KEY_VERTEX_LIT_FLAG)); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, false); @@ -1973,6 +1984,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, use_radiance_map); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, state.used_contact_shadows); if (p_directional_add || (directional_light && (e->sort_key & SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) { state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, true); @@ -2121,6 +2134,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, false); } void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow) { @@ -2155,7 +2170,19 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo ERR_FAIL_COND(!m); - bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture); + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + + while (m->next_pass.is_valid()) { + m = storage->material_owner.getornull(m->next_pass); + if (!m) + break; + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + } +} + +void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) { + + bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded); bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop; bool has_alpha = has_base_alpha || has_blend_alpha; bool shadow = false; @@ -2254,6 +2281,11 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo e->sort_key |= SORT_KEY_UNSHADED_FLAG; } + + if (!shadow && (m->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { + + e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG; + } } void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy) { @@ -2865,7 +2897,7 @@ void RasterizerSceneGLES3::_setup_reflections(RID *p_reflection_probe_cull_resul reflection_ubo.atlas_clamp[0] = float(x) / reflection_atlas->size; reflection_ubo.atlas_clamp[1] = float(y) / reflection_atlas->size; reflection_ubo.atlas_clamp[2] = float(width) / reflection_atlas->size; - reflection_ubo.atlas_clamp[3] = float(height / 2) / reflection_atlas->size; + reflection_ubo.atlas_clamp[3] = float(height) / reflection_atlas->size; Transform proj = (p_camera_inverse_transform * rpi->transform).inverse(); store_transform(proj, reflection_ubo.local_matrix); @@ -2885,7 +2917,19 @@ void RasterizerSceneGLES3::_setup_reflections(RID *p_reflection_probe_cull_resul glBindBufferBase(GL_UNIFORM_BUFFER, 6, state.reflection_array_ubo); } -void RasterizerSceneGLES3::_copy_screen() { +void RasterizerSceneGLES3::_copy_screen(bool p_invalidate_color, bool p_invalidate_depth) { + +#ifndef GLES_OVER_GL + if (p_invalidate_color) { + + GLenum attachments[2] = { + GL_COLOR_ATTACHMENT0, + GL_DEPTH_STENCIL_ATTACHMENT + }; + + glInvalidateFramebuffer(GL_FRAMEBUFFER, p_invalidate_depth ? 2 : 1, attachments); + } +#endif glBindVertexArray(storage->resources.quadie_array); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -3053,7 +3097,7 @@ void RasterizerSceneGLES3::_blur_effect_buffer() { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo); - _copy_screen(); + _copy_screen(true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, false); //vertical pass @@ -3064,7 +3108,7 @@ void RasterizerSceneGLES3::_blur_effect_buffer() { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[1].color); glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[i + 1].fbo); //next level, since mipmaps[0] starts one level bigger - _copy_screen(); + _copy_screen(true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, false); } } @@ -3112,7 +3156,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.depth_mipmap_fbos[i]); //copy to front first glViewport(0, 0, ss[0], ss[1]); - _copy_screen(); + _copy_screen(true); } ss[0] = storage->frame.current_rt->width; ss[1] = storage->frame.current_rt->height; @@ -3164,7 +3208,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ Color white(1, 1, 1, 1); glClearBufferfv(GL_COLOR, 0, white.components); // specular - _copy_screen(); + _copy_screen(true); //do the batm, i mean blur @@ -3185,7 +3229,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ if (i == 0) { glClearBufferfv(GL_COLOR, 0, white.components); // specular } - _copy_screen(); + _copy_screen(true); } } @@ -3202,7 +3246,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[0]); //previous level, since mipmaps[0] starts one level bigger glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level - _copy_screen(); + _copy_screen(true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SSAO_MERGE, false); } else { @@ -3251,14 +3295,14 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //copy to front first - _copy_screen(); + _copy_screen(true); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color); state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR, Vector2(0, 1)); glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level - _copy_screen(); + _copy_screen(true); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //restore filter glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -3310,7 +3354,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[0].fbo); glViewport(0, 0, ssr_w, ssr_h); - _copy_screen(); + _copy_screen(true); glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); } @@ -3341,7 +3385,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); //use additive to accumulate one over the other - _copy_screen(); + _copy_screen(true); glDisable(GL_BLEND); //end additive @@ -3365,7 +3409,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); - _copy_screen(); + _copy_screen(true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY, false); } @@ -3386,13 +3430,16 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p //copy specular to front buffer //copy diffuse to effect buffer - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); - glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + if (storage->frame.current_rt->buffers.active) { + //transfer to effect buffer if using buffers, also resolve MSAA + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); + glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { //no environment or transparent render, simply return and convert to SRGB @@ -3404,7 +3451,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]); storage->shaders.copy.bind(); - _copy_screen(); + _copy_screen(true); storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, false); storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); //compute luminance @@ -3460,7 +3507,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //copy to front first - _copy_screen(); + _copy_screen(true); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color); @@ -3469,7 +3516,6 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p _copy_screen(); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR, false); - state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH, false); @@ -3547,7 +3593,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.diffuse); } - _copy_screen(); + _copy_screen(true); if (composite_from != storage->frame.current_rt->buffers.diffuse) { @@ -3564,6 +3610,16 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p composite_from = storage->frame.current_rt->effects.mip_maps[0].color; } + if (env->dof_blur_near_enabled || env->dof_blur_far_enabled) { + //these needed to disable filtering, reenamble + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + if (env->auto_exposure) { //compute auto exposure @@ -3587,7 +3643,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p glBindFramebuffer(GL_FRAMEBUFFER, exposure_shrink[0].fbo); glViewport(0, 0, exposure_shrink_size, exposure_shrink_size); - _copy_screen(); + _copy_screen(true); //second step, shrink to 2x2 pixels state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_BEGIN, false); @@ -3631,7 +3687,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.exposure_shader.set_uniform(ExposureShaderGLES3::MAX_LUMINANCE, env->auto_exposure_max); state.exposure_shader.set_uniform(ExposureShaderGLES3::MIN_LUMINANCE, env->auto_exposure_min); - _copy_screen(); + _copy_screen(true); state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_FORCE_SET, false); state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_END, false); @@ -3695,14 +3751,14 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->exposure.color); state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_BLOOM, env->glow_bloom); - state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_TRESHOLD, env->glow_hdr_bleed_treshold); + state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_THRESHOLD, env->glow_hdr_bleed_threshold); state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::GLOW_HDR_SCALE, env->glow_hdr_bleed_scale); } else { glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger } glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo); - _copy_screen(); + _copy_screen(true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_GAUSSIAN_HORIZONTAL, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_FIRST_PASS, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GLOW_USE_AUTO_EXPOSURE, false); @@ -3810,7 +3866,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.tonemap_shader.set_uniform(TonemapShaderGLES3::BCS, Vector3(env->adjustments_brightness, env->adjustments_contrast, env->adjustments_saturation)); } - _copy_screen(); + _copy_screen(true, true); //turn off everything used state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, false); @@ -3886,7 +3942,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const state.used_contact_shadows = true; - if (storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { //detect with state.used_contact_shadows too + if (!storage->config.no_depth_prepass && storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { //detect with state.used_contact_shadows too //pre z pass glDisable(GL_BLEND); @@ -3900,7 +3956,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glColorMask(0, 0, 0, 0); glClearDepth(1.0f); - glClear(GL_DEPTH_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); render_list.clear(); _fill_render_list(p_cull_result, p_cull_count, true); @@ -3926,6 +3982,9 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const fb_cleared = true; render_pass++; + state.using_contact_shadows = true; + } else { + state.using_contact_shadows = false; } _setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_cam_projection, p_shadow_atlas); @@ -3973,7 +4032,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const } else { - use_mrt = env && (state.used_screen_texture || state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled + use_mrt = env && (state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled //effects disabled and transparency also prevent using MRTs use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]; use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS]; @@ -4007,8 +4066,13 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const } else { - current_fbo = storage->frame.current_rt->buffers.fbo; - glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); + if (storage->frame.current_rt->buffers.active) { + current_fbo = storage->frame.current_rt->buffers.fbo; + } else { + current_fbo = storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo; + } + + glBindFramebuffer(GL_FRAMEBUFFER, current_fbo); state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS, false); Vector<GLenum> draw_buffers; @@ -4018,8 +4082,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const } if (!fb_cleared) { - glClearDepth(1.0f); - glClear(GL_DEPTH_BUFFER_BIT); + glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0, 0); } Color clear_color(0, 0, 0, 0); @@ -4084,7 +4147,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const storage->shaders.copy.bind(); - _copy_screen(); + _copy_screen(true, true); //turn off everything used storage->shaders.copy.set_conditional(CopyShaderGLES3::SRGB_TO_LINEAR, false); @@ -4132,7 +4195,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glDrawBuffers(1, &gldb); } - if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { + if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || (!storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW))) { /* if (use_mrt) { @@ -4149,9 +4212,23 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const if (use_mrt) { _render_mrts(env, p_cam_projection); + } else { + //FIXME: check that this is possible to use + if (storage->frame.current_rt && storage->frame.current_rt->buffers.active && state.used_screen_texture) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); + glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + _blur_effect_buffer(); + //restored framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo); + glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); + } } - if (state.used_screen_texture) { + if (storage->frame.current_rt && state.used_screen_texture && storage->frame.current_rt->buffers.active) { glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); } @@ -4161,7 +4238,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glEnable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); - render_list.sort_by_depth(true); + render_list.sort_by_reverse_depth(true); if (state.directional_light_count == 0) { directional_light = NULL; @@ -4226,8 +4303,14 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const storage->canvas->canvas_begin(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, env_radiance_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } + + //disable all stuff } void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { @@ -4252,6 +4335,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_ float bias = 0; float normal_bias = 0; + state.using_contact_shadows = false; + CameraMatrix light_projection; Transform light_transform; @@ -4593,7 +4678,7 @@ void RasterizerSceneGLES3::initialize() { glBufferData(GL_UNIFORM_BUFFER, sizeof(State::EnvironmentRadianceUBO), &state.env_radiance_ubo, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); - render_list.max_elements = GLOBAL_DEF("rendering/gles3/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS); + render_list.max_elements = GLOBAL_DEF("rendering/limits/rendering/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS); if (render_list.max_elements > 1000000) render_list.max_elements = 1000000; if (render_list.max_elements < 1024) @@ -4667,7 +4752,7 @@ void RasterizerSceneGLES3::initialize() { { //directional light shadow directional_shadow.light_count = 0; - directional_shadow.size = nearest_power_of_2(GLOBAL_DEF("rendering/shadows/directional_shadow_size", 4096)); + directional_shadow.size = nearest_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size")); glGenFramebuffers(1, &directional_shadow.fbo); glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo); glGenTextures(1, &directional_shadow.depth); @@ -4734,8 +4819,6 @@ void RasterizerSceneGLES3::initialize() { state.scene_shader.add_custom_define("#define MAX_SKELETON_BONES " + itos(state.max_skeleton_bones) + "\n"); } - GLOBAL_DEF("rendering/gles3/shadow_filter_mode", 1); - GlobalConfig::get_singleton()->set_custom_property_info("rendering/gles3/shadow_filter_mode", PropertyInfo(Variant::INT, "rendering/gles3/shadow_filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13")); shadow_filter_mode = SHADOW_FILTER_NEAREST; { //reflection cubemaps @@ -4799,7 +4882,7 @@ void RasterizerSceneGLES3::initialize() { { - uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/buffers/immediate_buffer_size_kb", 2048); + uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/limits/buffers/immediate_buffer_size_kb", 2048); glGenBuffers(1, &state.immediate_buffer); glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer); @@ -4826,13 +4909,13 @@ void RasterizerSceneGLES3::initialize() { state.tonemap_shader.init(); { - GLOBAL_DEF("rendering/ssurf_scattering/quality", 1); - GlobalConfig::get_singleton()->set_custom_property_info("rendering/ssurf_scattering/quality", PropertyInfo(Variant::INT, "rendering/ssurf_scattering/quality", PROPERTY_HINT_ENUM, "Low,Medium,High")); - GLOBAL_DEF("rendering/ssurf_scattering/max_size", 1.0); - GlobalConfig::get_singleton()->set_custom_property_info("rendering/ssurf_scattering/max_size", PropertyInfo(Variant::INT, "rendering/ssurf_scattering/max_size", PROPERTY_HINT_RANGE, "0.01,8,0.01")); - GLOBAL_DEF("rendering/ssurf_scattering/follow_surface", false); + GLOBAL_DEF("rendering/quality/subsurface_scattering/quality", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/quality", PROPERTY_HINT_ENUM, "Low,Medium,High")); + GLOBAL_DEF("rendering/quality/subsurface_scattering/scale", 1.0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/scale", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/scale", PROPERTY_HINT_RANGE, "0.01,8,0.01")); + GLOBAL_DEF("rendering/quality/subsurface_scattering/follow_surface", false); - GLOBAL_DEF("rendering/reflections/high_quality_vct_gi", true); + GLOBAL_DEF("rendering/quality/voxel_cone_tracing/high_quality", true); } exposure_shrink_size = 243; @@ -4871,12 +4954,12 @@ void RasterizerSceneGLES3::initialize() { void RasterizerSceneGLES3::iteration() { - shadow_filter_mode = ShadowFilterMode(int(GlobalConfig::get_singleton()->get("rendering/gles3/shadow_filter_mode"))); - subsurface_scatter_follow_surface = GlobalConfig::get_singleton()->get("rendering/ssurf_scattering/follow_surface"); - subsurface_scatter_quality = SubSurfaceScatterQuality(int(GlobalConfig::get_singleton()->get("rendering/ssurf_scattering/quality"))); - subsurface_scatter_size = GlobalConfig::get_singleton()->get("rendering/ssurf_scattering/max_size"); + shadow_filter_mode = ShadowFilterMode(int(ProjectSettings::get_singleton()->get("rendering/quality/shadows/filter_mode"))); + subsurface_scatter_follow_surface = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/follow_surface"); + subsurface_scatter_quality = SubSurfaceScatterQuality(int(ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/quality"))); + subsurface_scatter_size = ProjectSettings::get_singleton()->get("rendering/quality/subsurface_scattering/scale"); - state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GlobalConfig::get_singleton()->get("rendering/reflections/high_quality_vct_gi")); + state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, ProjectSettings::get_singleton()->get("rendering/quality/voxel_cone_tracing/high_quality")); } void RasterizerSceneGLES3::finalize() { diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 5f0db446a9..f6509e0041 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -187,6 +187,7 @@ public: bool cull_front; bool used_sss; bool used_screen_texture; + bool using_contact_shadows; VS::ViewportDebugDraw debug_draw; } state; @@ -381,7 +382,7 @@ public: float glow_strength; float glow_bloom; VS::EnvironmentGlowBlendMode glow_blend_mode; - float glow_hdr_bleed_treshold; + float glow_hdr_bleed_threshold; float glow_hdr_bleed_scale; bool glow_bicubic_upscale; @@ -467,7 +468,7 @@ public: glow_strength = 1.0; glow_bloom = 0.0; glow_blend_mode = VS::GLOW_BLEND_MODE_SOFTLIGHT; - glow_hdr_bleed_treshold = 1.0; + glow_hdr_bleed_threshold = 1.0; glow_hdr_bleed_scale = 2.0; glow_bicubic_upscale = false; @@ -522,7 +523,7 @@ public: virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality); virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality); - virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale); + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale); virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); @@ -645,8 +646,9 @@ public: #define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 59) #define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 58) #define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 57) - SORT_KEY_SHADING_SHIFT = 57, - SORT_KEY_SHADING_MASK = 7, +#define SORT_KEY_VERTEX_LIT_FLAG (uint64_t(1) << 56) + SORT_KEY_SHADING_SHIFT = 56, + SORT_KEY_SHADING_MASK = 15, SORT_KEY_MATERIAL_INDEX_SHIFT = 40, SORT_KEY_GEOMETRY_INDEX_SHIFT = 20, SORT_KEY_GEOMETRY_TYPE_SHIFT = 15, @@ -666,7 +668,7 @@ public: uint64_t sort_key; }; - Element *_elements; + Element *base_elements; Element **elements; int element_count; @@ -700,11 +702,11 @@ public: struct SortByDepth { _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - return A->instance->depth > B->instance->depth; + return A->instance->depth < B->instance->depth; } }; - void sort_by_depth(bool p_alpha) { + void sort_by_depth(bool p_alpha) { //used for shadows SortArray<Element *, SortByDepth> sorter; if (p_alpha) { @@ -714,11 +716,28 @@ public: } } + struct SortByReverseDepth { + + _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { + return A->instance->depth > B->instance->depth; + } + }; + + void sort_by_reverse_depth(bool p_alpha) { //used for alpha + + SortArray<Element *, SortByReverseDepth> sorter; + if (p_alpha) { + sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); + } else { + sorter.sort(elements, element_count); + } + } + _FORCE_INLINE_ Element *add_element() { if (element_count + alpha_element_count >= max_elements) return NULL; - elements[element_count] = &_elements[element_count]; + elements[element_count] = &base_elements[element_count]; return elements[element_count++]; } @@ -727,7 +746,7 @@ public: if (element_count + alpha_element_count >= max_elements) return NULL; int idx = max_elements - alpha_element_count - 1; - elements[idx] = &_elements[idx]; + elements[idx] = &base_elements[idx]; alpha_element_count++; return elements[idx]; } @@ -737,9 +756,9 @@ public: element_count = 0; alpha_element_count = 0; elements = memnew_arr(Element *, max_elements); - _elements = memnew_arr(Element, max_elements); + base_elements = memnew_arr(Element, max_elements); for (int i = 0; i < max_elements; i++) - elements[i] = &_elements[i]; // assign elements + elements[i] = &base_elements[i]; // assign elements } RenderList() { @@ -749,7 +768,7 @@ public: ~RenderList() { memdelete_arr(elements); - memdelete_arr(_elements); + memdelete_arr(base_elements); } }; @@ -769,6 +788,8 @@ public: _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow); + _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow); + void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy); void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform); @@ -776,7 +797,7 @@ public: void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix &p_camera_projection, RID p_shadow_atlas); void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix &p_camera_projection, RID p_reflection_atlas, Environment *p_env); - void _copy_screen(); + void _copy_screen(bool p_invalidate_color = false, bool p_invalidate_depth = false); void _copy_to_front_buffer(Environment *env); void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index b1dc32e1c0..89bea1e8cc 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "rasterizer_storage_gles3.h" -#include "global_config.h" +#include "project_settings.h" #include "rasterizer_canvas_gles3.h" #include "rasterizer_scene_gles3.h" @@ -99,6 +99,21 @@ #define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E #define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) { + +#ifdef GLES_OVER_GL + + for (int i = 0; i < levels; i++) { + glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL); + width = MAX(1, (width / 2)); + height = MAX(1, (height / 2)); + } + +#else + glTexStorage2D(target, levels, internalformat, width, height); +#endif +} + GLuint RasterizerStorageGLES3::system_fbo = 0; Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) { @@ -1260,6 +1275,10 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //need this for proper sampling if (config.srgb_decode_supported && texture->srgb && !texture->using_srgb) { @@ -1275,87 +1294,192 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra glActiveTexture(GL_TEXTURE1); glGenTextures(1, &sky->radiance); - glBindTexture(GL_TEXTURE_2D, sky->radiance); - GLuint tmp_fb; + if (config.use_texture_array_environment) { - glGenFramebuffers(1, &tmp_fb); - glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb); + //texture3D + glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance); - int size = p_radiance_size; + GLuint tmp_fb; - int lod = 0; + glGenFramebuffers(1, &tmp_fb); + glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb); - int mipmaps = 6; + int size = p_radiance_size; - int mm_level = mipmaps; + int array_level = 6; - bool use_float = config.hdr_supported; + bool use_float = config.hdr_supported; - GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2; - GLenum format = GL_RGBA; - GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV; + GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2; + GLenum format = GL_RGBA; + GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV; - while (mm_level) { + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internal_format, size, size * 2, array_level, 0, format, type, NULL); - glTexImage2D(GL_TEXTURE_2D, lod, internal_format, size, size * 2, 0, format, type, NULL); - lod++; - mm_level--; + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - if (size > 1) - size >>= 1; - } + GLuint tmp_fb2; + GLuint tmp_tex; + { + //generate another one for rendering, as can't read and write from a single texarray it seems + glGenFramebuffers(1, &tmp_fb2); + glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2); + glGenTextures(1, &tmp_tex); + glBindTexture(GL_TEXTURE_2D, tmp_tex); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size * 2, 0, format, type, NULL); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0); + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +#ifdef DEBUG_ENABLED + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); +#endif + } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1); + for (int j = 0; j < array_level; j++) { - lod = 0; - mm_level = mipmaps; + glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2); - size = p_radiance_size; + if (j == 0) { - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_PANORAMA, true); - shaders.cubemap_filter.bind(); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, true); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, false); + shaders.cubemap_filter.bind(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(texture->target, texture->tex_id); + } else { - while (mm_level) { + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, true); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false); + shaders.cubemap_filter.bind(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance); + shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_ARRAY_INDEX, j - 1); //read from previous to ensure better blur + } + + for (int i = 0; i < 2; i++) { + glViewport(0, i * size, size, size); + glBindVertexArray(resources.quadie_array); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->radiance, lod); + shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0); + shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, j / float(array_level - 1)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindVertexArray(0); + } + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tmp_fb); + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, sky->radiance, 0, j); + glBindFramebuffer(GL_READ_FRAMEBUFFER, tmp_fb2); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBlitFramebuffer(0, 0, size, size * 2, 0, 0, size, size * 2, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, false); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false); + + //restore ranges + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance); + + glGenerateMipmap(GL_TEXTURE_2D_ARRAY); + + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); + glDeleteFramebuffers(1, &tmp_fb); + glDeleteFramebuffers(1, &tmp_fb2); + glDeleteTextures(1, &tmp_tex); + + } else { + //regular single texture with mipmaps + glBindTexture(GL_TEXTURE_2D, sky->radiance); + + GLuint tmp_fb; + + glGenFramebuffers(1, &tmp_fb); + glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb); + + int size = p_radiance_size; + + int lod = 0; + + int mipmaps = 6; + + int mm_level = mipmaps; + + bool use_float = config.hdr_supported; + + GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2; + GLenum format = GL_RGBA; + GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV; + + glTexStorage2DCustom(GL_TEXTURE_2D, mipmaps, internal_format, size, size * 2.0, format, type); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmaps - 1); + + lod = 0; + mm_level = mipmaps; + + size = p_radiance_size; + + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true); + shaders.cubemap_filter.bind(); + + while (mm_level) { + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->radiance, lod); #ifdef DEBUG_ENABLED - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE); #endif - for (int i = 0; i < 2; i++) { - glViewport(0, i * size, size, size); - glBindVertexArray(resources.quadie_array); + for (int i = 0; i < 2; i++) { + glViewport(0, i * size, size, size); + glBindVertexArray(resources.quadie_array); - shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0); - shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, lod / float(mipmaps - 1)); + shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0); + shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, lod / float(mipmaps - 1)); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glBindVertexArray(0); - } + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindVertexArray(0); + } - if (size > 1) - size >>= 1; - lod++; - mm_level--; - } - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false); - shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_PANORAMA, false); + if (size > 1) + size >>= 1; + lod++; + mm_level--; + } + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false); - //restore ranges - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1); + //restore ranges + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); - glDeleteFramebuffers(1, &tmp_fb); + glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); + glDeleteFramebuffers(1, &tmp_fb); + } } /* SHADER API */ @@ -1476,6 +1600,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->spatial.unshaded = false; p_shader->spatial.ontop = false; p_shader->spatial.uses_sss = false; + p_shader->spatial.uses_vertex_lighting = false; p_shader->spatial.uses_screen_texture = false; p_shader->spatial.uses_vertex = false; p_shader->spatial.writes_modelview_or_projection = false; @@ -1497,6 +1622,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { shaders.actions_scene.render_mode_flags["unshaded"] = &p_shader->spatial.unshaded; shaders.actions_scene.render_mode_flags["ontop"] = &p_shader->spatial.ontop; + shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting; + shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha; shaders.actions_scene.usage_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex; @@ -1753,6 +1880,14 @@ void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_wid material->line_width = p_width; } +void RasterizerStorageGLES3::material_set_next_pass(RID p_material, RID p_next_material) { + + Material *material = material_owner.get(p_material); + ERR_FAIL_COND(!material); + + material->next_pass = p_next_material; +} + bool RasterizerStorageGLES3::material_is_animated(RID p_material) { Material *material = material_owner.get(p_material); @@ -1761,7 +1896,11 @@ bool RasterizerStorageGLES3::material_is_animated(RID p_material) { _update_material(material); } - return material->is_animated_cache; + bool animated = material->is_animated_cache; + if (!animated && material->next_pass.is_valid()) { + animated = material_is_animated(material->next_pass); + } + return animated; } bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) { @@ -1771,7 +1910,13 @@ bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) { _update_material(material); } - return material->can_cast_shadow_cache; + bool casts_shadows = material->can_cast_shadow_cache; + + if (!casts_shadows && material->next_pass.is_valid()) { + casts_shadows = material_casts_shadows(material->next_pass); + } + + return casts_shadows; } void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) { @@ -4731,6 +4876,7 @@ RID RasterizerStorageGLES3::gi_probe_create() { gip->energy = 1.0; gip->propagation = 1.0; gip->bias = 0.4; + gip->normal_bias = 0.4; gip->interior = false; gip->compress = false; gip->version = 1; @@ -4837,6 +4983,14 @@ void RasterizerStorageGLES3::gi_probe_set_bias(RID p_probe, float p_range) { gip->bias = p_range; } +void RasterizerStorageGLES3::gi_probe_set_normal_bias(RID p_probe, float p_range) { + + GIProbe *gip = gi_probe_owner.getornull(p_probe); + ERR_FAIL_COND(!gip); + + gip->normal_bias = p_range; +} + void RasterizerStorageGLES3::gi_probe_set_propagation(RID p_probe, float p_range) { GIProbe *gip = gi_probe_owner.getornull(p_probe); @@ -4892,6 +5046,14 @@ float RasterizerStorageGLES3::gi_probe_get_bias(RID p_probe) const { return gip->bias; } +float RasterizerStorageGLES3::gi_probe_get_normal_bias(RID p_probe) const { + + const GIProbe *gip = gi_probe_owner.getornull(p_probe); + ERR_FAIL_COND_V(!gip, 0); + + return gip->normal_bias; +} + float RasterizerStorageGLES3::gi_probe_get_propagation(RID p_probe) const { const GIProbe *gip = gi_probe_owner.getornull(p_probe); @@ -5666,17 +5828,20 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) { rt->fbo = 0; } - if (rt->buffers.fbo) { + if (rt->buffers.active) { glDeleteFramebuffers(1, &rt->buffers.fbo); glDeleteRenderbuffers(1, &rt->buffers.depth); glDeleteRenderbuffers(1, &rt->buffers.diffuse); - glDeleteRenderbuffers(1, &rt->buffers.specular); - glDeleteRenderbuffers(1, &rt->buffers.normal_rough); - glDeleteRenderbuffers(1, &rt->buffers.sss); - glDeleteFramebuffers(1, &rt->buffers.effect_fbo); - glDeleteTextures(1, &rt->buffers.effect); + if (rt->buffers.effects_active) { + glDeleteRenderbuffers(1, &rt->buffers.specular); + glDeleteRenderbuffers(1, &rt->buffers.normal_rough); + glDeleteRenderbuffers(1, &rt->buffers.sss); + glDeleteFramebuffers(1, &rt->buffers.effect_fbo); + glDeleteTextures(1, &rt->buffers.effect); + } - rt->buffers.fbo = 0; + rt->buffers.effects_active = false; + rt->buffers.active = false; } if (rt->depth) { @@ -5714,13 +5879,15 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) { tex->active = false; for (int i = 0; i < 2; i++) { - for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) { - glDeleteFramebuffers(1, &rt->effects.mip_maps[i].sizes[j].fbo); - } + if (rt->effects.mip_maps[i].color) { + for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) { + glDeleteFramebuffers(1, &rt->effects.mip_maps[i].sizes[j].fbo); + } - glDeleteTextures(1, &rt->effects.mip_maps[i].color); - rt->effects.mip_maps[i].sizes.clear(); - rt->effects.mip_maps[i].levels = 0; + glDeleteTextures(1, &rt->effects.mip_maps[i].color); + rt->effects.mip_maps[i].sizes.clear(); + rt->effects.mip_maps[i].levels = 0; + } } /* @@ -5747,10 +5914,20 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { if (!hdr || rt->flags[RENDER_TARGET_NO_3D]) { - color_internal_format = GL_RGBA8; - color_format = GL_RGBA; - color_type = GL_UNSIGNED_BYTE; - image_format = Image::FORMAT_RGBA8; + if (rt->flags[RENDER_TARGET_NO_3D_EFFECTS] && !rt->flags[RENDER_TARGET_TRANSPARENT]) { + //if this is not used, linear colorspace looks pretty bad + //this is the default mode used for mobile + color_internal_format = GL_RGB10_A2; + color_format = GL_RGBA; + color_type = GL_UNSIGNED_INT_2_10_10_10_REV; + image_format = Image::FORMAT_RGBA8; + } else { + + color_internal_format = GL_RGBA8; + color_format = GL_RGBA; + color_type = GL_UNSIGNED_BYTE; + image_format = Image::FORMAT_RGBA8; + } } else { color_internal_format = GL_RGBA16F; color_format = GL_RGBA; @@ -5815,11 +5992,20 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { /* BACK FBO */ - if (!rt->flags[RENDER_TARGET_NO_3D]) { + if (!rt->flags[RENDER_TARGET_NO_3D] && (!rt->flags[RENDER_TARGET_NO_3D_EFFECTS] || rt->msaa != VS::VIEWPORT_MSAA_DISABLED)) { + + rt->buffers.active = true; static const int msaa_value[] = { 0, 2, 4, 8, 16 }; int msaa = msaa_value[rt->msaa]; + int max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (msaa > max_samples) { + WARN_PRINTS("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples)); + msaa = max_samples; + } + //regular fbo glGenFramebuffers(1, &rt->buffers.fbo); glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.fbo); @@ -5845,6 +6031,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { if (!rt->flags[RENDER_TARGET_NO_3D_EFFECTS]) { + rt->buffers.effects_active = true; glGenRenderbuffers(1, &rt->buffers.specular); glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.specular); @@ -5902,15 +6089,11 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.effect, 0); - if (status != GL_FRAMEBUFFER_COMPLETE) { - printf("err status: %x\n", status); - _render_target_clear(rt); - ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); - } - + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); if (status != GL_FRAMEBUFFER_COMPLETE) { + printf("err status: %x\n", status); _render_target_clear(rt); ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); } @@ -5988,7 +6171,12 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { _render_target_clear(rt); ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); } + } else { + rt->buffers.effects_active = false; } + } else { + rt->buffers.active = false; + rt->buffers.effects_active = true; } if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) { @@ -6008,12 +6196,12 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { glBindTexture(GL_TEXTURE_2D, rt->effects.mip_maps[i].color); int level = 0; + int fb_w = w; + int fb_h = h; while (true) { RenderTarget::Effects::MipMaps::Size mm; - - glTexImage2D(GL_TEXTURE_2D, level, color_internal_format, w, h, 0, color_format, color_type, NULL); mm.width = w; mm.height = h; rt->effects.mip_maps[i].sizes.push_back(mm); @@ -6027,8 +6215,15 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { level++; } + glTexStorage2DCustom(GL_TEXTURE_2D, level + 1, color_internal_format, fb_w, fb_h, color_format, color_type); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level); + glDisable(GL_SCISSOR_TEST); + glColorMask(1, 1, 1, 1); + if (rt->buffers.active == false) { + glDepthMask(GL_TRUE); + } for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) { @@ -6037,6 +6232,11 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { glGenFramebuffers(1, &mm.fbo); glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.mip_maps[i].color, j); + bool used_depth = false; + if (j == 0 && i == 0 && rt->buffers.active == false && !rt->flags[RENDER_TARGET_NO_3D]) { //will use this one for rendering 3D + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + used_depth = true; + } GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { @@ -6045,7 +6245,11 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { } float zero[4] = { 1, 0, 1, 0 }; + glViewport(0, 0, rt->effects.mip_maps[i].sizes[j].width, rt->effects.mip_maps[i].sizes[j].height); glClearBufferfv(GL_COLOR, 0, zero); + if (used_depth) { + glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0, 0); + } } glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); @@ -6686,7 +6890,6 @@ void RasterizerStorageGLES3::initialize() { int max_extensions = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &max_extensions); - print_line("GLES3: max extensions: " + itos(max_extensions)); for (int i = 0; i < max_extensions; i++) { const GLubyte *s = glGetStringi(GL_EXTENSIONS, i); if (!s) @@ -6696,8 +6899,8 @@ void RasterizerStorageGLES3::initialize() { } config.shrink_textures_x2 = false; - config.use_fast_texture_filter = int(GlobalConfig::get_singleton()->get("rendering/quality/use_nearest_mipmap_filter")); - config.use_anisotropic_filter = config.extensions.has("GL_EXT_texture_filter_anisotropic"); + config.use_fast_texture_filter = int(ProjectSettings::get_singleton()->get("rendering/quality/filters/use_nearest_mipmap_filter")); + config.use_anisotropic_filter = config.extensions.has("rendering/quality/filters/anisotropic_filter_level"); config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc"); config.etc_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture"); @@ -6712,7 +6915,6 @@ void RasterizerStorageGLES3::initialize() { config.hdr_supported = false; #endif - print_line("hdr supported: " + itos(config.hdr_supported)); config.pvrtc_supported = config.extensions.has("GL_IMG_texture_compression_pvrtc"); config.srgb_decode_supported = config.extensions.has("GL_EXT_texture_sRGB_decode"); @@ -6720,7 +6922,7 @@ void RasterizerStorageGLES3::initialize() { config.use_anisotropic_filter = config.extensions.has("GL_EXT_texture_filter_anisotropic"); if (config.use_anisotropic_filter) { glGetFloatv(_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &config.anisotropic_level); - config.anisotropic_level = MIN(int(GlobalConfig::get_singleton()->get("rendering/quality/anisotropic_filter_level")), config.anisotropic_level); + config.anisotropic_level = MIN(int(ProjectSettings::get_singleton()->get("rendering/quality/filters/anisotropic_filter_level")), config.anisotropic_level); } frame.clear_request = false; @@ -6831,7 +7033,7 @@ void RasterizerStorageGLES3::initialize() { { //transform feedback buffers - uint32_t xf_feedback_size = GLOBAL_DEF("rendering/buffers/blend_shape_max_buffer_size_kb", 4096); + uint32_t xf_feedback_size = GLOBAL_DEF("rendering/limits/buffers/blend_shape_max_buffer_size_kb", 4096); for (int i = 0; i < 2; i++) { glGenBuffers(1, &resources.transform_feedback_buffers[i]); @@ -6845,6 +7047,8 @@ void RasterizerStorageGLES3::initialize() { } shaders.cubemap_filter.init(); + bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx.mobile"); + shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq); shaders.particles.init(); #ifdef GLES_OVER_GL @@ -6857,6 +7061,29 @@ void RasterizerStorageGLES3::initialize() { frame.current_rt = NULL; config.keep_original_textures = false; config.generate_wireframes = false; + config.use_texture_array_environment = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections"); + + config.force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading"); + + GLOBAL_DEF("rendering/quality/depth_prepass/disable", false); + + String renderer = (const char *)glGetString(GL_RENDERER); + + config.no_depth_prepass = !bool(GLOBAL_GET("rendering/quality/depth_prepass/enable")); + if (!config.no_depth_prepass) { + + String vendors = GLOBAL_GET("rendering/quality/depth_prepass/disable_for_vendors"); + Vector<String> vendor_match = vendors.split(","); + for (int i = 0; i < vendor_match.size(); i++) { + String v = vendor_match[i].strip_edges(); + if (v == String()) + continue; + + if (renderer.findn(v) != -1) { + config.no_depth_prepass = true; + } + } + } } void RasterizerStorageGLES3::finalize() { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 3f8055d613..b536c9841c 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -48,6 +48,8 @@ class RasterizerSceneGLES3; #define _DECODE_EXT 0x8A49 #define _SKIP_DECODE_EXT 0x8A4A +void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type); + class RasterizerStorageGLES3 : public RasterizerStorage { public: RasterizerCanvasGLES3 *canvas; @@ -86,9 +88,14 @@ public: bool generate_wireframes; + bool use_texture_array_environment; + Set<String> extensions; bool keep_original_textures; + + bool no_depth_prepass; + bool force_vertex_shading; } config; mutable struct Shaders { @@ -442,6 +449,7 @@ public: bool uses_sss; bool uses_screen_texture; bool writes_modelview_or_projection; + bool uses_vertex_lighting; } spatial; @@ -494,6 +502,8 @@ public: Vector<RID> textures; float line_width; + RID next_pass; + uint32_t index; uint64_t last_pass; @@ -531,6 +541,7 @@ public: virtual Variant material_get_param(RID p_material, const StringName &p_param) const; virtual void material_set_line_width(RID p_material, float p_width); + virtual void material_set_next_pass(RID p_material, RID p_next_material); virtual bool material_is_animated(RID p_material); virtual bool material_casts_shadows(RID p_material); @@ -967,6 +978,7 @@ public: int dynamic_range; float energy; float bias; + float normal_bias; float propagation; bool interior; bool compress; @@ -1001,6 +1013,9 @@ public: virtual void gi_probe_set_bias(RID p_probe, float p_range); virtual float gi_probe_get_bias(RID p_probe) const; + virtual void gi_probe_set_normal_bias(RID p_probe, float p_range); + virtual float gi_probe_get_normal_bias(RID p_probe) const; + virtual void gi_probe_set_propagation(RID p_probe, float p_range); virtual float gi_probe_get_propagation(RID p_probe) const; @@ -1184,6 +1199,9 @@ public: GLuint depth; struct Buffers { + + bool active; + bool effects_active; GLuint fbo; GLuint depth; GLuint specular; @@ -1267,13 +1285,14 @@ public: buffers.fbo = 0; used_in_frame = false; - flags[RENDER_TARGET_VFLIP] = false; - flags[RENDER_TARGET_TRANSPARENT] = false; - flags[RENDER_TARGET_NO_3D_EFFECTS] = false; - flags[RENDER_TARGET_NO_3D] = false; - flags[RENDER_TARGET_NO_SAMPLING] = false; + for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) { + flags[i] = false; + } flags[RENDER_TARGET_HDR] = true; + buffers.active = false; + buffers.effects_active = false; + last_exposure_tick = 0; } }; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 6c568714f8..206f270f68 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -304,6 +304,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener uniform_sizes.resize(max_uniforms); uniform_alignments.resize(max_uniforms); uniform_defines.resize(max_uniforms); + bool uses_uniforms = false; for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { @@ -323,9 +324,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key()); r_gen_code.texture_hints[E->get().texture_order] = E->get().hint; } else { - if (r_gen_code.uniforms.empty()) { + if (!uses_uniforms) { r_gen_code.defines.push_back(String("#define USE_MATERIAL\n").ascii()); + uses_uniforms = true; } uniform_defines[E->get().order] = ucode; uniform_sizes[E->get().order] = _get_datatype_size(E->get().type); @@ -651,6 +653,14 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String &p_code, _dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode]); + if (r_gen_code.uniform_total_size) { //uniforms used? + int md = sizeof(float) * 4; + if (r_gen_code.uniform_total_size % md) { + r_gen_code.uniform_total_size += md - (r_gen_code.uniform_total_size % md); + } + r_gen_code.uniform_total_size += md; //pad just in case + } + return OK; } @@ -700,7 +710,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n"; actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n"; - actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_transform"] = "#define SKIP_TRANSFORM_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; /** SPATIAL SHADER **/ @@ -775,11 +785,18 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; - actions[VS::SHADER_SPATIAL].render_mode_defines["skip_default_transform"] = "#define SKIP_TRANSFORM_USED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; /* PARTICLES SHADER */ diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index c821acadf5..f1077e2d20 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -208,6 +208,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { Vector<const char *> strings; #ifdef GLES_OVER_GL strings.push_back("#version 330\n"); + strings.push_back("#define GLES_OVER_GL\n"); #else strings.push_back("#version 300 es\n"); #endif @@ -416,7 +417,8 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { strings.push_back(fragment_code4.get_data()); #ifdef DEBUG_SHADER - DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data())); + DEBUG_PRINT("\nFragment Globals:\n\n" + String(code_globals.get_data())); + DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string2.get_data())); for (int i = 0; i < strings.size(); i++) { //print_line("frag strings "+itos(i)+":"+String(strings[i])); diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index a7c388815d..d33193ee50 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -49,6 +49,9 @@ void main() { #define M_PI 3.14159265359 +#if !defined(USE_GLES_OVER_GL) +precision mediump float; +#endif #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) in vec3 cube_interp; @@ -87,14 +90,6 @@ vec4 texturePanorama(vec3 normal,sampler2D pano ) { #endif -float sRGB_gamma_correct(float c){ - float a = 0.055; - if(c < 0.0031308) - return 12.92*c; - else - return (1.0+a)*pow(c, 1.0/2.4) - a; -} - uniform float stuff; uniform vec2 pixel_size; @@ -131,7 +126,7 @@ void main() { vec4 color = texture( source_cube, normalize(cube_interp) ); #else - vec4 color = texture( source, uv_interp ); + vec4 color = textureLod( source, uv_interp,0.0 ); #endif diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index 2aec6380f5..485fbb6ee0 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -19,9 +19,16 @@ void main() { precision highp float; precision highp int; -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA uniform sampler2D source_panorama; //texunit:0 -#else +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY +uniform sampler2DArray source_dual_paraboloid_array; //texunit:0 +uniform int source_array_index; +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) uniform samplerCube source_cube; //texunit:0 #endif @@ -169,7 +176,7 @@ vec2 Hammersley(uint i, uint N) { uniform bool z_flip; -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA vec4 texturePanorama(vec3 normal,sampler2D pano ) { @@ -189,6 +196,23 @@ vec4 texturePanorama(vec3 normal,sampler2D pano ) { #endif +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + +vec4 textureDualParaboloidArray(vec3 normal) { + + vec3 norm = normalize(normal); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + if (norm.z<0.0) { + norm.y=0.5-norm.y+0.5; + } + return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0); + +} + +#endif + void main() { #ifdef USE_DUAL_PARABOLOID @@ -197,9 +221,8 @@ void main() { N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y)); N = normalize(N); - if (!z_flip) { + if (z_flip) { N.y=-N.y; //y is flipped to improve blending between both sides - } else { N.z=-N.z; } @@ -212,13 +235,25 @@ void main() { #ifdef USE_DIRECT_WRITE -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0); -#else +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0); +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) + + N.y=-N.y; frag_color=vec4(texture(N,source_cube).rgb,1.0); #endif + + + #else vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); @@ -233,9 +268,17 @@ void main() { float ndotl = clamp(dot(N, L),0.0,1.0); if (ndotl>0.0) { -#ifdef USE_PANORAMA +#ifdef USE_SOURCE_PANORAMA sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl; -#else +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + sum.rgb += textureDualParaboloidArray(H).rgb *ndotl; +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) + H.y=-H.y; sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl; #endif sum.a += ndotl; diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index 8ca8e21f11..09e522866c 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -14,7 +14,7 @@ uniform vec4 blur_section; void main() { - uv_interp = uv_in; + uv_interp = uv_in; gl_Position = vertex_attrib; #ifdef USE_BLUR_SECTION @@ -25,6 +25,9 @@ void main() { [fragment] +#if !defined(GLES_OVER_GL) +precision mediump float; +#endif in vec2 uv_interp; uniform sampler2D source_color; //texunit:0 @@ -99,7 +102,7 @@ uniform highp float auto_exposure_grey; #endif uniform float glow_bloom; -uniform float glow_hdr_treshold; +uniform float glow_hdr_threshold; uniform float glow_hdr_scale; #endif @@ -262,7 +265,7 @@ void main() { frag_color*=exposure; float luminance = max(frag_color.r,max(frag_color.g,frag_color.b)); - float feedback = max( smoothstep(glow_hdr_treshold,glow_hdr_treshold+glow_hdr_scale,luminance), glow_bloom ); + float feedback = max( smoothstep(glow_hdr_threshold,glow_hdr_threshold+glow_hdr_scale,luminance), glow_bloom ); frag_color *= feedback; @@ -285,4 +288,3 @@ void main() { } - diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl index 6a977a201e..a62c124dfe 100644 --- a/drivers/gles3/shaders/particles.glsl +++ b/drivers/gles3/shaders/particles.glsl @@ -178,7 +178,7 @@ VERTEX_SHADER_CODE #if !defined(DISABLE_FORCE) - if (true) { + if (false) { vec3 force = vec3(0.0); for(int i=0;i<attractor_count;i++) { @@ -187,7 +187,7 @@ VERTEX_SHADER_CODE float dist = length(rel_vec); if (attractors[i].radius < dist) continue; - if (attractors[i].eat_radius>0 && attractors[i].eat_radius > dist) { + if (attractors[i].eat_radius>0.0 && attractors[i].eat_radius > dist) { out_velocity_active.a=0.0; } diff --git a/drivers/gles3/shaders/resolve.glsl b/drivers/gles3/shaders/resolve.glsl index 181a3c99ec..0b50a9c57b 100644 --- a/drivers/gles3/shaders/resolve.glsl +++ b/drivers/gles3/shaders/resolve.glsl @@ -15,6 +15,9 @@ void main() { [fragment] +#if !defined(GLES_OVER_GL) +precision mediump float; +#endif in vec2 uv_interp; uniform sampler2D source_specular; //texunit:0 diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 40a295bc83..340a1f24d2 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -64,44 +64,45 @@ layout(std140) uniform SceneData { //ubo:0 highp mat4 camera_inverse_matrix; highp mat4 camera_matrix; - highp vec4 ambient_light_color; - highp vec4 bg_color; + mediump vec4 ambient_light_color; + mediump vec4 bg_color; - vec4 fog_color_enabled; - vec4 fog_sun_color_amount; + mediump vec4 fog_color_enabled; + mediump vec4 fog_sun_color_amount; - float ambient_energy; - float bg_energy; + mediump float ambient_energy; + mediump float bg_energy; - float z_offset; - float z_slope_scale; - float shadow_dual_paraboloid_render_zfar; - float shadow_dual_paraboloid_render_side; + 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 screen_pixel_size; - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; - float time; - float z_far; - float reflection_multiplier; - float subsurface_scatter_width; - float ambient_occlusion_affect_light; + highp float time; + highp float z_far; + mediump float reflection_multiplier; + mediump float subsurface_scatter_width; + mediump float ambient_occlusion_affect_light; bool fog_depth_enabled; - float fog_depth_begin; - float fog_depth_curve; + highp float fog_depth_begin; + highp float fog_depth_curve; bool fog_transmit_enabled; - float fog_transmit_curve; + highp float fog_transmit_curve; bool fog_height_enabled; - float fog_height_min; - float fog_height_max; - float fog_height_curve; + highp float fog_height_min; + highp float fog_height_max; + highp float fog_height_curve; }; uniform highp mat4 world_transform; + #ifdef USE_LIGHT_DIRECTIONAL layout(std140) uniform DirectionalLightData { //ubo:3 @@ -121,6 +122,90 @@ layout(std140) uniform DirectionalLightData { //ubo:3 #endif +#ifdef USE_VERTEX_LIGHTING +//omni and spot + +struct LightData { + + highp vec4 light_pos_inv_radius; + mediump vec4 light_direction_attenuation; + mediump vec4 light_color_energy; + mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled, + mediump vec4 light_clamp; + mediump vec4 shadow_color_contact; + highp mat4 shadow_matrix; + +}; + + +layout(std140) uniform OmniLightData { //ubo:4 + + LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; +}; + +layout(std140) uniform SpotLightData { //ubo:5 + + LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; +}; + +#ifdef USE_FORWARD_LIGHTING + + +uniform int omni_light_indices[MAX_FORWARD_LIGHTS]; +uniform int omni_light_count; + +uniform int spot_light_indices[MAX_FORWARD_LIGHTS]; +uniform int spot_light_count; + +#endif + +out vec4 diffuse_light_interp; +out vec4 specular_light_interp; + +void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color,float roughness,inout vec3 diffuse, inout vec3 specular) { + + float dotNL = max(dot(N,L), 0.0 ); + diffuse += dotNL * light_color; + + if (roughness > 0.0) { + + vec3 H = normalize(V + L); + float dotNH = max(dot(N,H), 0.0 ); + float intensity = pow( dotNH, (1.0-roughness) * 256.0); + specular += light_color * intensity; + + } +} + +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal, float roughness,inout vec3 diffuse, inout vec3 specular) { + + vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; + float light_length = length( light_rel_vec ); + float normalized_distance = light_length*omni_lights[idx].light_pos_inv_radius.w; + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w )); + + light_compute(normal,normalize(light_rel_vec),eye_vec,omni_lights[idx].light_color_energy.rgb * light_attenuation,roughness,diffuse,specular); + +} + +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness, inout vec3 diffuse, inout vec3 specular) { + + vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex; + float light_length = length( light_rel_vec ); + float normalized_distance = light_length*spot_lights[idx].light_pos_inv_radius.w; + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.001), spot_lights[idx].light_direction_attenuation.w )); + vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz; + float spot_cutoff=spot_lights[idx].light_params.y; + float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff); + float spot_rim = (1.0 - scos) / (1.0 - spot_cutoff); + light_attenuation *= 1.0 - pow( max(spot_rim,0.001), spot_lights[idx].light_params.x); + + + light_compute(normal,normalize(light_rel_vec),eye_vec,spot_lights[idx].light_color_energy.rgb*light_attenuation,roughness,diffuse,specular); +} + + +#endif /* Varyings */ @@ -275,6 +360,21 @@ void main() { highp mat4 modelview = camera_inverse_matrix * world_matrix; highp mat4 local_projection = projection_matrix; +//using world coordinates +#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) + + vertex = world_matrix * vertex; + normal = normalize((world_matrix * vec4(normal,0.0)).xyz); + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + + tangent = normalize((world_matrix * vec4(tangent,0.0)).xyz); + binormal = normalize((world_matrix * vec4(binormal,0.0)).xyz); +#endif +#endif + + float roughness=0.0; + //defines that make writing custom shaders easier #define projection_matrix local_projection #define world_transform world_matrix @@ -286,29 +386,42 @@ VERTEX_SHADER_CODE - -#if !defined(SKIP_TRANSFORM_USED) +//using local coordinates (default) +#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED) vertex = modelview * vertex; normal = normalize((modelview * vec4(normal,0.0)).xyz); + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + + tangent = normalize((modelview * vec4(tangent,0.0)).xyz); + binormal = normalize((modelview * vec4(binormal,0.0)).xyz); +#endif #endif +//using world coordinates +#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) - vertex_interp = vertex.xyz; - normal_interp = normal; + vertex = camera_inverse_matrix * vertex; + normal = normalize((camera_inverse_matrix * vec4(normal,0.0)).xyz); #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) -#if !defined(SKIP_TRANSFORM_USED) + tangent = normalize((camera_inverse_matrix * vec4(tangent,0.0)).xyz); + binormal = normalize((camera_inverse_matrix * vec4(binormal,0.0)).xyz); +#endif +#endif - tangent = normalize((modelview * vec4(tangent,0.0)).xyz); - binormal = normalize((modelview * vec4(binormal,0.0)).xyz); + vertex_interp = vertex.xyz; + normal_interp = normal; -#endif + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) tangent_interp = tangent; binormal_interp = binormal; #endif + #ifdef RENDER_DEPTH @@ -350,6 +463,54 @@ VERTEX_SHADER_CODE #endif position_interp=gl_Position; + +#ifdef USE_VERTEX_LIGHTING + + diffuse_light_interp=vec4(0.0); + specular_light_interp=vec4(0.0); + +#ifdef USE_FORWARD_LIGHTING + + for(int i=0;i<omni_light_count;i++) { + light_process_omni(omni_light_indices[i],vertex_interp,-normalize( vertex_interp ),normal_interp,roughness,diffuse_light_interp.rgb,specular_light_interp.rgb); + } + + for(int i=0;i<spot_light_count;i++) { + light_process_spot(spot_light_indices[i],vertex_interp,-normalize( vertex_interp ),normal_interp,roughness,diffuse_light_interp.rgb,specular_light_interp.rgb); + } +#endif + +#ifdef USE_LIGHT_DIRECTIONAL + + vec3 directional_diffuse = vec3(0.0); + vec3 directional_specular = vec3(0.0); + light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),normal_interp,roughness,directional_diffuse,directional_specular); + + float diff_avg = dot(diffuse_light_interp.rgb,vec3(0.33333)); + float diff_dir_avg = dot(directional_diffuse,vec3(0.33333)); + if (diff_avg>0.0) { + diffuse_light_interp.a=diff_dir_avg/(diff_avg+diff_dir_avg); + } else { + diffuse_light_interp.a=1.0; + } + + diffuse_light_interp.rgb+=directional_diffuse; + + float spec_avg = dot(specular_light_interp.rgb,vec3(0.33333)); + float spec_dir_avg = dot(directional_specular,vec3(0.33333)); + if (spec_avg>0.0) { + specular_light_interp.a=spec_dir_avg/(spec_avg+spec_dir_avg); + } else { + specular_light_interp.a=1.0; + } + + specular_light_interp.rgb+=directional_specular; + +#endif //USE_LIGHT_DIRECTIONAL + + +#endif // USE_VERTEX_LIGHTING + } @@ -405,7 +566,6 @@ uniform bool no_ambient_light; #ifdef USE_RADIANCE_MAP -uniform sampler2D radiance_map; //texunit:-2 layout(std140) uniform Radiance { //ubo:2 @@ -415,6 +575,53 @@ layout(std140) uniform Radiance { //ubo:2 }; +#define RADIANCE_MAX_LOD 5.0 + +#ifdef USE_RADIANCE_MAP_ARRAY + +uniform sampler2DArray radiance_map; //texunit:-2 + +vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) { + + vec3 norm = normalize(p_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + + // we need to lie the derivatives (normg) and assume that DP side is always the same + // to get proper texure filtering + vec2 normg=norm.xy; + if (norm.z>0.0) { + norm.y=0.5-norm.y+0.5; + } + + // thanks to OpenGL spec using floor(layer + 0.5) for texture arrays, + // it's easy to have precision errors using fract() to interpolate layers + // as such, using fixed point to ensure it works. + + float index = p_roughness * RADIANCE_MAX_LOD; + int indexi = int(index * 256.0); + vec3 base = textureGrad(p_tex, vec3(norm.xy, float(indexi/256)),dFdx(normg),dFdy(normg)).xyz; + vec3 next = textureGrad(p_tex, vec3(norm.xy, float(indexi/256+1)),dFdx(normg),dFdy(normg)).xyz; + return mix(base,next,float(indexi%256)/256.0); +} + +#else + +uniform sampler2D radiance_map; //texunit:-2 + +vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec,float p_roughness) { + + vec3 norm = normalize(p_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + if (norm.z>0.0) { + norm.y=0.5-norm.y+0.5; + } + return textureLod(p_tex, norm.xy, p_roughness * RADIANCE_MAX_LOD).xyz; +} + +#endif + #endif /* Material Uniforms */ @@ -439,39 +646,39 @@ layout(std140) uniform SceneData { highp mat4 camera_inverse_matrix; highp mat4 camera_matrix; - highp vec4 ambient_light_color; - highp vec4 bg_color; + mediump vec4 ambient_light_color; + mediump vec4 bg_color; - vec4 fog_color_enabled; - vec4 fog_sun_color_amount; + mediump vec4 fog_color_enabled; + mediump vec4 fog_sun_color_amount; - float ambient_energy; - float bg_energy; + mediump float ambient_energy; + mediump float bg_energy; - float z_offset; - float z_slope_scale; - float shadow_dual_paraboloid_render_zfar; - float shadow_dual_paraboloid_render_side; + 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 screen_pixel_size; - vec2 shadow_atlas_pixel_size; - vec2 directional_shadow_pixel_size; + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; - float time; - float z_far; - float reflection_multiplier; - float subsurface_scatter_width; - float ambient_occlusion_affect_light; + highp float time; + highp float z_far; + mediump float reflection_multiplier; + mediump float subsurface_scatter_width; + mediump float ambient_occlusion_affect_light; bool fog_depth_enabled; - float fog_depth_begin; - float fog_depth_curve; + highp float fog_depth_begin; + highp float fog_depth_curve; bool fog_transmit_enabled; - float fog_transmit_curve; + highp float fog_transmit_curve; bool fog_height_enabled; - float fog_height_min; - float fog_height_max; - float fog_height_curve; + highp float fog_height_min; + highp float fog_height_max; + highp float fog_height_curve; }; //directional light data @@ -498,6 +705,10 @@ uniform highp sampler2DShadow directional_shadow; //texunit:-4 #endif +#ifdef USE_VERTEX_LIGHTING +in vec4 diffuse_light_interp; +in vec4 specular_light_interp; +#endif //omni and spot struct LightData { @@ -583,6 +794,8 @@ layout(location=0) out vec4 frag_color; in highp vec4 position_interp; uniform highp sampler2D depth_buffer; //texunit:-8 +#ifdef USE_CONTACT_SHADOWS + float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { if (abs(dir.z)>0.99) @@ -597,6 +810,9 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { vec2 screen_rel = to_screen - from_screen; + if (length(screen_rel)<0.00001) + return 1.0; //too small, don't do anything + /*float pixel_size; //approximate pixel size if (screen_rel.x > screen_rel.y) { @@ -612,15 +828,16 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { vec2 pixel_incr = normalize(screen_rel)*screen_pixel_size; - float steps = length(screen_rel) / length(pixel_incr); + float steps = length(screen_rel) / length(pixel_incr); + steps = min(2000.0,steps); //put a limit to avoid freezing in some strange situation //steps=10.0; vec4 incr = (dest - source)/steps; float ratio=0.0; float ratio_incr = 1.0/steps; - do { + while(steps>0.0) { source += incr*2.0; bias+=incr*2.0; @@ -638,11 +855,13 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { ratio+=ratio_incr; steps-=1.0; - } while (steps>0.0); + } return 1.0; } +#endif + // GGX Specular // Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl float G1V(float dotNV, float k) @@ -703,6 +922,10 @@ LIGHT_SHADER_CODE diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI; } +#elif defined(DIFFUSE_TOON) + + diffuse += smoothstep(-roughness,max(roughness,0.01),dot(N,L)) * light_color * diffuse_color; + #elif defined(DIFFUSE_BURLEY) { @@ -733,6 +956,37 @@ LIGHT_SHADER_CODE if (roughness > 0.0) { + + // D + +#if defined(SPECULAR_BLINN) + + vec3 H = normalize(V + L); + float dotNH = max(dot(N,H), 0.0 ); + float intensity = pow( dotNH, (1.0-roughness) * 256.0); + specular += light_color * intensity * specular_blob_intensity; + +#elif defined(SPECULAR_PHONG) + + vec3 R = normalize(-reflect(L,N)); + float dotNV = max(0.0,dot(R,V)); + float intensity = pow( dotNV, (1.0-roughness) * 256.0); + specular += light_color * intensity * specular_blob_intensity; + +#elif defined(SPECULAR_TOON) + + vec3 R = normalize(-reflect(L,N)); + float dotNV = dot(R,V); + float mid = 1.0-roughness; + mid*=mid; + float intensity = smoothstep(mid-roughness*0.5,mid+roughness*0.5,dotNV) * mid; + diffuse += light_color * intensity * specular_blob_intensity; //write to diffuse, as in toon shading you generally want no reflection + +#elif defined(SPECULAR_DISABLED) + //none.. + +#else + // shlick+ggx as default float alpha = roughness * roughness; vec3 H = normalize(V + L); @@ -740,7 +994,6 @@ LIGHT_SHADER_CODE float dotNH = max(dot(N,H), 0.0 ); float dotLH = max(dot(L,H), 0.0 ); - // D #if defined(LIGHT_USE_ANISOTROPY) float aspect = sqrt(1.0-anisotropy*0.9); @@ -772,6 +1025,7 @@ LIGHT_SHADER_CODE float speci = dotNL * D * F * vis; specular += speci * light_color * specular_blob_intensity; +#endif #if defined(LIGHT_USE_CLEARCOAT) float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss)); @@ -862,7 +1116,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po } #endif -void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; float light_length = length( light_rel_vec ); @@ -903,31 +1157,34 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw; float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect); + +#ifdef USE_CONTACT_SHADOWS + if (shadow>0.01 && omni_lights[idx].shadow_color_contact.a>0.0) { float contact_shadow = contact_shadow_compute(vertex,normalize(light_rel_vec),min(light_length,omni_lights[idx].shadow_color_contact.a)); shadow=min(shadow,contact_shadow); - } +#endif light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow); } - light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } -void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex; float light_length = length( light_rel_vec ); float normalized_distance = light_length*spot_lights[idx].light_pos_inv_radius.w; - vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), spot_lights[idx].light_direction_attenuation.w )); + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.001), spot_lights[idx].light_direction_attenuation.w )); vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz; float spot_cutoff=spot_lights[idx].light_params.y; float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff); float spot_rim = (1.0 - scos) / (1.0 - spot_cutoff); - light_attenuation *= 1.0 - pow( spot_rim, spot_lights[idx].light_params.x); + light_attenuation *= 1.0 - pow( max(spot_rim,0.001), spot_lights[idx].light_params.x); if (spot_lights[idx].light_params.w>0.5) { //there is a shadowmap @@ -936,17 +1193,18 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp); +#ifdef USE_CONTACT_SHADOWS if (shadow>0.01 && spot_lights[idx].shadow_color_contact.a>0.0) { float contact_shadow = contact_shadow_compute(vertex,normalize(light_rel_vec),min(light_length,spot_lights[idx].shadow_color_contact.a)); shadow=min(shadow,contact_shadow); } - +#endif light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow); } - light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } @@ -986,27 +1244,19 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta } - - vec3 splane=normalize(local_ref_vec); vec4 clamp_rect=reflections[idx].atlas_clamp; - - splane.z*=-1.0; - if (splane.z>=0.0) { - splane.z+=1.0; - clamp_rect.y+=clamp_rect.w; - } else { - splane.z=1.0 - splane.z; - splane.y=-splane.y; + vec3 norm = normalize(local_ref_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + if (norm.z>0.0) { + norm.y=0.5-norm.y+0.5; } - splane.xy/=splane.z; - splane.xy=splane.xy * 0.5 + 0.5; - - splane.xy = splane.xy * clamp_rect.zw + clamp_rect.xy; - splane.xy = clamp(splane.xy,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw); + vec2 atlas_uv = norm.xy * clamp_rect.zw + clamp_rect.xy; + atlas_uv = clamp(atlas_uv,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw); highp vec4 reflection; - reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb; + reflection.rgb = textureLod(reflection_atlas,atlas_uv,roughness*5.0).rgb; if (reflections[idx].params.z < 0.5) { reflection.rgb = mix(skybox,reflection.rgb,blend); @@ -1073,6 +1323,7 @@ uniform highp vec3 gi_probe_bounds1; uniform highp vec3 gi_probe_cell_size1; uniform highp float gi_probe_multiplier1; uniform highp float gi_probe_bias1; +uniform highp float gi_probe_normal_bias1; uniform bool gi_probe_blend_ambient1; uniform mediump sampler3D gi_probe2; //texunit:-10 @@ -1081,12 +1332,12 @@ uniform highp vec3 gi_probe_bounds2; uniform highp vec3 gi_probe_cell_size2; uniform highp float gi_probe_multiplier2; uniform highp float gi_probe_bias2; +uniform highp float gi_probe_normal_bias2; uniform bool gi_probe2_enabled; uniform bool gi_probe_blend_ambient2; vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, bool blend_ambient, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias;//1.0; //dot(direction,mix(vec3(-1.0),vec3(1.0),greaterThan(direction,vec3(0.0))))*2.0; float alpha=0.0; vec3 color = vec3(0.0); @@ -1107,27 +1358,30 @@ vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, b return color; } -void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness,float p_bias, out vec4 out_spec, out vec4 out_diff) { +void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness,float p_bias,float p_normal_bias, inout vec4 out_spec, inout vec4 out_diff) { vec3 probe_pos = (probe_xform * vec4(pos,1.0)).xyz; vec3 ref_pos = (probe_xform * vec4(pos+ref_vec,1.0)).xyz; - ref_vec = normalize(ref_pos - probe_pos); + probe_pos+=(probe_xform * vec4(normal_mtx[2],0.0)).xyz*p_normal_bias; + /* out_diff.rgb = voxel_cone_trace(probe,cell_size,probe_pos,normalize((probe_xform * vec4(ref_vec,0.0)).xyz),0.0 ,100.0); out_diff.a = 1.0; return;*/ //out_diff = vec4(textureLod(probe,probe_pos*cell_size,3.0).rgb,1.0); //return; - if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds))))) + //this causes corrupted pixels, i have no idea why.. + if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds))))) { return; + } - vec3 blendv = probe_pos/bounds * 2.0 - 1.0; - float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z)); - blend=1.0; + //vec3 blendv = probe_pos/bounds * 2.0 - 1.0; + //float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z)); + float blend=1.0; float max_distance = length(bounds); @@ -1174,7 +1428,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s light*=multiplier; - out_diff = vec4(light*blend,blend); + out_diff += vec4(light*blend,blend); //irradiance @@ -1183,7 +1437,8 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s irr_light *= multiplier; //irr_light=vec3(0.0); - out_spec = vec4(irr_light*blend,blend); + out_spec += vec4(irr_light*blend,blend); + } @@ -1209,11 +1464,11 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_sp out_specular = vec3(0.0); - gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,gi_probe_bias1,spec_accum,diff_accum); + gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,gi_probe_bias1,gi_probe_normal_bias1,spec_accum,diff_accum); if (gi_probe2_enabled) { - gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,gi_probe_bias2,spec_accum,diff_accum); + gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,gi_probe_bias2,gi_probe_normal_bias2,spec_accum,diff_accum); } if (diff_accum.a>0.0) { @@ -1231,23 +1486,7 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_sp #endif -vec3 textureDualParabolod(sampler2D p_tex, vec3 p_vec,float p_lod) { - - vec3 norm = normalize(p_vec); - float y_ofs=0.0; - if (norm.z>=0.0) { - norm.z+=1.0; - y_ofs+=0.5; - } else { - norm.z=1.0 - norm.z; - norm.y=-norm.y; - } - - norm.xy/=norm.z; - norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs); - return textureLod(p_tex, norm.xy, p_lod).xyz; -} void main() { @@ -1372,10 +1611,20 @@ FRAGMENT_SHADER_CODE //apply energy conservation +#ifdef USE_VERTEX_LIGHTING + + vec3 specular_light = specular_light_interp.rgb; + vec3 diffuse_light = diffuse_light_interp.rgb; +#else + vec3 specular_light = vec3(0.0,0.0,0.0); - vec3 ambient_light; vec3 diffuse_light = vec3(0.0,0.0,0.0); +#endif + + vec3 ambient_light; + vec3 env_reflection_light = vec3(0.0,0.0,0.0); + vec3 eye_vec = -normalize( vertex_interp ); @@ -1387,16 +1636,12 @@ FRAGMENT_SHADER_CODE } else { { - -#define RADIANCE_MAX_LOD 5.0 - float lod = roughness * RADIANCE_MAX_LOD; - { //read radiance from dual paraboloid vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n); ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz); - vec3 radiance = textureDualParabolod(radiance_map,ref_vec,lod) * bg_energy; - specular_light = radiance; + vec3 radiance = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy; + env_reflection_light = radiance; } //no longer a cubemap @@ -1407,7 +1652,7 @@ FRAGMENT_SHADER_CODE { vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz); - vec3 env_ambient=textureDualParabolod(radiance_map,ambient_dir,RADIANCE_MAX_LOD) * bg_energy; + vec3 env_ambient=textureDualParaboloid(radiance_map,ambient_dir,1.0) * bg_energy; ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution); //ambient_light=vec3(0.0,0.0,0.0); @@ -1425,7 +1670,12 @@ FRAGMENT_SHADER_CODE ambient_light*=ambient_energy; -#ifdef USE_LIGHT_DIRECTIONAL + float specular_blob_intensity=1.0; +#if defined(SPECULAR_TOON) + specular_blob_intensity*=specular * 2.0; +#endif + +#if defined(USE_LIGHT_DIRECTIONAL) vec3 light_attenuation=vec3(1.0); @@ -1550,13 +1800,14 @@ FRAGMENT_SHADER_CODE } #endif +#ifdef USE_CONTACT_SHADOWS if (shadow>0.01 && shadow_color_contact.a>0.0) { float contact_shadow = contact_shadow_compute(vertex,-light_direction_attenuation.xyz,shadow_color_contact.a); shadow=min(shadow,contact_shadow); } - +#endif light_attenuation=mix(shadow_color_contact.rgb,vec3(1.0),shadow); @@ -1564,52 +1815,63 @@ FRAGMENT_SHADER_CODE #endif //LIGHT_DIRECTIONAL_SHADOW - light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); +#ifdef USE_VERTEX_LIGHTING + diffuse_light*=mix(vec3(1.0),light_attenuation,diffuse_light_interp.a); + specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a); + +#else + light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); +#endif #endif //#USE_LIGHT_DIRECTIONAL #ifdef USE_GI_PROBES - gi_probes_compute(vertex,normal,roughness,specular_light,ambient_light); + gi_probes_compute(vertex,normal,roughness,env_reflection_light,ambient_light); #endif - #ifdef USE_FORWARD_LIGHTING + highp vec4 reflection_accum = vec4(0.0,0.0,0.0,0.0); highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0); - - - for(int i=0;i<reflection_count;i++) { - reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,reflection_accum,ambient_accum); + reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,env_reflection_light,reflection_accum,ambient_accum); } if (reflection_accum.a>0.0) { specular_light+=reflection_accum.rgb/reflection_accum.a; + } else { + specular_light+=env_reflection_light; } + if (ambient_accum.a>0.0) { ambient_light+=ambient_accum.rgb/ambient_accum.a; } + + +#ifdef USE_VERTEX_LIGHTING + + diffuse_light*=albedo; +#else + for(int i=0;i<omni_light_count;i++) { - light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); } for(int i=0;i<spot_light_count;i++) { - light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); } - +#endif //USE_VERTEX_LIGHTING #endif - - #ifdef RENDER_DEPTH //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) #else @@ -1622,19 +1884,21 @@ FRAGMENT_SHADER_CODE #endif - - - - //energu conservation diffuse_light=mix(diffuse_light,vec3(0.0),metallic); ambient_light=mix(ambient_light,vec3(0.0),metallic); + + { + +#if defined(DIFFUSE_TOON) + //simplify for toon, as + specular_light *= specular * metallic * albedo * 2.0; +#else //brdf approximation (Lazarov 2013) float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); - + vec3 dielectric = vec3(0.034) * specular * 2.0; //energy conservation - vec3 dielectric = vec3(0.034) * 0.5 * 2.0; vec3 f0 = mix(dielectric, albedo, metallic); const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04); @@ -1643,11 +1907,13 @@ FRAGMENT_SHADER_CODE vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw; specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0; +#endif + } if (fog_color_enabled.a > 0.5) { - float fog_amount=0; + float fog_amount=0.0; diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index 3ce2edf4e9..988e31d1ea 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -18,6 +18,10 @@ void main() { [fragment] +#if !defined(GLES_OVER_GL) +precision mediump float; +#endif + in vec2 uv_interp; @@ -140,6 +144,38 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod) #endif +vec3 tonemap_filmic(vec3 color,float white) { + + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + float W = 11.2; + + vec3 coltn = ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; + float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F; + + return coltn/whitetn; + +} + +vec3 tonemap_aces(vec3 color) { + float a = 2.51f; + float b = 0.03f; + float c = 2.43f; + float d = 0.59f; + float e = 0.14f; + return color = clamp((color*(a*color+b))/(color*(c*color+d)+e),vec3(0.0),vec3(1.0)); +} + +vec3 tonemap_reindhart(vec3 color,vec3 white) { + + return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color ); +} + + void main() { ivec2 coord = ivec2(gl_FragCoord.xy); @@ -153,8 +189,11 @@ void main() { color*=exposure; - #if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) +#define USING_GLOW +#endif + +#if defined(USING_GLOW) vec3 glow = vec3(0.0); #ifdef USE_GLOW_LEVEL1 @@ -189,85 +228,83 @@ void main() { glow *= glow_intensity; +#endif -#ifdef USE_GLOW_REPLACE +#ifdef USE_REINDHART_TONEMAPPER - color.rgb = glow; + color.rgb = tonemap_reindhart(color.rgb,white); + +# if defined(USING_GLOW) + glow = tonemap_reindhart(glow,white); +# endif #endif -#ifdef USE_GLOW_SCREEN +#ifdef USE_FILMIC_TONEMAPPER - color.rgb = clamp((color.rgb + glow) - (color.rgb * glow), 0.0, 1.0); + color.rgb = tonemap_filmic(color.rgb,white); + +# if defined(USING_GLOW) + glow = tonemap_filmic(glow,white); +# endif #endif -#ifdef USE_GLOW_SOFTLIGHT +#ifdef USE_ACES_TONEMAPPER - { + color.rgb = tonemap_aces(color.rgb); - glow = (glow * 0.5) + 0.5; - color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r))); - color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g))); - color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b))); - } - -#endif +# if defined(USING_GLOW) + glow = tonemap_aces(glow); +# endif -#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) - color.rgb+=glow; #endif + //regular Linear -> SRGB conversion + vec3 a = vec3(0.055); + color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); +#if defined(USING_GLOW) + glow = mix( (vec3(1.0)+a)*pow(glow,vec3(1.0/2.4))-a , 12.92*glow , lessThan(glow,vec3(0.0031308))); #endif +//glow needs to be added in SRGB space (together with image space effects) -#ifdef USE_REINDHART_TONEMAPPER - - { - color.rgb = ( color.rgb * ( 1.0 + ( color.rgb / ( white) ) ) ) / ( 1.0 + color.rgb ); + color.rgb = clamp(color.rgb,0.0,1.0); - } +#if defined(USING_GLOW) + glow = clamp(glow,0.0,1.0); #endif -#ifdef USE_FILMIC_TONEMAPPER +#ifdef USE_GLOW_REPLACE - { + color.rgb = glow; - float A = 0.15; - float B = 0.50; - float C = 0.10; - float D = 0.20; - float E = 0.02; - float F = 0.30; - float W = 11.2; +#endif - vec3 coltn = ((color.rgb*(A*color.rgb+C*B)+D*E)/(color.rgb*(A*color.rgb+B)+D*F))-E/F; - float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F; +#ifdef USE_GLOW_SCREEN - color.rgb=coltn/whitetn; + color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0)); - } #endif -#ifdef USE_ACES_TONEMAPPER +#ifdef USE_GLOW_SOFTLIGHT { - float a = 2.51f; - float b = 0.03f; - float c = 2.43f; - float d = 0.59f; - float e = 0.14f; - color.rgb = clamp((color.rgb*(a*color.rgb+b))/(color.rgb*(c*color.rgb+d)+e),vec3(0.0),vec3(1.0)); + + glow = (glow * 0.5) + 0.5; + color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r))); + color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g))); + color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b))); } #endif - //regular Linear -> SRGB conversion - vec3 a = vec3(0.055); - color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); - +#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) + //additive + color.rgb+=glow; +#endif #ifdef USE_BCS diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp index 0d7e1d9d72..4f1f318aee 100644 --- a/drivers/png/resource_saver_png.cpp +++ b/drivers/png/resource_saver_png.cpp @@ -30,8 +30,8 @@ #include "resource_saver_png.h" #include "core/image.h" -#include "global_config.h" #include "os/file_access.h" +#include "project_settings.h" #include "scene/resources/texture.h" #include <png.h> diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 45827ee4f7..fb04ef0088 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -33,7 +33,7 @@ #include <pulse/error.h> -#include "global_config.h" +#include "project_settings.h" Error AudioDriverPulseAudio::init() { diff --git a/drivers/rtaudio/audio_driver_rtaudio.cpp b/drivers/rtaudio/audio_driver_rtaudio.cpp index 0cbe145b41..da998db66f 100644 --- a/drivers/rtaudio/audio_driver_rtaudio.cpp +++ b/drivers/rtaudio/audio_driver_rtaudio.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "audio_driver_rtaudio.h" -#include "global_config.h" #include "os/os.h" +#include "project_settings.h" #ifdef RTAUDIO_ENABLED diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 75f40cacca..e424590881 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -50,10 +50,10 @@ #include <mach-o/dyld.h> #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__OpenBSD__) #include <sys/param.h> #endif -#include "global_config.h" +#include "project_settings.h" #include <assert.h> #include <dlfcn.h> #include <errno.h> @@ -453,7 +453,7 @@ Error OS_Unix::close_dynamic_library(void *p_library_handle) { return OK; } -Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) { +Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) { const char *error; dlerror(); // Clear existing errors @@ -461,8 +461,12 @@ Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const S error = dlerror(); if (error != NULL) { - ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error); - ERR_FAIL_V(ERR_CANT_RESOLVE); + if (!p_optional) { + ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error); + ERR_FAIL_V(ERR_CANT_RESOLVE); + } else { + return ERR_CANT_RESOLVE; + } } return OK; } @@ -494,7 +498,7 @@ String OS_Unix::get_data_dir() const { if (has_environment("HOME")) { - bool use_godot = GlobalConfig::get_singleton()->get("application/use_shared_user_dir"); + bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir"); if (use_godot) return get_environment("HOME") + "/.godot/app_userdata/" + an; else @@ -502,12 +506,7 @@ String OS_Unix::get_data_dir() const { } } - return GlobalConfig::get_singleton()->get_resource_path(); -} - -bool OS_Unix::check_feature_support(const String &p_feature) { - - return VisualServer::get_singleton()->has_os_feature(p_feature); + return ProjectSettings::get_singleton()->get_resource_path(); } String OS_Unix::get_installed_templates_path() const { @@ -532,7 +531,7 @@ String OS_Unix::get_executable_path() const { return OS::get_executable_path(); } return b; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) char resolved_path[MAXPATHLEN]; realpath(OS::get_executable_path().utf8().get_data(), resolved_path); diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 67eb5cefdf..fdc6d6e28f 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -85,7 +85,7 @@ public: virtual Error open_dynamic_library(const String p_path, void *&p_library_handle); virtual Error close_dynamic_library(void *p_library_handle); - virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle); + virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false); virtual Error set_cwd(const String &p_cwd); @@ -117,8 +117,6 @@ public: virtual String get_executable_path() const; virtual String get_data_dir() const; - virtual bool check_feature_support(const String &p_feature); - //virtual void run( MainLoop * p_main_loop ); }; diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 23ba177824..a1ca2c678e 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "audio_driver_xaudio2.h" -#include "global_config.h" #include "os/os.h" +#include "project_settings.h" const char *AudioDriverXAudio2::get_name() const { return "XAudio2"; |