// 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 lumaOffset (-vec2(0.0, 0.0)*LUMA_size*CHROMA_pt) #define axis 1 #define Kernel(x) (1. - abs(x)) vec4 hook() { // Calculate bounds float low = ceil((LUMA_pos - 0.5*CHROMA_pt) * LUMA_size - lumaOffset - 0.5)[axis]; float high = floor((LUMA_pos + 0.5*CHROMA_pt) * LUMA_size - lumaOffset - 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 - lumaOffset[axis] + 0.5); float rel = (pos[axis] - LUMA_pos[axis])*CHROMA_size[axis]; float w = Kernel(rel); vec4 y = textureLod(LUMA_raw, pos, 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 lumaOffset (-vec2(0.0, 0.0)*LOWRES_Y_size*CHROMA_pt) #define axis 0 #define Kernel(x) (1. - abs(x)) vec4 hook() { // Calculate bounds float low = ceil((LOWRES_Y_pos - 0.5*CHROMA_pt) * LOWRES_Y_size - lumaOffset - 0.5)[axis]; float high = floor((LOWRES_Y_pos + 0.5*CHROMA_pt) * LOWRES_Y_size - lumaOffset - 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 - lumaOffset[axis] + 0.5); float rel = (pos[axis] - LOWRES_Y_pos[axis])*CHROMA_size[axis]; float w = Kernel(rel); vec4 y = textureLod(LOWRES_Y_raw, pos, 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 6) b[N-1-i] -= M(N-1-i, 1) * b[1]; if(i > 5) b[N-1-i] -= M(N-1-i, 2) * b[2]; if(i > 4) b[N-1-i] -= M(N-1-i, 3) * b[3]; if(i > 3) b[N-1-i] -= M(N-1-i, 4) * b[4]; if(i > 2) b[N-1-i] -= M(N-1-i, 5) * b[5]; if(i > 1) b[N-1-i] -= M(N-1-i, 6) * b[6]; if(i > 0) b[N-1-i] -= M(N-1-i, 7) * b[7]; b[N-1-i] /= M(N-1-i, N-1-i); interp += b[N-1-i] * (X[N-1-i] - X[N]); } return interp.zwxx; }