Jump to content

Bulge Pinch filter


JuloxRox
 Share

Recommended Posts

Hi all,

 

First of all, I would like to congrat the Pixi team for its amazing framework!

I am currently working on a bulge/pinch filter like the one presented here : https://github.com/GoodBoyDigital/glfx.js/blob/master/src/filters/warp/bulgepinch.js.

 

I am trying to adapt the glfx filter to the v3 pixi engine but I am not so much experimented with javascript and as3 to well understand what I am doing.

I based my conversion following your work on the dotscreen filter you already adapt for that library and here I am so far...

https://jsfiddle.net/aqvtw5yw/

 

PIXI.filters.AbstractFilter.call(this,    // vertex shader    null,    // fragment shader    [        'precision mediump float;',        'uniform vec2 center;',        'uniform float radius;',        'uniform float strength;',        'void main() {',            'vec2 coord = center;',            'float distance = length(coord);',            'if (distance < radius) {',                'float percent = distance / radius;',                'if (strength > 0.0) {',                    'coord *= mix(1.0, smoothstep(0.0, radius / distance, percent), strength * 0.75);',                '} else {',                    'coord *= mix(1.0, pow(percent, 1.0 + strength * 0.75) * radius / distance, 1.0 - percent);',                '}',            '}',        '}'    ].join('\n'),    // custom uniforms    {        radius: {type: '1f', value:10},        strength: {type: '1f', value:5},        center:   {type: '2fv', value:[100,100]}    });
 

Something is not working, no error shown in the console, I am a bit lost ;)

 

I would like to reproduce exactly the same so if someone here could help me a bit to accomplish my goal, it would be awsome!

 

Thanks for your help :)

Link to comment
Share on other sites

Ok guys I did it!

 

Here is a pixi v3 bulge / pinch filter inspired by glfx

 

//strength between -1 and 1function BulgePinchFilter(){    PIXI.filters.AbstractFilter.call(this,        // vertex shader        null,        // fragment shader        [            'precision mediump float;',            'uniform float radius;',            'uniform float strength;',            'uniform vec2 center;',            'uniform sampler2D uSampler;',            'uniform vec2 texSize;',            'varying vec2 vTextureCoord;',                        'void main()',            '{',                'vec2 coord = vTextureCoord * texSize;',                'coord -= center;',                'float distance = length(coord);',                'if (distance < radius) {',                    'float percent = distance / radius;',                    'if (strength > 0.0) {',                        'coord *= mix(1.0, smoothstep(0.0, radius /     distance, percent), strength * 0.75);',                    '} else {',                        'coord *= mix(1.0, pow(percent, 1.0 + strength * 0.75) * radius / distance, 1.0 - percent);',                    '}',                '}',                'coord += center;',                'gl_FragColor = texture2D(uSampler, coord / texSize);',                'vec2 clampedCoord = clamp(coord, vec2(0.0), texSize);',                'if (coord != clampedCoord) {',                    'gl_FragColor.a *= max(0.0, 1.0 - length(coord - clampedCoord));',                '}',            '}'        ].join('\n'),        // custom uniforms        {            radius: { type: '1f', value: 200 },            strength: { type: '1f', value: 0.8 },            center: { type: 'v2', value: {x: 280, y: 280} },            texSize: { type: 'v2', value: {x: window.innerWidth, y:window.innerHeight } }        }    );};BulgePinchFilter.prototype = Object.create(PIXI.filters.AbstractFilter.prototype);BulgePinchFilter.prototype.constructor = BulgePinchFilter;Object.defineProperties(BulgePinchFilter.prototype, {    radius: {        get: function ()        {            return this.uniforms.radius.value;        },        set: function (value)        {            this.uniforms.radius.value = value;        }    },    strength: {        get: function ()        {            return this.uniforms.strength.value;        },        set: function (value)        {            this.uniforms.strength.value = value;        }    }});var renderer = PIXI.autoDetectRenderer(300, 300);document.body.appendChild(renderer.view);var stage = new PIXI.Container();stage.interactive = true;var bg = PIXI.Sprite.fromImage("http://i.imgur.com/NGr3yaz.jpg");bg.anchor.set(0.5);bg.position.x = bg.position.y = 0;var container = new PIXI.Container();container.position.x = renderer.width / 2;container.position.y = renderer.height / 2;var filter = new BulgePinchFilter();container.addChild(bg);stage.addChild(container);window.requestAnimFrame = function(){    return (        window.requestAnimationFrame       ||         window.webkitRequestAnimationFrame ||         window.mozRequestAnimationFrame    ||         window.oRequestAnimationFrame      ||         window.msRequestAnimationFrame     ||         function(callback){            window.setTimeout(callback, 1000 / 60);        }    );}();function animate() {    container.filters = [filter];    renderer.render(stage);    requestAnimFrame(animate);}requestAnimFrame(animate);

 

JSFiddle : http://jsfiddle.net/apgt4mxt/3/

 

It works as expected !

One last problem, it seems that the coordinates of the center of the effect are not in pixels. For exemple my img is 300 x 300 but if I put center x = 150 and y = 150 the center point is not the center of the img.

Can someone explain me why?

 

Thanks !

Link to comment
Share on other sites

Nice job converting that filter, how do you feel about sending a PR to this repo where I have been trying to collect this extra filters for pixi?

 

https://github.com/pixijs/pixi-extra-filters

 

By the way, it looks off because you have texSize set to window.innerWidth and window.innerHeight. I updated it to use `dimensions` which pixi will set for you to the renderer and quad size, and it looks great:

 

http://jsfiddle.net/apgt4mxt/4/

Link to comment
Share on other sites

I have created a fork for putting that filter on github cause i dont have write access for a PR. The filter file is in the index of my fork. 

 

That isn't how PRs work. To make a PR you fork, then hit the green button on your personal fork to open a PR to my repo.

 

https://help.github.com/articles/using-pull-requests/#initiating-the-pull-request

Link to comment
Share on other sites

  • 3 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

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