Затухание между shadertoy шейдерами в p5. js? - PullRequest
1 голос
/ 17 июня 2020

Я пытаюсь переключаться между несколькими разными типами шейдеров из shadertoy, импортируя их в p5. js и пытаюсь найти лучший способ сделать это? Я пытаюсь выяснить, могу ли я каким-то образом просто использовать функцию tint() для регулировки непрозрачности шейдера после того, как я загружаю их и l oop через них, но точно не знаю, возможно ли это. Вот что у меня есть, любая помощь будет принята с благодарностью.

Вот полная ссылка на мой проект https://glitch.com/~outgoing-island-enthusiasm

    let theShader;
    let oldTime;
    let shaderNdx = 0;

    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'));
      theShader = shaders[0];  // start with the first shader
    }

    function setup() {
      //creates canvas
      createCanvas(windowWidth, windowHeight, WEBGL);
      noStroke();
    }

    function draw() {  
      // switch shaders every second
      let time = performance.now() / 1000 | 0;  // convert to seconds
      if (oldTime !== time) {
        oldTime = time;
        // increment shader index to the next shader but wrap around 
        // back to 0 at then of the array of shaders
        shaderNdx = (shaderNdx + 2) % shaders.length;
        theShader = shaders[shaderNdx]
      
      }

      //sets the active shader
      shader(theShader);

      theShader.setUniform("iResolution", [width, height]);
      theShader.setUniform("iFrame", frameCount);
      theShader.setUniform("iMouse", [mouseX, map(mouseY, 0, height, height, 0)]);
      theShader.setUniform("iTime", millis() / 1000.0);
      theShader.setUniform("u_resolution", [width, height]);
      theShader.setUniform("u_time", millis() / 1000.0);
      theShader.setUniform("u_mouse", [mouseX, map(mouseY, 0, height, height, 0)]);

      // rect gives us some geometry on the screen
      rect(0,0,width, height);
    }

    function windowResized(){
      resizeCanvas(windowWidth, windowHeight);
    }

1 Ответ

1 голос
/ 17 июня 2020

Изменить: Эскиз glitch.com, ссылка на который приведена ниже, теперь плавно переключается между тремя шейдерами. Всегда есть 2 активных шейдера (называемые foregroundShader и backgroundShader). Каждые changeEvery кадров текущий foregroundShader становится новым backgroundShader, а для foregroundShader выбирается новый шейдер. backgroundShader всегда имеет альфа 1.0 (непрозрачный), тогда как значение альфа шейдера переднего плана линейно увеличивается с 0.0 до 1.0 в течение одного «эпизода» с использованием p5. js map() работают следующим образом:

foregroundShader.setUniform(
    "backgroundAlpha",
    map(frameCount % changeEvery, 0, changeEvery-1, 0.0, 1.0)
);

Исходный ответ: Возможное решение для плавных переходов между двумя эскизами (я использовал шейдеры 1 и 2 из вашего примера в эскизе сбоя здесь ):

Визуализируйте оба шейдера друг над другом и задайте верхнему значение переменной альфа (прозрачности), например,

uniform float backgroundAlpha;

...

void main() {
    // Calculate r g b values of your colors somehow
    vec3 color = ...

    // Concatenate the alpha (transparency value)
    gl_FragColor = vec4(color.rgb, backgroundAlpha);
}

Затем вы можете установите значение backgroundAlpha от вашего sketch.js до некоторого VALUE, используя theShader.setUniform('backgroundAlpha', VALUE), где VALUE может быть результатом любой функции (должно быть между 0 и 1).

Тот же принцип должен работать и для трех шейдеров.

Обратите внимание, что первый вариант не работал с вашим скетчем с ошибкой, потому что вы использовали старую версию p5. js, которая все еще была a ошибка прозрачности . Однако он работал с использованием 1.0.0 (см. Изменения в файле index.html).

...