Jump to content

Creating custom filter


florentd
 Share

Recommended Posts

Hello, 

I'm trying to create a custom Filter in Phaser to make dithering.

I used this great resource as a reference: http://alex-charlton.com/posts/Dithering_on_the_GPU/

Here is my code (I modified the DotScreenFilter code): 

PIXI.DotScreenFilter = function()
{
    PIXI.AbstractFilter.call( this );

    this.passes = [this];

    // set the uniforms
    this.uniforms = {
        scale: {type: '1f', value:1},
        angle: {type: '1f', value:5},
        dimensions:   {type: '4fv', value:[0,0,0,0]},
        indexMatrix4x4: {type: '16i',value:[0,  8,  2,  10, 12, 4,  14, 6,3,  11, 1,  9,15, 7,  13, 5]}
    };

    this.fragmentSrc = [
    'precision mediump float;',
    'varying vec2 vTextureCoord;',
    'varying vec4 vColor;',
    'uniform vec4 dimensions;',
    'uniform sampler2D uSampler;',

    'uniform float angle;',
    'uniform float scale;',
    'uniform int indexMatrix4x4[16];',

    'float indexValue() {',
    'int x = int(mod(gl_FragCoord.x, 4));',
    'int y = int(mod(gl_FragCoord.y, 4));',
    'return float(indexMatrix4x4[(x + y * 4)]) / 16.0;',
    '}',

    'float dither(float color) {',
    'float closestColor = (color < 0.5) ? 0.0 : 1.0;',
    'float secondClosestColor = 1.0 - closestColor;',
    'float d = indexValue();',
    'float distance = abs(closestColor - color);',
    'return (distance < d) ? closestColor : secondClosestColor;',
    '}',


    'void main() {',
    'gl_FragColor = vec4(vec3(dither(vColor.a)), 1);',

    '}'
    ];
};

PIXI.DotScreenFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter;

/**
 * The scale of the effect.
 * @property scale
 * @type Number
 */
 Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', {
    get: function() {
        return this.uniforms.scale.value;
    },
    set: function(value) {
        this.dirty = true;
        this.uniforms.scale.value = value;
    }
});
 
/**
 * The radius of the effect.
 * @property angle
 * @type Number
 */
 Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', {
    get: function() {
        return this.uniforms.angle.value;
    },
    set: function(value) {
        this.dirty = true;
        this.uniforms.angle.value = value;
    }
});
 

When I run it,

i got these errors:

Quote

ERROR: 0:10: 'mod' : no matching overloaded function found (phaser.min.js, line 7)
ERROR: 0:11: 'mod' : no matching overloaded function found

 

Any ideas what is wrong ?

 


 

Link to comment
Share on other sites

  • 4 weeks later...

Thanks a lot for your response (and sorry for my late response).

anyway, I got now this error:

Quote

ERROR: 0:12: '[]' : Index expression must be constant

It seems that there is a lot of conversion error between int and float.

This is the original code I want to adapt as a shader in phase and I really struggle !

 

in float color;
out vec4 frag_color;

const int indexMatrix4x4[16] = int[](0,  8,  2,  10,
                                     12, 4,  14, 6,
                                     3,  11, 1,  9,
                                     15, 7,  13, 5);

float indexValue() {
    int x = int(mod(gl_FragCoord.x, 4));
    int y = int(mod(gl_FragCoord.y, 4));
    return indexMatrix4x4[(x + y * 4)] / 16.0;
}

float dither(float color) {
    float closestColor = (color < 0.5) ? 0 : 1;
    float secondClosestColor = 1 - closestColor;
    float d = indexValue();
    float distance = abs(closestColor - color);
    return (distance < d) ? closestColor : secondClosestColor;
}

void main () {
    fragColor = vec4(vec3(dither(color)), 1);
}

Any insight to adapt it for phaser ?

Link to comment
Share on other sites

Wow ! The effect is nice.

It works in firefox, but not in Chrome and Safari. And I was trying to implement dithering on the screen (like a post-processing effect), and not only on a texture, but It seems really complicated with my current knowledge of shaders. (sorry, if it sound ungrateful, your code is great ! )

