mirror of
				https://github.com/jojo61/vdr-plugin-softhdcuvid.git
				synced 2025-03-01 10:39:28 +00:00 
			
		
		
		
	More shader samples
This commit is contained in:
		
							
								
								
									
										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; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user