diff options
Diffstat (limited to 'drivers/gles3')
27 files changed, 2480 insertions, 2239 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index bb4c8ab4d7..da87a71679 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -211,6 +211,10 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con } else { + if (texture->redraw_if_visible) { //check before proxy, because this is usually used with proxies + VisualServerRaster::redraw_request(); + } + texture = texture->get_ptr(); if (texture->render_target) @@ -248,6 +252,10 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con } else { + if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies + VisualServerRaster::redraw_request(); + } + normal_map = normal_map->get_ptr(); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); @@ -824,6 +832,120 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur } } } break; + case Item::Command::TYPE_MULTIMESH: { + + Item::CommandMultiMesh *mmesh = static_cast<Item::CommandMultiMesh *>(c); + + RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.getornull(mmesh->multimesh); + + if (!multi_mesh) + break; + + RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(multi_mesh->mesh); + + if (!mesh_data) + break; + + RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mmesh->texture, mmesh->normal_map); + + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, multi_mesh->custom_data_format != VS::MULTIMESH_CUSTOM_DATA_NONE); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true); + //reset shader and force rebind + state.using_texture_rect = true; + _set_texture_rect_mode(false); + + if (texture) { + Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); + state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size); + } + + int amount = MAX(multi_mesh->size, multi_mesh->visible_instances); + + for (int j = 0; j < mesh_data->surfaces.size(); j++) { + RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j]; + // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing + glBindVertexArray(s->instancing_array_id); + + glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer + + int stride = (multi_mesh->xform_floats + multi_mesh->color_floats + multi_mesh->custom_data_floats) * 4; + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0); + glVertexAttribDivisor(8, 1); + glEnableVertexAttribArray(9); + glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 4 * 4); + glVertexAttribDivisor(9, 1); + + int color_ofs; + + if (multi_mesh->transform_format == VS::MULTIMESH_TRANSFORM_3D) { + glEnableVertexAttribArray(10); + glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 8 * 4); + glVertexAttribDivisor(10, 1); + color_ofs = 12 * 4; + } else { + glDisableVertexAttribArray(10); + glVertexAttrib4f(10, 0, 0, 1, 0); + color_ofs = 8 * 4; + } + + int custom_data_ofs = color_ofs; + + switch (multi_mesh->color_format) { + + case VS::MULTIMESH_COLOR_NONE: { + glDisableVertexAttribArray(11); + glVertexAttrib4f(11, 1, 1, 1, 1); + } break; + case VS::MULTIMESH_COLOR_8BIT: { + glEnableVertexAttribArray(11); + glVertexAttribPointer(11, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + color_ofs); + glVertexAttribDivisor(11, 1); + custom_data_ofs += 4; + + } break; + case VS::MULTIMESH_COLOR_FLOAT: { + glEnableVertexAttribArray(11); + glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + color_ofs); + glVertexAttribDivisor(11, 1); + custom_data_ofs += 4 * 4; + } break; + } + + switch (multi_mesh->custom_data_format) { + + case VS::MULTIMESH_CUSTOM_DATA_NONE: { + glDisableVertexAttribArray(12); + glVertexAttrib4f(12, 1, 1, 1, 1); + } break; + case VS::MULTIMESH_CUSTOM_DATA_8BIT: { + glEnableVertexAttribArray(12); + glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + custom_data_ofs); + glVertexAttribDivisor(12, 1); + + } break; + case VS::MULTIMESH_CUSTOM_DATA_FLOAT: { + glEnableVertexAttribArray(12); + glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + custom_data_ofs); + glVertexAttribDivisor(12, 1); + } break; + } + + if (s->index_array_len) { + glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount); + } else { + glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount); + } + + glBindVertexArray(0); + } + + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false); + state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false); + state.using_texture_rect = true; + _set_texture_rect_mode(false); + + } break; case Item::Command::TYPE_PARTICLES: { Item::CommandParticles *particles_cmd = static_cast<Item::CommandParticles *>(c); @@ -832,6 +954,9 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur if (!particles) break; + if (particles->inactive && !particles->emitting) + break; + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); //not used, so keep white VisualServerRaster::redraw_request(); @@ -997,13 +1122,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur glEnable(GL_SCISSOR_TEST); //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); - - int x = current_clip->final_clip_rect.position.x; int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); - int w = current_clip->final_clip_rect.size.x; - int h = current_clip->final_clip_rect.size.y; + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; - glScissor(x, y, w, h); + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y); reclip = false; } @@ -1138,7 +1261,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons if (current_clip) { glEnable(GL_SCISSOR_TEST); - glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y); } else { @@ -1160,8 +1287,8 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons { //skeleton handling - if (ci->skeleton.is_valid()) { - skeleton = storage->skeleton_owner.getornull(ci->skeleton); + if (ci->skeleton.is_valid() && storage->skeleton_owner.owns(ci->skeleton)) { + skeleton = storage->skeleton_owner.get(ci->skeleton); if (!skeleton->use_2d) { skeleton = NULL; } else { @@ -1261,6 +1388,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons continue; } + if (t->redraw_if_visible) { //check before proxy, because this is usually used with proxies + VisualServerRaster::redraw_request(); + } + t = t->get_ptr(); if (storage->config.srgb_decode_supported && t->using_srgb) { @@ -1515,7 +1646,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons if (reclip) { glEnable(GL_SCISSOR_TEST); - glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) + y = current_clip->final_clip_rect.position.y; + glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); } p_item_list = p_item_list->next; @@ -1537,17 +1671,12 @@ void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_s int ofs = h; glDisable(GL_BLEND); - //print_line(" debug lights "); while (light) { - - //print_line("debug light"); if (light->shadow_buffer.is_valid()) { - //print_line("sb is valid"); RasterizerStorageGLES3::CanvasLightShadow *sb = storage->canvas_light_shadow_owner.get(light->shadow_buffer); if (sb) { glBindTexture(GL_TEXTURE_2D, sb->distance); - //glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex); draw_generic_textured_rect(Rect2(h, ofs, w - h * 2, h), Rect2(0, 0, 1, 1)); ofs += h * 2; } @@ -1657,19 +1786,7 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons } break; } } - /* - if (i==0) { - for(int i=0;i<cc->lines.size();i++) { - Vector2 p = instance->xform_cache.xform(cc->lines.get(i)); - Plane pp(Vector3(p.x,p.y,0),1); - pp.normal = light.xform(pp.normal); - pp = projection.xform4(pp); - print_line(itos(i)+": "+pp.normal/pp.d); - //pp=light_mat.xform4(pp); - //print_line(itos(i)+": "+pp.normal/pp.d); - } - } -*/ + glBindVertexArray(cc->array_id); glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0); @@ -1875,7 +1992,7 @@ void RasterizerCanvasGLES3::initialize() { } { - uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128); + uint32_t poly_size = GLOBAL_DEF_RST("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); @@ -1922,7 +2039,7 @@ void RasterizerCanvasGLES3::initialize() { glGenVertexArrays(1, &data.polygon_buffer_pointer_array); - uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128); + uint32_t index_size = GLOBAL_DEF_RST("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_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 1abdaa5f80..e4824695d5 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -33,7 +33,9 @@ #include "gl_context/context_gl.h" #include "os/os.h" #include "project_settings.h" + #include <string.h> + RasterizerStorage *RasterizerGLES3::get_storage() { return storage; @@ -134,30 +136,32 @@ typedef void (*DEBUGPROCARB)(GLenum source, typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam); -void RasterizerGLES3::initialize() { - - if (OS::get_singleton()->is_stdout_verbose()) { - print_line("Using GLES3 video driver"); - } +Error RasterizerGLES3::is_viable() { #ifdef GLAD_ENABLED if (!gladLoadGL()) { ERR_PRINT("Error initializing GLAD"); + return ERR_UNAVAILABLE; } // GLVersion seems to be used for both GL and GL ES, so we need different version checks for them #ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required - if (GLVersion.major < 3 && GLVersion.minor < 3) { + if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 3)) { #else // OpenGL ES 3.0 if (GLVersion.major < 3) { #endif - ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n" - "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); - OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n" - "Godot Engine will self-destruct as soon as you acknowledge this error message.", - "Fatal error: Insufficient OpenGL / GLES driver support"); + return ERR_UNAVAILABLE; } +#endif // GLAD_ENABLED + return OK; +} + +void RasterizerGLES3::initialize() { + + print_verbose("Using GLES3 video driver"); + +#ifdef GLAD_ENABLED if (OS::get_singleton()->is_stdout_verbose()) { if (GLAD_GL_ARB_debug_output) { glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); @@ -167,7 +171,6 @@ void RasterizerGLES3::initialize() { print_line("OpenGL debugging not supported!"); } } - #endif // GLAD_ENABLED /* // For debugging @@ -192,22 +195,15 @@ void RasterizerGLES3::initialize() { scene->initialize(); } -void RasterizerGLES3::begin_frame() { - - uint64_t tick = OS::get_singleton()->get_ticks_usec(); +void RasterizerGLES3::begin_frame(double frame_step) { - double delta = double(tick - prev_ticks) / 1000000.0; - delta *= Engine::get_singleton()->get_time_scale(); + time_total += frame_step; - time_total += delta; - - if (delta == 0) { + if (frame_step == 0) { //to avoid hiccups - delta = 0.001; + frame_step = 0.001; } - prev_ticks = tick; - double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); if (time_total > time_roll_over) time_total = 0; //roll over every day (should be customz @@ -217,9 +213,7 @@ void RasterizerGLES3::begin_frame() { storage->frame.time[2] = Math::fmod(time_total, 900); storage->frame.time[3] = Math::fmod(time_total, 60); storage->frame.count++; - storage->frame.delta = delta; - - storage->frame.prev_tick = tick; + storage->frame.delta = frame_step; storage->update_dirty_resources(); @@ -234,7 +228,7 @@ void RasterizerGLES3::set_current_render_target(RID p_render_target) { if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) { //handle pending clear request, if the framebuffer was not cleared glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); - print_line("unbind clear of: " + storage->frame.clear_request_color); + glClearColor( storage->frame.clear_request_color.r, storage->frame.clear_request_color.g, @@ -281,7 +275,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c if (p_image.is_null() || p_image->empty()) return; - begin_frame(); + begin_frame(0.0); int window_w = OS::get_singleton()->get_video_mode(0).width; int window_h = OS::get_singleton()->get_video_mode(0).height; @@ -299,7 +293,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c canvas->canvas_begin(); RID texture = storage->texture_create(); - storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), VS::TEXTURE_FLAG_FILTER); + storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER); storage->texture_set_data(texture, p_image); Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); @@ -333,28 +327,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c storage->free(texture); // free since it's only one frame that stays there - if (OS::get_singleton()->is_layered_allowed()) { - if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { -#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED) - Size2 wndsize = OS::get_singleton()->get_layered_buffer_size(); - uint8_t *data = OS::get_singleton()->get_layered_buffer_data(); - if (data) { - glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data); - OS::get_singleton()->swap_layered_buffer(); - - return; - } -#endif - } else { - //clear alpha - glColorMask(false, false, false, true); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - glColorMask(true, true, true, true); - } - } - - OS::get_singleton()->swap_buffers(); + end_frame(true); } void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen) { @@ -451,7 +424,6 @@ RasterizerGLES3::RasterizerGLES3() { scene->storage = storage; storage->scene = scene; - prev_ticks = 0; time_total = 0; } diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index 5213101778..0a264caf8f 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -44,7 +44,6 @@ class RasterizerGLES3 : public Rasterizer { RasterizerCanvasGLES3 *canvas; RasterizerSceneGLES3 *scene; - uint64_t prev_ticks; double time_total; public: @@ -55,7 +54,7 @@ public: virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale); virtual void initialize(); - virtual void begin_frame(); + virtual void begin_frame(double frame_step); virtual void set_current_render_target(RID p_render_target); virtual void restore_render_target(); virtual void clear_render_target(const Color &p_color); @@ -63,9 +62,10 @@ public: virtual void end_frame(bool p_swap_buffers); virtual void finalize(); + static Error is_viable(); static void make_current(); - static void register_config(); + RasterizerGLES3(); ~RasterizerGLES3(); }; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 03ff84c093..88f14890ef 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -355,7 +355,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in bool should_redraw = shadow_atlas->quadrants[q].shadows[s].version != p_light_version; if (!should_realloc) { - shadow_atlas->quadrants[q].shadows[s].version = p_light_version; + shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version; //already existing, see if it should redraw or it's just OK return should_redraw; } @@ -365,7 +365,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in //find a better place if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, shadow_atlas->quadrants[q].subdivision, tick, new_quadrant, new_shadow)) { //found a better place! - ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows[new_shadow]; + ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; if (sh->owner.is_valid()) { //is taken, but is invalid, erasing it shadow_atlas->shadow_owners.erase(sh->owner); @@ -374,8 +374,8 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in } //erase previous - shadow_atlas->quadrants[q].shadows[s].version = 0; - shadow_atlas->quadrants[q].shadows[s].owner = RID(); + shadow_atlas->quadrants[q].shadows.write[s].version = 0; + shadow_atlas->quadrants[q].shadows.write[s].owner = RID(); sh->owner = p_light_intance; sh->alloc_tick = tick; @@ -395,7 +395,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in //already existing, see if it should redraw or it's just OK - shadow_atlas->quadrants[q].shadows[s].version = p_light_version; + shadow_atlas->quadrants[q].shadows.write[s].version = p_light_version; return should_redraw; } @@ -405,7 +405,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in //find a better place if (_shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, -1, tick, new_quadrant, new_shadow)) { //found a better place! - ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows[new_shadow]; + ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow]; if (sh->owner.is_valid()) { //is taken, but is invalid, erasing it shadow_atlas->shadow_owners.erase(sh->owner); @@ -502,7 +502,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size //erase probes reference to this if (reflection_atlas->reflections[i].owner.is_valid()) { ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner); - reflection_atlas->reflections[i].owner = RID(); + reflection_atlas->reflections.write[i].owner = RID(); ERR_CONTINUE(!reflection_probe_instance); reflection_probe_instance->reflection_atlas_index = -1; @@ -574,7 +574,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int //erase probes reference to this if (reflection_atlas->reflections[i].owner.is_valid()) { ReflectionProbeInstance *reflection_probe_instance = reflection_probe_instance_owner.getornull(reflection_atlas->reflections[i].owner); - reflection_atlas->reflections[i].owner = RID(); + reflection_atlas->reflections.write[i].owner = RID(); ERR_CONTINUE(!reflection_probe_instance); reflection_probe_instance->reflection_atlas_index = -1; @@ -629,7 +629,7 @@ void RasterizerSceneGLES3::reflection_probe_release_atlas_index(RID p_instance) ERR_FAIL_COND(reflection_atlas->reflections[rpi->reflection_atlas_index].owner != rpi->self); - reflection_atlas->reflections[rpi->reflection_atlas_index].owner = RID(); + reflection_atlas->reflections.write[rpi->reflection_atlas_index].owner = RID(); rpi->reflection_atlas_index = -1; rpi->atlas = RID(); @@ -701,8 +701,8 @@ bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance victim_rpi->reflection_atlas_index = -1; } - reflection_atlas->reflections[best_free].owner = p_instance; - reflection_atlas->reflections[best_free].last_frame = storage->frame.count; + reflection_atlas->reflections.write[best_free].owner = p_instance; + reflection_atlas->reflections.write[best_free].last_frame = storage->frame.count; rpi->reflection_atlas_index = best_free; rpi->atlas = p_reflection_atlas; @@ -896,7 +896,7 @@ void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_m env->ssr_roughness = p_roughness; } -void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { +void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -908,6 +908,7 @@ void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float env->ssao_intensity2 = p_intensity2; env->ssao_bias = p_bias; env->ssao_light_affect = p_light_affect; + env->ssao_ao_channel_affect = p_ao_channel_affect; env->ssao_color = p_color; env->ssao_filter = p_blur; env->ssao_quality = p_quality; @@ -1007,7 +1008,10 @@ RID RasterizerSceneGLES3::light_instance_create(RID p_light) { light_instance->light = p_light; light_instance->light_ptr = storage->light_owner.getornull(p_light); - ERR_FAIL_COND_V(!light_instance->light_ptr, RID()); + if (!light_instance->light_ptr) { + memdelete(light_instance); + ERR_FAIL_COND_V(!light_instance->light_ptr, RID()); + } light_instance->self = light_instance_owner.make_rid(light_instance); @@ -1189,6 +1193,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m int tc = p_material->textures.size(); RID *textures = p_material->textures.ptrw(); ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw(); + const ShaderLanguage::DataType *texture_types = p_material->shader->texture_types.ptr(); state.current_main_tex = 0; @@ -1197,33 +1202,16 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m glActiveTexture(GL_TEXTURE0 + i); GLenum target; - GLuint tex; - - RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull(textures[i]); + GLuint tex = 0; - if (!t) { - //check hints - target = GL_TEXTURE_2D; + RasterizerStorageGLES3::Texture *t = storage->texture_owner.getptr(textures[i]); - switch (texture_hints[i]) { - case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: - case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { - tex = storage->resources.black_tex; - } break; - case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: { - tex = storage->resources.aniso_tex; - } break; - case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { - tex = storage->resources.normal_tex; + if (t) { - } break; - default: { - tex = storage->resources.white_tex; - } break; + if (t->redraw_if_visible) { //must check before proxy because this is often used with proxies + VisualServerRaster::redraw_request(); } - } else { - t = t->get_ptr(); //resolve for proxies #ifdef TOOLS_ENABLED if (t->detect_3d) { @@ -1241,6 +1229,59 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m target = t->target; tex = t->tex_id; + } else { + + switch (texture_types[i]) { + case ShaderLanguage::TYPE_ISAMPLER2D: + case ShaderLanguage::TYPE_USAMPLER2D: + case ShaderLanguage::TYPE_SAMPLER2D: { + target = GL_TEXTURE_2D; + + switch (texture_hints[i]) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { + tex = storage->resources.black_tex; + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: { + tex = storage->resources.aniso_tex; + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { + tex = storage->resources.normal_tex; + + } break; + default: { + tex = storage->resources.white_tex; + } break; + } + + } break; + + case ShaderLanguage::TYPE_SAMPLERCUBE: { + // TODO + } break; + + case ShaderLanguage::TYPE_ISAMPLER3D: + case ShaderLanguage::TYPE_USAMPLER3D: + case ShaderLanguage::TYPE_SAMPLER3D: { + + target = GL_TEXTURE_3D; + + switch (texture_hints[i]) { + + // TODO + default: { + tex = storage->resources.white_tex_3d; + } break; + } + + } break; + + case ShaderLanguage::TYPE_ISAMPLER2DARRAY: + case ShaderLanguage::TYPE_USAMPLER2DARRAY: + case ShaderLanguage::TYPE_SAMPLER2DARRAY: { + // TODO + } break; + } } glBindTexture(target, tex); @@ -1335,7 +1376,7 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer - int stride = (multi_mesh->xform_floats + multi_mesh->color_floats) * 4; + int stride = (multi_mesh->xform_floats + multi_mesh->color_floats + multi_mesh->custom_data_floats) * 4; glEnableVertexAttribArray(8); glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + 0); glVertexAttribDivisor(8, 1); @@ -1356,6 +1397,8 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo color_ofs = 8 * 4; } + int custom_data_ofs = color_ofs; + switch (multi_mesh->color_format) { case VS::MULTIMESH_COLOR_NONE: { @@ -1366,12 +1409,33 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo glEnableVertexAttribArray(11); glVertexAttribPointer(11, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + color_ofs); glVertexAttribDivisor(11, 1); + custom_data_ofs += 4; } break; case VS::MULTIMESH_COLOR_FLOAT: { glEnableVertexAttribArray(11); glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + color_ofs); glVertexAttribDivisor(11, 1); + custom_data_ofs += 4 * 4; + } break; + } + + switch (multi_mesh->custom_data_format) { + + case VS::MULTIMESH_CUSTOM_DATA_NONE: { + glDisableVertexAttribArray(12); + glVertexAttrib4f(12, 1, 1, 1, 1); + } break; + case VS::MULTIMESH_CUSTOM_DATA_8BIT: { + glEnableVertexAttribArray(12); + glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, ((uint8_t *)NULL) + custom_data_ofs); + glVertexAttribDivisor(12, 1); + + } break; + case VS::MULTIMESH_CUSTOM_DATA_FLOAT: { + glEnableVertexAttribArray(12); + glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + custom_data_ofs); + glVertexAttribDivisor(12, 1); } break; } @@ -1545,6 +1609,11 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) { RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(c.texture); t = t->get_ptr(); //resolve for proxies + + if (t->redraw_if_visible) { + VisualServerRaster::redraw_request(); + } + #ifdef TOOLS_ENABLED if (t->detect_3d) { t->detect_3d(t->detect_3d_ud); @@ -2507,6 +2576,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr state.env_radiance_data.ambient_contribution = env->ambient_sky_contribution; state.ubo_data.ambient_occlusion_affect_light = env->ssao_light_affect; + state.ubo_data.ambient_occlusion_affect_ssao = env->ssao_ao_channel_affect; //fog @@ -3813,8 +3883,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.exposure_shader.set_conditional(ExposureShaderGLES3::EXPOSURE_END, false); //last step, swap with the framebuffer exposure, so the right exposure is kept int he framebuffer - SWAP(exposure_shrink[exposure_shrink.size() - 1].fbo, storage->frame.current_rt->exposure.fbo); - SWAP(exposure_shrink[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color); + SWAP(exposure_shrink.write[exposure_shrink.size() - 1].fbo, storage->frame.current_rt->exposure.fbo); + SWAP(exposure_shrink.write[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color); glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); @@ -4051,6 +4121,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const state.ubo_data.z_slope_scale = 0; state.ubo_data.shadow_dual_paraboloid_render_side = 0; state.ubo_data.shadow_dual_paraboloid_render_zfar = 0; + state.ubo_data.opaque_prepass_threshold = 0.99; p_cam_projection.get_viewport_size(state.ubo_data.viewport_size[0], state.ubo_data.viewport_size[1]); @@ -4663,6 +4734,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_ state.ubo_data.z_slope_scale = normal_bias; state.ubo_data.shadow_dual_paraboloid_render_side = dp_direction; state.ubo_data.shadow_dual_paraboloid_render_zfar = zfar; + state.ubo_data.opaque_prepass_threshold = 0.1; _setup_environment(NULL, light_projection, light_transform); @@ -4741,7 +4813,7 @@ bool RasterizerSceneGLES3::free(RID p_rid) { uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; uint32_t s = key & ShadowAtlas::SHADOW_INDEX_MASK; - shadow_atlas->quadrants[q].shadows[s].owner = RID(); + shadow_atlas->quadrants[q].shadows.write[s].owner = RID(); shadow_atlas->shadow_owners.erase(p_rid); } @@ -4831,7 +4903,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/limits/rendering/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS); + render_list.max_elements = GLOBAL_DEF_RST("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) diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index a6faeef473..cf387a69bc 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -140,6 +140,8 @@ public: float reflection_multiplier; float subsurface_scatter_width; float ambient_occlusion_affect_light; + float ambient_occlusion_affect_ssao; + float opaque_prepass_threshold; uint32_t fog_depth_enabled; float fog_depth_begin; @@ -151,6 +153,7 @@ public: float fog_height_max; float fog_height_curve; // make sure this struct is padded to be a multiple of 16 bytes for webgl + float pad[2]; } ubo_data; @@ -385,6 +388,7 @@ public: float ssao_radius2; float ssao_bias; float ssao_light_affect; + float ssao_ao_channel_affect; Color ssao_color; VS::EnvironmentSSAOQuality ssao_quality; float ssao_bilateral_sharpness; @@ -465,6 +469,7 @@ public: ssao_radius2 = 0.0; ssao_bias = 0.01; ssao_light_affect = 0; + ssao_ao_channel_affect = 0; ssao_filter = VS::ENV_SSAO_BLUR_3x3; ssao_quality = VS::ENV_SSAO_QUALITY_LOW; ssao_bilateral_sharpness = 4; @@ -543,7 +548,7 @@ public: 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); - virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 66a8a931e2..83f731f610 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -118,10 +118,11 @@ void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, 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) { +Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) const { r_compressed = false; r_gl_format = 0; + r_real_format = p_format; Ref<Image> image = p_image; srgb = false; @@ -565,6 +566,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8_ALPHA8 : GL_RGBA8; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = false; + r_real_format = Image::FORMAT_RGBA8; srgb = true; return image; @@ -595,7 +597,7 @@ RID RasterizerStorageGLES3::texture_create() { return texture_owner.make_rid(texture); } -void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { +void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VisualServer::TextureType p_type, uint32_t p_flags) { GLenum format; GLenum internal_format; @@ -612,15 +614,38 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ ERR_FAIL_COND(!texture); texture->width = p_width; texture->height = p_height; + texture->depth = p_depth_3d; texture->format = p_format; texture->flags = p_flags; texture->stored_cube_sides = 0; - texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, format, internal_format, type, compressed, srgb); + texture->type = p_type; + + switch (p_type) { + case VS::TEXTURE_TYPE_2D: { + texture->target = GL_TEXTURE_2D; + texture->images.resize(1); + } break; + case VS::TEXTURE_TYPE_CUBEMAP: { + texture->target = GL_TEXTURE_CUBE_MAP; + texture->images.resize(6); + } break; + case VS::TEXTURE_TYPE_2D_ARRAY: { + texture->target = GL_TEXTURE_2D_ARRAY; + texture->images.resize(p_depth_3d); + } break; + case VS::TEXTURE_TYPE_3D: { + texture->target = GL_TEXTURE_3D; + texture->images.resize(p_depth_3d); + } break; + } + + Image::Format real_format; + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed, srgb); texture->alloc_width = texture->width; texture->alloc_height = texture->height; + texture->alloc_depth = texture->depth; texture->gl_format_cache = format; texture->gl_type_cache = type; @@ -633,7 +658,34 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); - if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { + if (p_type == VS::TEXTURE_TYPE_3D || p_type == VS::TEXTURE_TYPE_2D_ARRAY) { + + int width = p_width; + int height = p_height; + int depth = p_depth_3d; + + int mipmaps = 0; + + while (width != 1 && height != 1) { + glTexImage3D(texture->target, 0, internal_format, width, height, depth, 0, format, type, NULL); + + width = MAX(1, width / 2); + height = MAX(1, height / 2); + + if (p_type == VS::TEXTURE_TYPE_3D) { + depth = MAX(1, depth / 2); + } + + mipmaps++; + + if (!(p_flags & VS::TEXTURE_FLAG_MIPMAPS)) + break; + } + + glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1); + + } else if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { //prealloc if video glTexImage2D(texture->target, 0, internal_format, p_width, p_height, 0, format, type, NULL); } @@ -641,7 +693,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ texture->active = true; } -void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side) { +void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) { Texture *texture = texture_owner.get(p_texture); @@ -658,10 +710,11 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p bool srgb; if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { - texture->images[p_cube_side] = p_image; + texture->images.write[p_layer] = p_image; } - Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type, compressed, srgb); + Image::Format real_format; + Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb); if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { @@ -677,7 +730,23 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p } }; - GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D; + GLenum blit_target; + + switch (texture->type) { + case VS::TEXTURE_TYPE_2D: { + blit_target = GL_TEXTURE_2D; + } break; + case VS::TEXTURE_TYPE_CUBEMAP: { + ERR_FAIL_INDEX(p_layer, 6); + blit_target = _cube_side_enum[p_layer]; + } break; + case VS::TEXTURE_TYPE_2D_ARRAY: { + blit_target = GL_TEXTURE_2D_ARRAY; + } break; + case VS::TEXTURE_TYPE_3D: { + blit_target = GL_TEXTURE_3D; + } break; + } texture->data_size = img->get_data().size(); PoolVector<uint8_t>::Read read = img->get_data().read(); @@ -785,20 +854,36 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p //print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h)); - if (texture->compressed) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + if (texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) { + + if (texture->compressed) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - int bw = w; - int bh = h; + int bw = w; + int bh = h; - glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]); + glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]); + } else { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { + glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]); + } else { + glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]); + } + } } else { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { - glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]); + if (texture->compressed) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + int bw = w; + int bh = h; + + glCompressedTexSubImage3D(blit_target, i, 0, 0, p_layer, bw, bh, 1, internal_format, size, &read[ofs]); } else { - glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexSubImage3D(blit_target, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]); } } tsize += size; @@ -813,14 +898,17 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p //printf("texture: %i x %i - size: %i - total: %i\n",texture->width,texture->height,tsize,_rinfo.texture_mem); - texture->stored_cube_sides |= (1 << p_cube_side); + texture->stored_cube_sides |= (1 << p_layer); - if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) { + if ((texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) && (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (texture->type != VS::TEXTURE_TYPE_CUBEMAP || texture->stored_cube_sides == (1 << 6) - 1)) { //generate mipmaps if they were requested and the image does not contain them glGenerateMipmap(texture->target); } else if (mipmaps > 1) { glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1); + } else { + glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, 0); } texture->mipmaps = mipmaps; @@ -831,7 +919,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p // Uploads pixel data to a sub-region of a texture, for the specified mipmap. // The texture pixels must have been allocated before, because most features seen in texture_set_data() make no sense in a partial update. // TODO If we want this to be usable without pre-filling pixels with a full image, we have to call glTexImage2D() with null data. -void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side) { +void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer) { Texture *texture = texture_owner.get(p_texture); @@ -857,9 +945,26 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I p_sub_img = p_image->get_rect(Rect2(src_x, src_y, src_w, src_h)); } - Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, format, internal_format, type, compressed, srgb); + Image::Format real_format; + Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb); + + GLenum blit_target; - GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D; + switch (texture->type) { + case VS::TEXTURE_TYPE_2D: { + blit_target = GL_TEXTURE_2D; + } break; + case VS::TEXTURE_TYPE_CUBEMAP: { + ERR_FAIL_INDEX(p_layer, 6); + blit_target = _cube_side_enum[p_layer]; + } break; + case VS::TEXTURE_TYPE_2D_ARRAY: { + blit_target = GL_TEXTURE_2D_ARRAY; + } break; + case VS::TEXTURE_TYPE_3D: { + blit_target = GL_TEXTURE_3D; + } break; + } PoolVector<uint8_t>::Read read = img->get_data().read(); @@ -869,18 +974,38 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I int src_data_size = img->get_data().size(); int src_ofs = 0; - if (texture->compressed) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glCompressedTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, internal_format, src_data_size, &read[src_ofs]); + if (texture->type == VS::TEXTURE_TYPE_2D || texture->type == VS::TEXTURE_TYPE_CUBEMAP) { + if (texture->compressed) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glCompressedTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, internal_format, src_data_size, &read[src_ofs]); + } else { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // `format` has to match the internal_format used when the texture was created + glTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, format, type, &read[src_ofs]); + } } else { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - // `format` has to match the internal_format used when the texture was created - glTexSubImage2D(blit_target, p_dst_mip, dst_x, dst_y, src_w, src_h, format, type, &read[src_ofs]); + if (texture->compressed) { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glCompressedTexSubImage3D(blit_target, p_dst_mip, dst_x, dst_y, p_layer, src_w, src_h, 1, format, src_data_size, &read[src_ofs]); + } else { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // `format` has to match the internal_format used when the texture was created + glTexSubImage3D(blit_target, p_dst_mip, dst_x, dst_y, p_layer, src_w, src_h, 1, format, type, &read[src_ofs]); + } + } + + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + + glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering + + } else { + + glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering } } -Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const { +Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) const { Texture *texture = texture_owner.get(p_texture); @@ -888,15 +1013,23 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi ERR_FAIL_COND_V(!texture->active, Ref<Image>()); ERR_FAIL_COND_V(texture->data_size == 0 && !texture->render_target, Ref<Image>()); - if (!texture->images[p_cube_side].is_null()) { - return texture->images[p_cube_side]; + if (texture->type == VS::TEXTURE_TYPE_CUBEMAP && p_layer < 6 && !texture->images[p_layer].is_null()) { + return texture->images[p_layer]; } #ifdef GLES_OVER_GL + Image::Format real_format; + GLenum gl_format; + GLenum gl_internal_format; + GLenum gl_type; + bool compressed; + bool srgb; + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb); + PoolVector<uint8_t> data; - int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->format, texture->mipmaps > 1 ? -1 : 0); + int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, texture->mipmaps > 1 ? -1 : 0); data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers PoolVector<uint8_t>::Write wb = data.write(); @@ -913,7 +1046,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi int ofs = 0; if (i > 0) { - ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->format, i - 1); + ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, real_format, i - 1); } if (texture->compressed) { @@ -949,7 +1082,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi (a | a << 2 | a << 4 | a << 6) << 24; } } else { - img_format = texture->format; + img_format = real_format; } wb = PoolVector<uint8_t>::Write(); @@ -977,10 +1110,10 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture, uint32_t p_flags) bool had_mipmaps = texture->flags & VS::TEXTURE_FLAG_MIPMAPS; + texture->flags = p_flags; + glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); - uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; - texture->flags = p_flags | cube; // can't remove a cube from being a cube if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) { @@ -1058,6 +1191,14 @@ Image::Format RasterizerStorageGLES3::texture_get_format(RID p_texture) const { return texture->format; } + +VisualServer::TextureType RasterizerStorageGLES3::texture_get_type(RID p_texture) const { + Texture *texture = texture_owner.get(p_texture); + + ERR_FAIL_COND_V(!texture, VS::TEXTURE_TYPE_2D); + + return texture->type; +} uint32_t RasterizerStorageGLES3::texture_get_texid(RID p_texture) const { Texture *texture = texture_owner.get(p_texture); @@ -1083,7 +1224,16 @@ uint32_t RasterizerStorageGLES3::texture_get_height(RID p_texture) const { return texture->height; } -void RasterizerStorageGLES3::texture_set_size_override(RID p_texture, int p_width, int p_height) { +uint32_t RasterizerStorageGLES3::texture_get_depth(RID p_texture) const { + + Texture *texture = texture_owner.get(p_texture); + + ERR_FAIL_COND_V(!texture, 0); + + return texture->depth; +} + +void RasterizerStorageGLES3::texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth) { Texture *texture = texture_owner.get(p_texture); @@ -1123,8 +1273,9 @@ void RasterizerStorageGLES3::texture_debug_usage(List<VS::TextureInfo> *r_info) VS::TextureInfo tinfo; tinfo.path = t->path; tinfo.format = t->format; - tinfo.size.x = t->alloc_width; - tinfo.size.y = t->alloc_height; + tinfo.width = t->alloc_width; + tinfo.height = t->alloc_height; + tinfo.depth = 0; tinfo.bytes = t->total_data_size; r_info->push_back(tinfo); } @@ -1169,7 +1320,7 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_ Texture *texture = texture_owner.get(p_source); ERR_FAIL_COND_V(!texture, RID()); - ERR_FAIL_COND_V(!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP), RID()); + ERR_FAIL_COND_V(texture->type != VS::TEXTURE_TYPE_CUBEMAP, RID()); bool use_float = config.hdr_supported; @@ -1285,7 +1436,8 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_ Texture *ctex = memnew(Texture); - ctex->flags = VS::TEXTURE_FLAG_CUBEMAP | VS::TEXTURE_FLAG_MIPMAPS | VS::TEXTURE_FLAG_FILTER; + ctex->type = VS::TEXTURE_TYPE_CUBEMAP; + ctex->flags = VS::TEXTURE_FLAG_MIPMAPS | VS::TEXTURE_FLAG_FILTER; ctex->width = p_resolution; ctex->height = p_resolution; ctex->alloc_width = p_resolution; @@ -1328,6 +1480,13 @@ void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) { } } +void RasterizerStorageGLES3::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { + + Texture *texture = texture_owner.get(p_texture); + ERR_FAIL_COND(!texture); + texture->redraw_if_visible = p_enable; +} + RID RasterizerStorageGLES3::sky_create() { Sky *sky = memnew(Sky); @@ -1758,6 +1917,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { p_shader->ubo_offsets = gen_code.uniform_offsets; p_shader->texture_count = gen_code.texture_uniforms.size(); p_shader->texture_hints = gen_code.texture_hints; + p_shader->texture_types = gen_code.texture_types; p_shader->uses_vertex_time = gen_code.uses_vertex_time; p_shader->uses_fragment_time = gen_code.uses_fragment_time; @@ -1868,6 +2028,13 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint_string = "Texture"; } break; + case ShaderLanguage::TYPE_SAMPLER3D: + case ShaderLanguage::TYPE_ISAMPLER3D: + case ShaderLanguage::TYPE_USAMPLER3D: { + pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture3D"; + } break; case ShaderLanguage::TYPE_SAMPLERCUBE: { pi.type = Variant::OBJECT; @@ -2642,6 +2809,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) { //set up the texture array, for easy access when it needs to be drawn if (material->shader && material->shader->texture_count) { + material->texture_is_3d.resize(material->shader->texture_count); material->textures.resize(material->shader->texture_count); for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) { @@ -2651,6 +2819,16 @@ void RasterizerStorageGLES3::_update_material(Material *material) { RID texture; + switch (E->get().type) { + case ShaderLanguage::TYPE_SAMPLER3D: + case ShaderLanguage::TYPE_SAMPLER2DARRAY: { + material->texture_is_3d.write[E->get().texture_order] = true; + } break; + default: { + material->texture_is_3d.write[E->get().texture_order] = false; + } break; + } + Map<StringName, Variant>::Element *V = material->params.find(E->key()); if (V) { texture = V->get(); @@ -2663,11 +2841,12 @@ void RasterizerStorageGLES3::_update_material(Material *material) { } } - material->textures[E->get().texture_order] = texture; + material->textures.write[E->get().texture_order] = texture; } } else { material->textures.clear(); + material->texture_is_3d.clear(); } } @@ -2968,9 +3147,9 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: for (int i = 0; i < surface->skeleton_bone_used.size(); i++) { if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) { - surface->skeleton_bone_used[i] = false; + surface->skeleton_bone_used.write[i] = false; } else { - surface->skeleton_bone_used[i] = true; + surface->skeleton_bone_used.write[i] = true; } } @@ -3233,7 +3412,7 @@ void RasterizerStorageGLES3::mesh_surface_update_region(RID p_mesh, int p_surfac PoolVector<uint8_t>::Read r = p_data.read(); - glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->array_id); + glBindBuffer(GL_ARRAY_BUFFER, mesh->surfaces[p_surface]->vertex_id); glBufferSubData(GL_ARRAY_BUFFER, p_offset, total_size, r.ptr()); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind } @@ -3397,6 +3576,7 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap return bsarr; } + Vector<AABB> RasterizerStorageGLES3::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); @@ -3448,6 +3628,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) { mesh->instance_change_notify(); } + int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); @@ -3461,6 +3642,7 @@ void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; + mesh->instance_change_notify(); } AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const { @@ -3816,12 +3998,12 @@ RID RasterizerStorageGLES3::multimesh_create() { return multimesh_owner.make_rid(multimesh); } -void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format) { +void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data_format) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); - if (multimesh->size == p_instances && multimesh->transform_format == p_transform_format && multimesh->color_format == p_color_format) + if (multimesh->size == p_instances && multimesh->transform_format == p_transform_format && multimesh->color_format == p_color_format && multimesh->custom_data_format == p_data_format) return; if (multimesh->buffer) { @@ -3832,6 +4014,7 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances multimesh->size = p_instances; multimesh->transform_format = p_transform_format; multimesh->color_format = p_color_format; + multimesh->custom_data_format = p_data_format; if (multimesh->size) { @@ -3849,36 +4032,49 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances multimesh->color_floats = 4; } - int format_floats = multimesh->color_floats + multimesh->xform_floats; + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE) { + multimesh->custom_data_floats = 0; + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + multimesh->custom_data_floats = 1; + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + multimesh->custom_data_floats = 4; + } + + int format_floats = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + multimesh->data.resize(format_floats * p_instances); - for (int i = 0; i < p_instances; i += format_floats) { + + for (int i = 0; i < p_instances * format_floats; i += format_floats) { int color_from = 0; + int custom_data_from = 0; if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) { - multimesh->data[i + 0] = 1.0; - multimesh->data[i + 1] = 0.0; - multimesh->data[i + 2] = 0.0; - multimesh->data[i + 3] = 0.0; - multimesh->data[i + 4] = 0.0; - multimesh->data[i + 5] = 1.0; - multimesh->data[i + 6] = 0.0; - multimesh->data[i + 7] = 0.0; + multimesh->data.write[i + 0] = 1.0; + multimesh->data.write[i + 1] = 0.0; + multimesh->data.write[i + 2] = 0.0; + multimesh->data.write[i + 3] = 0.0; + multimesh->data.write[i + 4] = 0.0; + multimesh->data.write[i + 5] = 1.0; + multimesh->data.write[i + 6] = 0.0; + multimesh->data.write[i + 7] = 0.0; color_from = 8; + custom_data_from = 8; } else { - multimesh->data[i + 0] = 1.0; - multimesh->data[i + 1] = 0.0; - multimesh->data[i + 2] = 0.0; - multimesh->data[i + 3] = 0.0; - multimesh->data[i + 4] = 0.0; - multimesh->data[i + 5] = 1.0; - multimesh->data[i + 6] = 0.0; - multimesh->data[i + 7] = 0.0; - multimesh->data[i + 8] = 0.0; - multimesh->data[i + 9] = 0.0; - multimesh->data[i + 10] = 1.0; - multimesh->data[i + 11] = 0.0; + multimesh->data.write[i + 0] = 1.0; + multimesh->data.write[i + 1] = 0.0; + multimesh->data.write[i + 2] = 0.0; + multimesh->data.write[i + 3] = 0.0; + multimesh->data.write[i + 4] = 0.0; + multimesh->data.write[i + 5] = 1.0; + multimesh->data.write[i + 6] = 0.0; + multimesh->data.write[i + 7] = 0.0; + multimesh->data.write[i + 8] = 0.0; + multimesh->data.write[i + 9] = 0.0; + multimesh->data.write[i + 10] = 1.0; + multimesh->data.write[i + 11] = 0.0; color_from = 12; + custom_data_from = 12; } if (multimesh->color_format == VS::MULTIMESH_COLOR_NONE) { @@ -3891,13 +4087,34 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances } cu; cu.colu = 0xFFFFFFFF; - multimesh->data[i + color_from + 0] = cu.colf; + multimesh->data.write[i + color_from + 0] = cu.colf; + custom_data_from = color_from + 1; } else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) { - multimesh->data[i + color_from + 0] = 1.0; - multimesh->data[i + color_from + 1] = 1.0; - multimesh->data[i + color_from + 2] = 1.0; - multimesh->data[i + color_from + 3] = 1.0; + multimesh->data.write[i + color_from + 0] = 1.0; + multimesh->data.write[i + color_from + 1] = 1.0; + multimesh->data.write[i + color_from + 2] = 1.0; + multimesh->data.write[i + color_from + 3] = 1.0; + custom_data_from = color_from + 4; + } + + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE) { + //none + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + + union { + uint32_t colu; + float colf; + } cu; + + cu.colu = 0; + multimesh->data.write[i + custom_data_from + 0] = cu.colf; + + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + multimesh->data.write[i + custom_data_from + 0] = 0.0; + multimesh->data.write[i + custom_data_from + 1] = 0.0; + multimesh->data.write[i + custom_data_from + 2] = 0.0; + multimesh->data.write[i + custom_data_from + 3] = 0.0; } } @@ -3958,8 +4175,8 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform(RID p_multimesh, i ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D); - int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index]; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index]; dataptr[0] = p_transform.basis.elements[0][0]; dataptr[1] = p_transform.basis.elements[0][1]; @@ -3989,8 +4206,8 @@ void RasterizerStorageGLES3::multimesh_instance_set_transform_2d(RID p_multimesh ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D); - int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index]; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index]; dataptr[0] = p_transform.elements[0][0]; dataptr[1] = p_transform.elements[1][0]; @@ -4015,8 +4232,8 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p ERR_FAIL_INDEX(p_index, multimesh->size); ERR_FAIL_COND(multimesh->color_format == VS::MULTIMESH_COLOR_NONE); - int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats]; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats]; if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { @@ -4041,6 +4258,38 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh, int p } } +void RasterizerStorageGLES3::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_custom_data) { + + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + ERR_FAIL_COND(!multimesh); + ERR_FAIL_INDEX(p_index, multimesh->size); + ERR_FAIL_COND(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE); + + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats]; + + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + + uint8_t *data8 = (uint8_t *)dataptr; + data8[0] = CLAMP(p_custom_data.r * 255.0, 0, 255); + data8[1] = CLAMP(p_custom_data.g * 255.0, 0, 255); + data8[2] = CLAMP(p_custom_data.b * 255.0, 0, 255); + data8[3] = CLAMP(p_custom_data.a * 255.0, 0, 255); + + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + dataptr[0] = p_custom_data.r; + dataptr[1] = p_custom_data.g; + dataptr[2] = p_custom_data.b; + dataptr[3] = p_custom_data.a; + } + + multimesh->dirty_data = true; + multimesh->dirty_aabb = true; + + if (!multimesh->update_list.in_list()) { + multimesh_update_list.add(&multimesh->update_list); + } +} RID RasterizerStorageGLES3::multimesh_get_mesh(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); @@ -4056,8 +4305,8 @@ Transform RasterizerStorageGLES3::multimesh_instance_get_transform(RID p_multime ERR_FAIL_INDEX_V(p_index, multimesh->size, Transform()); ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D, Transform()); - int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index]; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index]; Transform xform; @@ -4083,8 +4332,8 @@ Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_mu ERR_FAIL_INDEX_V(p_index, multimesh->size, Transform2D()); ERR_FAIL_COND_V(multimesh->transform_format == VS::MULTIMESH_TRANSFORM_3D, Transform2D()); - int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index]; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index]; Transform2D xform; @@ -4105,8 +4354,8 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int ERR_FAIL_INDEX_V(p_index, multimesh->size, Color()); ERR_FAIL_COND_V(multimesh->color_format == VS::MULTIMESH_COLOR_NONE, Color()); - int stride = multimesh->color_floats + multimesh->xform_floats; - float *dataptr = &multimesh->data[stride * p_index + multimesh->xform_floats]; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats]; if (multimesh->color_format == VS::MULTIMESH_COLOR_8BIT) { union { @@ -4131,6 +4380,59 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int return Color(); } +Color RasterizerStorageGLES3::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { + + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + ERR_FAIL_COND_V(!multimesh, Color()); + ERR_FAIL_INDEX_V(p_index, multimesh->size, Color()); + ERR_FAIL_COND_V(multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_NONE, Color()); + + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; + float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats]; + + if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) { + union { + uint32_t colu; + float colf; + } cu; + + cu.colf = dataptr[0]; + + return Color::hex(BSWAP32(cu.colu)); + + } else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) { + Color c; + c.r = dataptr[0]; + c.g = dataptr[1]; + c.b = dataptr[2]; + c.a = dataptr[3]; + + return c; + } + + return Color(); +} + +void RasterizerStorageGLES3::multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) { + + MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + ERR_FAIL_COND(!multimesh); + + int dsize = multimesh->data.size(); + + ERR_FAIL_COND(dsize != p_array.size()); + + PoolVector<float>::Read r = p_array.read(); + copymem(multimesh->data.ptrw(), r.ptr(), dsize * sizeof(float)); + + multimesh->dirty_data = true; + multimesh->dirty_aabb = true; + + if (!multimesh->update_list.in_list()) { + multimesh_update_list.add(&multimesh->update_list); + } +} + void RasterizerStorageGLES3::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); @@ -4179,7 +4481,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { mesh_aabb.size += Vector3(0.001, 0.001, 0.001); } - int stride = multimesh->color_floats + multimesh->xform_floats; + int stride = multimesh->color_floats + multimesh->xform_floats + multimesh->custom_data_floats; int count = multimesh->data.size(); float *data = multimesh->data.ptrw(); @@ -5642,7 +5944,7 @@ void RasterizerStorageGLES3::particles_set_draw_pass_mesh(RID p_particles, int p Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_INDEX(p_pass, particles->draw_passes.size()); - particles->draw_passes[p_pass] = p_mesh; + particles->draw_passes.write[p_pass] = p_mesh; } void RasterizerStorageGLES3::particles_restart(RID p_particles) { @@ -6516,7 +6818,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) { for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) { - RenderTarget::Effects::MipMaps::Size &mm = rt->effects.mip_maps[i].sizes[j]; + RenderTarget::Effects::MipMaps::Size &mm = rt->effects.mip_maps[i].sizes.write[j]; glGenFramebuffers(1, &mm.fbo); glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo); @@ -6696,7 +6998,10 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { //printf("errnum: %x\n",status); glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); - ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, RID()); + if (status != GL_FRAMEBUFFER_COMPLETE) { + memdelete(cls); + ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, RID()); + } return canvas_light_shadow_owner.make_rid(cls); } @@ -6869,6 +7174,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) { info.texture_mem -= texture->total_data_size; texture_owner.free(p_rid); memdelete(texture); + } else if (sky_owner.owns(p_rid)) { // delete the sky Sky *sky = sky_owner.get(p_rid); @@ -6928,7 +7234,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) { for (int i = 0; i < ins->materials.size(); i++) { if (ins->materials[i] == p_rid) { - ins->materials[i] = RID(); + ins->materials.write[i] = RID(); } } } @@ -7078,6 +7384,9 @@ bool RasterizerStorageGLES3::free(RID p_rid) { bool RasterizerStorageGLES3::has_os_feature(const String &p_feature) const { + if (p_feature == "bptc") + return config.bptc_supported; + if (p_feature == "s3tc") return config.s3tc_supported; @@ -7278,6 +7587,15 @@ void RasterizerStorageGLES3::initialize() { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, anisotexdata); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); + + glGenTextures(1, &resources.white_tex_3d); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_3D, resources.white_tex_3d); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 2, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata); + + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0); } glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units); @@ -7336,7 +7654,7 @@ void RasterizerStorageGLES3::initialize() { { //transform feedback buffers - uint32_t xf_feedback_size = GLOBAL_DEF("rendering/limits/buffers/blend_shape_max_buffer_size_kb", 4096); + uint32_t xf_feedback_size = GLOBAL_DEF_RST("rendering/limits/buffers/blend_shape_max_buffer_size_kb", 4096); for (int i = 0; i < 2; i++) { glGenBuffers(1, &resources.transform_feedback_buffers[i]); @@ -7359,7 +7677,6 @@ void RasterizerStorageGLES3::initialize() { #endif frame.count = 0; - frame.prev_tick = 0; frame.delta = 0; frame.current_rt = NULL; config.keep_original_textures = false; diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 6b626cbd00..b74dd77e26 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -123,6 +123,8 @@ public: GLuint normal_tex; GLuint aniso_tex; + GLuint white_tex_3d; + GLuint quadie; GLuint quadie_array; @@ -248,9 +250,10 @@ public: String path; uint32_t flags; - int width, height; - int alloc_width, alloc_height; + int width, height, depth; + int alloc_width, alloc_height, alloc_depth; Image::Format format; + VS::TextureType type; GLenum target; GLenum gl_format_cache; @@ -268,12 +271,13 @@ public: GLuint tex_id; bool using_srgb; + bool redraw_if_visible; uint16_t stored_cube_sides; RenderTarget *render_target; - Ref<Image> images[6]; + Vector<Ref<Image> > images; VisualServer::TextureDetectCallback detect_3d; void *detect_3d_ud; @@ -306,6 +310,7 @@ public: detect_normal = NULL; detect_normal_ud = NULL; proxy = NULL; + redraw_if_visible = false; } _ALWAYS_INLINE_ Texture *get_ptr() { @@ -335,20 +340,22 @@ public: mutable RID_Owner<Texture> texture_owner; - Ref<Image> _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); + Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) const; virtual RID texture_create(); - virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); - virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT); - virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT); - virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const; + virtual void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VS::TextureType p_type, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); + virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); + virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer = 0); + virtual Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) const; virtual void texture_set_flags(RID p_texture, uint32_t p_flags); virtual uint32_t texture_get_flags(RID p_texture) const; virtual Image::Format texture_get_format(RID p_texture) const; + virtual VS::TextureType texture_get_type(RID p_texture) const; virtual uint32_t texture_get_texid(RID p_texture) const; virtual uint32_t texture_get_width(RID p_texture) const; virtual uint32_t texture_get_height(RID p_texture) const; - virtual void texture_set_size_override(RID p_texture, int p_width, int p_height); + virtual uint32_t texture_get_depth(RID p_texture) const; + virtual void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth); virtual void texture_set_path(RID p_texture, const String &p_path); virtual String texture_get_path(RID p_texture) const; @@ -366,6 +373,7 @@ public: virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); virtual void texture_set_proxy(RID p_texture, RID p_proxy); + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable); /* SKY API */ @@ -407,6 +415,7 @@ public: Map<StringName, RID> default_textures; + Vector<ShaderLanguage::DataType> texture_types; Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; bool valid; @@ -529,6 +538,7 @@ public: Map<StringName, Variant> params; SelfList<Material> list; SelfList<Material> dirty_list; + Vector<bool> texture_is_3d; Vector<RID> textures; float line_width; int render_priority; @@ -690,7 +700,6 @@ public: AABB custom_aabb; mutable uint64_t last_pass; SelfList<MultiMesh>::List multimeshes; - _FORCE_INLINE_ void update_multimeshes() { SelfList<MultiMesh> *mm = multimeshes.first(); @@ -756,6 +765,7 @@ public: int size; VS::MultimeshTransformFormat transform_format; VS::MultimeshColorFormat color_format; + VS::MultimeshCustomDataFormat custom_data_format; Vector<float> data; AABB aabb; SelfList<MultiMesh> update_list; @@ -765,6 +775,7 @@ public: int xform_floats; int color_floats; + int custom_data_floats; bool dirty_aabb; bool dirty_data; @@ -776,11 +787,13 @@ public: dirty_data = true; xform_floats = 0; color_floats = 0; + custom_data_floats = 0; visible_instances = -1; size = 0; buffer = 0; transform_format = VS::MULTIMESH_TRANSFORM_2D; color_format = VS::MULTIMESH_COLOR_NONE; + custom_data_format = VS::MULTIMESH_CUSTOM_DATA_NONE; } }; @@ -792,19 +805,23 @@ public: virtual RID multimesh_create(); - virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format); + virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format, VS::MultimeshCustomDataFormat p_data_format = VS::MULTIMESH_CUSTOM_DATA_NONE); virtual int multimesh_get_instance_count(RID p_multimesh) const; virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh); virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform); virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform); virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color); + virtual void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color); virtual RID multimesh_get_mesh(RID p_multimesh) const; virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const; virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const; + virtual Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const; + + virtual void multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array); virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; @@ -1417,7 +1434,6 @@ public: int canvas_draw_commands; float time[4]; float delta; - uint64_t prev_tick; uint64_t count; } frame; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index eb8d6c485b..a78a392cbd 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -341,6 +341,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.texture_uniforms.resize(max_texture_uniforms); r_gen_code.texture_hints.resize(max_texture_uniforms); + r_gen_code.texture_types.resize(max_texture_uniforms); Vector<int> uniform_sizes; Vector<int> uniform_alignments; @@ -365,17 +366,18 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener if (SL::is_sampler_type(E->get().type)) { r_gen_code.vertex_global += ucode; r_gen_code.fragment_global += ucode; - r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key()); - r_gen_code.texture_hints[E->get().texture_order] = E->get().hint; + r_gen_code.texture_uniforms.write[E->get().texture_order] = _mkid(E->key()); + r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint; + r_gen_code.texture_types.write[E->get().texture_order] = E->get().type; } else { 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); - uniform_alignments[E->get().order] = _get_datatype_alignment(E->get().type); + uniform_defines.write[E->get().order] = ucode; + uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type); + uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type); } p_actions.uniforms->insert(E->key(), E->get()); @@ -434,8 +436,6 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener continue; } - print_line("u - "+String(E->key())+" offset: "+itos(r_gen_code.uniform_offsets[E->get().order])); - } */ @@ -700,6 +700,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener } } else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) { + if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) { + *p_actions.usage_flag_pointers["DISCARD"] = true; + used_flag_pointers.insert("DISCARD"); + } + code = "discard;"; } else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) { @@ -780,8 +785,6 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth"; - actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp"; - actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture"; actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size"; actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture"; @@ -824,7 +827,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp"; actions[VS::SHADER_SPATIAL].renames["COLOR"] = "color_interp"; actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; - //actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"]=ShaderLanguage::TYPE_INT; + actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "gl_InstanceID"; //builtins @@ -846,13 +849,11 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy"; actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; - //actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread"; actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission"; actions[VS::SHADER_SPATIAL].renames["AO"] = "ao"; actions[VS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission"; - //actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2; actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord"; actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom"; actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; @@ -894,10 +895,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; - 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["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; @@ -912,6 +912,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { 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"; 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"; /* PARTICLES SHADER */ diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h index bf776ee062..7a32057741 100644 --- a/drivers/gles3/shader_compiler_gles3.h +++ b/drivers/gles3/shader_compiler_gles3.h @@ -52,6 +52,7 @@ public: Vector<CharString> defines; Vector<StringName> texture_uniforms; + Vector<ShaderLanguage::DataType> texture_types; Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; Vector<uint32_t> uniform_offsets; diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 08b8a1cc26..007600bb42 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -240,8 +240,6 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { CharString code_globals; CharString material_string; - //print_line("code version? "+itos(conditional_version.code_version)); - CustomCode *cc = NULL; if (conditional_version.code_version > 0) { @@ -554,7 +552,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() { v.texture_uniform_locations.resize(cc->texture_uniforms.size()); for (int i = 0; i < cc->texture_uniforms.size(); i++) { - v.texture_uniform_locations[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data()); + v.texture_uniform_locations.write[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data()); glUniform1i(v.texture_uniform_locations[i], i + base_material_tex_index); } } @@ -743,13 +741,6 @@ void ShaderGLES3::set_custom_shader(uint32_t p_code_id) { void ShaderGLES3::free_custom_shader(uint32_t p_code_id) { - /* if (! custom_code_map.has( p_code_id )) { - print_line("no code id "+itos(p_code_id)); - } else { - print_line("freed code id "+itos(p_code_id)); - - }*/ - ERR_FAIL_COND(!custom_code_map.has(p_code_id)); if (conditional_version.code_version == p_code_id) conditional_version.code_version = 0; //bye diff --git a/drivers/gles3/shaders/blend_shape.glsl b/drivers/gles3/shaders/blend_shape.glsl index 4e0d066823..a1e954e33d 100644 --- a/drivers/gles3/shaders/blend_shape.glsl +++ b/drivers/gles3/shaders/blend_shape.glsl @@ -1,6 +1,6 @@ +/* clang-format off */ [vertex] - /* from VisualServer: @@ -23,56 +23,57 @@ ARRAY_INDEX=8, /* INPUT ATTRIBS */ -layout(location=0) in highp VFORMAT vertex_attrib; -layout(location=1) in vec3 normal_attrib; +layout(location = 0) in highp VFORMAT vertex_attrib; +/* clang-format on */ +layout(location = 1) in vec3 normal_attrib; #ifdef ENABLE_TANGENT -layout(location=2) in vec4 tangent_attrib; +layout(location = 2) in vec4 tangent_attrib; #endif #ifdef ENABLE_COLOR -layout(location=3) in vec4 color_attrib; +layout(location = 3) in vec4 color_attrib; #endif #ifdef ENABLE_UV -layout(location=4) in vec2 uv_attrib; +layout(location = 4) in vec2 uv_attrib; #endif #ifdef ENABLE_UV2 -layout(location=5) in vec2 uv2_attrib; +layout(location = 5) in vec2 uv2_attrib; #endif #ifdef ENABLE_SKELETON -layout(location=6) in ivec4 bone_attrib; -layout(location=7) in vec4 weight_attrib; +layout(location = 6) in ivec4 bone_attrib; +layout(location = 7) in vec4 weight_attrib; #endif /* BLEND ATTRIBS */ #ifdef ENABLE_BLEND -layout(location=8) in highp VFORMAT vertex_attrib_blend; -layout(location=9) in vec3 normal_attrib_blend; +layout(location = 8) in highp VFORMAT vertex_attrib_blend; +layout(location = 9) in vec3 normal_attrib_blend; #ifdef ENABLE_TANGENT -layout(location=10) in vec4 tangent_attrib_blend; +layout(location = 10) in vec4 tangent_attrib_blend; #endif #ifdef ENABLE_COLOR -layout(location=11) in vec4 color_attrib_blend; +layout(location = 11) in vec4 color_attrib_blend; #endif #ifdef ENABLE_UV -layout(location=12) in vec2 uv_attrib_blend; +layout(location = 12) in vec2 uv_attrib_blend; #endif #ifdef ENABLE_UV2 -layout(location=13) in vec2 uv2_attrib_blend; +layout(location = 13) in vec2 uv2_attrib_blend; #endif #ifdef ENABLE_SKELETON -layout(location=14) in ivec4 bone_attrib_blend; -layout(location=15) in vec4 weight_attrib_blend; +layout(location = 14) in ivec4 bone_attrib_blend; +layout(location = 15) in vec4 weight_attrib_blend; #endif #endif @@ -110,7 +111,6 @@ uniform float blend_amount; void main() { - #ifdef ENABLE_BLEND vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount; @@ -140,7 +140,6 @@ void main() { uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount; #endif - #ifdef ENABLE_SKELETON bone_out = bone_attrib_blend; @@ -149,7 +148,6 @@ void main() { #else //ENABLE_BLEND - vertex_out = vertex_attrib * blend_amount; #ifdef ENABLE_NORMAL @@ -177,7 +175,6 @@ void main() { uv2_out = uv2_attrib * blend_amount; #endif - #ifdef ENABLE_SKELETON bone_out = bone_attrib; @@ -188,10 +185,10 @@ void main() { gl_Position = vec4(0.0); } +/* clang-format off */ [fragment] - void main() { } - +/* clang-format on */ diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 326aab4c7c..53f563303a 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -1,12 +1,13 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec2 vertex; -layout(location=3) in vec4 color_attrib; +layout(location = 0) in highp vec2 vertex; +/* clang-format on */ +layout(location = 3) in vec4 color_attrib; #ifdef USE_SKELETON -layout(location=6) in uvec4 bone_indices; // attrib:6 -layout(location=7) in vec4 bone_weights; // attrib:7 +layout(location = 6) in uvec4 bone_indices; // attrib:6 +layout(location = 7) in vec4 bone_weights; // attrib:7 #endif #ifdef USE_TEXTURE_RECT @@ -18,25 +19,24 @@ uniform vec4 src_rect; #ifdef USE_INSTANCING -layout(location=8) in highp vec4 instance_xform0; -layout(location=9) in highp vec4 instance_xform1; -layout(location=10) in highp vec4 instance_xform2; -layout(location=11) in lowp vec4 instance_color; +layout(location = 8) in highp vec4 instance_xform0; +layout(location = 9) in highp vec4 instance_xform1; +layout(location = 10) in highp vec4 instance_xform2; +layout(location = 11) in lowp vec4 instance_color; #ifdef USE_INSTANCE_CUSTOM -layout(location=12) in highp vec4 instance_custom_data; +layout(location = 12) in highp vec4 instance_custom_data; #endif #endif -layout(location=4) in highp vec2 uv_attrib; +layout(location = 4) in highp vec2 uv_attrib; -//skeletn +// skeleton #endif uniform highp vec2 color_texpixel_size; - layout(std140) uniform CanvasItemData { //ubo:0 highp mat4 projection_matrix; @@ -46,7 +46,6 @@ layout(std140) uniform CanvasItemData { //ubo:0 uniform highp mat4 modelview_matrix; uniform highp mat4 extra_matrix; - out highp vec2 uv_interp; out mediump vec4 color_interp; @@ -55,7 +54,6 @@ out mediump vec4 color_interp; out highp vec2 pixel_size_interp; #endif - #ifdef USE_SKELETON uniform mediump sampler2D skeleton_texture; // texunit:-1 uniform highp mat4 skeleton_transform; @@ -66,7 +64,7 @@ uniform highp mat4 skeleton_transform_inverse; layout(std140) uniform LightData { //ubo:1 - //light matrices + // light matrices highp mat4 light_matrix; highp mat4 light_local_matrix; highp mat4 shadow_matrix; @@ -80,9 +78,8 @@ layout(std140) uniform LightData { //ubo:1 highp float shadow_distance_mult; }; - out vec4 light_uv_interp; - +out vec2 transformed_light_uv; out vec4 local_rot; @@ -100,27 +97,31 @@ uniform int h_frames; uniform int v_frames; #endif - #if defined(USE_MATERIAL) +/* clang-format off */ layout(std140) uniform UniformData { //ubo:2 MATERIAL_UNIFORMS }; +/* clang-format on */ #endif +/* clang-format off */ VERTEX_SHADER_GLOBALS +/* clang-format on */ + void main() { vec4 color = color_attrib; #ifdef USE_INSTANCING - mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0))); - color*=instance_color; + mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); + color *= instance_color; vec4 instance_custom = instance_custom_data; #else @@ -135,41 +136,40 @@ void main() { } else { uv_interp = src_rect.xy + abs(src_rect.zw) * vertex; } - highp vec4 outvec = vec4(dst_rect.xy + abs(dst_rect.zw) * mix(vertex,vec2(1.0,1.0)-vertex,lessThan(src_rect.zw,vec2(0.0,0.0))),0.0,1.0); + highp vec4 outvec = vec4(dst_rect.xy + abs(dst_rect.zw) * mix(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0))), 0.0, 1.0); #else uv_interp = uv_attrib; - highp vec4 outvec = vec4(vertex,0.0,1.0); + highp vec4 outvec = vec4(vertex, 0.0, 1.0); #endif - #ifdef USE_PARTICLES //scale by texture size - outvec.xy/=color_texpixel_size; + outvec.xy /= color_texpixel_size; //compute h and v frames and adjust UV interp for animation int total_frames = h_frames * v_frames; - int frame = min(int(float(total_frames) *instance_custom.z),total_frames-1); - float frame_w = 1.0/float(h_frames); - float frame_h = 1.0/float(v_frames); + int frame = min(int(float(total_frames) * instance_custom.z), total_frames - 1); + float frame_w = 1.0 / float(h_frames); + float frame_h = 1.0 / float(v_frames); uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames); uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / h_frames); #endif - #define extra_matrix extra_matrix2 -{ + { + /* clang-format off */ VERTEX_SHADER_CODE -} - + /* clang-format on */ + } #ifdef USE_NINEPATCH - pixel_size_interp=abs(dst_rect.zw) * vertex; + pixel_size_interp = abs(dst_rect.zw) * vertex; #endif #if !defined(SKIP_TRANSFORM_USED) @@ -183,47 +183,46 @@ VERTEX_SHADER_CODE #ifdef USE_PIXEL_SNAP - outvec.xy=floor(outvec+0.5).xy; + outvec.xy = floor(outvec + 0.5).xy; #endif - #ifdef USE_SKELETON - if (bone_weights!=vec4(0.0)){ //must be a valid bone + if (bone_weights != vec4(0.0)) { //must be a valid bone //skeleton transform ivec4 bone_indicesi = ivec4(bone_indices); - ivec2 tex_ofs = ivec2( bone_indicesi.x%256, (bone_indicesi.x/256)*2 ); - - highp mat2x4 m = mat2x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) - ) * bone_weights.x; + ivec2 tex_ofs = ivec2(bone_indicesi.x % 256, (bone_indicesi.x / 256) * 2); - tex_ofs = ivec2( bone_indicesi.y%256, (bone_indicesi.y/256)*2 ); + highp mat2x4 m; + m = mat2x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0)) * + bone_weights.x; - m+= mat2x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) - ) * bone_weights.y; + tex_ofs = ivec2(bone_indicesi.y % 256, (bone_indicesi.y / 256) * 2); - tex_ofs = ivec2( bone_indicesi.z%256, (bone_indicesi.z/256)*2 ); + m += mat2x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0)) * + bone_weights.y; - m+= mat2x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) - ) * bone_weights.z; + tex_ofs = ivec2(bone_indicesi.z % 256, (bone_indicesi.z / 256) * 2); + m += mat2x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0)) * + bone_weights.z; - tex_ofs = ivec2( bone_indicesi.w%256, (bone_indicesi.w/256)*2 ); + tex_ofs = ivec2(bone_indicesi.w % 256, (bone_indicesi.w / 256) * 2); - m+= mat2x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) - ) * bone_weights.w; + m += mat2x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0)) * + bone_weights.w; - mat4 bone_matrix = skeleton_transform * transpose(mat4(m[0],m[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))) * skeleton_transform_inverse; + mat4 bone_matrix = skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_transform_inverse; outvec = bone_matrix * outvec; } @@ -235,38 +234,39 @@ VERTEX_SHADER_CODE #ifdef USE_LIGHTING light_uv_interp.xy = (light_matrix * outvec).xy; - light_uv_interp.zw =(light_local_matrix * outvec).xy; + light_uv_interp.zw = (light_local_matrix * outvec).xy; + + mat3 inverse_light_matrix = mat3(inverse(light_matrix)); + inverse_light_matrix[0] = normalize(inverse_light_matrix[0]); + inverse_light_matrix[1] = normalize(inverse_light_matrix[1]); + inverse_light_matrix[2] = normalize(inverse_light_matrix[2]); + transformed_light_uv = (inverse_light_matrix * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping + #ifdef USE_SHADOWS - pos=outvec.xy; + pos = outvec.xy; #endif - - local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy ); - local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy ); + local_rot.xy = normalize((modelview_matrix * (extra_matrix * vec4(1.0, 0.0, 0.0, 0.0))).xy); + local_rot.zw = normalize((modelview_matrix * (extra_matrix * vec4(0.0, 1.0, 0.0, 0.0))).xy); #ifdef USE_TEXTURE_RECT - local_rot.xy*=sign(src_rect.z); - local_rot.zw*=sign(src_rect.w); + local_rot.xy *= sign(src_rect.z); + local_rot.zw *= sign(src_rect.w); #endif - - #endif - } +/* clang-format off */ [fragment] - - uniform mediump sampler2D color_texture; // texunit:0 +/* clang-format on */ uniform highp vec2 color_texpixel_size; uniform mediump sampler2D normal_texture; // texunit:1 - in highp vec2 uv_interp; in mediump vec4 color_interp; - #if defined(SCREEN_TEXTURE_USED) uniform sampler2D screen_texture; // texunit:-3 @@ -284,7 +284,6 @@ layout(std140) uniform CanvasItemData { highp float time; }; - #ifdef USE_LIGHTING layout(std140) uniform LightData { @@ -304,11 +303,10 @@ layout(std140) uniform LightData { uniform lowp sampler2D light_texture; // texunit:-1 in vec4 light_uv_interp; - +in vec2 transformed_light_uv; in vec4 local_rot; - #ifdef USE_SHADOWS uniform highp sampler2D shadow_texture; // texunit:-2 @@ -323,44 +321,49 @@ const bool at_light_pass = false; uniform mediump vec4 final_modulate; - - - -layout(location=0) out mediump vec4 frag_color; - +layout(location = 0) out mediump vec4 frag_color; #if defined(USE_MATERIAL) +/* clang-format off */ layout(std140) uniform UniformData { MATERIAL_UNIFORMS }; +/* clang-format on */ #endif +/* clang-format off */ + FRAGMENT_SHADER_GLOBALS +/* clang-format on */ + void light_compute( - inout vec4 light, - inout vec2 light_vec, - inout float light_height, - inout vec4 light_color, - vec2 light_uv, - inout vec4 shadow_color, - vec3 normal, - vec2 uv, + inout vec4 light, + inout vec2 light_vec, + inout float light_height, + inout vec4 light_color, + vec2 light_uv, + inout vec4 shadow_color, + vec3 normal, + vec2 uv, #if defined(SCREEN_UV_USED) - vec2 screen_uv, + vec2 screen_uv, #endif - vec4 color) { + vec4 color) { #if defined(USE_LIGHT_SHADER_CODE) + /* clang-format off */ + LIGHT_SHADER_CODE -#endif + /* clang-format on */ +#endif } #ifdef USE_TEXTURE_RECT @@ -376,48 +379,44 @@ in highp vec2 pixel_size_interp; uniform int np_repeat_v; uniform int np_repeat_h; uniform bool np_draw_center; -//left top right bottom in pixel coordinates +// left top right bottom in pixel coordinates uniform vec4 np_margins; +float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { - -float map_ninepatch_axis(float pixel, float draw_size,float tex_pixel_size,float margin_begin,float margin_end,int np_repeat,inout int draw_center) { - - - float tex_size = 1.0/tex_pixel_size; + float tex_size = 1.0 / tex_pixel_size; if (pixel < margin_begin) { return pixel * tex_pixel_size; - } else if (pixel >= draw_size-margin_end) { - return (tex_size-(draw_size-pixel)) * tex_pixel_size; + } else if (pixel >= draw_size - margin_end) { + return (tex_size - (draw_size - pixel)) * tex_pixel_size; } else { - if (!np_draw_center){ + if (!np_draw_center) { draw_center--; } - if (np_repeat==0) { //stretch + if (np_repeat == 0) { //stretch //convert to ratio float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end); //scale to source texture return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size; - } else if (np_repeat==1) { //tile + } else if (np_repeat == 1) { //tile //convert to ratio float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end); //scale to source texture return (margin_begin + ofs) * tex_pixel_size; - } else if (np_repeat==2) { //tile fit + } else if (np_repeat == 2) { //tile fit //convert to ratio float src_area = draw_size - margin_begin - margin_end; float dst_area = tex_size - margin_begin - margin_end; - float scale = max(1.0,floor(src_area / max(dst_area,0.0000001) + 0.5)); + float scale = max(1.0, floor(src_area / max(dst_area, 0.0000001) + 0.5)); //convert to ratio float ratio = (pixel - margin_begin) / src_area; - ratio = mod(ratio * scale,1.0); + ratio = mod(ratio * scale, 1.0); return (margin_begin + ratio * dst_area) * tex_pixel_size; } } - } #endif @@ -434,42 +433,39 @@ void main() { #ifdef USE_NINEPATCH - int draw_center=2; + int draw_center = 2; uv = vec2( - map_ninepatch_axis(pixel_size_interp.x,abs(dst_rect.z),color_texpixel_size.x,np_margins.x,np_margins.z,np_repeat_h,draw_center), - map_ninepatch_axis(pixel_size_interp.y,abs(dst_rect.w),color_texpixel_size.y,np_margins.y,np_margins.w,np_repeat_v,draw_center) - ); + map_ninepatch_axis(pixel_size_interp.x, abs(dst_rect.z), color_texpixel_size.x, np_margins.x, np_margins.z, np_repeat_h, draw_center), + map_ninepatch_axis(pixel_size_interp.y, abs(dst_rect.w), color_texpixel_size.y, np_margins.y, np_margins.w, np_repeat_v, draw_center)); - if (draw_center==0) { - color.a=0.0; + if (draw_center == 0) { + color.a = 0.0; } - uv = uv*src_rect.zw+src_rect.xy; //apply region if needed + uv = uv * src_rect.zw + src_rect.xy; //apply region if needed #endif if (clip_rect_uv) { - uv = clamp(uv,src_rect.xy,src_rect.xy+abs(src_rect.zw)); + uv = clamp(uv, src_rect.xy, src_rect.xy + abs(src_rect.zw)); } #endif #if !defined(COLOR_USED) -//default behavior, texture by color + //default behavior, texture by color #ifdef USE_DISTANCE_FIELD - const float smoothing = 1.0/32.0; - float distance = textureLod(color_texture, uv,0.0).a; + const float smoothing = 1.0 / 32.0; + float distance = textureLod(color_texture, uv, 0.0).a; color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a; #else - color *= texture( color_texture, uv ); + color *= texture(color_texture, uv); #endif #endif - - vec3 normal; #if defined(NORMAL_USED) @@ -480,60 +476,56 @@ void main() { #endif if (use_default_normal) { - normal.xy = textureLod(normal_texture, uv,0.0).xy * 2.0 - 1.0; - normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); - normal_used=true; + normal.xy = textureLod(normal_texture, uv, 0.0).xy * 2.0 - 1.0; + normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); + normal_used = true; } else { - normal = vec3(0.0,0.0,1.0); + normal = vec3(0.0, 0.0, 1.0); } - - #if defined(SCREEN_UV_USED) - vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size; + vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size; #endif - -{ - float normal_depth=1.0; + { + float normal_depth = 1.0; #if defined(NORMALMAP_USED) - vec3 normal_map=vec3(0.0,0.0,1.0); + vec3 normal_map = vec3(0.0, 0.0, 1.0); #endif + /* clang-format off */ + FRAGMENT_SHADER_CODE + /* clang-format on */ + #if defined(NORMALMAP_USED) - normal = mix(vec3(0.0,0.0,1.0), normal_map * vec3(2.0,-2.0,1.0) - vec3( 1.0, -1.0, 0.0 ), normal_depth ); + normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth); #endif - -} + } #ifdef DEBUG_ENCODED_32 - highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ); - color = vec4(vec3(enc32),1.0); + highp float enc32 = dot(color, highp vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1)); + color = vec4(vec3(enc32), 1.0); #endif - - color*=final_modulate; - - - + color *= final_modulate; #ifdef USE_LIGHTING - vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping + vec2 light_vec = transformed_light_uv; if (normal_used) { - normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; + normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy; } - float att=1.0; + float att = 1.0; vec2 light_uv = light_uv_interp.xy; - vec4 light = texture(light_texture,light_uv); + vec4 light = texture(light_texture, light_uv); - if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) { - color.a*=light_outside_alpha; //invisible + if (any(lessThan(light_uv_interp.xy, vec2(0.0, 0.0))) || any(greaterThanEqual(light_uv_interp.xy, vec2(1.0, 1.0)))) { + color.a *= light_outside_alpha; //invisible } else { float real_light_height = light_height; @@ -541,178 +533,176 @@ FRAGMENT_SHADER_CODE vec4 real_light_shadow_color = light_shadow_color; #if defined(USE_LIGHT_SHADER_CODE) -//light is written by the light shader + //light is written by the light shader light_compute( - light, - light_vec, - real_light_height, - real_light_color, - light_uv, - real_light_shadow_color, - normal, - uv, + light, + light_vec, + real_light_height, + real_light_color, + light_uv, + real_light_shadow_color, + normal, + uv, #if defined(SCREEN_UV_USED) - screen_uv, + screen_uv, #endif - color); + color); #endif light *= real_light_color; if (normal_used) { - vec3 light_normal = normalize(vec3(light_vec,-real_light_height)); - light*=max(dot(-light_normal,normal),0.0); + vec3 light_normal = normalize(vec3(light_vec, -real_light_height)); + light *= max(dot(-light_normal, normal), 0.0); } - color*=light; + color *= light; #ifdef USE_SHADOWS - - float angle_to_light = -atan(light_vec.x,light_vec.y); + light_vec = light_uv_interp.zw; //for shadows + float angle_to_light = -atan(light_vec.x, light_vec.y); float PI = 3.14159265358979323846264; /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays float ang*/ - float su,sz; + float su, sz; float abs_angle = abs(angle_to_light); vec2 point; float sh; - if (abs_angle<45.0*PI/180.0) { + if (abs_angle < 45.0 * PI / 180.0) { point = light_vec; - sh=0.0+(1.0/8.0); - } else if (abs_angle>135.0*PI/180.0) { + sh = 0.0 + (1.0 / 8.0); + } else if (abs_angle > 135.0 * PI / 180.0) { point = -light_vec; - sh = 0.5+(1.0/8.0); - } else if (angle_to_light>0.0) { + sh = 0.5 + (1.0 / 8.0); + } else if (angle_to_light > 0.0) { - point = vec2(light_vec.y,-light_vec.x); - sh = 0.25+(1.0/8.0); + point = vec2(light_vec.y, -light_vec.x); + sh = 0.25 + (1.0 / 8.0); } else { - point = vec2(-light_vec.y,light_vec.x); - sh = 0.75+(1.0/8.0); - + point = vec2(-light_vec.y, light_vec.x); + sh = 0.75 + (1.0 / 8.0); } - - highp vec4 s = shadow_matrix * vec4(point,0.0,1.0); - s.xyz/=s.w; - su=s.x*0.5+0.5; - sz=s.z*0.5+0.5; + highp vec4 s = shadow_matrix * vec4(point, 0.0, 1.0); + s.xyz /= s.w; + su = s.x * 0.5 + 0.5; + sz = s.z * 0.5 + 0.5; //sz=lightlength(light_vec); - highp float shadow_attenuation=0.0; + highp float shadow_attenuation = 0.0; #ifdef USE_RGBA_SHADOWS -#define SHADOW_DEPTH(m_tex,m_uv) dot(texture((m_tex),(m_uv)),vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ) +#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1)) #else -#define SHADOW_DEPTH(m_tex,m_uv) (texture((m_tex),(m_uv)).r) +#define SHADOW_DEPTH(m_tex, m_uv) (texture((m_tex), (m_uv)).r) #endif - - #ifdef SHADOW_USE_GRADIENT -#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture,vec2(m_ofs,sh)); shadow_attenuation+=1.0-smoothstep(sd,sd+shadow_gradient,sz); } +#define SHADOW_TEST(m_ofs) \ + { \ + highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); \ + shadow_attenuation += 1.0 - smoothstep(sd, sd + shadow_gradient, sz); \ + } #else -#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture,vec2(m_ofs,sh)); shadow_attenuation+=step(sz,sd); } +#define SHADOW_TEST(m_ofs) \ + { \ + highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); \ + shadow_attenuation += step(sz, sd); \ + } #endif - #ifdef SHADOW_FILTER_NEAREST SHADOW_TEST(su); #endif - #ifdef SHADOW_FILTER_PCF3 - SHADOW_TEST(su+shadowpixel_size); + SHADOW_TEST(su + shadowpixel_size); SHADOW_TEST(su); - SHADOW_TEST(su-shadowpixel_size); - shadow_attenuation/=3.0; + SHADOW_TEST(su - shadowpixel_size); + shadow_attenuation /= 3.0; #endif - #ifdef SHADOW_FILTER_PCF5 - SHADOW_TEST(su+shadowpixel_size*2.0); - SHADOW_TEST(su+shadowpixel_size); + SHADOW_TEST(su + shadowpixel_size * 2.0); + SHADOW_TEST(su + shadowpixel_size); SHADOW_TEST(su); - SHADOW_TEST(su-shadowpixel_size); - SHADOW_TEST(su-shadowpixel_size*2.0); - shadow_attenuation/=5.0; + SHADOW_TEST(su - shadowpixel_size); + SHADOW_TEST(su - shadowpixel_size * 2.0); + shadow_attenuation /= 5.0; #endif - #ifdef SHADOW_FILTER_PCF7 - SHADOW_TEST(su+shadowpixel_size*3.0); - SHADOW_TEST(su+shadowpixel_size*2.0); - SHADOW_TEST(su+shadowpixel_size); + SHADOW_TEST(su + shadowpixel_size * 3.0); + SHADOW_TEST(su + shadowpixel_size * 2.0); + SHADOW_TEST(su + shadowpixel_size); SHADOW_TEST(su); - SHADOW_TEST(su-shadowpixel_size); - SHADOW_TEST(su-shadowpixel_size*2.0); - SHADOW_TEST(su-shadowpixel_size*3.0); - shadow_attenuation/=7.0; + SHADOW_TEST(su - shadowpixel_size); + SHADOW_TEST(su - shadowpixel_size * 2.0); + SHADOW_TEST(su - shadowpixel_size * 3.0); + shadow_attenuation /= 7.0; #endif - #ifdef SHADOW_FILTER_PCF9 - SHADOW_TEST(su+shadowpixel_size*4.0); - SHADOW_TEST(su+shadowpixel_size*3.0); - SHADOW_TEST(su+shadowpixel_size*2.0); - SHADOW_TEST(su+shadowpixel_size); + SHADOW_TEST(su + shadowpixel_size * 4.0); + SHADOW_TEST(su + shadowpixel_size * 3.0); + SHADOW_TEST(su + shadowpixel_size * 2.0); + SHADOW_TEST(su + shadowpixel_size); SHADOW_TEST(su); - SHADOW_TEST(su-shadowpixel_size); - SHADOW_TEST(su-shadowpixel_size*2.0); - SHADOW_TEST(su-shadowpixel_size*3.0); - SHADOW_TEST(su-shadowpixel_size*4.0); - shadow_attenuation/=9.0; + SHADOW_TEST(su - shadowpixel_size); + SHADOW_TEST(su - shadowpixel_size * 2.0); + SHADOW_TEST(su - shadowpixel_size * 3.0); + SHADOW_TEST(su - shadowpixel_size * 4.0); + shadow_attenuation /= 9.0; #endif #ifdef SHADOW_FILTER_PCF13 - SHADOW_TEST(su+shadowpixel_size*6.0); - SHADOW_TEST(su+shadowpixel_size*5.0); - SHADOW_TEST(su+shadowpixel_size*4.0); - SHADOW_TEST(su+shadowpixel_size*3.0); - SHADOW_TEST(su+shadowpixel_size*2.0); - SHADOW_TEST(su+shadowpixel_size); + SHADOW_TEST(su + shadowpixel_size * 6.0); + SHADOW_TEST(su + shadowpixel_size * 5.0); + SHADOW_TEST(su + shadowpixel_size * 4.0); + SHADOW_TEST(su + shadowpixel_size * 3.0); + SHADOW_TEST(su + shadowpixel_size * 2.0); + SHADOW_TEST(su + shadowpixel_size); SHADOW_TEST(su); - SHADOW_TEST(su-shadowpixel_size); - SHADOW_TEST(su-shadowpixel_size*2.0); - SHADOW_TEST(su-shadowpixel_size*3.0); - SHADOW_TEST(su-shadowpixel_size*4.0); - SHADOW_TEST(su-shadowpixel_size*5.0); - SHADOW_TEST(su-shadowpixel_size*6.0); - shadow_attenuation/=13.0; + SHADOW_TEST(su - shadowpixel_size); + SHADOW_TEST(su - shadowpixel_size * 2.0); + SHADOW_TEST(su - shadowpixel_size * 3.0); + SHADOW_TEST(su - shadowpixel_size * 4.0); + SHADOW_TEST(su - shadowpixel_size * 5.0); + SHADOW_TEST(su - shadowpixel_size * 6.0); + shadow_attenuation /= 13.0; #endif - //color*=shadow_attenuation; - color=mix(real_light_shadow_color,color,shadow_attenuation); + //color *= shadow_attenuation; + color = mix(real_light_shadow_color, color, shadow_attenuation); //use shadows #endif } //use lighting #endif - //color.rgb*=color.a; + //color.rgb *= color.a; frag_color = color; - } diff --git a/drivers/gles3/shaders/canvas_shadow.glsl b/drivers/gles3/shaders/canvas_shadow.glsl index c757990de0..68d0713385 100644 --- a/drivers/gles3/shaders/canvas_shadow.glsl +++ b/drivers/gles3/shaders/canvas_shadow.glsl @@ -1,49 +1,45 @@ +/* clang-format off */ [vertex] - - uniform highp mat4 projection_matrix; +/* clang-format on */ uniform highp mat4 light_matrix; uniform highp mat4 world_matrix; uniform highp float distance_norm; -layout(location=0) in highp vec3 vertex; +layout(location = 0) in highp vec3 vertex; out highp vec4 position_interp; void main() { - gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex,1.0))); - position_interp=gl_Position; + gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex, 1.0))); + position_interp = gl_Position; } +/* clang-format off */ [fragment] in highp vec4 position_interp; +/* clang-format on */ #ifdef USE_RGBA_SHADOWS - -layout(location=0) out lowp vec4 distance_buf; - +layout(location = 0) out lowp vec4 distance_buf; #else - -layout(location=0) out highp float distance_buf; - +layout(location = 0) out highp float distance_buf; #endif void main() { - highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0;//bias; + highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias #ifdef USE_RGBA_SHADOWS highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); - distance_buf=comp; + distance_buf = comp; #else - distance_buf=depth; - + distance_buf = depth; #endif } - diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index 1b7c626d3c..a5637537d2 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -1,13 +1,14 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) -layout(location=4) in vec3 cube_in; +layout(location = 4) in vec3 cube_in; #else -layout(location=4) in vec2 uv_in; +layout(location = 4) in vec2 uv_in; #endif -layout(location=5) in vec2 uv2_in; +layout(location = 5) in vec2 uv2_in; #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) out vec3 cube_interp; @@ -32,7 +33,7 @@ void main() { #else uv_interp = uv_in; #ifdef V_FLIP - uv_interp.y = 1.0-uv_interp.y; + uv_interp.y = 1.0 - uv_interp.y; #endif #endif @@ -44,9 +45,9 @@ void main() { uv_interp = copy_section.xy + uv_interp * copy_section.zw; gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0; #endif - } +/* clang-format off */ [fragment] #define M_PI 3.14159265359 @@ -60,6 +61,7 @@ in vec3 cube_interp; #else in vec2 uv_interp; #endif +/* clang-format on */ #ifdef USE_ASYM_PANO uniform highp mat4 pano_transform; @@ -72,38 +74,33 @@ uniform samplerCube source_cube; //texunit:0 uniform sampler2D source; //texunit:0 #endif - #ifdef USE_MULTIPLIER uniform float multiplier; #endif #if defined(USE_PANORAMA) || defined(USE_ASYM_PANO) -vec4 texturePanorama(vec3 normal,sampler2D pano ) { +vec4 texturePanorama(vec3 normal, sampler2D pano) { vec2 st = vec2( - atan(normal.x, normal.z), - acos(normal.y) - ); - - if(st.x < 0.0) - st.x += M_PI*2.0; + atan(normal.x, normal.z), + acos(normal.y)); - st/=vec2(M_PI*2.0,M_PI); + if (st.x < 0.0) + st.x += M_PI * 2.0; - return textureLod(pano,st,0.0); + st /= vec2(M_PI * 2.0, M_PI); + return textureLod(pano, st, 0.0); } #endif - uniform float stuff; uniform vec2 pixel_size; in vec2 uv2_interp; - #ifdef USE_BCS uniform vec3 bcs; @@ -118,20 +115,17 @@ uniform sampler2D color_correction; //texunit:1 layout(location = 0) out vec4 frag_color; - - - void main() { //vec4 color = color_interp; #ifdef USE_PANORAMA - vec4 color = texturePanorama( normalize(cube_interp), source ); + vec4 color = texturePanorama(normalize(cube_interp), source); #elif defined(USE_ASYM_PANO) - // When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result. + // When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result. // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1. // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image. @@ -142,72 +136,68 @@ void main() { cube_normal = mat3(pano_transform) * cube_normal; cube_normal.z = -cube_normal.z; - vec4 color = texturePanorama( normalize(cube_normal.xyz), source ); + vec4 color = texturePanorama(normalize(cube_normal.xyz), source); #elif defined(USE_CUBEMAP) - vec4 color = texture( source_cube, normalize(cube_interp) ); + vec4 color = texture(source_cube, normalize(cube_interp)); #else - vec4 color = textureLod( source, uv_interp,0.0 ); + vec4 color = textureLod(source, uv_interp, 0.0); #endif - - #ifdef LINEAR_TO_SRGB //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))); + 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))); #endif #ifdef SRGB_TO_LINEAR - color.rgb = mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),color.rgb * (1.0 / 12.92),lessThan(color.rgb,vec3(0.04045))); + color.rgb = mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045))); #endif #ifdef DEBUG_GRADIENT - color.rg=uv_interp; - color.b=0.0; + color.rg = uv_interp; + color.b = 0.0; #endif #ifdef DISABLE_ALPHA - color.a=1.0; + color.a = 1.0; #endif - #ifdef GAUSSIAN_HORIZONTAL - color*=0.38774; - color+=texture( source, uv_interp+vec2( 1.0, 0.0)*pixel_size )*0.24477; - color+=texture( source, uv_interp+vec2( 2.0, 0.0)*pixel_size )*0.06136; - color+=texture( source, uv_interp+vec2(-1.0, 0.0)*pixel_size )*0.24477; - color+=texture( source, uv_interp+vec2(-2.0, 0.0)*pixel_size )*0.06136; + color *= 0.38774; + color += texture(source, uv_interp + vec2(1.0, 0.0) * pixel_size) * 0.24477; + color += texture(source, uv_interp + vec2(2.0, 0.0) * pixel_size) * 0.06136; + color += texture(source, uv_interp + vec2(-1.0, 0.0) * pixel_size) * 0.24477; + color += texture(source, uv_interp + vec2(-2.0, 0.0) * pixel_size) * 0.06136; #endif #ifdef GAUSSIAN_VERTICAL - color*=0.38774; - color+=texture( source, uv_interp+vec2( 0.0, 1.0)*pixel_size )*0.24477; - color+=texture( source, uv_interp+vec2( 0.0, 2.0)*pixel_size )*0.06136; - color+=texture( source, uv_interp+vec2( 0.0,-1.0)*pixel_size )*0.24477; - color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136; + color *= 0.38774; + color += texture(source, uv_interp + vec2(0.0, 1.0) * pixel_size) * 0.24477; + color += texture(source, uv_interp + vec2(0.0, 2.0) * pixel_size) * 0.06136; + color += texture(source, uv_interp + vec2(0.0, -1.0) * pixel_size) * 0.24477; + color += texture(source, uv_interp + vec2(0.0, -2.0) * pixel_size) * 0.06136; #endif #ifdef USE_BCS - color.rgb = mix(vec3(0.0),color.rgb,bcs.x); - color.rgb = mix(vec3(0.5),color.rgb,bcs.y); - color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z); + color.rgb = mix(vec3(0.0), color.rgb, bcs.x); + color.rgb = mix(vec3(0.5), color.rgb, bcs.y); + color.rgb = mix(vec3(dot(vec3(1.0), color.rgb) * 0.33333), color.rgb, bcs.z); #endif #ifdef USE_COLOR_CORRECTION - color.r = texture(color_correction,vec2(color.r,0.0)).r; - color.g = texture(color_correction,vec2(color.g,0.0)).g; - color.b = texture(color_correction,vec2(color.b,0.0)).b; + color.r = texture(color_correction, vec2(color.r, 0.0)).r; + color.g = texture(color_correction, vec2(color.g, 0.0)).g; + color.b = texture(color_correction, vec2(color.b, 0.0)).b; #endif #ifdef USE_MULTIPLIER - color.rgb*=multiplier; + color.rgb *= multiplier; #endif frag_color = color; } - diff --git a/drivers/gles3/shaders/cube_to_dp.glsl b/drivers/gles3/shaders/cube_to_dp.glsl index 5ffc78c0b9..2b74f054f9 100644 --- a/drivers/gles3/shaders/cube_to_dp.glsl +++ b/drivers/gles3/shaders/cube_to_dp.glsl @@ -1,8 +1,9 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; @@ -12,10 +13,11 @@ void main() { gl_Position = vertex_attrib; } +/* clang-format off */ [fragment] - uniform highp samplerCube source_cube; //texunit:0 +/* clang-format on */ in vec2 uv_interp; uniform bool z_flip; @@ -25,55 +27,53 @@ uniform highp float bias; void main() { - highp vec3 normal = vec3( uv_interp * 2.0 - 1.0, 0.0 ); -/* - if(z_flip) { - normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y)); + highp vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0); + /* + if (z_flip) { + normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); } else { - normal.z = -0.5 + 0.5*((normal.x * normal.x) + (normal.y * normal.y)); + normal.z = -0.5 + 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); } -*/ + */ - //normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); - //normal.xy*=1.0+normal.z; + //normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); + //normal.xy *= 1.0 + normal.z; - normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y)); + normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); + normal = normalize(normal); + /* + normal.z = 0.5; normal = normalize(normal); + */ -/* - normal.z=0.5; - normal=normalize(normal); -*/ if (!z_flip) { - normal.z=-normal.z; + normal.z = -normal.z; } - //normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 )); - float depth = texture(source_cube,normal).r; + //normal = normalize(vec3(uv_interp * 2.0 - 1.0, 1.0)); + float depth = texture(source_cube, normal).r; // absolute values for direction cosines, bigger value equals closer to basis axis vec3 unorm = abs(normal); - if ( (unorm.x >= unorm.y) && (unorm.x >= unorm.z) ) { - // x code - unorm = normal.x > 0.0 ? vec3( 1.0, 0.0, 0.0 ) : vec3( -1.0, 0.0, 0.0 ) ; - } else if ( (unorm.y > unorm.x) && (unorm.y >= unorm.z) ) { - // y code - unorm = normal.y > 0.0 ? vec3( 0.0, 1.0, 0.0 ) : vec3( 0.0, -1.0, 0.0 ) ; - } else if ( (unorm.z > unorm.x) && (unorm.z > unorm.y) ) { - // z code - unorm = normal.z > 0.0 ? vec3( 0.0, 0.0, 1.0 ) : vec3( 0.0, 0.0, -1.0 ) ; + if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) { + // x code + unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0); + } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) { + // y code + unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0); + } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) { + // z code + unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0); } else { - // oh-no we messed up code - // has to be - unorm = vec3( 1.0, 0.0, 0.0 ); + // oh-no we messed up code + // has to be + unorm = vec3(1.0, 0.0, 0.0); } - float depth_fix = 1.0 / dot(normal,unorm); - + float depth_fix = 1.0 / dot(normal, unorm); depth = 2.0 * depth - 1.0; float linear_depth = 2.0 * z_near * z_far / (z_far + z_near - depth * (z_far - z_near)); - gl_FragDepth = (linear_depth*depth_fix+bias) / z_far; + gl_FragDepth = (linear_depth * depth_fix + bias) / z_far; } - diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index 485fbb6ee0..f65f798ff0 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -1,22 +1,24 @@ +/* clang-format off */ [vertex] +layout(location = 0) in highp vec2 vertex; +/* clang-format on */ -layout(location=0) in highp vec2 vertex; - -layout(location=4) in highp vec2 uv; +layout(location = 4) in highp vec2 uv; out highp vec2 uv_interp; void main() { - uv_interp=uv; - gl_Position=vec4(vertex,0,1); + uv_interp = uv; + gl_Position = vec4(vertex, 0, 1); } +/* clang-format off */ [fragment] - precision highp float; +/* clang-format on */ precision highp int; #ifdef USE_SOURCE_PANORAMA @@ -36,90 +38,85 @@ uniform int face_id; uniform float roughness; in highp vec2 uv_interp; - layout(location = 0) out vec4 frag_color; - #define M_PI 3.14159265359 - -vec3 texelCoordToVec(vec2 uv, int faceID) -{ - mat3 faceUvVectors[6]; -/* - // -x - faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z - faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face - - // +x - faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z - faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face - - // -y - faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x - faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z - faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face - - // +y - faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x - faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z - faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face - - // -z - faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x - faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face - - // +z - faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x - faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face -*/ - - // -x - faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z - faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face - - // +x - faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z - faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face - - // -y - faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x - faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z - faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face - - // +y - faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x - faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z - faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face - - // -z - faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x - faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face - - // +z - faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x - faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y - faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face - - // out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2]. - vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2]; - return normalize(result); +vec3 texelCoordToVec(vec2 uv, int faceID) { + mat3 faceUvVectors[6]; + /* + // -x + faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z + faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face + + // +x + faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z + faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face + + // -y + faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z + faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face + + // +y + faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z + faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face + + // -z + faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x + faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face + + // +z + faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face + */ + + // -x + faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z + faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face + + // +x + faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z + faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face + + // -y + faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z + faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face + + // +y + faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z + faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face + + // -z + faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x + faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face + + // +z + faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face + + // out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2]. + vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2]; + return normalize(result); } -vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) -{ +vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) { float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph] // Compute distribution direction float Phi = 2.0 * M_PI * Xi.x; - float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y)); float SinTheta = sqrt(1.0 - CosTheta * CosTheta); // Convert to spherical direction @@ -137,33 +134,29 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) } // http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float GGX(float NdotV, float a) -{ +float GGX(float NdotV, float a) { float k = a / 2.0; return NdotV / (NdotV * (1.0 - k) + k); } // http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float G_Smith(float a, float nDotV, float nDotL) -{ +float G_Smith(float a, float nDotV, float nDotL) { return GGX(nDotL, a * a) * GGX(nDotV, a * a); } float radicalInverse_VdC(uint bits) { - bits = (bits << 16u) | (bits >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - return float(bits) * 2.3283064365386963e-10; // / 0x100000000 + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 } vec2 Hammersley(uint i, uint N) { - return vec2(float(i)/float(N), radicalInverse_VdC(i)); + return vec2(float(i) / float(N), radicalInverse_VdC(i)); } - - #ifdef LOW_QUALITY #define SAMPLE_COUNT 64u @@ -178,37 +171,33 @@ uniform bool z_flip; #ifdef USE_SOURCE_PANORAMA -vec4 texturePanorama(vec3 normal,sampler2D pano ) { +vec4 texturePanorama(vec3 normal, sampler2D pano) { vec2 st = vec2( - atan(normal.x, normal.z), - acos(normal.y) - ); - - if(st.x < 0.0) - st.x += M_PI*2.0; + atan(normal.x, normal.z), + acos(normal.y)); - st/=vec2(M_PI*2.0,M_PI); + if (st.x < 0.0) + st.x += M_PI * 2.0; - return textureLod(pano,st,0.0); + st /= vec2(M_PI * 2.0, M_PI); + return textureLod(pano, st, 0.0); } #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; + 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); - + return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index)), 0.0); } #endif @@ -217,19 +206,18 @@ void main() { #ifdef USE_DUAL_PARABOLOID - vec3 N = vec3( uv_interp * 2.0 - 1.0, 0.0 ); - N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y)); + vec3 N = vec3(uv_interp * 2.0 - 1.0, 0.0); + N.z = 0.5 - 0.5 * ((N.x * N.x) + (N.y * N.y)); N = normalize(N); if (z_flip) { - N.y=-N.y; //y is flipped to improve blending between both sides - N.z=-N.z; + N.y = -N.y; //y is flipped to improve blending between both sides + N.z = -N.z; } - #else - vec2 uv = (uv_interp * 2.0) - 1.0; - vec3 N = texelCoordToVec(uv, face_id); + vec2 uv = (uv_interp * 2.0) - 1.0; + vec3 N = texelCoordToVec(uv, face_id); #endif //vec4 color = color_interp; @@ -237,49 +225,46 @@ void main() { #ifdef USE_SOURCE_PANORAMA - frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0); + frag_color = vec4(texturePanorama(N, source_panorama).rgb, 1.0); #endif #ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY - frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0); + 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); + 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); - for(uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) { + for (uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) { vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT); - vec3 H = ImportanceSampleGGX( xi, roughness, N ); - vec3 V = N; - vec3 L = normalize(2.0 * dot( V, H ) * H - V); + vec3 H = ImportanceSampleGGX(xi, roughness, N); + vec3 V = N; + vec3 L = (2.0 * dot(V, H) * H - V); - float ndotl = clamp(dot(N, L),0.0,1.0); + float ndotl = clamp(dot(N, L), 0.0, 1.0); - if (ndotl>0.0) { + if (ndotl > 0.0) { #ifdef USE_SOURCE_PANORAMA - sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl; + sum.rgb += texturePanorama(L, source_panorama).rgb * ndotl; #endif #ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY - sum.rgb += textureDualParaboloidArray(H).rgb *ndotl; + sum.rgb += textureDualParaboloidArray(L).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; + L.y = -L.y; + sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl; #endif sum.a += ndotl; } @@ -289,6 +274,4 @@ void main() { frag_color = vec4(sum.rgb, 1.0); #endif - } - diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index c8567b4d53..b67d06bc10 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -1,8 +1,9 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; @@ -23,11 +24,13 @@ void main() { #endif } +/* clang-format off */ [fragment] #if !defined(GLES_OVER_GL) precision mediump float; #endif +/* clang-format on */ in vec2 uv_interp; uniform sampler2D source_color; //texunit:0 @@ -39,7 +42,6 @@ uniform sampler2D source_ssao; //texunit:1 uniform float lod; uniform vec2 pixel_size; - layout(location = 0) out vec4 frag_color; #ifdef SSAO_MERGE @@ -48,31 +50,31 @@ uniform vec4 ssao_color; #endif -#if defined (GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL) +#if defined(GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL) uniform float glow_strength; #endif -#if defined(DOF_FAR_BLUR) || defined (DOF_NEAR_BLUR) +#if defined(DOF_FAR_BLUR) || defined(DOF_NEAR_BLUR) #ifdef DOF_QUALITY_LOW -const int dof_kernel_size=5; -const int dof_kernel_from=2; -const float dof_kernel[5] = float[] (0.153388,0.221461,0.250301,0.221461,0.153388); +const int dof_kernel_size = 5; +const int dof_kernel_from = 2; +const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388); #endif #ifdef DOF_QUALITY_MEDIUM -const int dof_kernel_size=11; -const int dof_kernel_from=5; -const float dof_kernel[11] = float[] (0.055037,0.072806,0.090506,0.105726,0.116061,0.119726,0.116061,0.105726,0.090506,0.072806,0.055037); +const int dof_kernel_size = 11; +const int dof_kernel_from = 5; +const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037); #endif #ifdef DOF_QUALITY_HIGH -const int dof_kernel_size=21; -const int dof_kernel_from=10; -const float dof_kernel[21] = float[] (0.028174,0.032676,0.037311,0.041944,0.046421,0.050582,0.054261,0.057307,0.059587,0.060998,0.061476,0.060998,0.059587,0.057307,0.054261,0.050582,0.046421,0.041944,0.037311,0.032676,0.028174); +const int dof_kernel_size = 21; +const int dof_kernel_from = 10; +const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174); #endif uniform sampler2D dof_source_depth; //texunit:1 @@ -88,7 +90,6 @@ uniform sampler2D source_dof_original; //texunit:2 #endif - #ifdef GLOW_FIRST_PASS uniform float exposure; @@ -112,53 +113,51 @@ uniform float camera_z_near; void main() { - - #ifdef GAUSSIAN_HORIZONTAL vec2 pix_size = pixel_size; - pix_size*=0.5; //reading from larger buffer, so use more samples - vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.214607; - color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.189879; - color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.157305; - color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.071303; - color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.189879; - color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.157305; - color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.071303; + pix_size *= 0.5; //reading from larger buffer, so use more samples + vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.214607; + color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.189879; + color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.157305; + color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.071303; + color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.189879; + color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.157305; + color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.071303; frag_color = color; #endif #ifdef GAUSSIAN_VERTICAL - vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pixel_size,lod )*0.38774; - color+=textureLod( source_color, uv_interp+vec2( 0.0, 1.0)*pixel_size,lod )*0.24477; - color+=textureLod( source_color, uv_interp+vec2( 0.0, 2.0)*pixel_size,lod )*0.06136; - color+=textureLod( source_color, uv_interp+vec2( 0.0,-1.0)*pixel_size,lod )*0.24477; - color+=textureLod( source_color, uv_interp+vec2( 0.0,-2.0)*pixel_size,lod )*0.06136; + vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.38774; + color += textureLod(source_color, uv_interp + vec2(0.0, 1.0) * pixel_size, lod) * 0.24477; + color += textureLod(source_color, uv_interp + vec2(0.0, 2.0) * pixel_size, lod) * 0.06136; + color += textureLod(source_color, uv_interp + vec2(0.0, -1.0) * pixel_size, lod) * 0.24477; + color += textureLod(source_color, uv_interp + vec2(0.0, -2.0) * pixel_size, lod) * 0.06136; frag_color = color; #endif -//glow uses larger sigma for a more rounded blur effect + //glow uses larger sigma for a more rounded blur effect #ifdef GLOW_GAUSSIAN_HORIZONTAL vec2 pix_size = pixel_size; - pix_size*=0.5; //reading from larger buffer, so use more samples - vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.174938; - color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.165569; - color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.140367; - color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.106595; - color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.165569; - color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.140367; - color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.106595; - color*=glow_strength; + pix_size *= 0.5; //reading from larger buffer, so use more samples + vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.174938; + color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.165569; + color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.140367; + color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.106595; + color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.165569; + color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.140367; + color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.106595; + color *= glow_strength; frag_color = color; #endif #ifdef GLOW_GAUSSIAN_VERTICAL - vec4 color =textureLod( source_color, uv_interp+vec2(0.0, 0.0)*pixel_size,lod )*0.288713; - color+=textureLod( source_color, uv_interp+vec2(0.0, 1.0)*pixel_size,lod )*0.233062; - color+=textureLod( source_color, uv_interp+vec2(0.0, 2.0)*pixel_size,lod )*0.122581; - color+=textureLod( source_color, uv_interp+vec2(0.0,-1.0)*pixel_size,lod )*0.233062; - color+=textureLod( source_color, uv_interp+vec2(0.0,-2.0)*pixel_size,lod )*0.122581; - color*=glow_strength; + vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.288713; + color += textureLod(source_color, uv_interp + vec2(0.0, 1.0) * pixel_size, lod) * 0.233062; + color += textureLod(source_color, uv_interp + vec2(0.0, 2.0) * pixel_size, lod) * 0.122581; + color += textureLod(source_color, uv_interp + vec2(0.0, -1.0) * pixel_size, lod) * 0.233062; + color += textureLod(source_color, uv_interp + vec2(0.0, -2.0) * pixel_size, lod) * 0.122581; + color *= glow_strength; frag_color = color; #endif @@ -166,47 +165,45 @@ void main() { vec4 color_accum = vec4(0.0); - float depth = textureLod( dof_source_depth, uv_interp, 0.0).r; + float depth = textureLod(dof_source_depth, uv_interp, 0.0).r; depth = depth * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); #endif - float amount = smoothstep(dof_begin,dof_end,depth); - float k_accum=0.0; + float amount = smoothstep(dof_begin, dof_end, depth); + float k_accum = 0.0; - for(int i=0;i<dof_kernel_size;i++) { + for (int i = 0; i < dof_kernel_size; i++) { - int int_ofs = i-dof_kernel_from; + int int_ofs = i - dof_kernel_from; vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius; float tap_k = dof_kernel[i]; - float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; + float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; tap_depth = tap_depth * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + tap_depth = ((tap_depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); #endif - float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0); - tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect - - vec4 tap_color = textureLod( source_color, tap_uv, 0.0) * tap_k; - - k_accum+=tap_k*tap_amount; - color_accum+=tap_color*tap_amount; + float tap_amount = mix(smoothstep(dof_begin, dof_end, tap_depth), 1.0, int_ofs == 0); + tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect + vec4 tap_color = textureLod(source_color, tap_uv, 0.0) * tap_k; + k_accum += tap_k * tap_amount; + color_accum += tap_color * tap_amount; } - if (k_accum>0.0) { - color_accum/=k_accum; + if (k_accum > 0.0) { + color_accum /= k_accum; } - frag_color = color_accum;///k_accum; + frag_color = color_accum; ///k_accum; #endif @@ -214,47 +211,45 @@ void main() { vec4 color_accum = vec4(0.0); - float max_accum=0.0; + float max_accum = 0.0; - for(int i=0;i<dof_kernel_size;i++) { + for (int i = 0; i < dof_kernel_size; i++) { - int int_ofs = i-dof_kernel_from; + int int_ofs = i - dof_kernel_from; vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius; - float ofs_influence = max(0.0,1.0-float(abs(int_ofs))/float(dof_kernel_from)); + float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from)); float tap_k = dof_kernel[i]; - vec4 tap_color = textureLod( source_color, tap_uv, 0.0); + vec4 tap_color = textureLod(source_color, tap_uv, 0.0); - float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; + float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; tap_depth = tap_depth * 2.0 - 1.0; -#ifdef USE_ORTHOGONAL_PROJECTION - tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#ifdef USE_ORTHOGONAL_PROJECTION + tap_depth = ((tap_depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); #endif - float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth); - tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect + float tap_amount = 1.0 - smoothstep(dof_end, dof_begin, tap_depth); + tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect #ifdef DOF_NEAR_FIRST_TAP - tap_color.a= 1.0-smoothstep(dof_end,dof_begin,tap_depth); + tap_color.a = 1.0 - smoothstep(dof_end, dof_begin, tap_depth); #endif - max_accum=max(max_accum,tap_amount*ofs_influence); - - color_accum+=tap_color*tap_k; + max_accum = max(max_accum, tap_amount * ofs_influence); + color_accum += tap_color * tap_k; } - color_accum.a=max(color_accum.a,sqrt(max_accum)); - + color_accum.a = max(color_accum.a, sqrt(max_accum)); #ifdef DOF_NEAR_BLUR_MERGE - vec4 original = textureLod( source_dof_original, uv_interp, 0.0); - color_accum = mix(original,color_accum,color_accum.a); + vec4 original = textureLod(source_dof_original, uv_interp, 0.0); + color_accum = mix(original, color_accum, color_accum.a); #endif @@ -265,37 +260,32 @@ void main() { #endif - - #ifdef GLOW_FIRST_PASS #ifdef GLOW_USE_AUTO_EXPOSURE - frag_color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; + frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey; #endif - frag_color*=exposure; + frag_color *= exposure; - float luminance = max(frag_color.r,max(frag_color.g,frag_color.b)); - float feedback = max( smoothstep(glow_hdr_threshold,glow_hdr_threshold+glow_hdr_scale,luminance), glow_bloom ); + float luminance = max(frag_color.r, max(frag_color.g, frag_color.b)); + float feedback = max(smoothstep(glow_hdr_threshold, glow_hdr_threshold + glow_hdr_scale, luminance), glow_bloom); frag_color *= feedback; #endif - #ifdef SIMPLE_COPY - vec4 color =textureLod( source_color, uv_interp,0.0); + vec4 color = textureLod(source_color, uv_interp, 0.0); frag_color = color; #endif #ifdef SSAO_MERGE - vec4 color =textureLod( source_color, uv_interp,0.0); - float ssao =textureLod( source_ssao, uv_interp,0.0).r; + vec4 color = textureLod(source_color, uv_interp, 0.0); + float ssao = textureLod(source_ssao, uv_interp, 0.0).r; - frag_color = vec4( mix(color.rgb,color.rgb*mix(ssao_color.rgb,vec3(1.0),ssao),color.a), 1.0 ); + frag_color = vec4(mix(color.rgb, color.rgb * mix(ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0); #endif - - } diff --git a/drivers/gles3/shaders/exposure.glsl b/drivers/gles3/shaders/exposure.glsl index 001b90a0f1..759adcda06 100644 --- a/drivers/gles3/shaders/exposure.glsl +++ b/drivers/gles3/shaders/exposure.glsl @@ -1,19 +1,19 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; - +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ void main() { gl_Position = vertex_attrib; - } +/* clang-format off */ [fragment] - uniform highp sampler2D source_exposure; //texunit:0 +/* clang-format on */ #ifdef EXPOSURE_BEGIN @@ -33,66 +33,56 @@ uniform highp float max_luminance; layout(location = 0) out highp float exposure; - - void main() { - - #ifdef EXPOSURE_BEGIN - - ivec2 src_pos = ivec2(gl_FragCoord.xy)*source_render_size/target_size; + ivec2 src_pos = ivec2(gl_FragCoord.xy) * source_render_size / target_size; #if 1 //more precise and expensive, but less jittery - ivec2 next_pos = ivec2(gl_FragCoord.xy+ivec2(1))*source_render_size/target_size; - next_pos = max(next_pos,src_pos+ivec2(1)); //so it at least reads one pixel - highp vec3 source_color=vec3(0.0); - for(int i=src_pos.x;i<next_pos.x;i++) { - for(int j=src_pos.y;j<next_pos.y;j++) { - source_color += texelFetch(source_exposure,ivec2(i,j),0).rgb; + ivec2 next_pos = ivec2(gl_FragCoord.xy + ivec2(1)) * source_render_size / target_size; + next_pos = max(next_pos, src_pos + ivec2(1)); //so it at least reads one pixel + highp vec3 source_color = vec3(0.0); + for (int i = src_pos.x; i < next_pos.x; i++) { + for (int j = src_pos.y; j < next_pos.y; j++) { + source_color += texelFetch(source_exposure, ivec2(i, j), 0).rgb; } } - source_color/=float( (next_pos.x-src_pos.x)*(next_pos.y-src_pos.y) ); + source_color /= float((next_pos.x - src_pos.x) * (next_pos.y - src_pos.y)); #else - highp vec3 source_color = texelFetch(source_exposure,src_pos,0).rgb; + highp vec3 source_color = texelFetch(source_exposure, src_pos, 0).rgb; #endif - exposure = max(source_color.r,max(source_color.g,source_color.b)); + exposure = max(source_color.r, max(source_color.g, source_color.b)); #else ivec2 coord = ivec2(gl_FragCoord.xy); - exposure = texelFetch(source_exposure,coord*3+ivec2(0,0),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(1,0),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(2,0),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(0,1),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(1,1),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(2,1),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(0,2),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(1,2),0).r; - exposure += texelFetch(source_exposure,coord*3+ivec2(2,2),0).r; - exposure *= (1.0/9.0); + exposure = texelFetch(source_exposure, coord * 3 + ivec2(0, 0), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 0), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 0), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(0, 1), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 1), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 1), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(0, 2), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 2), 0).r; + exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 2), 0).r; + exposure *= (1.0 / 9.0); #ifdef EXPOSURE_END #ifdef EXPOSURE_FORCE_SET //will stay as is #else - highp float prev_lum = texelFetch(prev_exposure,ivec2(0,0),0).r; //1 pixel previous exposure - exposure = clamp( prev_lum + (exposure-prev_lum)*exposure_adjust,min_luminance,max_luminance); + highp float prev_lum = texelFetch(prev_exposure, ivec2(0, 0), 0).r; //1 pixel previous exposure + exposure = clamp(prev_lum + (exposure - prev_lum) * exposure_adjust, min_luminance, max_luminance); #endif //EXPOSURE_FORCE_SET - #endif //EXPOSURE_END #endif //EXPOSURE_BEGIN - - } - - diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl index fbee08c0fe..8523c08597 100644 --- a/drivers/gles3/shaders/particles.glsl +++ b/drivers/gles3/shaders/particles.glsl @@ -1,14 +1,13 @@ +/* clang-format off */ [vertex] - - -layout(location=0) in highp vec4 color; -layout(location=1) in highp vec4 velocity_active; -layout(location=2) in highp vec4 custom; -layout(location=3) in highp vec4 xform_1; -layout(location=4) in highp vec4 xform_2; -layout(location=5) in highp vec4 xform_3; - +layout(location = 0) in highp vec4 color; +/* clang-format on */ +layout(location = 1) in highp vec4 velocity_active; +layout(location = 2) in highp vec4 custom; +layout(location = 3) in highp vec4 xform_1; +layout(location = 4) in highp vec4 xform_2; +layout(location = 5) in highp vec4 xform_3; struct Attractor { @@ -39,7 +38,6 @@ uniform float lifetime; uniform mat4 emission_transform; uniform uint random_seed; - out highp vec4 out_color; //tfb: out highp vec4 out_velocity_active; //tfb: out highp vec4 out_custom; //tfb: @@ -47,20 +45,24 @@ out highp vec4 out_xform_1; //tfb: out highp vec4 out_xform_2; //tfb: out highp vec4 out_xform_3; //tfb: - #if defined(USE_MATERIAL) +/* clang-format off */ layout(std140) uniform UniformData { //ubo:0 MATERIAL_UNIFORMS }; +/* clang-format on */ #endif +/* clang-format off */ VERTEX_SHADER_GLOBALS +/* clang-format on */ + uint hash(uint x) { x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b); @@ -69,13 +71,12 @@ uint hash(uint x) { return x; } - void main() { #ifdef PARTICLES_COPY - out_color=color; - out_velocity_active=velocity_active; + out_color = color; + out_velocity_active = velocity_active; out_custom = custom; out_xform_1 = xform_1; out_xform_2 = xform_2; @@ -83,47 +84,47 @@ void main() { #else - bool apply_forces=true; - bool apply_velocity=true; - float local_delta=delta; + bool apply_forces = true; + bool apply_velocity = true; + float local_delta = delta; float mass = 1.0; - float restart_phase = float(gl_VertexID)/float(total_particles); + float restart_phase = float(gl_VertexID) / float(total_particles); - if (randomness>0.0) { + if (randomness > 0.0) { uint seed = cycle; if (restart_phase >= system_phase) { - seed-=uint(1); + seed -= uint(1); } - seed*=uint(total_particles); - seed+=uint(gl_VertexID); + seed *= uint(total_particles); + seed += uint(gl_VertexID); float random = float(hash(seed) % uint(65536)) / 65536.0; - restart_phase+=randomness * random * 1.0 / float(total_particles); + restart_phase += randomness * random * 1.0 / float(total_particles); } - restart_phase*= (1.0-explosiveness); - bool restart=false; + restart_phase *= (1.0 - explosiveness); + bool restart = false; bool shader_active = velocity_active.a > 0.5; if (system_phase > prev_system_phase) { // restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed - if (restart_phase >= prev_system_phase && restart_phase < system_phase ) { - restart=true; + if (restart_phase >= prev_system_phase && restart_phase < system_phase) { + restart = true; #ifdef USE_FRACTIONAL_DELTA local_delta = (system_phase - restart_phase) * lifetime; #endif } - } else if(delta > 0.0) { + } else if (delta > 0.0) { if (restart_phase >= prev_system_phase) { - restart=true; + restart = true; #ifdef USE_FRACTIONAL_DELTA local_delta = (1.0 - restart_phase + system_phase) * lifetime; #endif - } else if (restart_phase < system_phase ) { - restart=true; + } else if (restart_phase < system_phase) { + restart = true; #ifdef USE_FRACTIONAL_DELTA local_delta = (system_phase - restart_phase) * lifetime; #endif @@ -133,14 +134,14 @@ void main() { uint current_cycle = cycle; if (system_phase < restart_phase) { - current_cycle-=uint(1); + current_cycle -= uint(1); } uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID); int index = int(gl_VertexID); if (restart) { - shader_active=emitting; + shader_active = emitting; } mat4 xform; @@ -150,30 +151,33 @@ void main() { #else if (clear || restart) { #endif - out_color=vec4(1.0); - out_velocity_active=vec4(0.0); - out_custom=vec4(0.0); + out_color = vec4(1.0); + out_velocity_active = vec4(0.0); + out_custom = vec4(0.0); if (!restart) - shader_active=false; + shader_active = false; xform = mat4( - vec4(1.0,0.0,0.0,0.0), - vec4(0.0,1.0,0.0,0.0), - vec4(0.0,0.0,1.0,0.0), - vec4(0.0,0.0,0.0,1.0) - ); + vec4(1.0, 0.0, 0.0, 0.0), + vec4(0.0, 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); } else { - out_color=color; - out_velocity_active=velocity_active; - out_custom=custom; - xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0))); + out_color = color; + out_velocity_active = velocity_active; + out_custom = custom; + xform = transpose(mat4(xform_1, xform_2, xform_3, vec4(vec3(0.0), 1.0))); } if (shader_active) { //execute shader { + /* clang-format off */ + VERTEX_SHADER_CODE + + /* clang-format on */ } #if !defined(DISABLE_FORCE) @@ -181,26 +185,25 @@ VERTEX_SHADER_CODE if (false) { vec3 force = vec3(0.0); - for(int i=0;i<attractor_count;i++) { + for (int i = 0; i < attractor_count; i++) { vec3 rel_vec = xform[3].xyz - attractors[i].pos; float dist = length(rel_vec); if (attractors[i].radius < dist) continue; - if (attractors[i].eat_radius>0.0 && attractors[i].eat_radius > dist) { - out_velocity_active.a=0.0; + if (attractors[i].eat_radius > 0.0 && attractors[i].eat_radius > dist) { + out_velocity_active.a = 0.0; } rel_vec = normalize(rel_vec); - float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation); + float attenuation = pow(dist / attractors[i].radius, attractors[i].attenuation); - if (attractors[i].dir==vec3(0.0)) { + if (attractors[i].dir == vec3(0.0)) { //towards center - force+=attractors[i].strength * rel_vec * attenuation * mass; + force += attractors[i].strength * rel_vec * attenuation * mass; } else { - force+=attractors[i].strength * attractors[i].dir * attenuation *mass; - + force += attractors[i].strength * attractors[i].dir * attenuation * mass; } } @@ -216,25 +219,24 @@ VERTEX_SHADER_CODE } #endif } else { - xform=mat4(0.0); + xform = mat4(0.0); } xform = transpose(xform); - out_velocity_active.a = mix(0.0,1.0,shader_active); + out_velocity_active.a = mix(0.0, 1.0, shader_active); out_xform_1 = xform[0]; out_xform_2 = xform[1]; out_xform_3 = xform[2]; #endif //PARTICLES_COPY - } +/* clang-format off */ [fragment] -//any code here is never executed, stuff is filled just so it works - +// any code here is never executed, stuff is filled just so it works #if defined(USE_MATERIAL) @@ -251,10 +253,15 @@ FRAGMENT_SHADER_GLOBALS void main() { { + LIGHT_SHADER_CODE + } { + FRAGMENT_SHADER_CODE + } } +/* clang-format on */ diff --git a/drivers/gles3/shaders/resolve.glsl b/drivers/gles3/shaders/resolve.glsl index 0b50a9c57b..d64d8308c1 100644 --- a/drivers/gles3/shaders/resolve.glsl +++ b/drivers/gles3/shaders/resolve.glsl @@ -1,27 +1,29 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; - void main() { uv_interp = uv_in; gl_Position = vertex_attrib; } +/* clang-format off */ [fragment] #if !defined(GLES_OVER_GL) precision mediump float; #endif +/* clang-format on */ in vec2 uv_interp; -uniform sampler2D source_specular; //texunit:0 -uniform sampler2D source_ssr; //texunit:1 +uniform sampler2D source_specular; // texunit:0 +uniform sampler2D source_ssr; // texunit:1 uniform vec2 pixel_size; @@ -31,14 +33,12 @@ layout(location = 0) out vec4 frag_color; void main() { - vec4 specular = texture( source_specular, uv_interp ); + vec4 specular = texture(source_specular, uv_interp); #ifdef USE_SSR - - vec4 ssr = textureLod(source_ssr,uv_interp,0.0); - specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a); + vec4 ssr = textureLod(source_ssr, uv_interp, 0.0); + specular.rgb = mix(specular.rgb, ssr.rgb * specular.a, ssr.a); #endif - frag_color = vec4(specular.rgb,1.0); + frag_color = vec4(specular.rgb, 1.0); } - diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index f5481c597c..12cbe02d0c 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1,3 +1,4 @@ +/* clang-format off */ [vertex] #define M_PI 3.14159265359 @@ -16,50 +17,50 @@ ARRAY_WEIGHTS=7, ARRAY_INDEX=8, */ -//hack to use uv if no uv present so it works with lightmap - +// hack to use uv if no uv present so it works with lightmap /* INPUT ATTRIBS */ -layout(location=0) in highp vec4 vertex_attrib; -layout(location=1) in vec3 normal_attrib; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 1) in vec3 normal_attrib; #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) -layout(location=2) in vec4 tangent_attrib; +layout(location = 2) in vec4 tangent_attrib; #endif #if defined(ENABLE_COLOR_INTERP) -layout(location=3) in vec4 color_attrib; +layout(location = 3) in vec4 color_attrib; #endif #if defined(ENABLE_UV_INTERP) -layout(location=4) in vec2 uv_attrib; +layout(location = 4) in vec2 uv_attrib; #endif #if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP) -layout(location=5) in vec2 uv2_attrib; +layout(location = 5) in vec2 uv2_attrib; #endif uniform float normal_mult; #ifdef USE_SKELETON -layout(location=6) in uvec4 bone_indices; // attrib:6 -layout(location=7) in vec4 bone_weights; // attrib:7 +layout(location = 6) in uvec4 bone_indices; // attrib:6 +layout(location = 7) in vec4 bone_weights; // attrib:7 #endif #ifdef USE_INSTANCING -layout(location=8) in highp vec4 instance_xform0; -layout(location=9) in highp vec4 instance_xform1; -layout(location=10) in highp vec4 instance_xform2; -layout(location=11) in lowp vec4 instance_color; +layout(location = 8) in highp vec4 instance_xform0; +layout(location = 9) in highp vec4 instance_xform1; +layout(location = 10) in highp vec4 instance_xform2; +layout(location = 11) in lowp vec4 instance_color; #if defined(ENABLE_INSTANCE_CUSTOM) -layout(location=12) in highp vec4 instance_custom_data; +layout(location = 12) in highp vec4 instance_custom_data; #endif #endif -layout(std140) uniform SceneData { //ubo:0 +layout(std140) uniform SceneData { // ubo:0 highp mat4 projection_matrix; highp mat4 inv_projection_matrix; @@ -90,6 +91,8 @@ layout(std140) uniform SceneData { //ubo:0 mediump float reflection_multiplier; mediump float subsurface_scatter_width; mediump float ambient_occlusion_affect_light; + mediump float ambient_occlusion_affect_ao_channel; + mediump float opaque_prepass_threshold; bool fog_depth_enabled; highp float fog_depth_begin; @@ -100,12 +103,10 @@ layout(std140) uniform SceneData { //ubo:0 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 @@ -113,7 +114,7 @@ layout(std140) uniform DirectionalLightData { //ubo:3 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_params; // cone attenuation, angle, specular, shadow enabled, mediump vec4 light_clamp; mediump vec4 shadow_color_contact; highp mat4 shadow_matrix1; @@ -133,14 +134,12 @@ 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_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]; @@ -153,7 +152,6 @@ layout(std140) uniform SpotLightData { //ubo:5 #ifdef USE_FORWARD_LIGHTING - uniform int omni_light_indices[MAX_FORWARD_LIGHTS]; uniform int omni_light_count; @@ -165,49 +163,45 @@ uniform int spot_light_count; 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) { +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 ); + float dotNL = max(dot(N, L), 0.0); diffuse += dotNL * light_color / M_PI; if (roughness > 0.0) { vec3 H = normalize(V + L); - float dotNH = max(dot(N,H), 0.0 ); - float intensity = (roughness >= 1.0 ? 1.0 : pow( dotNH, (1.0-roughness) * 256.0)); + float dotNH = max(dot(N, H), 0.0); + float intensity = (roughness >= 1.0 ? 1.0 : 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) { +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); + 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 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_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_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); + light_compute(normal, normalize(light_rel_vec), eye_vec, spot_lights[idx].light_color_energy.rgb * light_attenuation, roughness, diffuse, specular); } - #endif /* Varyings */ @@ -223,29 +217,33 @@ out vec4 color_interp; out vec2 uv_interp; #endif -#if defined(ENABLE_UV2_INTERP) || defined (USE_LIGHTMAP) +#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP) out vec2 uv2_interp; #endif - #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) out vec3 tangent_interp; out vec3 binormal_interp; #endif - #if defined(USE_MATERIAL) -layout(std140) uniform UniformData { //ubo:1 +/* clang-format off */ +layout(std140) uniform UniformData { // ubo:1 MATERIAL_UNIFORMS }; +/* clang-format on */ #endif +/* clang-format off */ + VERTEX_SHADER_GLOBALS +/* clang-format on */ + #ifdef RENDER_DEPTH_DUAL_PARABOLOID out highp float dp_clip; @@ -255,7 +253,7 @@ out highp float dp_clip; #define SKELETON_TEXTURE_WIDTH 256 #ifdef USE_SKELETON -uniform highp sampler2D skeleton_texture; //texunit:-1 +uniform highp sampler2D skeleton_texture; // texunit:-1 #endif out highp vec4 position_interp; @@ -270,21 +268,19 @@ void main() { mat4 world_matrix = world_transform; - #ifdef USE_INSTANCING { - highp mat4 m=mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0)); + highp mat4 m = mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)); world_matrix = world_matrix * transpose(m); } #endif vec3 normal = normal_attrib * normal_mult; - #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) vec3 tangent = tangent_attrib.xyz; - tangent*=normal_mult; + tangent *= normal_mult; float binormalf = tangent_attrib.a; #endif @@ -296,10 +292,9 @@ void main() { #endif - #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) - vec3 binormal = normalize( cross(normal,tangent) * binormalf ); + vec3 binormal = normalize(cross(normal, tangent) * binormalf); #endif #if defined(ENABLE_UV_INTERP) @@ -322,84 +317,95 @@ void main() { #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(ENSURE_CORRECT_NORMALS) + mat3 normal_matrix = mat3(transpose(inverse(world_matrix))); + normal = normal_matrix * normal; +#else + normal = normalize((world_matrix * vec4(normal, 0.0)).xyz); +#endif #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); + tangent = normalize((world_matrix * vec4(tangent, 0.0)).xyz); + binormal = normalize((world_matrix * vec4(binormal, 0.0)).xyz); #endif #endif - float roughness=0.0; + float roughness = 1.0; //defines that make writing custom shaders easier #define projection_matrix local_projection #define world_transform world_matrix - #ifdef USE_SKELETON { //skeleton transform ivec4 bone_indicesi = ivec4(bone_indices); // cast to signed int - ivec2 tex_ofs = ivec2( bone_indicesi.x%256, (bone_indicesi.x/256)*3 ); - highp mat3x4 m = mat3x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) - ) * bone_weights.x; + ivec2 tex_ofs = ivec2(bone_indicesi.x % 256, (bone_indicesi.x / 256) * 3); + highp mat3x4 m; + m = mat3x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) * + bone_weights.x; - tex_ofs = ivec2( bone_indicesi.y%256, (bone_indicesi.y/256)*3 ); + tex_ofs = ivec2(bone_indicesi.y % 256, (bone_indicesi.y / 256) * 3); - m+= mat3x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) - ) * bone_weights.y; + m += mat3x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) * + bone_weights.y; - tex_ofs = ivec2( bone_indicesi.z%256, (bone_indicesi.z/256)*3 ); + tex_ofs = ivec2(bone_indicesi.z % 256, (bone_indicesi.z / 256) * 3); - m+= mat3x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) - ) * bone_weights.z; + m += mat3x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) * + bone_weights.z; + tex_ofs = ivec2(bone_indicesi.w % 256, (bone_indicesi.w / 256) * 3); - tex_ofs = ivec2( bone_indicesi.w%256, (bone_indicesi.w/256)*3 ); + m += mat3x4( + texelFetch(skeleton_texture, tex_ofs, 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0), + texelFetch(skeleton_texture, tex_ofs + ivec2(0, 2), 0)) * + bone_weights.w; - m+= mat3x4( - texelFetch(skeleton_texture,tex_ofs,0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), - texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) - ) * bone_weights.w; - - mat4 bone_matrix = transpose(mat4(m[0],m[1],m[2],vec4(0.0,0.0,0.0,1.0))); + mat4 bone_matrix = transpose(mat4(m[0], m[1], m[2], vec4(0.0, 0.0, 0.0, 1.0))); world_matrix = bone_matrix * world_matrix; } #endif mat4 modelview = camera_inverse_matrix * world_matrix; -{ + { + /* clang-format off */ VERTEX_SHADER_CODE -} - - + /* clang-format on */ + } -//using local coordinates (default) +// 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(ENSURE_CORRECT_NORMALS) + mat3 normal_matrix = mat3(transpose(inverse(modelview))); + normal = normal_matrix * normal; +#else + normal = normalize((modelview * vec4(normal, 0.0)).xyz); +#endif #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); + tangent = normalize((modelview * vec4(tangent, 0.0)).xyz); + binormal = normalize((modelview * vec4(binormal, 0.0)).xyz); #endif #endif @@ -407,74 +413,70 @@ VERTEX_SHADER_CODE #if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) vertex = camera_inverse_matrix * vertex; - normal = normalize((camera_inverse_matrix * vec4(normal,0.0)).xyz); + normal = normalize((camera_inverse_matrix * vec4(normal, 0.0)).xyz); #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) - tangent = normalize((camera_inverse_matrix * vec4(tangent,0.0)).xyz); - binormal = normalize((camera_inverse_matrix * vec4(binormal,0.0)).xyz); + tangent = normalize((camera_inverse_matrix * vec4(tangent, 0.0)).xyz); + binormal = normalize((camera_inverse_matrix * vec4(binormal, 0.0)).xyz); #endif #endif vertex_interp = vertex.xyz; normal_interp = normal; - #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) tangent_interp = tangent; binormal_interp = binormal; #endif - #ifdef RENDER_DEPTH - #ifdef RENDER_DEPTH_DUAL_PARABOLOID - vertex_interp.z*= shadow_dual_paraboloid_render_side; - normal_interp.z*= shadow_dual_paraboloid_render_side; + vertex_interp.z *= shadow_dual_paraboloid_render_side; + normal_interp.z *= shadow_dual_paraboloid_render_side; - dp_clip=vertex_interp.z; //this attempts to avoid noise caused by objects sent to the other parabolloid side due to bias + dp_clip = vertex_interp.z; //this attempts to avoid noise caused by objects sent to the other parabolloid side due to bias //for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges - highp vec3 vtx = vertex_interp+normalize(vertex_interp)*z_offset; + highp vec3 vtx = vertex_interp + normalize(vertex_interp) * z_offset; highp float distance = length(vtx); vtx = normalize(vtx); - vtx.xy/=1.0-vtx.z; - vtx.z=(distance/shadow_dual_paraboloid_render_zfar); - vtx.z=vtx.z * 2.0 - 1.0; + vtx.xy /= 1.0 - vtx.z; + vtx.z = (distance / shadow_dual_paraboloid_render_zfar); + vtx.z = vtx.z * 2.0 - 1.0; vertex_interp = vtx; - #else float z_ofs = z_offset; - z_ofs += (1.0-abs(normal_interp.z))*z_slope_scale; - vertex_interp.z-=z_ofs; + z_ofs += (1.0 - abs(normal_interp.z)) * z_slope_scale; + vertex_interp.z -= z_ofs; #endif //RENDER_DEPTH_DUAL_PARABOLOID #endif //RENDER_DEPTH - gl_Position = projection_matrix * vec4(vertex_interp,1.0); + gl_Position = projection_matrix * vec4(vertex_interp, 1.0); - position_interp=gl_Position; + position_interp = gl_Position; #ifdef USE_VERTEX_LIGHTING - diffuse_light_interp=vec4(0.0); - specular_light_interp=vec4(0.0); + 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 < 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); + 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 @@ -482,36 +484,34 @@ VERTEX_SHADER_CODE vec3 directional_diffuse = vec3(0.0); vec3 directional_specular = vec3(0.0); - light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),light_color_energy.rgb,roughness,directional_diffuse,directional_specular); + light_compute(normal_interp, -light_direction_attenuation.xyz, -normalize(vertex_interp), light_color_energy.rgb, 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); + 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.a = 1.0; } - diffuse_light_interp.rgb+=directional_diffuse; + 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); + 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.a = 1.0; } - specular_light_interp.rgb+=directional_specular; + specular_light_interp.rgb += directional_specular; #endif //USE_LIGHT_DIRECTIONAL - #endif // USE_VERTEX_LIGHTING - } - +/* clang-format off */ [fragment] /* texture unit usage, N is max_texture_unity-N @@ -530,6 +530,7 @@ VERTEX_SHADER_CODE */ uniform highp mat4 world_transform; +/* clang-format on */ #define M_PI 3.14159265359 @@ -555,42 +556,33 @@ in vec3 binormal_interp; in highp vec3 vertex_interp; in vec3 normal_interp; - /* PBR CHANNELS */ -//used on forward mainly -uniform bool no_ambient_light; - - - #ifdef USE_RADIANCE_MAP - - -layout(std140) uniform Radiance { //ubo:2 +layout(std140) uniform Radiance { // ubo:2 mat4 radiance_inverse_xform; float radiance_ambient_contribution; - }; #define RADIANCE_MAX_LOD 5.0 #ifdef USE_RADIANCE_MAP_ARRAY -uniform sampler2DArray radiance_map; //texunit:-2 +uniform sampler2DArray radiance_map; // texunit:-2 -vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) { +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); + 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 texture filtering - vec2 normg=norm.xy; - if (norm.z>0.0) { - norm.y=0.5-norm.y+0.5; + 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, @@ -599,22 +591,22 @@ vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) { 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); + 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 +uniform sampler2D radiance_map; // texunit:-2 -vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec,float p_roughness) { +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; + 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; } @@ -625,20 +617,24 @@ vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec,float p_roughness) { /* Material Uniforms */ - - #if defined(USE_MATERIAL) +/* clang-format off */ layout(std140) uniform UniformData { MATERIAL_UNIFORMS }; +/* clang-format on */ #endif +/* clang-format off */ + FRAGMENT_SHADER_GLOBALS +/* clang-format on */ + layout(std140) uniform SceneData { highp mat4 projection_matrix; @@ -670,6 +666,8 @@ layout(std140) uniform SceneData { mediump float reflection_multiplier; mediump float subsurface_scatter_width; mediump float ambient_occlusion_affect_light; + mediump float ambient_occlusion_affect_ao_channel; + mediump float opaque_prepass_threshold; bool fog_depth_enabled; highp float fog_depth_begin; @@ -682,7 +680,7 @@ layout(std140) uniform SceneData { highp float fog_height_curve; }; -//directional light data + //directional light data #ifdef USE_LIGHT_DIRECTIONAL @@ -691,7 +689,7 @@ layout(std140) uniform DirectionalLightData { 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_params; // cone attenuation, angle, specular, shadow enabled, mediump vec4 light_clamp; mediump vec4 shadow_color_contact; highp mat4 shadow_matrix1; @@ -701,8 +699,7 @@ layout(std140) uniform DirectionalLightData { mediump vec4 shadow_split_offsets; }; - -uniform highp sampler2DShadow directional_shadow; //texunit:-4 +uniform highp sampler2DShadow directional_shadow; // texunit:-4 #endif @@ -710,52 +707,47 @@ uniform highp sampler2DShadow directional_shadow; //texunit:-4 in vec4 diffuse_light_interp; in vec4 specular_light_interp; #endif -//omni and spot +// 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_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 +layout(std140) uniform OmniLightData { // ubo:4 LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; }; -layout(std140) uniform SpotLightData { //ubo:5 +layout(std140) uniform SpotLightData { // ubo:5 LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; }; - -uniform highp sampler2DShadow shadow_atlas; //texunit:-5 - +uniform highp sampler2DShadow shadow_atlas; // texunit:-5 struct ReflectionData { mediump vec4 box_extents; mediump vec4 box_offset; mediump vec4 params; // intensity, 0, interior , boxproject - mediump vec4 ambient; //ambient color, energy + mediump vec4 ambient; // ambient color, energy mediump vec4 atlas_clamp; - highp mat4 local_matrix; //up to here for spot and omni, rest is for directional - //notes: for ambientblend, use distance to edge to blend between already existing global environment + highp mat4 local_matrix; // up to here for spot and omni, rest is for directional + // notes: for ambientblend, use distance to edge to blend between already existing global environment }; layout(std140) uniform ReflectionProbeData { //ubo:6 ReflectionData reflections[MAX_REFLECTION_DATA_STRUCTS]; }; -uniform mediump sampler2D reflection_atlas; //texunit:-3 - +uniform mediump sampler2D reflection_atlas; // texunit:-3 #ifdef USE_FORWARD_LIGHTING @@ -770,39 +762,38 @@ uniform int reflection_count; #endif - #if defined(SCREEN_TEXTURE_USED) -uniform highp sampler2D screen_texture; //texunit:-7 +uniform highp sampler2D screen_texture; // texunit:-7 #endif #ifdef USE_MULTIPLE_RENDER_TARGETS -layout(location=0) out vec4 diffuse_buffer; -layout(location=1) out vec4 specular_buffer; -layout(location=2) out vec4 normal_mr_buffer; +layout(location = 0) out vec4 diffuse_buffer; +layout(location = 1) out vec4 specular_buffer; +layout(location = 2) out vec4 normal_mr_buffer; #if defined(ENABLE_SSS) -layout(location=3) out float sss_buffer; +layout(location = 3) out float sss_buffer; #endif #else -layout(location=0) out vec4 frag_color; +layout(location = 0) out vec4 frag_color; #endif in highp vec4 position_interp; -uniform highp sampler2D depth_buffer; //texunit:-8 +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) + if (abs(dir.z) > 0.99) return 1.0; - vec3 endpoint = pos+dir*max_distance; + vec3 endpoint = pos + dir * max_distance; vec4 source = position_interp; vec4 dest = projection_matrix * vec4(endpoint, 1.0); @@ -811,51 +802,48 @@ 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 + if (length(screen_rel) < 0.00001) + return 1.0; // too small, don't do anything - /*float pixel_size; //approximate pixel size + /* + float pixel_size; // approximate pixel size if (screen_rel.x > screen_rel.y) { - pixel_size = abs((pos.x-endpoint.x)/(screen_rel.x/screen_pixel_size.x)); + pixel_size = abs((pos.x - endpoint.x) / (screen_rel.x / screen_pixel_size.x)); } else { - pixel_size = abs((pos.y-endpoint.y)/(screen_rel.y/screen_pixel_size.y)); - - }*/ - vec4 bias = projection_matrix * vec4(pos+vec3(0.0,0.0,max_distance*0.5), 1.0); //todo un-harcode the 0.04 - - - - vec2 pixel_incr = normalize(screen_rel)*screen_pixel_size; + pixel_size = abs((pos.y - endpoint.y) / (screen_rel.y / screen_pixel_size.y)); + } + */ + vec4 bias = projection_matrix * vec4(pos + vec3(0.0, 0.0, max_distance * 0.5), 1.0); + vec2 pixel_incr = normalize(screen_rel) * screen_pixel_size; 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; + 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; + vec4 incr = (dest - source) / steps; + float ratio = 0.0; + float ratio_incr = 1.0 / steps; - while(steps>0.0) { - source += incr*2.0; - bias+=incr*2.0; + while (steps > 0.0) { + source += incr * 2.0; + bias += incr * 2.0; vec3 uv_depth = (source.xyz / source.w) * 0.5 + 0.5; - float depth = texture(depth_buffer,uv_depth.xy).r; + float depth = texture(depth_buffer, uv_depth.xy).r; if (depth < uv_depth.z) { - if (depth > (bias.z/bias.w) * 0.5 + 0.5) { - return min(pow(ratio,4.0),1.0); + if (depth > (bias.z / bias.w) * 0.5 + 0.5) { + return min(pow(ratio, 4.0), 1.0); } else { return 1.0; } } - - ratio+=ratio_incr; - steps-=1.0; + ratio += ratio_incr; + steps -= 1.0; } return 1.0; @@ -863,7 +851,6 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { #endif - // This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V. // We're dividing this factor off because the overall term we'll end up looks like // (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012): @@ -885,51 +872,48 @@ float G_GGX_2cos(float cos_theta_m, float alpha) { // C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994) // Eq. (19), although see Heitz (2014) the about the problems with his derivation. // It nevertheless approximates GGX well with k = alpha/2. - float k = 0.5*alpha; + float k = 0.5 * alpha; return 0.5 / (cos_theta_m * (1.0 - k) + k); - // float cos2 = cos_theta_m*cos_theta_m; - // float sin2 = (1.0-cos2); - // return 1.0 /( cos_theta_m + sqrt(cos2 + alpha*alpha*sin2) ); + // float cos2 = cos_theta_m * cos_theta_m; + // float sin2 = (1.0 - cos2); + // return 1.0 / (cos_theta_m + sqrt(cos2 + alpha * alpha * sin2)); } float D_GGX(float cos_theta_m, float alpha) { - float alpha2 = alpha*alpha; - float d = 1.0 + (alpha2-1.0)*cos_theta_m*cos_theta_m; - return alpha2/(M_PI * d * d); + float alpha2 = alpha * alpha; + float d = 1.0 + (alpha2 - 1.0) * cos_theta_m * cos_theta_m; + return alpha2 / (M_PI * d * d); } float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { float cos2 = cos_theta_m * cos_theta_m; - float sin2 = (1.0-cos2); + float sin2 = (1.0 - cos2); float s_x = alpha_x * cos_phi; float s_y = alpha_y * sin_phi; - return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x*s_x + s_y*s_y)*sin2 ), 0.001); + return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x * s_x + s_y * s_y) * sin2), 0.001); } float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { float cos2 = cos_theta_m * cos_theta_m; - float sin2 = (1.0-cos2); - float r_x = cos_phi/alpha_x; - float r_y = sin_phi/alpha_y; - float d = cos2 + sin2*(r_x * r_x + r_y * r_y); + float sin2 = (1.0 - cos2); + float r_x = cos_phi / alpha_x; + float r_y = sin_phi / alpha_y; + float d = cos2 + sin2 * (r_x * r_x + r_y * r_y); return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001); } - -float SchlickFresnel(float u) -{ - float m = 1.0-u; - float m2 = m*m; - return m2*m2*m; // pow(m,5) +float SchlickFresnel(float u) { + float m = 1.0 - u; + float m2 = m * m; + return m2 * m2 * m; // pow(m,5) } -float GTR1(float NdotH, float a) -{ - if (a >= 1.0) return 1.0/M_PI; - float a2 = a*a; - float t = 1.0 + (a2-1.0)*NdotH*NdotH; - return (a2-1.0) / (M_PI*log(a2)*t); +float GTR1(float NdotH, float a) { + if (a >= 1.0) return 1.0 / M_PI; + float a2 = a * a; + float t = 1.0 + (a2 - 1.0) * NdotH * NdotH; + return (a2 - 1.0) / (M_PI * log(a2) * t); } vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) { @@ -941,18 +925,21 @@ vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) { 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 rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { #if defined(USE_LIGHT_SHADER_CODE) -//light is written by the light shader + // light is written by the light shader vec3 normal = N; vec3 albedo = diffuse_color; vec3 light = L; vec3 view = V; + /* clang-format off */ + LIGHT_SHADER_CODE + /* clang-format on */ #else - float NdotL = dot(N,L); + float NdotL = dot(N, L); float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); float cNdotV = max(NdotV, 0.0); @@ -964,10 +951,9 @@ LIGHT_SHADER_CODE float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance #endif - #if defined(DIFFUSE_LAMBERT_WRAP) - //energy conserving lambert wrap shader - diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))); + // energy conserving lambert wrap shader + diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))); #elif defined(DIFFUSE_OREN_NAYAR) @@ -975,12 +961,11 @@ LIGHT_SHADER_CODE // see http://mimosa-pudica.net/improved-oren-nayar.html float LdotV = dot(L, V); - float s = LdotV - NdotL * NdotV; float t = mix(1.0, max(NdotL, NdotV), step(0.0, s)); float sigma2 = roughness * roughness; // TODO: this needs checking - vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) ); + vec3 A = 1.0 + sigma2 * (-0.5 / (sigma2 + 0.33) + 0.17 * diffuse_color / (sigma2 + 0.13)); float B = 0.45 * sigma2 / (sigma2 + 0.09); diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI); @@ -988,21 +973,20 @@ LIGHT_SHADER_CODE #elif defined(DIFFUSE_TOON) - diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL); + diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL); #elif defined(DIFFUSE_BURLEY) { - vec3 H = normalize(V + L); - float cLdotH = max(0.0,dot(L, H)); + float cLdotH = max(0.0, dot(L, H)); float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness; float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV); float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL); diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; - /* + /* float energyBias = mix(roughness, 0.0, 0.5); float energyFactor = mix(roughness, 1.0, 1.0 / 1.51); float fd90 = energyBias + 2.0 * VoH * VoH * roughness; @@ -1010,84 +994,81 @@ LIGHT_SHADER_CODE float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0); float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0); - diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/ + diffuse_brdf_NL = lightScatter * viewScatter * energyFactor; + */ } #else - //lambert + // lambert diffuse_brdf_NL = cNdotL * (1.0 / M_PI); #endif -#if defined(TRANSMISSION_USED) - diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation; -#else diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation; -#endif - +#if defined(TRANSMISSION_USED) + diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation; +#endif #if defined(LIGHT_USE_RIM) - float rim_light = pow(max(0.0,1.0-cNdotV), max(0.0,(1.0-roughness)*16.0)); - diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color; + float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); + diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color; #endif } - if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely - // D #if defined(SPECULAR_BLINN) vec3 H = normalize(V + L); - float cNdotH = max(dot(N,H), 0.0 ); - float intensity = pow( cNdotH, (1.0-roughness) * 256.0); + float cNdotH = max(dot(N, H), 0.0); + float intensity = pow(cNdotH, (1.0 - roughness) * 256.0); specular_light += light_color * intensity * specular_blob_intensity * attenuation; #elif defined(SPECULAR_PHONG) - vec3 R = normalize(-reflect(L,N)); - float cRdotV = max(0.0,dot(R,V)); - float intensity = pow( cRdotV, (1.0-roughness) * 256.0); - specular_light += light_color * intensity * specular_blob_intensity * attenuation; + vec3 R = normalize(-reflect(L, N)); + float cRdotV = max(0.0, dot(R, V)); + float intensity = pow(cRdotV, (1.0 - roughness) * 256.0); + specular_light += light_color * intensity * specular_blob_intensity * attenuation; #elif defined(SPECULAR_TOON) - vec3 R = normalize(-reflect(L,N)); - float RdotV = dot(R,V); - float mid = 1.0-roughness; - mid*=mid; - float intensity = smoothstep(mid-roughness*0.5, mid+roughness*0.5, RdotV) * mid; + vec3 R = normalize(-reflect(L, N)); + float RdotV = dot(R, V); + float mid = 1.0 - roughness; + mid *= mid; + float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; diffuse_light += light_color * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection #elif defined(SPECULAR_DISABLED) - //none.. + // none.. #elif defined(SPECULAR_SCHLICK_GGX) // shlick+ggx as default vec3 H = normalize(V + L); - float cNdotH = max(dot(N,H), 0.0); - float cLdotH = max(dot(L,H), 0.0); + float cNdotH = max(dot(N, H), 0.0); + float cLdotH = max(dot(L, H), 0.0); -# if defined(LIGHT_USE_ANISOTROPY) +#if defined(LIGHT_USE_ANISOTROPY) - float aspect = sqrt(1.0-anisotropy*0.9); - float rx = roughness/aspect; - float ry = roughness*aspect; - float ax = rx*rx; - float ay = ry*ry; - float XdotH = dot( T, H ); - float YdotH = dot( B, H ); + float aspect = sqrt(1.0 - anisotropy * 0.9); + float rx = roughness / aspect; + float ry = roughness * aspect; + float ax = rx * rx; + float ay = ry * ry; + 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 +#else float alpha = roughness * roughness; float D = D_GGX(cNdotH, alpha); float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha); -# endif +#endif // F float F0 = 1.0; // FIXME float cLdotH5 = SchlickFresnel(cLdotH); @@ -1100,19 +1081,18 @@ LIGHT_SHADER_CODE #if defined(LIGHT_USE_CLEARCOAT) if (clearcoat_gloss > 0.0) { -# if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) +#if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) vec3 H = normalize(V + L); -# endif -# if !defined(SPECULAR_SCHLICK_GGX) - float cNdotH = max(dot(N,H), 0.0); - float cLdotH = max(dot(L,H), 0.0); +#endif +#if !defined(SPECULAR_SCHLICK_GGX) + float cNdotH = max(dot(N, H), 0.0); + float cLdotH = max(dot(L, H), 0.0); float cLdotH5 = SchlickFresnel(cLdotH); #endif float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); float Fr = mix(.04, 1.0, cLdotH5); float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); - float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; @@ -1120,45 +1100,42 @@ LIGHT_SHADER_CODE #endif } - #endif //defined(USE_LIGHT_SHADER_CODE) } - float sample_shadow(highp sampler2DShadow shadow, vec2 shadow_pixel_size, vec2 pos, float depth, vec4 clamp_rect) { #ifdef SHADOW_MODE_PCF_13 - float avg=textureProj(shadow,vec4(pos,depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x*2.0,0.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x*2.0,0.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y*2.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y*2.0),depth,1.0)); - return avg*(1.0/13.0); + float avg = textureProj(shadow, vec4(pos, depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(-shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(-shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(-shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(0.0, shadow_pixel_size.y * 2.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(0.0, -shadow_pixel_size.y * 2.0), depth, 1.0)); + return avg * (1.0 / 13.0); #elif defined(SHADOW_MODE_PCF_5) - float avg=textureProj(shadow,vec4(pos,depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0)); - avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0)); - return avg*(1.0/5.0); + float avg = textureProj(shadow, vec4(pos, depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); + avg += textureProj(shadow, vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); + return avg * (1.0 / 5.0); #else - return textureProj(shadow,vec4(pos,depth,1.0)); + return textureProj(shadow, vec4(pos, depth, 1.0)); #endif - } #ifdef RENDER_DEPTH_DUAL_PARABOLOID @@ -1167,239 +1144,227 @@ in highp float dp_clip; #endif - - #if 0 -//need to save texture depth for this - +// need to save texture depth for this vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 pos, float distance) { float scale = 8.25 * (1.0 - translucency) / subsurface_scatter_width; float d = scale * distance; - /** - * Armed with the thickness, we can now calculate the color by means of the - * precalculated transmittance profile. - * (It can be precomputed into a texture, for maximum performance): - */ + /** + * Armed with the thickness, we can now calculate the color by means of the + * precalculated transmittance profile. + * (It can be precomputed into a texture, for maximum performance): + */ float dd = -d * d; - vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + - vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + - vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) + - vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) + - vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + - vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); - - /** - * Using the profile, we finally approximate the transmitted lighting from - * the back of the object: - */ - return profile * clamp(0.3 + dot(light_vec, normal),0.0,1.0); + vec3 profile = + vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); + + /** + * Using the profile, we finally approximate the transmitted lighting from + * the back of the object: + */ + return profile * clamp(0.3 + dot(light_vec, normal),0.0,1.0); } #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 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 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 ); - float normalized_distance = light_length*omni_lights[idx].light_pos_inv_radius.w; - float omni_attenuation = pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w ); + 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; + float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w); vec3 light_attenuation = vec3(omni_attenuation); #if !defined(SHADOWS_DISABLED) - if (omni_lights[idx].light_params.w>0.5) { - //there is a shadowmap + if (omni_lights[idx].light_params.w > 0.5) { + // there is a shadowmap - highp vec3 splane=(omni_lights[idx].shadow_matrix * vec4(vertex,1.0)).xyz; - float shadow_len=length(splane); - splane=normalize(splane); - vec4 clamp_rect=omni_lights[idx].light_clamp; + highp vec3 splane = (omni_lights[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; + float shadow_len = length(splane); + splane = normalize(splane); + vec4 clamp_rect = omni_lights[idx].light_clamp; - if (splane.z>=0.0) { + if (splane.z >= 0.0) { - splane.z+=1.0; + splane.z += 1.0; - clamp_rect.y+=clamp_rect.w; + clamp_rect.y += clamp_rect.w; } else { - splane.z=1.0 - splane.z; + splane.z = 1.0 - splane.z; /* - if (clamp_rect.z<clamp_rect.w) { - clamp_rect.x+=clamp_rect.z; + if (clamp_rect.z < clamp_rect.w) { + clamp_rect.x += clamp_rect.z; } else { - clamp_rect.y+=clamp_rect.w; + clamp_rect.y += clamp_rect.w; } */ - } - splane.xy/=splane.z; - splane.xy=splane.xy * 0.5 + 0.5; + splane.xy /= splane.z; + splane.xy = splane.xy * 0.5 + 0.5; splane.z = shadow_len * omni_lights[idx].light_pos_inv_radius.w; - 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); + 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); + 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_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,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, rim * omni_attenuation, 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, vec3 transmission,float roughness, float metallic, 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 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; - float spot_attenuation = pow( max(1.0 - normalized_distance, 0.001), spot_lights[idx].light_direction_attenuation.w ); + 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; + float spot_attenuation = 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 = max(0.0001,(1.0 - scos) / (1.0 - spot_cutoff)); - spot_attenuation*= 1.0 - pow( spot_rim, spot_lights[idx].light_params.x); + float spot_cutoff = spot_lights[idx].light_params.y; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_cutoff); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_cutoff)); + spot_attenuation *= 1.0 - pow(spot_rim, spot_lights[idx].light_params.x); vec3 light_attenuation = vec3(spot_attenuation); #if !defined(SHADOWS_DISABLED) - if (spot_lights[idx].light_params.w>0.5) { + if (spot_lights[idx].light_params.w > 0.5) { //there is a shadowmap - highp vec4 splane=(spot_lights[idx].shadow_matrix * vec4(vertex,1.0)); - splane.xyz/=splane.w; + highp vec4 splane = (spot_lights[idx].shadow_matrix * vec4(vertex, 1.0)); + splane.xyz /= splane.w; - float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp); + 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); + 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_attenuation *= mix(spot_lights[idx].shadow_color_contact.rgb, vec3(1.0), shadow); } #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,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, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); } -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) { +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) { - vec3 ref_vec = normalize(reflect(vertex,normal)); - vec3 local_pos = (reflections[idx].local_matrix * vec4(vertex,1.0)).xyz; + vec3 ref_vec = normalize(reflect(vertex, normal)); + vec3 local_pos = (reflections[idx].local_matrix * vec4(vertex, 1.0)).xyz; vec3 box_extents = reflections[idx].box_extents.xyz; - if (any(greaterThan(abs(local_pos),box_extents))) { //out of the reflection box + if (any(greaterThan(abs(local_pos), box_extents))) { //out of the reflection box return; } vec3 inner_pos = abs(local_pos / box_extents); - float blend = max(inner_pos.x,max(inner_pos.y,inner_pos.z)); + float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z)); //make blend more rounded - blend=mix(length(inner_pos),blend,blend); - blend*=blend; - blend=max(0.0, 1.0-blend); + blend = mix(length(inner_pos), blend, blend); + blend *= blend; + blend = max(0.0, 1.0 - blend); - if (reflections[idx].params.x>0.0){// compute reflection + if (reflections[idx].params.x > 0.0) { // compute reflection - vec3 local_ref_vec = (reflections[idx].local_matrix * vec4(ref_vec,0.0)).xyz; + vec3 local_ref_vec = (reflections[idx].local_matrix * vec4(ref_vec, 0.0)).xyz; if (reflections[idx].params.w > 0.5) { //box project vec3 nrdir = normalize(local_ref_vec); - vec3 rbmax = (box_extents - local_pos)/nrdir; - vec3 rbmin = (-box_extents - local_pos)/nrdir; - + vec3 rbmax = (box_extents - local_pos) / nrdir; + vec3 rbmin = (-box_extents - local_pos) / nrdir; - vec3 rbminmax = mix(rbmin,rbmax,greaterThan(nrdir,vec3(0.0,0.0,0.0))); + vec3 rbminmax = mix(rbmin, rbmax, greaterThan(nrdir, vec3(0.0, 0.0, 0.0))); float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); vec3 posonbox = local_pos + nrdir * fa; local_ref_vec = posonbox - reflections[idx].box_offset.xyz; } - - vec4 clamp_rect=reflections[idx].atlas_clamp; + vec4 clamp_rect = reflections[idx].atlas_clamp; 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; + 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; } - 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); + 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,atlas_uv,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); + reflection.rgb = mix(skybox, reflection.rgb, blend); } - reflection.rgb*=reflections[idx].params.x; + reflection.rgb *= reflections[idx].params.x; reflection.a = blend; - reflection.rgb*=reflection.a; + reflection.rgb *= reflection.a; - reflection_accum+=reflection; + reflection_accum += reflection; } #ifndef USE_LIGHTMAP - if (reflections[idx].ambient.a>0.0) { //compute ambient using skybox + if (reflections[idx].ambient.a > 0.0) { //compute ambient using skybox + vec3 local_amb_vec = (reflections[idx].local_matrix * vec4(normal, 0.0)).xyz; - vec3 local_amb_vec = (reflections[idx].local_matrix * vec4(normal,0.0)).xyz; + vec3 splane = normalize(local_amb_vec); + vec4 clamp_rect = reflections[idx].atlas_clamp; - vec3 splane=normalize(local_amb_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; + 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; + splane.z = 1.0 - splane.z; + splane.y = -splane.y; } - splane.xy/=splane.z; - splane.xy=splane.xy * 0.5 + 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); + splane.xy = clamp(splane.xy, clamp_rect.xy, clamp_rect.xy + clamp_rect.zw); highp vec4 ambient_out; - ambient_out.a=blend; - ambient_out.rgb = textureLod(reflection_atlas,splane.xy,5.0).rgb; - ambient_out.rgb=mix(reflections[idx].ambient.rgb,ambient_out.rgb,reflections[idx].ambient.a); + ambient_out.a = blend; + ambient_out.rgb = textureLod(reflection_atlas, splane.xy, 5.0).rgb; + ambient_out.rgb = mix(reflections[idx].ambient.rgb, ambient_out.rgb, reflections[idx].ambient.a); if (reflections[idx].params.z < 0.5) { - ambient_out.rgb = mix(ambient,ambient_out.rgb,blend); + ambient_out.rgb = mix(ambient, ambient_out.rgb, blend); } ambient_out.rgb *= ambient_out.a; - ambient_accum+=ambient_out; + ambient_accum += ambient_out; } else { highp vec4 ambient_out; - ambient_out.a=blend; - ambient_out.rgb=reflections[idx].ambient.rgb; + ambient_out.a = blend; + ambient_out.rgb = reflections[idx].ambient.rgb; if (reflections[idx].params.z < 0.5) { - ambient_out.rgb = mix(ambient,ambient_out.rgb,blend); + ambient_out.rgb = mix(ambient, ambient_out.rgb, blend); } ambient_out.rgb *= ambient_out.a; - ambient_accum+=ambient_out; - + ambient_accum += ambient_out; } #endif } @@ -1438,13 +1403,13 @@ uniform bool gi_probe_blend_ambient2; vec3 voxel_cone_trace(mediump 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; + 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); - while(dist < max_distance && alpha < 0.95) { + while (dist < max_distance && alpha < 0.95) { float diameter = max(1.0, 2.0 * tan_half_angle * dist); - vec4 scolor = textureLod(probe, (pos + dist * direction) * cell_size, log2(diameter) ); + vec4 scolor = textureLod(probe, (pos + dist * direction) * cell_size, log2(diameter)); float a = (1.0 - alpha); color += scolor.rgb * a; alpha += a * scolor.a; @@ -1452,35 +1417,33 @@ vec3 voxel_cone_trace(mediump sampler3D probe, vec3 cell_size, vec3 pos, vec3 am } if (blend_ambient) { - color.rgb = mix(ambient,color.rgb,min(1.0,alpha/0.95)); + color.rgb = mix(ambient, color.rgb, min(1.0, alpha / 0.95)); } return color; } -void gi_probe_compute(mediump 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) { - - +void gi_probe_compute(mediump 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; + 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; + 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.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; //this causes corrupted pixels, i have no idea why.. - if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds))))) { + if (any(bvec2(any(lessThan(probe_pos, vec3(0.0))), any(greaterThan(probe_pos, bounds))))) { return; } - vec3 blendv = abs(probe_pos/bounds * 2.0 - 1.0); - float blend = clamp(1.0-max(blendv.x,max(blendv.y,blendv.z)), 0.0, 1.0); + vec3 blendv = abs(probe_pos / bounds * 2.0 - 1.0); + float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0); //float blend=1.0; float max_distance = length(bounds); @@ -1489,14 +1452,13 @@ void gi_probe_compute(mediump sampler3D probe, mat4 probe_xform, vec3 bounds,vec #ifdef VCT_QUALITY_HIGH #define MAX_CONE_DIRS 6 - vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] ( - vec3(0, 0, 1), - vec3(0.866025, 0, 0.5), - vec3(0.267617, 0.823639, 0.5), - vec3(-0.700629, 0.509037, 0.5), - vec3(-0.700629, -0.509037, 0.5), - vec3(0.267617, -0.823639, 0.5) - ); + vec3 cone_dirs[MAX_CONE_DIRS] = vec3[]( + vec3(0, 0, 1), + vec3(0.866025, 0, 0.5), + vec3(0.267617, 0.823639, 0.5), + vec3(-0.700629, 0.509037, 0.5), + vec3(-0.700629, -0.509037, 0.5), + vec3(0.267617, -0.823639, 0.5)); float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15); float cone_angle_tan = 0.577; @@ -1505,54 +1467,50 @@ void gi_probe_compute(mediump sampler3D probe, mat4 probe_xform, vec3 bounds,vec #define MAX_CONE_DIRS 4 - vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] ( + vec3 cone_dirs[MAX_CONE_DIRS] = vec3[]( vec3(0.707107, 0, 0.707107), vec3(0, 0.707107, 0.707107), vec3(-0.707107, 0, 0.707107), - vec3(0, -0.707107, 0.707107) - ); + vec3(0, -0.707107, 0.707107)); float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.25, 0.25, 0.25); float cone_angle_tan = 0.98269; - max_distance*=0.5; + max_distance *= 0.5; float min_ref_tan = 0.2; #endif - vec3 light=vec3(0.0); - for(int i=0;i<MAX_CONE_DIRS;i++) { - - vec3 dir = normalize( (probe_xform * vec4(pos + normal_mtx * cone_dirs[i],1.0)).xyz - probe_pos); - light+=cone_weights[i] * voxel_cone_trace(probe,cell_size,probe_pos,ambient,blend_ambient,dir,cone_angle_tan,max_distance,p_bias); + vec3 light = vec3(0.0); + for (int i = 0; i < MAX_CONE_DIRS; i++) { + vec3 dir = normalize((probe_xform * vec4(pos + normal_mtx * cone_dirs[i], 1.0)).xyz - probe_pos); + light += cone_weights[i] * voxel_cone_trace(probe, cell_size, probe_pos, ambient, blend_ambient, dir, cone_angle_tan, max_distance, p_bias); } - light*=multiplier; + light *= multiplier; - out_diff += vec4(light*blend,blend); + out_diff += vec4(light * blend, blend); //irradiance - vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,max(min_ref_tan,tan(roughness * 0.5 * M_PI)) ,max_distance,p_bias); + vec3 irr_light = voxel_cone_trace(probe, cell_size, probe_pos, environment, blend_ambient, ref_vec, max(min_ref_tan, tan(roughness * 0.5 * M_PI)), max_distance, p_bias); irr_light *= multiplier; //irr_light=vec3(0.0); - out_spec += vec4(irr_light*blend,blend); - + out_spec += vec4(irr_light * blend, blend); } - void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_specular, inout vec3 out_ambient) { roughness = roughness * roughness; - vec3 ref_vec = normalize(reflect(normalize(pos),normal)); + vec3 ref_vec = normalize(reflect(normalize(pos), normal)); //find arbitrary tangent and bitangent, then build a matrix vec3 v0 = abs(normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0); vec3 tangent = normalize(cross(v0, normal)); vec3 bitangent = normalize(cross(tangent, normal)); - mat3 normal_mat = mat3(tangent,bitangent,normal); + mat3 normal_mat = mat3(tangent, bitangent, normal); vec4 diff_accum = vec4(0.0); vec4 spec_accum = vec4(0.0); @@ -1564,85 +1522,81 @@ 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,gi_probe_normal_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,gi_probe_normal_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) { - diff_accum.rgb/=diff_accum.a; + if (diff_accum.a > 0.0) { + diff_accum.rgb /= diff_accum.a; } - if (spec_accum.a>0.0) { - spec_accum.rgb/=spec_accum.a; + if (spec_accum.a > 0.0) { + spec_accum.rgb /= spec_accum.a; } - out_specular+=spec_accum.rgb; - out_ambient+=diff_accum.rgb; - + out_specular += spec_accum.rgb; + out_ambient += diff_accum.rgb; } #endif - - void main() { #ifdef RENDER_DEPTH_DUAL_PARABOLOID - if (dp_clip>0.0) + if (dp_clip > 0.0) discard; #endif //lay out everything, whathever is unused is optimized away anyway highp vec3 vertex = vertex_interp; - vec3 albedo = vec3(0.8,0.8,0.8); + vec3 albedo = vec3(1.0); vec3 transmission = vec3(0.0); float metallic = 0.0; float specular = 0.5; - vec3 emission = vec3(0.0,0.0,0.0); + vec3 emission = vec3(0.0); float roughness = 1.0; float rim = 0.0; float rim_tint = 0.0; - float clearcoat=0.0; - float clearcoat_gloss=0.0; - float anisotropy = 1.0; - vec2 anisotropy_flow = vec2(1.0,0.0); + float clearcoat = 0.0; + float clearcoat_gloss = 0.0; + float anisotropy = 0.0; + vec2 anisotropy_flow = vec2(1.0, 0.0); #if defined(ENABLE_AO) - float ao=1.0; - float ao_light_affect=0.0; + float ao = 1.0; + float ao_light_affect = 0.0; #endif float alpha = 1.0; #if defined(DO_SIDE_CHECK) - float side=float(gl_FrontFacing)*2.0-1.0; + float side = gl_FrontFacing ? 1.0 : -1.0; #else - float side=1.0; + float side = 1.0; #endif - #if defined(ALPHA_SCISSOR_USED) float alpha_scissor = 0.5; #endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) - vec3 binormal = normalize(binormal_interp)*side; - vec3 tangent = normalize(tangent_interp)*side; + vec3 binormal = normalize(binormal_interp) * side; + vec3 tangent = normalize(tangent_interp) * side; #else vec3 binormal = vec3(0.0); vec3 tangent = vec3(0.0); #endif - vec3 normal = normalize(normal_interp)*side; + vec3 normal = normalize(normal_interp) * side; #if defined(ENABLE_UV_INTERP) vec2 uv = uv_interp; #endif -#if defined(ENABLE_UV2_INTERP) || defined (USE_LIGHTMAP) +#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP) vec2 uv2 = uv2_interp; #endif @@ -1655,66 +1609,67 @@ void main() { vec3 normalmap = vec3(0.5); #endif - float normaldepth=1.0; + float normaldepth = 1.0; #if defined(SCREEN_UV_USED) - vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size; + vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size; #endif -#if defined (ENABLE_SSS) - float sss_strength=0.0; +#if defined(ENABLE_SSS) + float sss_strength = 0.0; #endif -{ - + { + /* clang-format off */ FRAGMENT_SHADER_CODE -} - + /* clang-format on */ + } #if defined(ALPHA_SCISSOR_USED) - if (alpha<alpha_scissor) { + if (alpha < alpha_scissor) { discard; } #endif #ifdef USE_OPAQUE_PREPASS - if (alpha<0.99) { + if (alpha < opaque_prepass_threshold) { discard; } + #endif #if defined(ENABLE_NORMALMAP) - normalmap.xy=normalmap.xy*2.0-1.0; - normalmap.z=sqrt(1.0-dot(normalmap.xy,normalmap.xy)); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. + normalmap.xy = normalmap.xy * 2.0 - 1.0; + normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. - normal = normalize( mix(normal_interp,tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z,normaldepth) ) * side; + normal = normalize(mix(normal_interp, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)) * side; #endif #if defined(LIGHT_USE_ANISOTROPY) - if (anisotropy>0.01) { + if (anisotropy > 0.01) { //rotation matrix - mat3 rot = mat3( tangent, binormal, normal ); + mat3 rot = mat3(tangent, binormal, normal); //make local to space - tangent = normalize(rot * vec3(anisotropy_flow.x,anisotropy_flow.y,0.0)); - binormal = normalize(rot * vec3(-anisotropy_flow.y,anisotropy_flow.x,0.0)); + tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0)); + binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0)); } #endif #ifdef ENABLE_CLIP_ALPHA - if (albedo.a<0.99) { + if (albedo.a < 0.99) { //used for doublepass and shadowmapping discard; } #endif -/////////////////////// LIGHTING ////////////////////////////// + /////////////////////// LIGHTING ////////////////////////////// //apply energy conservation @@ -1724,68 +1679,65 @@ FRAGMENT_SHADER_CODE vec3 diffuse_light = diffuse_light_interp.rgb; #else - vec3 specular_light = vec3(0.0,0.0,0.0); - vec3 diffuse_light = vec3(0.0,0.0,0.0); + vec3 specular_light = vec3(0.0, 0.0, 0.0); + 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 ); - + vec3 env_reflection_light = vec3(0.0, 0.0, 0.0); + vec3 eye_vec = -normalize(vertex_interp); #ifdef USE_RADIANCE_MAP - if (no_ambient_light) { - ambient_light=vec3(0.0,0.0,0.0); - } else { - { - - { //read radiance from dual paraboloid +#ifdef AMBIENT_LIGHT_DISABLED + ambient_light = vec3(0.0, 0.0, 0.0); +#else + { - 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 = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy; - env_reflection_light = radiance; - - } - //no longer a cubemap - //vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y); + { //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 = textureDualParaboloid(radiance_map, ref_vec, roughness) * bg_energy; + env_reflection_light = radiance; } + //no longer a cubemap + //vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y); + } #ifndef USE_LIGHTMAP - { + { - vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz); - vec3 env_ambient=textureDualParaboloid(radiance_map,ambient_dir,1.0) * bg_energy; + vec3 ambient_dir = normalize((radiance_inverse_xform * vec4(normal, 0.0)).xyz); + 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); - } -#endif + ambient_light = mix(ambient_light_color.rgb, env_ambient, radiance_ambient_contribution); + //ambient_light=vec3(0.0,0.0,0.0); } +#endif +#endif //AMBIENT_LIGHT_DISABLED #else - if (no_ambient_light){ - ambient_light=vec3(0.0,0.0,0.0); - } else { - ambient_light=ambient_light_color.rgb; - } +#ifdef AMBIENT_LIGHT_DISABLED + ambient_light = vec3(0.0, 0.0, 0.0); +#else + ambient_light = ambient_light_color.rgb; +#endif //AMBIENT_LIGHT_DISABLED + #endif - ambient_light*=ambient_energy; + ambient_light *= ambient_energy; - float specular_blob_intensity=1.0; + float specular_blob_intensity = 1.0; #if defined(SPECULAR_TOON) - specular_blob_intensity*=specular * 2.0; + specular_blob_intensity *= specular * 2.0; #endif #if defined(USE_LIGHT_DIRECTIONAL) - vec3 light_attenuation=vec3(1.0); + vec3 light_attenuation = vec3(1.0); float depth_z = -vertex.z; #ifdef LIGHT_DIRECTIONAL_SHADOW @@ -1799,261 +1751,234 @@ FRAGMENT_SHADER_CODE if (depth_z < shadow_split_offsets.x) { #endif //LIGHT_USE_PSSM4 - vec3 pssm_coord; - float pssm_fade=0.0; + vec3 pssm_coord; + float pssm_fade = 0.0; #ifdef LIGHT_USE_PSSM_BLEND - float pssm_blend; - vec3 pssm_coord2; - bool use_blend=true; + float pssm_blend; + vec3 pssm_coord2; + bool use_blend = true; #endif - #ifdef LIGHT_USE_PSSM4 + if (depth_z < shadow_split_offsets.y) { - if (depth_z < shadow_split_offsets.y) { - - if (depth_z < shadow_split_offsets.x) { - - highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; + if (depth_z < shadow_split_offsets.x) { + highp vec4 splane = (shadow_matrix1 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; #if defined(LIGHT_USE_PSSM_BLEND) - splane=(shadow_matrix2 * vec4(vertex,1.0)); - pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z); + splane = (shadow_matrix2 * vec4(vertex, 1.0)); + pssm_coord2 = splane.xyz / splane.w; + pssm_blend = smoothstep(0.0, shadow_split_offsets.x, depth_z); #endif - } else { + } else { - highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; + highp vec4 splane = (shadow_matrix2 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; #if defined(LIGHT_USE_PSSM_BLEND) - splane=(shadow_matrix3 * vec4(vertex,1.0)); - pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z); + splane = (shadow_matrix3 * vec4(vertex, 1.0)); + pssm_coord2 = splane.xyz / splane.w; + pssm_blend = smoothstep(shadow_split_offsets.x, shadow_split_offsets.y, depth_z); #endif + } + } else { - } - } else { - - - if (depth_z < shadow_split_offsets.z) { + if (depth_z < shadow_split_offsets.z) { - highp vec4 splane=(shadow_matrix3 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; + highp vec4 splane = (shadow_matrix3 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; #if defined(LIGHT_USE_PSSM_BLEND) - splane=(shadow_matrix4 * vec4(vertex,1.0)); - pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(shadow_split_offsets.y,shadow_split_offsets.z,depth_z); + splane = (shadow_matrix4 * vec4(vertex, 1.0)); + pssm_coord2 = splane.xyz / splane.w; + pssm_blend = smoothstep(shadow_split_offsets.y, shadow_split_offsets.z, depth_z); #endif - } else { + } else { - highp vec4 splane=(shadow_matrix4 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; - pssm_fade = smoothstep(shadow_split_offsets.z,shadow_split_offsets.w,depth_z); + highp vec4 splane = (shadow_matrix4 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; + pssm_fade = smoothstep(shadow_split_offsets.z, shadow_split_offsets.w, depth_z); #if defined(LIGHT_USE_PSSM_BLEND) - use_blend=false; + use_blend = false; #endif - + } } - } - - #endif //LIGHT_USE_PSSM4 #ifdef LIGHT_USE_PSSM2 - if (depth_z < shadow_split_offsets.x) { - - highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; + if (depth_z < shadow_split_offsets.x) { + highp vec4 splane = (shadow_matrix1 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; #if defined(LIGHT_USE_PSSM_BLEND) - splane=(shadow_matrix2 * vec4(vertex,1.0)); - pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z); + splane = (shadow_matrix2 * vec4(vertex, 1.0)); + pssm_coord2 = splane.xyz / splane.w; + pssm_blend = smoothstep(0.0, shadow_split_offsets.x, depth_z); #endif - } else { - highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; - pssm_fade = smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z); + } else { + highp vec4 splane = (shadow_matrix2 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; + pssm_fade = smoothstep(shadow_split_offsets.x, shadow_split_offsets.y, depth_z); #if defined(LIGHT_USE_PSSM_BLEND) - use_blend=false; + use_blend = false; #endif - - } + } #endif //LIGHT_USE_PSSM2 #if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2) - { //regular orthogonal - highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); - pssm_coord=splane.xyz/splane.w; - } + { //regular orthogonal + highp vec4 splane = (shadow_matrix1 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; + } #endif + //one one sample - //one one sample - - float shadow = sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp); + float shadow = sample_shadow(directional_shadow, directional_shadow_pixel_size, pssm_coord.xy, pssm_coord.z, light_clamp); #if defined(LIGHT_USE_PSSM_BLEND) - if (use_blend) { - shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp),pssm_blend); - } + if (use_blend) { + shadow = mix(shadow, sample_shadow(directional_shadow, directional_shadow_pixel_size, pssm_coord2.xy, pssm_coord2.z, light_clamp), pssm_blend); + } #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); + 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(mix(shadow_color_contact.rgb,vec3(1.0),shadow),vec3(1.0),pssm_fade); - - + light_attenuation = mix(mix(shadow_color_contact.rgb, vec3(1.0), shadow), vec3(1.0), pssm_fade); } - #endif // !defined(SHADOWS_DISABLED) #endif //LIGHT_DIRECTIONAL_SHADOW #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); + 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,transmission,light_params.z*specular_blob_intensity,roughness,metallic,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, 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,env_reflection_light,ambient_light); + gi_probes_compute(vertex, normal, roughness, env_reflection_light, ambient_light); #endif #ifdef USE_LIGHTMAP - ambient_light = texture(lightmap,uv2).rgb * lightmap_energy; + ambient_light = texture(lightmap, uv2).rgb * lightmap_energy; #endif #ifdef USE_LIGHTMAP_CAPTURE { - vec3 cone_dirs[12] = vec3[] ( - vec3(0, 0, 1), - vec3(0.866025, 0, 0.5), - vec3(0.267617, 0.823639, 0.5), - vec3(-0.700629, 0.509037, 0.5), - vec3(-0.700629, -0.509037, 0.5), - vec3(0.267617, -0.823639, 0.5), - vec3(0, 0, -1), - vec3(0.866025, 0, -0.5), - vec3(0.267617, 0.823639, -0.5), - vec3(-0.700629, 0.509037, -0.5), - vec3(-0.700629, -0.509037, -0.5), - vec3(0.267617, -0.823639, -0.5) - ); - - - vec3 local_normal = normalize(camera_matrix * vec4(normal,0.0)).xyz; + vec3 cone_dirs[12] = vec3[]( + vec3(0, 0, 1), + vec3(0.866025, 0, 0.5), + vec3(0.267617, 0.823639, 0.5), + vec3(-0.700629, 0.509037, 0.5), + vec3(-0.700629, -0.509037, 0.5), + vec3(0.267617, -0.823639, 0.5), + vec3(0, 0, -1), + vec3(0.866025, 0, -0.5), + vec3(0.267617, 0.823639, -0.5), + vec3(-0.700629, 0.509037, -0.5), + vec3(-0.700629, -0.509037, -0.5), + vec3(0.267617, -0.823639, -0.5)); + + vec3 local_normal = normalize(camera_matrix * vec4(normal, 0.0)).xyz; vec4 captured = vec4(0.0); float sum = 0.0; - for(int i=0;i<12;i++) { - float amount = max(0.0,dot(local_normal,cone_dirs[i])); //not correct, but creates a nice wrap around effect - captured += lightmap_captures[i]*amount; - sum+=amount; + for (int i = 0; i < 12; i++) { + float amount = max(0.0, dot(local_normal, cone_dirs[i])); //not correct, but creates a nice wrap around effect + captured += lightmap_captures[i] * amount; + sum += amount; } - captured/=sum; + captured /= sum; if (lightmap_capture_sky) { - ambient_light = mix( ambient_light, captured.rgb, captured.a); + ambient_light = mix(ambient_light, captured.rgb, captured.a); } else { ambient_light = captured.rgb; } - } #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,env_reflection_light,reflection_accum,ambient_accum); + 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, env_reflection_light, reflection_accum, ambient_accum); } - if (reflection_accum.a>0.0) { - specular_light+=reflection_accum.rgb/reflection_accum.a; + if (reflection_accum.a > 0.0) { + specular_light += reflection_accum.rgb / reflection_accum.a; } else { - specular_light+=env_reflection_light; + specular_light += env_reflection_light; } #ifndef USE_LIGHTMAP - if (ambient_accum.a>0.0) { - ambient_light=ambient_accum.rgb/ambient_accum.a; + if (ambient_accum.a > 0.0) { + ambient_light = ambient_accum.rgb / ambient_accum.a; } #endif - #ifdef USE_VERTEX_LIGHTING - diffuse_light*=albedo; + 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,transmission,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); + 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, 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,transmission,roughness,metallic,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, transmission, roughness, metallic, 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 - specular_light*=reflection_multiplier; - ambient_light*=albedo; //ambient must be multiplied by albedo at the end + specular_light *= reflection_multiplier; + ambient_light *= albedo; //ambient must be multiplied by albedo at the end #if defined(ENABLE_AO) - ambient_light*=ao; - ao_light_affect = mix(1.0,ao,ao_light_affect); - specular_light*=ao_light_affect; - diffuse_light*=ao_light_affect; + ambient_light *= ao; + ao_light_affect = mix(1.0, ao, ao_light_affect); + specular_light *= ao_light_affect; + diffuse_light *= ao_light_affect; #endif - - //energy conservation - diffuse_light *= 1.0-metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point - ambient_light *= 1.0-metallic; - + diffuse_light *= 1.0 - metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point + ambient_light *= 1.0 - metallic; { @@ -2064,27 +1989,24 @@ FRAGMENT_SHADER_CODE // Environment brdf approximation (Lazarov 2013) // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); - const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04); + const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04); vec4 r = roughness * c0 + c1; - float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); - float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y; - vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; + float ndotv = clamp(dot(normal, eye_vec), 0.0, 1.0); + float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; + vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw; vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo); specular_light *= AB.x * specular_color + AB.y; #endif - } if (fog_color_enabled.a > 0.5) { - float fog_amount=0.0; - - + float fog_amount = 0.0; #ifdef USE_LIGHT_DIRECTIONAL - vec3 fog_color = mix( fog_color_enabled.rgb, fog_sun_color_amount.rgb,fog_sun_color_amount.a * pow(max( dot(normalize(vertex),-light_direction_attenuation.xyz), 0.0),8.0) ); + vec3 fog_color = mix(fog_color_enabled.rgb, fog_sun_color_amount.rgb, fog_sun_color_amount.a * pow(max(dot(normalize(vertex), -light_direction_attenuation.xyz), 0.0), 8.0)); #else vec3 fog_color = fog_color_enabled.rgb; @@ -2094,79 +2016,67 @@ FRAGMENT_SHADER_CODE if (fog_depth_enabled) { - float fog_z = smoothstep(fog_depth_begin,z_far,length(vertex)); + float fog_z = smoothstep(fog_depth_begin, z_far, length(vertex)); - fog_amount = pow(fog_z,fog_depth_curve); + fog_amount = pow(fog_z, fog_depth_curve); if (fog_transmit_enabled) { vec3 total_light = emission + ambient_light + specular_light + diffuse_light; - float transmit = pow(fog_z,fog_transmit_curve); - fog_color = mix(max(total_light,fog_color),fog_color,transmit); + float transmit = pow(fog_z, fog_transmit_curve); + fog_color = mix(max(total_light, fog_color), fog_color, transmit); } } if (fog_height_enabled) { - float y = (camera_matrix * vec4(vertex,1.0)).y; - fog_amount = max(fog_amount,pow(smoothstep(fog_height_min,fog_height_max,y),fog_height_curve)); + float y = (camera_matrix * vec4(vertex, 1.0)).y; + fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve)); } float rev_amount = 1.0 - fog_amount; - emission = emission * rev_amount + fog_color * fog_amount; - ambient_light*=rev_amount; - specular_light*rev_amount; - diffuse_light*=rev_amount; - + ambient_light *= rev_amount; + specular_light *rev_amount; + diffuse_light *= rev_amount; } #ifdef USE_MULTIPLE_RENDER_TARGETS - #ifdef SHADELESS - diffuse_buffer=vec4(albedo.rgb,0.0); - specular_buffer=vec4(0.0); + diffuse_buffer = vec4(albedo.rgb, 0.0); + specular_buffer = vec4(0.0); #else -#if defined(ENABLE_AO) - - float ambient_scale=0.0; // AO is supplied by material -#else //approximate ambient scale for SSAO, since we will lack full ambient - float max_emission=max(emission.r,max(emission.g,emission.b)); - float max_ambient=max(ambient_light.r,max(ambient_light.g,ambient_light.b)); - float max_diffuse=max(diffuse_light.r,max(diffuse_light.g,diffuse_light.b)); - float total_ambient = max_ambient+max_diffuse+max_emission; - float ambient_scale = (total_ambient>0.0) ? (max_ambient+ambient_occlusion_affect_light*max_diffuse)/total_ambient : 0.0; -#endif //ENABLE_AO + float max_emission = max(emission.r, max(emission.g, emission.b)); + float max_ambient = max(ambient_light.r, max(ambient_light.g, ambient_light.b)); + float max_diffuse = max(diffuse_light.r, max(diffuse_light.g, diffuse_light.b)); + float total_ambient = max_ambient + max_diffuse + max_emission; + float ambient_scale = (total_ambient > 0.0) ? (max_ambient + ambient_occlusion_affect_light * max_diffuse) / total_ambient : 0.0; - diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale); - specular_buffer=vec4(specular_light,metallic); +#if defined(ENABLE_AO) + ambient_scale = mix(0.0, ambient_scale, ambient_occlusion_affect_ao_channel); +#endif + diffuse_buffer = vec4(emission + diffuse_light + ambient_light, ambient_scale); + specular_buffer = vec4(specular_light, metallic); #endif //SHADELESS - normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness); + normal_mr_buffer = vec4(normalize(normal) * 0.5 + 0.5, roughness); -#if defined (ENABLE_SSS) +#if defined(ENABLE_SSS) sss_buffer = sss_strength; #endif - #else //USE_MULTIPLE_RENDER_TARGETS - #ifdef SHADELESS - frag_color=vec4(albedo,alpha); + frag_color = vec4(albedo, alpha); #else - frag_color=vec4(emission+ambient_light+diffuse_light+specular_light,alpha); + frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha); #endif //SHADELESS - #endif //USE_MULTIPLE_RENDER_TARGETS - - #endif //RENDER_DEPTH - - } diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl index b2e6f7a736..86546319a0 100644 --- a/drivers/gles3/shaders/screen_space_reflection.glsl +++ b/drivers/gles3/shaders/screen_space_reflection.glsl @@ -1,8 +1,9 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; out vec2 pos_interp; @@ -11,13 +12,14 @@ void main() { uv_interp = uv_in; gl_Position = vertex_attrib; - pos_interp.xy=gl_Position.xy; + pos_interp.xy = gl_Position.xy; } +/* clang-format off */ [fragment] - in vec2 uv_interp; +/* clang-format on */ in vec2 pos_interp; uniform sampler2D source_diffuse; //texunit:0 @@ -40,81 +42,67 @@ uniform float depth_tolerance; uniform float distance_fade; uniform float curve_fade_in; - layout(location = 0) out vec4 frag_color; - -vec2 view_to_screen(vec3 view_pos,out float w) { - vec4 projected = projection * vec4(view_pos, 1.0); - projected.xyz /= projected.w; - projected.xy = projected.xy * 0.5 + 0.5; - w=projected.w; - return projected.xy; +vec2 view_to_screen(vec3 view_pos, out float w) { + vec4 projected = projection * vec4(view_pos, 1.0); + projected.xyz /= projected.w; + projected.xy = projected.xy * 0.5 + 0.5; + w = projected.w; + return projected.xy; } - - #define M_PI 3.14159265359 void main() { - - //// - - vec4 diffuse = texture( source_diffuse, uv_interp ); - vec4 normal_roughness = texture( source_normal_roughness, uv_interp); + vec4 diffuse = texture(source_diffuse, uv_interp); + vec4 normal_roughness = texture(source_normal_roughness, uv_interp); vec3 normal; - - normal = normal_roughness.xyz*2.0-1.0; + normal = normal_roughness.xyz * 2.0 - 1.0; float roughness = normal_roughness.w; - float depth_tex = texture(source_depth,uv_interp).r; + float depth_tex = texture(source_depth, uv_interp).r; - vec4 world_pos = inverse_projection * vec4( uv_interp*2.0-1.0, depth_tex*2.0-1.0, 1.0 ); - vec3 vertex = world_pos.xyz/world_pos.w; + vec4 world_pos = inverse_projection * vec4(uv_interp * 2.0 - 1.0, depth_tex * 2.0 - 1.0, 1.0); + vec3 vertex = world_pos.xyz / world_pos.w; vec3 view_dir = normalize(vertex); vec3 ray_dir = normalize(reflect(view_dir, normal)); - if (dot(ray_dir,normal)<0.001) { - frag_color=vec4(0.0); + if (dot(ray_dir, normal) < 0.001) { + frag_color = vec4(0.0); return; } //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0); - - //ray_dir = normalize(vec3(1,1,-1)); - + //ray_dir = normalize(vec3(1, 1, -1)); //////////////// - - //make ray length and clip it against the near plane (don't want to trace beyond visible) + // make ray length and clip it against the near plane (don't want to trace beyond visible) float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far; - vec3 ray_end = vertex + ray_dir*ray_len; + vec3 ray_end = vertex + ray_dir * ray_len; float w_begin; - vec2 vp_line_begin = view_to_screen(vertex,w_begin); + vec2 vp_line_begin = view_to_screen(vertex, w_begin); float w_end; - vec2 vp_line_end = view_to_screen( ray_end, w_end); - vec2 vp_line_dir = vp_line_end-vp_line_begin; - - //we need to interpolate w along the ray, to generate perspective correct reflections - - w_begin = 1.0/w_begin; - w_end = 1.0/w_end; + vec2 vp_line_end = view_to_screen(ray_end, w_end); + vec2 vp_line_dir = vp_line_end - vp_line_begin; + // we need to interpolate w along the ray, to generate perspective correct reflections + w_begin = 1.0 / w_begin; + w_end = 1.0 / w_end; - float z_begin = vertex.z*w_begin; - float z_end = ray_end.z*w_end; + float z_begin = vertex.z * w_begin; + float z_end = ray_end.z * w_end; - vec2 line_begin = vp_line_begin/pixel_size; - vec2 line_dir = vp_line_dir/pixel_size; + vec2 line_begin = vp_line_begin / pixel_size; + vec2 line_dir = vp_line_dir / pixel_size; float z_dir = z_end - z_begin; float w_dir = w_end - w_begin; - // clip the line to the viewport edges float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x)); @@ -124,126 +112,114 @@ void main() { float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y); line_dir *= line_clip; z_dir *= line_clip; - w_dir *=line_clip; + w_dir *= line_clip; - //clip z and w advance to line advance - vec2 line_advance = normalize(line_dir); //down to pixel - float step_size = length(line_advance)/length(line_dir); - float z_advance = z_dir*step_size; // adapt z advance to line advance - float w_advance = w_dir*step_size; // adapt w advance to line advance + // clip z and w advance to line advance + vec2 line_advance = normalize(line_dir); // down to pixel + float step_size = length(line_advance) / length(line_dir); + float z_advance = z_dir * step_size; // adapt z advance to line advance + float w_advance = w_dir * step_size; // adapt w advance to line advance - //make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice) - float advance_angle_adj = 1.0/max(abs(line_advance.x),abs(line_advance.y)); - line_advance*=advance_angle_adj; // adapt z advance to line advance - z_advance*=advance_angle_adj; - w_advance*=advance_angle_adj; + // make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice) + float advance_angle_adj = 1.0 / max(abs(line_advance.x), abs(line_advance.y)); + line_advance *= advance_angle_adj; // adapt z advance to line advance + z_advance *= advance_angle_adj; + w_advance *= advance_angle_adj; vec2 pos = line_begin; float z = z_begin; float w = w_begin; - float z_from=z/w; - float z_to=z_from; + float z_from = z / w; + float z_to = z_from; float depth; - vec2 prev_pos=pos; + vec2 prev_pos = pos; - bool found=false; + bool found = false; - float steps_taken=0.0; + float steps_taken = 0.0; - for(int i=0;i<num_steps;i++) { + for (int i = 0; i < num_steps; i++) { - pos+=line_advance; - z+=z_advance; - w+=w_advance; + pos += line_advance; + z += z_advance; + w += w_advance; - //convert to linear depth + // convert to linear depth - depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0; + depth = texture(source_depth, pos * pixel_size).r * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); #endif - depth=-depth; + depth = -depth; z_from = z_to; - z_to = z/w; + z_to = z / w; - if (depth>z_to) { - //if depth was surpassed - if (depth<=max(z_to,z_from)+depth_tolerance) { - //check the depth tolerance - found=true; + if (depth > z_to) { + // if depth was surpassed + if (depth <= max(z_to, z_from) + depth_tolerance) { + // check the depth tolerance + found = true; } break; } - steps_taken+=1.0; - prev_pos=pos; + steps_taken += 1.0; + prev_pos = pos; } - - - if (found) { - float margin_blend=1.0; + float margin_blend = 1.0; - - vec2 margin = vec2((viewport_size.x+viewport_size.y)*0.5*0.05); //make a uniform margin - if (any(bvec4(lessThan(pos,-margin),greaterThan(pos,viewport_size+margin)))) { - //clip outside screen + margin - frag_color=vec4(0.0); + vec2 margin = vec2((viewport_size.x + viewport_size.y) * 0.5 * 0.05); // make a uniform margin + if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, viewport_size + margin)))) { + // clip outside screen + margin + frag_color = vec4(0.0); return; } { //blend fading out towards external margin - vec2 margin_grad = mix(pos-viewport_size,-pos,lessThan(pos,vec2(0.0))); - margin_blend = 1.0-smoothstep(0.0,margin.x,max(margin_grad.x,margin_grad.y)); - //margin_blend=1.0; - + vec2 margin_grad = mix(pos - viewport_size, -pos, lessThan(pos, vec2(0.0))); + margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y)); + //margin_blend = 1.0; } vec2 final_pos; float grad; - grad=steps_taken/float(num_steps); - float initial_fade = curve_fade_in==0.0 ? 1.0 : pow(clamp(grad,0.0,1.0),curve_fade_in); - float fade = pow(clamp(1.0-grad,0.0,1.0),distance_fade)*initial_fade; - final_pos=pos; - - - - - - + grad = steps_taken / float(num_steps); + float initial_fade = curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), curve_fade_in); + float fade = pow(clamp(1.0 - grad, 0.0, 1.0), distance_fade) * initial_fade; + final_pos = pos; #ifdef REFLECT_ROUGHNESS - vec4 final_color; - //if roughness is enabled, do screen space cone tracing + // if roughness is enabled, do screen space cone tracing if (roughness > 0.001) { /////////////////////////////////////////////////////////////////////////////////////// - //use a blurred version (in consecutive mipmaps) of the screen to simulate roughness + // use a blurred version (in consecutive mipmaps) of the screen to simulate roughness - float gloss = 1.0-roughness; + float gloss = 1.0 - roughness; float cone_angle = roughness * M_PI * 0.5; vec2 cone_dir = final_pos - line_begin; float cone_len = length(cone_dir); - cone_dir = normalize(cone_dir); //will be used normalized from now on + cone_dir = normalize(cone_dir); // will be used normalized from now on float max_mipmap = filter_mipmap_levels - 1.0; - float gloss_mult=gloss; + float gloss_mult = gloss; - float rem_alpha=1.0; + float rem_alpha = 1.0; final_color = vec4(0.0); - for(int i=0;i<7;i++) { + for (int i = 0; i < 7; i++) { - float op_len = 2.0 * tan(cone_angle) * cone_len; //opposite side of iso triangle + float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle float radius; { - //fit to sphere inside cone (sphere ends at end of cone), something like this: + // fit to sphere inside cone (sphere ends at end of cone), something like this: // ___ // \O/ // V @@ -257,31 +233,31 @@ void main() { radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h); } - //find the place where screen must be sampled - vec2 sample_pos = ( line_begin + cone_dir * (cone_len - radius) ) * pixel_size; - //radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels - float mipmap = clamp( log2( radius ), 0.0, max_mipmap ); + // find the place where screen must be sampled + vec2 sample_pos = (line_begin + cone_dir * (cone_len - radius)) * pixel_size; + // radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels + float mipmap = clamp(log2(radius), 0.0, max_mipmap); + //mipmap = max(mipmap - 1.0, 0.0); - //mipmap = max(mipmap-1.0,0.0); - //do sampling + // do sampling vec4 sample_color; { - sample_color = textureLod(source_diffuse,sample_pos,mipmap); + sample_color = textureLod(source_diffuse, sample_pos, mipmap); } - //multiply by gloss - sample_color.rgb*=gloss_mult; - sample_color.a=gloss_mult; + // multiply by gloss + sample_color.rgb *= gloss_mult; + sample_color.a = gloss_mult; rem_alpha -= sample_color.a; - if(rem_alpha < 0.0) { + if (rem_alpha < 0.0) { sample_color.rgb *= (1.0 - abs(rem_alpha)); } - final_color+=sample_color; + final_color += sample_color; - if (final_color.a>=0.95) { + if (final_color.a >= 0.95) { // This code of accumulating gloss and aborting on near one // makes sense when you think of cone tracing. // Think of it as if roughness was 0, then we could abort on the first @@ -290,29 +266,21 @@ void main() { break; } - cone_len-=radius*2.0; //go to next (smaller) circle. - - gloss_mult*=gloss; - + cone_len -= radius * 2.0; // go to next (smaller) circle. + gloss_mult *= gloss; } } else { - final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0); + final_color = textureLod(source_diffuse, final_pos * pixel_size, 0.0); } - frag_color = vec4(final_color.rgb,fade*margin_blend); + frag_color = vec4(final_color.rgb, fade * margin_blend); #else - frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,fade*margin_blend); + frag_color = vec4(textureLod(source_diffuse, final_pos * pixel_size, 0.0).rgb, fade * margin_blend); #endif - - } else { - frag_color = vec4(0.0,0.0,0.0,0.0); + frag_color = vec4(0.0, 0.0, 0.0, 0.0); } - - - } - diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl index 219f0957e0..be44365169 100644 --- a/drivers/gles3/shaders/ssao.glsl +++ b/drivers/gles3/shaders/ssao.glsl @@ -1,34 +1,30 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ void main() { gl_Position = vertex_attrib; - gl_Position.z=1.0; + gl_Position.z = 1.0; } +/* clang-format off */ [fragment] #define TWO_PI 6.283185307179586476925286766559 #ifdef SSAO_QUALITY_HIGH - #define NUM_SAMPLES (80) - #endif #ifdef SSAO_QUALITY_LOW - #define NUM_SAMPLES (15) - #endif #if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH) - #define NUM_SAMPLES (40) - #endif // If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower @@ -43,19 +39,21 @@ void main() { // This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent // taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9 -const int ROTATIONS[] = int[]( 1, 1, 2, 3, 2, 5, 2, 3, 2, -3, 3, 5, 5, 3, 4, 7, 5, 5, 7, -9, 8, 5, 5, 7, 7, 7, 8, 5, 8, -11, 12, 7, 10, 13, 8, 11, 8, 7, 14, -11, 11, 13, 12, 13, 19, 17, 13, 11, 18, -19, 11, 11, 14, 17, 21, 15, 16, 17, 18, -13, 17, 11, 17, 19, 18, 25, 18, 19, 19, -29, 21, 19, 27, 31, 29, 21, 18, 17, 29, -31, 31, 23, 18, 25, 26, 25, 23, 19, 34, -19, 27, 21, 25, 39, 29, 17, 21, 27 ); +const int ROTATIONS[] = int[]( + 1, 1, 2, 3, 2, 5, 2, 3, 2, + 3, 3, 5, 5, 3, 4, 7, 5, 5, 7, + 9, 8, 5, 5, 7, 7, 7, 8, 5, 8, + 11, 12, 7, 10, 13, 8, 11, 8, 7, 14, + 11, 11, 13, 12, 13, 19, 17, 13, 11, 18, + 19, 11, 11, 14, 17, 21, 15, 16, 17, 18, + 13, 17, 11, 17, 19, 18, 25, 18, 19, 19, + 29, 21, 19, 27, 31, 29, 21, 18, 17, 29, + 31, 31, 23, 18, 25, 26, 25, 23, 19, 34, + 19, 27, 21, 25, 39, 29, 17, 21, 27); +/* clang-format on */ //#define NUM_SPIRAL_TURNS (7) -const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES-1]; +const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES - 1]; uniform sampler2D source_depth; //texunit:0 uniform highp usampler2D source_depth_mipmaps; //texunit:1 @@ -90,44 +88,41 @@ vec3 reconstructCSPosition(vec2 S, float z) { } vec3 getPosition(ivec2 ssP) { - vec3 P; - P.z = texelFetch(source_depth, ssP, 0).r; + vec3 P; + P.z = texelFetch(source_depth, ssP, 0).r; - P.z = P.z * 2.0 - 1.0; + P.z = P.z * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + P.z = ((P.z + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else - P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); + P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); #endif - P.z = -P.z; + P.z = -P.z; - // Offset to pixel center - P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); - return P; + // Offset to pixel center + P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); + return P; } /** Reconstructs screen-space unit normal from screen-space position */ vec3 reconstructCSFaceNormal(vec3 C) { - return normalize(cross(dFdy(C), dFdx(C))); + return normalize(cross(dFdy(C), dFdx(C))); } - - /** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */ -vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR){ - // Radius relative to ssR - float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES)); - float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle; +vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR) { + // Radius relative to ssR + float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES)); + float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle; - ssR = alpha; - return vec2(cos(angle), sin(angle)); + ssR = alpha; + return vec2(cos(angle), sin(angle)); } - /** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */ vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) { - // Derivation: - // mipLevel = floor(log(ssR / MAX_OFFSET)); + // Derivation: + // mipLevel = floor(log(ssR / MAX_OFFSET)); int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL); ivec2 ssP = ivec2(ssR * unitOffset) + ssC; @@ -138,98 +133,91 @@ vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) { // Manually clamp to the texture size because texelFetch bypasses the texture unit ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (screen_size >> mipLevel) - ivec2(1)); - if (mipLevel < 1) { //read from depth buffer P.z = texelFetch(source_depth, mipP, 0).r; P.z = P.z * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + P.z = ((P.z + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); - #endif P.z = -P.z; } else { //read from mipmaps - uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel-1).r; - P.z = -(float(d)/65535.0)*camera_z_far; + uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel - 1).r; + P.z = -(float(d) / 65535.0) * camera_z_far; } - // Offset to pixel center P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); return P; } - - /** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds - to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius + to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius - Note that units of H() in the HPG12 paper are meters, not - unitless. The whole falloff/sampling function is therefore - unitless. In this implementation, we factor out (9 / radius). + Note that units of H() in the HPG12 paper are meters, not + unitless. The whole falloff/sampling function is therefore + unitless. In this implementation, we factor out (9 / radius). - Four versions of the falloff function are implemented below + Four versions of the falloff function are implemented below */ -float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius,in float p_radius, in int tapIndex, in float randomPatternRotationAngle) { - // Offset on the unit disk, spun for this pixel - float ssR; - vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR); - ssR *= ssDiskRadius; +float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in float p_radius, in int tapIndex, in float randomPatternRotationAngle) { + // Offset on the unit disk, spun for this pixel + float ssR; + vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR); + ssR *= ssDiskRadius; - // The occluding point in camera space - vec3 Q = getOffsetPosition(ssC, unitOffset, ssR); + // The occluding point in camera space + vec3 Q = getOffsetPosition(ssC, unitOffset, ssR); - vec3 v = Q - C; + vec3 v = Q - C; - float vv = dot(v, v); - float vn = dot(v, n_C); + float vv = dot(v, v); + float vn = dot(v, n_C); - const float epsilon = 0.01; - float radius2 = p_radius*p_radius; + const float epsilon = 0.01; + float radius2 = p_radius * p_radius; - // A: From the HPG12 paper - // Note large epsilon to avoid overdarkening within cracks - //return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6; + // A: From the HPG12 paper + // Note large epsilon to avoid overdarkening within cracks + //return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6; - // B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended] - float f=max(radius2 - vv, 0.0); - return f * f * f * max((vn - bias) / (epsilon + vv), 0.0); + // B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended] + float f = max(radius2 - vv, 0.0); + return f * f * f * max((vn - bias) / (epsilon + vv), 0.0); - // C: Medium contrast (which looks better at high radii), no division. Note that the - // contribution still falls off with radius^2, but we've adjusted the rate in a way that is - // more computationally efficient and happens to be aesthetically pleasing. - // return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0); + // C: Medium contrast (which looks better at high radii), no division. Note that the + // contribution still falls off with radius^2, but we've adjusted the rate in a way that is + // more computationally efficient and happens to be aesthetically pleasing. + // return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0); - // D: Low contrast, no division operation - // return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0); + // D: Low contrast, no division operation + // return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0); } - - void main() { - - // Pixel being shaded ivec2 ssC = ivec2(gl_FragCoord.xy); // World space point being shaded vec3 C = getPosition(ssC); -/* if (C.z <= -camera_z_far*0.999) { - // We're on the skybox - visibility=1.0; - return; - }*/ + /* + if (C.z <= -camera_z_far * 0.999) { + // We're on the skybox + visibility=1.0; + return; + } + */ - //visibility=-C.z/camera_z_far; + //visibility = -C.z / camera_z_far; //return; #if 0 - vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; + vec3 n_C = texelFetch(source_normal, ssC, 0).rgb * 2.0 - 1.0; #else vec3 n_C = reconstructCSFaceNormal(C); n_C = -n_C; @@ -251,7 +239,7 @@ void main() { #endif float sum = 0.0; for (int i = 0; i < NUM_SAMPLES; ++i) { - sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius,i, randomPatternRotationAngle); + sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius, i, randomPatternRotationAngle); } float A = max(0.0, 1.0 - sum * intensity_div_r6 * (5.0 / float(NUM_SAMPLES))); @@ -271,10 +259,10 @@ void main() { sum = 0.0; for (int i = 0; i < NUM_SAMPLES; ++i) { - sum += sampleAO(ssC, C, n_C, ssDiskRadius,radius2, i, randomPatternRotationAngle); + sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius2, i, randomPatternRotationAngle); } - A= min(A,max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / float(NUM_SAMPLES)))); + A = min(A, max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / float(NUM_SAMPLES)))); #endif // Bilateral box-filter over a quad for free, respecting depth edges // (the difference that this makes is subtle) @@ -286,8 +274,4 @@ void main() { } visibility = A; - } - - - diff --git a/drivers/gles3/shaders/ssao_blur.glsl b/drivers/gles3/shaders/ssao_blur.glsl index 472dc21acf..c49ea1e957 100644 --- a/drivers/gles3/shaders/ssao_blur.glsl +++ b/drivers/gles3/shaders/ssao_blur.glsl @@ -1,26 +1,25 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; - +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ void main() { gl_Position = vertex_attrib; - gl_Position.z=1.0; + gl_Position.z = 1.0; } +/* clang-format off */ [fragment] - uniform sampler2D source_ssao; //texunit:0 +/* clang-format on */ uniform sampler2D source_depth; //texunit:1 uniform sampler2D source_normal; //texunit:3 - layout(location = 0) out float visibility; - ////////////////////////////////////////////////////////////////////////////////////////////// // Tunable Parameters: @@ -28,32 +27,30 @@ layout(location = 0) out float visibility; uniform float edge_sharpness; /** Step in 2-pixel intervals since we already blurred against neighbors in the - first AO pass. This constant can be increased while R decreases to improve - performance at the expense of some dithering artifacts. + first AO pass. This constant can be increased while R decreases to improve + performance at the expense of some dithering artifacts. - Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was - unobjectionable after shading was applied but eliminated most temporal incoherence - from using small numbers of sample taps. - */ + Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was + unobjectionable after shading was applied but eliminated most temporal incoherence + from using small numbers of sample taps. + */ uniform int filter_scale; /** Filter radius in pixels. This will be multiplied by SCALE. */ -#define R (4) - +#define R (4) ////////////////////////////////////////////////////////////////////////////////////////////// - // Gaussian coefficients const float gaussian[R + 1] = -// float[](0.356642, 0.239400, 0.072410, 0.009869); -// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0 - float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0 -// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0 + //float[](0.356642, 0.239400, 0.072410, 0.009869); + //float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0 + float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0 +//float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0 -/** (1, 0) or (0, 1)*/ -uniform ivec2 axis; +/** (1, 0) or (0, 1) */ +uniform ivec2 axis; uniform float camera_z_far; uniform float camera_z_near; @@ -65,18 +62,18 @@ void main() { ivec2 ssC = ivec2(gl_FragCoord.xy); float depth = texelFetch(source_depth, ssC, 0).r; - //vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; + //vec3 normal = texelFetch(source_normal, ssC, 0).rgb * 2.0 - 1.0; depth = depth * 2.0 - 1.0; depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); float depth_divide = 1.0 / camera_z_far; -// depth*=depth_divide; + //depth *= depth_divide; /* - if (depth > camera_z_far*0.999) { - discard;//skybox + if (depth > camera_z_far * 0.999) { + discard; //skybox } */ @@ -96,23 +93,21 @@ void main() { if (r != 0) { ivec2 ppos = ssC + axis * (r * filter_scale); - float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r; - ivec2 rpos = clamp(ppos,ivec2(0),clamp_limit); + float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r; + ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit); float temp_depth = texelFetch(source_depth, rpos, 0).r; //vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0; temp_depth = temp_depth * 2.0 - 1.0; temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near)); -// temp_depth *= depth_divide; + //temp_depth *= depth_divide; // spatial domain: offset gaussian tap float weight = 0.3 + gaussian[abs(r)]; - //weight *= max(0.0,dot(temp_normal,normal)); + //weight *= max(0.0, dot(temp_normal, normal)); // range domain (the "bilateral" weight). As depth difference increases, decrease weight. - weight *= max(0.0, 1.0 - - edge_sharpness * abs(temp_depth - depth) - ); + weight *= max(0.0, 1.0 - edge_sharpness * abs(temp_depth - depth)); sum += value * weight; totalWeight += weight; diff --git a/drivers/gles3/shaders/ssao_minify.glsl b/drivers/gles3/shaders/ssao_minify.glsl index 647c762438..1696648dae 100644 --- a/drivers/gles3/shaders/ssao_minify.glsl +++ b/drivers/gles3/shaders/ssao_minify.glsl @@ -1,20 +1,22 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ void main() { gl_Position = vertex_attrib; } +/* clang-format off */ [fragment] - #ifdef MINIFY_START #define SDEPTH_TYPE highp sampler2D uniform float camera_z_far; +/* clang-format on */ uniform float camera_z_near; #else @@ -32,28 +34,23 @@ layout(location = 0) out mediump uint depth; void main() { - ivec2 ssP = ivec2(gl_FragCoord.xy); - // Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling. - // On DX9, the bit-and can be implemented with floating-point modulo + // Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling. + // On DX9, the bit-and can be implemented with floating-point modulo #ifdef MINIFY_START float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; fdepth = fdepth * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - fdepth = ((fdepth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + fdepth = ((fdepth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near)); #endif fdepth /= camera_z_far; - depth = uint(clamp(fdepth*65535.0,0.0,65535.0)); + depth = uint(clamp(fdepth * 65535.0, 0.0, 65535.0)); #else depth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; #endif - - } - - diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl index fc66d66198..f40fb3a244 100644 --- a/drivers/gles3/shaders/subsurf_scattering.glsl +++ b/drivers/gles3/shaders/subsurf_scattering.glsl @@ -1,105 +1,93 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; - void main() { uv_interp = uv_in; gl_Position = vertex_attrib; } +/* clang-format off */ [fragment] //#define QUALIFIER uniform // some guy on the interweb says it may be faster with this #define QUALIFIER const #ifdef USE_25_SAMPLES - -const int kernel_size=25; -QUALIFIER vec2 kernel[25] = vec2[] ( - vec2(0.530605, 0.0), - vec2(0.000973794, -3.0), - vec2(0.00333804, -2.52083), - vec2(0.00500364, -2.08333), - vec2(0.00700976, -1.6875), - vec2(0.0094389, -1.33333), - vec2(0.0128496, -1.02083), - vec2(0.017924, -0.75), - vec2(0.0263642, -0.520833), - vec2(0.0410172, -0.333333), - vec2(0.0493588, -0.1875), - vec2(0.0402784, -0.0833333), - vec2(0.0211412, -0.0208333), - vec2(0.0211412, 0.0208333), - vec2(0.0402784, 0.0833333), - vec2(0.0493588, 0.1875), - vec2(0.0410172, 0.333333), - vec2(0.0263642, 0.520833), - vec2(0.017924, 0.75), - vec2(0.0128496, 1.02083), - vec2(0.0094389, 1.33333), - vec2(0.00700976, 1.6875), - vec2(0.00500364, 2.08333), - vec2(0.00333804, 2.52083), - vec2(0.000973794, 3.0) -); - +const int kernel_size = 25; +/* clang-format on */ +QUALIFIER vec2 kernel[25] = vec2[]( + vec2(0.530605, 0.0), + vec2(0.000973794, -3.0), + vec2(0.00333804, -2.52083), + vec2(0.00500364, -2.08333), + vec2(0.00700976, -1.6875), + vec2(0.0094389, -1.33333), + vec2(0.0128496, -1.02083), + vec2(0.017924, -0.75), + vec2(0.0263642, -0.520833), + vec2(0.0410172, -0.333333), + vec2(0.0493588, -0.1875), + vec2(0.0402784, -0.0833333), + vec2(0.0211412, -0.0208333), + vec2(0.0211412, 0.0208333), + vec2(0.0402784, 0.0833333), + vec2(0.0493588, 0.1875), + vec2(0.0410172, 0.333333), + vec2(0.0263642, 0.520833), + vec2(0.017924, 0.75), + vec2(0.0128496, 1.02083), + vec2(0.0094389, 1.33333), + vec2(0.00700976, 1.6875), + vec2(0.00500364, 2.08333), + vec2(0.00333804, 2.52083), + vec2(0.000973794, 3.0)); #endif //USE_25_SAMPLES #ifdef USE_17_SAMPLES - -const int kernel_size=17; - +const int kernel_size = 17; QUALIFIER vec2 kernel[17] = vec2[]( - vec2(0.536343, 0.0), - vec2(0.00317394, -2.0), - vec2(0.0100386, -1.53125), - vec2(0.0144609, -1.125), - vec2(0.0216301, -0.78125), - vec2(0.0347317, -0.5), - vec2(0.0571056, -0.28125), - vec2(0.0582416, -0.125), - vec2(0.0324462, -0.03125), - vec2(0.0324462, 0.03125), - vec2(0.0582416, 0.125), - vec2(0.0571056, 0.28125), - vec2(0.0347317, 0.5), - vec2(0.0216301, 0.78125), - vec2(0.0144609, 1.125), - vec2(0.0100386, 1.53125), - vec2(0.00317394,2.0) -); - + vec2(0.536343, 0.0), + vec2(0.00317394, -2.0), + vec2(0.0100386, -1.53125), + vec2(0.0144609, -1.125), + vec2(0.0216301, -0.78125), + vec2(0.0347317, -0.5), + vec2(0.0571056, -0.28125), + vec2(0.0582416, -0.125), + vec2(0.0324462, -0.03125), + vec2(0.0324462, 0.03125), + vec2(0.0582416, 0.125), + vec2(0.0571056, 0.28125), + vec2(0.0347317, 0.5), + vec2(0.0216301, 0.78125), + vec2(0.0144609, 1.125), + vec2(0.0100386, 1.53125), + vec2(0.00317394, 2.0)); #endif //USE_17_SAMPLES - #ifdef USE_11_SAMPLES - -const int kernel_size=11; - +const int kernel_size = 11; QUALIFIER vec2 kernel[11] = vec2[]( - vec2(0.560479, 0.0), - vec2(0.00471691, -2.0), - vec2(0.0192831, -1.28), - vec2(0.03639, -0.72), - vec2(0.0821904, -0.32), - vec2(0.0771802, -0.08), - vec2(0.0771802, 0.08), - vec2(0.0821904, 0.32), - vec2(0.03639, 0.72), - vec2(0.0192831, 1.28), - vec2(0.00471691,2.0) -); - + vec2(0.560479, 0.0), + vec2(0.00471691, -2.0), + vec2(0.0192831, -1.28), + vec2(0.03639, -0.72), + vec2(0.0821904, -0.32), + vec2(0.0771802, -0.08), + vec2(0.0771802, 0.08), + vec2(0.0821904, 0.32), + vec2(0.03639, 0.72), + vec2(0.0192831, 1.28), + vec2(0.00471691, 2.0)); #endif //USE_11_SAMPLES - - uniform float max_radius; uniform float camera_z_far; uniform float camera_z_near; @@ -115,28 +103,24 @@ layout(location = 0) out vec4 frag_color; void main() { - float strength = texture(source_sss,uv_interp).r; - strength*=strength; //stored as sqrt + float strength = texture(source_sss, uv_interp).r; + strength *= strength; //stored as sqrt // Fetch color of current pixel: vec4 base_color = texture(source_diffuse, uv_interp); - - if (strength>0.0) { - + if (strength > 0.0) { // Fetch linear depth of current pixel: float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; float scale = unit_size; //remember depth is negative by default in OpenGL #else depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); float scale = unit_size / depth; //remember depth is negative by default in OpenGL #endif - - // Calculate the final step to fetch the surrounding pixels: vec2 step = max_radius * scale * dir; step *= strength; // Modulate it using the alpha channel. @@ -157,35 +141,33 @@ void main() { #ifdef ENABLE_FOLLOW_SURFACE // If the difference in depth is huge, we lerp color back to "colorM": - float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0; + float depth_cmp = texture(source_depth, offset).r * 2.0 - 1.0; #ifdef USE_ORTHOGONAL_PROJECTION - depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0; #else depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near)); #endif - float s = clamp(300.0f * scale * - max_radius * abs(depth - depth_cmp),0.0,1.0); + float s = clamp(300.0f * scale * max_radius * abs(depth - depth_cmp), 0.0, 1.0); color = mix(color, base_color.rgb, s); #endif // Accumulate: - color*=kernel[i].x; + color *= kernel[i].x; #ifdef ENABLE_STRENGTH_WEIGHTING float color_s = texture(source_sss, offset).r; - color_weight+=color_s * kernel[i].x; - color*=color_s; + color_weight += color_s * kernel[i].x; + color *= color_s; #endif color_accum += color; - } #ifdef ENABLE_STRENGTH_WEIGHTING - color_accum/=color_weight; + color_accum /= color_weight; #endif - frag_color = vec4(color_accum,base_color.a); //keep alpha (used for SSAO) + frag_color = vec4(color_accum, base_color.a); //keep alpha (used for SSAO) } else { frag_color = base_color; } diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index a75871f08e..e4aa8d5730 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -1,27 +1,29 @@ +/* clang-format off */ [vertex] - -layout(location=0) in highp vec4 vertex_attrib; -layout(location=4) in vec2 uv_in; +layout(location = 0) in highp vec4 vertex_attrib; +/* clang-format on */ +layout(location = 4) in vec2 uv_in; out vec2 uv_interp; void main() { - gl_Position = vertex_attrib; + uv_interp = uv_in; + #ifdef V_FLIP - uv_interp.y = 1.0-uv_interp.y; + uv_interp.y = 1.0f - uv_interp.y; #endif - } +/* clang-format off */ [fragment] #if !defined(GLES_OVER_GL) precision mediump float; #endif - +/* clang-format on */ in vec2 uv_interp; @@ -31,89 +33,74 @@ uniform float exposure; uniform float white; #ifdef USE_AUTO_EXPOSURE - uniform highp sampler2D source_auto_exposure; //texunit:1 uniform highp float auto_exposure_grey; - #endif #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 // only use glow when at least one glow level is selected uniform highp sampler2D source_glow; //texunit:2 uniform highp float glow_intensity; - #endif #ifdef USE_BCS - uniform vec3 bcs; - #endif #ifdef USE_COLOR_CORRECTION - uniform sampler2D color_correction; //texunit:3 - #endif - layout(location = 0) out vec4 frag_color; #ifdef USE_GLOW_FILTER_BICUBIC - // w0, w1, w2, and w3 are the four cubic B-spline basis functions -float w0(float a) -{ - return (1.0/6.0)*(a*(a*(-a + 3.0) - 3.0) + 1.0); +float w0(float a) { + return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); } -float w1(float a) -{ - return (1.0/6.0)*(a*a*(3.0*a - 6.0) + 4.0); +float w1(float a) { + return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f); } -float w2(float a) -{ - return (1.0/6.0)*(a*(a*(-3.0*a + 3.0) + 3.0) + 1.0); +float w2(float a) { + return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f); } -float w3(float a) -{ - return (1.0/6.0)*(a*a*a); +float w3(float a) { + return (1.0f / 6.0f) * (a * a * a); } // g0 and g1 are the two amplitude functions -float g0(float a) -{ - return w0(a) + w1(a); +float g0(float a) { + return w0(a) + w1(a); } -float g1(float a) -{ - return w2(a) + w3(a); +float g1(float a) { + return w2(a) + w3(a); } // h0 and h1 are the two offset functions -float h0(float a) -{ - return -1.0 + w1(a) / (w0(a) + w1(a)); +float h0(float a) { + return -1.0f + w1(a) / (w0(a) + w1(a)); } -float h1(float a) -{ - return 1.0 + w3(a) / (w2(a) + w3(a)); +float h1(float a) { + return 1.0f + w3(a) / (w2(a) + w3(a)); } uniform ivec2 glow_texture_size; -vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod) -{ - float lod=float(p_lod); +vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { + float lod = float(p_lod); vec2 tex_size = vec2(glow_texture_size >> p_lod); - vec2 pixel_size =1.0/tex_size; - uv = uv*tex_size + 0.5; - vec2 iuv = floor( uv ); - vec2 fuv = fract( uv ); + vec2 pixel_size = vec2(1.0f) / tex_size; + + uv = uv * tex_size + vec2(0.5f); + + vec2 iuv = floor(uv); + vec2 fuv = fract(uv); float g0x = g0(fuv.x); float g1x = g1(fuv.x); @@ -122,206 +109,189 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod) float h0y = h0(fuv.y); float h1y = h1(fuv.y); - vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * pixel_size; - vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * pixel_size; - vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * pixel_size; - vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * pixel_size; + vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size; + vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size; + vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size; + vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size; - return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) + - g1x * textureLod(tex, p1,lod)) + - g1(fuv.y) * (g0x * textureLod(tex, p2,lod) + - g1x * textureLod(tex, p3,lod)); + return (g0(fuv.y) * (g0x * textureLod(tex, p0, lod) + g1x * textureLod(tex, p1, lod))) + + (g1(fuv.y) * (g0x * textureLod(tex, p2, lod) + g1x * textureLod(tex, p3, lod))); } - - -#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) texture2D_bicubic(m_tex,m_uv,m_lod) - +#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) #else - -#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) textureLod(m_tex,m_uv,float(m_lod)) - +#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod)) #endif +vec3 tonemap_filmic(vec3 color, float white) { + const float A = 0.15f; + const float B = 0.50f; + const float C = 0.10f; + const float D = 0.20f; + const float E = 0.02f; + const float F = 0.30f; + const float W = 11.2f; -vec3 tonemap_filmic(vec3 color,float white) { + vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; + float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F; - 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; + return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); +} - 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; +vec3 tonemap_aces(vec3 color, float white) { + const float A = 2.51f; + const float B = 0.03f; + const float C = 2.43f; + const float D = 0.59f; + const float E = 0.14f; - return coltn/whitetn; + vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E); + float white_tonemapped = (white * (A * white + B)) / (white * (C * white + D) + E); + return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); } -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, float white) { + return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here! } -vec3 tonemap_reindhart(vec3 color,float white) { - - return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color ); +vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1] + const vec3 a = vec3(0.055f); + return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); } -void main() { - - vec4 color = textureLod(source, uv_interp, 0.0); - -#ifdef USE_AUTO_EXPOSURE - - color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; +vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color +#ifdef USE_REINDHART_TONEMAPPER + return tonemap_reindhart(color, white); #endif - color*=exposure; +#ifdef USE_FILMIC_TONEMAPPER + return tonemap_filmic(color, white); +#endif -#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 +#ifdef USE_ACES_TONEMAPPER + return tonemap_aces(color, white); #endif -#if defined(USING_GLOW) - vec3 glow = vec3(0.0); + return clamp(color, vec3(0.0f), vec3(1.0f)); // no other seleced -> linear +} -#ifdef USE_GLOW_LEVEL1 +vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels + vec3 glow = vec3(0.0f); - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,1).rgb; +#ifdef USE_GLOW_LEVEL1 + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb; #endif #ifdef USE_GLOW_LEVEL2 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,2).rgb; + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb; #endif #ifdef USE_GLOW_LEVEL3 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,3).rgb; + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb; #endif #ifdef USE_GLOW_LEVEL4 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,4).rgb; + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb; #endif #ifdef USE_GLOW_LEVEL5 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,5).rgb; + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb; #endif #ifdef USE_GLOW_LEVEL6 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,6).rgb; + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb; #endif #ifdef USE_GLOW_LEVEL7 - glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,7).rgb; + glow += GLOW_TEXTURE_SAMPLE(tex, uv, 7).rgb; #endif + return glow; +} - glow *= glow_intensity; - +vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blending mode +#ifdef USE_GLOW_REPLACE + color = glow; #endif - -#ifdef USE_REINDHART_TONEMAPPER - - color.rgb = tonemap_reindhart(color.rgb,white); - -# if defined(USING_GLOW) - glow = tonemap_reindhart(glow,white); -# endif - +#ifdef USE_GLOW_SCREEN + color = max((color + glow) - (color * glow), vec3(0.0)); #endif -#ifdef USE_FILMIC_TONEMAPPER - - color.rgb = tonemap_filmic(color.rgb,white); - -# if defined(USING_GLOW) - glow = tonemap_filmic(glow,white); -# endif +#ifdef USE_GLOW_SOFTLIGHT + glow = glow * vec3(0.5f) + vec3(0.5f); + color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r))); + color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g))); + color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b))); #endif -#ifdef USE_ACES_TONEMAPPER - - color.rgb = tonemap_aces(color.rgb); - -# if defined(USING_GLOW) - glow = tonemap_aces(glow); -# endif - +#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) // no other selected -> additive + color += glow; #endif -#ifdef KEEP_3D_LINEAR - // leave color as is... -#else - //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))); -#endif + return color; +} -#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 +vec3 apply_bcs(vec3 color, vec3 bcs) { + color = mix(vec3(0.0f), color, bcs.x); + color = mix(vec3(0.5f), color, bcs.y); + color = mix(vec3(dot(vec3(1.0f), color) * 0.33333f), color, bcs.z); -//glow needs to be added in SRGB space (together with image space effects) + return color; +} - color.rgb = clamp(color.rgb,0.0,1.0); +vec3 apply_color_correction(vec3 color, sampler2D correction_tex) { + color.r = texture(correction_tex, vec2(color.r, 0.0f)).r; + color.g = texture(correction_tex, vec2(color.g, 0.0f)).g; + color.b = texture(correction_tex, vec2(color.b, 0.0f)).b; -#if defined(USING_GLOW) - glow = clamp(glow,0.0,1.0); -#endif + return color; +} -#ifdef USE_GLOW_REPLACE +void main() { + vec3 color = textureLod(source, uv_interp, 0.0f).rgb; - color.rgb = glow; + // Exposure +#ifdef USE_AUTO_EXPOSURE + color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey; #endif -#ifdef USE_GLOW_SCREEN + color *= exposure; - color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0)); + // Early Tonemap & SRGB Conversion + color = apply_tonemapping(color, white); + +#ifdef KEEP_3D_LINEAR + // leave color as is (-> don't convert to SRGB) +#else + color = linear_to_srgb(color); // regular linear -> SRGB conversion #endif -#ifdef USE_GLOW_SOFTLIGHT + // Glow - { +#ifdef USING_GLOW + vec3 glow = gather_glow(source_glow, uv_interp) * glow_intensity; - 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))); - } + // high dynamic range -> SRGB + glow = apply_tonemapping(glow, white); + glow = linear_to_srgb(glow); + color = apply_glow(color, glow); #endif -#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) - //additive - color.rgb+=glow; -#endif + // Additional effects #ifdef USE_BCS - - color.rgb = mix(vec3(0.0),color.rgb,bcs.x); - color.rgb = mix(vec3(0.5),color.rgb,bcs.y); - color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z); - + color = apply_bcs(color, bcs); #endif #ifdef USE_COLOR_CORRECTION - - color.r = texture(color_correction,vec2(color.r,0.0)).r; - color.g = texture(color_correction,vec2(color.g,0.0)).g; - color.b = texture(color_correction,vec2(color.b,0.0)).b; + color = apply_color_correction(color, color_correction); #endif - - frag_color=vec4(color.rgb,1.0); + frag_color = vec4(color, 1.0f); } |