发布1.0.0版本

This commit is contained in:
evan.liu 2026-09-18 20:54:52 +08:00
parent d0074858bf
commit e992ec0386
2275 changed files with 213818 additions and 816 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
/deploy/
/build_log.txt
/configure_log.txt
/icon_preview.png
obs-studio/build-aux

View File

@ -0,0 +1,397 @@
-- HUD Overlay Color Script for OBS (separate Create / Update buttons)
-- Green-screen style keying: keeps only the green symbols and removes all other colors (including black) + custom symbol color
-- Principle: greenness = G - max(R, B); green symbols are positive, black/gray/white backgrounds are ~0
-- Requires: obs-shaderfilter plugin (installed)
-- Install: OBS -> Tools -> Scripts -> + -> select this file -> pick a color
-- "Create Scene" : builds the scene from scratch (deletes and recreates both media sources)
-- "Update Scene" : updates the existing scene in place (video paths, color, keying parameters)
obs = obslua
local SETTING_FRONT_PATH = "front_path"
local SETTING_BACK_PATH = "back_path"
local SETTING_COLOR = "hud_color" -- preset color index
local SETTING_KEY_LOW = "key_low"
local SETTING_KEY_HIGH = "key_high"
local SETTING_OPACITY = "opacity"
local SCENE_NAME = "HUD Overlay Color"
local FRONT_NAME = "HUD - Front Color"
local BACK_NAME = "Center IG - Back Color"
local FILTER_NAME = "HUD Colorize"
-- Preset colors (ordered from strongest to weakest contrast against a teal background)
local COLOR_PRESETS = {
{ name = "Red (recommended, complementary to teal)", r = 1.0, g = 0.0, b = 0.0 },
{ name = "Magenta", r = 1.0, g = 0.0, b = 1.0 },
{ name = "Orange", r = 1.0, g = 0.5, b = 0.0 },
{ name = "Yellow", r = 1.0, g = 1.0, b = 0.0 },
{ name = "White", r = 1.0, g = 1.0, b = 1.0 },
{ name = "Green (original color)", r = 0.0, g = 1.0, b = 0.0 },
{ name = "Bright green (neon green)", r = 0.25, g = 1.0, b = 0.1 },
{ name = "Black (strong contrast on light backgrounds)", r = 0.0, g = 0.0, b = 0.0 },
}
local front_path = ""
local back_path = ""
local color_index = 1
local key_low = 0.02
local key_high = 0.20
local opacity = 1.0
local fit_retries = 0
-- Green-preserving keying + recolor shader:
-- greenness = G - max(R, B); only greenish pixels are positive
-- alpha = smoothstep(key_low, key_high, greenness); soft edges preserve the anti-aliased transition
-- Color is forced to the specified HUD color (premultiplied output)
local SHADER_TEXT = [==[
uniform float key_low <
string label = "Key low";
string widget_type = "slider";
float minimum = 0.0;
float maximum = 0.5;
float step = 0.001;
> = 0.02;
uniform float key_high <
string label = "Key high";
string widget_type = "slider";
float minimum = 0.01;
float maximum = 1.0;
float step = 0.005;
> = 0.20;
uniform float hud_r <
string label = "HUD color R";
string widget_type = "slider";
float minimum = 0.0;
float maximum = 1.0;
float step = 0.01;
> = 1.0;
uniform float hud_g <
string label = "HUD color G";
string widget_type = "slider";
float minimum = 0.0;
float maximum = 1.0;
float step = 0.01;
> = 0.0;
uniform float hud_b <
string label = "HUD color B";
string widget_type = "slider";
float minimum = 0.0;
float maximum = 1.0;
float step = 0.01;
> = 0.0;
uniform float opacity <
string label = "Opacity";
string widget_type = "slider";
float minimum = 0.0;
float maximum = 1.0;
float step = 0.01;
> = 1.0;
float4 mainImage(VertData v_in) : TARGET
{
float4 px = image.Sample(textureSampler, v_in.uv);
// The OBS filter chain input is premultiplied; un-premultiply first (media sources have alpha=1, so usually no effect)
px.rgb *= (px.a > 0.0) ? (1.0 / px.a) : 0.0;
// Greenness: only green symbols are positive; black/gray/white backgrounds are ~0
float greenness = px.g - max(px.r, px.b);
// Soft-threshold keying: fully transparent below key_low, fully opaque above key_high
float a = smoothstep(key_low, max(key_high, key_low + 0.001), greenness) * opacity;
// Premultiplied output: specified color x alpha
return float4(float3(hud_r, hud_g, hud_b) * a, a);
}
]==]
------------------------------------------------------------
-- Utility functions
------------------------------------------------------------
local function remove_source_by_name(name)
local s = obs.obs_get_source_by_name(name)
if s ~= nil then
obs.obs_source_remove(s)
obs.obs_source_release(s)
end
end
local function create_media_source(name, path)
local s = obs.obs_data_create()
obs.obs_data_set_string(s, "local_file", path)
obs.obs_data_set_bool(s, "is_local_file", true)
obs.obs_data_set_bool(s, "looping", true)
obs.obs_data_set_bool(s, "restart_on_activate", true)
obs.obs_data_set_bool(s, "close_when_inactive", false)
local src = obs.obs_source_create("ffmpeg_source", name, s, nil)
obs.obs_data_release(s)
return src
end
-- Point an existing media source at a new file without recreating it
local function update_media_source_path(src, path)
local s = obs.obs_source_get_settings(src)
obs.obs_data_set_string(s, "local_file", path)
obs.obs_source_update(src, s)
obs.obs_data_release(s)
end
local function apply_key_filter(src)
local old = obs.obs_source_get_filter_by_name(src, FILTER_NAME)
if old ~= nil then
obs.obs_source_filter_remove(src, old)
obs.obs_source_release(old)
end
local preset = COLOR_PRESETS[color_index] or COLOR_PRESETS[1]
local fs = obs.obs_data_create()
obs.obs_data_set_bool(fs, "from_file", false)
obs.obs_data_set_string(fs, "shader_text", SHADER_TEXT)
obs.obs_data_set_double(fs, "key_low", key_low)
obs.obs_data_set_double(fs, "key_high", key_high)
obs.obs_data_set_double(fs, "hud_r", preset.r)
obs.obs_data_set_double(fs, "hud_g", preset.g)
obs.obs_data_set_double(fs, "hud_b", preset.b)
obs.obs_data_set_double(fs, "opacity", opacity)
-- First check whether the obs-shaderfilter plugin is loaded
if obs.obs_source_get_display_name("shader_filter") == nil then
obs.obs_data_release(fs)
obs.script_log(obs.LOG_WARNING,
"HUD Overlay Color: obs-shaderfilter plugin not detected; keying was not applied. Please fully quit OBS (including the system tray) and restart it.")
return
end
local f = obs.obs_source_create("shader_filter", FILTER_NAME, fs, nil)
obs.obs_data_release(fs)
if f ~= nil then
obs.obs_source_filter_add(src, f)
obs.obs_source_release(f)
end
end
local function fit_items_to_canvas()
local vi = obs.obs_video_info()
if obs.obs_get_video_info(vi) == false then
return false
end
local cw, ch = vi.base_width, vi.base_height
local scene_src = obs.obs_get_source_by_name(SCENE_NAME)
if scene_src == nil then
return false
end
local scene = obs.obs_scene_from_source(scene_src)
local items = obs.obs_scene_enum_items(scene)
local all_ready = true
for _, item in ipairs(items) do
local s = obs.obs_sceneitem_get_source(item)
local w = obs.obs_source_get_width(s)
local h = obs.obs_source_get_height(s)
if w > 0 and h > 0 then
local scale = math.min(cw / w, ch / h)
local sc = obs.vec2()
sc.x = scale
sc.y = scale
obs.obs_sceneitem_set_scale(item, sc)
local pos = obs.vec2()
pos.x = (cw - w * scale) / 2
pos.y = (ch - h * scale) / 2
obs.obs_sceneitem_set_pos(item, pos)
-- Use Lanczos when upscaling line-art footage; sharper than the default bilinear
if obs.obs_sceneitem_set_scale_filter ~= nil then
obs.obs_sceneitem_set_scale_filter(item, obs.OBS_SCALE_LANCZOS or 4)
end
else
all_ready = false
end
end
obs.sceneitem_list_release(items)
obs.obs_source_release(scene_src)
return all_ready
end
local function fit_retry()
fit_retries = fit_retries - 1
if fit_items_to_canvas() or fit_retries <= 0 then
obs.timer_remove(fit_retry)
end
end
local function schedule_fit()
fit_retries = 10
obs.timer_remove(fit_retry)
obs.timer_add(fit_retry, 500)
end
------------------------------------------------------------
-- Create scene (from scratch)
------------------------------------------------------------
local function create_scene()
if front_path == "" or back_path == "" then
obs.script_log(obs.LOG_WARNING, "HUD Overlay Color: please set the foreground and background video paths first")
return
end
local scene = nil
local scene_src = obs.obs_get_source_by_name(SCENE_NAME)
if scene_src ~= nil then
scene = obs.obs_scene_from_source(scene_src)
else
scene = obs.obs_scene_create(SCENE_NAME)
scene_src = obs.obs_scene_get_source(scene)
end
remove_source_by_name(FRONT_NAME)
remove_source_by_name(BACK_NAME)
local back = create_media_source(BACK_NAME, back_path)
obs.obs_scene_add(scene, back)
local front = create_media_source(FRONT_NAME, front_path)
apply_key_filter(front)
obs.obs_scene_add(scene, front)
obs.obs_source_release(back)
obs.obs_source_release(front)
obs.obs_frontend_set_current_scene(scene_src)
obs.obs_source_release(scene_src)
schedule_fit()
obs.script_log(obs.LOG_INFO, "HUD Overlay Color: scene created, symbol color = " ..
(COLOR_PRESETS[color_index] or COLOR_PRESETS[1]).name)
end
------------------------------------------------------------
-- Update scene (in place, without recreating sources)
------------------------------------------------------------
local function update_scene()
if front_path == "" or back_path == "" then
obs.script_log(obs.LOG_WARNING, "HUD Overlay Color: please set the foreground and background video paths first")
return
end
local scene_src = obs.obs_get_source_by_name(SCENE_NAME)
if scene_src == nil then
obs.script_log(obs.LOG_WARNING,
"HUD Overlay Color: scene \"" .. SCENE_NAME .. "\" does not exist yet; please use \"Create Scene\" first")
return
end
local back = obs.obs_get_source_by_name(BACK_NAME)
local front = obs.obs_get_source_by_name(FRONT_NAME)
if back == nil or front == nil then
if back ~= nil then obs.obs_source_release(back) end
if front ~= nil then obs.obs_source_release(front) end
obs.obs_source_release(scene_src)
obs.script_log(obs.LOG_WARNING,
"HUD Overlay Color: media sources are missing; please use \"Create Scene\" to rebuild the scene")
return
end
-- Update video files in place
update_media_source_path(back, back_path)
update_media_source_path(front, front_path)
-- Re-apply the keying filter with the current color / keying parameters
apply_key_filter(front)
obs.obs_source_release(back)
obs.obs_source_release(front)
obs.obs_frontend_set_current_scene(scene_src)
obs.obs_source_release(scene_src)
schedule_fit()
obs.script_log(obs.LOG_INFO, "HUD Overlay Color: scene updated, symbol color = " ..
(COLOR_PRESETS[color_index] or COLOR_PRESETS[1]).name)
end
local function on_create_clicked(props, p)
create_scene()
return true
end
local function on_update_clicked(props, p)
update_scene()
return true
end
------------------------------------------------------------
-- Script UI and settings
------------------------------------------------------------
function script_description()
return "Green-screen style keying: keeps only the green symbols and removes all other colors (including black).\n" ..
"Principle: greenness = G - max(R, B), which is less likely to pick up background noise than the old 'use the G channel as alpha' approach.\n" ..
"\"Create Scene\": builds the scene from scratch (deletes and recreates both media sources).\n" ..
"\"Update Scene\": updates the existing scene in place (video paths, symbol color, keying parameters).\n" ..
"The filter panel also has HUD color R/G/B sliders for fine-tuning to any color."
end
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_path(props, SETTING_FRONT_PATH,
"Foreground video (HUD, green symbols)", obs.OBS_PATH_FILE,
"Video files (*.avi *.mp4 *.mov *.mkv *.webm);;All files (*.*)", "")
obs.obs_properties_add_path(props, SETTING_BACK_PATH,
"Background video (bottom layer)", obs.OBS_PATH_FILE,
"Video files (*.avi *.mp4 *.mov *.mkv *.webm);;All files (*.*)", "")
local clist = obs.obs_properties_add_list(props, SETTING_COLOR,
"Symbol color", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_INT)
for i, c in ipairs(COLOR_PRESETS) do
obs.obs_property_list_add_int(clist, c.name, i)
end
obs.obs_properties_add_float_slider(props, SETTING_KEY_LOW,
"Green lower bound (increase if noise/color artifacts remain)", 0.0, 0.5, 0.001)
obs.obs_properties_add_float_slider(props, SETTING_KEY_HIGH,
"Green upper bound (decrease if thin lines fade or edges get too soft)", 0.01, 1.0, 0.005)
obs.obs_properties_add_float_slider(props, SETTING_OPACITY,
"Overall opacity", 0.0, 1.0, 0.01)
obs.obs_properties_add_button(props, "create_btn", "Create Scene", on_create_clicked)
obs.obs_properties_add_button(props, "update_btn", "Update Scene", on_update_clicked)
return props
end
function script_defaults(settings)
obs.obs_data_set_default_string(settings, SETTING_FRONT_PATH,
"D:\\Test Pictures + Video\\HUD - Front Video.avi")
obs.obs_data_set_default_string(settings, SETTING_BACK_PATH,
"D:\\Test Pictures + Video\\Center IG - Back Videos.avi")
obs.obs_data_set_default_int(settings, SETTING_COLOR, 1)
obs.obs_data_set_default_double(settings, SETTING_KEY_LOW, 0.02)
obs.obs_data_set_default_double(settings, SETTING_KEY_HIGH, 0.20)
obs.obs_data_set_default_double(settings, SETTING_OPACITY, 1.0)
end
function script_update(settings)
front_path = obs.obs_data_get_string(settings, SETTING_FRONT_PATH)
back_path = obs.obs_data_get_string(settings, SETTING_BACK_PATH)
color_index = obs.obs_data_get_int(settings, SETTING_COLOR)
key_low = obs.obs_data_get_double(settings, SETTING_KEY_LOW)
key_high = obs.obs_data_get_double(settings, SETTING_KEY_HIGH)
opacity = obs.obs_data_get_double(settings, SETTING_OPACITY)
end

