mpv-conf/shaders/ravu-lite-r3.glsl

112 lines
64 KiB
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-Lite (r3, compute)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_lite_lut3
//!WIDTH 2 HOOKED.w *
//!HEIGHT 2 HOOKED.h *
//!WHEN HOOKED.w OUTPUT.w / 0.707106 < HOOKED.h OUTPUT.h / 0.707106 < *
//!COMPUTE 64 16 32 8
shared float inp[432];
void hook() {
ivec2 group_base = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize);
int local_pos = int(gl_LocalInvocationID.x) * 12 + int(gl_LocalInvocationID.y);
for (int id = int(gl_LocalInvocationIndex); id < 432; id += int(gl_WorkGroupSize.x * gl_WorkGroupSize.y)) {
int x = id / 12, y = id % 12;
inp[id] = HOOKED_tex(HOOKED_pt * vec2(float(group_base.x+x)+(-1.5), float(group_base.y+y)+(-1.5))).x;
}
groupMemoryBarrier();
barrier();
vec3 abd = vec3(0.0);
float gx, gy;
gx = (inp[local_pos + 25]-inp[local_pos + 1])/2.0;
gy = (inp[local_pos + 14]-inp[local_pos + 12])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (inp[local_pos + 26]-inp[local_pos + 2])/2.0;
gy = (inp[local_pos + 15]-inp[local_pos + 13])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 27]-inp[local_pos + 3])/2.0;
gy = (inp[local_pos + 16]-inp[local_pos + 14])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (inp[local_pos + 37]-inp[local_pos + 13])/2.0;
gy = (inp[local_pos + 26]-inp[local_pos + 24])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 38]-inp[local_pos + 14])/2.0;
gy = (inp[local_pos + 27]-inp[local_pos + 25])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.13080118386382833;
gx = (inp[local_pos + 39]-inp[local_pos + 15])/2.0;
gy = (inp[local_pos + 28]-inp[local_pos + 26])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 49]-inp[local_pos + 25])/2.0;
gy = (inp[local_pos + 38]-inp[local_pos + 36])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (inp[local_pos + 50]-inp[local_pos + 26])/2.0;
gy = (inp[local_pos + 39]-inp[local_pos + 37])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (inp[local_pos + 51]-inp[local_pos + 27])/2.0;
gy = (inp[local_pos + 40]-inp[local_pos + 38])/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
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 + 0.5) / 288.0;
vec4 res = vec4(0.0), w;
w = texture(ravu_lite_lut3, vec2(0.038461538461538464, coord_y));
res += inp[local_pos + 0] * w + inp[local_pos + 52] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.11538461538461539, coord_y));
res += inp[local_pos + 1] * w + inp[local_pos + 51] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.19230769230769232, coord_y));
res += inp[local_pos + 2] * w + inp[local_pos + 50] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.2692307692307692, coord_y));
res += inp[local_pos + 3] * w + inp[local_pos + 49] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.34615384615384615, coord_y));
res += inp[local_pos + 4] * w + inp[local_pos + 48] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.4230769230769231, coord_y));
res += inp[local_pos + 12] * w + inp[local_pos + 40] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.5, coord_y));
res += inp[local_pos + 13] * w + inp[local_pos + 39] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.5769230769230769, coord_y));
res += inp[local_pos + 14] * w + inp[local_pos + 38] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.6538461538461539, coord_y));
res += inp[local_pos + 15] * w + inp[local_pos + 37] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.7307692307692307, coord_y));
res += inp[local_pos + 16] * w + inp[local_pos + 36] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.8076923076923077, coord_y));
res += inp[local_pos + 24] * w + inp[local_pos + 28] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.8846153846153846, coord_y));
res += inp[local_pos + 25] * w + inp[local_pos + 27] * w.wzyx;
w = texture(ravu_lite_lut3, vec2(0.9615384615384616, coord_y));
res += inp[local_pos + 26] * w;
res = clamp(res, 0.0, 1.0);
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(0, 0), vec4(res[0], 0.0, 0.0, 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(0, 1), vec4(res[1], 0.0, 0.0, 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(1, 0), vec4(res[2], 0.0, 0.0, 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 2 + ivec2(1, 1), vec4(res[3], 0.0, 0.0, 0.0));
}
//!TEXTURE ravu_lite_lut3
//!SIZE 13 288
//!FORMAT rgba16hf
//!FILTER NEAREST
1e0e05847785268dd40e3e9b061b380bbb199e19ff18f718529bde118e03d81a3b895b0fae8d5a82e915ca1b319c4f911228aca13aa2f69d042dff2c08b00ab095a10f28d79d5ba2ab1b9216a8914b9c1c1b0018441ae517fb2c05b0f82c07b0543c543c543c543c4e8ca204fd093788eb97c19ca51d371726914292b81d3c1e9e9cfa96fd16501d3305e483468c520826191e1eaa9d7098d52821a18fa3fba05d2d5a2d34b033b01aa1e82821a1cca30c1f49199a992a9ecb16f01c8e109b1a482d26b0382d31b0533c533c533c533c4b8e9c05c68c750e459af89c7e1edf18939dca9d9320b320529e689b911b641f1f8af18f7310de807f0f4f1e799dc389e5296ea03ea361a4ae2d9e2d55b04ab0519c4a2a6ca5c2a4b620501bb09b4fa04793dd201e9e301c192e59b09f2d95b0513c543c543c513c3c8058869382f58df49bc59ce91fee13e3a0eca162241b243d9eb89aaf118c20a30f3f8cf48ea58aff98d320469e52931929aea452a5ad1a812f4e2f2eb132b1b0a49b29e410baa5e0202599348cf49e40a18424b4a15824cf2f54b1852f63b14e3c513c513c4e3ce90c5c8b150cf2917d9c2f98121db21538a17ca13524f523a29c079d4819481ffd00248edf8b110dd49a9620759dca8bf32806a5fba44f1d4b2ff12e06b102b1ada3f829dd9880a666223814959b1da13e9f432564a31f231f3051b16d2f9ab14d3c533c533c4d3c6f11cb0d0690ca92929c5198681b431a199ffe9ec9210f21ca9d239e421da51f6906808dd808cd84519fee157b13591eb228b7a4a5a33c1a762e102e97b086b0a59da32a42a28ea71225f021ada2bba42e221b27ada5aa9fe12fcab0512e75b14d3c543c543c4d3c83913c891d82cc02ee948c98ec1e469b18a6bea5b4279a27959a689ada96292008890193f085eb0bcf8cbc21539d519eef2765a6b4a52925bb3075300eb207b267a64729d522bba69922e2906f9d859f52a64728bda62128123149b2b0306cb2483c513c513c483c3f0fa395b3137f904d973f1820186c994ba423a4ee258425e595459c9b88401e18981f96a9135e18bf90ee20fa9a9d9e9a25a4a661a487263d30852f6bb162b1f7a4a7293d20d5a7f924841ea9a212a3a4a4162923a867266a3125b27630aeb2453c543c543c453c8501fa959e158489cd01e61a8298af95b39f1da05b224f21b19160941214bd16ce9cf69c6b1cbe1dfea3bd9e892172229b1a04a9bc1da628d52e162ea5b082b0cf9ac3290a9f47a8282a4b297ca958aa8428762c3aacc9a67f31f4b0c52ef1b2473c553c553c473c880f72986e107e83609b6c19d51f479fa5a86ea88a299029e9888c9f44993a211699c890560099175d951b238d9872a1782720a7d7a73c287531fb30b3b2b0b2f1a61e2a4b25e9a87e243e9a93a0cb9db2a8cb29a4a89129d331d9b22a3110b3453c533c533c453c4710e9983c0c990c6e97e21b6c1cd09e6da716a66a284928ff8bc3a0b415b320359ee19c3f1b761e381b7322b39859a37922f8a60da5da289e30dc2fc4b1a2b1e79fea2a7d1a38aade26ec22d2a5aca441a60e2a35a9032837323ab2833059b3403c573c573c403ccc1a9d174b9c9b980920da20ad9e36a2a9a0409d752206224e88279b1918a91ad2a786a7ef272228f1a913a96e2a1b295aa992acb8285f2dea2e742d96b050b05b27ca2c89a8a3ac552fca2e41af50af542ed530cdb0c0ad2534afae112bc4b43e3c5c3c5c3c3e3c4494f112120c178c3880689d901c3816f31a8f165a1af718769c320b2088ed1c74888190d00a0c0fb110cd1d019e78083f28aba11ca38e9d4a2d3a2d2bb023b02fa13028a89ccba3881d7e1985965b9ee51cfb184d1ad20e372d1cb0282d2ab0533c543c543c533c128eeb8d910cc70b5c9ad59c761d791a59916d8acd1dae1d3f9d2c9c6a1b771e180dcb0d7991e583ef19ce1e8f9e17996828b1a070a4b49c702d582d32b035b0159de32845a09da56a20e01c779c8da0fc1c5b1dd205200b8a2d1cb0182d50b0523c543c543c523c410e37094f8dfd8e1f9e859bf61d8d1b8f9ef19c7d215221e89e179fea1d88202f0436023e01ec870416771a4d9a1f814d2834a149a41c97ba2d3c2d40b029b07e1e042a2ca463a8532476244fa49ba4472433249fa2a1a15f2ee4afd22cccb04f3c563c563c4f3c340a0a05018f308e539b679c111f5b1417a1c3a1ba249223aa9f0e9c6c139b21ec0f7981d88ce690db9a3720579d960c93289ea4bea43c1dd92f102f3eb12fb1b0a4332a5d984da6eb217d985c9186a0b9a02525aba2ea231c3058b1492f75b14a3c563c563c4a3cdf109389ea898d91389bf393be1b260b93a154a18d249523829e2a9fdc1b2521bf8ce892da0c0912029f801da292e9187b27e9a514a3c422cd2f962e16b105b1c1a1432bd5a03aa88324e21c0ca0a1a343854127b0a5501f84301eb1b72ed8b1463c593c593c463c2b173d0ec49404958c9bb4162f16b292be9f56a009230522ada149a1432189224c93b396cd1410164aa4799e29219323bd252fa7169edb24422fd42dc3b0abb0541c4e2c70a696a95c280d2671a63ea80c27d7292da98fa5a23077b0722d0ab2453c5c3c5c3c453c5d90978e7d076e818e0e3894581d3b9d44a6cfa5ee279d27b29cfa9b8891eb20e88f9896900cbe1335883f20cb9a959d1c2507a6b1a4d72618312b300db21cb2e5a6a02a301f7fa71724608cd59d30a135a6bc281aa79a2779313fb2563085b2403c593c593c403c3715d192ca8ff290bb15461c6f8d799ea7a4e7a32f267825499d6e9ec91aba20de998d9bf918d71b739db419d91c9a99300ecba7699d4f29d0308e2e86b162b1a7a33b2c1da06ba