Use shader with another createCanvas

hey, I’m doing a sketch with shaders inside a p5. I have 3 p5.Renderer object using createGraphics.
the first one is the “screen” that I’m painting on, and the others are ‘currentFrame’ & ‘lastFrame’ which I’m trying to compute the shader on the ‘currentFrame’ and then copy it to ‘lastFrame’ and again and again (and like that I wish to make an animation).
for “copying” the ‘currentFrame’ to ‘lastFrame’ I use lastFrame.image(currentFrame, 0, 0);.
the problem is that I suspect that its not working fine, because here is a really basic code that whats it is supposed to do is to lastFrame.image(screen,0, 0); and then in the ‘frag shader’ to draw the lastTexture. but it just keeps the screen black. maybe there is a better way to do that?
here is the code:
sketck:

let shade;
let lastFrame;
let currentFrame;
let screen;

function preload(){
  shade = loadShader("shader.vert", "shader.frag");
}

function setup() {
  createCanvas(600, 600,WEBGL);
  currentFrame = createGraphics(width, height,WEBGL);
  lastFrame = createGraphics(width, height);
  screen = createGraphics(width, height);
  
  screen.background(0);
  screen.fill(255,0,0);
  screen.noStroke();
  screen.ellipse(width/2,height/2,200)
  screen.stroke(255);
  // noLoop();

}
function draw() {
  push();
  translate(-width/2, -height/2);
  if(mouseIsPressed) {
    screen.line(pmouseX,pmouseY,mouseX,mouseY);
  }
  lastFrame.image(screen,0, 0);

  currentFrame.shader(shade);
  
  shade.setUniform("currentTexture", screen);
  shade.setUniform("lastFrame", lastFrame);
  shade.setUniform("normalRes", [1.0/width, 1.0/height]);

  currentFrame.rect(0,0,width,height);
  // Copy current frame to last frame
  lastFrame.image(currentFrame, 0, 0);
   // Output to screen
  image(currentFrame, 0, 0);
  pop();
}

Frag.shader:

#ifdef GL_ES
precision highp float;
#endif

varying vec2 vTexCoord;
uniform vec2 normalRes;
uniform sampler2D currentTexture;
uniform sampler2D lastTexture;

void main() {
    vec2 uv = vTexCoord;

    uv.y = 1.0 - uv.y;
    vec4 currentColor = texture2D(currentTexture, uv);
    vec4 lastColor = texture2D(lastTexture, uv);
    float a = currentColor.r;

    vec4 color;

    float x = uv.x;
    float y = uv.y;
    color = vec4(texture2D(lastTexture, uv));

  
    gl_FragColor = color;

}

Vert.shader:

attribute vec3 aPosition;
attribute vec2 aTexCoord;

varying vec2 vTexCoord;

void main() {
  // copy the texcoords
  vTexCoord = aTexCoord;

  vec4 positionVec4 = vec4(aPosition, 1.0);
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;

  gl_Position = positionVec4;
}

here is the sketch in the p5 editor:

any help would be great :slight_smile: thank you

I believe this is called double buffering. You have a back buffer and a front buffer and switch them every frame.

The thread below should have the answers you’re looking for :slight_smile:

2 Likes

thanks for the answer @sableRaph !
I didn’t know that backBuffer was the name of it :slight_smile:
apparently, I made a mistake in my code and wrote:

  shade.setUniform("lastFrame", lastFrame);

instade of:

  shade.setUniform("lastTexture", lastFrame);

:smiling_face_with_tear: :smiling_face_with_tear: :smiling_face_with_tear:

1 Like