mpv-conf/shaders/ravu-zoom-r3-rgb.glsl

234 lines
1.8 MiB
Text
Raw Permalink Normal View History

2021-12-03 20:50:08 +08:00
//
// This program 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 of the License, or
// (at your option) any later version.
//
// This program 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 program. If not, see <http://www.gnu.org/licenses/>.
//!DESC RAVU-Zoom (rgb, r3, compute)
//!HOOK MAIN
//!BIND HOOKED
//!BIND ravu_zoom_lut3
//!WIDTH OUTPUT.w
//!HEIGHT OUTPUT.h
//!OFFSET ALIGN
//!WHEN HOOKED.w OUTPUT.w < HOOKED.h OUTPUT.h < *
//!COMPUTE 32 8
const vec3 color_primary = vec3(0.2126, 0.7152, 0.0722);
#define LUTPOS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))
shared vec3 samples[532];
void hook() {
ivec2 group_begin = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize);
ivec2 group_end = group_begin + ivec2(gl_WorkGroupSize) - ivec2(1);
ivec2 rectl = ivec2(floor(HOOKED_size * HOOKED_map(group_begin) - 0.5)) - 2;
ivec2 rectr = ivec2(floor(HOOKED_size * HOOKED_map(group_end) - 0.5)) + 3;
ivec2 rect = rectr - rectl + 1;
for (int id = int(gl_LocalInvocationIndex); id < rect.x * rect.y; id += int(gl_WorkGroupSize.x * gl_WorkGroupSize.y)) {
int y = id / rect.x, x = id % rect.x;
samples[x + y * 38] = HOOKED_tex(HOOKED_pt * (vec2(rectl + ivec2(x, y)) + vec2(0.5,0.5) + HOOKED_off)).xyz;
}
groupMemoryBarrier();
barrier();
vec2 pos = HOOKED_size * HOOKED_map(ivec2(gl_GlobalInvocationID));
vec2 subpix = fract(pos - 0.5);
pos -= subpix;
subpix = LUTPOS(subpix, vec2(9.0));
vec2 subpix_inv = 1.0 - subpix;
subpix /= vec2(5.0, 288.0);
subpix_inv /= vec2(5.0, 288.0);
ivec2 ipos = ivec2(floor(pos)) - rectl;
int lpos = ipos.x + ipos.y * 38;
vec3 sample0 = samples[-78 + lpos];
vec3 sample1 = samples[-40 + lpos];
float luma1 = dot(sample1, color_primary);
vec3 sample2 = samples[-2 + lpos];
float luma2 = dot(sample2, color_primary);
vec3 sample3 = samples[36 + lpos];
float luma3 = dot(sample3, color_primary);
vec3 sample4 = samples[74 + lpos];
float luma4 = dot(sample4, color_primary);
vec3 sample5 = samples[112 + lpos];
vec3 sample6 = samples[-77 + lpos];
float luma6 = dot(sample6, color_primary);
vec3 sample7 = samples[-39 + lpos];
float luma7 = dot(sample7, color_primary);
vec3 sample8 = samples[-1 + lpos];
float luma8 = dot(sample8, color_primary);
vec3 sample9 = samples[37 + lpos];
float luma9 = dot(sample9, color_primary);
vec3 sample10 = samples[75 + lpos];
float luma10 = dot(sample10, color_primary);
vec3 sample11 = samples[113 + lpos];
float luma11 = dot(sample11, color_primary);
vec3 sample12 = samples[-76 + lpos];
float luma12 = dot(sample12, color_primary);
vec3 sample13 = samples[-38 + lpos];
float luma13 = dot(sample13, color_primary);
vec3 sample14 = samples[0 + lpos];
float luma14 = dot(sample14, color_primary);
vec3 sample15 = samples[38 + lpos];
float luma15 = dot(sample15, color_primary);
vec3 sample16 = samples[76 + lpos];
float luma16 = dot(sample16, color_primary);
vec3 sample17 = samples[114 + lpos];
float luma17 = dot(sample17, color_primary);
vec3 sample18 = samples[-75 + lpos];
float luma18 = dot(sample18, color_primary);
vec3 sample19 = samples[-37 + lpos];
float luma19 = dot(sample19, color_primary);
vec3 sample20 = samples[1 + lpos];
float luma20 = dot(sample20, color_primary);
vec3 sample21 = samples[39 + lpos];
float luma21 = dot(sample21, color_primary);
vec3 sample22 = samples[77 + lpos];
float luma22 = dot(sample22, color_primary);
vec3 sample23 = samples[115 + lpos];
float luma23 = dot(sample23, color_primary);
vec3 sample24 = samples[-74 + lpos];
float luma24 = dot(sample24, color_primary);
vec3 sample25 = samples[-36 + lpos];
float luma25 = dot(sample25, color_primary);
vec3 sample26 = samples[2 + lpos];
float luma26 = dot(sample26, color_primary);
vec3 sample27 = samples[40 + lpos];
float luma27 = dot(sample27, color_primary);
vec3 sample28 = samples[78 + lpos];
float luma28 = dot(sample28, color_primary);
vec3 sample29 = samples[116 + lpos];
float luma29 = dot(sample29, color_primary);
vec3 sample30 = samples[-73 + lpos];
vec3 sample31 = samples[-35 + lpos];
float luma31 = dot(sample31, color_primary);
vec3 sample32 = samples[3 + lpos];
float luma32 = dot(sample32, color_primary);
vec3 sample33 = samples[41 + lpos];
float luma33 = dot(sample33, color_primary);
vec3 sample34 = samples[79 + lpos];
float luma34 = dot(sample34, color_primary);
vec3 sample35 = samples[117 + lpos];
vec3 abd = vec3(0.0);
float gx, gy;
gx = (luma13-luma1)/2.0;
gy = (luma8-luma6)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
gx = (luma14-luma2)/2.0;
gy = (-luma10+8.0*luma9-8.0*luma7+luma6)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (luma15-luma3)/2.0;
gy = (-luma11+8.0*luma10-8.0*luma8+luma7)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (luma16-luma4)/2.0;
gy = (luma11-luma9)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
gx = (-luma25+8.0*luma19-8.0*luma7+luma1)/12.0;
gy = (luma14-luma12)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (-luma26+8.0*luma20-8.0*luma8+luma2)/12.0;
gy = (-luma16+8.0*luma15-8.0*luma13+luma12)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (-luma27+8.0*luma21-8.0*luma9+luma3)/12.0;
gy = (-luma17+8.0*luma16-8.0*luma14+luma13)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (-luma28+8.0*luma22-8.0*luma10+luma4)/12.0;
gy = (luma17-luma15)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (-luma31+8.0*luma25-8.0*luma13+luma7)/12.0;
gy = (luma20-luma18)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (-luma32+8.0*luma26-8.0*luma14+luma8)/12.0;
gy = (-luma22+8.0*luma21-8.0*luma19+luma18)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (-luma33+8.0*luma27-8.0*luma15+luma9)/12.0;
gy = (-luma23+8.0*luma22-8.0*luma20+luma19)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (-luma34+8.0*luma28-8.0*luma16+luma10)/12.0;
gy = (luma23-luma21)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (luma31-luma19)/2.0;
gy = (luma26-luma24)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
gx = (luma32-luma20)/2.0;
gy = (-luma28+8.0*luma27-8.0*luma25+luma24)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (luma33-luma21)/2.0;
gy = (-luma29+8.0*luma28-8.0*luma26+luma25)/12.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (luma34-luma22)/2.0;
gy = (luma29-luma27)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
float a = abd.x, b = abd.y, d = abd.z;
float T = a + d, D = a * d - b * b;
float delta = sqrt(max(T * T / 4.0 - D, 0.0));
float L1 = T / 2.0 + delta, L2 = T / 2.0 - delta;
float sqrtL1 = sqrt(L1), sqrtL2 = sqrt(L2);
float theta = mix(mod(atan(L1 - a, b) + 3.141592653589793, 3.141592653589793), 0.0, abs(b) < 1.192092896e-7);
float lambda = sqrtL1;
float mu = mix((sqrtL1 - sqrtL2) / (sqrtL1 + sqrtL2), 0.0, sqrtL1 + sqrtL2 < 1.192092896e-7);
float angle = floor(theta * 24.0 / 3.141592653589793);
float strength = mix(mix(0.0, 1.0, lambda >= 0.004), mix(2.0, 3.0, lambda >= 0.05), lambda >= 0.016);
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
float coord_y = ((angle * 4.0 + strength) * 3.0 + coherence) / 288.0;
vec3 res = vec3(0.0);
vec4 w;
w = texture(ravu_zoom_lut3, vec2(0.0, coord_y) + subpix);
res += sample0 * w[0];
res += sample1 * w[1];
res += sample2 * w[2];
res += sample3 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.2, coord_y) + subpix);
res += sample4 * w[0];
res += sample5 * w[1];
res += sample6 * w[2];
res += sample7 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.4, coord_y) + subpix);
res += sample8 * w[0];
res += sample9 * w[1];
res += sample10 * w[2];
res += sample11 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.6, coord_y) + subpix);
res += sample12 * w[0];
res += sample13 * w[1];
res += sample14 * w[2];
res += sample15 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.8, coord_y) + subpix);
res += sample16 * w[0];
res += sample17 * w[1];
w = texture(ravu_zoom_lut3, vec2(0.0, coord_y) + subpix_inv);
res += sample35 * w[0];
res += sample34 * w[1];
res += sample33 * w[2];
res += sample32 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.2, coord_y) + subpix_inv);
res += sample31 * w[0];
res += sample30 * w[1];
res += sample29 * w[2];
res += sample28 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.4, coord_y) + subpix_inv);
res += sample27 * w[0];
res += sample26 * w[1];
res += sample25 * w[2];
res += sample24 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.6, coord_y) + subpix_inv);
res += sample23 * w[0];
res += sample22 * w[1];
res += sample21 * w[2];
res += sample20 * w[3];
w = texture(ravu_zoom_lut3, vec2(0.8, coord_y) + subpix_inv);
res += sample19 * w[0];
res += sample18 * w[1];
res = clamp(res, 0.0, 1.0);
imageStore(out_image, ivec2(gl_GlobalInvocationID), vec4(res, 1.0));
}
//!TEXTURE ravu_zoom_lut3
//!SIZE 45 2592
//!FORMAT rgba16hf
//!FILTER LINEAR
0000000000000000f38e809491134494b693fb94c4840a8a2a8feb926e0b03928f8d7d90e2001390258de091398ab7910c8be892818e6e90368a4393e38f4592000000000000000000000000000000008a94648dd794c29b850f1e96f198a39a518f238965903798df8e038b2d8c5694118fe78ae08cbf94cd8b36824191f394e98d97847193ff990000000000000000000000000000000050a15d9b9f94e991ada09196ce944294e89e7298e48bc18a329b3595b38b2f05c1995b96748fcd89989507961a91d886d00ec6957d93438c000000000000000000000000003c0000b418159f823b7b9fa2192099583ad79a5c17e7983839aa999d14f79512386f9733107098033621992e8b1a9acc339e9a7c93139c4b2f2e9c00000000000000000000000000000000391c998100000000851d7719000000008318580d00000000be14d70d000000001411640800000000648c6708000000002394008b000000000000000000000000a68dfb9261140f941993c295a1192396699302974e8dbb844f909e93170cc99330909190b2819190c48e24914e010c8e06915494c48f95939d8d02931b8e0f92b894570ffc121996b593198d8f94809a7b960d93d096689c2d83e3022796aa960892e98e1592b3980091d98e9c8c8393d68e4584d98e5a948b914c8f61943496ab8d1189c3948d94f4119f125c970696f49ee99a3d95419344a19e9ccd069c957c9fdd98c9971f0a249fee9940910a8ffd997a95718e1204f5988f965a914388eb9427986495d291d2133f964495898ec919fd96b6092695c61528a06f3b712f20183a9fad3a702e56164d9ca239a52d1e18f19ba138c92cc4143d982c37b12b6b131b9a4c3588297090c39bd532ce26bb94839c5c2e61214198dc98929e9b9c1618109100000000d91cc391000000009416df92000000003818230f000000003813e20c00000000eb034c0d00000000e094d48d00000000b896298f00000000e0986c0e000000007404218f1d147d8bb58ce1912115b58d828d26921e12bf8fb6905093ae0ddc90fa8d78907d095a8ce08eff91e18483909787af8e700cc08e5d8f52930c8eab901b86178dcd05e38a2491f28de4916d9831928f8ea493169aa791fe8fb791b998ea92b08e7f910d98a9906d8cd98c9d92bf91d1908a8d7d94728b03894c982391bc8e138a179257930a84cb81b88d9b8b0b9c6a990c955292359fa69bd1955e91919eb09a71922190b29d709ae9924891d298f995d28b958245987f9774936190e9850e95e8903186a51172946694358f8115298db58f028cd212ba9e4d3ad633ed162da0ac39de3296166f9dcd38f331e8155f9ced37f330111483982736e52fe713bd9a8e34c72d3c0eb799ed31882bb391da9b902db9267591fc989c9c1b9acc02e18d0000000035149f83000000004815db0e00000000c411810f00000000f10a8a10000000003c914608000000002c816702000000005497318e000000005495019000000000509738858f14e30e9a9139936b12e2179c912d02e711ae88d08b869860103481f98f23908181c78bf80de10c6a10c9090c946b942314c211d98b908ec7073c86a388bf867a08c086218a3888b98b2296fb91c9909b948390d892a8917590df96a38a0a97c48c9494a88f728d658dfe90ca89c390dd13b6089d0f33970394cb10258deb8c538ceb8dc0867a8e62980881ba9967984393c38b9f9d0d9ca3954791eb9c7b9a2490318a339cdd99c98f3c82669793960b8f4788f1920e93a006e40b3c11a597c2941b9a85118c98e38dd081a914090bab8a59885213559d33390636d813949ea4385835cb130d9ce73792342516cd9989369733ef135e961a350132fb9e1394983378307389409af730dd2d2c846b99b62c7729b38cc797e09ac099ee95860800000000fe11ff0900000000158d501400000000eb84f313000000007d8de10f0000000059801f1400000000a6977391000000002495789700000000dd941989000000001701af8d9911fd104a80738ca213e012f28d3f902f0e6010a8902c8ec809a20c2692fe91498cfc8e898e208d24011900128c848e1387ed89e68c4f8ee989aa8ac705448461060e06cc8d078dbc8d7194af8e558ce78f29967a8f2789d68fa5941f90a20a3a91e8931791708e4c908592168ef48f728c6c8ec68e948f828bbf901790518ff98df18fe98a0a01eb83d68123998b98c7946f8d099c3d9b8595b48fed9b599b67924988499b799a8e914608ff960497fb90fd16f895bb95da8fda8feb914091c58de18b1385a203aa8e688ea810a3100488c08b840def9a173817385f13cd9a42374237f51360983536353675134d9625352635ff0eee94083411345b130b96fd31fe31cb094297d02fd42f4d8d6398712b712b9f8c2796199a039a0d9b521000000000df9a9b1300000000fc979b14000000002196fa15000000005492c41800000000a595eb0d000000007696f606000000006097728c000000005c95978e000000002789fb8cec0efc130c953d96fa9384171f9223941f902f0e2f8a0a0bd61323178790748d1984410c1c8dc88efc8427090f926407de901c8a219006915090748fb8960908080cbc0dbf8c5b8d278f7b9475972804a0845092f99108847594dc0b2816329e20097a84f28c7f0b418a098c748cd88d8c88bd8ea588a58e80082e901a93620f918fef928280ec9726079f02ea98039a0d96d78fde9a839c0296b48adb98009b5897c48e5898f4998911309fab968697478efc0cfd953795a090759859920c90b68aaa8d6e910f0d5a94aa122b964115be012288e1061696053633399b1246915235a438260273129734e437001631109e338e3