This commit is contained in:
2026-03-27 07:06:16 +01:00
commit 1541961403
340 changed files with 151916 additions and 0 deletions
+235
View File
@@ -0,0 +1,235 @@
// MIT License
// Copyright (c) 2023 João Chrisóstomo
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//!PARAM chroma_offset_x
//!TYPE float
0.0
//!PARAM chroma_offset_y
//!TYPE float
0.0
//!HOOK CHROMA
//!BIND LUMA
//!BIND CHROMA
//!SAVE LUMA_LR
//!WIDTH CHROMA.w
//!HEIGHT LUMA.h
//!WHEN CHROMA.w LUMA.w <
//!DESC Joint Bilateral (Hermite 1st step, Downscaling Luma)
float comp_wd(vec2 v) {
float x = min(length(v), 1.0);
return smoothstep(0.0, 1.0, 1.0 - x);
}
vec4 hook() {
vec2 luma_pos = LUMA_pos;
luma_pos.x += chroma_offset_x / LUMA_size.x;
float start = ceil((luma_pos.x - (1.0 / CHROMA_size.x)) * LUMA_size.x - 0.5);
float end = floor((luma_pos.x + (1.0 / CHROMA_size.x)) * LUMA_size.x - 0.5);
float wt = 0.0;
float luma_sum = 0.0;
vec2 pos = luma_pos;
for (float dx = start.x; dx <= end.x; dx++) {
pos.x = LUMA_pt.x * (dx + 0.5);
vec2 dist = (pos - luma_pos) * CHROMA_size;
float wd = comp_wd(dist);
float luma_pix = LUMA_tex(pos).x;
luma_sum += wd * luma_pix;
wt += wd;
}
vec4 output_pix = vec4(luma_sum /= wt, 0.0, 0.0, 1.0);
return clamp(output_pix, 0.0, 1.0);
}
//!HOOK CHROMA
//!BIND LUMA_LR
//!BIND CHROMA
//!BIND LUMA
//!SAVE LUMA_LR
//!WIDTH CHROMA.w
//!HEIGHT CHROMA.h
//!WHEN CHROMA.w LUMA.w <
//!DESC Joint Bilateral (Hermite 2nd step, Downscaling Luma)
float comp_wd(vec2 v) {
float x = min(length(v), 1.0);
return smoothstep(0.0, 1.0, 1.0 - x);
}
vec4 hook() {
vec2 luma_pos = LUMA_LR_pos;
luma_pos.y += chroma_offset_y / LUMA_LR_size.y;
float start = ceil((luma_pos.y - (1.0 / CHROMA_size.y)) * LUMA_LR_size.y - 0.5);
float end = floor((luma_pos.y + (1.0 / CHROMA_size.y)) * LUMA_LR_size.y - 0.5);
float wt = 0.0;
float luma_sum = 0.0;
vec2 pos = luma_pos;
for (float dy = start; dy <= end; dy++) {
pos.y = LUMA_LR_pt.y * (dy + 0.5);
vec2 dist = (pos - luma_pos) * CHROMA_size;
float wd = comp_wd(dist);
float luma_pix = LUMA_LR_tex(pos).x;
luma_sum += wd * luma_pix;
wt += wd;
}
vec4 output_pix = vec4(luma_sum /= wt, 0.0, 0.0, 1.0);
return clamp(output_pix, 0.0, 1.0);
}
//!PARAM distance_coeff
//!TYPE float
//!MINIMUM 0.0
2.0
//!PARAM intensity_coeff
//!TYPE float
//!MINIMUM 0.0
128.0
//!HOOK CHROMA
//!BIND LUMA
//!BIND LUMA_LR
//!BIND HOOKED
//!WIDTH LUMA.w
//!HEIGHT LUMA.h
//!WHEN CHROMA.w LUMA.w <
//!OFFSET ALIGN
//!DESC Joint Bilateral (Upscaling Chroma)
float comp_w(vec2 spatial_distance, float intensity_distance) {
return max(100.0 * exp(-distance_coeff * pow(length(spatial_distance), 2.0) - intensity_coeff * pow(intensity_distance, 2.0)), 1e-32);
}
vec4 hook() {
float luma_zero = LUMA_texOff(0.0).x;
vec4 output_pix = vec4(0.0, 0.0, 0.0, 1.0);
vec2 pp = HOOKED_pos * HOOKED_size - vec2(0.5);
vec2 fp = floor(pp);
pp -= fp;
#ifdef HOOKED_gather
vec4 chroma_quads[4][2];
chroma_quads[0][0] = HOOKED_gather(vec2((fp + vec2(0.0, 0.0)) * HOOKED_pt), 0);
chroma_quads[1][0] = HOOKED_gather(vec2((fp + vec2(2.0, 0.0)) * HOOKED_pt), 0);
chroma_quads[2][0] = HOOKED_gather(vec2((fp + vec2(0.0, 2.0)) * HOOKED_pt), 0);
chroma_quads[3][0] = HOOKED_gather(vec2((fp + vec2(2.0, 2.0)) * HOOKED_pt), 0);
chroma_quads[0][1] = HOOKED_gather(vec2((fp + vec2(0.0, 0.0)) * HOOKED_pt), 1);
chroma_quads[1][1] = HOOKED_gather(vec2((fp + vec2(2.0, 0.0)) * HOOKED_pt), 1);
chroma_quads[2][1] = HOOKED_gather(vec2((fp + vec2(0.0, 2.0)) * HOOKED_pt), 1);
chroma_quads[3][1] = HOOKED_gather(vec2((fp + vec2(2.0, 2.0)) * HOOKED_pt), 1);
vec2 chroma_pixels[12];
chroma_pixels[0] = vec2(chroma_quads[0][0].z, chroma_quads[0][1].z);
chroma_pixels[1] = vec2(chroma_quads[1][0].w, chroma_quads[1][1].w);
chroma_pixels[2] = vec2(chroma_quads[0][0].x, chroma_quads[0][1].x);
chroma_pixels[3] = vec2(chroma_quads[0][0].y, chroma_quads[0][1].y);
chroma_pixels[4] = vec2(chroma_quads[1][0].x, chroma_quads[1][1].x);
chroma_pixels[5] = vec2(chroma_quads[1][0].y, chroma_quads[1][1].y);
chroma_pixels[6] = vec2(chroma_quads[2][0].w, chroma_quads[2][1].w);
chroma_pixels[7] = vec2(chroma_quads[2][0].z, chroma_quads[2][1].z);
chroma_pixels[8] = vec2(chroma_quads[3][0].w, chroma_quads[3][1].w);
chroma_pixels[9] = vec2(chroma_quads[3][0].z, chroma_quads[3][1].z);
chroma_pixels[10] = vec2(chroma_quads[2][0].y, chroma_quads[2][1].y);
chroma_pixels[11] = vec2(chroma_quads[3][0].x, chroma_quads[3][1].x);
vec4 luma_quads[4];
luma_quads[0] = LUMA_LR_gather(vec2((fp + vec2(0.0, 0.0)) * HOOKED_pt), 0);
luma_quads[1] = LUMA_LR_gather(vec2((fp + vec2(2.0, 0.0)) * HOOKED_pt), 0);
luma_quads[2] = LUMA_LR_gather(vec2((fp + vec2(0.0, 2.0)) * HOOKED_pt), 0);
luma_quads[3] = LUMA_LR_gather(vec2((fp + vec2(2.0, 2.0)) * HOOKED_pt), 0);
float luma_pixels[12];
luma_pixels[0] = luma_quads[0].z;
luma_pixels[1] = luma_quads[1].w;
luma_pixels[2] = luma_quads[0].x;
luma_pixels[3] = luma_quads[0].y;
luma_pixels[4] = luma_quads[1].x;
luma_pixels[5] = luma_quads[1].y;
luma_pixels[6] = luma_quads[2].w;
luma_pixels[7] = luma_quads[2].z;
luma_pixels[8] = luma_quads[3].w;
luma_pixels[9] = luma_quads[3].z;
luma_pixels[10] = luma_quads[2].y;
luma_pixels[11] = luma_quads[3].x;
#else
vec2 chroma_pixels[12];
chroma_pixels[0] = HOOKED_tex(vec2((fp + vec2(0.5, -0.5)) * HOOKED_pt)).xy;
chroma_pixels[1] = HOOKED_tex(vec2((fp + vec2(1.5, -0.5)) * HOOKED_pt)).xy;
chroma_pixels[2] = HOOKED_tex(vec2((fp + vec2(-0.5, 0.5)) * HOOKED_pt)).xy;
chroma_pixels[3] = HOOKED_tex(vec2((fp + vec2( 0.5, 0.5)) * HOOKED_pt)).xy;
chroma_pixels[4] = HOOKED_tex(vec2((fp + vec2( 1.5, 0.5)) * HOOKED_pt)).xy;
chroma_pixels[5] = HOOKED_tex(vec2((fp + vec2( 2.5, 0.5)) * HOOKED_pt)).xy;
chroma_pixels[6] = HOOKED_tex(vec2((fp + vec2(-0.5, 1.5)) * HOOKED_pt)).xy;
chroma_pixels[7] = HOOKED_tex(vec2((fp + vec2( 0.5, 1.5)) * HOOKED_pt)).xy;
chroma_pixels[8] = HOOKED_tex(vec2((fp + vec2( 1.5, 1.5)) * HOOKED_pt)).xy;
chroma_pixels[9] = HOOKED_tex(vec2((fp + vec2( 2.5, 1.5)) * HOOKED_pt)).xy;
chroma_pixels[10] = HOOKED_tex(vec2((fp + vec2( 0.5, 2.5)) * HOOKED_pt)).xy;
chroma_pixels[11] = HOOKED_tex(vec2((fp + vec2( 1.5, 2.5)) * HOOKED_pt)).xy;
float luma_pixels[12];
luma_pixels[0] = LUMA_LR_tex(vec2((fp + vec2(0.5, -0.5)) * HOOKED_pt)).x;
luma_pixels[1] = LUMA_LR_tex(vec2((fp + vec2(1.5, -0.5)) * HOOKED_pt)).x;
luma_pixels[2] = LUMA_LR_tex(vec2((fp + vec2(-0.5, 0.5)) * HOOKED_pt)).x;
luma_pixels[3] = LUMA_LR_tex(vec2((fp + vec2( 0.5, 0.5)) * HOOKED_pt)).x;
luma_pixels[4] = LUMA_LR_tex(vec2((fp + vec2( 1.5, 0.5)) * HOOKED_pt)).x;
luma_pixels[5] = LUMA_LR_tex(vec2((fp + vec2( 2.5, 0.5)) * HOOKED_pt)).x;
luma_pixels[6] = LUMA_LR_tex(vec2((fp + vec2(-0.5, 1.5)) * HOOKED_pt)).x;
luma_pixels[7] = LUMA_LR_tex(vec2((fp + vec2( 0.5, 1.5)) * HOOKED_pt)).x;
luma_pixels[8] = LUMA_LR_tex(vec2((fp + vec2( 1.5, 1.5)) * HOOKED_pt)).x;
luma_pixels[9] = LUMA_LR_tex(vec2((fp + vec2( 2.5, 1.5)) * HOOKED_pt)).x;
luma_pixels[10] = LUMA_LR_tex(vec2((fp + vec2( 0.5, 2.5)) * HOOKED_pt)).x;
luma_pixels[11] = LUMA_LR_tex(vec2((fp + vec2( 1.5, 2.5)) * HOOKED_pt)).x;
#endif
float w[12];
w[0] = comp_w(vec2( 0.0,-1.0) - pp, luma_zero - luma_pixels[0] );
w[1] = comp_w(vec2( 1.0,-1.0) - pp, luma_zero - luma_pixels[1] );
w[2] = comp_w(vec2(-1.0, 0.0) - pp, luma_zero - luma_pixels[2] );
w[3] = comp_w(vec2( 0.0, 0.0) - pp, luma_zero - luma_pixels[3] );
w[4] = comp_w(vec2( 1.0, 0.0) - pp, luma_zero - luma_pixels[4] );
w[5] = comp_w(vec2( 2.0, 0.0) - pp, luma_zero - luma_pixels[5] );
w[6] = comp_w(vec2(-1.0, 1.0) - pp, luma_zero - luma_pixels[6] );
w[7] = comp_w(vec2( 0.0, 1.0) - pp, luma_zero - luma_pixels[7] );
w[8] = comp_w(vec2( 1.0, 1.0) - pp, luma_zero - luma_pixels[8] );
w[9] = comp_w(vec2( 2.0, 1.0) - pp, luma_zero - luma_pixels[9] );
w[10] = comp_w(vec2( 0.0, 2.0) - pp, luma_zero - luma_pixels[10]);
w[11] = comp_w(vec2( 1.0, 2.0) - pp, luma_zero - luma_pixels[11]);
float wt = 0.0;
vec2 ct = vec2(0.0);
for (int i = 0; i < 12; i++) {
wt += w[i];
ct += w[i] * chroma_pixels[i];
}
output_pix.xy = clamp(ct / wt, 0.0, 1.0);
return output_pix;
}
+186
View File
@@ -0,0 +1,186 @@
// MIT License
// Copyright (c) 2023 João Chrisóstomo
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//!HOOK POSTKERNEL
//!BIND POSTKERNEL
//!BIND PREKERNEL
//!DESC Pixel Clipper (Upscaling AR)
//!WHEN POSTKERNEL.w PREKERNEL.w / 1.000 > POSTKERNEL.h PREKERNEL.h / 1.000 > *
#define TWELVE_TAP_AR 0
const float strength = 0.8;
vec4 hook() {
vec2 pp = PREKERNEL_pos * PREKERNEL_size - vec2(0.5);
vec2 fp = floor(pp);
vec4 f = PREKERNEL_tex(vec2((fp + vec2( 0.5, 0.5)) * PREKERNEL_pt));
vec4 g = PREKERNEL_tex(vec2((fp + vec2( 1.5, 0.5)) * PREKERNEL_pt));
vec4 j = PREKERNEL_tex(vec2((fp + vec2( 0.5, 1.5)) * PREKERNEL_pt));
vec4 k = PREKERNEL_tex(vec2((fp + vec2( 1.5, 1.5)) * PREKERNEL_pt));
#if (TWELVE_TAP_AR == 1)
vec4 b = PREKERNEL_tex(vec2((fp + vec2(0.5, -0.5)) * PREKERNEL_pt));
vec4 c = PREKERNEL_tex(vec2((fp + vec2(1.5, -0.5)) * PREKERNEL_pt));
vec4 e = PREKERNEL_tex(vec2((fp + vec2(-0.5, 0.5)) * PREKERNEL_pt));
vec4 h = PREKERNEL_tex(vec2((fp + vec2( 2.5, 0.5)) * PREKERNEL_pt));
vec4 i = PREKERNEL_tex(vec2((fp + vec2(-0.5, 1.5)) * PREKERNEL_pt));
vec4 l = PREKERNEL_tex(vec2((fp + vec2( 2.5, 1.5)) * PREKERNEL_pt));
vec4 n = PREKERNEL_tex(vec2((fp + vec2(0.5, 2.5) ) * PREKERNEL_pt));
vec4 o = PREKERNEL_tex(vec2((fp + vec2(1.5, 2.5) ) * PREKERNEL_pt));
#endif
vec4 min_pix = vec4(1e8);
min_pix = min(min_pix, f);
min_pix = min(min_pix, g);
min_pix = min(min_pix, j);
min_pix = min(min_pix, k);
#if (TWELVE_TAP_AR == 1)
min_pix = min(min_pix, b);
min_pix = min(min_pix, c);
min_pix = min(min_pix, e);
min_pix = min(min_pix, h);
min_pix = min(min_pix, i);
min_pix = min(min_pix, l);
min_pix = min(min_pix, n);
min_pix = min(min_pix, o);
#endif
vec4 max_pix = vec4(1e-8);
max_pix = max(max_pix, f);
max_pix = max(max_pix, g);
max_pix = max(max_pix, j);
max_pix = max(max_pix, k);
#if (TWELVE_TAP_AR == 1)
max_pix = max(max_pix, b);
max_pix = max(max_pix, c);
max_pix = max(max_pix, e);
max_pix = max(max_pix, h);
max_pix = max(max_pix, i);
max_pix = max(max_pix, l);
max_pix = max(max_pix, n);
max_pix = max(max_pix, o);
#endif
//Sample current high-res pixel
vec4 hr_pix = POSTKERNEL_texOff(0.0);
// Clamp the intensity so it doesn't ring
vec4 clipped = clamp(hr_pix, min_pix, max_pix);
return mix(hr_pix, clipped, strength);
}
//!HOOK CHROMA_SCALED
//!BIND CHROMA
//!BIND CHROMA_SCALED
//!DESC Pixel Clipper (Chroma AR)
//!WHEN CHROMA_SCALED.w CHROMA.w / 1.000 > CHROMA_SCALED.h CHROMA.h / 1.000 > *
#define TWELVE_TAP_AR 0
const float strength = 0.8;
vec4 hook() {
vec2 pp = CHROMA_pos * CHROMA_size - vec2(0.5);
vec2 fp = floor(pp);
vec4 f = CHROMA_tex(vec2((fp + vec2( 0.5, 0.5)) * CHROMA_pt));
vec4 g = CHROMA_tex(vec2((fp + vec2( 1.5, 0.5)) * CHROMA_pt));
vec4 j = CHROMA_tex(vec2((fp + vec2( 0.5, 1.5)) * CHROMA_pt));
vec4 k = CHROMA_tex(vec2((fp + vec2( 1.5, 1.5)) * CHROMA_pt));
#if (TWELVE_TAP_AR == 1)
vec4 b = CHROMA_tex(vec2((fp + vec2(0.5, -0.5)) * CHROMA_pt));
vec4 c = CHROMA_tex(vec2((fp + vec2(1.5, -0.5)) * CHROMA_pt));
vec4 e = CHROMA_tex(vec2((fp + vec2(-0.5, 0.5)) * CHROMA_pt));
vec4 h = CHROMA_tex(vec2((fp + vec2( 2.5, 0.5)) * CHROMA_pt));
vec4 i = CHROMA_tex(vec2((fp + vec2(-0.5, 1.5)) * CHROMA_pt));
vec4 l = CHROMA_tex(vec2((fp + vec2( 2.5, 1.5)) * CHROMA_pt));
vec4 n = CHROMA_tex(vec2((fp + vec2(0.5, 2.5) ) * CHROMA_pt));
vec4 o = CHROMA_tex(vec2((fp + vec2(1.5, 2.5) ) * CHROMA_pt));
#endif
vec4 min_pix = vec4(1e8);
min_pix = min(min_pix, f);
min_pix = min(min_pix, g);
min_pix = min(min_pix, j);
min_pix = min(min_pix, k);
#if (TWELVE_TAP_AR == 1)
min_pix = min(min_pix, b);
min_pix = min(min_pix, c);
min_pix = min(min_pix, e);
min_pix = min(min_pix, h);
min_pix = min(min_pix, i);
min_pix = min(min_pix, l);
min_pix = min(min_pix, n);
min_pix = min(min_pix, o);
#endif
vec4 max_pix = vec4(1e-8);
max_pix = max(max_pix, f);
max_pix = max(max_pix, g);
max_pix = max(max_pix, j);
max_pix = max(max_pix, k);
#if (TWELVE_TAP_AR == 1)
max_pix = max(max_pix, b);
max_pix = max(max_pix, c);
max_pix = max(max_pix, e);
max_pix = max(max_pix, h);
max_pix = max(max_pix, i);
max_pix = max(max_pix, l);
max_pix = max(max_pix, n);
max_pix = max(max_pix, o);
#endif
//Sample current high-res pixel
vec4 hr_pix = CHROMA_SCALED_texOff(0.0);
// Clamp the intensity so it doesn't ring
vec4 clipped = clamp(hr_pix, min_pix, max_pix);
return mix(hr_pix, clipped, strength);
}
//!HOOK POSTKERNEL
//!BIND PREKERNEL
//!BIND POSTKERNEL
//!DESC Pixel Clipper (Downscaling AR)
//!WHEN POSTKERNEL.w PREKERNEL.w / 1.000 < POSTKERNEL.h PREKERNEL.h / 1.000 < *
const float strength = 1.0;
vec4 hook() {
int radius = int(ceil((PREKERNEL_size.x / POSTKERNEL_size.x) * 0.5));
vec4 pix = vec4(0.0);
vec4 min_pix = vec4(1e8);
vec4 max_pix = vec4(1e-8);
for (int dx = -radius; dx <= radius; dx++) {
for (int dy = -radius; dy <= radius; dy++) {
pix = PREKERNEL_texOff(vec2(dx, dy));
min_pix = min(pix, min_pix);
max_pix = max(pix, max_pix);
}
}
vec4 lr_pix = POSTKERNEL_texOff(0.0);
vec4 clipped = clamp(lr_pix, min_pix, max_pix);
return mix(lr_pix, clipped, strength);
}
+11
View File
@@ -0,0 +1,11 @@
//!DESC color-alt_luma (Black & White)
//!HOOK LUMA
//!BIND HOOKED
vec4 hook()
{
float color = LUMA_texOff(0).x;
return vec4(1.0 - color);
}
+13
View File
@@ -0,0 +1,13 @@
//!DESC color levels +
//!HOOK MAINPRESUB
//!BIND HOOKED
const float min = 16.0 / 255.0;
const float max = 255.0 / (235.0 - 16.0);
vec4 hook()
{
return (HOOKED_texOff(0) - min) * max;
}
@@ -0,0 +1,13 @@
//!DESC color levels + (CHROMA)
//!HOOK CHROMA
//!BIND HOOKED
const float min = 16.0 / 255.0;
const float max = 255.0 / (240.0 - 16.0);
vec4 hook()
{
return (HOOKED_texOff(0) - min) * max;
}
+13
View File
@@ -0,0 +1,13 @@
//!DESC color levels + (LUMA)
//!HOOK LUMA
//!BIND HOOKED
const float min = 16.0 / 255.0;
const float max = 255.0 / (235.0 - 16.0);
vec4 hook()
{
return (HOOKED_texOff(0) - min) * max;
}
+13
View File
@@ -0,0 +1,13 @@
//!DESC color levels -
//!HOOK MAINPRESUB
//!BIND HOOKED
const float min = 16.0 / 255.0;
const float max = (235.0 - 16.0) / 255.0;
vec4 hook()
{
return (HOOKED_texOff(0) * max) + min;
}
@@ -0,0 +1,13 @@
//!DESC color levels - (CHROMA)
//!HOOK CHROMA
//!BIND HOOKED
const float min = 16.0 / 255.0;
const float max = (240.0 - 16.0) / 255.0;
vec4 hook()
{
return (HOOKED_texOff(0) * max) + min;
}
+13
View File
@@ -0,0 +1,13 @@
//!DESC color levels - (LUMA)
//!HOOK LUMA
//!BIND HOOKED
const float min = 16.0 / 255.0;
const float max = (235.0 - 16.0) / 255.0;
vec4 hook()
{
return (HOOKED_texOff(0) * max) + min;
}
+12
View File
@@ -0,0 +1,12 @@
//!HOOK OUTPUT
//!BIND HOOKED
//!DESC signal range scaling
vec4 color = HOOKED_texOff(vec2(0.0, 0.0));
vec4 hook() {
const float REFBLACK = ( 64. / 1023.);
const float REFWHITE = ( 940. / 1023.);
color.rgb *= REFWHITE - REFBLACK;
color.rgb += REFBLACK;
return color;
}
+72
View File
@@ -0,0 +1,72 @@
//!DESC MinBlur-USM
//!HOOK LUMA
//!BIND HOOKED
#define CMPSWAP(i, j) if (a[i] > a[j]) {\
float t = a[i];\
a[i] = a[j];\
a[j] = t;\
}
float remove_grain_20() {
float r = 0.;
r += HOOKED_texOff(vec2(-1, -1)).x;
r += HOOKED_texOff(vec2(+0, -1)).x;
r += HOOKED_texOff(vec2(+1, -1)).x;
r += HOOKED_texOff(vec2(-1, +0)).x;
r += HOOKED_texOff(vec2(+0, +0)).x;
r += HOOKED_texOff(vec2(+1, +0)).x;
r += HOOKED_texOff(vec2(-1, +1)).x;
r += HOOKED_texOff(vec2(+0, +1)).x;
r += HOOKED_texOff(vec2(+1, +1)).x;
r /= 9;
return r;
}
float remove_grain_11() {
float r = 0.;
r += HOOKED_texOff(vec2(-1, -1)).x * 1.;
r += HOOKED_texOff(vec2(+0, -1)).x * 2.;
r += HOOKED_texOff(vec2(+1, -1)).x * 1.;
r += HOOKED_texOff(vec2(-1, +0)).x * 2.;
r += HOOKED_texOff(vec2(+0, +0)).x * 4.;
r += HOOKED_texOff(vec2(+1, +0)).x * 2.;
r += HOOKED_texOff(vec2(-1, +1)).x * 1.;
r += HOOKED_texOff(vec2(+0, +1)).x * 2.;
r += HOOKED_texOff(vec2(+1, +1)).x * 1.;
r /= 16;
return r;
}
float remove_grain_4() {
float a[9];
a[0] = HOOKED_texOff(vec2(-1, -1)).x;
a[1] = HOOKED_texOff(vec2(+0, -1)).x;
a[2] = HOOKED_texOff(vec2(+1, -1)).x;
a[3] = HOOKED_texOff(vec2(-1, +0)).x;
a[4] = HOOKED_texOff(vec2(+0, +0)).x;
a[5] = HOOKED_texOff(vec2(+1, +0)).x;
a[6] = HOOKED_texOff(vec2(-1, +1)).x;
a[7] = HOOKED_texOff(vec2(+0, +1)).x;
a[8] = HOOKED_texOff(vec2(+1, +1)).x;
CMPSWAP(0, 1); CMPSWAP(2, 3); CMPSWAP(4, 5); CMPSWAP(7, 8);
CMPSWAP(0, 2); CMPSWAP(1, 3); CMPSWAP(6, 8);
CMPSWAP(1, 2); CMPSWAP(6, 7); CMPSWAP(5, 8);
CMPSWAP(4, 7); CMPSWAP(3, 8);
CMPSWAP(4, 6); CMPSWAP(5, 7);
CMPSWAP(5, 6); CMPSWAP(2, 7);
CMPSWAP(0, 5); CMPSWAP(1, 6); CMPSWAP(3, 7);
CMPSWAP(0, 4); CMPSWAP(1, 5); CMPSWAP(3, 6);
CMPSWAP(1, 4); CMPSWAP(2, 5);
CMPSWAP(2, 4); CMPSWAP(3, 5);
CMPSWAP(3, 4);
return a[4];
}
vec4 hook() {
float src = HOOKED_tex(HOOKED_pos).x;
float rg11 = remove_grain_11();
float rg4 = remove_grain_4();
float min_blur = (src - rg11) * (src - rg4) < 0 ? src : abs(src - rg11) < abs(src - rg4) ? rg11 : rg4;
return vec4(src + src - min_blur, 0, 0, 0);
}
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
//!DESC Reduce static noise (chroma)
//!HOOK CHROMA
//!BIND HOOKED
// Change this to tune the strength of the noise
// Apparently this has to be float on some setups
#define STRENGTH 48.0
// PRNG taken from mpv's deband shader
float mod289(float x) { return x - floor(x / 289.0) * 289.0; }
float permute(float x) { return mod289((34.0*x + 1.0) * x); }
float rand(float x) { return fract(x / 41.0); }
vec4 hook() {
vec3 _m = vec3(HOOKED_pos, 0.5) + vec3(1.0);
float h = permute(permute(permute(_m.x)+_m.y)+_m.z);
vec4 noise;
noise.x = rand(h); h = permute(h);
noise.y = rand(h);
return HOOKED_tex(HOOKED_pos) + vec4(STRENGTH/8192.0) * (noise - 0.5);
}
+22
View File
@@ -0,0 +1,22 @@
//!DESC Reduce static noise (luma)
//!HOOK LUMA
//!BIND HOOKED
// Change this to tune the strength of the noise
// Apparently this has to be float on some setups
#define STRENGTH 48.0
// PRNG taken from mpv's deband shader
float mod289(float x) { return x - floor(x / 289.0) * 289.0; }
float permute(float x) { return mod289((34.0*x + 1.0) * x); }
float rand(float x) { return fract(x / 41.0); }
vec4 hook() {
vec3 _m = vec3(HOOKED_pos, 1.0) + vec3(1.0);
float h = permute(permute(permute(_m.x)+_m.y)+_m.z);
vec4 noise;
noise.x = rand(h);
return HOOKED_tex(HOOKED_pos) + vec4(STRENGTH/8192.0) * (noise - 0.5);
}
+220
View File
@@ -0,0 +1,220 @@
// https://www.itu.int/rec/R-REC-BT.1886
//!HOOK OUTPUT
//!BIND HOOKED
//!DESC transfer function (bt.1886, inverse)
float bt1886_eotf(float V, float gamma, float Lw, float Lb) {
float a = pow(pow(Lw, 1.0 / gamma) - pow(Lb, 1.0 / gamma), gamma);
float b = pow(Lb, 1.0 / gamma) / (pow(Lw, 1.0 / gamma) - pow(Lb, 1.0 / gamma));
float L = a * pow(max(V + b, 0.0), gamma);
return L;
}
vec3 bt1886_eotf(vec3 color, float gamma, float Lw, float Lb) {
return vec3(
bt1886_eotf(color.r, gamma, Lw, Lb),
bt1886_eotf(color.g, gamma, Lw, Lb),
bt1886_eotf(color.b, gamma, Lw, Lb)
);
}
vec4 hook() {
vec4 color = HOOKED_tex(HOOKED_pos);
color.rgb = bt1886_eotf(color.rgb, 2.4, 1.0, 0.001);
return color;
}
//!TEXTURE TONE
//!SIZE 1024 1
//!FORMAT rgba16f
//!FILTER LINEAR
//!BORDER REPEAT
//!STORAGE
//!HOOK OUTPUT
//!BIND HOOKED
//!BIND TONE
//!SAVE GARB
//!WIDTH 4096
//!HEIGHT 1
//!DESC bake lut
float bezier(float t, float a, float b, float c) {
a = mix(a, b, t);
b = mix(b, c, t);
a = mix(a, b, t);
return a;
}
vec2 bezier(float t, vec2 a, vec2 b, vec2 c) {
return vec2(
bezier(t, a.x, b.x, c.x),
bezier(t, a.y, b.y, c.y)
);
}
vec4 hook() {
vec2 b = bezier(HOOKED_pos.x, vec2(0.0, 0.0), vec2(0.5, 0.8), vec2(1.0, 1.0));
imageStore(TONE, ivec2(int(1023.0 * b.x), 0), vec4(vec3(b.y), 1.0));
vec4 color = HOOKED_texOff(0);
return color;
}
//!HOOK OUTPUT
//!BIND HOOKED
//!BIND TONE
//!DESC tone-mapping
float cbrt(float x) {
return sign(x) * pow(abs(x), 1.0 / 3.0);
}
vec3 RGB_to_XYZ(vec3 RGB) {
mat3 M = mat3(
0.41239079926595934, 0.357584339383878, 0.1804807884018343,
0.21263900587151027, 0.715168678767756, 0.07219231536073371,
0.01933081871559182, 0.11919477979462598, 0.9505321522496607);
return RGB * M;
}
vec3 XYZ_to_RGB(vec3 XYZ) {
mat3 M = mat3(
3.2409699419045226, -1.537383177570094, -0.4986107602930034,
-0.9692436362808796, 1.8759675015077202, 0.04155505740717559,
0.05563007969699366, -0.20397695888897652, 1.0569715142428786);
return XYZ * M;
}
vec3 XYZ_to_LMS(vec3 XYZ) {
mat3 M = mat3(
0.8190224379967030, 0.3619062600528904, -0.1288737815209879,
0.0329836539323885, 0.9292868615863434, 0.0361446663506424,
0.0481771893596242, 0.2642395317527308, 0.6335478284694309);
return XYZ * M;
}
vec3 LMS_to_XYZ(vec3 LMS) {
mat3 M = mat3(
1.2268798758459243, -0.5578149944602171, 0.2813910456659647,
-0.0405757452148008, 1.1122868032803170, -0.0717110580655164,
-0.0763729366746601, -0.4214933324022432, 1.5869240198367816);
return LMS * M;
}
vec3 LMS_to_Lab(vec3 LMS) {
mat3 M = mat3(
0.2104542683093140, 0.7936177747023054, -0.0040720430116193,
1.9779985324311684, -2.4285922420485799, 0.4505937096174110,
0.0259040424655478, 0.7827717124575296, -0.8086757549230774);
LMS = vec3(
cbrt(LMS.x),
cbrt(LMS.y),
cbrt(LMS.z)
);
return LMS * M;
}
vec3 Lab_to_LMS(vec3 Lab) {
mat3 M = mat3(
1.0000000000000000, 0.3963377773761749, 0.2158037573099136,
1.0000000000000000, -0.1055613458156586, -0.0638541728258133,
1.0000000000000000, -0.0894841775298119, -1.2914855480194092);
Lab = Lab * M;
return vec3(
pow(Lab.x, 3.0),
pow(Lab.y, 3.0),
pow(Lab.z, 3.0)
);
}
float L_to_Lr(float x) {
const float k1 = 0.206;
const float k2 = 0.03;
const float k3 = (1.0 + k1) / (1.0 + k2);
return 0.5 * (k3 * x - k1 + sqrt(pow(k3 * x - k1, 2.0) + 4.0 * k2 * k3 * x));
}
float Lr_to_L(float x) {
const float k1 = 0.206;
const float k2 = 0.03;
const float k3 = (1.0 + k1) / (1.0 + k2);
return (x * (x + k1)) / (k3 * (x + k2));
}
vec3 RGB_to_Lab(vec3 color) {
color = RGB_to_XYZ(color);
color = XYZ_to_LMS(color);
color = LMS_to_Lab(color);
color.x = L_to_Lr(color.x);
return color;
}
vec3 Lab_to_RGB(vec3 color) {
color.x = Lr_to_L(color.x);
color = Lab_to_LMS(color);
color = LMS_to_XYZ(color);
color = XYZ_to_RGB(color);
return color;
}
float curve(float x) {
// TODO: remove two compare
if (x <= 1e-6)
return 0.0;
if (x >= 1.0 - 1e-6)
return 1.0;
return imageLoad(TONE, ivec2(int(1023.0 * x), 0)).x;
}
vec3 tone_mapping_ictcp(vec3 ICtCp) {
float I2 = curve(ICtCp.x);
ICtCp.yz *= max(ICtCp.x / I2, I2 / ICtCp.x);
ICtCp.x = I2;
return ICtCp;
}
vec4 hook() {
vec4 color = HOOKED_texOff(0);
color.rgb = RGB_to_Lab(color.rgb);
color.rgb = tone_mapping_ictcp(color.rgb);
color.rgb = Lab_to_RGB(color.rgb);
return color;
}
//!HOOK OUTPUT
//!BIND HOOKED
//!DESC transfer function (bt.1886)
float bt1886_eotf_inv(float L, float gamma, float Lw, float Lb) {
float a = pow(pow(Lw, 1.0 / gamma) - pow(Lb, 1.0 / gamma), gamma);
float b = pow(Lb, 1.0 / gamma) / (pow(Lw, 1.0 / gamma) - pow(Lb, 1.0 / gamma));
float V = pow(max(L / a, 0.0), 1.0 / gamma) - b;
return V;
}
vec3 bt1886_eotf_inv(vec3 color, float gamma, float Lw, float Lb) {
return vec3(
bt1886_eotf_inv(color.r, gamma, Lw, Lb),
bt1886_eotf_inv(color.g, gamma, Lw, Lb),
bt1886_eotf_inv(color.b, gamma, Lw, Lb)
);
}
vec4 hook() {
vec4 color = HOOKED_tex(HOOKED_pos);
color.rgb = bt1886_eotf_inv(color.rgb, 2.4, 1.0, 0.001);
return color;
}
+24
View File
@@ -0,0 +1,24 @@
//!DESC unsharp-masking_blur
//!HOOK MAIN
//!BIND HOOKED
#define BLUR -1.0 // terrible when below -2
vec4 hook()
{
const float st1 = 1.2;
vec4 p = HOOKED_tex(HOOKED_pos);
vec4 sum1 = HOOKED_texOff(st1 * vec2(+1, +1))
+ HOOKED_texOff(st1 * vec2(+1, -1))
+ HOOKED_texOff(st1 * vec2(-1, +1))
+ HOOKED_texOff(st1 * vec2(-1, -1));
const float st2 = 1.5;
vec4 sum2 = HOOKED_texOff(st2 * vec2(+1, 0))
+ HOOKED_texOff(st2 * vec2( 0, +1))
+ HOOKED_texOff(st2 * vec2(-1, 0))
+ HOOKED_texOff(st2 * vec2( 0, -1));
vec4 t = p * 0.859375 + sum2 * -0.1171875 + sum1 * -0.09765625;
return p + t * BLUR;
}
@@ -0,0 +1,24 @@
//!DESC unsharp-masking_sharpen
//!HOOK MAIN
//!BIND HOOKED
#define SHARPEN 1.0 // terrible when over 3
vec4 hook()
{
const float st1 = 1.2;
vec4 p = HOOKED_tex(HOOKED_pos);
vec4 sum1 = HOOKED_texOff(st1 * vec2(+1, +1))
+ HOOKED_texOff(st1 * vec2(+1, -1))
+ HOOKED_texOff(st1 * vec2(-1, +1))
+ HOOKED_texOff(st1 * vec2(-1, -1));
const float st2 = 1.5;
vec4 sum2 = HOOKED_texOff(st2 * vec2(+1, 0))
+ HOOKED_texOff(st2 * vec2( 0, +1))
+ HOOKED_texOff(st2 * vec2(-1, 0))
+ HOOKED_texOff(st2 * vec2( 0, -1));
vec4 t = p * 0.859375 + sum2 * -0.1171875 + sum1 * -0.09765625;
return p + t * SHARPEN;
}
+45
View File
@@ -0,0 +1,45 @@
//!DESC unsharp
//!HOOK SCALED
//!BIND HOOKED
#define effect_width 1
#define coeff_blur 0.9
#define coeff_orig (1 + coeff_blur)
#define Src(a,b) HOOKED_texOff(vec2(a,b))
#define dx (effect_width)
#define dy (effect_width)
vec4 hook()
{
// Retrieves the original pixel
vec4 orig = Src(0,0);
// Calculates blurred image (gaussian blur)
vec4 c1 = Src(-dx,-dy);
vec4 c2 = Src(0,-dy);
vec4 c3 = Src(dx,-dy);
vec4 c4 = Src(-dx,0);
vec4 c5 = Src(dx,0);
vec4 c6 = Src(-dx,dy);
vec4 c7 = Src(0,dy);
vec4 c8 = Src(dx,dy);
// gaussian blur filter
// [ 1, 2 , 1 ]
// [ 2, 4 , 2 ]
// [ 1, 2 , 1 ]
// c1 c2 c3
// c4 c5
// c6 c7 c8
vec4 blur = (c1 + c3 + c6 + c8 + 2 * (c2 + c4 + c5 + c7) + 4 * orig)/16;
// The blurred image is substracted from the origginal image
vec4 corr = coeff_orig*orig - coeff_blur*blur;
return corr;
}