Binary file not shown.

BIN
deploy/bin/64bit/Qt6Gui.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
deploy/bin/64bit/Qt6Svg.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
deploy/bin/64bit/Qt6Xml.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
deploy/bin/64bit/lua51.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
deploy/bin/64bit/obs.dll Normal file

Binary file not shown.

BIN
deploy/bin/64bit/obs64.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
deploy/bin/64bit/srt.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
deploy/bin/64bit/zlib.dll Normal file

Binary file not shown.

View File

@ -0,0 +1,250 @@
#include "color.effect"
uniform float4x4 ViewProj;
uniform float2 base_dimension;
uniform float2 base_dimension_i;
uniform texture2d image;
uniform float multiplier;
sampler_state textureSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VertInOut {
float2 uv : TEXCOORD0;
float4 pos : POSITION;
};
struct FragData {
float2 uv : TEXCOORD0;
};
VertInOut VSDefault(VertData vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 DrawArea(FragData frag_in)
{
float2 uv = frag_in.uv;
float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
// Handle potential OpenGL flip.
if (obs_glsl_compile)
uv_delta.y = abs(uv_delta.y);
float2 uv_min = uv - 0.5 * uv_delta;
float2 uv_max = uv_min + uv_delta;
float2 load_index_begin = floor(uv_min * base_dimension);
float2 load_index_end = ceil(uv_max * base_dimension);
float2 target_dimension = 1.0 / uv_delta;
float2 target_pos = uv * target_dimension;
float2 target_pos_min = target_pos - 0.5;
float2 target_pos_max = target_pos + 0.5;
float2 scale = base_dimension_i * target_dimension;
float4 total_color = float4(0.0, 0.0, 0.0, 0.0);
float load_index_y = load_index_begin.y;
do {
float source_y_min = load_index_y * scale.y;
float source_y_max = source_y_min + scale.y;
float y_min = max(source_y_min, target_pos_min.y);
float y_max = min(source_y_max, target_pos_max.y);
float height = y_max - y_min;
float load_index_x = load_index_begin.x;
do {
float source_x_min = load_index_x * scale.x;
float source_x_max = source_x_min + scale.x;
float x_min = max(source_x_min, target_pos_min.x);
float x_max = min(source_x_max, target_pos_max.x);
float width = x_max - x_min;
float area = width * height;
float4 color = image.Load(int3(load_index_x, load_index_y, 0));
total_color += area * color;
++load_index_x;
} while (load_index_x < load_index_end.x);
++load_index_y;
} while (load_index_y < load_index_end.y);
return total_color;
}
float4 PSDrawAreaRGBA(FragData frag_in) : TARGET
{
return DrawArea(frag_in);
}
float4 PSDrawAreaRGBAMultiply(FragData frag_in) : TARGET
{
float4 rgba = DrawArea(frag_in);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawAreaRGBATonemap(FragData frag_in) : TARGET
{
float4 rgba = DrawArea(frag_in);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawAreaRGBAMultiplyTonemap(FragData frag_in) : TARGET
{
float4 rgba = DrawArea(frag_in);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 DrawAreaUpscale(FragData frag_in)
{
float2 uv = frag_in.uv;
float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
// Handle potential OpenGL flip.
if (obs_glsl_compile)
uv_delta.y = abs(uv_delta.y);
float2 uv_min = uv - 0.5 * uv_delta;
float2 uv_max = uv_min + uv_delta;
float2 load_index_first = floor(uv_min * base_dimension);
float2 load_index_last = ceil(uv_max * base_dimension) - 1.0;
if (load_index_first.x < load_index_last.x) {
float uv_boundary_x = load_index_last.x * base_dimension_i.x;
uv.x = ((uv.x - uv_boundary_x) / uv_delta.x) * base_dimension_i.x + uv_boundary_x;
} else
uv.x = (load_index_first.x + 0.5) * base_dimension_i.x;
if (load_index_first.y < load_index_last.y) {
float uv_boundary_y = load_index_last.y * base_dimension_i.y;
uv.y = ((uv.y - uv_boundary_y) / uv_delta.y) * base_dimension_i.y + uv_boundary_y;
} else
uv.y = (load_index_first.y + 0.5) * base_dimension_i.y;
return image.Sample(textureSampler, uv);
}
float4 PSDrawAreaRGBAUpscale(FragData frag_in) : TARGET
{
return DrawAreaUpscale(frag_in);
}
float4 PSDrawAreaRGBAUpscaleMultiply(FragData frag_in) : TARGET
{
float4 rgba = DrawAreaUpscale(frag_in);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawAreaRGBAUpscaleTonemap(FragData frag_in) : TARGET
{
float4 rgba = DrawAreaUpscale(frag_in);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawAreaRGBAUpscaleMultiplyTonemap(FragData frag_in) : TARGET
{
float4 rgba = DrawAreaUpscale(frag_in);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBA(frag_in);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBAMultiply(frag_in);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBATonemap(frag_in);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBAMultiplyTonemap(frag_in);
}
}
technique DrawUpscale
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBAUpscale(frag_in);
}
}
technique DrawUpscaleMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBAUpscaleMultiply(frag_in);
}
}
technique DrawUpscaleTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBAUpscaleTonemap(frag_in);
}
}
technique DrawUpscaleMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAreaRGBAUpscaleMultiplyTonemap(frag_in);
}
}

