Skip to content

filter() shader uniforms stop working if you use more than one #6466

@davepagurek

Description

@davepagurek

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build Process
  • Unit Testing
  • Internalization
  • Friendly Errors
  • Other (specify if possible)

p5.js version

main branch

Web browser and version

Firefox, Chrome

Operating System

macOS 14

Steps to reproduce this

Steps:

  1. Create two filter shaders that need uniforms
  2. Apply uniforms and apply both shaders one after the other via filter()
    The uniforms don't get passed in or updated.

Snippet:

let shaderA
let shaderB

function setup() {
  createCanvas(400, 400, WEBGL);
  shaderA = createFilterShader(`
    precision highp float;
    uniform sampler2D tex0;
    uniform float off;
    varying vec2 vTexCoord;
    void main() {
      gl_FragColor = texture2D(tex0, vTexCoord + vec2(-off, 0.));
    }
  `)
  shaderB = createFilterShader(`
    precision highp float;
    uniform sampler2D tex0;
    uniform float off;
    varying vec2 vTexCoord;
    void main() {
      gl_FragColor = texture2D(tex0, vTexCoord + vec2(0, -off));
    }
  `)
}

function draw() {
  background(220)
  rectMode(CENTER)
  rect(0, 0, 20, 20)
  
  // Uncommenting one at a time works, but having both uncommented
  // makes neither shader's uniforms work
  
  shaderA.setUniform('off', map(mouseX, 0, width, -1, 1, true))
  filter(shaderA)
  
  shaderB.setUniform('off', map(mouseY, 0, height, -1, 1, true))
  filter(shaderB)
}

Live: https://editor.p5js.org/davepagurek/sketches/IQyixHYPt

Causes

It seems to be because of this section of code:

let isSameUserShader = (
this.filterShader !== undefined &&
userShader._vertSrc === this.filterShader._vertSrc &&
userShader._fragSrc === this.filterShader._fragSrc
);
if (!isSameUserShader) {
this.filterShader =
new p5.Shader(pg._renderer, userShader._vertSrc, userShader._fragSrc);
this.filterShader.parentShader = userShader;
}

If you switch filter shaders from one to another, it creates a new shader object. This means that the shader actually being run is not the one you are setting the uniforms on.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    DONE! 🎉

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions