mpv-conf/shaders/ravu-zoom-r2.glsl

155 lines
735 KiB
Text
Raw 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 (luma, r2, compute)
//!HOOK LUMA
//!BIND HOOKED
//!BIND ravu_zoom_lut2
//!WIDTH OUTPUT.w
//!HEIGHT OUTPUT.h
//!OFFSET ALIGN
//!WHEN HOOKED.w OUTPUT.w < HOOKED.h OUTPUT.h < *
//!COMPUTE 32 8
#define LUTPOS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))
shared float samples[432];
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)) - 1;
ivec2 rectr = ivec2(floor(HOOKED_size * HOOKED_map(group_end) - 0.5)) + 2;
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 * 36] = HOOKED_tex(HOOKED_pt * (vec2(rectl + ivec2(x, y)) + vec2(0.5,0.5) + HOOKED_off)).x;
}
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(2.0, 288.0);
subpix_inv /= vec2(2.0, 288.0);
ivec2 ipos = ivec2(floor(pos)) - rectl;
int lpos = ipos.x + ipos.y * 36;
float sample0 = samples[-37 + lpos];
float sample1 = samples[-1 + lpos];
float sample2 = samples[35 + lpos];
float sample3 = samples[71 + lpos];
float sample4 = samples[-36 + lpos];
float sample5 = samples[0 + lpos];
float sample6 = samples[36 + lpos];
float sample7 = samples[72 + lpos];
float sample8 = samples[-35 + lpos];
float sample9 = samples[1 + lpos];
float sample10 = samples[37 + lpos];
float sample11 = samples[73 + lpos];
float sample12 = samples[-34 + lpos];
float sample13 = samples[2 + lpos];
float sample14 = samples[38 + lpos];
float sample15 = samples[74 + lpos];
vec3 abd = vec3(0.0);
float gx, gy;
gx = (sample4-sample0);
gy = (sample1-sample0);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
gx = (sample5-sample1);
gy = (sample2-sample0)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample6-sample2);
gy = (sample3-sample1)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample7-sample3);
gy = (sample3-sample2);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
gx = (sample8-sample0)/2.0;
gy = (sample5-sample4);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample9-sample1)/2.0;
gy = (sample6-sample4)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (sample10-sample2)/2.0;
gy = (sample7-sample5)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (sample11-sample3)/2.0;
gy = (sample7-sample6);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample12-sample4)/2.0;
gy = (sample9-sample8);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample13-sample5)/2.0;
gy = (sample10-sample8)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (sample14-sample6)/2.0;
gy = (sample11-sample9)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.07901060453704994;
gx = (sample15-sample7)/2.0;
gy = (sample11-sample10);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample12-sample8);
gy = (sample13-sample12);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04792235409415088;
gx = (sample13-sample9);
gy = (sample14-sample12)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample14-sample10);
gy = (sample15-sample13)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06153352068439959;
gx = (sample15-sample11);
gy = (sample15-sample14);
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;
float res = 0.0;
vec4 w;
w = texture(ravu_zoom_lut2, 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_lut2, vec2(0.5, coord_y) + subpix);
res += sample4 * w[0];
res += sample5 * w[1];
res += sample6 * w[2];
res += sample7 * w[3];
w = texture(ravu_zoom_lut2, vec2(0.0, coord_y) + subpix_inv);
res += sample15 * w[0];
res += sample14 * w[1];
res += sample13 * w[2];
res += sample12 * w[3];
w = texture(ravu_zoom_lut2, vec2(0.5, coord_y) + subpix_inv);
res += sample11 * w[0];
res += sample10 * w[1];
res += sample9 * w[2];
res += sample8 * w[3];
res = clamp(res, 0.0, 1.0);
imageStore(out_image, ivec2(gl_GlobalInvocationID), vec4(res, 0.0, 0.0, 0.0));
}
//!TEXTURE ravu_zoom_lut2
//!SIZE 18 2592
//!FORMAT rgba16hf
//!FILTER LINEAR
0000000000000000298d43a18e98fd93a70cc49f0099e1942f146c9f3995c40bf58f2c9b6595d8913297f09b60993197069cba9c5399e68caa999097e29c1a9d00000000000000000000003c00000000629c7d3b549f3c137c93533a799c1710060f37397198ea86cf8a13385d98de05850fff35679b37929307b833e29d7e959e9b372fc89d849900000000000000000117429d6c989897ba1526a00e9b959816142f9f449a9495c60f639e6b9ad995b88a529bae9800955998929c65957f8bf79aba9b579a189ac8951692159c0399769643966397e498989b6d3b502f02927b9ca13a6e2ece9498979939b12d218b33959c38c22c788c41932d37a32bdd9288994c35a42965976298d832b4262198ce9c422e1020269c839905a1569d8c993310a49be2973797ea0e6e9ce69a9198d910179d8b99ee94e914ab9b21985205a184c7992c985194ba98329ce3986895389af19a06996c98df978e948f99379a39966204a6957198f99c503acf33cb98579da639d632a78c3099c238003283913695e737f630010a66952936e02f2194df978d34c42d6d968c98e8316e2b7698bb9a892d5b26139b1f99f39ddb9ce599f70c21994801590f1217a19bf2967f93380ff69bf899a28eec0a399b67999d8cd119ad97d89dc6992892a7987898629495955597b1973d958596d0957798cb980991ad07de91d495909c333903367a9a429b9e384f3586988498dd378f34721110978236943379945c981d350332db93ea968b336c305d967999e730bd2d2f98b599a92c5b2916993998789b589b7898a98f9f97a497338da489029a169ace80b002f299bb99c90f5e96bb99209aae048c8428963396168cde9062970898868d1e96da978998ef94f4886490688e9d979d1045111f193094599a163816387f9a9d993c373d37b9996d963136323626940c94223522359d9459930a340b348e935595ff31003222942797cf2fd12fa897a199552b5f2be1984b98c59b4a9b0d9c029547984b98ca0f8a9278998e9b9b14bc913d9a339bed14958c60993b9bc811d799099752909c1546947d987098d290af97d598d4979f95b998cd980e951e969c9708966e916312409905363139a39b0e9850359f38099b66959134e037c8979f9392338236fa947f920332283511995c966d308f3398960198be2dea301a98119a4629a82cf2986599759c349cdb980097aa98859ba0158197949a9a9d111799952f9a229c4b183994279ad79c1d1116945698a99913053a9ce496819b6804639831991e987b969796a69a4197bf9029984c95ca0901952198d133513ab79cd796dc32a339809cf391f231c53887983692f130ed37ac973694e12f29363694e29cad2d8f34d5999598612be63198980f9c2826812d249b9499c89c7e9d62981d96879c7e9d73180c9a5d9c359f221ab196569adb9e8a16e296c09b8f9ed297b8931c98cb9aa681b497b199a59ac194d799609a0f992b98bf9bb59a67963b99329b199a5c950c9a4f996b2f6c3b449c3696612ea43a5d9df88ab12d9a3901962692d72c9c38ab0362939c2b2f374d909f9564294b35e795bd988626d5329f98f59b3f20532e6c9a7c98dd9ecda05d970000000000000000f59afa9aa1a03117ff8d5b9c93a0b68d9894b899bd9e96175694cc97c49bb88f8498969ae49c0d91c3987799cc991c988f99249971962a9c000000000000000000000000003c00004d1105a0803ba699ac19119c583a93904609599b34395214df8c70991338298b4f958e9cfc356b8a7496a09cc533eb96c4988f9f3b2f7a9c00000000000000000000000000000000d0a0bc9edf9cdd95df9e4da07899cf92a99d4e9f979cd798b998869f8f9d429c369e0e9fd19d6e9ce49c4d9d8799a49a799c7a9c8e9c749a00000000000000000000003c00000000da1f513bf717e717f91e393a021a051c601d2639c319891b461b153802180c19e1161236ac1224183495f83387945a85049bb42f799ae1950000000000000000e09ef69e4d9c8c9a8e9f46a0659d6c9b409f21a03c9d109b949e989f139d899ab29c289de49baa99369d559da49cb69ac39cd79cc89c969b229c619b0a9c8f9aa4979f9443989597d31c463bfc2fa6165f1f723a192f6119441e7e39362e551a511d8c38382d741adf192537222c8417e5155935182a4a13239501339e27b8925d9aca2e39229d98769a6a9b089c599a839d8d9afa95ed997b9d9f9dd09aeb98089d769d4b9b8e99ee9d9b9ea59cd39a7c9cb29cfe9b85999a9c999c009ee29c249ce89bdd9bae9ab49b7a9a9e9b859b35992f041b950e96b919353a05344b0a441e84392b337515c71caf381b323b1a461ccf372731b21953182a361730b11636149a34172e861455950532d72bac94ad9ad72d2427a499fd9bc29b939cee972f9c159b349965986b9d0a9d929b2c9a3a9dbb9d629db69b939d299e4a9df19b439c379cb39bf399839c5d9c529c5c9b869c419c2c9cca9ae19b0d9bc89b6e96ee94b88f7794ad954516233915364811291b8e3864351519501bcb37a334c5189d198036b433f5186718223521325117a50da43391308f1190940731fd2dfb90459ada2ca5298699a198469877983c98e3953c9a6898e18b8d9b959b9b9a5f9ca99cff9ca49c0a9b889cfa9ccd9cbf9b4f99a99c6c9cf79b2b9c859c5f9c5e9b1e9b439bc69b599af88c4998139c0a9c1d986d96299576981a1417381638f115661434374537421b911a32363436571b131928352b35b31a760c13341834af1cd20817321f321e15339402300530318a619bd72ba12b1f9431982a9a5e99b999e09a139b8e9ad399299aa29a0f9d379ca89c119d389db79b979c4c9db59cae9