LYGIA Shader Library

pincushion (lygia/distort/pincushion)

Pincushion distortion

Dependencies:

Use:

barrel(SAMPLER_TYPE tex, <vec2> st [, <vec2|float> distance])

Check it on Github



#ifndef PINCUSHION_TYPE
#define PINCUSHION_TYPE vec3
#endif

#ifndef PINCUSHION_SAMPLER_FNC
#define PINCUSHION_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV).rgb
#endif

#ifndef FNC_PINCUSHION
#define FNC_PINCUSHION

vec2 pincushion(vec2 st, vec2 pixel, float amt) {
    float prop = pixel.x / pixel.y; // screen proroption
    vec2 m = vec2(0.5, 0.5 / prop); // center coords
    vec2 d = st - m;                // vector from center to current fragment
    float dist = sqrt(dot(d, d));   // distance of pixel from center

    float power = (TAU / (2.0 * sqrt(dot(m, m)))) * -amt;
    float bind = (prop < 1.0)? m.x : m.y;

    float A = (power > 0.0)? tan(dist * power) : atan(dist * -power * 10.0);
    float B = (power > 0.0)? tan(bind * power) : atan(-power * bind * 10.0);

    vec2 uv = m + normalize(d) * A * bind/B;
    return vec2(uv.x, uv.y * prop);
}

PINCUSHION_TYPE pincushion(SAMPLER_TYPE tex, vec2 st, vec2 pixel, float amt) {
    vec2 uv = pincushion(st, pixel, amt);
    return PINCUSHION_SAMPLER_FNC(tex, uv);
}
#endif

Dependencies:

Use:

barrel(SAMPLER_TYPE tex, <float2> st [, <float2|float> distance])

Check it on Github



#ifndef PINCUSHION_TYPE
#define PINCUSHION_TYPE float3
#endif

#ifndef PINCUSHION_SAMPLER_FNC
#define PINCUSHION_SAMPLER_FNC(TEX, UV) SAMPLER_FNC(TEX, UV).rgb
#endif

#ifndef FNC_PINCUSHION
#define FNC_PINCUSHION

float2 pincushion(float2 st, float2 pixel, float amt) {
    float prop = pixel.x / pixel.y; // screen proroption
    float2 m = float2(0.5, 0.5 / prop); // center coords
    float2 d = st - m;                // vector from center to current fragment
    float dist = sqrt(dot(d, d));   // distance of pixel from center

    float power = (TAU / (2.0 * sqrt(dot(m, m)))) * -amt;
    float bind = (prop < 1.0)? m.x : m.y;

    float A = (power > 0.0)? tan(dist * power) : atan(dist * -power * 10.0);
    float B = (power > 0.0)? tan(bind * power) : atan(-power * bind * 10.0);

    float2 uv = m + normalize(d) * A * bind/B;
    return float2(uv.x, uv.y * prop);
}

PINCUSHION_TYPE pincushion(SAMPLER_TYPE tex, float2 st, float2 pixel, float amt) {
    float2 uv = pincushion(st, pixel, amt);
    return PINCUSHION_SAMPLER_FNC(tex, uv);
}
#endif

Examples

Licenses

LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.

Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).

It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository