Rotating a deformation effect in a shader?

A bit of a shader beginner here. I’m trying to create an effect that basically warps part of a texture like this, based on where the mouse is:

Which I have working pretty well. But, I want it to be able to rotate and warp in any direction (depending on the angle from the mouse to the center of the canvas). I’ve tried rotating the resulting y offset with something like vec2(0., offsetY) * a 2d rotation matrix, and adding the result to the texture coordinates, but doing that ends up with some weirdness like:

Here’s my shadertoy link and the shader code: Shader - Shadertoy BETA

float sinc(float x, float amp, float freq) {
    x = freq*x;
    return amp*sin(x)/(x);
vec2 centeredCoord(vec2 c1, vec2 c2) {
    return vec2(c1 / c2) * 2. - 1.; // between -1 and 1
mat2 rotate2D(float angle) {
    return mat2(cos(angle), -sin(angle),
                sin(angle), cos(angle));

void mainImage( out vec4 fragColor, in vec2 fragCoord )
    // Declare variables
    float PI = 3.14159;
    float amplitude;
    float ampFactor = .1;
    float speedFactor = .3;
    float AOIFactor = 2.;
    float frequency = 50.;
    float oscillations = 2.;
    // How much deformation to do for this fragment
    amplitude = sin(PI * iTime * speedFactor) * (PI - fract(iTime / oscillations * speedFactor) * PI) * ampFactor;

    // Initialize texture coordinates
    vec2 texCoord = centeredCoord(fragCoord.xy, iResolution.xx);
    vec2 mouseCoord = centeredCoord(iMouse.xy, iResolution.xx);
    // The main sinc functions
    //float offsetX = sinc(texCoord.y - mouseCoord.y, amplitude, frequency);
    float offsetY = sinc(texCoord.x - mouseCoord.x, amplitude, frequency);
    // Rotate the result of the sinc functions...    
    vec2 tempCoord = vec2(0., offsetY);
    vec2 rotatedCoord = tempCoord * rotate2D(PI * 1.);
    //THIS produces undesirable results...
    rotatedCoord = tempCoord * rotate2D(PI * 1.3);
    // Apply rotation to the texture
    vec2 newCoord = texCoord + rotatedCoord;
    // Get distance from mouse
    float dist = distance(mouseCoord, texCoord);
    // Draw fragment
    fragColor = texture(iChannel0, mix(newCoord, texCoord, clamp(0., dist * AOIFactor, 1.)));

If anyone knows what I’m doing wrong or can point me in the right direction, that would be great! Thanks!

Not sure that this is what you’re looking for with rotation. Just a random shot :slight_smile:

1 Like

Hey, thanks for taking the time! The effect I’m trying to get is more like this, but without the actual texture being rotated–just the direction of the warp effect. So the warping is still in a straight line as opposed to a swirl like yours.

The second attempt:

1 Like

Sweet, yeah that’s basically what I’m looking for. I’ll have to dig into your code to really understand it, but it’s definitely the right direction. Thanks, I really appreciate your help!

1 Like