# Applying grayscale filter not working after scene restart

**URL:** <https://phaser.discourse.group/t/applying-grayscale-filter-not-working-after-scene-restart/1700>\
**Category:** Phaser 3\
**Created:** [March 16, 2019, 2:18am UTC](https://phaser.discourse.group/t/applying-grayscale-filter-not-working-after-scene-restart/1700 "2019-03-16T02:18:26Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![colemars](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/colemars/32/917_2.png) [@colemars](https://phaser.discourse.group/u/colemars)\
**Post date:** [March 16, 2019, 2:18am UTC](https://phaser.discourse.group/t/applying-grayscale-filter-not-working-after-scene-restart/1700/1 "2019-03-16T02:18:26Z")

</div>

Edit:

I’ve demonstrated this using lab code for replicability’s sake:

You can input the following code into [http://labs.phaser.io](http://labs.phaser.io/edit.html?src=src%5Cactions%5Cgrid%20align.js) console.

Click Grayscale, Reset, then grayscale again.

```
var DemoA = new Phaser.Class({

    Extends: Phaser.Scene,

    initialize:

    function DemoA ()
    {
        Phaser.Scene.call(this, { key: 'demoA', active: true });
    },

    preload: function ()
    {
        this.load.image('picA', 'assets/pics/lance-overdose-loader-eye.png');
         this.load.image('picB', 'assets/pics/sukasuka-chtholly.png');
    },

    create: function ()
    {
        this.grayscalePipeline = this.game.renderer.addPipeline('Grayscale', new GrayscalePipeline(this.game));
        const text = this.add.text(0, 0, 'grayscale', {
        color: 'white',
        fontSize: 20
      });
      const newText = this.add.text(0, 50, 'reset scene', {
        color: 'white',
        fontSize: 20
      });

    text.setInteractive({ useHandCursor: true });
    newText.setInteractive({ useHandCursor: true });

    text.on('pointerup', () => {
      this.cameras.main.setRenderToTexture(this.grayscalePipeline);
    });

    newText.on('pointerup', () => {
      this.scene.restart();
    });
    
        this.add.image(400, 300, 'picA');

        this.input.once('pointerdown', function () {

            this.scene.sendToBack();

        }, this);
    }

});

var DemoB = new Phaser.Class({

    Extends: Phaser.Scene,

    initialize:

    function DemoB ()
    {
        Phaser.Scene.call(this, { key: 'demoB', active: true });
    },

    preload: function ()
    {
        this.load.image('picB', 'assets/pics/sukasuka-chtholly.png');
    },

    create: function ()
    {
        this.add.image(400, 500, 'picB');
    }

});

var DemoC = new Phaser.Class({

    Extends: Phaser.Scene,

    initialize:

    function DemoC ()
    {
        Phaser.Scene.call(this, { key: 'demoC', active: true });
    },

    preload: function ()
    {
        this.load.image('picC', 'assets/pics/titan-mech.png');
    },

    create: function ()
    {
        this.add.image(300, 300, 'picC');
    }

});

var GrayscalePipeline = new Phaser.Class({

    Extends: Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline,

    initialize:

    function GrayscalePipeline (game)
    {
        Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline.call(this, {
            game: game,
            renderer: game.renderer,
            fragShader:`
                precision mediump float;
                uniform sampler2D uMainSampler;
                varying vec2 outTexCoord;
                void main(void) {
                vec4 color = texture2D(uMainSampler, outTexCoord);
                float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
                gl_FragColor = vec4(vec3(gray), 1.0);
                }`
        });
    } 
});

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: [DemoB, DemoC, DemoA]
};

var game = new Phaser.Game(config);
```

---

<div class="post-metadata">

**Author:** ![Telinc1](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/telinc1/32/60_2.png) [@Telinc1](https://phaser.discourse.group/u/Telinc1)\
**Post date:** [March 16, 2019, 12:39pm UTC](https://phaser.discourse.group/t/applying-grayscale-filter-not-working-after-scene-restart/1700/2 "2019-03-16T12:39:56Z")

</div>

You add the `Grayscale` pipeline every time `SceneA` is created. Because pipelines are registered globally for the entire game, this will cause an error if you create the Scene more than once. As the [source code of `addPipeline`](https://github.com/photonstorm/phaser/tree/v3.16.2/src/renderer/webgl/WebGLRenderer.js#L815) will tell you, passing a duplicate key will not register the pipeline you pass in, but still return it. As a result, the sprite will use an unregistered pipeline.

There are three ways you can fix this - two of them involve making sure the pipeline is only registered once. When initializing `this.grayscalePipeline`, you can check if the `Grayscale` pipeline already exists and create it only if it doesn’t - `this.grayscalePipeline = this.game.renderer.getPipeline('Grayscale') || this.game.renderer.addPipeline('Grayscale', new GrayscalePipeline(this.game));`. This works because `getPipeline` returns `null` if the given key doesn’t exist and the `||` operator will evaluate the right side only if the left one is falsey. Really, this is equivalent to the following code:

```javascript
this.grayscalePipeline = this.game.renderer.getPipeline('Grayscale');

if(this.grayscalePipeline == null){
    this.grayscalePipeline = this.game.renderer.addPipeline('Grayscale', new GrayscalePipeline(this.game));
}

```

Another way you could fix this is to skip the creation of the pipeline entirely if it already exists:

```javascript
if(!this.game.renderer.hasPipeline('Grayscale')){
    this.game.renderer.addPipeline('Grayscale', new GrayscalePipeline(this.game))
}

```

Then, you can pass the key (`'Grayscale')` instead of a reference (`this.grayscalePipeline`) to the `setRenderToTexture` method. The downside of fixing it this way is that you won’t have a reference to the exact pipeline, so you won’t be able to change it, which is why I recommend doing it the first way.

Speaking of changing the pipeline, I’m going to once again stress that a single pipeline instance is global for the whole game. If you need a separate pipeline each time you start the Scene (for example, if you’re using the pipeline in another scene), you can dynamically generate a pipeline key - for example, `'Grayscale_' + Date.now()`. The problem with this is that, if you restart the Scene multiple times, you’ll be left with a lot of unused registered pipelines. If you fix it this way, you’ll have to unregister the pipeline (with `removePipeline`) before the Scene shuts down (which you can detect with [a `shutdown` event from the Scene’s event emitter](https://photonstorm.github.io/phaser3-docs/Phaser.Scenes.Events.html#event:SHUTDOWN)).
