Skip to content

Instantly share code, notes, and snippets.

@SaFrMo
Last active January 24, 2022 20:16
Show Gist options
  • Select an option

  • Save SaFrMo/622b3b42e2c858b8a3b059656b7c119f to your computer and use it in GitHub Desktop.

Select an option

Save SaFrMo/622b3b42e2c858b8a3b059656b7c119f to your computer and use it in GitHub Desktop.
Shader snippets

Contents

  1. object-fit: contain
  2. object-fit: cover

object-fit: contain

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.

Solution:

vec2 uv = containAndCenter(imageDimensions, containerDimensions, gl_FragCoord);
gl_FragColor = texture2D(yourSampler2D, uv);

Code:

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;
}

object-fit: cover

Solution:

vec2 uv = coverAndCenter(texDimensions, containerDimensions, uv);

Code:

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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment