Problem: we have:
- image with dimensions vec2 imageDimensions
- container with dimensions vec2 containerDimensions
We want that image to center vertically, stretch to fit the width of its container, and not repeat.
vec2 uv = containAndCenter(imageDimensions, containerDimensions, gl_FragCoord);
gl_FragColor = texture2D(yourSampler2D, uv);
vec2 containAndCenter(vec2 imageDimensions, vec2 containerDimensions, vec2 fragCoord){
// let's see how much we have to scale for the image to fill the width
float imageScale = containerDimensions.x / imageDimensions.x;
// get dimensions if we scaled the entire image by that much
vec2 newImageSize = imageDimensions * imageScale;
vec2 uv = vec2(
// get regular uv x
fragCoord.x / containerDimensions .x,
// scale Y according to progress along max image size
fragCoord.y / newImageSize.y
);
// get max y value
float maxY = containerDimensions.y / newImageSize.y;
// offset to center
uv.y -= (maxY - 1.) / 2.;
// clamp uv between (0,0)..(1,1) so we don't repeat the image
uv = clamp(uv, vec2(0.), vec2(1.));
return uv;
}
vec2 uv = coverAndCenter(texDimensions, containerDimensions, uv);
vec2 coverAndCenter(vec2 imageDimensions, vec2 containerDimensions, vec2 uv){
float multiplier = (imageDimensions.y * containerDimensions.x) / (containerDimensions.y * imageDimensions.x);
return (containerDimensions.x / containerDimensions.y > imageDimensions.x / imageDimensions.y)
// container is more landscape than image - adjust y
? vec2(uv.x, uv.y / multiplier - multiplier * 0.5)
// image is more landscape than container - adjust x
: vec2(uv.x * multiplier - multiplier * 0.5, uv.y);
}