Link to comment
Share on other sites

Hi 

I don't know how to apply a filter to a group of game objects with Phaser 3.  However I have managed to apply the dither filter to a group using Phaser CE.

https://github.com/neilbgames/My-attempt-at-implementing-http-alex-charlton.com-posts-Dithering_on_the_GPU-using-PhaserCE

I understand that Phaser CE code doesn't belong in this section but I thought I would post this in case it may be useful. 

Link to comment
Share on other sites

  • 2 weeks later...

Thanks for your help Gold Finch :)

I finally succeed, so for the 3 peoples in the world who (maybe) want to do a dither effect with shader in Phaser, here is my code:

 

PIXI.dither = function()
{
    PIXI.AbstractFilter.call( this );
 
    this.passes = [this];
 
    // set the uniforms
    this.uniforms = {
        scale: {type: '1f', value:1},
        angle: {type: '1f', value:5},
        dimensions:   {type: '4fv', value:[0,0,0,0]}
    };

    this.fragmentSrc = [
  
        'precision mediump float;',

            'uniform sampler2D uSampler;',
            'varying vec2 vTextureCoord;',
            'float scale = 0.5;',
            'float find_closest(int x, int y, float c0) {',
                
          'vec4 dither0 = vec4( 1.0, 33.0, 9.0, 41.0);',
                'vec4 dither1 = vec4(49.0, 17.0, 57.0, 25.0);',
                'vec4 dither2 = vec4(13.0, 45.0, 5.0, 37.0);',
                'vec4 dither3 = vec4(61.0, 29.0, 53.0, 21.0);',

                'float limit = 0.0;',
                'float value = 0.0;',
                
                'vec4 dither;',
                
                'if(x == 0) {',
                    'dither = dither0;',
                '} else if(x == 1) {',
                    'dither = dither1;',
                '} else if(x == 2) {',
                    'dither = dither2;',
                '} else if(x == 3) {',
                    'dither = dither3;',
                '}',
                
                'if(x < 5) {',
                    'if(y == 0) {',
                        'value = dither[0];',
                    '} else if(y == 1) {',
                        'value = dither[1];',
                    '} else if(y == 2) {',
                        'value = dither[2];',
                    '} else if(y == 3) {',
                        'value = dither[3];',
                    '}',
                
                    'limit = (value + 1.0) / 64.0;',
                '}',
                'if(c0 < limit) {',
                    'return 0.0;',
                '} else {',
                    'return 1.0;',
                '}',
            '}',
            'void main() {',
                
                   'vec3 lum = vec3(0.299, 0.587, 0.114);',
                'float grayscale = dot(texture2D(uSampler, vTextureCoord).rgb, lum);',
                'vec3 rgb = texture2D(uSampler, vTextureCoord).rgb;',
                'vec2 xy = gl_FragCoord.xy * scale;',
                'int x = int(mod(xy.x, 4.0));',
                'int y = int(mod(xy.y, 4.0));',
                'vec3 finalRGB;',
                'finalRGB.r = find_closest(x, y, rgb.r);',
                'finalRGB.g = find_closest(x, y, rgb.g);',
                'finalRGB.b = find_closest(x, y, rgb.b);',
                'gl_FragColor = vec4(finalRGB, 1.0);',
            '}'
    ];
};

PIXI.dither.prototype = Object.create( PIXI.AbstractFilter.prototype );
PIXI.dither.prototype.constructor = PIXI.dither;
 
/**
 * The scale of the effect.
 * @property scale
 * @type Number
 */
Object.defineProperty(PIXI.dither.prototype, 'scale', {
    get: function() {
        return this.uniforms.scale.value;
    },
    set: function(value) {
        this.dirty = true;
        this.uniforms.scale.value = value;
    }
});
 
/**
 * The radius of the effect.
 * @property angle
 * @type Number
 */
Object.defineProperty(PIXI.dither.prototype, 'angle', {
    get: function() {
        return this.uniforms.angle.value;
    },
    set: function(value) {
        this.dirty = true;
        this.uniforms.angle.value = value;
    }
});
 
    

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...