View File

@ -0,0 +1,236 @@
/*
* bicubic sharper (better for downscaling)
* note - this shader is adapted from the GPL bsnes shader, very good stuff
* there.
*/
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float2 base_dimension;
uniform float2 base_dimension_i;
uniform float undistort_factor = 1.0;
uniform float multiplier;
sampler_state textureSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VertOut {
float2 uv : TEXCOORD0;
float4 pos : POSITION;
};
struct FragData {
float2 uv : TEXCOORD0;
};
VertOut VSDefault(VertData v_in)
{
VertOut vert_out;
vert_out.uv = v_in.uv * base_dimension;
vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
return vert_out;
}
float4 weight4(float x)
{
/* Sharper version. May look better in some cases. B=0, C=0.75 */
return float4(
((-0.75 * x + 1.5) * x - 0.75) * x,
(1.25 * x - 2.25) * x * x + 1.0,
((-1.25 * x + 1.5) * x + 0.75) * x,
(0.75 * x - 0.75) * x * x);
}
float AspectUndistortX(float x, float a)
{
// The higher the power, the longer the linear part will be.
return (1.0 - a) * (x * x * x * x * x) + a * x;
}
float AspectUndistortU(float u)
{
// Normalize texture coord to -1.0 to 1.0 range, and back.
return AspectUndistortX((u - 0.5) * 2.0, undistort_factor) * 0.5 + 0.5;
}
float2 undistort_coord(float xpos, float ypos)
{
return float2(AspectUndistortU(xpos), ypos);
}
float4 undistort_pixel(float xpos, float ypos)
{
return image.Sample(textureSampler, undistort_coord(xpos, ypos));
}
float4 undistort_line(float4 xpos, float ypos, float4 rowtaps)
{
return undistort_pixel(xpos.x, ypos) * rowtaps.x +
undistort_pixel(xpos.y, ypos) * rowtaps.y +
undistort_pixel(xpos.z, ypos) * rowtaps.z +
undistort_pixel(xpos.w, ypos) * rowtaps.w;
}
float4 DrawBicubic(FragData f_in, bool undistort)
{
float2 pos = f_in.uv;
float2 pos1 = floor(pos - 0.5) + 0.5;
float2 f = pos - pos1;
float4 rowtaps = weight4(f.x);
float4 coltaps = weight4(f.y);
float2 uv1 = pos1 * base_dimension_i;
float2 uv0 = uv1 - base_dimension_i;
float2 uv2 = uv1 + base_dimension_i;
float2 uv3 = uv2 + base_dimension_i;
if (undistort) {
float4 xpos = float4(uv0.x, uv1.x, uv2.x, uv3.x);
return undistort_line(xpos, uv0.y, rowtaps) * coltaps.x +
undistort_line(xpos, uv1.y, rowtaps) * coltaps.y +
undistort_line(xpos, uv2.y, rowtaps) * coltaps.z +
undistort_line(xpos, uv3.y, rowtaps) * coltaps.w;
}
float u_weight_sum = rowtaps.y + rowtaps.z;
float u_middle_offset = rowtaps.z * base_dimension_i.x / u_weight_sum;
float u_middle = uv1.x + u_middle_offset;
float v_weight_sum = coltaps.y + coltaps.z;
float v_middle_offset = coltaps.z * base_dimension_i.y / v_weight_sum;
float v_middle = uv1.y + v_middle_offset;
int2 coord_top_left = int2(max(uv0 * base_dimension, 0.5));
int2 coord_bottom_right = int2(min(uv3 * base_dimension, base_dimension - 0.5));
float4 top = image.Load(int3(coord_top_left, 0)) * rowtaps.x;
top += image.Sample(textureSampler, float2(u_middle, uv0.y)) * u_weight_sum;
top += image.Load(int3(coord_bottom_right.x, coord_top_left.y, 0)) * rowtaps.w;
float4 total = top * coltaps.x;
float4 middle = image.Sample(textureSampler, float2(uv0.x, v_middle)) * rowtaps.x;
middle += image.Sample(textureSampler, float2(u_middle, v_middle)) * u_weight_sum;
middle += image.Sample(textureSampler, float2(uv3.x, v_middle)) * rowtaps.w;
total += middle * v_weight_sum;
float4 bottom = image.Load(int3(coord_top_left.x, coord_bottom_right.y, 0)) * rowtaps.x;
bottom += image.Sample(textureSampler, float2(u_middle, uv3.y)) * u_weight_sum;
bottom += image.Load(int3(coord_bottom_right, 0)) * rowtaps.w;
total += bottom * coltaps.w;
return total;
}
float4 PSDrawBicubicRGBA(FragData f_in, bool undistort) : TARGET
{
return DrawBicubic(f_in, undistort);
}
float4 PSDrawBicubicRGBAMultiply(FragData f_in, bool undistort) : TARGET
{
float4 rgba = DrawBicubic(f_in, undistort);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawBicubicRGBATonemap(FragData f_in, bool undistort) : TARGET
{
float4 rgba = DrawBicubic(f_in, undistort);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawBicubicRGBAMultiplyTonemap(FragData f_in, bool undistort) : TARGET
{
float4 rgba = DrawBicubic(f_in, undistort);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBA(f_in, false);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBAMultiply(f_in, false);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBATonemap(f_in, false);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBAMultiplyTonemap(f_in, false);
}
}
technique DrawUndistort
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBA(f_in, true);
}
}
technique DrawUndistortMultiply
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBAMultiply(f_in, true);
}
}
technique DrawUndistortTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBATonemap(f_in, true);
}
}
technique DrawUndistortMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawBicubicRGBAMultiplyTonemap(f_in, true);
}
}

View File

