Warning, /frameworks/kdeclarative/src/qmlcontrols/graphicaleffects/lanczos2sharp.frag is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
0003     SPDX-FileCopyrightText: 2023 Mike Noe <noeerover@gmail.com>
0004 
0005     Hyllian's lanczos windowed-jinc 2-lobe sharper 3D with anti-ringing Shader
0006 
0007     Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
0008 
0009     Permission is hereby granted, free of charge, to any person obtaining a copy
0010     of this software and associated documentation files (the "Software"), to deal
0011     in the Software without restriction, including without limitation the rights
0012     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0013     copies of the Software, and to permit persons to whom the Software is
0014     furnished to do so, subject to the following conditions:
0015 
0016     The above copyright notice and this permission notice shall be included in
0017     all copies or substantial portions of the Software.
0018 
0019     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0020     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0021     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0022     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0023     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0024     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0025     THE SOFTWARE.
0026 */
0027 
0028 #version 440
0029 
0030 layout(location = 0) in vec2 texcoord;
0031 layout(location = 0) out vec4 fragColor;
0032 
0033 layout(std140, binding = 0) uniform buf {
0034     mat4 qt_Matrix;
0035     float qt_Opacity;
0036 
0037     vec2 targetSize;
0038     float windowSinc;
0039     float sinc;
0040     float antiRingingStrength;
0041     float resolution;
0042 } ubuf;
0043 
0044 layout(binding = 1) uniform sampler2D source;
0045 
0046 // A=0.5, B=0.825 is the best jinc approximation for x<2.5. if B=1.0, it's a lanczos filter.
0047 // Increase A to get more blur. Decrease it to get a sharper picture.
0048 // B = 0.825 to get rid of dithering. Increase B to get a fine sharpness, though dithering returns.
0049 
0050 #define wa (ubuf.windowSinc * pi)
0051 #define wb (ubuf.sinc * pi)
0052 
0053 const float pi = 3.1415926535897932384626433832795;
0054 const vec3 dtt = vec3(65536.0, 255.0, 1.0);
0055 
0056 vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
0057 {
0058     return dtt * mat4x3(A, B, C, D);
0059 }
0060 
0061 vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
0062 {
0063     return min(a, min(b, min(c, d)));
0064 }
0065 
0066 vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
0067 {
0068     return max(a, max(b, max(c, d)));
0069 }
0070 
0071 vec4 lanczos(vec4 x)
0072 {
0073     return (x == vec4(0.0)) ?  vec4(wa * wb) : sin(x * wa) * sin(x * wb) / (x * x);
0074 }
0075 
0076 void main()
0077 {
0078     // Discard any pixels that are outside the bounds of the texture.
0079     // This prevents artifacts when the texture doesn't have a full-alpha border.
0080     if (any(lessThan(texcoord, vec2(0.0))) || any(greaterThan(texcoord, vec2(1.0)))) {
0081         discard;
0082     }
0083 
0084     vec2 dx = vec2(1.0, 0.0);
0085     vec2 dy = vec2(0.0, 1.0);
0086 
0087     vec2 pixelCoord = texcoord * ubuf.targetSize / ubuf.resolution;
0088     vec2 texel = (floor(pixelCoord) + vec2(0.5, 0.5)) * ubuf.resolution / ubuf.targetSize;
0089 
0090     vec2 texelCenter = (floor(pixelCoord - vec2(0.5, 0.5)) + vec2(0.5, 0.5));
0091 
0092     mat4 weights;
0093     weights[0] = lanczos(vec4(distance(pixelCoord, texelCenter - dx - dy),
0094                               distance(pixelCoord, texelCenter - dy),
0095                               distance(pixelCoord, texelCenter + dx - dy),
0096                               distance(pixelCoord, texelCenter + 2.0 * dx - dy)));
0097     weights[1] = lanczos(vec4(distance(pixelCoord, texelCenter - dx),
0098                               distance(pixelCoord, texelCenter),
0099                               distance(pixelCoord, texelCenter + dx),
0100                               distance(pixelCoord, texelCenter + 2.0 * dx)));
0101     weights[2] = lanczos(vec4(distance(pixelCoord, texelCenter - dx + dy),
0102                               distance(pixelCoord, texelCenter + dy),
0103                               distance(pixelCoord, texelCenter + dx + dy),
0104                               distance(pixelCoord, texelCenter + 2.0 * dx + dy)));
0105     weights[3] = lanczos(vec4(distance(pixelCoord, texelCenter - dx + 2.0 * dy),
0106                               distance(pixelCoord, texelCenter + 2.0 * dy),
0107                               distance(pixelCoord, texelCenter + dx + 2.0 * dy),
0108                               distance(pixelCoord, texelCenter + 2.0 * dx + 2.0 * dy)));
0109 
0110     dx = dx * ubuf.resolution / ubuf.targetSize;
0111     dy = dy * ubuf.resolution / ubuf.targetSize;
0112     texelCenter = texelCenter * ubuf.resolution / ubuf.targetSize;
0113 
0114     // reading the texels
0115     vec3 color = texture(source, texcoord).xyz;
0116 
0117     vec3 c00 = texture(source, texelCenter - dx - dy).xyz;
0118     vec3 c10 = texture(source, texelCenter - dy).xyz;
0119     vec3 c20 = texture(source, texelCenter + dx - dy).xyz;
0120     vec3 c30 = texture(source, texelCenter + 2.0 * dx - dy).xyz;
0121     vec3 c01 = texture(source, texelCenter - dx).xyz;
0122     vec3 c11 = texture(source, texelCenter).xyz;
0123     vec3 c21 = texture(source, texelCenter + dx).xyz;
0124     vec3 c31 = texture(source, texelCenter + 2.0 * dx).xyz;
0125     vec3 c02 = texture(source, texelCenter - dx + dy).xyz;
0126     vec3 c12 = texture(source, texelCenter + dy).xyz;
0127     vec3 c22 = texture(source, texelCenter + dx + dy).xyz;
0128     vec3 c32 = texture(source, texelCenter + 2.0 * dx + dy).xyz;
0129     vec3 c03 = texture(source, texelCenter - dx + 2.0 * dy).xyz;
0130     vec3 c13 = texture(source, texelCenter + 2.0 * dy).xyz;
0131     vec3 c23 = texture(source, texelCenter + dx + 2.0 * dy).xyz;
0132     vec3 c33 = texture(source, texelCenter + 2.0 * dx + 2.0 * dy).xyz;
0133 
0134     vec3 F6 = texture(source, texel + dx + 0.25 * dx + 0.25 * dy).xyz;
0135     vec3 F7 = texture(source, texel + dx + 0.25 * dx - 0.25 * dy).xyz;
0136     vec3 F8 = texture(source, texel + dx - 0.25 * dx - 0.25 * dy).xyz;
0137     vec3 F9 = texture(source, texel + dx - 0.25 * dx + 0.25 * dy).xyz;
0138 
0139     vec3 H6 = texture(source, texel + 0.25 * dx + 0.25 * dy + dy).xyz;
0140     vec3 H7 = texture(source, texel + 0.25 * dx - 0.25 * dy + dy).xyz;
0141     vec3 H8 = texture(source, texel - 0.25 * dx - 0.25 * dy + dy).xyz;
0142     vec3 H9 = texture(source, texel - 0.25 * dx + 0.25 * dy + dy).xyz;
0143 
0144     vec4 f0 = reduce4(F6, F7, F8, F9);
0145     vec4 h0 = reduce4(H6, H7, H8, H9);
0146 
0147     //  Get min/max samples
0148     vec3 min_sample = min4(c11, c21, c12, c22);
0149     vec3 max_sample = max4(c11, c21, c12, c22);
0150 
0151     color = weights[0] * transpose(mat4x3(c00, c10, c20, c30));
0152     color += weights[1] * transpose(mat4x3(c01, c11, c21, c31));
0153     color += weights[2] * transpose(mat4x3(c02, c12, c22, c32));
0154     color += weights[3] * transpose(mat4x3(c03, c13, c23, c33));
0155     color = color / dot(vec4(1.0) * weights, vec4(1.0));
0156 
0157     // Anti-ringing
0158     vec3 aux = color;
0159     color = clamp(color, min_sample, max_sample);
0160 
0161     color = mix(aux, color, ubuf.antiRingingStrength);
0162 
0163     float alpha = texture(source, texcoord).a * ubuf.qt_Opacity;
0164     fragColor = vec4(color, alpha);
0165 }