alexzchen Posted September 12, 2019 Share Posted September 12, 2019 I wrote a filter to achieve special effects. Part of the code is as follows,scale and rotate works well,but the anchor I set seems not right,the sprite still rotates around the upper left corner. constructor(texture:PIXI.Texture) { super(MyFilter.vertSrc, MyFilter.fragSrc) this.maskMatrix = new PIXI.Matrix(); let sprite = new PIXI.Sprite(texture); app.stage.addChild(sprite); sprite.visible = false; this.maskSprite = sprite; this.maskSprite.anchor.set(0.5) //it doesn't work! this._translate = [0, 0]; this.uniforms.mapSampler = sprite.texture; this.uniforms.filterMatrix = this.maskMatrix; } translate(x:number, y:number) { this._translate[0] = x; this._translate[1] = y; this.uniforms.vTranslate = this._translate; } scale(x:number, y:number) { this.maskSprite.scale.set(x, y); } rotate(rad:number) { this.maskSprite.rotation = rad; } ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 12, 2019 Share Posted September 12, 2019 calculateSpriteMatrix takes anchor into account: https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/filters/FilterSystem.js#L395 It should work. You've made a mistake in a place that is hidden from my telepathy, please provide a demo on codepen/jsfiddle/pixi-playground. Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 18, 2019 Author Share Posted September 18, 2019 On 9/13/2019 at 12:44 AM, ivan.popelyshev said: calculateSpriteMatrix takes anchor into account: https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/filters/FilterSystem.js#L395 It should work. You've made a mistake in a place that is hidden from my telepathy, please provide a demo on codepen/jsfiddle/pixi-playground. I provided a demo on codepen,please visit this url: https://codepen.io/alexzchen/pen/GRKYZWq I expect to draw filters based on the center point when tile/rotate/scale/move, not the upper left corner now, please help me, thanks. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 18, 2019 Share Posted September 18, 2019 center of filterArea or center of screen? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 18, 2019 Share Posted September 18, 2019 OK, I can explain how to work with calculateSpriteMatrix: imagine that you have both cloth and flowers inside the scene as a separate sprites. One covers another. Use "flowerSprite.position" , "anchor", "scale" and everything else to position FLOWER SPRITE correctly. the matrix will reflect it. Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 18, 2019 Author Share Posted September 18, 2019 Just now, ivan.popelyshev said: center of filterArea or center of screen? center of the filterArea Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 18, 2019 Author Share Posted September 18, 2019 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 18, 2019 Share Posted September 18, 2019 Right now your approach is hybrid: you use both sprite matrix and manually add rotate/scale inside shader. step 1: Forget about filter, use two sprites, set "flowerSprite.blendMode = PIXI.BLEND_MODES.ADD". Check that you correctly position/rotate/scale that flower sprite. step 2: add a filter, but keep flowerSprite in the stage for transform recalculation, set "flowerSprite.renderable=false" so it doesnt render. Dont use any rotations/scales/stuff inside filter, just use that filterMatrix and vFilterCoord. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 18, 2019 Share Posted September 18, 2019 ok then, "flowerSprite.position" should be that center in your stage, scale/rotation you understand, set its "pivot" to offset. Its a transform problem that you are trying to solve. Understand position/scale/rotation/pivot sequence and you'll be golden Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 18, 2019 Author Share Posted September 18, 2019 thanks very much, I will have a try ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 18, 2019 Share Posted September 18, 2019 Also, if you are going to do "A.rgb*B.rgb" stuff - its basically MULTIPLY blendMode that can be achieved without filter. Try TilingSprite! var ts = new PIXI.TilingSprite(myTexture, w, h); ts.tileTransform.position.set(w/2,h/2); ts.tileTransform.scale.set(...); ts.tileTransform.rotation = ... ts.tileTransform.pivot.set(...); //offset //might actually swap position/pivot there, i dont remember ;) ts.blendMode = PIXI.BLEND_MODES.MULTIPLY; Also see if you'll need to switch off mipmaps for flower texture. "flowerTexture.baseTexture.mipmap=false". Or set wrapMode to REPEAT, but that's only for pow2-textures. for non-pow2 you can also set mipmap to PIXI.MIPMAP_MODES.ON - that'll work for WEBGL2 (unavailable un most mobiles). Cant explain it all in one post, its tricky webgl stuff. If you manage to make it work with sprite or tilingSprite, then filter is also easy - filterMatrix, vFilterCoord helps you to get correct coords for sampling, then you apply your own equation for colors. Dont forget that its premultiplied alpha - might have some problems if your flowers are transparent. Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 18, 2019 Author Share Posted September 18, 2019 I tried Tiling Sprite and MULTILIPLE, but this way can't meet my requirements. My cloth picture may have some transparency. I don't want the flower picture to cover the transparent area. Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 18, 2019 Author Share Posted September 18, 2019 In addition, there may be multiple sprites on my stage. I only hope that the flower only works on the specified cloth sprite without affecting other sprites, so I may not be able to use PIXI.BLEND_MODES. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 18, 2019 Share Posted September 18, 2019 > In addition, there may be multiple sprites on my stage. Yes, that looks like a Filter. But you can do the following: add flower inside cloth, and add a AlphaFilter on cloth. That way MULTIPLY approach can work The idea is that any filter forces pixi to use temporary FrameBuffer to calculate the result. I'm not against approach of custom filter - I supply you alternatives that are easier to do, and that cant be tested and debugged fast - then you can make your own filter when everything else (transforms) is already solved. Quote Link to comment Share on other sites More sharing options...
alexzchen Posted September 19, 2019 Author Share Posted September 19, 2019 Thanks for your advice, I've tried it as you said. It seems to work, but how do I remove the black area? I want it became transparent which is black now function setup(loader, res) { let cloth = new PIXI.Sprite(PIXI.loader.resources["cloth"].texture) let flower = new PIXI.TilingSprite(PIXI.loader.resources["flower"].texture); let fw = 328; let fh = 240; let cw = 179; let ch = 182; flower.anchor.set(0.5,0.5); flower.rotation = 0.3; flower.scale.set(1.1,1.1); flower.width = fw; flower.height = fh; flower.position.set(fw/2,fh/2); flower.tilePosition.set((fw-cw)/2,(fh-ch)/2); flower.blendMode= PIXI.BLEND_MODES["MULTIPLY"]; cloth.filters = [new PIXI.filters.AlphaFilter()]; cloth.addChild(flower); app.stage.addChild(cloth); } Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted September 19, 2019 Share Posted September 19, 2019 if your cloth wont be rotated, you can just change filterArea every frame - that will limit the temporary buffer pixi uses to draw this thing on. cloth.filterArea = cloth.getBounds(); // execute every frame or every time you change something If you start rotating cloth... well.. I believe you'll need to get inside filter and use that multiply formula you did before, "gl_FragColor = stuff1 * stuff2". However this time, you already have formulaes for position, scale and pivot (which is basically tilePosition of tilingSprite) Actually, why do you even rotate that TilingSprite? I thought "tilingSprite.tileTransform.rotation" is better in your case 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.