@ -0,0 +1,123 @@
/*
* bilinear low res scaling, samples 8 pixels of a larger image to scale to a
* low resolution image below half size
*/
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float multiplier;
sampler_state textureSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertData VSDefault(VertData v_in)
{
VertData vert_out;
vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = v_in.uv;
return vert_out;
}
float4 pixel(float2 uv)
{
return image.Sample(textureSampler, uv);
}
float4 DrawLowresBilinear(VertData f_in)
{
float2 uv = f_in.uv;
float2 stepxy = float2(ddx(uv.x), ddy(uv.y));
float2 stepxy1 = stepxy * 0.0625;
float2 stepxy3 = stepxy * 0.1875;
float2 stepxy5 = stepxy * 0.3125;
float2 stepxy7 = stepxy * 0.4375;
// Simulate Direct3D 8-sample pattern
float4 out_color;
out_color = pixel(uv + float2( stepxy1.x, -stepxy3.y));
out_color += pixel(uv + float2(-stepxy1.x, stepxy3.y));
out_color += pixel(uv + float2( stepxy5.x, stepxy1.y));
out_color += pixel(uv + float2(-stepxy3.x, -stepxy5.y));
out_color += pixel(uv + float2(-stepxy5.x, stepxy5.y));
out_color += pixel(uv + float2(-stepxy7.x, -stepxy1.y));
out_color += pixel(uv + float2( stepxy3.x, stepxy7.y));
out_color += pixel(uv + float2( stepxy7.x, -stepxy7.y));
return out_color * 0.125;
}
float4 PSDrawLowresBilinearRGBA(VertData f_in) : TARGET
{
return DrawLowresBilinear(f_in);
}
float4 PSDrawLowresBilinearRGBAMultiply(VertData f_in) : TARGET
{
float4 rgba = DrawLowresBilinear(f_in);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawLowresBilinearRGBATonemap(VertData f_in) : TARGET
{
float4 rgba = DrawLowresBilinear(f_in);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawLowresBilinearRGBAMultiplyTonemap(VertData f_in) : TARGET
{
float4 rgba = DrawLowresBilinear(f_in);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLowresBilinearRGBA(f_in);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLowresBilinearRGBAMultiply(f_in);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLowresBilinearRGBATonemap(f_in);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLowresBilinearRGBAMultiplyTonemap(f_in);
}
}

View File

@ -0,0 +1,172 @@
float srgb_linear_to_nonlinear_channel(float u)
{
return (u <= 0.0031308) ? (12.92 * u) : ((1.055 * pow(u, 1. / 2.4)) - 0.055);
}
float3 srgb_linear_to_nonlinear(float3 v)
{
return float3(srgb_linear_to_nonlinear_channel(v.r), srgb_linear_to_nonlinear_channel(v.g), srgb_linear_to_nonlinear_channel(v.b));
}
float srgb_nonlinear_to_linear_channel(float u)
{
return (u <= 0.04045) ? (u / 12.92) : pow(mad(u, 1. / 1.055, .055 / 1.055), 2.4);
}
float3 srgb_nonlinear_to_linear(float3 v)
{
return float3(srgb_nonlinear_to_linear_channel(v.r), srgb_nonlinear_to_linear_channel(v.g), srgb_nonlinear_to_linear_channel(v.b));
}
float3 rec709_to_rec2020(float3 v)
{
float r = dot(v, float3(0.62740389593469903, 0.32928303837788370, 0.043313065687417225));
float g = dot(v, float3(0.069097289358232075, 0.91954039507545871, 0.011362315566309178));
float b = dot(v, float3(0.016391438875150280, 0.088013307877225749, 0.89559525324762401));
return float3(r, g, b);
}
float3 d65p3_to_rec709(float3 v)
{
float r = dot(v, float3(1.2249401762805598, -0.22494017628055996, 0.));
float g = dot(v, float3(-0.042056954709688163, 1.0420569547096881, 0.));
float b = dot(v, float3(-0.019637554590334432, -0.078636045550631889, 1.0982736001409663));
return float3(r, g, b);
}
float3 rec2020_to_rec709(float3 v)
{
float r = dot(v, float3(1.6604910021084345, -0.58764113878854951, -0.072849863319884883));
float g = dot(v, float3(-0.12455047452159074, 1.1328998971259603, -0.0083494226043694768));
float b = dot(v, float3(-0.018150763354905303, -0.10057889800800739, 1.1187296613629127));
return float3(r, g, b);
}
float3 reinhard(float3 rgb)
{
rgb /= rgb + float3(1., 1., 1.);
rgb = saturate(rgb);
rgb = pow(rgb, float3(1. / 2.4, 1. / 2.4, 1. / 2.4));
rgb = srgb_nonlinear_to_linear(rgb);
return rgb;
}
float linear_to_st2084_channel(float x)
{
float c = pow(abs(x), 0.1593017578);
return pow((0.8359375 + 18.8515625 * c) / (1. + 18.6875 * c), 78.84375);
}
float3 linear_to_st2084(float3 rgb)
{
return float3(linear_to_st2084_channel(rgb.r), linear_to_st2084_channel(rgb.g), linear_to_st2084_channel(rgb.b));
}
float st2084_to_linear_channel(float u)
{
float c = pow(abs(u), 1. / 78.84375);
return pow(abs(max(c - 0.8359375, 0.) / (18.8515625 - 18.6875 * c)), 1. / 0.1593017578);
}
float3 st2084_to_linear(float3 rgb)
{
return float3(st2084_to_linear_channel(rgb.r), st2084_to_linear_channel(rgb.g), st2084_to_linear_channel(rgb.b));
}
float eetf_0_Lmax(float maxRGB1_pq, float Lw, float Lmax)
{
float Lw_pq = linear_to_st2084_channel(Lw / 10000.);
float E1 = saturate(maxRGB1_pq / Lw_pq); // Ensure normalization in case Lw is a lie
float maxLum = linear_to_st2084_channel(Lmax / 10000.) / Lw_pq;
float KS = (1.5 * maxLum) - 0.5;
float E2 = E1;
if (E1 > KS)
{
float T = (E1 - KS) / (1. - KS);
float Tsquared = T * T;
float Tcubed = Tsquared * T;
float P = (2. * Tcubed - 3. * Tsquared + 1.) * KS + (Tcubed - 2. * Tsquared + T) * (1. - KS) + (-2. * Tcubed + 3. * Tsquared) * maxLum;
E2 = P;
}
float E3 = E2;
float E4 = E3 * Lw_pq;
return E4;
}
float3 maxRGB_eetf_internal(float3 rgb_linear, float maxRGB1_linear, float maxRGB1_pq, float Lw, float Lmax)
{
float maxRGB2_pq = eetf_0_Lmax(maxRGB1_pq, Lw, Lmax);
float maxRGB2_linear = st2084_to_linear_channel(maxRGB2_pq);
// avoid divide-by-zero possibility
maxRGB1_linear = max(6.10352e-5, maxRGB1_linear);
rgb_linear *= maxRGB2_linear / maxRGB1_linear;
return rgb_linear;
}
float3 maxRGB_eetf_pq_to_linear(float3 rgb_pq, float Lw, float Lmax)
{
float3 rgb_linear = st2084_to_linear(rgb_pq);
float maxRGB1_linear = max(max(rgb_linear.r, rgb_linear.g), rgb_linear.b);
float maxRGB1_pq = max(max(rgb_pq.r, rgb_pq.g), rgb_pq.b);
return maxRGB_eetf_internal(rgb_linear, maxRGB1_linear, maxRGB1_pq, Lw, Lmax);
}
float3 maxRGB_eetf_linear_to_linear(float3 rgb_linear, float Lw, float Lmax)
{
float maxRGB1_linear = max(max(rgb_linear.r, rgb_linear.g), rgb_linear.b);
float maxRGB1_pq = linear_to_st2084_channel(maxRGB1_linear);
return maxRGB_eetf_internal(rgb_linear, maxRGB1_linear, maxRGB1_pq, Lw, Lmax);
}
float3 st2084_to_linear_eetf(float3 rgb, float Lw, float Lmax)
{
return (Lw > Lmax) ? maxRGB_eetf_pq_to_linear(rgb, Lw, Lmax) : st2084_to_linear(rgb);
}
float linear_to_hlg_channel(float u)
{
float ln2_i = 1. / log(2.);
float m = 0.17883277 / ln2_i;
return (u <= (1. / 12.)) ? sqrt(3. * u) : ((log2((12. * u) - 0.28466892) * m) + 0.55991073);
}
float3 linear_to_hlg(float3 rgb, float Lw)
{
rgb = saturate(rgb);
if (Lw > 1000.)
{
rgb = maxRGB_eetf_linear_to_linear(rgb, Lw, 1000.);
rgb *= 10000. / Lw;
}
else
{
rgb *= 10.;
}
float Yd = dot(rgb, float3(0.2627, 0.678, 0.0593));
// avoid inf from pow(0., negative) by using smallest positive normal number
Yd = max(6.10352e-5, Yd);
rgb *= pow(Yd, -1. / 6.);
return float3(linear_to_hlg_channel(rgb.r), linear_to_hlg_channel(rgb.g), linear_to_hlg_channel(rgb.b));
}
float hlg_to_linear_channel(float u)
{
float ln2_i = 1. / log(2.);
float m = ln2_i / 0.17883277;
float a = -ln2_i * 0.55991073 / 0.17883277;
return (u <= 0.5) ? ((u * u) / 3.) : ((exp2(u * m + a) + 0.28466892) / 12.);
}
float3 hlg_to_linear(float3 v, float exponent)
{
float3 rgb = float3(hlg_to_linear_channel(v.r), hlg_to_linear_channel(v.g), hlg_to_linear_channel(v.b));
float Ys = dot(rgb, float3(0.2627, 0.678, 0.0593));
rgb *= pow(Ys, exponent);
return rgb;
}

View File

@ -0,0 +1,271 @@
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float multiplier;
sampler_state def_sampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertInOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertInOut VSDefault(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 PSDrawBare(VertInOut vert_in) : TARGET
{
return image.Sample(def_sampler, vert_in.uv);
}
float4 PSDrawAlphaDivide(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb *= (rgba.a > 0.) ? (1. / rgba.a) : 0.;
return rgba;
}
float4 PSDrawAlphaDivideTonemap(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb *= (rgba.a > 0.) ? (1. / rgba.a) : 0.;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawAlphaDivideR10L(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb *= (rgba.a > 0.) ? (multiplier / rgba.a) : 0.;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = linear_to_st2084(rgba.rgb);
uint3 rgb1023 = uint3(mad(rgba.rgb, 876., 64.5));
uint b = (rgb1023.b & 0x3Fu) << 2;
uint g = ((rgb1023.b & 0x3C0u) >> 6) | ((rgb1023.g & 0xFu) << 4);
uint r = ((rgb1023.g & 0x3F0u) >> 4) | ((rgb1023.r & 0x3u) << 6);
uint a = ((rgb1023.r & 0x3FCu) >> 2);
return float4(uint4(r, g, b, a)) / 255.;
}
float4 PSDrawNonlinearAlpha(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_linear_to_nonlinear(rgba.rgb);
rgba.rgb *= rgba.a;
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
return rgba;
}
float4 PSDrawNonlinearAlphaMultiply(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_linear_to_nonlinear(rgba.rgb);
rgba.rgb *= rgba.a;
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawSrgbDecompress(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
return rgba;
}
float4 PSDrawSrgbDecompressMultiply(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawMultiply(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawTonemap(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawMultiplyTonemap(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawPQ(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = st2084_to_linear(rgba.rgb) * multiplier;
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawTonemapPQ(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = st2084_to_linear(rgba.rgb) * multiplier;
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawD65P3(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
rgba.rgb = d65p3_to_rec709(rgba.rgb);
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawBare(vert_in);
}
}
technique DrawAlphaDivide
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAlphaDivide(vert_in);
}
}
technique DrawAlphaDivideTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAlphaDivideTonemap(vert_in);
}
}
technique DrawAlphaDivideR10L
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawAlphaDivideR10L(vert_in);
}
}
technique DrawNonlinearAlpha
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawNonlinearAlpha(vert_in);
}
}
technique DrawNonlinearAlphaMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawNonlinearAlphaMultiply(vert_in);
}
}
technique DrawSrgbDecompress
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawSrgbDecompress(vert_in);
}
}
technique DrawSrgbDecompressMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawSrgbDecompressMultiply(vert_in);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawMultiply(vert_in);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawTonemap(vert_in);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawMultiplyTonemap(vert_in);
}
}
technique DrawPQ
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawPQ(vert_in);
}
}
technique DrawTonemapPQ
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawTonemapPQ(vert_in);
}
}
technique DrawD65P3
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawD65P3(vert_in);
}
}

