Skip to content

Instantly share code, notes, and snippets.

@raphaelameaume
Created May 29, 2020 15:01
Show Gist options
  • Save raphaelameaume/d1731132ef01efd948e67c0778770981 to your computer and use it in GitHub Desktop.
Save raphaelameaume/d1731132ef01efd948e67c0778770981 to your computer and use it in GitHub Desktop.
Simulate background:size cover in fragment shader
vec2 uvCover (vec2 uv, vec2 size, vec2 resolution) {
vec2 coverUv = uv;
vec2 s = resolution; // Screen
vec2 i = size; // Image
float rs = s.x / s.y;
float ri = i.x / i.y;
vec2 new = rs < ri ? vec2(i.x * s.y / i.y, s.y) : vec2(s.x, i.y * s.x / i.x);
vec2 offset = (rs < ri ? vec2((new.x - s.x) / 2.0, 0.0) : vec2(0.0, (new.y - s.y) / 2.0)) / new;
coverUv = coverUv * s / new + offset;
return coverUv;
}
@michaeldll
Copy link

Thank you for this function, it helped me a lot in a personal project.

Here it is in WGSL, in case somebody else might find it useful:

fn uvCover (uv: vec2f, size: vec2f, resolution: vec2f) -> vec2f {
    var coverUv: vec2f = uv;

    var s: vec2f = resolution; // Screen
    var i: vec2f = size; // Image

    var rs: f32 = s.x / s.y;
    var ri: f32 = i.x / i.y;

    var newUv: vec2f = select(
        vec2f(s.x, i.y * s.x / i.x), 
        vec2f(i.x * s.y / i.y, s.y), 
        rs < ri
    );
    var offsetUv: vec2f = select(
        vec2f(0., (newUv.y - s.y) / 2.0) / newUv, 
        vec2f(((newUv.x) - s.x) / 2.0, 0.),
        rs < ri
    );
    
    coverUv = coverUv * s / newUv + offsetUv;

    return coverUv;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment