diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/dummy/rasterizer_dummy.h | 1 | ||||
| -rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.cpp | 28 | ||||
| -rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 116 | ||||
| -rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.h | 18 | ||||
| -rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 36 | ||||
| -rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 5 | ||||
| -rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 25 | ||||
| -rw-r--r-- | drivers/gles2/shader_gles2.h | 2 | ||||
| -rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 5 | ||||
| -rw-r--r-- | drivers/gles2/shaders/scene.glsl | 54 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 19 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 44 | ||||
| -rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 2 | ||||
| -rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 14 | ||||
| -rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 5 | ||||
| -rw-r--r-- | drivers/gles3/shaders/cubemap_filter.glsl | 2 | ||||
| -rw-r--r-- | drivers/gles3/shaders/scene.glsl | 59 | ||||
| -rw-r--r-- | drivers/gles3/shaders/ssao.glsl | 6 | ||||
| -rw-r--r-- | drivers/windows/file_access_windows.cpp | 4 |
19 files changed, 330 insertions, 115 deletions
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 3b31da1dd7..253936ca34 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -692,6 +692,7 @@ public: /* RENDER TARGET */ RID render_target_create() { return RID(); } + void render_target_set_position(RID p_render_target, int p_x, int p_y) {} void render_target_set_size(RID p_render_target, int p_width, int p_height) {} RID render_target_get_texture(RID p_render_target) const { return RID(); } void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {} diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 7232d2d95a..b82186162d 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -113,9 +113,22 @@ void RasterizerCanvasGLES2::canvas_begin() { state.canvas_shader.bind(); state.using_transparent_rt = false; + int viewport_x, viewport_y, viewport_width, viewport_height; + if (storage->frame.current_rt) { glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); state.using_transparent_rt = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]; + + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { + // set Viewport and Scissor when rendering directly to screen + viewport_width = storage->frame.current_rt->width; + viewport_height = storage->frame.current_rt->height; + viewport_x = storage->frame.current_rt->x; + viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y; + glScissor(viewport_x, viewport_y, viewport_width, viewport_height); + glViewport(viewport_x, viewport_y, viewport_width, viewport_height); + glEnable(GL_SCISSOR_TEST); + } } if (storage->frame.clear_request) { @@ -179,6 +192,14 @@ void RasterizerCanvasGLES2::canvas_end() { glDisableVertexAttribArray(i); } + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { + //reset viewport to full window size + int viewport_width = OS::get_singleton()->get_window_size().width; + int viewport_height = OS::get_singleton()->get_window_size().height; + glViewport(0, 0, viewport_width, viewport_height); + glScissor(0, 0, viewport_width, viewport_height); + } + state.using_texture_rect = false; state.using_skeleton = false; state.using_ninepatch = false; @@ -1060,6 +1081,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur } else { glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 3, buffer + color_ofs); } + } else { + glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, 1.0, 1.0, 1.0, 1.0); } if (multi_mesh->custom_data_floats) { @@ -1192,6 +1215,11 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) { + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { + ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen"); + return; + } + if (storage->frame.current_rt->copy_screen_effect.color == 0) { ERR_EXPLAIN("Can't use screen texture copying in a render target configured without copy buffers"); ERR_FAIL(); diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 2d9eec10d2..0231bb5837 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -1011,7 +1011,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G has_alpha = false; } - RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element(); + RenderList::Element *e = (has_alpha || p_material->shader->spatial.no_depth_test) ? render_list.add_alpha_element() : render_list.add_element(); if (!e) { return; @@ -1027,6 +1027,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G e->light_index = RenderList::MAX_LIGHTS; e->use_accum_ptr = &e->use_accum; e->instancing = (e->instance->base_type == VS::INSTANCE_MULTIMESH) ? 1 : 0; + e->front_facing = false; if (e->geometry->last_pass != render_pass) { e->geometry->last_pass = render_pass; @@ -1046,6 +1047,10 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G e->material_index = e->material->index; + if (mirror) { + e->front_facing = true; + } + e->refprobe_0_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default e->refprobe_1_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default @@ -1257,7 +1262,29 @@ static const GLenum gl_primitive[] = { GL_TRIANGLE_FAN }; -bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size) { +void RasterizerSceneGLES2::_set_cull(bool p_front, bool p_disabled, bool p_reverse_cull) { + + bool front = p_front; + if (p_reverse_cull) + front = !front; + + if (p_disabled != state.cull_disabled) { + if (p_disabled) + glDisable(GL_CULL_FACE); + else + glEnable(GL_CULL_FACE); + + state.cull_disabled = p_disabled; + } + + if (front != state.cull_front) { + + glCullFace(front ? GL_FRONT : GL_BACK); + state.cull_front = front; + } +} + +bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size) { // material parameters @@ -1295,21 +1322,6 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m } break; } - switch (p_material->shader->spatial.cull_mode) { - case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED: { - glDisable(GL_CULL_FACE); - } break; - - case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_BACK: { - glEnable(GL_CULL_FACE); - glCullFace(p_reverse_cull ? GL_FRONT : GL_BACK); - } break; - case RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_FRONT: { - glEnable(GL_CULL_FACE); - glCullFace(p_reverse_cull ? GL_BACK : GL_FRONT); - } break; - } - int tc = p_material->textures.size(); const Pair<StringName, RID> *textures = p_material->textures.ptr(); @@ -2202,6 +2214,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int prev_blend_mode = -2; //will always catch the first go + state.cull_front = false; + state.cull_disabled = false; + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + if (p_alpha_pass) { glEnable(GL_BLEND); } else { @@ -2244,7 +2261,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, bool rebind_reflection = false; bool rebind_lightmap = false; - if (!p_shadow) { + if (!p_shadow && material->shader) { bool unshaded = material->shader->spatial.unshaded; @@ -2264,7 +2281,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, bool depth_prepass = false; - if (!p_alpha_pass && material->shader && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + if (!p_alpha_pass && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { depth_prepass = true; } @@ -2441,12 +2458,14 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, if (rebind || material != prev_material) { storage->info.render.material_switch_count++; - shader_rebind = _setup_material(material, p_reverse_cull, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0)); + shader_rebind = _setup_material(material, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0)); if (shader_rebind) { storage->info.render.shader_rebind_count++; } } + _set_cull(e->front_facing, material->shader->spatial.cull_mode == RasterizerStorageGLES2::Shader::Spatial::CULL_MODE_DISABLED, p_reverse_cull); + if (i == 0 || shader_rebind) { //first time must rebind if (p_shadow) { @@ -2695,6 +2714,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const Environment *env = NULL; int viewport_width, viewport_height; + int viewport_x = 0; + int viewport_y = 0; bool probe_interior = false; bool reverse_cull = false; @@ -2734,6 +2755,13 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const viewport_width = storage->frame.current_rt->width; viewport_height = storage->frame.current_rt->height; + viewport_x = storage->frame.current_rt->x; + + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { + viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y; + } else { + viewport_y = storage->frame.current_rt->y; + } } state.used_screen_texture = false; @@ -2799,7 +2827,13 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const // other stuff glBindFramebuffer(GL_FRAMEBUFFER, current_fb); - glViewport(0, 0, viewport_width, viewport_height); + glViewport(viewport_x, viewport_y, viewport_width, viewport_height); + + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { + + glScissor(viewport_x, viewport_y, viewport_width, viewport_height); + glEnable(GL_SCISSOR_TEST); + } glDepthFunc(GL_LEQUAL); glDepthMask(GL_TRUE); @@ -2834,6 +2868,10 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) { + glDisable(GL_SCISSOR_TEST); + } + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); glBlendEquation(GL_FUNC_ADD); @@ -2860,13 +2898,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const } } - if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) { - - if (sky && sky->panorama.is_valid()) { - _draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation); - } - } - if (probe_interior) { env_radiance_tex = 0; //do not use radiance texture on interiors state.default_ambient = Color(0, 0, 0, 1); //black as default ambient for interior @@ -2877,10 +2908,18 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const render_list.sort_by_key(false); _render_render_list(render_list.elements, render_list.element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, false, false); + // then draw the sky after + if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) { + + if (sky && sky->panorama.is_valid()) { + _draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation); + } + } + if (storage->frame.current_rt && state.used_screen_texture) { //copy screen texture - if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) { + if (storage->frame.current_rt->multisample_active) { // Resolve framebuffer to front buffer before copying #ifdef GLES_OVER_GL @@ -2892,14 +2931,16 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); #elif IPHONE_ENABLED + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo); glResolveMultisampleFramebufferAPPLE(); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -#else - // In GLES2 Blit is not available, so just copy color texture manually +#elif ANDROID_ENABLED + + // In GLES2 AndroidBlit is not available, so just copy color texture manually _copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color); #endif } @@ -2933,8 +2974,17 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -#else - // In GLES2 Blit is not available, so just copy color texture manually +#elif IPHONE_ENABLED + + glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo); + glResolveMultisampleFramebufferAPPLE(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +#elif ANDROID_ENABLED + + // In GLES2 Android Blit is not available, so just copy color texture manually _copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color); #endif } diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index d805984dca..d5a691d0b9 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -198,14 +198,15 @@ public: int directional_light_count; int reflection_probe_count; - bool cull_front; - bool cull_disabled; bool used_sss; bool using_contact_shadows; VS::ViewportDebugDraw debug_draw; */ + bool cull_front; + bool cull_disabled; + bool used_screen_texture; bool shadow_is_dual_parabolloid; float dual_parbolloid_direction; @@ -503,8 +504,7 @@ public: enum { MAX_LIGHTS = 255, MAX_REFLECTION_PROBES = 255, - DEFAULT_MAX_ELEMENTS = 65536, - SORT_KEY_PRIORITY_SHIFT = 56 + DEFAULT_MAX_ELEMENTS = 65536 }; int max_elements; @@ -518,6 +518,7 @@ public: bool use_accum; //is this an add pass for multipass bool *use_accum_ptr; + bool front_facing; union { //TODO: should be endian swapped on big endian @@ -603,12 +604,10 @@ public: struct SortByReverseDepthAndPriority { _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT); - uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT); - if (layer_A == layer_B) { + if (A->priority == B->priority) { return A->instance->depth > B->instance->depth; } else { - return layer_A < layer_B; + return A->priority < B->priority; } } }; @@ -687,7 +686,8 @@ public: void _draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy, const Basis &p_sky_orientation); - _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0)); + _FORCE_INLINE_ void _set_cull(bool p_front, bool p_disabled, bool p_reverse_cull); + _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0)); _FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton); _FORCE_INLINE_ void _setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas); _FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform); diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index d709056709..7b5f193b2b 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -91,7 +91,7 @@ GLuint RasterizerStorageGLES2::system_fbo = 0; //void *glRenderbufferStorageMultisampleAPPLE; //void *glResolveMultisampleFramebufferAPPLE; #define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE -#else +#elif ANDROID_ENABLED #include <GLES2/gl2ext.h> PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; @@ -4568,9 +4568,16 @@ void RasterizerStorageGLES2::instance_remove_dependency(RID p_base, RasterizerSc void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { + // do not allocate a render target with no size if (rt->width <= 0 || rt->height <= 0) return; + // do not allocate a render target that is attached to the screen + if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + rt->fbo = RasterizerStorageGLES2::system_fbo; + return; + } + GLuint color_internal_format; GLuint color_format; GLuint color_type = GL_UNSIGNED_BYTE; @@ -4712,7 +4719,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); -#else +#elif ANDROID_ENABLED // Render to a texture in android glGenTextures(1, &rt->multisample_color); glBindTexture(GL_TEXTURE_2D, rt->multisample_color); @@ -4779,6 +4786,10 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) { + // there is nothing to clear when DIRECT_TO_SCREEN is used + if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) + return; + if (rt->fbo) { glDeleteFramebuffers(1, &rt->fbo); glDeleteTextures(1, &rt->color); @@ -4873,6 +4884,15 @@ RID RasterizerStorageGLES2::render_target_create() { return render_target_owner.make_rid(rt); } +void RasterizerStorageGLES2::render_target_set_position(RID p_render_target, int p_x, int p_y) { + + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + rt->x = p_x; + rt->y = p_y; +} + void RasterizerStorageGLES2::render_target_set_size(RID p_render_target, int p_width, int p_height) { RenderTarget *rt = render_target_owner.getornull(p_render_target); @@ -5002,6 +5022,14 @@ void RasterizerStorageGLES2::render_target_set_flag(RID p_render_target, RenderT RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); + // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as + // those functions change how they operate depending on the value of DIRECT_TO_SCREEN + if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + _render_target_clear(rt); + rt->flags[p_flag] = p_value; + _render_target_allocate(rt); + } + rt->flags[p_flag] = p_value; switch (p_flag) { @@ -5574,11 +5602,11 @@ void RasterizerStorageGLES2::initialize() { //Manually load extensions for android and ios #ifdef IPHONE_ENABLED - + // appears that IPhone doesn't need to dlopen TODO: test this rigorously before removing //void *gles2_lib = dlopen(NULL, RTLD_LAZY); //glRenderbufferStorageMultisampleAPPLE = dlsym(gles2_lib, "glRenderbufferStorageMultisampleAPPLE"); //glResolveMultisampleFramebufferAPPLE = dlsym(gles2_lib, "glResolveMultisampleFramebufferAPPLE"); -#else +#elif ANDROID_ENABLED void *gles2_lib = dlopen("libGLESv2.so", RTLD_LAZY); glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glRenderbufferStorageMultisampleEXT"); diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 3134082e2a..af57aa3d9b 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -1175,7 +1175,7 @@ public: } } external; - int width, height; + int x, y, width, height; bool flags[RENDER_TARGET_FLAG_MAX]; @@ -1192,6 +1192,8 @@ public: multisample_color(0), multisample_depth(0), multisample_active(false), + x(0), + y(0), width(0), height(0), used_in_frame(false), @@ -1209,6 +1211,7 @@ public: void _render_target_allocate(RenderTarget *rt); virtual RID render_target_create(); + virtual void render_target_set_position(RID p_render_target, int p_x, int p_y); virtual void render_target_set_size(RID p_render_target, int p_width, int p_height); virtual RID render_target_get_texture(RID p_render_target) const; virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index d00b03fb8a..b48b93944c 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -316,9 +316,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) { StringBuffer<> uniform_code; - uniform_code += "uniform "; + // use highp if no precision is specified to prevent different default values in fragment and vertex shader + SL::DataPrecision precision = E->get().precision; + if (precision == SL::PRECISION_DEFAULT) { + precision = SL::PRECISION_HIGHP; + } - uniform_code += _prestr(E->get().precision); + uniform_code += "uniform "; + uniform_code += _prestr(precision); uniform_code += _typestr(E->get().type); uniform_code += " "; uniform_code += _mkid(E->key()); @@ -356,6 +361,21 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener fragment_global += final_code; } + // constants + + for (Map<StringName, SL::ShaderNode::Constant>::Element *E = snode->constants.front(); E; E = E->next()) { + String gcode; + gcode += "const "; + gcode += _prestr(E->get().precision); + gcode += _typestr(E->get().type); + gcode += " " + _mkid(E->key()); + gcode += "="; + gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + gcode += ";\n"; + vertex_global += gcode; + fragment_global += gcode; + } + // functions Map<StringName, String> function_code; @@ -934,6 +954,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; // No defines for particle shaders in GLES2, there are no GPU particles diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index ebea40e10e..2456a83d35 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -1,4 +1,4 @@ -/*************************************************************************/ +/*************************************************************************/ /* shader_gles2.h */ /*************************************************************************/ /* This file is part of: */ diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 7dce784f52..0818942b0a 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -112,7 +112,12 @@ void main() { #ifdef USE_INSTANCING mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); color *= instance_color; + +#ifdef USE_INSTANCE_CUSTOM vec4 instance_custom = instance_custom_data; +#else + vec4 instance_custom = vec4(0.0); +#endif #else mat4 extra_matrix_instance = extra_matrix; diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index 0fa290e57c..2aef913ae8 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -1151,7 +1151,8 @@ void light_compute( float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, - inout vec3 specular_light) { + inout vec3 specular_light, + inout float alpha) { //this makes lights behave closer to linear, but then addition of lights looks bad //better left disabled @@ -1306,10 +1307,10 @@ LIGHT_SHADER_CODE // shlick+ggx as default #if defined(LIGHT_USE_ANISOTROPY) - float alpha = roughness * roughness; + float alpha_ggx = roughness * roughness; float aspect = sqrt(1.0 - anisotropy * 0.9); - float ax = alpha / aspect; - float ay = alpha * aspect; + float ax = alpha_ggx / aspect; + float ay = alpha_ggx * aspect; float XdotH = dot(T, H); float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH, cNdotH); @@ -1317,10 +1318,10 @@ LIGHT_SHADER_CODE float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); #else - float alpha = roughness * roughness; - float D = D_GGX(cNdotH, alpha); - //float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha); - float G = V_GGX(cNdotL, cNdotV, alpha); + float alpha_ggx = roughness * roughness; + float D = D_GGX(cNdotH, alpha_ggx); + //float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx); + float G = V_GGX(cNdotL, cNdotV, alpha_ggx); #endif // F vec3 f0 = F0(metallic, specular, diffuse_color); @@ -1350,6 +1351,10 @@ LIGHT_SHADER_CODE #endif } +#ifdef USE_SHADOW_TO_OPACITY + alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0)); +#endif + #endif //defined(USE_LIGHT_SHADER_CODE) } @@ -1535,17 +1540,21 @@ FRAGMENT_SHADER_CODE vec3 eye_position = view; +#if !defined(USE_SHADOW_TO_OPACITY) + #if defined(ALPHA_SCISSOR_USED) if (alpha < alpha_scissor) { discard; } -#endif +#endif // ALPHA_SCISSOR_USED #ifdef USE_DEPTH_PREPASS if (alpha < 0.99) { discard; } -#endif +#endif // USE_DEPTH_PREPASS + +#endif // !USE_SHADOW_TO_OPACITY #ifdef BASE_PASS //none @@ -2061,13 +2070,32 @@ FRAGMENT_SHADER_CODE clearcoat_gloss, anisotropy, diffuse_light, - specular_light); + specular_light, + alpha); #endif //vertex lighting #endif //USE_LIGHTING //compute and merge +#ifdef USE_SHADOW_TO_OPACITY + + alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); + +#if defined(ALPHA_SCISSOR_USED) + if (alpha < alpha_scissor) { + discard; + } +#endif // ALPHA_SCISSOR_USED + +#ifdef USE_DEPTH_PREPASS + if (alpha < 0.99) { + discard; + } +#endif // USE_DEPTH_PREPASS + +#endif // !USE_SHADOW_TO_OPACITY + #ifndef RENDER_DEPTH #ifdef SHADELESS @@ -2105,8 +2133,6 @@ FRAGMENT_SHADER_CODE #endif // gl_FragColor = vec4(normal, 1.0); -#endif //unshaded - //apply fog #if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED) @@ -2161,6 +2187,8 @@ FRAGMENT_SHADER_CODE #endif // defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED) +#endif //unshaded + #else // not RENDER_DEPTH //depth render #ifdef USE_RGBA_SHADOWS diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 9aec348291..7e02f2f3f5 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2374,7 +2374,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G has_alpha = false; } - RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element(); + RenderList::Element *e = (has_alpha || p_material->shader->spatial.no_depth_test) ? render_list.add_alpha_element() : render_list.add_element(); if (!e) return; @@ -3304,7 +3304,7 @@ void RasterizerSceneGLES3::_prepare_depth_texture() { void RasterizerSceneGLES3::_bind_depth_texture() { if (!state.bound_depth_texture) { - ERR_FAIL_COND(!state.prepared_depth_texture) + ERR_FAIL_COND(!state.prepared_depth_texture); //bind depth for read glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 8); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth); @@ -4552,8 +4552,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const } _post_process(env, p_cam_projection); - - if (false && shadow_atlas) { + // Needed only for debugging + /* if (shadow_atlas && storage->frame.current_rt) { //_copy_texture_to_front_buffer(shadow_atlas->depth); storage->canvas->canvas_begin(); @@ -4563,7 +4563,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const 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)); } - if (false && storage->frame.current_rt) { + if (storage->frame.current_rt) { //_copy_texture_to_front_buffer(shadow_atlas->depth); storage->canvas->canvas_begin(); @@ -4573,7 +4573,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 16, storage->frame.current_rt->height / 16), Rect2(0, 0, 1, 1)); } - if (false && reflection_atlas && storage->frame.current_rt) { + if (reflection_atlas && storage->frame.current_rt) { //_copy_texture_to_front_buffer(shadow_atlas->depth); storage->canvas->canvas_begin(); @@ -4582,7 +4582,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const 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)); } - if (false && directional_shadow.fbo) { + if (directional_shadow.fbo) { //_copy_texture_to_front_buffer(shadow_atlas->depth); storage->canvas->canvas_begin(); @@ -4592,7 +4592,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const 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)); } - if (false && env_radiance_tex) { + if ( env_radiance_tex) { //_copy_texture_to_front_buffer(shadow_atlas->depth); storage->canvas->canvas_begin(); @@ -4603,8 +4603,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const 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 } diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 661be28e6b..01b85458c2 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -3501,7 +3501,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: if (p_vertex_count < (1 << 16)) { //read 16 bit indices const uint16_t *src_idx = (const uint16_t *)ir.ptr(); - for (int i = 0; i < index_count; i += 6) { + for (int i = 0; i + 5 < index_count; i += 6) { wr[i + 0] = src_idx[i / 2]; wr[i + 1] = src_idx[i / 2 + 1]; @@ -3515,7 +3515,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: //read 16 bit indices const uint32_t *src_idx = (const uint32_t *)ir.ptr(); - for (int i = 0; i < index_count; i += 6) { + for (int i = 0; i + 5 < index_count; i += 6) { wr[i + 0] = src_idx[i / 2]; wr[i + 1] = src_idx[i / 2 + 1]; @@ -3531,7 +3531,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: index_count = p_vertex_count * 2; wf_indices.resize(index_count); PoolVector<uint32_t>::Write wr = wf_indices.write(); - for (int i = 0; i < index_count; i += 6) { + for (int i = 0; i + 5 < index_count; i += 6) { wr[i + 0] = i / 2; wr[i + 1] = i / 2 + 1; @@ -3772,28 +3772,30 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_index_array(RID p_m Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(surface->index_array_len == 0, PoolVector<uint8_t>()); - PoolVector<uint8_t> ret; ret.resize(surface->index_array_byte_size); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id); + + if (surface->index_array_byte_size > 0) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id); #if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) - { - PoolVector<uint8_t>::Write w = ret.write(); - glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr()); - } + { + PoolVector<uint8_t>::Write w = ret.write(); + glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr()); + } #else - void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT); - ERR_FAIL_NULL_V(data, PoolVector<uint8_t>()); - { - PoolVector<uint8_t>::Write w = ret.write(); - copymem(w.ptr(), data, surface->index_array_byte_size); - } - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT); + ERR_FAIL_NULL_V(data, PoolVector<uint8_t>()); + { + PoolVector<uint8_t>::Write w = ret.write(); + copymem(w.ptr(), data, surface->index_array_byte_size); + } + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); #endif - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + return ret; } @@ -7268,6 +7270,10 @@ RID RasterizerStorageGLES3::render_target_create() { return render_target_owner.make_rid(rt); } +void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) { + //only used in GLES2 +} + void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height) { RenderTarget *rt = render_target_owner.getornull(p_render_target); @@ -8154,7 +8160,7 @@ void RasterizerStorageGLES3::initialize() { } shaders.cubemap_filter.init(); - bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx.mobile"); + bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx"); shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq); shaders.particles.init(); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index a4cc84ef02..3d86558407 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -297,6 +297,7 @@ public: target(GL_TEXTURE_2D), data_size(0), compressed(false), + srgb(false), total_data_size(0), ignore_mipmaps(false), mipmaps(0), @@ -1394,6 +1395,7 @@ public: void _render_target_allocate(RenderTarget *rt); virtual RID render_target_create(); + virtual void render_target_set_position(RID p_render_target, int p_x, int p_y); virtual void render_target_set_size(RID p_render_target, int p_width, int p_height); virtual RID render_target_get_texture(RID p_render_target) const; virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index ad26294527..b0f0a71d56 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -472,6 +472,19 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.fragment_global += interp_mode + "in " + vcode; } + for (Map<StringName, SL::ShaderNode::Constant>::Element *E = pnode->constants.front(); E; E = E->next()) { + String gcode; + gcode += "const "; + gcode += _prestr(E->get().precision); + gcode += _typestr(E->get().type); + gcode += " " + _mkid(E->key()); + gcode += "="; + gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + gcode += ";\n"; + r_gen_code.vertex_global += gcode; + r_gen_code.fragment_global += gcode; + } + Map<StringName, String> function_code; //code for functions @@ -944,6 +957,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; /* PARTICLES SHADER */ diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 0d1e7ee4a1..a46b31c92e 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -117,7 +117,12 @@ void main() { #ifdef USE_INSTANCING mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); color *= instance_color; + +#ifdef USE_INSTANCE_CUSTOM vec4 instance_custom = instance_custom_data; +#else + vec4 instance_custom = vec4(0.0); +#endif #else mat4 extra_matrix_instance = extra_matrix; diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index f65f798ff0..619e29b130 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -163,7 +163,7 @@ vec2 Hammersley(uint i, uint N) { #else -#define SAMPLE_COUNT 512u +#define SAMPLE_COUNT 1024u #endif diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 584668a09c..f08d3f4d23 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -993,7 +993,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, vec3(metallic)); } -void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light, inout float alpha) { #if defined(USE_LIGHT_SHADER_CODE) // light is written by the light shader @@ -1135,19 +1135,19 @@ LIGHT_SHADER_CODE #if defined(LIGHT_USE_ANISOTROPY) - float alpha = roughness * roughness; + float alpha_ggx = roughness * roughness; float aspect = sqrt(1.0 - anisotropy * 0.9); - float ax = alpha / aspect; - float ay = alpha * aspect; + float ax = alpha_ggx / aspect; + float ay = alpha_ggx * aspect; float XdotH = dot(T, H); float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH); #else - float alpha = roughness * roughness; - float D = D_GGX(cNdotH, alpha); - float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha); + float alpha_ggx = roughness * roughness; + float D = D_GGX(cNdotH, alpha_ggx); + float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx); #endif // F vec3 f0 = F0(metallic, specular, diffuse_color); @@ -1174,6 +1174,10 @@ LIGHT_SHADER_CODE #endif } +#ifdef USE_SHADOW_TO_OPACITY + alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0)); +#endif + #endif //defined(USE_LIGHT_SHADER_CODE) } @@ -1250,7 +1254,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, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, 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, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light, inout float alpha) { vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz - vertex; float light_length = length(light_rel_vec); @@ -1304,10 +1308,10 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi light_attenuation *= mix(omni_lights[idx].shadow_color_contact.rgb, vec3(1.0), shadow); } #endif //SHADOWS_DISABLED - light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * omni_attenuation, 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, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light, alpha); } -void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, 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, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light, inout float alpha) { vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz - vertex; float light_length = length(light_rel_vec); @@ -1339,7 +1343,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi } #endif //SHADOWS_DISABLED - light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * spot_attenuation, 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, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light, alpha); } void reflection_process(int idx, vec3 vertex, vec3 normal, vec3 binormal, vec3 tangent, float roughness, float anisotropy, vec3 ambient, vec3 skybox, inout highp vec4 reflection_accum, inout highp vec4 ambient_accum) { @@ -1705,11 +1709,13 @@ FRAGMENT_SHADER_CODE /* clang-format on */ } +#if !defined(USE_SHADOW_TO_OPACITY) + #if defined(ALPHA_SCISSOR_USED) if (alpha < alpha_scissor) { discard; } -#endif +#endif // ALPHA_SCISSOR_USED #ifdef USE_OPAQUE_PREPASS @@ -1717,7 +1723,9 @@ FRAGMENT_SHADER_CODE discard; } -#endif +#endif // USE_OPAQUE_PREPASS + +#endif // !USE_SHADOW_TO_OPACITY #if defined(ENABLE_NORMALMAP) @@ -2044,7 +2052,7 @@ FRAGMENT_SHADER_CODE 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, transmission, light_params.z * specular_blob_intensity, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); + light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light, alpha); #endif #endif //#USE_LIGHT_DIRECTIONAL @@ -2057,17 +2065,36 @@ FRAGMENT_SHADER_CODE #else for (int i = 0; i < omni_light_count; i++) { - light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light); + light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light, alpha); } for (int i = 0; i < spot_light_count; i++) { - light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light); + light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light, alpha); } #endif //USE_VERTEX_LIGHTING #endif +#ifdef USE_SHADOW_TO_OPACITY + alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); + +#if defined(ALPHA_SCISSOR_USED) + if (alpha < alpha_scissor) { + discard; + } +#endif // ALPHA_SCISSOR_USED + +#ifdef USE_OPAQUE_PREPASS + + if (alpha < opaque_prepass_threshold) { + discard; + } + +#endif // USE_OPAQUE_PREPASS + +#endif // USE_SHADOW_TO_OPACITY + #ifdef RENDER_DEPTH //nothing happens, so a tree-ssa optimizer will result in no fragment shader :) #else diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl index be44365169..d9cdc3fc1f 100644 --- a/drivers/gles3/shaders/ssao.glsl +++ b/drivers/gles3/shaders/ssao.glsl @@ -16,15 +16,15 @@ void main() { #define TWO_PI 6.283185307179586476925286766559 #ifdef SSAO_QUALITY_HIGH -#define NUM_SAMPLES (80) +#define NUM_SAMPLES (16) #endif #ifdef SSAO_QUALITY_LOW -#define NUM_SAMPLES (15) +#define NUM_SAMPLES (8) #endif #if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH) -#define NUM_SAMPLES (40) +#define NUM_SAMPLES (12) #endif // If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index c13300d09f..31360d319f 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -340,13 +340,11 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) { } uint32_t FileAccessWindows::_get_unix_permissions(const String &p_file) { - ERR_PRINT("Windows does not support unix permissions"); return 0; } Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { - ERR_PRINT("Windows does not support unix permissions"); - return FAILED; + return ERR_UNAVAILABLE; } FileAccessWindows::FileAccessWindows() : |