mpv-conf/shaders/ravu-3x-r3-rgb.glsl

175 lines
97 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 (rgb, r3)
//!HOOK MAIN
//!BIND HOOKED
//!BIND ravu_3x_lut3
//!WIDTH 3 HOOKED.w *
//!HEIGHT 3 HOOKED.h *
//!WHEN HOOKED.w OUTPUT.w / 0.471404 < HOOKED.h OUTPUT.h / 0.471404 < *
//!COMPUTE 96 24 32 8
const vec3 color_primary = vec3(0.2126, 0.7152, 0.0722);
shared vec3 inp[432];
shared float inp_luma[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))).xyz;
inp_luma[id] = dot(inp[id], color_primary);
}
groupMemoryBarrier();
barrier();
float luma1 = inp_luma[local_pos + 1];
float luma2 = inp_luma[local_pos + 2];
float luma3 = inp_luma[local_pos + 3];
float luma5 = inp_luma[local_pos + 12];
float luma6 = inp_luma[local_pos + 13];
float luma7 = inp_luma[local_pos + 14];
float luma8 = inp_luma[local_pos + 15];
float luma9 = inp_luma[local_pos + 16];
float luma10 = inp_luma[local_pos + 24];
float luma11 = inp_luma[local_pos + 25];
float luma12 = inp_luma[local_pos + 26];
float luma13 = inp_luma[local_pos + 27];
float luma14 = inp_luma[local_pos + 28];
float luma15 = inp_luma[local_pos + 36];
float luma16 = inp_luma[local_pos + 37];
float luma17 = inp_luma[local_pos + 38];
float luma18 = inp_luma[local_pos + 39];
float luma19 = inp_luma[local_pos + 40];
float luma21 = inp_luma[local_pos + 49];
float luma22 = inp_luma[local_pos + 50];
float luma23 = inp_luma[local_pos + 51];
vec3 abd = vec3(0.0);
float gx, gy;
gx = (luma11-luma1)/2.0;
gy = (luma7-luma5)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (luma12-luma2)/2.0;
gy = (luma8-luma6)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma13-luma3)/2.0;
gy = (luma9-luma7)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (luma16-luma6)/2.0;
gy = (luma12-luma10)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma17-luma7)/2.0;
gy = (luma13-luma11)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.13080118386382833;
gx = (luma18-luma8)/2.0;
gy = (luma14-luma12)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma21-luma11)/2.0;
gy = (luma17-luma15)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.1018680644198163;
gx = (luma22-luma12)/2.0;
gy = (luma18-luma16)/2.0;
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.11543163961422666;
gx = (luma23-luma13)/2.0;
gy = (luma19-luma17)/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.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_lut3, vec2(0.019230769230769232, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.057692307692307696, coord_y));
res0 += outerProduct(inp[local_pos + 0], w0) + outerProduct(inp[local_pos + 52], w1.wzyx);
res1 += outerProduct(inp[local_pos + 0], w1) + outerProduct(inp[local_pos + 52], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.09615384615384616, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.1346153846153846, coord_y));
res0 += outerProduct(inp[local_pos + 1], w0) + outerProduct(inp[local_pos + 51], w1.wzyx);
res1 += outerProduct(inp[local_pos + 1], w1) + outerProduct(inp[local_pos + 51], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.17307692307692307, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.21153846153846154, coord_y));
res0 += outerProduct(inp[local_pos + 2], w0) + outerProduct(inp[local_pos + 50], w1.wzyx);
res1 += outerProduct(inp[local_pos + 2], w1) + outerProduct(inp[local_pos + 50], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.25, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.28846153846153844, coord_y));
res0 += outerProduct(inp[local_pos + 3], w0) + outerProduct(inp[local_pos + 49], w1.wzyx);
res1 += outerProduct(inp[local_pos + 3], w1) + outerProduct(inp[local_pos + 49], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.3269230769230769, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.36538461538461536, coord_y));
res0 += outerProduct(inp[local_pos + 4], w0) + outerProduct(inp[local_pos + 48], w1.wzyx);
res1 += outerProduct(inp[local_pos + 4], w1) + outerProduct(inp[local_pos + 48], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.40384615384615385, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.4423076923076923, coord_y));
res0 += outerProduct(inp[local_pos + 12], w0) + outerProduct(inp[local_pos + 40], w1.wzyx);
res1 += outerProduct(inp[local_pos + 12], w1) + outerProduct(inp[local_pos + 40], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.4807692307692308, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.5192307692307693, coord_y));
res0 += outerProduct(inp[local_pos + 13], w0) + outerProduct(inp[local_pos + 39], w1.wzyx);
res1 += outerProduct(inp[local_pos + 13], w1) + outerProduct(inp[local_pos + 39], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.5576923076923077, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.5961538461538461, coord_y));
res0 += outerProduct(inp[local_pos + 14], w0) + outerProduct(inp[local_pos + 38], w1.wzyx);
res1 += outerProduct(inp[local_pos + 14], w1) + outerProduct(inp[local_pos + 38], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.6346153846153846, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.6730769230769231, coord_y));
res0 += outerProduct(inp[local_pos + 15], w0) + outerProduct(inp[local_pos + 37], w1.wzyx);
res1 += outerProduct(inp[local_pos + 15], w1) + outerProduct(inp[local_pos + 37], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.7115384615384616, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.75, coord_y));
res0 += outerProduct(inp[local_pos + 16], w0) + outerProduct(inp[local_pos + 36], w1.wzyx);
res1 += outerProduct(inp[local_pos + 16], w1) + outerProduct(inp[local_pos + 36], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.7884615384615384, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.8269230769230769, coord_y));
res0 += outerProduct(inp[local_pos + 24], w0) + outerProduct(inp[local_pos + 28], w1.wzyx);
res1 += outerProduct(inp[local_pos + 24], w1) + outerProduct(inp[local_pos + 28], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.8653846153846154, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.9038461538461539, coord_y));
res0 += outerProduct(inp[local_pos + 25], w0) + outerProduct(inp[local_pos + 27], w1.wzyx);
res1 += outerProduct(inp[local_pos + 25], w1) + outerProduct(inp[local_pos + 27], w0.wzyx);
w0 = texture(ravu_3x_lut3, vec2(0.9423076923076923, coord_y));
w1 = texture(ravu_3x_lut3, vec2(0.9807692307692307, coord_y));
res0 += outerProduct(inp[local_pos + 26], w0);
res1 += outerProduct(inp[local_pos + 26], 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 + 26], 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_lut3
//!SIZE 26 216
//!FORMAT rgba16hf
//!FILTER NEAREST
38892004018c74806e00eb8be3034d89241f53a17c9ca421431b561a8da0679a6924612654240523e82248211c242b21609c49a18e1f4c1bc621659a8ba0b81a0b8c2204f5889b006700548917048f8bd8208f22e11b17a101a1489d10194d9d962ef6260124b22661a046228ea1669ebe316033b7316c274227f322f122b7223f243827aa2e18a0e826f39d58a197226f1cce222d21dfa0f9a02f9d1319319d1726cf249623a827db24ef25ad245c23e2312e2811257e337924d9311228de248536b1388736b438b4388736b1388536618d8408e18a6f8a8584c48c5e064d853f0556a228a0061e7e0c9217ce9e6a9b5d2075245b20eb1f1720b01f2323fa1f54a09ea2df0c8507091e0f9c339f29174b8b66081c8d7b856789e8867c068d8c6a1ddd1f140390a212a271a2079d5ba2922efa2516221e2510a3111984a562a40332d933ed31d52776274622fe24002220242c27e82ef0a1cd2519a44ba53a1b841806212620c4a12da254a24b9d64a2cf27152679253b28d4251c277925ef249d32f22920282f34282777327d297727c036bb38cb36c938c938cb36bb38c03623030e0eb50c0608300cf0098d0e980eec9ddba187a13195179c389bc39fb19f1d2197232e2110215221b8219c233b22f8a17aa2219eee9cbf97b8a0d2a00a9d810cd40ddf02060c8408540e990e3a0a5b131e95e29bbfa0dca095a224a10aa3902d8022d613d91c84a662a1f4a8fba86f322e3448322029de280729b22bfa281d23b0267b2eb0a52e20e8a802a97ea12912961be01e8da067a068a3cba12aa3f32879271c274428d3250528cf25b425e232d32b5c2a5c3444296132fe29b428dd36b138f436ea38ea38f436b138dd366613f9106c99688928995a99f8976b9cd29a20987c1ba4195b1d1b9b06a0a296939e49a211a29a1727994f9911935c9e7a90099c6f92431b8c1e5c982e9fdc10d89aa08dd393d6987294109c5e97b29a27a0891bb994a19e429e5812911c4598e12d951629a450208d996aa03594d01c49338034fe329c21e21d58a759a9eea791a1dd20b02ed39cf622998e819d50a05a1c00212598d29db39fe09cbe14249c549e4f20191d39a4ea9427a400938b9add33752409a7d63495aa7433ee1ea5a88238f1399238003a003a9238f1398238af9468921198d592ae9233932a0eac8e63982d95fc16a919d0189f94e09d3e992ca2c5a31fa47708269bb582bd19cc9a729cd49d58988514331e48988f9cae1a4599e896859a5392ff962587ea11959541a28c1c5d1b42a1399a3ca0ff96819de32d7d0c62a51b229b9d149c5a9af119eb32373473329120d21a43a72ca84aa7609c3c258d2fb89f972410a0c0a2fea01925ba25a81eaf982ba21ea430a3e9a58a1fb926ca267ba5521e7ba60a9bef8c45341f28e9a40a3517ab8433ad18e2a96838d1398538ff39ff398538d1396838688394092386e482518575092a10ef0c43960599b796fc09840d2d98ea9ab798f69fcc9dd29f780842837c98cd053e98429c869d95997188ee099c9c339e3a9cc68cc00021902c86f586e50e1312de0caca485a329a4259ecd9ca89b258d2a97992cef9c7ba4d71dbd9d179807a4099f3d32ed33dc317b21f61fd32053279b21ae263b29ac2f669dab20b9a7f2a8bca5e125f226a626d39c7c9e3ea749a753a8972a8f2aa829cf1a181c32a629a5e1a55a343c2c1b29d534c2a2b232721c15a5f4376d391738a039a03917386d39f437a1a184a0c59d909807117f1ae11b2718bd2451242d196c1bb99dc89e66a037a0a41960a3e095be20351e931d6714ea18749e7f209f23149e8e1ef39bfd9b590c74a0fda2daa48614ff9ba71ad91df71c851ee0240024ac9d78162ca5d8a368a0b62b77a4fea425989493ba191421509b4b337c349a329420cd16f1a554a9e3a5a8a06f9a292d7d9c911d279f5f20be1e68253b279424351a61a0baa160a596a7818619250a23a7a5f09da4a4211d4a1cc5335e2527a5da34f9ab8d32e6a271aa7c38e339b138383a383ab138e3397c3834a011a0519f6e9110915d1ce91c031b0d21a222661e67144595499e569f2e9d82205a91a7204e1b9a17309aec9b119ddf9c021b5a1e0e906a1a818c339bca95aaa279a4e2a52796a295e71d8420502001212826002619981a82bba43ba53da5132884a8e5a85a9690999624ae257c200f320e33d0303d20db08069971a2c2191a2825290f2f5d9f1e1e46a4ce8dfe174c29232a6129b11b6e9db3a658a802a918299a2bbe2adda7f1155ca8711c7623b434572d032af0349aacbb2fc8ad6caf2838a439a838503a503aa838a4392838f0a0fca025a13c83859439079c0ed18e3922bc212622fe13181af1168a0cbc1acb0e751c3d16209c739c309a8118ff98eb2155218923801c051991150e9b458d02a54da5d4a52696c28d808619144e04a4a920a873a57b1f3509cea161a69ca6bead64b123b116159524282a3f29412a9d304032672d83a661a6c425102c772a5131153155334324730dfda7bda811a786302931c4318a0e9c1ef2aa59ac85ac0430082f8e2ddfa2d218a6b05daf0aaec2366f329a31f43433aa5625b4b285b3e737d639a838003a003aa838d639e7378195488c93942d94f791fa94158a6f93961960a48f9a76240a225120e0a09f1ba9a45c100aa527a1f7a11ea3da1c03a4d49cd7a43d1a0322f3246d1c6ea099215895ba8d3996aa92c9943b94d68be295919d68233d942ba658a40da4161ea6a04930202825272429d41c722602a08d225c3222341e324b20f51d74a35f9b3ba30a28f1289b30171c75290c2185a1f325321ae2249b9012a42ca6b7a0021d74a4bb98e41c1a9c011d961c6ea0df936ba