mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
More shader samples
This commit is contained in:
parent
9347f2a502
commit
277d7fbd86
222
shaders/KrigBilateral.glsl
Normal file
222
shaders/KrigBilateral.glsl
Normal file
@ -0,0 +1,222 @@
|
||||
// KrigBilateral by Shiandow
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 3.0 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library.
|
||||
|
||||
//!HOOK CHROMA
|
||||
//!BIND HOOKED
|
||||
//!BIND LUMA
|
||||
//!SAVE LOWRES_Y
|
||||
//!WIDTH LUMA.w
|
||||
//!WHEN CHROMA.w LUMA.w <
|
||||
//!DESC KrigBilateral Downscaling Y pass 1
|
||||
|
||||
#define offset vec2(0,0)
|
||||
|
||||
#define axis 1
|
||||
|
||||
#define Kernel(x) dot(vec3(0.42659, -0.49656, 0.076849), cos(vec3(0, 1, 2) * acos(-1.) * (x + 1.)))
|
||||
|
||||
vec4 hook() {
|
||||
// Calculate bounds
|
||||
float low = ceil((LUMA_pos - CHROMA_pt) * LUMA_size - offset - 0.5)[axis];
|
||||
float high = floor((LUMA_pos + CHROMA_pt) * LUMA_size - offset - 0.5)[axis];
|
||||
|
||||
float W = 0.0;
|
||||
vec4 avg = vec4(0);
|
||||
vec2 pos = LUMA_pos;
|
||||
|
||||
for (float k = low; k <= high; k++) {
|
||||
pos[axis] = LUMA_pt[axis] * (k - offset[axis] + 0.5);
|
||||
float rel = (pos[axis] - LUMA_pos[axis])*CHROMA_size[axis];
|
||||
float w = Kernel(rel);
|
||||
|
||||
vec4 y = textureGrad(LUMA_raw, pos, vec2(0.0), vec2(0.0)).xxxx * LUMA_mul;
|
||||
y.y *= y.y;
|
||||
avg += w * y;
|
||||
W += w;
|
||||
}
|
||||
avg /= W;
|
||||
avg.y = abs(avg.y - pow(avg.x, 2.0));
|
||||
return avg;
|
||||
}
|
||||
|
||||
//!HOOK CHROMA
|
||||
//!BIND HOOKED
|
||||
//!BIND LOWRES_Y
|
||||
//!SAVE LOWRES_Y
|
||||
//!WHEN CHROMA.w LUMA.w <
|
||||
//!DESC KrigBilateral Downscaling Y pass 2
|
||||
|
||||
#define offset vec2(0,0)
|
||||
|
||||
#define axis 0
|
||||
|
||||
#define Kernel(x) dot(vec3(0.42659, -0.49656, 0.076849), cos(vec3(0, 1, 2) * acos(-1.) * (x + 1.)))
|
||||
|
||||
vec4 hook() {
|
||||
// Calculate bounds
|
||||
float low = ceil((LOWRES_Y_pos - CHROMA_pt) * LOWRES_Y_size - offset - 0.5)[axis];
|
||||
float high = floor((LOWRES_Y_pos + CHROMA_pt) * LOWRES_Y_size - offset - 0.5)[axis];
|
||||
|
||||
float W = 0.0;
|
||||
vec4 avg = vec4(0);
|
||||
vec2 pos = LOWRES_Y_pos;
|
||||
|
||||
for (float k = low; k <= high; k++) {
|
||||
pos[axis] = LOWRES_Y_pt[axis] * (k - offset[axis] + 0.5);
|
||||
float rel = (pos[axis] - LOWRES_Y_pos[axis])*CHROMA_size[axis];
|
||||
float w = Kernel(rel);
|
||||
|
||||
vec4 y = textureGrad(LOWRES_Y_raw, pos, vec2(0.0), vec2(0.0)).xxxx * LOWRES_Y_mul;
|
||||
y.y *= y.y;
|
||||
avg += w * y;
|
||||
W += w;
|
||||
}
|
||||
avg /= W;
|
||||
avg.y = abs(avg.y - pow(avg.x, 2.0)) + LOWRES_Y_texOff(0).y;
|
||||
return avg;
|
||||
}
|
||||
|
||||
//!HOOK CHROMA
|
||||
//!BIND HOOKED
|
||||
//!BIND LUMA
|
||||
//!BIND LOWRES_Y
|
||||
//!WIDTH LUMA.w
|
||||
//!HEIGHT LUMA.h
|
||||
//!WHEN CHROMA.w LUMA.w <
|
||||
//!OFFSET ALIGN
|
||||
//!DESC KrigBilateral Upscaling UV
|
||||
|
||||
// -- Convenience --
|
||||
#define sqr(x) dot(x,x)
|
||||
#define bitnoise 1.0/(2.0*255.0)
|
||||
#define noise 0.05//5.0*bitnoise
|
||||
#define chromaOffset vec2(0.0, 0.0)
|
||||
|
||||
// -- Window Size --
|
||||
#define taps 3
|
||||
#define even (float(taps) - 2.0 * floor(float(taps) / 2.0) == 0.0)
|
||||
#define minX int(1.0-ceil(float(taps)/2.0))
|
||||
#define maxX int(floor(float(taps)/2.0))
|
||||
|
||||
#define Kernel(x) (cos(acos(-1.0)*(x)/float(taps))) // Hann kernel
|
||||
|
||||
// -- Input processing --
|
||||
#define GetY(coord) LOWRES_Y_tex(LOWRES_Y_pt*(pos+coord+vec2(0.5))).xy
|
||||
#define GetUV(coord) CHROMA_tex(CHROMA_pt*(pos+coord+vec2(0.5))).xy
|
||||
|
||||
#define N (taps*taps - 1)
|
||||
|
||||
#define M(i,j) Mx[min(i,j)*N + max(i,j) - min(i,j)*(min(i,j)+1)/2]
|
||||
|
||||
#define C(i,j) (inversesqrt(1.0 + (X[i].y + X[j].y)/localVar) * exp(-0.5*(sqr(X[i].x - X[j].x)/(localVar + X[i].y + X[j].y) + sqr((coords[i] - coords[j])/radius))) + (X[i].x - y) * (X[j].x - y) / localVar)
|
||||
#define c(i) (inversesqrt(1.0 + X[i].y/localVar) * exp(-0.5*(sqr(X[i].x - y)/(localVar + X[i].y) + sqr((coords[i] - offset)/radius))))
|
||||
|
||||
vec4 hook() {
|
||||
vec2 pos = CHROMA_pos * HOOKED_size - chromaOffset - vec2(0.5);
|
||||
vec2 offset = pos - (even ? floor(pos) : round(pos));
|
||||
pos -= offset;
|
||||
|
||||
vec2 coords[N+1];
|
||||
vec4 X[N+1];
|
||||
float y = LUMA_texOff(0).x;
|
||||
vec4 total = vec4(0);
|
||||
|
||||
coords[0] = vec2(-1,-1); coords[1] = vec2(-1, 0); coords[2] = vec2(-1, 1);
|
||||
coords[3] = vec2( 0,-1); coords[4] = vec2( 0, 1); coords[5] = vec2( 1,-1);
|
||||
coords[6] = vec2( 1, 0); coords[7] = vec2( 1, 1); coords[8] = vec2( 0, 0);
|
||||
|
||||
for (int i=0; i<N+1; i++) {
|
||||
X[i] = vec4(GetY(coords[i]), GetUV(coords[i]));
|
||||
vec2 w = clamp(1.5 - abs(coords[i] - offset), 0.0, 1.0);
|
||||
total += w.x*w.y*vec4(X[i].x, pow(X[i].x, 2.0), X[i].y, 1.0);
|
||||
}
|
||||
total.xyz /= total.w;
|
||||
float localVar = sqr(noise) + abs(total.y - pow(total.x, 2.0)) + total.z;
|
||||
float radius = 1.0;
|
||||
|
||||
float Mx[N*(N+1)/2];
|
||||
float b[N];
|
||||
vec4 interp = X[N];
|
||||
|
||||
b[0] = c(0) - c(N) - C(0,N) + C(N,N); M(0, 0) = C(0,0) - C(0,N) - C(0,N) + C(N,N); M(0, 1) = C(0,1) - C(1,N) - C(0,N) + C(N,N); M(0, 2) = C(0,2) - C(2,N) - C(0,N) + C(N,N); M(0, 3) = C(0,3) - C(3,N) - C(0,N) + C(N,N); M(0, 4) = C(0,4) - C(4,N) - C(0,N) + C(N,N); M(0, 5) = C(0,5) - C(5,N) - C(0,N) + C(N,N); M(0, 6) = C(0,6) - C(6,N) - C(0,N) + C(N,N); M(0, 7) = C(0,7) - C(7,N) - C(0,N) + C(N,N);
|
||||
b[1] = c(1) - c(N) - C(1,N) + C(N,N); M(1, 1) = C(1,1) - C(1,N) - C(1,N) + C(N,N); M(1, 2) = C(1,2) - C(2,N) - C(1,N) + C(N,N); M(1, 3) = C(1,3) - C(3,N) - C(1,N) + C(N,N); M(1, 4) = C(1,4) - C(4,N) - C(1,N) + C(N,N); M(1, 5) = C(1,5) - C(5,N) - C(1,N) + C(N,N); M(1, 6) = C(1,6) - C(6,N) - C(1,N) + C(N,N); M(1, 7) = C(1,7) - C(7,N) - C(1,N) + C(N,N);
|
||||
b[2] = c(2) - c(N) - C(2,N) + C(N,N); M(2, 2) = C(2,2) - C(2,N) - C(2,N) + C(N,N); M(2, 3) = C(2,3) - C(3,N) - C(2,N) + C(N,N); M(2, 4) = C(2,4) - C(4,N) - C(2,N) + C(N,N); M(2, 5) = C(2,5) - C(5,N) - C(2,N) + C(N,N); M(2, 6) = C(2,6) - C(6,N) - C(2,N) + C(N,N); M(2, 7) = C(2,7) - C(7,N) - C(2,N) + C(N,N);
|
||||
b[3] = c(3) - c(N) - C(3,N) + C(N,N); M(3, 3) = C(3,3) - C(3,N) - C(3,N) + C(N,N); M(3, 4) = C(3,4) - C(4,N) - C(3,N) + C(N,N); M(3, 5) = C(3,5) - C(5,N) - C(3,N) + C(N,N); M(3, 6) = C(3,6) - C(6,N) - C(3,N) + C(N,N); M(3, 7) = C(3,7) - C(7,N) - C(3,N) + C(N,N);
|
||||
b[4] = c(4) - c(N) - C(4,N) + C(N,N); M(4, 4) = C(4,4) - C(4,N) - C(4,N) + C(N,N); M(4, 5) = C(4,5) - C(5,N) - C(4,N) + C(N,N); M(4, 6) = C(4,6) - C(6,N) - C(4,N) + C(N,N); M(4, 7) = C(4,7) - C(7,N) - C(4,N) + C(N,N);
|
||||
b[5] = c(5) - c(N) - C(5,N) + C(N,N); M(5, 5) = C(5,5) - C(5,N) - C(5,N) + C(N,N); M(5, 6) = C(5,6) - C(6,N) - C(5,N) + C(N,N); M(5, 7) = C(5,7) - C(7,N) - C(5,N) + C(N,N);
|
||||
b[6] = c(6) - c(N) - C(6,N) + C(N,N); M(6, 6) = C(6,6) - C(6,N) - C(6,N) + C(N,N); M(6, 7) = C(6,7) - C(7,N) - C(6,N) + C(N,N);
|
||||
b[7] = c(7) - c(N) - C(7,N) + C(N,N); M(7, 7) = C(7,7) - C(7,N) - C(7,N) + C(N,N);
|
||||
|
||||
b[1] -= b[0] * M(1, 0) / M(0, 0); M(1, 1) -= M(0, 1) * M(1, 0) / M(0, 0); M(1, 2) -= M(0, 2) * M(1, 0) / M(0, 0); M(1, 3) -= M(0, 3) * M(1, 0) / M(0, 0); M(1, 4) -= M(0, 4) * M(1, 0) / M(0, 0); M(1, 5) -= M(0, 5) * M(1, 0) / M(0, 0); M(1, 6) -= M(0, 6) * M(1, 0) / M(0, 0); M(1, 7) -= M(0, 7) * M(1, 0) / M(0, 0);
|
||||
b[2] -= b[0] * M(2, 0) / M(0, 0); M(2, 2) -= M(0, 2) * M(2, 0) / M(0, 0); M(2, 3) -= M(0, 3) * M(2, 0) / M(0, 0); M(2, 4) -= M(0, 4) * M(2, 0) / M(0, 0); M(2, 5) -= M(0, 5) * M(2, 0) / M(0, 0); M(2, 6) -= M(0, 6) * M(2, 0) / M(0, 0); M(2, 7) -= M(0, 7) * M(2, 0) / M(0, 0);
|
||||
b[3] -= b[0] * M(3, 0) / M(0, 0); M(3, 3) -= M(0, 3) * M(3, 0) / M(0, 0); M(3, 4) -= M(0, 4) * M(3, 0) / M(0, 0); M(3, 5) -= M(0, 5) * M(3, 0) / M(0, 0); M(3, 6) -= M(0, 6) * M(3, 0) / M(0, 0); M(3, 7) -= M(0, 7) * M(3, 0) / M(0, 0);
|
||||
b[4] -= b[0] * M(4, 0) / M(0, 0); M(4, 4) -= M(0, 4) * M(4, 0) / M(0, 0); M(4, 5) -= M(0, 5) * M(4, 0) / M(0, 0); M(4, 6) -= M(0, 6) * M(4, 0) / M(0, 0); M(4, 7) -= M(0, 7) * M(4, 0) / M(0, 0);
|
||||
b[5] -= b[0] * M(5, 0) / M(0, 0); M(5, 5) -= M(0, 5) * M(5, 0) / M(0, 0); M(5, 6) -= M(0, 6) * M(5, 0) / M(0, 0); M(5, 7) -= M(0, 7) * M(5, 0) / M(0, 0);
|
||||
b[6] -= b[0] * M(6, 0) / M(0, 0); M(6, 6) -= M(0, 6) * M(6, 0) / M(0, 0); M(6, 7) -= M(0, 7) * M(6, 0) / M(0, 0);
|
||||
b[7] -= b[0] * M(7, 0) / M(0, 0); M(7, 7) -= M(0, 7) * M(7, 0) / M(0, 0);
|
||||
|
||||
b[2] -= b[1] * M(2, 1) / M(1, 1); M(2, 2) -= M(1, 2) * M(2, 1) / M(1, 1); M(2, 3) -= M(1, 3) * M(2, 1) / M(1, 1); M(2, 4) -= M(1, 4) * M(2, 1) / M(1, 1); M(2, 5) -= M(1, 5) * M(2, 1) / M(1, 1); M(2, 6) -= M(1, 6) * M(2, 1) / M(1, 1); M(2, 7) -= M(1, 7) * M(2, 1) / M(1, 1);
|
||||
b[3] -= b[1] * M(3, 1) / M(1, 1); M(3, 3) -= M(1, 3) * M(3, 1) / M(1, 1); M(3, 4) -= M(1, 4) * M(3, 1) / M(1, 1); M(3, 5) -= M(1, 5) * M(3, 1) / M(1, 1); M(3, 6) -= M(1, 6) * M(3, 1) / M(1, 1); M(3, 7) -= M(1, 7) * M(3, 1) / M(1, 1);
|
||||
b[4] -= b[1] * M(4, 1) / M(1, 1); M(4, 4) -= M(1, 4) * M(4, 1) / M(1, 1); M(4, 5) -= M(1, 5) * M(4, 1) / M(1, 1); M(4, 6) -= M(1, 6) * M(4, 1) / M(1, 1); M(4, 7) -= M(1, 7) * M(4, 1) / M(1, 1);
|
||||
b[5] -= b[1] * M(5, 1) / M(1, 1); M(5, 5) -= M(1, 5) * M(5, 1) / M(1, 1); M(5, 6) -= M(1, 6) * M(5, 1) / M(1, 1); M(5, 7) -= M(1, 7) * M(5, 1) / M(1, 1);
|
||||
b[6] -= b[1] * M(6, 1) / M(1, 1); M(6, 6) -= M(1, 6) * M(6, 1) / M(1, 1); M(6, 7) -= M(1, 7) * M(6, 1) / M(1, 1);
|
||||
b[7] -= b[1] * M(7, 1) / M(1, 1); M(7, 7) -= M(1, 7) * M(7, 1) / M(1, 1);
|
||||
|
||||
b[3] -= b[2] * M(3, 2) / M(2, 2); M(3, 3) -= M(2, 3) * M(3, 2) / M(2, 2); M(3, 4) -= M(2, 4) * M(3, 2) / M(2, 2); M(3, 5) -= M(2, 5) * M(3, 2) / M(2, 2); M(3, 6) -= M(2, 6) * M(3, 2) / M(2, 2); M(3, 7) -= M(2, 7) * M(3, 2) / M(2, 2);
|
||||
b[4] -= b[2] * M(4, 2) / M(2, 2); M(4, 4) -= M(2, 4) * M(4, 2) / M(2, 2); M(4, 5) -= M(2, 5) * M(4, 2) / M(2, 2); M(4, 6) -= M(2, 6) * M(4, 2) / M(2, 2); M(4, 7) -= M(2, 7) * M(4, 2) / M(2, 2);
|
||||
b[5] -= b[2] * M(5, 2) / M(2, 2); M(5, 5) -= M(2, 5) * M(5, 2) / M(2, 2); M(5, 6) -= M(2, 6) * M(5, 2) / M(2, 2); M(5, 7) -= M(2, 7) * M(5, 2) / M(2, 2);
|
||||
b[6] -= b[2] * M(6, 2) / M(2, 2); M(6, 6) -= M(2, 6) * M(6, 2) / M(2, 2); M(6, 7) -= M(2, 7) * M(6, 2) / M(2, 2);
|
||||
b[7] -= b[2] * M(7, 2) / M(2, 2); M(7, 7) -= M(2, 7) * M(7, 2) / M(2, 2);
|
||||
|
||||
b[4] -= b[3] * M(4, 3) / M(3, 3); M(4, 4) -= M(3, 4) * M(4, 3) / M(3, 3); M(4, 5) -= M(3, 5) * M(4, 3) / M(3, 3); M(4, 6) -= M(3, 6) * M(4, 3) / M(3, 3); M(4, 7) -= M(3, 7) * M(4, 3) / M(3, 3);
|
||||
b[5] -= b[3] * M(5, 3) / M(3, 3); M(5, 5) -= M(3, 5) * M(5, 3) / M(3, 3); M(5, 6) -= M(3, 6) * M(5, 3) / M(3, 3); M(5, 7) -= M(3, 7) * M(5, 3) / M(3, 3);
|
||||
b[6] -= b[3] * M(6, 3) / M(3, 3); M(6, 6) -= M(3, 6) * M(6, 3) / M(3, 3); M(6, 7) -= M(3, 7) * M(6, 3) / M(3, 3);
|
||||
b[7] -= b[3] * M(7, 3) / M(3, 3); M(7, 7) -= M(3, 7) * M(7, 3) / M(3, 3);
|
||||
|
||||
b[5] -= b[4] * M(5, 4) / M(4, 4); M(5, 5) -= M(4, 5) * M(5, 4) / M(4, 4); M(5, 6) -= M(4, 6) * M(5, 4) / M(4, 4); M(5, 7) -= M(4, 7) * M(5, 4) / M(4, 4);
|
||||
b[6] -= b[4] * M(6, 4) / M(4, 4); M(6, 6) -= M(4, 6) * M(6, 4) / M(4, 4); M(6, 7) -= M(4, 7) * M(6, 4) / M(4, 4);
|
||||
b[7] -= b[4] * M(7, 4) / M(4, 4); M(7, 7) -= M(4, 7) * M(7, 4) / M(4, 4);
|
||||
|
||||
b[6] -= b[5] * M(6, 5) / M(5, 5); M(6, 6) -= M(5, 6) * M(6, 5) / M(5, 5); M(6, 7) -= M(5, 7) * M(6, 5) / M(5, 5);
|
||||
b[7] -= b[5] * M(7, 5) / M(5, 5); M(7, 7) -= M(5, 7) * M(7, 5) / M(5, 5);
|
||||
|
||||
b[7] -= b[6] * M(7, 6) / M(6, 6); M(7, 7) -= M(6, 7) * M(7, 6) / M(6, 6);
|
||||
|
||||
b[N-1-0] /= M(N-1-0, N-1-0);
|
||||
interp += b[N-1-0] * (X[N-1-0] - X[N]);
|
||||
|
||||
b[N-1-1] -= M(N-1-1, 7) * b[7]; b[N-1-1] /= M(N-1-1, N-1-1);
|
||||
interp += b[N-1-1] * (X[N-1-1] - X[N]);
|
||||
|
||||
b[N-1-2] -= M(N-1-2, 6) * b[6]; b[N-1-2] -= M(N-1-2, 7) * b[7]; b[N-1-2] /= M(N-1-2, N-1-2);
|
||||
interp += b[N-1-2] * (X[N-1-2] - X[N]);
|
||||
|
||||
b[N-1-3] -= M(N-1-3, 5) * b[5]; b[N-1-3] -= M(N-1-3, 6) * b[6]; b[N-1-3] -= M(N-1-3, 7) * b[7]; b[N-1-3] /= M(N-1-3, N-1-3);
|
||||
interp += b[N-1-3] * (X[N-1-3] - X[N]);
|
||||
|
||||
b[N-1-4] -= M(N-1-4, 4) * b[4]; b[N-1-4] -= M(N-1-4, 5) * b[5]; b[N-1-4] -= M(N-1-4, 6) * b[6]; b[N-1-4] -= M(N-1-4, 7) * b[7]; b[N-1-4] /= M(N-1-4, N-1-4);
|
||||
interp += b[N-1-4] * (X[N-1-4] - X[N]);
|
||||
|
||||
b[N-1-5] -= M(N-1-5, 3) * b[3]; b[N-1-5] -= M(N-1-5, 4) * b[4]; b[N-1-5] -= M(N-1-5, 5) * b[5]; b[N-1-5] -= M(N-1-5, 6) * b[6]; b[N-1-5] -= M(N-1-5, 7) * b[7]; b[N-1-5] /= M(N-1-5, N-1-5);
|
||||
interp += b[N-1-5] * (X[N-1-5] - X[N]);
|
||||
|
||||
b[N-1-6] -= M(N-1-6, 2) * b[2]; b[N-1-6] -= M(N-1-6, 3) * b[3]; b[N-1-6] -= M(N-1-6, 4) * b[4]; b[N-1-6] -= M(N-1-6, 5) * b[5]; b[N-1-6] -= M(N-1-6, 6) * b[6]; b[N-1-6] -= M(N-1-6, 7) * b[7]; b[N-1-6] /= M(N-1-6, N-1-6);
|
||||
interp += b[N-1-6] * (X[N-1-6] - X[N]);
|
||||
|
||||
b[N-1-7] -= M(N-1-7, 1) * b[1]; b[N-1-7] -= M(N-1-7, 2) * b[2]; b[N-1-7] -= M(N-1-7, 3) * b[3]; b[N-1-7] -= M(N-1-7, 4) * b[4]; b[N-1-7] -= M(N-1-7, 5) * b[5]; b[N-1-7] -= M(N-1-7, 6) * b[6]; b[N-1-7] -= M(N-1-7, 7) * b[7]; b[N-1-7] /= M(N-1-7, N-1-7);
|
||||
interp += b[N-1-7] * (X[N-1-7] - X[N]);
|
||||
|
||||
return interp.zwxx;
|
||||
}
|
206
shaders/LumaSharpenHook.glsl
Normal file
206
shaders/LumaSharpenHook.glsl
Normal file
@ -0,0 +1,206 @@
|
||||
// vim: set ft=glsl:
|
||||
|
||||
/*
|
||||
LumaSharpenHook 0.3
|
||||
|
||||
original hlsl by Christian Cann Schuldt Jensen ~ CeeJay.dk
|
||||
port to glsl by Anon
|
||||
|
||||
It blurs the original pixel with the surrounding pixels and then subtracts this blur to sharpen the image.
|
||||
It does this in luma to avoid color artifacts and allows limiting the maximum sharpning to avoid or lessen halo artifacts.
|
||||
|
||||
This is similar to using Unsharp Mask in Photoshop.
|
||||
*/
|
||||
|
||||
// -- Hooks --
|
||||
//!HOOK LUMA
|
||||
//!BIND HOOKED
|
||||
|
||||
|
||||
// -- Sharpening --
|
||||
#define sharp_strength 0.30 //[0.10 to 3.00] Strength of the sharpening
|
||||
|
||||
#define sharp_clamp 0.035 //[0.000 to 1.000] Limits maximum amount of sharpening a pixel recieves - Default is 0.035
|
||||
|
||||
// -- Advanced sharpening settings --
|
||||
#define pattern 2 //[1|2|3|4] Choose a sample pattern. 1 = Fast, 2 = Normal, 3 = Wider, 4 = Pyramid shaped.
|
||||
//[8|9] Experimental slower patterns. 8 = 9 tap 9 fetch gaussian, 9 = 9 tap 9 fetch high pass.
|
||||
|
||||
#define offset_bias 1.0 //[0.0 to 6.0] Offset bias adjusts the radius of the sampling pattern.
|
||||
|
||||
vec4 hook(){
|
||||
vec4 colorInput = LUMA_tex(LUMA_pos);
|
||||
|
||||
|
||||
//We are on luma plane: xyzw = [luma_val, 0.0, 0.0, 1.0]
|
||||
float ori = colorInput.x;
|
||||
|
||||
// -- Combining the strength and luma multipliers --
|
||||
float sharp_strength_luma = sharp_strength; //I'll be combining even more multipliers with it later on
|
||||
|
||||
float px = 1.0;
|
||||
float py = 1.0;
|
||||
|
||||
// Sampling patterns
|
||||
|
||||
// [ NW, , NE ] Each texture lookup (except ori)
|
||||
// [ ,ori, ] samples 4 pixels
|
||||
// [ SW, , SE ]
|
||||
|
||||
// -- Pattern 1 -- A (fast) 7 tap gaussian using only 2+1 texture fetches.
|
||||
#if pattern == 1
|
||||
|
||||
// -- Gaussian filter --
|
||||
// [ 1/9, 2/9, ] [ 1 , 2 , ]
|
||||
// [ 2/9, 8/9, 2/9] = [ 2 , 8 , 2 ]
|
||||
// [ , 2/9, 1/9] [ , 2 , 1 ]
|
||||
|
||||
px = (px / 3.0) * offset_bias;
|
||||
py = (py / 3.0) * offset_bias;
|
||||
|
||||
float blur_ori = LUMA_texOff(vec2(px,py)).x; // North West
|
||||
blur_ori += LUMA_texOff(vec2(-px,-py)).x; // South East
|
||||
|
||||
//blur_ori += LUMA_texOff(vec2(px,py)).x; // North East
|
||||
//blur_ori += LUMA_texOff(vec2(-px,-py)).x; // South West
|
||||
|
||||
blur_ori *= 0.5; //Divide by the number of texture fetches
|
||||
|
||||
sharp_strength_luma *= 1.5; // Adjust strength to aproximate the strength of pattern 2
|
||||
#endif
|
||||
|
||||
// -- Pattern 2 -- A 9 tap gaussian using 4+1 texture fetches.
|
||||
#if pattern == 2
|
||||
// -- Gaussian filter --
|
||||
// [ .25, .50, .25] [ 1 , 2 , 1 ]
|
||||
// [ .50, 1, .50] = [ 2 , 4 , 2 ]
|
||||
// [ .25, .50, .25] [ 1 , 2 , 1 ]
|
||||
|
||||
px = px * 0.5 * offset_bias;
|
||||
py = py * 0.5 * offset_bias;
|
||||
|
||||
float blur_ori = LUMA_texOff(vec2(px,-py)).x; // South East
|
||||
blur_ori += LUMA_texOff(vec2(-px,-py)).x; // South West
|
||||
blur_ori += LUMA_texOff(vec2(px,py)).x; // North East
|
||||
blur_ori += LUMA_texOff(vec2(-px,py)).x; // North West
|
||||
|
||||
blur_ori *= 0.25; // ( /= 4) Divide by the number of texture fetches
|
||||
#endif
|
||||
|
||||
// -- Pattern 3 -- An experimental 17 tap gaussian using 4+1 texture fetches.
|
||||
#if pattern == 3
|
||||
|
||||
// -- Gaussian filter --
|
||||
// [ , 4 , 6 , , ]
|
||||
// [ ,16 ,24 ,16 , 4 ]
|
||||
// [ 6 ,24 , ,24 , 6 ]
|
||||
// [ 4 ,16 ,24 ,16 , ]
|
||||
// [ , , 6 , 4 , ]
|
||||
|
||||
px = px * offset_bias;
|
||||
py = py * offset_bias;
|
||||
|
||||
float blur_ori = LUMA_texOff(vec2(0.4*px,-1.2*py)).x; // South South East
|
||||
blur_ori += LUMA_texOff(vec2(-1.2*px,-0.4*py)).x; // West South West
|
||||
blur_ori += LUMA_texOff(vec2(1.2*px,0.4*py)).x; // East North East
|
||||
blur_ori += LUMA_texOff(vec2(-0.4*px,1.2*py)).x; // North North West
|
||||
|
||||
blur_ori *= 0.25; // ( /= 4) Divide by the number of texture fetches
|
||||
|
||||
sharp_strength_luma *= 0.51;
|
||||
#endif
|
||||
|
||||
// -- Pattern 4 -- A 9 tap high pass (pyramid filter) using 4+1 texture fetches.
|
||||
#if pattern == 4
|
||||
// -- Gaussian filter --
|
||||
// [ .50, .50, .50] [ 1 , 1 , 1 ]
|
||||
// [ .50, , .50] = [ 1 , , 1 ]
|
||||
// [ .50, .50, .50] [ 1 , 1 , 1 ]
|
||||
|
||||
float blur_ori = LUMA_texOff(vec2(0.5 * px,-py * offset_bias)).x; // South South East
|
||||
blur_ori += LUMA_texOff(vec2(offset_bias * -px,0.5 * -py)).x; // West South West
|
||||
blur_ori += LUMA_texOff(vec2(offset_bias * px,0.5 * py)).x; // East North East
|
||||
blur_ori += LUMA_texOff(vec2(0.5 * -px,py * offset_bias)).x; // North North West
|
||||
|
||||
//blur_ori += (2.0 * ori); // Probably not needed. Only serves to lessen the effect.
|
||||
|
||||
blur_ori *= 0.25; //Divide by the number of texture fetches
|
||||
|
||||
sharp_strength_luma *= 0.666; // Adjust strength to aproximate the strength of pattern 2
|
||||
#endif
|
||||
|
||||
// -- Pattern 8 -- A (slower) 9 tap gaussian using 9 texture fetches.
|
||||
#if pattern == 8
|
||||
|
||||
// -- Gaussian filter --
|
||||
// [ 1 , 2 , 1 ]
|
||||
// [ 2 , 4 , 2 ]
|
||||
// [ 1 , 2 , 1 ]
|
||||
|
||||
px = px * offset_bias;
|
||||
py = py * offset_bias;
|
||||
|
||||
float blur_ori = LUMA_texOff(vec2(-px,py)).x; // North West
|
||||
blur_ori += LUMA_texOff(vec2(px,-py)).x; // South East
|
||||
blur_ori += LUMA_texOff(vec2(-px,-py)).x; // South West
|
||||
blur_ori += LUMA_texOff(vec2(px,py)).x; // North East
|
||||
|
||||
float blur_ori2 = LUMA_texOff(vec2(0.0,py)).x; // North
|
||||
blur_ori2 += LUMA_texOff(vec2(0.0,-py)).x; // South
|
||||
blur_ori2 += LUMA_texOff(vec2(-px,0.0)).x; // West
|
||||
blur_ori2 += LUMA_texOff(vec2(px,0.0)).x; // East
|
||||
blur_ori2 *= 2.0;
|
||||
|
||||
blur_ori += blur_ori2;
|
||||
blur_ori += (ori * 4.0); // Probably not needed. Only serves to lessen the effect.
|
||||
|
||||
// dot()s with gaussian strengths here?
|
||||
|
||||
blur_ori /= 16.0; //Divide by the number of texture fetches
|
||||
|
||||
sharp_strength_luma *= 0.75; // Adjust strength to aproximate the strength of pattern 2
|
||||
#endif
|
||||
|
||||
// -- Pattern 9 -- A (slower) 9 tap high pass using 9 texture fetches.
|
||||
#if pattern == 9
|
||||
|
||||
// -- Gaussian filter --
|
||||
// [ 1 , 1 , 1 ]
|
||||
// [ 1 , 1 , 1 ]
|
||||
// [ 1 , 1 , 1 ]
|
||||
|
||||
px = px * offset_bias;
|
||||
py = py * offset_bias;
|
||||
|
||||
float blur_ori = LUMA_texOff(vec2(-px,py)).x; // North West
|
||||
blur_ori += LUMA_texOff(vec2(px,-py)).x; // South East
|
||||
blur_ori += LUMA_texOff(vec2(-px,-py)).x; // South West
|
||||
blur_ori += LUMA_texOff(vec2(px,py)).x; // North East
|
||||
|
||||
blur_ori += ori; // Probably not needed. Only serves to lessen the effect.
|
||||
|
||||
blur_ori += LUMA_texOff(vec2(0.0,py)).x; // North
|
||||
blur_ori += LUMA_texOff(vec2(0.0,-py)).x; // South
|
||||
blur_ori += LUMA_texOff(vec2(-px,0.0)).x; // West
|
||||
blur_ori += LUMA_texOff(vec2(px,0.0)).x; // East
|
||||
|
||||
blur_ori /= 9.0; //Divide by the number of texture fetches
|
||||
|
||||
sharp_strength_luma *= (8.0/9.0); // Adjust strength to aproximate the strength of pattern 2
|
||||
#endif
|
||||
|
||||
// -- Calculate the sharpening --
|
||||
float sharp = ori - blur_ori; //Subtracting the blurred image from the original image
|
||||
|
||||
// -- Adjust strength of the sharpening and clamp it--
|
||||
float sharp_strength_luma_clamp = sharp_strength_luma / (2.0 * sharp_clamp); //Roll part of the clamp into the dot
|
||||
|
||||
float sharp_luma = clamp((sharp * sharp_strength_luma_clamp + 0.5), 0.0,1.0 ); //Calculate the luma, adjust the strength, scale up and clamp
|
||||
sharp_luma = (sharp_clamp * 2.0) * sharp_luma - sharp_clamp; //scale down
|
||||
|
||||
|
||||
// -- Combining the values to get the final sharpened pixel --
|
||||
|
||||
colorInput.x = colorInput.x + sharp_luma; // Add the sharpening to the input color.
|
||||
return clamp(colorInput, 0.0,1.0);
|
||||
}
|
246
shaders/adaptive-sharpen.glsl
Normal file
246
shaders/adaptive-sharpen.glsl
Normal file
@ -0,0 +1,246 @@
|
||||
// Copyright (c) 2015-2018, bacondither
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer
|
||||
// in this position and unchanged.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Adaptive sharpen - version 2018-04-14 - (requires ps >= 3.0)
|
||||
// Tuned for use post resize
|
||||
|
||||
//!HOOK SCALED
|
||||
//!BIND HOOKED
|
||||
//!SAVE ASSD
|
||||
//!COMPONENTS 2
|
||||
//!DESC adaptive-sharpen
|
||||
|
||||
//--------------------------------------- Settings ------------------------------------------------
|
||||
|
||||
#define curve_height 1.6 // Main control of sharpening strength [>0]
|
||||
// 0.3 <-> 2.0 is a reasonable range of values
|
||||
|
||||
// Defined values under this row are "optimal" DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU ARE DOING!
|
||||
|
||||
#define curveslope 0.5 // Sharpening curve slope, high edge values
|
||||
|
||||
#define L_overshoot 0.003 // Max light overshoot before compression [>0.001]
|
||||
#define L_compr_low 0.167 // Light compression, default (0.169=~9x)
|
||||
#define L_compr_high 0.334 // Light compression, surrounded by edges (0.337=~4x)
|
||||
|
||||
#define D_overshoot 0.009 // Max dark overshoot before compression [>0.001]
|
||||
#define D_compr_low 0.250 // Dark compression, default (0.253=~6x)
|
||||
#define D_compr_high 0.500 // Dark compression, surrounded by edges (0.504=~2.5x)
|
||||
|
||||
#define scale_lim 0.1 // Abs max change before compression (0.1=+-10%)
|
||||
#define scale_cs 0.056 // Compression slope above scale_lim
|
||||
|
||||
#define pm_p sat(1.0/curve_height) // Power mean p-value [>0-1.0]
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
// Soft limit
|
||||
#define soft_lim(v,s) ( (exp(2.0*min(abs(v), s*24.0)/s) - 1.0)/(exp(2.0*min(abs(v), s*24.0)/s) + 1.0)*s )
|
||||
|
||||
// Weighted power mean
|
||||
#define wpmean(a,b,c) ( pow((c*pow(abs(a), pm_p) + (1.0-c)*pow(b, pm_p)), (1.0/pm_p)) )
|
||||
|
||||
// Get destination pixel values
|
||||
#define get(x,y) ( HOOKED_texOff(vec2(x, y)).rgb )
|
||||
#define sat(x) ( clamp(x, 0.0, 1.0) )
|
||||
|
||||
// Colour to luma, fast approx gamma, avg of rec. 709 & 601 luma coeffs
|
||||
#define CtL(RGB) ( sqrt(dot(vec3(0.2558, 0.6511, 0.0931), pow(sat(RGB), vec3(2.0)))) )
|
||||
|
||||
// Center pixel diff
|
||||
#define mdiff(a,b,c,d,e,f,g) ( abs(luma[g]-luma[a]) + abs(luma[g]-luma[b]) \
|
||||
+ abs(luma[g]-luma[c]) + abs(luma[g]-luma[d]) \
|
||||
+ 0.5*(abs(luma[g]-luma[e]) + abs(luma[g]-luma[f])) )
|
||||
|
||||
#define b_diff(pix) ( abs(blur-c[pix]) )
|
||||
|
||||
vec4 hook() {
|
||||
|
||||
vec4 o = HOOKED_tex(HOOKED_pos);
|
||||
|
||||
// Get points, saturate colour data in c[0]
|
||||
// [ c22 ]
|
||||
// [ c24, c9, c23 ]
|
||||
// [ c21, c1, c2, c3, c18 ]
|
||||
// [ c19, c10, c4, c0, c5, c11, c16 ]
|
||||
// [ c20, c6, c7, c8, c17 ]
|
||||
// [ c15, c12, c14 ]
|
||||
// [ c13 ]
|
||||
vec3 c[25] = vec3[](sat(o.rgb), get(-1,-1), get( 0,-1), get( 1,-1), get(-1, 0),
|
||||
get( 1, 0), get(-1, 1), get( 0, 1), get( 1, 1), get( 0,-2),
|
||||
get(-2, 0), get( 2, 0), get( 0, 2), get( 0, 3), get( 1, 2),
|
||||
get(-1, 2), get( 3, 0), get( 2, 1), get( 2,-1), get(-3, 0),
|
||||
get(-2, 1), get(-2,-1), get( 0,-3), get( 1,-2), get(-1,-2));
|
||||
|
||||
// Blur, gauss 3x3
|
||||
vec3 blur = (2.0 * (c[2]+c[4]+c[5]+c[7]) + (c[1]+c[3]+c[6]+c[8]) + 4.0 * c[0]) / 16.0;
|
||||
|
||||
// Contrast compression, center = 0.5, scaled to 1/3
|
||||
float c_comp = sat(0.266666681f + 0.9*exp2(dot(blur, vec3(-7.4/3.0))));
|
||||
|
||||
// Edge detection
|
||||
// Relative matrix weights
|
||||
// [ 1 ]
|
||||
// [ 4, 5, 4 ]
|
||||
// [ 1, 5, 6, 5, 1 ]
|
||||
// [ 4, 5, 4 ]
|
||||
// [ 1 ]
|
||||
float edge = length( 1.38*b_diff(0)
|
||||
+ 1.15*(b_diff(2) + b_diff(4) + b_diff(5) + b_diff(7))
|
||||
+ 0.92*(b_diff(1) + b_diff(3) + b_diff(6) + b_diff(8))
|
||||
+ 0.23*(b_diff(9) + b_diff(10) + b_diff(11) + b_diff(12)) ) * c_comp;
|
||||
|
||||
// RGB to luma
|
||||
float c0_Y = CtL(c[0]);
|
||||
|
||||
float luma[25] = float[](c0_Y, CtL(c[1]), CtL(c[2]), CtL(c[3]), CtL(c[4]), CtL(c[5]), CtL(c[6]),
|
||||
CtL(c[7]), CtL(c[8]), CtL(c[9]), CtL(c[10]), CtL(c[11]), CtL(c[12]),
|
||||
CtL(c[13]), CtL(c[14]), CtL(c[15]), CtL(c[16]), CtL(c[17]), CtL(c[18]),
|
||||
CtL(c[19]), CtL(c[20]), CtL(c[21]), CtL(c[22]), CtL(c[23]), CtL(c[24]));
|
||||
|
||||
// Precalculated default squared kernel weights
|
||||
const vec3 w1 = vec3(0.5, 1.0, 1.41421356237); // 0.25, 1.0, 2.0
|
||||
const vec3 w2 = vec3(0.86602540378, 1.0, 0.54772255751); // 0.75, 1.0, 0.3
|
||||
|
||||
// Transition to a concave kernel if the center edge val is above thr
|
||||
vec3 dW = pow(mix( w1, w2, smoothstep( 0.3, 0.8, edge)), vec3(2.0));
|
||||
|
||||
float mdiff_c0 = 0.02 + 3.0*( abs(luma[0]-luma[2]) + abs(luma[0]-luma[4])
|
||||
+ abs(luma[0]-luma[5]) + abs(luma[0]-luma[7])
|
||||
+ 0.25*(abs(luma[0]-luma[1]) + abs(luma[0]-luma[3])
|
||||
+abs(luma[0]-luma[6]) + abs(luma[0]-luma[8])) );
|
||||
|
||||
// Use lower weights for pixels in a more active area relative to center pixel area
|
||||
// This results in narrower and less visible overshoots around sharp edges
|
||||
float weights[12] = float[](( min((mdiff_c0/mdiff(24, 21, 2, 4, 9, 10, 1)), dW.y) ),
|
||||
( dW.x ),
|
||||
( min((mdiff_c0/mdiff(23, 18, 5, 2, 9, 11, 3)), dW.y) ),
|
||||
( dW.x ),
|
||||
( dW.x ),
|
||||
( min((mdiff_c0/mdiff(4, 20, 15, 7, 10, 12, 6)), dW.y) ),
|
||||
( dW.x ),
|
||||
( min((mdiff_c0/mdiff(5, 7, 17, 14, 12, 11, 8)), dW.y) ),
|
||||
( min((mdiff_c0/mdiff(2, 24, 23, 22, 1, 3, 9)), dW.z) ),
|
||||
( min((mdiff_c0/mdiff(20, 19, 21, 4, 1, 6, 10)), dW.z) ),
|
||||
( min((mdiff_c0/mdiff(17, 5, 18, 16, 3, 8, 11)), dW.z) ),
|
||||
( min((mdiff_c0/mdiff(13, 15, 7, 14, 6, 8, 12)), dW.z) ));
|
||||
|
||||
weights[0] = (max(max((weights[8] + weights[9])/4.0, weights[0]), 0.25) + weights[0])/2.0;
|
||||
weights[2] = (max(max((weights[8] + weights[10])/4.0, weights[2]), 0.25) + weights[2])/2.0;
|
||||
weights[5] = (max(max((weights[9] + weights[11])/4.0, weights[5]), 0.25) + weights[5])/2.0;
|
||||
weights[7] = (max(max((weights[10] + weights[11])/4.0, weights[7]), 0.25) + weights[7])/2.0;
|
||||
|
||||
// Calculate the negative part of the laplace kernel
|
||||
float weightsum = 0.0;
|
||||
float neg_laplace = 0.0;
|
||||
|
||||
for (int pix = 0; pix < 12; ++pix)
|
||||
{
|
||||
neg_laplace += luma[pix+1]*weights[pix];
|
||||
weightsum += weights[pix];
|
||||
}
|
||||
|
||||
neg_laplace = neg_laplace / weightsum;
|
||||
|
||||
// Compute sharpening magnitude function
|
||||
float sharpen_val = (curve_height/(curve_height*curveslope*pow((edge), 3.5) + 0.625));
|
||||
|
||||
// Calculate sharpening diff and scale
|
||||
float sharpdiff = (c0_Y - neg_laplace)*(sharpen_val + 0.01);
|
||||
|
||||
// Calculate local near min & max, partial sort
|
||||
float temp;
|
||||
|
||||
for (int i1 = 0; i1 < 24; i1 += 2)
|
||||
{
|
||||
temp = luma[i1];
|
||||
luma[i1] = min(luma[i1], luma[i1+1]);
|
||||
luma[i1+1] = max(temp, luma[i1+1]);
|
||||
}
|
||||
|
||||
for (int i2 = 24; i2 > 0; i2 -= 2)
|
||||
{
|
||||
temp = luma[0];
|
||||
luma[0] = min(luma[0], luma[i2]);
|
||||
luma[i2] = max(temp, luma[i2]);
|
||||
|
||||
temp = luma[24];
|
||||
luma[24] = max(luma[24], luma[i2-1]);
|
||||
luma[i2-1] = min(temp, luma[i2-1]);
|
||||
}
|
||||
|
||||
for (int i1 = 1; i1 < 24-1; i1 += 2)
|
||||
{
|
||||
temp = luma[i1];
|
||||
luma[i1] = min(luma[i1], luma[i1+1]);
|
||||
luma[i1+1] = max(temp, luma[i1+1]);
|
||||
}
|
||||
|
||||
for (int i2 = 24-1; i2 > 1; i2 -= 2)
|
||||
{
|
||||
temp = luma[1];
|
||||
luma[1] = min(luma[1], luma[i2]);
|
||||
luma[i2] = max(temp, luma[i2]);
|
||||
|
||||
temp = luma[24-1];
|
||||
luma[24-1] = max(luma[24-1], luma[i2-1]);
|
||||
luma[i2-1] = min(temp, luma[i2-1]);
|
||||
}
|
||||
|
||||
float nmax = (max(luma[23], c0_Y)*3.0 + luma[24])/4.0;
|
||||
float nmin = (min(luma[1], c0_Y)*3.0 + luma[0])/4.0;
|
||||
|
||||
// Calculate tanh scale factors
|
||||
float min_dist = min(abs(nmax - c0_Y), abs(c0_Y - nmin));
|
||||
float pos_scale = min_dist + min(L_overshoot, 1.0001 - min_dist - c0_Y);
|
||||
float neg_scale = min_dist + min(D_overshoot, 0.0001 + c0_Y - min_dist);
|
||||
|
||||
pos_scale = min(pos_scale, scale_lim*(1.0 - scale_cs) + pos_scale*scale_cs);
|
||||
neg_scale = min(neg_scale, scale_lim*(1.0 - scale_cs) + neg_scale*scale_cs);
|
||||
|
||||
// Soft limited anti-ringing with tanh, wpmean to control compression slope
|
||||
sharpdiff = wpmean(max(sharpdiff, 0.0), soft_lim( max(sharpdiff, 0.0), pos_scale ), L_compr_low )
|
||||
- wpmean(min(sharpdiff, 0.0), soft_lim( min(sharpdiff, 0.0), neg_scale ), D_compr_low );
|
||||
|
||||
return vec4(sharpdiff, c0_Y, 0, 1);
|
||||
}
|
||||
|
||||
//!HOOK SCALED
|
||||
//!BIND HOOKED
|
||||
//!BIND ASSD
|
||||
//!DESC adaptive-sharpen equalization
|
||||
|
||||
#define video_level_out false // True to preserve BTB & WTW (minor summation error)
|
||||
// Normally it should be set to false
|
||||
#define SD(x,y) ASSD_texOff(vec2(x,y)).r
|
||||
|
||||
vec4 hook() {
|
||||
vec4 o = HOOKED_texOff(0);
|
||||
float sharpdiff = SD( 0, 0) - 0.6 * 0.25 * (SD(-0.5,-0.5) + SD( 0.5,-0.5) + SD(-0.5, 0.5) + SD( 0.5, 0.5));
|
||||
float c0_Y = ASSD_texOff(vec2(0)).g;
|
||||
float sharpdiff_lim = clamp(c0_Y + sharpdiff, 0.0, 1.0) - c0_Y;
|
||||
float satmul = (c0_Y + max(sharpdiff_lim*0.9, sharpdiff_lim)*1.03 + 0.03)/(c0_Y + 0.03);
|
||||
vec3 res = c0_Y + (sharpdiff_lim*3 + sharpdiff)/4 + (clamp(o.rgb, 0.0, 1.0) - c0_Y)*satmul;
|
||||
o.rgb = video_level_out == true ? res + o.rgb - clamp(o.rgb, 0.0, 1.0) : res;
|
||||
return o;
|
||||
}
|
Loading…
Reference in New Issue
Block a user