[Custom Pipeline] Settings uniforms per object

Hi, I’m trying to write a custom pipeline to replace certain colours on a sprite, the shader works fine, but it seems like every object using the pipeline is always using the same uniforms.

Here’s the pipeline

import { GameObjects } from 'phaser';

export class DyePipeline extends Phaser.Renderer.WebGL.Pipelines.SinglePipeline {
  // the unique id of this pipeline
  public static readonly KEY = 'Dye';

  constructor(game: Phaser.Game) {
    super({
      game: game,
      name: 'Dye',
      fragShader: `
        precision mediump float;

        uniform sampler2D uMainSampler;
        uniform sampler2D uPaletteSampler;
        uniform sampler2D uDyeSampler;

        uniform float uDyePaletteIndex;

        varying vec2 outTexCoord;

        void main(void) 
        {
          vec4 texture = texture2D(uMainSampler, outTexCoord);
          
          float mapIndex = texture.r;
          float dyeIndex = texture.b;
          float paletteIndex = texture.g;

          float rowOffset = 1.0 / 73.0; // Divide by the number of rows
          vec2 dyeTexCoord = vec2(dyeIndex, uDyePaletteIndex * rowOffset);

          //vec4 paletteColor = texture2D(uPaletteSampler, vec2(0.13, 0.0));
          vec4 dyeColor = texture2D(uDyeSampler, dyeTexCoord);
          
          gl_FragColor = dyeColor;
        }
      `,
      
    });
  }

  onBind(gameObject: GameObjects.GameObject) {
    super.onBind();
    console.log(gameObject);
    //@ts-ignore
    const data = gameObject.pipelineData;

    this.set1f('uDyePaletteIndex', Math.floor(Math.random() * 72));
  }
}

Right now I’m just setting it to a random value, but all objects are sharing that value.
How can I use different values per object?

Figured out what I was missing:

onBind(gameObject: GameObjects.GameObject) {
    super.onBind();

    const data = gameObject.pipelineData;

    this.set1f('uDyePaletteIndex', data.dyeIndex);
  }

  onBatch (gameObject: GameObjects.GameObject) {
    if (gameObject) {
      this.flush();
    }
  }

onBind is called on every game object that contains the pipeline and this is where you set your per object variables.

and then calling flush during onBatch does something, but makes it work.
You can just do everything in onBind, but the examples separate the two, not sure why.

1 Like