View File

@ -0,0 +1,84 @@
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture_rect image;
sampler_state def_sampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertInOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertInOut VSDefault(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 PSDrawBare(VertInOut vert_in) : TARGET
{
return image.Sample(def_sampler, vert_in.uv);
}
float4 PSDrawD65P3(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
rgba.rgb = d65p3_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawOpaque(VertInOut vert_in) : TARGET
{
return float4(image.Sample(def_sampler, vert_in.uv).rgb, 1.0);
}
float4 PSDrawSrgbDecompress(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
rgba.rgb = srgb_nonlinear_to_linear(rgba.rgb);
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawBare(vert_in);
}
}
technique DrawD65P3
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawD65P3(vert_in);
}
}
technique DrawOpaque
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawOpaque(vert_in);
}
}
technique DrawSrgbDecompress
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawSrgbDecompress(vert_in);
}
}

View File

@ -0,0 +1,325 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float multiplier;
uniform texture2d previous_image;
uniform float2 dimensions;
uniform int field_order;
uniform bool frame2;
sampler_state textureSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
int3 select(int2 texel, int x, int y)
{
return int3(texel + int2(x, y), 0);
}
float4 load_at_prev(int2 texel, int x, int y)
{
return previous_image.Load(select(texel, x, y));
}
float4 load_at_image(int2 texel, int x, int y)
{
return image.Load(select(texel, x, y));
}
float4 load_at(int2 texel, int x, int y, int field)
{
if(field == 0)
return load_at_image(texel, x, y);
else
return load_at_prev(texel, x, y);
}
#define YADIF_UPDATE(c, level) \
if(score.c < spatial_score.c) \
{ \
spatial_score.c = score.c; \
spatial_pred.c = (load_at(texel, level, -1, field) + load_at(texel, -level, 1, field)).c / 2; \
#define YADIF_CHECK_ONE(level, c) \
{ \
float4 score = abs(load_at(texel, -1 + level, 1, field) - load_at(texel, -1 - level, -1, field)) + \
abs(load_at(texel, level, 1, field) - load_at(texel, -level, -1, field)) + \
abs(load_at(texel, 1 + level, 1, field) - load_at(texel, 1 - level, -1, field)); \
YADIF_UPDATE(c, level) } \
}
#define YADIF_CHECK(level) \
{ \
float4 score = abs(load_at(texel, -1 + level, 1, field) - load_at(texel, -1 - level, -1, field)) + \
abs(load_at(texel, level, 1, field) - load_at(texel, -level, -1, field)) + \
abs(load_at(texel, 1 + level, 1, field) - load_at(texel, 1 - level, -1, field)); \
YADIF_UPDATE(r, level) YADIF_CHECK_ONE(level * 2, r) } \
YADIF_UPDATE(g, level) YADIF_CHECK_ONE(level * 2, g) } \
YADIF_UPDATE(b, level) YADIF_CHECK_ONE(level * 2, b) } \
YADIF_UPDATE(a, level) YADIF_CHECK_ONE(level * 2, a) } \
}
float4 texel_at_yadif(int2 texel, int field, bool mode0)
{
if((texel.y % 2) == field)
return load_at(texel, 0, 0, field);
#define YADIF_AVG(x_off, y_off) ((load_at_prev(texel, x_off, y_off) + load_at_image(texel, x_off, y_off))/2)
float4 c = load_at(texel, 0, 1, field),
d = YADIF_AVG(0, 0),
e = load_at(texel, 0, -1, field);
float4 temporal_diff0 = (abs(load_at_prev(texel, 0, 0) - load_at_image(texel, 0, 0))) / 2,
temporal_diff1 = (abs(load_at_prev(texel, 0, 1) - c) + abs(load_at_prev(texel, 0, -1) - e)) / 2,
temporal_diff2 = (abs(load_at_image(texel, 0, 1) - c) + abs(load_at_image(texel, 0, -1) - e)) / 2,
diff = max(temporal_diff0, max(temporal_diff1, temporal_diff2));
float4 spatial_pred = (c + e) / 2,
spatial_score = abs(load_at(texel, -1, 1, field) - load_at(texel, -1, -1, field)) +
abs(c - e) +
abs(load_at(texel, 1, 1, field) - load_at(texel, 1, -1, field)) - 1;
YADIF_CHECK(-1)
YADIF_CHECK(1)
if (mode0) {
float4 b = YADIF_AVG(0, 2),
f = YADIF_AVG(0, -2);
float4 max_ = max(d - e, max(d - c, min(b - c, f - e))),
min_ = min(d - e, min(d - c, max(b - c, f - e)));
diff = max(diff, max(min_, -max_));
} else {
diff = max(diff, max(min(d - e, d - c), -max(d - e, d - c)));
}
#define YADIF_SPATIAL(c) \
{ \
if(spatial_pred.c > d.c + diff.c) \
spatial_pred.c = d.c + diff.c; \
else if(spatial_pred.c < d.c - diff.c) \
spatial_pred.c = d.c - diff.c; \
}
YADIF_SPATIAL(r)
YADIF_SPATIAL(g)
YADIF_SPATIAL(b)
YADIF_SPATIAL(a)
return spatial_pred;
}
float4 texel_at_yadif_2x(int2 texel, int field, bool mode0)
{
field = frame2 ? (1 - field) : field;
return texel_at_yadif(texel, field, mode0);
}
float4 texel_at_discard(int2 texel, int field)
{
texel.y = texel.y / 2 * 2;
return load_at_image(texel, 0, field);
}
float4 texel_at_discard_2x(int2 texel, int field)
{
field = frame2 ? field : (1 - field);
return texel_at_discard(texel, field);
}
float4 texel_at_blend(int2 texel, int field)
{
return (load_at_image(texel, 0, 0) + load_at_image(texel, 0, 1)) / 2;
}
float4 texel_at_blend_2x(int2 texel, int field)
{
if (!frame2)
return (load_at_image(texel, 0, 0) +
load_at_prev(texel, 0, 1)) / 2;
else
return (load_at_image(texel, 0, 0) +
load_at_image(texel, 0, 1)) / 2;
}
float4 texel_at_linear(int2 texel, int field)
{
if ((texel.y % 2) == field)
return load_at_image(texel, 0, 0);
return (load_at_image(texel, 0, -1) + load_at_image(texel, 0, 1)) / 2;
}
float4 texel_at_linear_2x(int2 texel, int field)
{
field = frame2 ? field : (1 - field);
return texel_at_linear(texel, field);
}
float4 texel_at_yadif_discard(int2 texel, int field)
{
return (texel_at_yadif(texel, field, true) + texel_at_discard(texel, field)) / 2;
}
float4 texel_at_yadif_discard_2x(int2 texel, int field)
{
field = frame2 ? (1 - field) : field;
return (texel_at_yadif(texel, field, true) + texel_at_discard(texel, field)) / 2;
}
int2 pixel_uv(float2 uv)
{
return int2(uv * dimensions);
}
float4 PSYadifMode0RGBA(VertData v_in) : TARGET
{
return texel_at_yadif(pixel_uv(v_in.uv), field_order, true);
}
float4 PSYadifMode0RGBA_2x(VertData v_in) : TARGET
{
return texel_at_yadif_2x(pixel_uv(v_in.uv), field_order, true);
}
float4 PSYadifMode2RGBA(VertData v_in) : TARGET
{
return texel_at_yadif(pixel_uv(v_in.uv), field_order, false);
}
float4 PSYadifMode2RGBA_2x(VertData v_in) : TARGET
{
return texel_at_yadif_2x(pixel_uv(v_in.uv), field_order, false);
}
float4 PSYadifDiscardRGBA(VertData v_in) : TARGET
{
return texel_at_yadif_discard(pixel_uv(v_in.uv), field_order);
}
float4 PSYadifDiscardRGBA_2x(VertData v_in) : TARGET
{
return texel_at_yadif_discard_2x(pixel_uv(v_in.uv), field_order);
}
float4 PSLinearRGBA(VertData v_in) : TARGET
{
return texel_at_linear(pixel_uv(v_in.uv), field_order);
}
float4 PSLinearRGBA_2x(VertData v_in) : TARGET
{
return texel_at_linear_2x(pixel_uv(v_in.uv), field_order);
}
float4 PSDiscardRGBA(VertData v_in) : TARGET
{
return texel_at_discard(pixel_uv(v_in.uv), field_order);
}
float4 PSDiscardRGBA_2x(VertData v_in) : TARGET
{
return texel_at_discard_2x(pixel_uv(v_in.uv), field_order);
}
float4 PSBlendRGBA(VertData v_in) : TARGET
{
return texel_at_blend(pixel_uv(v_in.uv), field_order);
}
float4 PSBlendRGBA_2x(VertData v_in) : TARGET
{
return texel_at_blend_2x(pixel_uv(v_in.uv), field_order);
}
VertData VSDefault(VertData v_in)
{
VertData vert_out;
vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = v_in.uv;
return vert_out;
}
#define TECHNIQUE(rgba_ps, rgba_ps_multiply, rgba_ps_tonemap, rgba_ps_multiply_tonemap) \
float4 rgba_ps_multiply(VertData v_in) : TARGET \
{ \
float4 rgba = rgba_ps(v_in); \
rgba.rgb *= multiplier; \
return rgba; \
} \
float4 rgba_ps_tonemap(VertData v_in) : TARGET \
{ \
float4 rgba = rgba_ps(v_in); \
rgba.rgb = rec709_to_rec2020(rgba.rgb); \
rgba.rgb = reinhard(rgba.rgb); \
rgba.rgb = rec2020_to_rec709(rgba.rgb); \
return rgba; \
} \
float4 rgba_ps_multiply_tonemap(VertData v_in) : TARGET \
{ \
float4 rgba = rgba_ps(v_in); \
rgba.rgb *= multiplier; \
rgba.rgb = rec709_to_rec2020(rgba.rgb); \
rgba.rgb = reinhard(rgba.rgb); \
rgba.rgb = rec2020_to_rec709(rgba.rgb); \
return rgba; \
} \
technique Draw \
{ \
pass \
{ \
vertex_shader = VSDefault(v_in); \
pixel_shader = rgba_ps(v_in); \
} \
} \
technique DrawMultiply \
{ \
pass \
{ \
vertex_shader = VSDefault(v_in); \
pixel_shader = rgba_ps_multiply(v_in); \
} \
} \
technique DrawTonemap \
{ \
pass \
{ \
vertex_shader = VSDefault(v_in); \
pixel_shader = rgba_ps_tonemap(v_in); \
} \
} \
technique DrawMultiplyTonemap \
{ \
pass \
{ \
vertex_shader = VSDefault(v_in); \
pixel_shader = rgba_ps_multiply_tonemap(v_in); \
} \
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSBlendRGBA, PSBlendRGBA_multiply, PSBlendRGBA_tonemap, PSBlendRGBA_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSBlendRGBA_2x, PSBlendRGBA_2x_multiply, PSBlendRGBA_2x_tonemap, PSBlendRGBA_2x_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSDiscardRGBA, PSDiscardRGBA_multiply, PSDiscardRGBA_tonemap, PSDiscardRGBA_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSDiscardRGBA_2x, PSDiscardRGBA_2x_multiply, PSDiscardRGBA_2x_tonemap, PSDiscardRGBA_2x_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSLinearRGBA, PSLinearRGBA_multiply, PSLinearRGBA_tonemap, PSLinearRGBA_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSLinearRGBA_2x, PSLinearRGBA_2x_multiply, PSLinearRGBA_2x_tonemap, PSLinearRGBA_2x_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSYadifMode0RGBA, PSYadifMode0RGBA_multiply, PSYadifMode0RGBA_tonemap, PSYadifMode0RGBA_multiply_tonemap);

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 Ruwen Hahn <palana@stunned.de>
* John R. Bradley <jrb@turrettech.com>
* Lain Bailey <lain@obsproject.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "deinterlace_base.effect"
TECHNIQUE(PSYadifMode0RGBA_2x, PSYadifMode0RGBA_2x_multiply, PSYadifMode0RGBA_2x_tonemap, PSYadifMode0RGBA_2x_multiply_tonemap);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,292 @@
/*
* lanczos sharper
* note - this shader is adapted from the GPL bsnes shader, very good stuff
* there.
*/
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float2 base_dimension;
uniform float2 base_dimension_i;
uniform float undistort_factor = 1.0;
uniform float multiplier;
sampler_state textureSampler
{
AddressU = Clamp;
AddressV = Clamp;
Filter = Linear;
};
struct VertData {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VertOut {
float2 uv : TEXCOORD0;
float4 pos : POSITION;
};
struct FragData {
float2 uv : TEXCOORD0;
};
VertOut VSDefault(VertData v_in)
{
VertOut vert_out;
vert_out.uv = v_in.uv * base_dimension;
vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
return vert_out;
}
float weight(float x)
{
float x_pi = x * 3.141592654;
return 3.0 * sin(x_pi) * sin(x_pi * (1.0 / 3.0)) / (x_pi * x_pi);
}
void weight6(float f_neg, out float3 tap012, out float3 tap345)
{
tap012 = float3(
weight(f_neg - 2.0),
weight(f_neg - 1.0),
min(1.0, weight(f_neg))); // Replace NaN with 1.0.
tap345 = float3(
weight(f_neg + 1.0),
weight(f_neg + 2.0),
weight(f_neg + 3.0));
// Normalize weights
float sum = tap012.x + tap012.y + tap012.z + tap345.x + tap345.y + tap345.z;
float sum_i = 1.0 / sum;
tap012 = tap012 * sum_i;
tap345 = tap345 * sum_i;
}
float AspectUndistortX(float x, float a)
{
// The higher the power, the longer the linear part will be.
return (1.0 - a) * (x * x * x * x * x) + a * x;
}
float AspectUndistortU(float u)
{
// Normalize texture coord to -1.0 to 1.0 range, and back.
return AspectUndistortX((u - 0.5) * 2.0, undistort_factor) * 0.5 + 0.5;
}
float2 undistort_coord(float xpos, float ypos)
{
return float2(AspectUndistortU(xpos), ypos);
}
float4 undistort_pixel(float xpos, float ypos)
{
return image.Sample(textureSampler, undistort_coord(xpos, ypos));
}
float4 undistort_line(float3 xpos012, float3 xpos345, float ypos, float3 rowtap012,
float3 rowtap345)
{
return
undistort_pixel(xpos012.x, ypos) * rowtap012.x +
undistort_pixel(xpos012.y, ypos) * rowtap012.y +
undistort_pixel(xpos012.z, ypos) * rowtap012.z +
undistort_pixel(xpos345.x, ypos) * rowtap345.x +
undistort_pixel(xpos345.y, ypos) * rowtap345.y +
undistort_pixel(xpos345.z, ypos) * rowtap345.z;
}
float4 DrawLanczos(FragData f_in, bool undistort)
{
float2 pos = f_in.uv;
float2 pos2 = floor(pos - 0.5) + 0.5;
float2 f_neg = pos2 - pos;
float3 rowtap012, rowtap345;
weight6(f_neg.x, rowtap012, rowtap345);
float3 coltap012, coltap345;
weight6(f_neg.y, coltap012, coltap345);
float2 uv2 = pos2 * base_dimension_i;
float2 uv1 = uv2 - base_dimension_i;
float2 uv0 = uv1 - base_dimension_i;
float2 uv3 = uv2 + base_dimension_i;
float2 uv4 = uv3 + base_dimension_i;
float2 uv5 = uv4 + base_dimension_i;
if (undistort) {
float3 xpos012 = float3(uv0.x, uv1.x, uv2.x);
float3 xpos345 = float3(uv3.x, uv4.x, uv5.x);
return undistort_line(xpos012, xpos345, uv0.y, rowtap012, rowtap345) * coltap012.x +
undistort_line(xpos012, xpos345, uv1.y, rowtap012, rowtap345) * coltap012.y +
undistort_line(xpos012, xpos345, uv2.y, rowtap012, rowtap345) * coltap012.z +
undistort_line(xpos012, xpos345, uv3.y, rowtap012, rowtap345) * coltap345.x +
undistort_line(xpos012, xpos345, uv4.y, rowtap012, rowtap345) * coltap345.y +
undistort_line(xpos012, xpos345, uv5.y, rowtap012, rowtap345) * coltap345.z;
}
float u_weight_sum = rowtap012.z + rowtap345.x;
float u_middle_offset = rowtap345.x * base_dimension_i.x / u_weight_sum;
float u_middle = uv2.x + u_middle_offset;
float v_weight_sum = coltap012.z + coltap345.x;
float v_middle_offset = coltap345.x * base_dimension_i.y / v_weight_sum;
float v_middle = uv2.y + v_middle_offset;
float2 coord_limit = base_dimension - 0.5;
float2 coord0_f = max(uv0 * base_dimension, 0.5);
float2 coord1_f = max(uv1 * base_dimension, 0.5);
float2 coord4_f = min(uv4 * base_dimension, coord_limit);
float2 coord5_f = min(uv5 * base_dimension, coord_limit);
int2 coord0 = int2(coord0_f);
int2 coord1 = int2(coord1_f);
int2 coord4 = int2(coord4_f);
int2 coord5 = int2(coord5_f);
float4 row0 = image.Load(int3(coord0, 0)) * rowtap012.x;
row0 += image.Load(int3(coord1.x, coord0.y, 0)) * rowtap012.y;
row0 += image.Sample(textureSampler, float2(u_middle, uv0.y)) * u_weight_sum;
row0 += image.Load(int3(coord4.x, coord0.y, 0)) * rowtap345.y;
row0 += image.Load(int3(coord5.x, coord0.y, 0)) * rowtap345.z;
float4 total = row0 * coltap012.x;
float4 row1 = image.Load(int3(coord0.x, coord1.y, 0)) * rowtap012.x;
row1 += image.Load(int3(coord1.x, coord1.y, 0)) * rowtap012.y;
row1 += image.Sample(textureSampler, float2(u_middle, uv1.y)) * u_weight_sum;
row1 += image.Load(int3(coord4.x, coord1.y, 0)) * rowtap345.y;
row1 += image.Load(int3(coord5.x, coord1.y, 0)) * rowtap345.z;
total += row1 * coltap012.y;
float4 row23 = image.Sample(textureSampler, float2(uv0.x, v_middle)) * rowtap012.x;
row23 += image.Sample(textureSampler, float2(uv1.x, v_middle)) * rowtap012.y;
row23 += image.Sample(textureSampler, float2(u_middle, v_middle)) * u_weight_sum;
row23 += image.Sample(textureSampler, float2(uv4.x, v_middle)) * rowtap345.y;
row23 += image.Sample(textureSampler, float2(uv5.x, v_middle)) * rowtap345.z;
total += row23 * v_weight_sum;
float4 row4 = image.Load(int3(coord0.x, coord4.y, 0)) * rowtap012.x;
row4 += image.Load(int3(coord1.x, coord4.y, 0)) * rowtap012.y;
row4 += image.Sample(textureSampler, float2(u_middle, uv4.y)) * u_weight_sum;
row4 += image.Load(int3(coord4.x, coord4.y, 0)) * rowtap345.y;
row4 += image.Load(int3(coord5.x, coord4.y, 0)) * rowtap345.z;
total += row4 * coltap345.y;
float4 row5 = image.Load(int3(coord0.x, coord5.y, 0)) * rowtap012.x;
row5 += image.Load(int3(coord1.x, coord5.y, 0)) * rowtap012.y;
row5 += image.Sample(textureSampler, float2(u_middle, uv5.y)) * u_weight_sum;
row5 += image.Load(int3(coord4.x, coord5.y, 0)) * rowtap345.y;
row5 += image.Load(int3(coord5, 0)) * rowtap345.z;
total += row5 * coltap345.z;
return total;
}
float4 PSDrawLanczosRGBA(FragData f_in, bool undistort) : TARGET
{
return DrawLanczos(f_in, undistort);
}
float4 PSDrawLanczosRGBAMultiply(FragData f_in, bool undistort) : TARGET
{
float4 rgba = DrawLanczos(f_in, undistort);
rgba.rgb *= multiplier;
return rgba;
}
float4 PSDrawLanczosRGBATonemap(FragData f_in, bool undistort) : TARGET
{
float4 rgba = DrawLanczos(f_in, undistort);
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
float4 PSDrawLanczosRGBAMultiplyTonemap(FragData f_in, bool undistort) : TARGET
{
float4 rgba = DrawLanczos(f_in, undistort);
rgba.rgb *= multiplier;
rgba.rgb = rec709_to_rec2020(rgba.rgb);
rgba.rgb = reinhard(rgba.rgb);
rgba.rgb = rec2020_to_rec709(rgba.rgb);
return rgba;
}
technique Draw
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBA(f_in, false);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBAMultiply(f_in, false);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBATonemap(f_in, false);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBAMultiplyTonemap(f_in, false);
}
}
technique DrawUndistort
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBA(f_in, true);
}
}
technique DrawUndistortMultiply
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBAMultiply(f_in, true);
}
}
technique DrawUndistortTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBATonemap(f_in, true);
}
}
technique DrawUndistortMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(v_in);
pixel_shader = PSDrawLanczosRGBAMultiplyTonemap(f_in, true);
}
}

