Exca Posted January 25, 2016 Share Posted January 25, 2016 I was wondering if it's possible to instantiate one filter and then use that in multiple objects with different uniform values? If it's possible, then what would be the correct way to do it? Quote Link to comment Share on other sites More sharing options...
mattstyles Posted January 25, 2016 Share Posted January 25, 2016 Uniforms are variable, you can update them on the fly. The custom filter example shows mutating uniforms. Quote Link to comment Share on other sites More sharing options...
Exca Posted January 26, 2016 Author Share Posted January 26, 2016 That was not exactly what I meant, the question wasn't specific enough. Here's an example based on that custom filter example of what I'd like to do: var renderer = PIXI.autoDetectRenderer(800, 600); document.body.appendChild(renderer.view); // create the root of the scene graph var stage = new PIXI.Container(); function CustomFilter(fragmentSource) { PIXI.AbstractFilter.call(this, // vertex shader null, // fragment shader fragmentSource, // set the uniforms { customUniform : {type : '1f', value : 0} } ); } CustomFilter.prototype = Object.create(PIXI.AbstractFilter.prototype); CustomFilter.prototype.constructor = CustomFilter; var sprite1 = PIXI.Sprite.fromImage("_assets/bkg-grass.jpg"); stage.addChild(sprite1); var sprite2 = PIXI.Sprite.fromImage("_assets/bkg-grass.jpg"); stage.addChild(sprite2); PIXI.loader.add('shader','_assets/basics/shader.frag'); PIXI.loader.once('complete',onLoaded); PIXI.loader.load(); var filter; function onLoaded (loader,res) { var fragmentSrc = res.shader.data; filter = new CustomFilter(fragmentSrc); //Use the shader as filter or shader, both are ok for my case. sprite1.shader = filter; sprite2.shader = filter; animate(); } function animate() { //This changes uniforms in both of the sprites. I'd like to have separate //uniforms per sprite without creating new filters per each as that //compiles into a lot of shader programs. filter.uniforms.customUniform.value += 0.04; renderer.render(stage); requestAnimationFrame( animate ); } Quote Link to comment Share on other sites More sharing options...
chg Posted January 26, 2016 Share Posted January 26, 2016 17 hours ago, Exca said: I was wondering if it's possible to instantiate one filter and then use that in multiple objects with different uniform values? If it's possible, then what would be the correct way to do it? I imagine this would be possible but I'm thinking you need to ensure the objects aren't batched, and that you run code just before they are about to be rendered that changes the uniforms... you might have to dig a little bit into Pixi.js to do this. The catch is that changing uniforms means a WebGL state changes and a separate draw call, meaning that the Pixi sprite batcher will need to draw it's current batch and start a new batch of sprites for the filter & changed uniforms (the later I don't think Pixi.js will necessarily handle for you)... this may or may not be a performance issue for you later depending on how many changes the batcher sees walking the scene graph (this is a guess on my part). If it works out that you will change the uniforms many many times per frame, you may want to consider other approaches. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted January 26, 2016 Share Posted January 26, 2016 5 hours ago, chg said: I imagine this would be possible but I'm thinking you need to ensure the objects aren't batched, and that you run code just before they are about to be rendered that changes the uniforms... you might have to dig a little bit into Pixi.js to do this. Filters are breaking batches, because they are using off-screen buffers. I think its better to override _renderWebGL method. I use "_" because its really mySprite.oldRenderWebGL = mySprite.renderWebGL; mySprite.renderWebGL = function() { //that part is copied from container's renderWebGL. // if the object is not visible or the alpha is 0 then no need to render this element if (!this.visible || this.worldAlpha <= 0 || !this.renderable) { return; } //change uniform of filter to my value! this.filters[0].uniforms.blablabla.value = this.filterUniformValue; //call old method. For your knowledge, its PIXI.Container.prototype.renderWebGL this.oldRenderWebGL(); } Patch all objects that needs that hack. Quote Link to comment Share on other sites More sharing options...
Exca Posted January 27, 2016 Author Share Posted January 27, 2016 Thanks! Anyone know how can I mark post as answered with this upgraded forum? Can't seem to find the button. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.