From 1f86aea9424bdd3bebe9436d5ebac88a54b843ec Mon Sep 17 00:00:00 2001 From: hooke007 Date: Sat, 12 Nov 2022 16:38:44 +0000 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=B8=8E=E6=95=B4=E5=90=88?= =?UTF-8?q?=E4=B8=8A=E6=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- portable_config/scripts/playlistmanager.lua | 9 ++- portable_config/scripts/thumbfast.lua | 20 ++++- .../scripts/uosc/elements/Menu.lua | 29 ++++--- portable_config/scripts/uosc/lib/menus.lua | 80 +++++++++---------- portable_config/scripts/uosc/lib/text.lua | 2 +- portable_config/scripts/uosc/lib/utils.lua | 43 +++++----- portable_config/scripts/uosc/main.lua | 8 +- portable_config/shaders/nlmeans.glsl | 60 +++++++++----- portable_config/shaders/nlmeans_next.glsl | 60 +++++++++----- 9 files changed, 189 insertions(+), 122 deletions(-) diff --git a/portable_config/scripts/playlistmanager.lua b/portable_config/scripts/playlistmanager.lua index 72d6282b..90f3fd4d 100644 --- a/portable_config/scripts/playlistmanager.lua +++ b/portable_config/scripts/playlistmanager.lua @@ -1,6 +1,6 @@ --[[ SOURCE_ https://github.com/jonniek/mpv-playlistmanager/blob/master/playlistmanager.lua -COMMIT_ 76626ee6aaa79e08ac937fa6306b4c59f1cd6ee5 +COMMIT_ 1a9d250a7d7c7d49a8d0aaa6c4261a50ab74773c 高级播放列表,用于替换内置的过于简洁的列表 自定义快捷键方案示例,在 input.conf 中另起一行: @@ -38,7 +38,7 @@ local settings = { filename_replace = "", ---[=====[ START OF SAMPLE REPLACE, to use remove start and end line +--[=====[ START OF SAMPLE REPLACE - Remove this line to use it --Sample replace: replaces underscore to space on all files --for mp4 and webm; remove extension, remove brackets and surrounding whitespace, change dot between alphanumeric to space filename_replace = [[ @@ -266,8 +266,9 @@ update_opts({filename_replace = true, loadfiles_filetypes = true}) function on_loaded() filename = mp.get_property("filename") path = mp.get_property('path') - if utils.readdir(path, "dirs") then - -- a directory has been loaded, let's not do anything as mpv will expand it into files + local ext = filename:match("%.(.+)$") + if not ext or not filetype_lookup[ext:lower()] then + -- a directory or playlist has been loaded, let's not do anything as mpv will expand it into files return end --if not a url then join path with working directory diff --git a/portable_config/scripts/thumbfast.lua b/portable_config/scripts/thumbfast.lua index 3a426543..e0dd243b 100644 --- a/portable_config/scripts/thumbfast.lua +++ b/portable_config/scripts/thumbfast.lua @@ -1,6 +1,6 @@ --[[ SOURCE_ https://github.com/po5/thumbfast/blob/master/thumbfast.lua -COMMIT_ 38dc494c68534cefff0cf6a207004dc9d609c87c +COMMIT_ a145b37dc296837a4e48dff68beeeefc674c9bb3 适配多个OSC类脚本的新缩略图引擎 ]]-- @@ -254,6 +254,8 @@ local function calc_dimensions() end end +local info_timer = nil + local function info(w, h) local display_w, display_h = w, h @@ -261,14 +263,21 @@ local function info(w, h) local image = mp.get_property_native("current-tracks/video/image", true) local albumart = image and mp.get_property_native("current-tracks/video/albumart", false) local short_video = mp.get_property_native("duration", 0) <= options.min_duration - disabled = not (w and h) or + disabled = (w or 0) == 0 or (h or 0) == 0 or has_vid == 0 or (network and not options.network) or (albumart and not options.audio) or (image and not albumart) or (short_video and options.min_duration > 0) - local json, err = mp.utils.format_json({width=display_w, height=display_h, disabled=disabled, socket=options.socket, tnpath=options.tnpath, overlay_id=options.overlay_id}) + if info_timer then + info_timer:kill() + info_timer = nil + elseif has_vid == 0 or not disabled then + info_timer = mp.add_timeout(0.05, function() info(w, h) end) + end + + local json, err = mp.utils.format_json({width=display_w, height=display_h, disabled=disabled, available=true, socket=options.socket, tnpath=options.tnpath, overlay_id=options.overlay_id}) mp.commandv("script-message", "thumbfast-info", json) end @@ -574,7 +583,12 @@ end local function file_load() clear() real_w, real_h = nil, nil + last_real_w, last_real_h = nil, nil last_seek_time = nil + if info_timer then + info_timer:kill() + info_timer = nil + end calc_dimensions() info(effective_w, effective_h) diff --git a/portable_config/scripts/uosc/elements/Menu.lua b/portable_config/scripts/uosc/elements/Menu.lua index f57035be..fba0d7b3 100644 --- a/portable_config/scripts/uosc/elements/Menu.lua +++ b/portable_config/scripts/uosc/elements/Menu.lua @@ -329,10 +329,13 @@ end ---@param index? integer ---@param menu? MenuStack -function Menu:scroll_to_index(index, menu) +---@param immediate? boolean +function Menu:scroll_to_index(index, menu, immediate) menu = menu or self.current if (index and index >= 1 and index <= #menu.items) then - self:scroll_to(round((self.scroll_step * (index - 1)) - ((menu.height - self.scroll_step) / 2)), menu) + local position = round((self.scroll_step * (index - 1)) - ((menu.height - self.scroll_step) / 2)) + if immediate then self:set_scroll_to(position, menu) + else self:scroll_to(position, menu) end end end @@ -348,7 +351,7 @@ end ---@param menu? MenuStack function Menu:select_value(value, menu) menu = menu or self.current - local index = itable_find(menu.items, function(_, item) return item.value == value end) + local index = itable_find(menu.items, function(item) return item.value == value end) self:select_index(index, 5) end @@ -369,7 +372,7 @@ end ---@param index? integer ---@param menu? MenuStack -function Menu:activate_unique_index(index, menu) +function Menu:activate_one_index(index, menu) self:deactivate_items(menu) self:activate_index(index, menu) end @@ -378,16 +381,16 @@ end ---@param menu? MenuStack function Menu:activate_value(value, menu) menu = menu or self.current - local index = itable_find(menu.items, function(_, item) return item.value == value end) + local index = itable_find(menu.items, function(item) return item.value == value end) self:activate_index(index, menu) end ---@param value? any ---@param menu? MenuStack -function Menu:activate_unique_value(value, menu) +function Menu:activate_one_value(value, menu) menu = menu or self.current - local index = itable_find(menu.items, function(_, item) return item.value == value end) - self:activate_unique_index(index, menu) + local index = itable_find(menu.items, function(item) return item.value == value end) + self:activate_one_index(index, menu) end ---@param id string @@ -417,7 +420,7 @@ end ---@param menu? MenuStack function Menu:delete_value(value, menu) menu = menu or self.current - local index = itable_find(menu.items, function(_, item) return item.value == value end) + local index = itable_find(menu.items, function(item) return item.value == value end) self:delete_index(index) end @@ -425,14 +428,14 @@ end function Menu:prev(menu) menu = menu or self.current menu.selected_index = math.max(menu.selected_index and menu.selected_index - 1 or #menu.items, 1) - self:scroll_to_index(menu.selected_index, menu) + self:scroll_to_index(menu.selected_index, menu, true) end ---@param menu? MenuStack function Menu:next(menu) menu = menu or self.current menu.selected_index = math.min(menu.selected_index and menu.selected_index + 1 or 1, #menu.items) - self:scroll_to_index(menu.selected_index, menu) + self:scroll_to_index(menu.selected_index, menu, true) end function Menu:back() @@ -579,8 +582,8 @@ function Menu:enable_key_bindings() self:add_key_binding('shift+enter', 'menu-select-alt5', self:create_key_action('open_selected_item_soft')) self:add_key_binding('shift+kp_enter', 'menu-select-alt6', self:create_key_action('open_selected_item_soft')) self:add_key_binding('esc', 'menu-close', self:create_key_action('close')) - self:add_key_binding('pgup', 'menu-page-up', self:create_key_action('on_pgup')) - self:add_key_binding('pgdwn', 'menu-page-down', self:create_key_action('on_pgdwn')) + self:add_key_binding('pgup', 'menu-page-up', self:create_key_action('on_pgup'), 'repeatable') + self:add_key_binding('pgdwn', 'menu-page-down', self:create_key_action('on_pgdwn'), 'repeatable') self:add_key_binding('home', 'menu-home', self:create_key_action('on_home')) self:add_key_binding('end', 'menu-end', self:create_key_action('on_end')) end diff --git a/portable_config/scripts/uosc/lib/menus.lua b/portable_config/scripts/uosc/lib/menus.lua index 942493a5..8efc0705 100644 --- a/portable_config/scripts/uosc/lib/menus.lua +++ b/portable_config/scripts/uosc/lib/menus.lua @@ -159,6 +159,7 @@ function open_file_navigation_menu(directory_path, handle_select, opts) local files, directories = read_directory(directory.path, opts.allowed_types) local is_root = not directory.dirname + local path_separator = path_separator(directory.path) if not files or not directories then return end @@ -171,77 +172,72 @@ function open_file_navigation_menu(directory_path, handle_select, opts) if is_root then if state.os == 'windows' then - items[#items + 1] = { - title = '..', hint = '驱动器列表', value = {is_drives = true, is_to_parent = true}, separator = true, - } + items[#items + 1] = {title = '..', hint = '驱动器列表', value = '{drives}', separator = true} end else - local serialized = serialize_path(directory.dirname) - serialized.is_directory = true - serialized.is_to_parent = true - items[#items + 1] = {title = '..', hint = '上级目录', value = serialized, separator = true} + items[#items + 1] = {title = '..', hint = '上级目录', value = directory.dirname, separator = true} end - local items_start_index = #items + 1 + local selected_index = #items + 1 - local path_separator = path_separator(directory.path) for _, dir in ipairs(directories) do - local serialized = serialize_path(utils.join_path(directory.path, dir)) - if serialized then - serialized.is_directory = true - items[#items + 1] = {title = serialized.basename, value = serialized, hint = path_separator} - end + items[#items + 1] = {title = dir, value = join_path(directory.path, dir), hint = path_separator} end for _, file in ipairs(files) do - local serialized = serialize_path(utils.join_path(directory.path, file)) - if serialized then - serialized.is_file = true - items[#items + 1] = {title = serialized.basename, value = serialized} - end + items[#items + 1] = {title = file, value = join_path(directory.path, file)} end for index, item in ipairs(items) do - if not item.value.is_to_parent then - if index == items_start_index then item.selected = true end - - if opts.active_path == item.value.path then - item.active = true - if not opts.selected_path then item.selected = true end - end - - if opts.selected_path == item.value.path then item.selected = true end + if not item.value.is_to_parent and opts.active_path == item.value then + item.active = true + if not opts.selected_path then selected_index = index end end + + if opts.selected_path == item.value then selected_index = index end end local menu_data = { type = opts.type, title = opts.title or directory.basename .. path_separator, items = items, - on_open = opts.on_open, on_close = opts.on_close, + selected_index = selected_index, } + local menu_options = {on_open = opts.on_open, on_close = opts.on_close} return Menu:open(menu_data, function(path) + local is_drives = path == '{drives}' + local is_to_parent = is_drives or #path < #directory_path local inheritable_options = { type = opts.type, title = opts.title, allowed_types = opts.allowed_types, active_path = opts.active_path, } - if path.is_drives then + if is_drives then open_drives_menu(function(drive_path) open_file_navigation_menu(drive_path, handle_select, inheritable_options) - end, {type = inheritable_options.type, title = inheritable_options.title, selected_path = directory.path}) + end, { + type = inheritable_options.type, title = inheritable_options.title, selected_path = directory.path, + on_open = opts.on_open, on_close = opts.on_close, + }) return end - if path.is_directory then + local info, error = utils.file_info(path) + + if not info then + msg.error('Can\'t retrieve path info for "' .. path .. '". Error: ' .. (error or '')) + return + end + + if info.is_dir then -- Preselect directory we are coming from - if path.is_to_parent then + if is_to_parent then inheritable_options.selected_path = directory.path end - open_file_navigation_menu(path.path, handle_select, inheritable_options) + open_file_navigation_menu(path, handle_select, inheritable_options) else - handle_select(path.path) + handle_select(path) end - end) + end, menu_options) end -- Opens a file navigation menu with Windows drives as items. @@ -255,7 +251,7 @@ function open_drives_menu(handle_select, opts) playback_only = false, args = {'wmic', 'logicaldisk', 'get', 'name', '/value'}, }) - local items = {} + local items, selected_index = {}, 1 if process.status == 0 then for _, value in ipairs(split(process.stdout, '\n')) do @@ -263,15 +259,17 @@ function open_drives_menu(handle_select, opts) if drive then local drive_path = normalize_path(drive) items[#items + 1] = { - title = drive, hint = '盘符', value = drive_path, - selected = opts.selected_path == drive_path, - active = opts.active_path == drive_path, + title = drive, hint = '盘符', value = drive_path, active = opts.active_path == drive_path, } + if opts.selected_path == drive_path then selected_index = #items end end end else msg.error(process.stderr) end - return Menu:open({type = opts.type, title = opts.title or '驱动器列表', items = items}, handle_select) + return Menu:open( + {type = opts.type, title = opts.title or '驱动器列表', items = items, selected_index = selected_index}, + handle_select + ) end diff --git a/portable_config/scripts/uosc/lib/text.lua b/portable_config/scripts/uosc/lib/text.lua index 307845d7..7c1cf4ec 100644 --- a/portable_config/scripts/uosc/lib/text.lua +++ b/portable_config/scripts/uosc/lib/text.lua @@ -324,7 +324,7 @@ function text_width(text, opts) if not text or text == '' then return 0 end ---@type boolean, boolean - local bold, italic = opts.bold or false, opts.italic or false + local bold, italic = opts.bold or options.font_bold, opts.italic or false if options.text_width_estimation then ---@type {[string|number]: {[1]: number, [2]: integer}} diff --git a/portable_config/scripts/uosc/lib/utils.lua b/portable_config/scripts/uosc/lib/utils.lua index 1156075f..52cf16d8 100644 --- a/portable_config/scripts/uosc/lib/utils.lua +++ b/portable_config/scripts/uosc/lib/utils.lua @@ -145,23 +145,26 @@ function opacity_to_alpha(opacity) return 255 - math.ceil(255 * opacity) end -do +path_separator = (function() local os_separator = state.os == 'windows' and '\\' or '/' -- Get appropriate path separator for the given path. ---@param path string ---@return string - function path_separator(path) + return function(path) return path:sub(1, 2) == '\\\\' and '\\' or os_separator end +end)() - -- Joins paths with the OS aware path separator or UNC separator. - ---@param p1 string - ---@param p2 string - ---@return string - function utils.join_path(p1, p2) - return p1 .. path_separator(p1) .. p2 - end +-- Joins paths with the OS aware path separator or UNC separator. +---@param p1 string +---@param p2 string +---@return string +function join_path(p1, p2) + local p1, separator = trim_trailing_separator(p1) + -- Prevents joining drive letters with a redundant separator (`C:\\foo`), + -- as `trim_trailing_separator()` doesn't trim separators from drive letters. + return p1:sub(#p1) == separator and p1 .. p2 or p1 .. separator.. p2 end -- Check if path is absolute. @@ -178,22 +181,22 @@ end ---@return string function ensure_absolute(path) if is_absolute(path) then return path end - return utils.join_path(state.cwd, path) + return join_path(state.cwd, path) end -- Remove trailing slashes/backslashes. ---@param path string ----@return string +---@return string path, string trimmed_separator_type function trim_trailing_separator(path) - path = trim_end(path, path_separator(path)) + local separator = path_separator(path) + path = trim_end(path, separator) if state.os == 'windows' then -- Drive letters on windows need trailing backslash - if path:sub(#path) == ':' then return path .. '\\' end - return path + if path:sub(#path) == ':' then path = path .. '\\' end else - if path == '' then return '/' end - return path + if path == '' then path = '/' end end + return path, separator end -- Ensures path is absolute, remove trailing slashes/backslashes. @@ -202,8 +205,8 @@ end ---@return string function normalize_path_lite(path) if not path or is_protocol(path) then return path end - path = ensure_absolute(path) - return trim_trailing_separator(path) + path = trim_trailing_separator(ensure_absolute(path)) + return path end -- Ensures path is absolute, remove trailing slashes/backslashes, normalization of path separators and deduplication. @@ -286,7 +289,7 @@ function read_directory(path, allowed_types) for _, item in ipairs(items) do if item ~= '.' and item ~= '..' then - local info = utils.file_info(utils.join_path(path, item)) + local info = utils.file_info(join_path(path, item)) if info then if info.is_file then if not allowed_types or has_any_extension(item, allowed_types) then @@ -313,7 +316,7 @@ function get_adjacent_files(file_path, allowed_types) local current_file_index local paths = {} for index, file in ipairs(files) do - paths[#paths + 1] = utils.join_path(current_file.dirname, file) + paths[#paths + 1] = join_path(current_file.dirname, file) if current_file.basename == file then current_file_index = index end end if not current_file_index then return end diff --git a/portable_config/scripts/uosc/main.lua b/portable_config/scripts/uosc/main.lua index e9c7fb2e..0dfa5639 100644 --- a/portable_config/scripts/uosc/main.lua +++ b/portable_config/scripts/uosc/main.lua @@ -1,6 +1,6 @@ --[[ SOURCE_ https://github.com/tomasklaen/uosc/tree/main/scripts -COMMIT_ 64feeb04b78d7132e02242cea5d3bd179003199a +COMMIT_ 107e758144448ca66554f7f8902f4cbf58bfb566 极简主义设计驱动的多功能界面脚本群组,兼容 thumbfast 新缩略图引擎 ]]-- @@ -489,7 +489,7 @@ function load_file_index_in_current_directory(index) if index < 0 then index = #files + index + 1 end if files[index] then - mp.commandv('loadfile', utils.join_path(serialized.dirname, files[index])) + mp.commandv('loadfile', join_path(serialized.dirname, files[index])) end end end @@ -907,7 +907,7 @@ mp.add_key_binding(nil, 'open-file', function() -- Update active file in directory navigation menu local function handle_file_loaded() if Menu:is_open('open-file') then - Elements.menu:activate_value(normalize_path(mp.get_property_native('path'))) + Elements.menu:activate_one_value(normalize_path(mp.get_property_native('path'))) end end @@ -1008,7 +1008,7 @@ mp.add_key_binding(nil, 'audio-device', create_self_updating_menu_opener({ })) mp.add_key_binding(nil, 'open-config-directory', function() local config_path = mp.command_native({'expand-path', '~~/mpv.conf'}) - local config = serialize_path(config_path) + local config = serialize_path(normalize_path(config_path)) if config then local args diff --git a/portable_config/shaders/nlmeans.glsl b/portable_config/shaders/nlmeans.glsl index d14dc181..bbbba2e0 100644 --- a/portable_config/shaders/nlmeans.glsl +++ b/portable_config/shaders/nlmeans.glsl @@ -99,7 +99,7 @@ vec4 hook() * - LUMA=P=1 * - CHROMA=P=1 * - Sharp: - * - LUMA=S=4:AS=1:PS=3:EP=0 + * - LUMA=S=9:AS=1:EP=0 * * It is recommended to make multiple copies of this shader with settings * tweaked for different types of content, and then dispatch the appropriate @@ -142,7 +142,7 @@ vec4 hook() #ifdef LUMA_raw #define AS 0 #define ASF 1.0 -#define ASP 0.5 +#define ASP 0.25 #else #define AS 0 #define ASF 0.0 @@ -187,6 +187,7 @@ vec4 hook() * 3: diamond (symmetrical) * 4: triangle (pointing upward, center pixel is in the bottom-middle) * 5: truncated triangle (last row halved) + * 6: offset square (accepts even and odd sizes) */ #ifdef LUMA_raw #define RS 3 @@ -280,7 +281,7 @@ vec4 hook() * factor is set to 3. */ #ifdef LUMA_raw -#define RF 1 +#define RF 0 #else #define RF 1 #endif @@ -347,55 +348,70 @@ const int hr = R/2; #define S_LINE_A(hz,Z) Z #define S_SQUARE(z,hz) for (z.x = -hz; z.x <= hz; z.x++) for (z.y = -hz; z.y <= hz; z.y++) +#define S_SQUARE_OFF(z,hz) for (z.x = 0; z.x <= hz; z.x++) for (z.y = 0; z.y <= hz; z.y++) #define S_SQUARE_A(hz,Z) (Z*Z) // research shapes #define T1 (T+1) +#define FOR_FRAME for (r.z = 0; r.z < T1; r.z++) #if R == 0 || R == 1 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_1X1(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_1X1(r,hr) const int r_area = S_1X1_A(hr,R)*T1; +#elif RS == 6 +#define FOR_RESEARCH(r) FOR_FRAME S_SQUARE_OFF(r,hr) +const int r_area = S_SQUARE_A(hr,R)*T1; #elif RS == 5 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_TRUNC_TRIANGLE(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_TRUNC_TRIANGLE(r,hr) const int r_area = S_TRIANGLE_A(hr,hr)*T1; #elif RS == 4 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_TRIANGLE(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_TRIANGLE(r,hr) const int r_area = S_TRIANGLE_A(hr,R)*T1; #elif RS == 3 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_DIAMOND(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_DIAMOND(r,hr) const int r_area = S_DIAMOND_A(hr,R)*T1; #elif RS == 2 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_VERTICAL(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_VERTICAL(r,hr) const int r_area = S_LINE_A(hr,R)*T1; #elif RS == 1 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_HORIZONTAL(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_HORIZONTAL(r,hr) const int r_area = S_LINE_A(hr,R)*T1; -#else -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_SQUARE(r,hr) +#elif RS == 0 && R == 2 // interpolated 2x2 +#define FOR_RESEARCH(r) FOR_FRAME S_SQUARE(r,0.5) +const int r_area = 4*T1; +#elif RS == 0 +#define FOR_RESEARCH(r) FOR_FRAME S_SQUARE(r,hr) const int r_area = S_SQUARE_A(hr,R)*T1; #endif // patch shapes #define RI1 (RI+1) +#define FOR_ROTATION for (float ri = 0; ri < 360; ri+=360.0/RI1) #if P == 0 || P == 1 #define FOR_PATCH(p) S_1X1(p,hp) for (float ri = 0; ri <= 0; ri++) const int p_area = S_1X1_A(hp,P)*RI1; +#elif PS == 6 +#define FOR_PATCH(p) S_SQUARE_OFF(p,hp) FOR_ROTATION +const int p_area = S_SQUARE_A(hp,P)*RI1; #elif PS == 5 -#define FOR_PATCH(p) S_TRUNC_TRIANGLE(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_TRUNC_TRIANGLE(p,hp) FOR_ROTATION const int p_area = S_TRIANGLE_A(hp,hp)*RI1; #elif PS == 4 -#define FOR_PATCH(p) S_TRIANGLE(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_TRIANGLE(p,hp) FOR_ROTATION const int p_area = S_TRIANGLE_A(hp,P)*RI1; #elif PS == 3 -#define FOR_PATCH(p) S_DIAMOND(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_DIAMOND(p,hp) FOR_ROTATION const int p_area = S_DIAMOND_A(hp,P)*RI1; #elif PS == 2 -#define FOR_PATCH(p) S_VERTICAL(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_VERTICAL(p,hp) FOR_ROTATION const int p_area = S_LINE_A(hp,P)*RI1; #elif PS == 1 -#define FOR_PATCH(p) S_HORIZONTAL(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_HORIZONTAL(p,hp) FOR_ROTATION const int p_area = S_LINE_A(hp,P)*RI1; -#else -#define FOR_PATCH(p) S_SQUARE(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#elif PS == 0 && P == 2 // interpolated 2x2 +#define FOR_PATCH(p) S_SQUARE(p,0.5) FOR_ROTATION +const int p_area = 4*RI1; +#elif PS == 0 +#define FOR_PATCH(p) S_SQUARE(p,hp) FOR_ROTATION const int p_area = S_SQUARE_A(hp,P)*RI1; #endif @@ -454,8 +470,16 @@ vec4 hook() const float pdiff_scale = 1.0/(h*h); vec4 pdiff_sq = vec4(0); +#if defined(LUMA_gather) && P == 3 && PS == 4 && RF == 0 && RI == 0 && T == 0 + const ivec2 offsets[4] = {ivec2(0,-1), ivec2(-1,0), ivec2(0,0), ivec2(1,0)}; + #define gather(pos) (LUMA_mul * vec4(textureGatherOffsets(LUMA_raw, pos, offsets))) + pdiff_sq.x = dot(pow(gather(HOOKED_pos) - gather(HOOKED_pos+r.xy*HOOKED_pt), vec4(2)), vec4(1)); +#elif defined(LUMA_gather) && P == 2 && PS == 6 && RF == 0 && RI == 0 && T == 0 + pdiff_sq.x = dot(pow(LUMA_gather(HOOKED_pos, 0) - LUMA_gather(HOOKED_pos+r.xy*HOOKED_pt, 0), vec4(2)), vec4(1)); +#else FOR_PATCH(p) pdiff_sq += pow(HOOKED_texOff(p) - load(ROT(p)+r), vec4(2)); +#endif vec4 weight = exp(-pdiff_sq * p_scale * pdiff_scale); weight *= exp(-pow(length(r*SD) * SS, 2)); diff --git a/portable_config/shaders/nlmeans_next.glsl b/portable_config/shaders/nlmeans_next.glsl index e45c3f39..85e7e642 100644 --- a/portable_config/shaders/nlmeans_next.glsl +++ b/portable_config/shaders/nlmeans_next.glsl @@ -109,7 +109,7 @@ vec4 hook() * - LUMA=P=1 * - CHROMA=P=1 * - Sharp: - * - LUMA=S=4:AS=1:PS=3:EP=0 + * - LUMA=S=9:AS=1:EP=0 * * It is recommended to make multiple copies of this shader with settings * tweaked for different types of content, and then dispatch the appropriate @@ -152,7 +152,7 @@ vec4 hook() #ifdef LUMA_raw #define AS 0 #define ASF 1.0 -#define ASP 0.5 +#define ASP 0.25 #else #define AS 0 #define ASF 0.0 @@ -197,6 +197,7 @@ vec4 hook() * 3: diamond (symmetrical) * 4: triangle (pointing upward, center pixel is in the bottom-middle) * 5: truncated triangle (last row halved) + * 6: offset square (accepts even and odd sizes) */ #ifdef LUMA_raw #define RS 3 @@ -290,7 +291,7 @@ vec4 hook() * factor is set to 3. */ #ifdef LUMA_raw -#define RF 1 +#define RF 0 #else #define RF 1 #endif @@ -357,55 +358,70 @@ const int hr = R/2; #define S_LINE_A(hz,Z) Z #define S_SQUARE(z,hz) for (z.x = -hz; z.x <= hz; z.x++) for (z.y = -hz; z.y <= hz; z.y++) +#define S_SQUARE_OFF(z,hz) for (z.x = 0; z.x <= hz; z.x++) for (z.y = 0; z.y <= hz; z.y++) #define S_SQUARE_A(hz,Z) (Z*Z) // research shapes #define T1 (T+1) +#define FOR_FRAME for (r.z = 0; r.z < T1; r.z++) #if R == 0 || R == 1 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_1X1(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_1X1(r,hr) const int r_area = S_1X1_A(hr,R)*T1; +#elif RS == 6 +#define FOR_RESEARCH(r) FOR_FRAME S_SQUARE_OFF(r,hr) +const int r_area = S_SQUARE_A(hr,R)*T1; #elif RS == 5 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_TRUNC_TRIANGLE(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_TRUNC_TRIANGLE(r,hr) const int r_area = S_TRIANGLE_A(hr,hr)*T1; #elif RS == 4 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_TRIANGLE(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_TRIANGLE(r,hr) const int r_area = S_TRIANGLE_A(hr,R)*T1; #elif RS == 3 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_DIAMOND(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_DIAMOND(r,hr) const int r_area = S_DIAMOND_A(hr,R)*T1; #elif RS == 2 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_VERTICAL(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_VERTICAL(r,hr) const int r_area = S_LINE_A(hr,R)*T1; #elif RS == 1 -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_HORIZONTAL(r,hr) +#define FOR_RESEARCH(r) FOR_FRAME S_HORIZONTAL(r,hr) const int r_area = S_LINE_A(hr,R)*T1; -#else -#define FOR_RESEARCH(r) for (r.z = 0; r.z < T1; r.z++) S_SQUARE(r,hr) +#elif RS == 0 && R == 2 // interpolated 2x2 +#define FOR_RESEARCH(r) FOR_FRAME S_SQUARE(r,0.5) +const int r_area = 4*T1; +#elif RS == 0 +#define FOR_RESEARCH(r) FOR_FRAME S_SQUARE(r,hr) const int r_area = S_SQUARE_A(hr,R)*T1; #endif // patch shapes #define RI1 (RI+1) +#define FOR_ROTATION for (float ri = 0; ri < 360; ri+=360.0/RI1) #if P == 0 || P == 1 #define FOR_PATCH(p) S_1X1(p,hp) for (float ri = 0; ri <= 0; ri++) const int p_area = S_1X1_A(hp,P)*RI1; +#elif PS == 6 +#define FOR_PATCH(p) S_SQUARE_OFF(p,hp) FOR_ROTATION +const int p_area = S_SQUARE_A(hp,P)*RI1; #elif PS == 5 -#define FOR_PATCH(p) S_TRUNC_TRIANGLE(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_TRUNC_TRIANGLE(p,hp) FOR_ROTATION const int p_area = S_TRIANGLE_A(hp,hp)*RI1; #elif PS == 4 -#define FOR_PATCH(p) S_TRIANGLE(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_TRIANGLE(p,hp) FOR_ROTATION const int p_area = S_TRIANGLE_A(hp,P)*RI1; #elif PS == 3 -#define FOR_PATCH(p) S_DIAMOND(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_DIAMOND(p,hp) FOR_ROTATION const int p_area = S_DIAMOND_A(hp,P)*RI1; #elif PS == 2 -#define FOR_PATCH(p) S_VERTICAL(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_VERTICAL(p,hp) FOR_ROTATION const int p_area = S_LINE_A(hp,P)*RI1; #elif PS == 1 -#define FOR_PATCH(p) S_HORIZONTAL(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#define FOR_PATCH(p) S_HORIZONTAL(p,hp) FOR_ROTATION const int p_area = S_LINE_A(hp,P)*RI1; -#else -#define FOR_PATCH(p) S_SQUARE(p,hp) for (float ri = 0; ri < 360; ri+=360/RI1) +#elif PS == 0 && P == 2 // interpolated 2x2 +#define FOR_PATCH(p) S_SQUARE(p,0.5) FOR_ROTATION +const int p_area = 4*RI1; +#elif PS == 0 +#define FOR_PATCH(p) S_SQUARE(p,hp) FOR_ROTATION const int p_area = S_SQUARE_A(hp,P)*RI1; #endif @@ -464,8 +480,16 @@ vec4 hook() const float pdiff_scale = 1.0/(h*h); vec4 pdiff_sq = vec4(0); +#if defined(LUMA_gather) && P == 3 && PS == 4 && RF == 0 && RI == 0 && T == 0 + const ivec2 offsets[4] = {ivec2(0,-1), ivec2(-1,0), ivec2(0,0), ivec2(1,0)}; + #define gather(pos) (LUMA_mul * vec4(textureGatherOffsets(LUMA_raw, pos, offsets))) + pdiff_sq.x = dot(pow(gather(HOOKED_pos) - gather(HOOKED_pos+r.xy*HOOKED_pt), vec4(2)), vec4(1)); +#elif defined(LUMA_gather) && P == 2 && PS == 6 && RF == 0 && RI == 0 && T == 0 + pdiff_sq.x = dot(pow(LUMA_gather(HOOKED_pos, 0) - LUMA_gather(HOOKED_pos+r.xy*HOOKED_pt, 0), vec4(2)), vec4(1)); +#else FOR_PATCH(p) pdiff_sq += pow(HOOKED_texOff(p) - load(ROT(p)+r), vec4(2)); +#endif vec4 weight = exp(-pdiff_sq * p_scale * pdiff_scale); weight *= exp(-pow(length(r*SD) * SS, 2));