WARP

port from shadertoy. Position distortion with sin/cos

Original shader: https://www.shadertoy.com/view/ttlGDf

Shader code
shader_type spatial;
render_mode unshaded, cull_disabled;

uniform float strength : hint_range(0.0, 1.0) = 0.4;
uniform float speed : hint_range(0.0, 2.0) = 0.333;
uniform vec2 screen_resolution = vec2(1280.0, 720.0); // Must be set from GDScript

void fragment() {
    float t = TIME * speed;

    vec3 col = vec3(0.0);
    
    // Convert SCREEN_UV to range [-1, 1], centering it
    vec2 pos = SCREEN_UV * 2.0 - 1.0;
    
    // Preserve aspect ratio manually using the screen resolution uniform
    pos.y *= (screen_resolution.y / screen_resolution.x);
    
    pos *= 4.0; // Scale up for a larger effect

    for (float k = 1.0; k < 7.0; k += 1.0) { 
        pos.x += strength * sin(2.0 * t + k * 1.5 * pos.y) + t * 0.5;
        pos.y += strength * cos(2.0 * t + k * 1.5 * pos.x);
    }

    // Color calculation using time and position
    col += 0.5 + 0.5 * cos(TIME + pos.xyx + vec3(0.0, 2.0, 4.0));

    // Gamma correction
    col = pow(col, vec3(0.4545));

    // Set final output
    ALBEDO = col;
    ALPHA = 1.0;
}
Tags
distortion, psychedelic, warp
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Perspective Warp/Skew Shader

Slipgate texture warp

Customizable Warp Shader (4.4)

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Eyecon
Eyecon
3 months ago

Hey you could use vec2 res=1.0/SCREEN_PIXEL_SIZE; in fragment instead of passing resolution from script.

imjustnerdio
imjustnerdio
3 months ago

Here is the modified code if you want to use it on canvas_item

shader_type canvas_item;

uniform float strength : hint_range(0.0, 1.0) = 0.4;
uniform float speed : hint_range(0.0, 2.0) = 0.333;

void fragment() {
  float t = TIME * speed;

  vec3 col = vec3(0.0);
   
  vec2 res=1.0/SCREEN_PIXEL_SIZE;

  // Convert SCREEN_UV to range [-1, 1], centering it
  vec2 pos = SCREEN_UV * 2.0 – 1.0;
   
  // Preserve aspect ratio manually using the screen resolution uniform
  pos.y *= (res.y / res.x);
   
  pos *= 4.0; // Scale up for a larger effect

  for (float k = 1.0; k < 7.0; k += 1.0) { 
    pos.x += strength * sin(2.0 * t + k * 1.5 * pos.y) + t * 0.5;
    pos.y += strength * cos(2.0 * t + k * 1.5 * pos.x);
  }

  // Color calculation using time and position
  col += 0.5 + 0.5 * cos(TIME + pos.xyx + vec3(0.0, 2.0, 4.0));

  // Gamma correction
  col = pow(col, vec3(0.4545));

  // Set final output
  COLOR.rgb = col;
  COLOR.a = 1.0;
}

Last edited 3 months ago by imjustnerdio