happycoder2121
happycoder2121

Reputation: 75

p5.js ping-pong buffering causes texture glitch

I'm trying to implement a smudge effect on a texture using shaders and p5.js. I can see that the texture is being loaded into the shader and I can see the smudging, but my texture is flickering on each frame. The idea was to use two buffers and pass the other buffer as the buffer's texture to persist the result (ping-pong). Am I missing something? Here's the code:

let container;
let img;
let recorder;
let buffers;
let flowField;
let options;
let isRecording = false;
let capturedImg;
let shaders = [];
let useBuffer0 = true; // flag to swap ping–pong buffers

const WIDTH = 1080;
const HEIGHT = 1350;
const BG_COLOR = "#F6F0E0";
const FRAME_RATE = 24;
const SHADER_PASSES = 2;

/*---------------PRELOAD---------------*/
function preload() {
  container = document.getElementById("container");
  img = loadImage("./assets/images/colorImg.png");

  // Load two shader passes
  shader0 = loadShader(
    "./assets/shaders/distortion/shader.vert",
    "./assets/shaders/distortion/smudge.frag"
  );
  shader1 = loadShader(
    "./assets/shaders/distortion/shader.vert",
    "./assets/shaders/distortion/smudge.frag"
  );
}

/*---------------SETUP---------------*/
function setup() {
    createCanvas(WIDTH, HEIGHT);
  options = WebUtils.getCookies();
  frameRate(FRAME_RATE);
  background(BG_COLOR);
  recorder = new CanvasRecorder(canvas);
  
  textureBuffer  = createGraphics(WIDTH, HEIGHT);
  shadderBuffer0 = createGraphics(WIDTH, HEIGHT, WEBGL);
  shaderBuffer1  =  createGraphics(WIDTH, HEIGHT, WEBGL);

  textureBuffer.background(img);
  shadderBuffer0.shader(shader0);

  shader0.setUniform('texture0', img);
  shader0.setUniform('resolution', [width, height]);
  shader0.setUniform('time', millis() / 1000.0);
  shader0.setUniform('mouse', [mouseX, height - mouseY]);
  shadderBuffer0.rect(0, 0, width, height);
}

/*---------------DRAW---------------*/
function draw() {

  const buffer = useBuffer0 ? shadderBuffer0 : shaderBuffer1;
  const otherBuffer = useBuffer0 ? shaderBuffer1 : shadderBuffer0;  
  const shader = useBuffer0 ? shader0 : shader1;
  buffer.shader(shader)
  shader.setUniform('texture0', otherBuffer);
  shader.setUniform('resolution', [width, height]);
  shader.setUniform('time', millis() / 1000.0);
  shader.setUniform('mouse', [mouseX, height - mouseY]);
  buffer.rect(0, 0, width, height);

  useBuffer0 = !useBuffer0;

  image(buffer, 0, 0);

}

smudge.frag:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 resolution;
uniform vec2 mouse;
uniform sampler2D texture0;

void main() {
    vec2 uv = gl_FragCoord.xy / resolution;
    vec2 center = mouse / resolution;
    vec2 delta = uv - center;
    float dist = length(delta);
    float radius = 0.07;
    float strength = 0.5;
    
    if(dist < radius) {
        float factor = (radius - dist) / radius;
        float angle = factor * strength * 3.14159;
        float s = sin(angle);
        float c = cos(angle);
        mat2 rot = mat2(c, -s, s, c);
        delta = rot * delta;
    }

    uv = center + delta;
    gl_FragColor = texture2D(texture0, uv);
}

shader.vert:

attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;

void main() {
    vTexCoord = aTexCoord;
    vec4 positionVec4 = vec4(aPosition, 1.0);
    positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
    gl_Position = positionVec4;
}

Upvotes: 0

Views: 27

Answers (1)

mk135
mk135

Reputation: 1

Try this:

void main() {
    vec2 uv = gl_FragCoord.xy / resolution;
    uv.y = 1.0 - uv.y;

Upvotes: 0

Related Questions