View File

@ -0,0 +1,159 @@
#include "color.effect"
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float multiplier;
sampler_state def_sampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertInOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertInOut VSDefault(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 PSDraw(VertInOut vert_in) : TARGET
{
return float4(image.Sample(def_sampler, vert_in.uv).rgb, 1.0);
}
float4 PSDrawSrgbDecompress(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb = srgb_nonlinear_to_linear(rgb);
return float4(rgb, 1.0);
}
float4 PSDrawSrgbDecompressMultiply(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb = srgb_nonlinear_to_linear(rgb);
rgb *= multiplier;
return float4(rgb, 1.0);
}
float4 PSDrawMultiply(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb *= multiplier;
return float4(rgb, 1.0);
}
float4 PSDrawTonemap(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb = rec709_to_rec2020(rgb);
rgb = reinhard(rgb);
rgb = rec2020_to_rec709(rgb);
return float4(rgb, 1.0);
}
float4 PSDrawMultiplyTonemap(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb *= multiplier;
rgb = rec709_to_rec2020(rgb);
rgb = reinhard(rgb);
rgb = rec2020_to_rec709(rgb);
return float4(rgb, 1.0);
}
float4 PSDrawPQ(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb = st2084_to_linear(rgb) * multiplier;
rgb = rec2020_to_rec709(rgb);
return float4(rgb, 1.0);
}
float4 PSDrawTonemapPQ(VertInOut vert_in) : TARGET
{
float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb;
rgb = st2084_to_linear(rgb) * multiplier;
rgb = reinhard(rgb);
rgb = rec2020_to_rec709(rgb);
return float4(rgb, 1.0);
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDraw(vert_in);
}
}
technique DrawSrgbDecompress
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawSrgbDecompress(vert_in);
}
}
technique DrawSrgbDecompressMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawSrgbDecompressMultiply(vert_in);
}
}
technique DrawMultiply
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawMultiply(vert_in);
}
}
technique DrawTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawTonemap(vert_in);
}
}
technique DrawMultiplyTonemap
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawMultiplyTonemap(vert_in);
}
}
technique DrawPQ
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawPQ(vert_in);
}
}
technique DrawTonemapPQ
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawTonemapPQ(vert_in);
}
}

View File

@ -0,0 +1,38 @@
uniform float4x4 ViewProj;
uniform texture2d image;
sampler_state def_sampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertInOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertInOut VSDefault(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 PSDraw(VertInOut vert_in) : TARGET
{
float4 rgba = image.Sample(def_sampler, vert_in.uv);
if (rgba.a > 0.0)
rgba.rgb /= rgba.a;
return saturate(rgba);
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDraw(vert_in);
}
}

View File

@ -0,0 +1,36 @@
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float2 scale;
sampler_state def_sampler {
Filter = Linear;
AddressU = Repeat;
AddressV = Repeat;
};
struct VertInOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertInOut VSDefault(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv * scale;
return vert_out;
}
float4 PSDrawBare(VertInOut vert_in) : TARGET
{
return image.Sample(def_sampler, vert_in.uv);
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSDrawBare(vert_in);
}
}

View File

@ -0,0 +1,80 @@
uniform float4x4 ViewProj;
uniform float4 color = {1.0, 1.0, 1.0, 1.0};
uniform float4 randomvals1;
uniform float4 randomvals2;
uniform float4 randomvals3;
struct SolidVertInOut {
float4 pos : POSITION;
};
SolidVertInOut VSSolid(SolidVertInOut vert_in)
{
SolidVertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
return vert_out;
}
float4 PSSolid(SolidVertInOut vert_in) : TARGET
{
return color;
}
float rand(float4 pos, float4 rand_vals)
{
return 0.5 + 0.5 * frac(sin(dot(pos.xy, float2(rand_vals.x, rand_vals.y))) * rand_vals.z);
}
float4 PSRandom(SolidVertInOut vert_in) : TARGET
{
return float4(rand(vert_in.pos, randomvals1),
rand(vert_in.pos, randomvals2),
rand(vert_in.pos, randomvals3),
1.0);
}
struct SolidColoredVertInOut {
float4 pos : POSITION;
float4 color : COLOR;
};
SolidColoredVertInOut VSSolidColored(SolidColoredVertInOut vert_in)
{
SolidColoredVertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.color = vert_in.color;
return vert_out;
}
float4 PSSolidColored(SolidColoredVertInOut vert_in) : TARGET
{
return vert_in.color * color;
}
technique Solid
{
pass
{
vertex_shader = VSSolid(vert_in);
pixel_shader = PSSolid(vert_in);
}
}
technique SolidColored
{
pass
{
vertex_shader = VSSolidColored(vert_in);
pixel_shader = PSSolidColored(vert_in);
}
}
technique Random
{
pass
{
vertex_shader = VSSolid(vert_in);
pixel_shader = PSRandom(vert_in);
}
}

View File

@ -0,0 +1,4 @@
AJAOutput.Device="مَخرج جهاز AJA I/O"
AJAOutput.ProgramOutput="مَخرج البرنامج"
AJAOutput.PreviewOutput="إستعراض المخرج"
AJAOutput.MiscOutput="إعدادات إضافية"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O Qurğu Çıxışı"
AJAOutput.ProgramOutput="Proqram Çıxışı"
AJAOutput.PreviewOutput="Önizləmə Çıxışı"
AJAOutput.MiscOutput="Əlavə Parametrlər"
AJAOutput.MultiViewEnable="Çoxlu Görünüşü Aktivləşdir"
AJAOutput.MultiViewAudioSource="Çox Görünüşlü Səs Mənbəyi"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Захоп прылады AJA I/O"
AJAOutput.ProgramOutput="Праграмны вывад"
AJAOutput.PreviewOutput="Прадпрагляд вываду"
AJAOutput.MiscOutput="Дадатковыя налады"
AJAOutput.MultiViewEnable="Уключыць мультыпрагляд"
AJAOutput.MultiViewAudioSource="Мультыпрагляд крыніц аўдыя"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Dispositiu de sortida d'E/S AJA"
AJAOutput.ProgramOutput="Sortida del programa"
AJAOutput.PreviewOutput="Sortida de la vista prèvia"
AJAOutput.MiscOutput="Configuració addicional"
AJAOutput.MultiViewEnable="Activa la vista múltiple"
AJAOutput.MultiViewAudioSource="Font d'àudio de visualització múltiple"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Výstup AJA I/O zařízení"
AJAOutput.ProgramOutput="Výstup programu"
AJAOutput.PreviewOutput="Náhled výstupu"
AJAOutput.MiscOutput="Další nastavení"
AJAOutput.MultiViewEnable="Povolit Multi View"
AJAOutput.MultiViewAudioSource="Zdroj zvuku pro Multi View"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA-I/O-Geräteausgabe"
AJAOutput.ProgramOutput="Programmausgabe"
AJAOutput.PreviewOutput="Vorschauausgabe"
AJAOutput.MiscOutput="Weitere Einstellungen"
AJAOutput.MultiViewEnable="Multiview aktivieren"
AJAOutput.MultiViewAudioSource="Multiview-Audioquelle"

View File

@ -0,0 +1 @@
#

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O Device Output"
AJAOutput.ProgramOutput="Program Output"
AJAOutput.PreviewOutput="Preview Output"
AJAOutput.MiscOutput="Additional Settings"
AJAOutput.MultiViewEnable="Enable Multi View"
AJAOutput.MultiViewAudioSource="Multi View Audio Source"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Dispositivo de salida AJA I/O"
AJAOutput.ProgramOutput="Salida de programa"
AJAOutput.PreviewOutput="Salida de vista previa"
AJAOutput.MiscOutput="Ajustes adicionales"
AJAOutput.MultiViewEnable="Habilitar vista múltiple"
AJAOutput.MultiViewAudioSource="Fuente de audio de la vista múltiple"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O seadme väljund"
AJAOutput.ProgramOutput="Programmi väljund"
AJAOutput.PreviewOutput="Eelvaate väljund"
AJAOutput.MiscOutput="Täiendavad seaded"
AJAOutput.MultiViewEnable="Lülita mitmikvaade sisse"
AJAOutput.MultiViewAudioSource="Mitmikvaate heliallikas"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="خروجی دستگاه و/خ AJA"
AJAOutput.ProgramOutput="خروجی برنامه"
AJAOutput.PreviewOutput="پیش نمایش خروجی"
AJAOutput.MiscOutput="تنظیمات اضافی"
AJAOutput.MultiViewEnable="فعال‌کردن نمای چندگانه"
AJAOutput.MultiViewAudioSource="منبع صوتی نمای چندگانه"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Sortie du périphérique d’entrée/sortie AJA"
AJAOutput.ProgramOutput="Sortie du programme"
AJAOutput.PreviewOutput="Aperçu de sortie"
AJAOutput.MiscOutput="Paramètres supplémentaires"
AJAOutput.MultiViewEnable="Activer la vue multiple"
AJAOutput.MultiViewAudioSource="Source Audio de la Vue Multiple"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Saída do dispositivo de E/S AJA"
AJAOutput.ProgramOutput="Saída do programa"
AJAOutput.PreviewOutput="Saída de vista previa"
AJAOutput.MiscOutput="Configuracions adiccionais"
AJAOutput.MultiViewEnable="Activar vistas múltiples"
AJAOutput.MultiViewAudioSource="Fonte de son da vista múltiple"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O eszközkimenet"
AJAOutput.ProgramOutput="Programkimenet"
AJAOutput.PreviewOutput="Előnézeti kimenet"
AJAOutput.MiscOutput="További beállítások"
AJAOutput.MultiViewEnable="Többszörös nézet engedélyezése"
AJAOutput.MultiViewAudioSource="Többszörös nézet hangforrása"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Perangkat Keluaran AJA I/O"
AJAOutput.ProgramOutput="Keluaran Program"
AJAOutput.PreviewOutput="Keluaran Pratinjau"
AJAOutput.MiscOutput="Pengaturan Tambahan"
AJAOutput.MultiViewEnable="Aktifkan Tampilan Ganda"
AJAOutput.MultiViewAudioSource="Tampilan Ganda Sumber Audio"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="I/O uscita dispositivo AJA"
AJAOutput.ProgramOutput="Output programma"
AJAOutput.PreviewOutput="Anteprima output"
AJAOutput.MiscOutput="Impostazioni aggiuntive"
AJAOutput.MultiViewEnable="Abilita visualizzazione multipla"
AJAOutput.MultiViewAudioSource="Sorgente audio multi visualizzazione"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/Oデバイス出力"
AJAOutput.ProgramOutput="プログラム出力"
AJAOutput.PreviewOutput="プレビュー出力"
AJAOutput.MiscOutput="追加設定"
AJAOutput.MultiViewEnable="マルチビューを有効にする"
AJAOutput.MultiViewAudioSource="マルチビュー 音声ソース"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA-I/O-მოწყობილობით გამოტანა"
AJAOutput.ProgramOutput="პროგრამის გამოტანა"
AJAOutput.PreviewOutput="შეთვალიერების გამოტანა"
AJAOutput.MiscOutput="დამატებითი პარამეტრები"
AJAOutput.MultiViewEnable="მრავალხედიანის ჩართვა"
AJAOutput.MultiViewAudioSource="მრავალხედიანი ხმოვანი წყარო"

View File

@ -0,0 +1 @@
AJAOutput.MiscOutput="Iɣewwaren nniḍen"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O 장치 출력"
AJAOutput.ProgramOutput="프로그램 출력"
AJAOutput.PreviewOutput="미리보기 출력"
AJAOutput.MiscOutput="추가 설정"
AJAOutput.MultiViewEnable="다중 화면 활성화"
AJAOutput.MultiViewAudioSource="다중 화면 오디오 소스"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Output Peranti AJA I/O"
AJAOutput.ProgramOutput="Output Program"
AJAOutput.PreviewOutput="Output Pratonton"
AJAOutput.MiscOutput="Tetapan Tambahan"
AJAOutput.MultiViewEnable="Benarkan Pandangan Berbilang"
AJAOutput.MultiViewAudioSource="Sumber Audio Pandangan Berbilang"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O Apparaat Uitvoer"
AJAOutput.ProgramOutput="Programma Uitvoer"
AJAOutput.PreviewOutput="Preview uitvoer"
AJAOutput.MiscOutput="Aanvullende instellingen"
AJAOutput.MultiViewEnable="Multi weergave inschakelen"
AJAOutput.MultiViewAudioSource="Multi weergave audiobron"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Wyjście AJA I/O"
AJAOutput.ProgramOutput="Wyjście aplikacji"
AJAOutput.PreviewOutput="Wyjście na podgląd"
AJAOutput.MiscOutput="Dodatkowe ustawienia"
AJAOutput.MultiViewEnable="Włącz Multiview"
AJAOutput.MultiViewAudioSource="Źródło dźwięku Multiview"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Saída do dispositivo I/O AJA"
AJAOutput.ProgramOutput="Saída do programa"
AJAOutput.PreviewOutput="Saída da pré-visualização"
AJAOutput.MiscOutput="Configurações adicionais"
AJAOutput.MultiViewEnable="Habilitar visualização múltipla"
AJAOutput.MultiViewAudioSource="Fonte de áudio da visualização múltipla"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Saída do dispositivo AJA I/O"
AJAOutput.ProgramOutput="Saída do programa"
AJAOutput.PreviewOutput="Saída da antevisão"
AJAOutput.MiscOutput="Definições adicionais"
AJAOutput.MultiViewEnable="Ativar multivisualização"
AJAOutput.MultiViewAudioSource="Fonte de áudio de multivisualização"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Устройство вывода AJA I/O"
AJAOutput.ProgramOutput="Вывод программы"
AJAOutput.PreviewOutput="Предпросмотр вывода"
AJAOutput.MiscOutput="Дополнительные настройки"
AJAOutput.MultiViewEnable="Включить мультипросмотр"
AJAOutput.MultiViewAudioSource="Мультипросмотр источника аудио"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="Výstup AJA I/O zariadenia"
AJAOutput.ProgramOutput="Výstup programu"
AJAOutput.PreviewOutput="Výstup náhľadu"
AJAOutput.MiscOutput="Ďalšie nastavenia"
AJAOutput.MultiViewEnable="Zapnúť Multi View"
AJAOutput.MultiViewAudioSource="Multi View zdroj zvuku"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="I/O-enhetsutmatning för AJA"
AJAOutput.ProgramOutput="Programutmatning"
AJAOutput.PreviewOutput="Förhandsvisningsutmatning"
AJAOutput.MiscOutput="Ytterligare inställningar"
AJAOutput.MultiViewEnable="Aktivera multivy"
AJAOutput.MultiViewAudioSource="Ljudkälla i multivy"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="เอาต์พุตอุปกรณ์ I/O ของ AJA"
AJAOutput.ProgramOutput="เอาต์พุตของโปรแกรม"
AJAOutput.PreviewOutput="แสดงตัวอย่างเอาต์พุต"
AJAOutput.MiscOutput="การตั้งค่าเพิ่มเติม"
AJAOutput.MultiViewEnable="เปิดใช้การแสดงผลหลายจอ"
AJAOutput.MultiViewAudioSource="แหล่งเสียงการแสดงผลหลายจอ"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O Cihaz Çıktısı"
AJAOutput.ProgramOutput="Program Çıktısı"
AJAOutput.PreviewOutput="Önizleme Çıktısı"
AJAOutput.MiscOutput="Ek Ayarlar"
AJAOutput.MultiViewEnable="Çoklu Görünümü Etkinleştir"
AJAOutput.MultiViewAudioSource="Çoklu Görünümlü Ses Kaynağı"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O ئۈسكۈنە چىقىرىش"
AJAOutput.ProgramOutput="پىروگرامما چىقىرىش"
AJAOutput.PreviewOutput="ئالدىن كۆزىتىش چىقىرىش"
AJAOutput.MiscOutput="قوشۇمچە تەڭشەك"
AJAOutput.MultiViewEnable="كۆپ كۆرۈنۈشنى قوزغات"
AJAOutput.MultiViewAudioSource="كۆپ كۆرۈنۈش ئۈن مەنبەسى"

View File

@ -0,0 +1,6 @@
AJAOutput.Device="AJA I/O 设备输出"
AJAOutput.ProgramOutput="程序输出"
AJAOutput.PreviewOutput="预览输出"
AJAOutput.MiscOutput="附加设置"
AJAOutput.MultiViewEnable="启用多视图"
AJAOutput.MultiViewAudioSource="音频源多视图"

Some files were not shown because too many files have changed in this diff Show More