Skip to content

Instantly share code, notes, and snippets.

@aggregate1166877
Last active November 27, 2024 21:32
Show Gist options
  • Select an option

  • Save aggregate1166877/a889083801d67917c26c12a98e7f57a7 to your computer and use it in GitHub Desktop.

Select an option

Save aggregate1166877/a889083801d67917c26c12a98e7f57a7 to your computer and use it in GitHub Desktop.

Revisions

  1. aggregate1166877 revised this gist Jan 6, 2020. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion GodotCleanFisheyeBarrelDistortion.shader
    Original file line number Diff line number Diff line change
    @@ -58,7 +58,6 @@ void fragment(){
    }
    else {
    COLOR.a = 0.0;
    xy = UV;
    }

    // Apply manual crop.
  2. aggregate1166877 revised this gist Jan 6, 2020. 1 changed file with 21 additions and 11 deletions.
    32 changes: 21 additions & 11 deletions GodotCleanFisheyeBarrelDistortion.shader
    Original file line number Diff line number Diff line change
    @@ -22,10 +22,11 @@
    shader_type canvas_item;

    // Inspector params:
    uniform float effect = -1.1; // -1.0 is BARREL, 0.1 is PINCUSHION.
    uniform float effect = -1.1; // -1.0 is BARREL, 0.1 is PINCUSHION. For planets, ideally -1.1 to -4.
    uniform float effect_scale = 1.1; // Play with this to slightly vary the results.
    uniform bool apply_crop = false; // Cut out the junk outside the sphere.
    uniform float crop_multiplier = 1.2; // Higher value = more crop.
    uniform bool dynamic_crop = false; // Guesses the crop amount with an admittedly badly inaccurate formula.
    uniform bool manual_crop = false; // Cut out the junk outside the sphere.
    uniform float manual_amount = 0.95; // Higher value = more crop.

    vec2 distort(vec2 p) {
    float d = length(p);
    @@ -41,18 +42,27 @@ void fragment(){
    xy.x = xy.x - 1.0;
    xy.y = xy.y - 1.0;

    // Dynamic crop adjustment. -0.5 is equavalent to 'none'.
    float d_adjust = -0.5;
    if (dynamic_crop) {
    d_adjust = (effect/4.0) * -0.6;
    }

    // Perform distortion if needed.
    vec4 tex;
    float d = length(xy);
    if (d < 1.5) {
    if (d < 1.0 - d_adjust) {
    xy = distort(xy);
    tex = texture(TEXTURE, xy);
    COLOR = tex;
    }
    else{
    else {
    COLOR.a = 0.0;
    xy = UV;
    }

    vec4 tex = texture(TEXTURE, xy);
    if (apply_crop && d > (effect_scale / crop_multiplier)) {
    tex.a = 0.0;
    }

    COLOR = tex;
    // Apply manual crop.
    if (manual_crop && d > manual_amount) {
    COLOR.a = 0.0;
    }
    }
  3. aggregate1166877 revised this gist Dec 22, 2019. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions GodotCleanFisheyeBarrelDistortion.shader
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,9 @@
    *
    * See the final result in the edited part of my SO question:
    * https://computergraphics.stackexchange.com/questions/9434/shader-or-formula-that-distorts-inward
    *
    * License: CC0
    * https://creativecommons.org/publicdomain/zero/1.0/
    */

    shader_type canvas_item;
  4. aggregate1166877 revised this gist Dec 22, 2019. 1 changed file with 6 additions and 9 deletions.
    15 changes: 6 additions & 9 deletions GodotCleanFisheyeBarrelDistortion.shader
    Original file line number Diff line number Diff line change
    @@ -25,31 +25,28 @@ uniform bool apply_crop = false; // Cut out the junk outside the sphere.
    uniform float crop_multiplier = 1.2; // Higher value = more crop.

    vec2 distort(vec2 p) {
    float d = length(p);
    float z = sqrt(1.0 + d * d * effect);
    float r = atan(d, z) / 3.14159;
    r *= effect_scale;
    float phi = atan(p.y, p.x);

    float d = length(p);
    float z = sqrt(1.0 + d * d * effect);
    float r = atan(d, z) / 3.14159;
    r *= effect_scale;
    float phi = atan(p.y, p.x);
    return vec2(r*cos(phi)+.5,r*sin(phi)+.5);
    }

    void fragment(){
    vec2 xy = (2.0 * UV);

    xy.x = xy.x - 1.0;
    xy.y = xy.y - 1.0;

    float d = length(xy);
    if (d < 1.5){
    if (d < 1.5) {
    xy = distort(xy);
    }
    else{
    xy = UV;
    }

    vec4 tex = texture(TEXTURE, xy);

    if (apply_crop && d > (effect_scale / crop_multiplier)) {
    tex.a = 0.0;
    }
  5. aggregate1166877 renamed this gist Dec 22, 2019. 1 changed file with 0 additions and 0 deletions.
  6. aggregate1166877 created this gist Dec 22, 2019.
    58 changes: 58 additions & 0 deletions CleanFisheyeBarrelDistortion.shader
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    /**
    * This shader creates fisheye or barrel distortion by sliding values in the
    * desired direction. It aims to have a minimal amount of pixelation, and was
    * originally conceived of to procedurally generate cartoon planets and bodies
    * from easily generatable flat textures.
    *
    * Thanks to user Dan (6145) on Stack Overflow for providing the math. I also
    * stole some code from here for the texture placement:
    * https://gist.github.com/quiglemj/971f4cec1b128c58b4864c5200bfc579
    * This shader differs from the above gist in that it does not stretch the
    * center towards the edges, but rather crushes the edges in towards the
    * center, and thus eliminates pixelation entirely while achieving a near
    * identical effect.
    *
    * See the final result in the edited part of my SO question:
    * https://computergraphics.stackexchange.com/questions/9434/shader-or-formula-that-distorts-inward
    */

    shader_type canvas_item;

    // Inspector params:
    uniform float effect = -1.1; // -1.0 is BARREL, 0.1 is PINCUSHION.
    uniform float effect_scale = 1.1; // Play with this to slightly vary the results.
    uniform bool apply_crop = false; // Cut out the junk outside the sphere.
    uniform float crop_multiplier = 1.2; // Higher value = more crop.

    vec2 distort(vec2 p) {
    float d = length(p);
    float z = sqrt(1.0 + d * d * effect);
    float r = atan(d, z) / 3.14159;
    r *= effect_scale;
    float phi = atan(p.y, p.x);

    return vec2(r*cos(phi)+.5,r*sin(phi)+.5);
    }

    void fragment(){
    vec2 xy = (2.0 * UV);

    xy.x = xy.x - 1.0;
    xy.y = xy.y - 1.0;

    float d = length(xy);
    if (d < 1.5){
    xy = distort(xy);
    }
    else{
    xy = UV;
    }

    vec4 tex = texture(TEXTURE, xy);

    if (apply_crop && d > (effect_scale / crop_multiplier)) {
    tex.a = 0.0;
    }

    COLOR = tex;
    }