mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-22 15:51:30 +11:00
Optimize and simplify Pixel AA, Average Fill, and Blur Fill presets (#467)
* Simplify pixel AA; Dependents to be refactored * Finish refactoring pixel_aa itself; Dependent presets TBD * Update average and border fill * Tune default blur strengths in blur fill * Clean up includes * Minor corrections
This commit is contained in:
parent
89530c1dec
commit
6f921ee481
|
@ -27,8 +27,8 @@ wrap_mode2 = mirrored_repeat
|
||||||
shader3 = shaders/blur_fill/render_sampling_areas.slang
|
shader3 = shaders/blur_fill/render_sampling_areas.slang
|
||||||
filter_linear3 = true
|
filter_linear3 = true
|
||||||
scale_type3 = source
|
scale_type3 = source
|
||||||
scale_x3 = 2.0
|
scale_x3 = 1.1
|
||||||
scale_y3 = 2.0
|
scale_y3 = 1.1
|
||||||
float_framebuffer3 = true
|
float_framebuffer3 = true
|
||||||
alias3 = "Tiled"
|
alias3 = "Tiled"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
shaders = 12
|
shaders = 12
|
||||||
|
|
||||||
parameters = "SIGMA;BLUR_RADIUS"
|
parameters = "SIGMA;BLUR_RADIUS"
|
||||||
SIGMA = 2.0
|
SIGMA = 1.5
|
||||||
BLUR_RADIUS = 3.0
|
BLUR_RADIUS = 3.0
|
||||||
|
|
||||||
shader0 = ../blurs/shaders/kawase/linearize.slang
|
shader0 = ../blurs/shaders/kawase/linearize.slang
|
||||||
|
@ -27,8 +27,8 @@ wrap_mode2 = mirrored_repeat
|
||||||
shader3 = shaders/blur_fill/render_sampling_areas.slang
|
shader3 = shaders/blur_fill/render_sampling_areas.slang
|
||||||
filter_linear3 = true
|
filter_linear3 = true
|
||||||
scale_type3 = source
|
scale_type3 = source
|
||||||
scale_x3 = 1.0
|
scale_x3 = 0.7
|
||||||
scale_y3 = 1.0
|
scale_y3 = 0.7
|
||||||
float_framebuffer3 = true
|
float_framebuffer3 = true
|
||||||
alias3 = "Tiled"
|
alias3 = "Tiled"
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@ wrap_mode2 = mirrored_repeat
|
||||||
shader3 = shaders/blur_fill/render_sampling_areas.slang
|
shader3 = shaders/blur_fill/render_sampling_areas.slang
|
||||||
filter_linear3 = true
|
filter_linear3 = true
|
||||||
scale_type3 = source
|
scale_type3 = source
|
||||||
scale_x3 = 3.0
|
scale_x3 = 2.0
|
||||||
scale_y3 = 3.0
|
scale_y3 = 2.0
|
||||||
float_framebuffer3 = true
|
float_framebuffer3 = true
|
||||||
alias3 = "Tiled"
|
alias3 = "Tiled"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Average fill v1.4 by fishku
|
Average fill v1.5 by fishku
|
||||||
Copyright (C) 2023
|
Copyright (C) 2023
|
||||||
Public domain license (CC0)
|
Public domain license (CC0)
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
3 = Smooth angle-based blending
|
3 = Smooth angle-based blending
|
||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
|
v1.5: Optimize. Update to new Pixel AA version.
|
||||||
v1.4: Add anti-aliased interpolation for non-integer scaling.
|
v1.4: Add anti-aliased interpolation for non-integer scaling.
|
||||||
v1.3: Fix scaling bugs.
|
v1.3: Fix scaling bugs.
|
||||||
v1.2: Fix scaling bugs.
|
v1.2: Fix scaling bugs.
|
||||||
|
@ -34,7 +35,10 @@
|
||||||
v1.0: Initial release.
|
v1.0: Initial release.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include "parameters.slang"
|
#include "parameters.slang"
|
||||||
|
#include "../../../interpolation/shaders/pixel_aa/shared.slang"
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
layout(push_constant) uniform Push {
|
layout(push_constant) uniform Push {
|
||||||
vec4 InputSize;
|
vec4 InputSize;
|
||||||
|
@ -69,14 +73,24 @@ global;
|
||||||
layout(location = 0) in vec4 Position;
|
layout(location = 0) in vec4 Position;
|
||||||
layout(location = 1) in vec2 TexCoord;
|
layout(location = 1) in vec2 TexCoord;
|
||||||
layout(location = 0) out vec2 vTexCoord;
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
layout(location = 1) out vec2 tx_coord;
|
||||||
|
layout(location = 2) out vec2 tx_per_px;
|
||||||
|
layout(location = 3) out vec2 tx_to_uv;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord;
|
vTexCoord = TexCoord;
|
||||||
|
const vec2 scale_o2i = scale_o2i();
|
||||||
|
tx_coord = (vTexCoord - 0.49999) * scale_o2i + get_input_center();
|
||||||
|
tx_per_px = scale_o2i * param.FinalViewportSize.zw;
|
||||||
|
tx_to_uv = param.InputSize.zw;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 1) in vec2 tx_coord;
|
||||||
|
layout(location = 2) in vec2 tx_per_px;
|
||||||
|
layout(location = 3) in vec2 tx_to_uv;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Input;
|
layout(set = 0, binding = 2) uniform sampler2D Input;
|
||||||
layout(set = 0, binding = 3) uniform sampler2D Top;
|
layout(set = 0, binding = 3) uniform sampler2D Top;
|
||||||
|
@ -122,20 +136,14 @@ vec3 blend_corner(vec3 a, // The first color to blend
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../../../interpolation/shaders/pixel_aa/shared.slang"
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
const vec2 scale_o2i = scale_o2i();
|
if (tx_coord.x < param.OS_CROP_LEFT) {
|
||||||
const vec2 pixel_coord =
|
|
||||||
(vTexCoord - 0.49999) * scale_o2i + get_input_center();
|
|
||||||
|
|
||||||
if (pixel_coord.x < param.OS_CROP_LEFT) {
|
|
||||||
if (param.EXTEND_H < 0.5) {
|
if (param.EXTEND_H < 0.5) {
|
||||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const vec3 left = textureLod(Left, vec2(0.5), BIG_NUMBER).rgb;
|
const vec3 left = textureLod(Left, vec2(0.5), BIG_NUMBER).rgb;
|
||||||
if (pixel_coord.y < param.OS_CROP_TOP) {
|
if (tx_coord.y < param.OS_CROP_TOP) {
|
||||||
if (param.EXTEND_V < 0.5) {
|
if (param.EXTEND_V < 0.5) {
|
||||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
return;
|
return;
|
||||||
|
@ -155,7 +163,7 @@ void main() {
|
||||||
viewport_corner - content_corner),
|
viewport_corner - content_corner),
|
||||||
1.0);
|
1.0);
|
||||||
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
||||||
} else if (pixel_coord.y < param.InputSize.y - param.OS_CROP_BOTTOM) {
|
} else if (tx_coord.y < param.InputSize.y - param.OS_CROP_BOTTOM) {
|
||||||
// Left bar
|
// Left bar
|
||||||
FragColor = vec4(pow(left, vec3(param.FILL_GAMMA)), 1.0);
|
FragColor = vec4(pow(left, vec3(param.FILL_GAMMA)), 1.0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -179,8 +187,8 @@ void main() {
|
||||||
1.0);
|
1.0);
|
||||||
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
||||||
}
|
}
|
||||||
} else if (pixel_coord.x < param.InputSize.x - param.OS_CROP_RIGHT) {
|
} else if (tx_coord.x < param.InputSize.x - param.OS_CROP_RIGHT) {
|
||||||
if (pixel_coord.y < param.OS_CROP_TOP) {
|
if (tx_coord.y < param.OS_CROP_TOP) {
|
||||||
if (param.EXTEND_V < 0.5) {
|
if (param.EXTEND_V < 0.5) {
|
||||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
return;
|
return;
|
||||||
|
@ -188,41 +196,22 @@ void main() {
|
||||||
// Top bar
|
// Top bar
|
||||||
FragColor = vec4(textureLod(Top, vec2(0.5), BIG_NUMBER).rgb, 1.0);
|
FragColor = vec4(textureLod(Top, vec2(0.5), BIG_NUMBER).rgb, 1.0);
|
||||||
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
||||||
} else if (pixel_coord.y < param.InputSize.y - param.OS_CROP_BOTTOM) {
|
} else if (tx_coord.y < param.InputSize.y - param.OS_CROP_BOTTOM) {
|
||||||
// Uncropped
|
// Uncropped
|
||||||
if (param.FORCE_INTEGER_SCALING > 0.5) {
|
if (param.FORCE_INTEGER_SCALING > 0.5) {
|
||||||
// Do a perfectly sharp (nearest neighbor) sampling.
|
// Do a perfectly sharp (nearest neighbor) sampling.
|
||||||
FragColor = vec4(texture(Input, (floor(pixel_coord) + 0.5) *
|
FragColor = vec4(
|
||||||
param.InputSize.zw)
|
texture(Input, (floor(tx_coord) + 0.5) * param.InputSize.zw)
|
||||||
.rgb,
|
.rgb,
|
||||||
1.0);
|
1.0);
|
||||||
} else {
|
} else {
|
||||||
// Do a sharp anti-aliased interpolation.
|
// Do a sharp anti-aliased interpolation.
|
||||||
// Do not correct for gamma additionally because the input is
|
// Do not correct for gamma additionally because the input is
|
||||||
// already in linear color space.
|
// already in linear color space.
|
||||||
if (param.PIX_AA_SUBPX < 0.5) {
|
FragColor = pixel_aa(
|
||||||
const vec2 tx_size = get_texel_size(pixel_coord) *
|
Input, tx_per_px, tx_to_uv, tx_coord, param.PIX_AA_SHARP,
|
||||||
scale_o2i * param.InputSize.zw;
|
/* gamma_correct = */ false, param.PIX_AA_SUBPX > 0.5,
|
||||||
FragColor =
|
param.PIX_AA_SUBPX_BGR > 0.5);
|
||||||
vec4(sample_aa(Input, pixel_coord, param.InputSize.zw,
|
|
||||||
false, param.PIX_AA_SHARP, tx_size),
|
|
||||||
1.0);
|
|
||||||
} else {
|
|
||||||
for (int i = -1; i < 2; ++i) {
|
|
||||||
const vec2 subpix_coord =
|
|
||||||
pixel_coord +
|
|
||||||
vec2((param.PIX_AA_SUBPX_BGR < 0.5 ? i : -i) / 3.0,
|
|
||||||
0.0) *
|
|
||||||
param.FinalViewportSize.zw * param.InputSize.xy;
|
|
||||||
const vec2 tx_size = get_texel_size(subpix_coord) *
|
|
||||||
scale_o2i * param.InputSize.zw /
|
|
||||||
vec2(3.0, 1.0);
|
|
||||||
FragColor[i + 1] = sample_aa(
|
|
||||||
Input, subpix_coord, param.InputSize.zw, false,
|
|
||||||
param.PIX_AA_SHARP, tx_size)[i + 1];
|
|
||||||
}
|
|
||||||
FragColor[3] = 1.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (param.EXTEND_V < 0.5) {
|
if (param.EXTEND_V < 0.5) {
|
||||||
|
@ -240,7 +229,7 @@ void main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const vec3 right = textureLod(Right, vec2(0.5), BIG_NUMBER).rgb;
|
const vec3 right = textureLod(Right, vec2(0.5), BIG_NUMBER).rgb;
|
||||||
if (pixel_coord.y < param.OS_CROP_TOP) {
|
if (tx_coord.y < param.OS_CROP_TOP) {
|
||||||
if (param.EXTEND_V < 0.5) {
|
if (param.EXTEND_V < 0.5) {
|
||||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
return;
|
return;
|
||||||
|
@ -260,7 +249,7 @@ void main() {
|
||||||
viewport_corner - content_corner),
|
viewport_corner - content_corner),
|
||||||
1.0);
|
1.0);
|
||||||
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
FragColor.rgb = pow(FragColor.rgb, vec3(param.FILL_GAMMA));
|
||||||
} else if (pixel_coord.y < param.InputSize.y - param.OS_CROP_BOTTOM) {
|
} else if (tx_coord.y < param.InputSize.y - param.OS_CROP_BOTTOM) {
|
||||||
// Right bar
|
// Right bar
|
||||||
FragColor = vec4(pow(right, vec3(param.FILL_GAMMA)), 1.0);
|
FragColor = vec4(pow(right, vec3(param.FILL_GAMMA)), 1.0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// See compose.slang for copyright and other information.
|
// See compose.slang for copyright and other information.
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#pragma parameter AVERAGE_FILL_SETTINGS "=== Average fill v1.4 settings ===" 0.0 0.0 1.0 1.0
|
#pragma parameter AVERAGE_FILL_SETTINGS "=== Average fill v1.5 settings ===" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter OS_CROP_TOP "Overscan crop top" 0.0 0.0 1024.0 1.0
|
#pragma parameter OS_CROP_TOP "Overscan crop top" 0.0 0.0 1024.0 1.0
|
||||||
#pragma parameter OS_CROP_BOTTOM "Overscan crop bottom" 0.0 0.0 1024.0 1.0
|
#pragma parameter OS_CROP_BOTTOM "Overscan crop bottom" 0.0 0.0 1024.0 1.0
|
||||||
#pragma parameter OS_CROP_LEFT "Overscan crop left" 0.0 0.0 1024.0 1.0
|
#pragma parameter OS_CROP_LEFT "Overscan crop left" 0.0 0.0 1024.0 1.0
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Blur fill v1.5 by fishku
|
Blur fill v1.6 by fishku
|
||||||
Copyright (C) 2023
|
Copyright (C) 2023
|
||||||
Public domain license (CC0)
|
Public domain license (CC0)
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
strength of the blur.
|
strength of the blur.
|
||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
|
v1.6: Optimize. Update to new Pixel AA version. Tune default blur strength.
|
||||||
v1.5: Add anti-aliased interpolation for non-integer scaling.
|
v1.5: Add anti-aliased interpolation for non-integer scaling.
|
||||||
v1.4: Fix scaling bugs.
|
v1.4: Fix scaling bugs.
|
||||||
v1.3: Reduce shimmering artifacts.
|
v1.3: Reduce shimmering artifacts.
|
||||||
|
@ -35,8 +36,11 @@
|
||||||
v1.0: Initial release.
|
v1.0: Initial release.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../../../blurs/shaders/dual_filter/parameters.slang"
|
// clang-format off
|
||||||
#include "parameters.slang"
|
#include "parameters.slang"
|
||||||
|
#include "../../../blurs/shaders/dual_filter/parameters.slang"
|
||||||
|
#include "../../../interpolation/shaders/pixel_aa/shared.slang"
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
layout(push_constant) uniform Push {
|
layout(push_constant) uniform Push {
|
||||||
vec4 InputSize;
|
vec4 InputSize;
|
||||||
|
@ -71,31 +75,37 @@ global;
|
||||||
layout(location = 0) in vec4 Position;
|
layout(location = 0) in vec4 Position;
|
||||||
layout(location = 1) in vec2 TexCoord;
|
layout(location = 1) in vec2 TexCoord;
|
||||||
layout(location = 0) out vec2 vTexCoord;
|
layout(location = 0) out vec2 vTexCoord;
|
||||||
|
layout(location = 1) out vec2 tx_coord;
|
||||||
|
layout(location = 2) out vec2 tx_per_px;
|
||||||
|
layout(location = 3) out vec2 tx_to_uv;
|
||||||
|
layout(location = 4) out vec4 input_extrema;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord;
|
vTexCoord = TexCoord;
|
||||||
|
const vec2 scale_o2i = scale_o2i();
|
||||||
|
tx_coord = (vTexCoord - 0.49999) * scale_o2i + get_input_center();
|
||||||
|
tx_per_px = scale_o2i * param.FinalViewportSize.zw;
|
||||||
|
tx_to_uv = param.InputSize.zw;
|
||||||
|
input_extrema = vec4(param.OS_CROP_LEFT, param.OS_CROP_TOP,
|
||||||
|
param.InputSize.x - param.OS_CROP_RIGHT,
|
||||||
|
param.InputSize.y - param.OS_CROP_BOTTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 vTexCoord;
|
||||||
|
layout(location = 1) in vec2 tx_coord;
|
||||||
|
layout(location = 2) in vec2 tx_per_px;
|
||||||
|
layout(location = 3) in vec2 tx_to_uv;
|
||||||
|
layout(location = 4) in vec4 input_extrema;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Input;
|
layout(set = 0, binding = 2) uniform sampler2D Input;
|
||||||
layout(set = 0, binding = 3) uniform sampler2D Tiled;
|
layout(set = 0, binding = 3) uniform sampler2D Tiled;
|
||||||
layout(set = 0, binding = 4) uniform sampler2D Blurred;
|
layout(set = 0, binding = 4) uniform sampler2D Blurred;
|
||||||
|
|
||||||
#include "../../../interpolation/shaders/pixel_aa/shared.slang"
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
const vec2 scale_o2i = scale_o2i();
|
if (any(lessThan(tx_coord, input_extrema.xy)) ||
|
||||||
const vec2 pixel_coord =
|
any(greaterThanEqual(tx_coord, input_extrema.zw))) {
|
||||||
(vTexCoord - 0.49999) * scale_o2i + get_input_center();
|
|
||||||
|
|
||||||
const vec4 input_extrema = vec4(param.OS_CROP_LEFT, param.OS_CROP_TOP,
|
|
||||||
param.InputSize.x - param.OS_CROP_RIGHT,
|
|
||||||
param.InputSize.y - param.OS_CROP_BOTTOM);
|
|
||||||
if (any(lessThan(pixel_coord, input_extrema.xy)) ||
|
|
||||||
any(greaterThanEqual(pixel_coord, input_extrema.zw))) {
|
|
||||||
if (param.BLUR_RADIUS > 0.0) {
|
if (param.BLUR_RADIUS > 0.0) {
|
||||||
// Sample blur.
|
// Sample blur.
|
||||||
FragColor = vec4(
|
FragColor = vec4(
|
||||||
|
@ -117,36 +127,17 @@ void main() {
|
||||||
if (param.FORCE_INTEGER_SCALING > 0.5) {
|
if (param.FORCE_INTEGER_SCALING > 0.5) {
|
||||||
// Do a perfectly sharp (nearest neighbor) sampling.
|
// Do a perfectly sharp (nearest neighbor) sampling.
|
||||||
FragColor = vec4(
|
FragColor = vec4(
|
||||||
texture(Input, (floor(pixel_coord) + 0.5) * param.InputSize.zw)
|
texture(Input, (floor(tx_coord) + 0.5) * param.InputSize.zw)
|
||||||
.rgb,
|
.rgb,
|
||||||
1.0);
|
1.0);
|
||||||
} else {
|
} else {
|
||||||
// Do a sharp anti-aliased interpolation.
|
// Do a sharp anti-aliased interpolation.
|
||||||
// Do not correct for gamma additionally because the input is
|
// Do not correct for gamma additionally because the input is
|
||||||
// already in linear color space.
|
// already in linear color space.
|
||||||
if (param.PIX_AA_SUBPX < 0.5) {
|
FragColor = pixel_aa(
|
||||||
const vec2 tx_size = get_texel_size(pixel_coord) * scale_o2i *
|
Input, tx_per_px, tx_to_uv, tx_coord, param.PIX_AA_SHARP,
|
||||||
param.InputSize.zw;
|
/* gamma_correct = */ false, param.PIX_AA_SUBPX > 0.5,
|
||||||
FragColor =
|
param.PIX_AA_SUBPX_BGR > 0.5);
|
||||||
vec4(sample_aa(Input, pixel_coord, param.InputSize.zw,
|
|
||||||
false, param.PIX_AA_SHARP, tx_size),
|
|
||||||
1.0);
|
|
||||||
} else {
|
|
||||||
for (int i = -1; i < 2; ++i) {
|
|
||||||
const vec2 subpix_coord =
|
|
||||||
pixel_coord +
|
|
||||||
vec2((param.PIX_AA_SUBPX_BGR < 0.5 ? i : -i) / 3.0,
|
|
||||||
0.0) *
|
|
||||||
param.FinalViewportSize.zw * param.InputSize.xy;
|
|
||||||
const vec2 tx_size = get_texel_size(subpix_coord) *
|
|
||||||
scale_o2i * param.InputSize.zw /
|
|
||||||
vec2(3.0, 1.0);
|
|
||||||
FragColor[i + 1] =
|
|
||||||
sample_aa(Input, subpix_coord, param.InputSize.zw,
|
|
||||||
false, param.PIX_AA_SHARP, tx_size)[i + 1];
|
|
||||||
}
|
|
||||||
FragColor[3] = 1.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// See compose.slang for copyright and other information.
|
// See compose.slang for copyright and other information.
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#pragma parameter BLUR_FILL_SETTINGS "=== Blur fill v1.5 settings ===" 0.0 0.0 1.0 1.0
|
#pragma parameter BLUR_FILL_SETTINGS "=== Blur fill v1.6 settings ===" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter OS_CROP_TOP "Overscan crop top" 0.0 0.0 1024.0 1.0
|
#pragma parameter OS_CROP_TOP "Overscan crop top" 0.0 0.0 1024.0 1.0
|
||||||
#pragma parameter OS_CROP_BOTTOM "Overscan crop bottom" 0.0 0.0 1024.0 1.0
|
#pragma parameter OS_CROP_BOTTOM "Overscan crop bottom" 0.0 0.0 1024.0 1.0
|
||||||
#pragma parameter OS_CROP_LEFT "Overscan crop left" 0.0 0.0 1024.0 1.0
|
#pragma parameter OS_CROP_LEFT "Overscan crop left" 0.0 0.0 1024.0 1.0
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Pixel AA v1.1 by fishku
|
Pixel AA v1.2 by fishku
|
||||||
Copyright (C) 2023
|
Copyright (C) 2023
|
||||||
Public domain license (CC0)
|
Public domain license (CC0)
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
subpixel anti-aliasing, results are identical to the "pixellate" shader.
|
subpixel anti-aliasing, results are identical to the "pixellate" shader.
|
||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
|
v1.2: Optimize and simplify algorithm. Enable sharpness < 1.0. Fix subpixel
|
||||||
|
sampling bug.
|
||||||
v1.1: Better subpixel sampling.
|
v1.1: Better subpixel sampling.
|
||||||
v1.0: Initial release.
|
v1.0: Initial release.
|
||||||
*/
|
*/
|
||||||
|
@ -44,44 +46,29 @@ global;
|
||||||
#pragma stage vertex
|
#pragma stage vertex
|
||||||
layout(location = 0) in vec4 Position;
|
layout(location = 0) in vec4 Position;
|
||||||
layout(location = 1) in vec2 TexCoord;
|
layout(location = 1) in vec2 TexCoord;
|
||||||
layout(location = 0) out vec2 vTexCoord;
|
layout(location = 0) out vec2 tx_coord;
|
||||||
layout(location = 1) out vec2 pix_coord;
|
layout(location = 1) out vec2 tx_per_px;
|
||||||
|
layout(location = 2) out vec2 tx_to_uv;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = global.MVP * Position;
|
gl_Position = global.MVP * Position;
|
||||||
vTexCoord = TexCoord;
|
tx_coord = TexCoord * param.SourceSize.xy;
|
||||||
pix_coord = vTexCoord * param.SourceSize.xy;
|
tx_per_px = param.SourceSize.xy * param.OutputSize.zw;
|
||||||
|
tx_to_uv = param.SourceSize.zw;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma stage fragment
|
#pragma stage fragment
|
||||||
layout(location = 0) in vec2 vTexCoord;
|
layout(location = 0) in vec2 tx_coord;
|
||||||
layout(location = 1) in vec2 pix_coord;
|
layout(location = 1) in vec2 tx_per_px;
|
||||||
|
layout(location = 2) in vec2 tx_to_uv;
|
||||||
layout(location = 0) out vec4 FragColor;
|
layout(location = 0) out vec4 FragColor;
|
||||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||||
|
|
||||||
#include "shared.slang"
|
#include "shared.slang"
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
if (param.PIX_AA_SUBPX < 0.5) {
|
FragColor =
|
||||||
FragColor =
|
pixel_aa(Source, tx_per_px, tx_to_uv, tx_coord, param.PIX_AA_SHARP,
|
||||||
vec4(sample_aa(Source, pix_coord, param.SourceSize.zw,
|
param.PIX_AA_GAMMA > 0.5, param.PIX_AA_SUBPX > 0.5,
|
||||||
param.PIX_AA_GAMMA > 0.5, param.PIX_AA_SHARP),
|
param.PIX_AA_SUBPX_BGR > 0.5);
|
||||||
1.0);
|
|
||||||
} else {
|
|
||||||
// Subpixel sampling: Shift the sampling by 1/3rd of an output pixel,
|
|
||||||
// assuming that the output size is at monitor resolution.
|
|
||||||
for (int i = -1; i < 2; ++i) {
|
|
||||||
const vec2 subpix_coord =
|
|
||||||
pix_coord +
|
|
||||||
vec2((param.PIX_AA_SUBPX_BGR < 0.5 ? i : -i) / 3.0, 0.0) *
|
|
||||||
param.OutputSize.zw * param.SourceSize.xy;
|
|
||||||
// With subpixel sampling, the sampling area is effectively reduced
|
|
||||||
// to a third.
|
|
||||||
const vec2 tx_size = get_texel_size(subpix_coord) / vec2(3.0, 1.0);
|
|
||||||
FragColor[i + 1] = sample_aa(
|
|
||||||
Source, subpix_coord, param.SourceSize.zw,
|
|
||||||
param.PIX_AA_GAMMA > 0.5, param.PIX_AA_SHARP, tx_size)[i + 1];
|
|
||||||
}
|
|
||||||
FragColor[3] = 1.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
// This file has to be included at the frag shader stage so that fwidth() is
|
// See pixel_aa.slang for copyright and other information.
|
||||||
// defined.
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#pragma parameter PIX_AA_SETTINGS "=== Pixel AA v1.1 settings ===" 0.0 0.0 1.0 1.0
|
#pragma parameter PIX_AA_SETTINGS "=== Pixel AA v1.2 settings ===" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter PIX_AA_SHARP "Pixel AA sharpening amount" 1.0 1.0 4.0 0.05
|
#pragma parameter PIX_AA_SHARP "Pixel AA sharpening amount" 1.5 0.0 2.0 0.05
|
||||||
#pragma parameter PIX_AA_GAMMA "Enable gamma-correct blending" 1.0 0.0 1.0 1.0
|
#pragma parameter PIX_AA_GAMMA "Enable gamma-correct blending" 1.0 0.0 1.0 1.0
|
||||||
#pragma parameter PIX_AA_SUBPX "Enable subpixel AA" 0.0 0.0 1.0 1.0
|
#pragma parameter PIX_AA_SUBPX "Enable subpixel AA" 0.0 0.0 1.0 1.0
|
||||||
#pragma parameter PIX_AA_SUBPX_BGR "Use BGR subpx. instead of RGB" 0.0 0.0 1.0 1.0
|
#pragma parameter PIX_AA_SUBPX_BGR "Use BGR subpx. instead of RGB" 0.0 0.0 1.0 1.0
|
||||||
|
@ -25,40 +24,65 @@ vec3 to_lin(vec3 x) { return pow(x, vec3(2.2)); }
|
||||||
|
|
||||||
vec3 to_srgb(vec3 x) { return pow(x, vec3(1.0 / 2.2)); }
|
vec3 to_srgb(vec3 x) { return pow(x, vec3(1.0 / 2.2)); }
|
||||||
|
|
||||||
vec2 get_texel_size(vec2 pix_coord) {
|
// Function to get a single sample using the "pixel AA" method.
|
||||||
return clamp(fwidth(pix_coord), 1.0e-5, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Params:
|
// Params:
|
||||||
// pix_coord: Coordinate in source pixel coordinates
|
// tx_coord: Coordinate in source pixel (texel) coordinates
|
||||||
// px_size_uv: 1 / source resolution
|
vec3 sample_aa(sampler2D tex, vec2 tx_per_px, vec2 tx_to_uv, vec2 tx_coord,
|
||||||
vec3 sample_aa(sampler2D tex, vec2 pix_coord, vec2 px_size_uv,
|
float sharpness, bool gamma_correct) {
|
||||||
bool gamma_correct, float sharpness, vec2 tx_size) {
|
// The offset for interpolation is a periodic function with
|
||||||
const vec2 tx_coord = pix_coord - 0.5 * tx_size;
|
// a period length of 1 texel.
|
||||||
const vec2 tx_coord_i = floor(tx_coord);
|
// The input coordinate is shifted so that the center of the texel
|
||||||
const vec2 tx_offset =
|
// aligns with the start of the period.
|
||||||
slopestep(1.0 - tx_size, vec2(1.0), fract(tx_coord), sharpness);
|
// First, get the period and phase.
|
||||||
// With gamma correct blending, we have to do 4 taps and blend manually.
|
vec2 period;
|
||||||
// Without it, we can make use of a single tap using bilinear interpolation.
|
const vec2 phase = modf(tx_coord - 0.5, period);
|
||||||
|
// The function starts at 0, then starts transitioning at
|
||||||
|
// 0.5 - 0.5 / pixels_per_texel, then reaches 0.5 at 0.5,
|
||||||
|
// Then reaches 1 at 0.5 + 0.5 / pixels_per_texel.
|
||||||
|
// For sharpness values < 1.0, blend to bilinear filtering.
|
||||||
|
const vec2 offset =
|
||||||
|
slopestep(min(1.0, sharpness) * (0.5 - 0.5 * tx_per_px),
|
||||||
|
1.0 - min(1.0, sharpness) * (1.0 - (0.5 + 0.5 * tx_per_px)),
|
||||||
|
phase, max(1.0, sharpness));
|
||||||
|
|
||||||
|
// With gamma correct blending, we have to do 4 taps and interpolate
|
||||||
|
// manually. Without it, we can make use of a single tap using bilinear
|
||||||
|
// interpolation. The offsets are shifted back to the texel center before
|
||||||
|
// sampling.
|
||||||
if (gamma_correct) {
|
if (gamma_correct) {
|
||||||
const vec3 samples[] = {
|
const vec3 samples[] = {
|
||||||
to_lin(texture(tex, (tx_coord_i + 0.5) * px_size_uv).rgb),
|
to_lin(texture(tex, (period + 0.5) * tx_to_uv).rgb),
|
||||||
to_lin(
|
to_lin(texture(tex, (period + vec2(1.5, 0.5)) * tx_to_uv).rgb),
|
||||||
texture(tex, (tx_coord_i + vec2(1.5, 0.5)) * px_size_uv).rgb),
|
to_lin(texture(tex, (period + vec2(0.5, 1.5)) * tx_to_uv).rgb),
|
||||||
to_lin(
|
to_lin(texture(tex, (period + 1.5) * tx_to_uv).rgb)};
|
||||||
texture(tex, (tx_coord_i + vec2(0.5, 1.5)) * px_size_uv).rgb),
|
return to_srgb(mix(mix(samples[0], samples[1], offset.x),
|
||||||
to_lin(texture(tex, (tx_coord_i + 1.5) * px_size_uv).rgb)};
|
mix(samples[2], samples[3], offset.x), offset.y));
|
||||||
return to_srgb(mix(mix(samples[0], samples[1], tx_offset.x),
|
|
||||||
mix(samples[2], samples[3], tx_offset.x),
|
|
||||||
tx_offset.y));
|
|
||||||
} else {
|
} else {
|
||||||
return texture(tex, (tx_coord_i + 0.5 + tx_offset) * px_size_uv).rgb;
|
return texture(tex, (period + 0.5 + offset) * tx_to_uv).rgb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 sample_aa(sampler2D tex, vec2 pix_coord, vec2 px_size_uv,
|
// Function to get a pixel value, taking into consideration possible subpixel
|
||||||
bool gamma_correct, float sharpness) {
|
// interpolation.
|
||||||
const vec2 tx_size = get_texel_size(pix_coord);
|
vec4 pixel_aa(sampler2D tex, vec2 tx_per_px, vec2 tx_to_uv, vec2 tx_coord,
|
||||||
return sample_aa(tex, pix_coord, px_size_uv, gamma_correct, sharpness,
|
float sharpness, bool gamma_correct, bool sample_subpx,
|
||||||
tx_size);
|
bool subpx_bgr) {
|
||||||
|
if (sample_subpx) {
|
||||||
|
// Subpixel sampling: Shift the sampling by 1/3rd of an output pixel for
|
||||||
|
// each subpixel, assuming that the output size is at monitor
|
||||||
|
// resolution.
|
||||||
|
const vec2 sub_tx_offset =
|
||||||
|
vec2(tx_per_px.x / 3.0 * (subpx_bgr ? -1.0 : 1.0), 0.0);
|
||||||
|
vec3 res;
|
||||||
|
for (int i = -1; i < 2; ++i) {
|
||||||
|
res[i + 1] = sample_aa(tex, tx_per_px, tx_to_uv,
|
||||||
|
tx_coord + sub_tx_offset * float(i),
|
||||||
|
sharpness, gamma_correct)[i + 1];
|
||||||
|
}
|
||||||
|
return vec4(res, 1.0);
|
||||||
|
} else {
|
||||||
|
return vec4(sample_aa(tex, tx_per_px, tx_to_uv, tx_coord, sharpness,
|
||||||
|
gamma_correct),
|
||||||
|
1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue