I am looking for a shader (or at least the right terminology) for crushing an image. It should be something very similar to barrel distortion, but instead of the center crushing outward to the edges, I want to edges to crush inward to the center.

So, this image:
enter image description here

instead of being deformed like this:
enter image description here

Should rather be deformed like this:
enter image description here

This will be used for a Godot project, but even regular shading language would be tremendously helpful. I tried modifying this gist to no avail.


Here is the final result using the accepted answer's solution: enter image description here


1 Answer 1


Your example images do not make the desired effect very apparent, but the opposite of a barrel distortion is a pincushion distortion: enter image description here

I found a fisheye shader on ShaderToy which produces the following image:

enter image description here

By slightly modifying the shader code:

// This shader is based on cafe's fisheye shader:
// https://www.shadertoy.com/view/ll2GWV

vec3 checker(vec2 uv){
    return vec3(abs(floor(mod(uv.x*10.,2.))-floor(mod(uv.y*10.,2.))));   

void mainImage( out vec4 fragColor, in vec2 fragCoord )
    vec2 uv = fragCoord.xy*2. / iResolution.xy-vec2(1.);

    // To use in Godot, port this section:

    // I picked these somewhat arbitrarily
    const float BARREL = -1.0;
    const float PINCUSHION = 0.1;

    float effect = PINCUSHION; // Set effect to either BARREL or PINCUSHION
    float effect_scale = 1.0;  // Play with this to slightly vary the results

    /// Fisheye Distortion ///
    float d=length(uv);
    float z = sqrt(1.0 + d * d * effect);
    float r = atan(d, z) / 3.14159;
    r *= effect_scale;
    float phi = atan(uv.y, uv.x);

    uv = vec2(r*cos(phi)+.5,r*sin(phi)+.5);

    // end relevant logic

    fragColor = vec4(checker(uv),1.);

We can easily obtain the opposite effect:

enter image description here

If this is not the exact effect you're looking for, I recommend playing around with the code a bit yourself. Change some signs from + to -, add scale factors and explore the possibilities. You may even stumble across a more interesting effect than what were you looking for.

  • $\begingroup$ Wait, does pincushion distortion actually crush inward? I always got the idea it just pulls the edges outward :P $\endgroup$ Dec 21, 2019 at 19:51
  • $\begingroup$ Please disregard my previous deleted comments, I was being a dumbass. Your solution does 100% what I need. I'll be creating a gist tonight which you may include in your answer if you'd like. $\endgroup$ Dec 21, 2019 at 22:04
  • $\begingroup$ Here is the gist for the final solution: gist.github.com/aggregate1166877/… . I've added a preview to my question for the sake of completion. $\endgroup$ Dec 22, 2019 at 7:13
  • $\begingroup$ @aggregate1166877 Nice work! Glad my answer was useful. Thanks for sharing your final solution. $\endgroup$
    – Dan
    Dec 23, 2019 at 0:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.