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 }