mpv-conf/shaders/ravu-3x-r2-yuv.glsl

130 lines
40 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-3x (yuv, r2)
//!HOOK NATIVE
//!BIND HOOKED
//!BIND ravu_3x_lut2
//!WIDTH 3 HOOKED.w *
//!HEIGHT 3 HOOKED.h *
//!WHEN HOOKED.w OUTPUT.w / 0.471404 < HOOKED.h OUTPUT.h / 0.471404 < * LUMA.w 0 > *
//!COMPUTE 96 24 32 8
shared vec3 inp[340];
shared float inp_luma[340];
void hook() {
ivec2 group_base = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize);
int local_pos = int(gl_LocalInvocationID.x) * 10 + int(gl_LocalInvocationID.y);
for (int id = int(gl_LocalInvocationIndex); id < 340; id += int(gl_WorkGroupSize.x * gl_WorkGroupSize.y)) {
int x = id / 10, y = id % 10;
inp[id] = HOOKED_tex(HOOKED_pt * vec2(float(group_base.x+x)+(-0.5), float(group_base.y+y)+(-0.5))).xyz;
inp_luma[id] = inp[id].x;
}
groupMemoryBarrier();
barrier();
float luma0 = inp_luma[local_pos + 0];
float luma1 = inp_luma[local_pos + 1];
float luma2 = inp_luma[local_pos + 2];
float luma3 = inp_luma[local_pos + 10];
float luma4 = inp_luma[local_pos + 11];
float luma5 = inp_luma[local_pos + 12];
float luma6 = inp_luma[local_pos + 20];
float luma7 = inp_luma[local_pos + 21];
float luma8 = inp_luma[local_pos + 22];
vec3 abd = vec3(0.0);
float gx, gy;
gx = (luma3-luma0);
gy = (luma1-luma0);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (luma4-luma1);
gy = (luma2-luma0)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma5-luma2);
gy = (luma2-luma1);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (luma6-luma0)/2.0;
gy = (luma4-luma3);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma7-luma1)/2.0;
gy = (luma5-luma3)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.13080118386382833;
gx = (luma8-luma2)/2.0;
gy = (luma5-luma4);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma6-luma3);
gy = (luma7-luma6);
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (luma7-luma4);
gy = (luma8-luma6)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma8-luma5);
gy = (luma8-luma7);
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.005), 2.0, lambda >= 0.02);
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
float coord_y = ((angle * 3.0 + strength) * 3.0 + coherence + 0.5) / 216.0;
mat4x3 res0 = mat4x3(0.0), res1 = mat4x3(0.0);
vec4 w0, w1;
w0 = texture(ravu_3x_lut2, vec2(0.05, coord_y));
w1 = texture(ravu_3x_lut2, vec2(0.15, coord_y));
res0 += outerProduct(inp[local_pos + 0], w0) + outerProduct(inp[local_pos + 22], w1.wzyx);
res1 += outerProduct(inp[local_pos + 0], w1) + outerProduct(inp[local_pos + 22], w0.wzyx);
w0 = texture(ravu_3x_lut2, vec2(0.25, coord_y));
w1 = texture(ravu_3x_lut2, vec2(0.35, coord_y));
res0 += outerProduct(inp[local_pos + 1], w0) + outerProduct(inp[local_pos + 21], w1.wzyx);
res1 += outerProduct(inp[local_pos + 1], w1) + outerProduct(inp[local_pos + 21], w0.wzyx);
w0 = texture(ravu_3x_lut2, vec2(0.45, coord_y));
w1 = texture(ravu_3x_lut2, vec2(0.55, coord_y));
res0 += outerProduct(inp[local_pos + 2], w0) + outerProduct(inp[local_pos + 20], w1.wzyx);
res1 += outerProduct(inp[local_pos + 2], w1) + outerProduct(inp[local_pos + 20], w0.wzyx);
w0 = texture(ravu_3x_lut2, vec2(0.65, coord_y));
w1 = texture(ravu_3x_lut2, vec2(0.75, coord_y));
res0 += outerProduct(inp[local_pos + 10], w0) + outerProduct(inp[local_pos + 12], w1.wzyx);
res1 += outerProduct(inp[local_pos + 10], w1) + outerProduct(inp[local_pos + 12], w0.wzyx);
w0 = texture(ravu_3x_lut2, vec2(0.85, coord_y));
w1 = texture(ravu_3x_lut2, vec2(0.95, coord_y));
res0 += outerProduct(inp[local_pos + 11], w0);
res1 += outerProduct(inp[local_pos + 11], w1);
res0[0] = clamp(res0[0], 0.0, 1.0);
res0[1] = clamp(res0[1], 0.0, 1.0);
res0[2] = clamp(res0[2], 0.0, 1.0);
res0[3] = clamp(res0[3], 0.0, 1.0);
res1[0] = clamp(res1[0], 0.0, 1.0);
res1[1] = clamp(res1[1], 0.0, 1.0);
res1[2] = clamp(res1[2], 0.0, 1.0);
res1[3] = clamp(res1[3], 0.0, 1.0);
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(0, 0), vec4(res0[0], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(0, 1), vec4(res0[1], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(0, 2), vec4(res0[2], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(1, 0), vec4(res0[3], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(1, 1), vec4(inp[local_pos + 11], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(1, 2), vec4(res1[0], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(2, 0), vec4(res1[1], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(2, 1), vec4(res1[2], 0.0));
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(2, 2), vec4(res1[3], 0.0));
}
//!TEXTURE ravu_3x_lut2
//!SIZE 10 216
//!FORMAT rgba16hf
//!FILTER NEAREST
24303b2aea26e7296718e6253f0ade9aba31c932b6312d2a262a4526502146264d276f2a33307a1a022a4399ec110226fa310b2b83270a339f22ed31e92a4c2774368d3876369438943876368d3874363e2f5426371f992572a31c0f8ba52ea82f32fa331d32d729cb29ea2683251f2705247928fe2f36a1e426ada7caa4231b90332d2d892a9934d1275133c82ce62959366f3866368a388a3866366f3859366d2dad9e9aa3d218d4a65ea572aba7aa6d32703441325e293029f7298d2d042a902353269a2fa4a5de1fcca9a7aae6a21b34262e082df234942b5733842c162b80367e389936b438b43899367e388036682eeb259c9cca1f4c9a6ca878a779a56232c2333d32d920592058a51ba6f5a4731c6328352f82982c20d6a6a3a85ea967334b286ca45634a2aaf7328d259fa69638e039a138053a053aa138e03996388e2c5720c8a4d59f4aa077a936a787a671325a3323321825d024ea9eaea4199cf6206829f22e01a01b9e57aaf4aa64ac8c34552dc3249f3494ab56331c2884a67538a3398e38173a173a8e38a3397538b826b1a808ac7fa463a5c9a808a827a802330134b332ea28be28842754262f284a1c8f28982e2ba5e1a382ad93adf7ad6e35cb30f62db834cca6b632632645a63b385c395638d839d83956385c393b382e317c30fa2fd9a26d2150af9cb074b0bc300631442fad94760aa323d4268325b23059313b326725c8a4dbb012b1b9af7534822db71ffa34b3aecd321925eba843388e39b6385b3a5b3ab6388e394338c32de62c0a2e6b8c159c30acc2ad0dafdf30d030462e869ee820702a372c822c49304130e130201e829d39b002af57ad863672334230903436af0c2e2eaaafac9336b0388e38a03aa03a8e38b038933603b17db29bb0ec26be2726a3efadafad38317131a31840ab27aa882de0322c32fe348e35393769275e24cdaee1b042b0db38cb35fe3343342eac0db008b43ab34b35db38d038663a663ad038db384b35512f3e297d24c228749a0322db9e20a1d1318b32a731e52803294524b5161125aa26982a1e305704e72810a0fe9f7c206932e52a99250d33319fee31dc298c240f37ee383137183918393137ee380f37dc2d42261e1ddb24c09e48110fa33fa4da31b2325d318c277d27801ea31ddc225828df2b5830c29845266ba569a5bea01a34f62dad296034b38ccb32c72bcb25ce36a4383037123912393037a438ce36e22cc31ab4a445201ca5ac19daa417a660318c32e830be268426498f2224481f222af62ce2306aa12425bea974a96ca52135a231c42f0e3579298a33722eba2bd635bb375f36bc38bc385f36bb37d6358f2d4c236da2a71d879d05a71da5d5a39e328c3325327c240924d2a695a85fa5cc1f6229aa2fa599bb1e06a7dea80baadb33542a27a33f34d1abbe329b25fea78b38d839af38123a123aaf38d8398b38372954a4f3a88aa0c39fd9a53a9f299dbf324e33d6314d254c24dfa357a6b59f90274a2c5730f69d069cc0ab78ac7fad18353a2fe528973402ac3332031597aa6738ac39b3381e3a1e3ab338ac3967386fa492acbfad6ea2bda24e1faf24bd24e8326d33c6311e2616255ca40da5cd9de62ac82d1c3130a1f09cc3ad48ae18af7b366e320030cd348ba8793110a310ac08384b396e38dc39dc396e384b3908381730862fcd2e06a1481c4cad3daf9baf3d314530942c1b9d39200a8c3928392a5b306731723220275aa6a8b072b16eb05d350930401c033533af75322c26d3a7873760391539623a623a153960398737ae28b429e62ce71ce2a1f2a862acb8ad21315b2ee022eda416253529212d392e0b30fb300832da23daa0e6ae3cae2fad7438ab3597318134bbaff0a962b0c7aec43487388c39b73ab73a8c398738c43444ae71ac97a3651c6a963110e3a821acca30fc29a0acb2a26620c62c582f5e30f53258340735ce1ddd9f3eb029af0eaef239c23798340c3462ae6bb0b4b279b1da3119387439ce3ace3a74391938da31fb2eb8288423d3284f9b8823519df1a0f731a632aa311b293c290924e5175c25e226b32a3630191512290e9d0a9feb208032132bac25fb32289dc531ac297c24fa36e9382e370d390d392e37e938fa36722def245a132d25bc9f1d1ed29f1ea2f03195322531cc27f327bc1b041c47237029d52cf0308e13ba27dea41da646a23a34122e162941346d9d2732ba293a21c236b3386237133913396237b338c236282cf499dca5e31c24a68a1466a41aa5d231b432db3069287f2755956624491fc02a862d8131619d5d280ea941a99ca35b35c831952ef1348b2814334b2d6428bf35c237a336a938a938a336c237bf35f42c331fc0a4f21dbe9f75a550a340a2f932b1332d323d2575241ca85ca9a1a5511b3f29c72f5e9a2c20bea576a8e3a90834902a82a43834eeab973201253ba88038db39bc380f3a0f3abc38db39803812269aa7e5a992a0439f4ca3b10a2e0a34337633b931be258c23d2a64aa85ca26427902c9f30b39c2588d2aa3cac52ad3f35422fe926873440acd131c79f6eab6238c039de38233a233ade38c039623873a805ad9fad3ca404a2ef1b64245724c233c033aa310027a12416a7f6a607a095298b2d2a3108a05498b3ac93ad99aebf366832a82ec034fea9de3003a826ad04386c39ba38f139f139ba386c390438f72c322c342c06a0031624a95aac37ad863227311a2d0b9e6321f4a67524292aa02e9b3009323d281ca7c0aec6b064b0be350230d6a6f7342bafbe3180228ea73c377c396f39613a613a6f397c393c374a98f022802a621de8a10aa231a9f9aa9b31782d36a2caa65e2647212d2c612daf2fb5315433042673a4a0ae83af02a