blob: f4a437d613376ab61f87dbd89e0a6bc5399857e9 [file] [log] [blame] [edit]
#version 310 es
precision highp float;
layout(binding = 0) uniform highp sampler2D uInputTexture;
layout(location = 1) uniform vec4 uCropRegion;
layout(location = 2) uniform bool uBicubic;
layout(location = 0) in highp vec2 vTexCoord;
layout(location = 0) out highp vec4 outColor;
// Computes cubic B-spline filtering kernel coefficients on v-1, v, v+1, v+2.
vec4 cubic(float v) {
vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
vec4 s = n * n * n;
float x = s.x;
float y = s.y - 4.0 * s.x;
float z = s.z - 4.0 * s.y + 6.0 * s.x;
float w = 6.0 - x - y - z;
return vec4(x, y, z, w) / 6.0;
}
// Samples 2D texture with bicubic filtering.
vec4 textureBicubic(sampler2D sampler, vec2 texCoords) {
vec2 texSize = vec2(textureSize(sampler, 0));
vec2 invTexSize = 1.0 / texSize;
texCoords = texCoords * texSize - 0.5;
vec2 fxy = fract(texCoords);
texCoords -= fxy;
vec4 xcubic = cubic(fxy.x);
vec4 ycubic = cubic(fxy.y);
vec4 c = texCoords.xxyy + vec2(-0.5, 1.5).xyxy;
vec4 s = vec4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw);
vec4 d = (c + vec4(xcubic.yw, ycubic.yw) / s) * invTexSize.xxyy;
vec4 sample0 = texture(sampler, d.xz);
vec4 sample1 = texture(sampler, d.yz);
vec4 sample2 = texture(sampler, d.xw);
vec4 sample3 = texture(sampler, d.yw);
return mix(mix(sample0, sample1, s.y), mix(sample2, sample3, s.y), s.w);
}
void main() {
float src_x = uCropRegion.x;
float src_y = uCropRegion.y;
float crop_width = uCropRegion.z;
float crop_height = uCropRegion.w;
vec2 sample_coord = vec2(
src_x + vTexCoord.x * crop_width,
src_y + vTexCoord.y * crop_height);
if (uBicubic) {
outColor = textureBicubic(uInputTexture, sample_coord);
} else {
outColor = texture(uInputTexture, sample_coord);
}
}