How to smoothly fading between multiple shaders with p5.js?

I am trying to figure out how to fade between an array of shaders at random rates and random opacities. I tried creating an if statement that would provide a new target opacity and target rate of time it would take to fully change to the target opacity. I tried drawing the shader in the IF statement but it did not fade smoothly. Any help would be appreciated. Here is what I have so far in the .js file. And I have the full project at this link https://glitch.com/edit/#!/mulripleshadertest?path=sketch.js%3A74%3A2

I also asked this question on stackoverflow too at https://stackoverflow.com/questions/62803711/how-to-smoothly-fading-between-multiple-shaders-with-p5-js?noredirect=1#comment111126038_62803711

let backgroundShader1;
let foregroundShader1;
let shaderBackground1Ndx = Math.floor(Math.random() * 15); //choose random shader
let shaderForeground1Ndx = Math.floor(Math.random() * 15);

let w, h;
let shaderTexture;
let changeEvery1 =100; //set rate
let changeEvery2 =100;
let alpha1 = Math.random() //random opacity level
let alpha2 = Math.random()


const shaders = [];

function preload() {
  // load the shaders
  shaders.push(loadShader("shader1.vert", "shader1.frag"));
  shaders.push(loadShader("shader2.vert", "shader2.frag"));
  shaders.push(loadShader("shader3.vert", "shader3.frag"));
  shaders.push(loadShader("shader3.vert", "shader4.frag"));
  shaders.push(loadShader("shader3.vert", "shader5.frag"));
  shaders.push(loadShader("shader3.vert", "shader6.frag"));
  shaders.push(loadShader("shader3.vert", "shader7.frag"));
  shaders.push(loadShader("shader3.vert", "shader8.frag"));
  shaders.push(loadShader("shader3.vert", "shader9.frag"));
  shaders.push(loadShader("shader3.vert", "shader10.frag"));
  shaders.push(loadShader("shader3.vert", "shader11.frag"));
  shaders.push(loadShader("shader3.vert", "shader12.frag"));
  shaders.push(loadShader("shader3.vert", "shader13.frag"));
  shaders.push(loadShader("shader3.vert", "shader14.frag"));
  theShader = shaders[0]; // start with the first shader
}

function setup() {
  frameRate(20);
  w = windowWidth;
  h = windowHeight;
  //creates canvas
  createCanvas(w, h, WEBGL);
  noStroke();

  // initialize the createGraphics layers
  shaderTexture = createGraphics(w, h, WEBGL);
  shaderTexture.noStroke();
  
  backgroundShader1 = shaders[shaderBackground1Ndx];
  foregroundShader1 = shaders[shaderForeground1Ndx];

}

function draw() {
  background(255);
  //
  //layer1
  //
  let time1 = frameCount % changeEvery1;
  if (time1 == 0) {
    backgroundShader1 = foregroundShader1;
    shaderForeground1Ndx = (shaderForeground1Ndx + Math.floor(Math.random() * 14)) % shaders.length;
    foregroundShader1 = shaders[shaderForeground1Ndx];
    
    //backgroundShader1.setUniform("backgroundAlpha",map(time1, 0, changeEvery1,alpha2,0));
    //foregroundShader1.setUniform("backgroundAlpha", map(time1, 0, changeEvery1, 0, alpha1));
    
    alpha2=alpha1 
    alpha1 = Math.random()*.5+.5; //random opacity b/w 0-1
    changeEvery2=changeEvery1; 
    changeEvery1=Math.floor(Math.random() * 150) + 50; //choose rate between certain amount of sec
  
  }

  // Background shader
  shaderTexture.shader(backgroundShader1);
  shaderTexture.rect(0, 0, 2 * w, h);
  backgroundShader1.setUniform("iResolution", [w, h]);
  backgroundShader1.setUniform("iFrame", frameCount);
  backgroundShader1.setUniform("iMouse", [mouseX, map(mouseY, 0, h, h, 0)]);
  backgroundShader1.setUniform("iTime", millis() / 1000.0);
  backgroundShader1.setUniform("u_resolution", [w, h]);
  backgroundShader1.setUniform("u_time", millis() / 1000.0);
  backgroundShader1.setUniform("u_mouse", [mouseX, map(mouseY, 0, h, h, 0)]);
  backgroundShader1.setUniform("backgroundAlpha",map(time1, 0, changeEvery2,alpha2,0)); //maps the shader fading out
  //backgroundShader1.setUniform("backgroundAlpha",map(time1, 0, Math.floor(Math.random() * 700) + 100,Math.random(),0));
  texture(shaderTexture);
  rect(-windowWidth / 2, -windowHeight /2, windowWidth, windowHeight);

  // Foreground shader
  shaderTexture.shader(foregroundShader1);
  shaderTexture.rect(0, 0, 2 * w, h);
  foregroundShader1.setUniform("iResolution", [w, h]);
  foregroundShader1.setUniform("iFrame", frameCount);
  foregroundShader1.setUniform("iMouse", [mouseX, map(mouseY, 0, h, h, 0)]);
  foregroundShader1.setUniform("iTime", millis() / 1000.0);
  foregroundShader1.setUniform("u_resolution", [w, h]);
  foregroundShader1.setUniform("u_time", millis() / 1000.0);
  foregroundShader1.setUniform("u_mouse", [mouseX, map(mouseY, 0, h, h, 0)]);
  //console.log("alpha: ", map(frameCount % changeEvery, 0, changeEvery-1, 0.0, 1.0)) ;
  foregroundShader1.setUniform("backgroundAlpha", map(time1, 0, changeEvery1, 0, alpha1)); //maps shader fading in
  //foregroundShader1.setUniform("backgroundAlpha", map(time1, 0, Math.floor(Math.random() * 700) + 100,0,Math.random()));

  texture(shaderTexture);
  rect(-windowWidth / 2,-windowHeight / 2,windowWidth,windowHeight);
  
 
  
}
  
function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

What if you create two off-screen buffers instead of one? That means calling createGraphics() twice, rendering each shader to one of them, finally draw them on the screen one after the other.

Oops… I saw Jul '20 in this post and I thought it was from a week ago (instead of a year ago) :slight_smile: Maybe you solved this already?