radixzz Posted February 21, 2017 Share Posted February 21, 2017 Hi guys! I'm trying to figure out how to apply some custom frag shader into a filter. The intented effect is a simple crt warp over a sprite. Here is what I got so far: https://jsfiddle.net/djq6kjx4/1/ but It should look something like the image in the attachment. As you can see from the example above the warp effect is mostly visible to one corner. Now I'm starting with shaders but I think the reason is that vTextureCoord is somehow off? I tried to use the mapCoords and unmapCoords from https://github.com/pixijs/pixi-filters/blob/master/src/pixelate/pixelate.frag similarly without success (I have no Idea what those do). Some time after I tried to use gl_fragCoord directly like this: vec2 coord = gl_FragCoord.xy / dimensions.xy; wich seems to do the trick but the texture comes out flippled. Im sure it can be fixed but I don't think this is a good path to follow. Right? Any hint would be much appreciated Thanks Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 22, 2017 Share Posted February 22, 2017 Filters are working with region on renderTexture, not the full texture, that's why mapCoord / unmapCoord is needed. Also you can't use gl_FragCoord, because it can be either framebuffer either resulting canvas, framebuffer can have different size than screen, and canvas can be flipped. mapCoord/unmapCoord and "uvs" ( vTextureCoord ) are our trade-off to use multiple filters at once and to use pool of pow2 renderTextures. The problem is, they are in pixels, so you need dimensions. coord = mapCoord(coord ) / dimensions; coord = warp( coord ); coord = unmapCoord(coord * dimensions); But you already have them! Or, you can compute them automagically: //that's better move to your filter class filter.apply = function(filterManager, input, output) { this.uniforms.dimensions[0] = input.sourceFrame.width this.uniforms.dimensions[1] = input.sourceFrame.height // draw the filter... filterManager.applyFilter(this, input, output); } https://jsfiddle.net/60e5pp8d/1/ Also, you can remove division (/dimensions) and filterArea if you take into account what filterArea is really is: filterArea[0] = output.size.width; filterArea[1] = output.size.height; filterArea[2] = input.sourceFrame.x; filterArea[3] = input.sourceFrame.y; You can calculate the real params you need in "filter.apply", and reduce our code that way it'll look better I'm very sorry that there weren't that kind shader there before, and that we have to hack that. I make a promise to fix that in my next big overhaul of filters, that'll be soon! radixzz and pdl.dev 2 Quote Link to comment Share on other sites More sharing options...
radixzz Posted February 23, 2017 Author Share Posted February 23, 2017 Thank you very much! Quote Link to comment Share on other sites More sharing options...
tywang2006 Posted February 24, 2017 Share Posted February 24, 2017 On 2/22/2017 at 9:57 AM, ivan.popelyshev said: Filters are working with region on renderTexture, not the full texture, that's why mapCoord / unmapCoord is needed. Also you can't use gl_FragCoord, because it can be either framebuffer either resulting canvas, framebuffer can have different size than screen, and canvas can be flipped. mapCoord/unmapCoord and "uvs" ( vTextureCoord ) are our trade-off to use multiple filters at once and to use pool of pow2 renderTextures. The problem is, they are in pixels, so you need dimensions. coord = mapCoord(coord ) / dimensions; coord = warp( coord ); coord = unmapCoord(coord * dimensions); But you already have them! Or, you can compute them automagically: //that's better move to your filter class filter.apply = function(filterManager, input, output) { this.uniforms.dimensions[0] = input.sourceFrame.width this.uniforms.dimensions[1] = input.sourceFrame.height // draw the filter... filterManager.applyFilter(this, input, output); } https://jsfiddle.net/60e5pp8d/1/ Also, you can remove division (/dimensions) and filterArea if you take into account what filterArea is really is: filterArea[0] = output.size.width; filterArea[1] = output.size.height; filterArea[2] = input.sourceFrame.x; filterArea[3] = input.sourceFrame.y; You can calculate the real params you need in "filter.apply", and reduce our code that way it'll look better I'm very sorry that there weren't that kind shader there before, and that we have to hack that. I make a promise to fix that in my next big overhaul of filters, that'll be soon! just did test, mask is not working... Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 24, 2017 Share Posted February 24, 2017 https://jsfiddle.net/60e5pp8d/1/ works , what are you talking about? Quote Link to comment Share on other sites More sharing options...
Sambrosia Posted March 3, 2017 Share Posted March 3, 2017 On 2/24/2017 at 7:49 AM, tywang2006 said: I make a promise to fix that in my next big overhaul of filters, that'll be soon! Cool to hear! I think clear documentation for how the coordinates/uvs actually work would help things a lot. Same for the FilterManager. I'm still not sure what exactly that does, even after reading through the sources. I'd be happy to help write docs, but I lack the knowledge to do so here. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
pdl.dev Posted March 20, 2017 Share Posted March 20, 2017 I'm having similar problem understanding this conversion between the coordinates. I'm trying to create a filter that creates an animated "growing circle", like wave, that grows with "time". I would like to generally set the center to [0.5, 0.5] so that it centers on the sprite. However, it doesn't seem like so and moving the sprite's position also makes it changes. I've applied the "mapCoord" as suggested. Please see: https://jsfiddle.net/3j9xxutf/1/ Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 21, 2017 Share Posted March 21, 2017 Yes, we know its a serious bug I'll post an issue to github. We definitely need to rework filters for pixi-v5. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 25, 2017 Share Posted March 25, 2017 OK, temporary fix: vec2 mapCoord( vec2 coord ) { coord *= filterArea.xy; return coord; } vec2 unmapCoord( vec2 coord ) { coord /= filterArea.xy; return coord; } Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 25, 2017 Share Posted March 25, 2017 @pdl.dev And your fix: 1. ignore zw 2. newCenter = center varying vec2 vTextureCoord; uniform sampler2D uSampler; uniform vec4 filterArea; uniform vec2 dimensions; uniform float time; uniform vec2 center; uniform vec4 color; uniform float size; vec2 mapCoord( vec2 coord ) { coord *= filterArea.xy; return coord; } void main() { vec2 uv = vTextureCoord; vec4 finalColor; vec2 mappedCoord = mapCoord(uv) / dimensions; vec2 newCenter = center; float r = distance(mappedCoord, newCenter); float value = smoothstep(time-size,time,r) - smoothstep(time+size, time, r); finalColor += value * color; finalColor.w = 1.0; if (value < 1.0 && value > 0.0) { gl_FragColor = mix(texture2D(uSampler, uv), finalColor, 1.0); } else { gl_FragColor = texture2D(uSampler, uv); } } Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 25, 2017 Share Posted March 25, 2017 Clarification: "filterArea.xy" is the relative size of the area "filterArea.zw" is its position. Use it only if you need absolute position Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 25, 2017 Share Posted March 25, 2017 Quote Link to comment Share on other sites More sharing options...
Oliver Zhou Posted January 17, 2020 Share Posted January 17, 2020 (edited) I tried this example in v5, it seems that it didn't work as expected any more. I have no idea why class CrtWarpFilter extends PIXI.Filter { constructor() { super(null, ` precision mediump float; varying vec2 vTextureCoord; uniform sampler2D uSampler; uniform highp vec4 inputSize; uniform highp vec4 outputFrame; vec2 mapCoord( vec2 coord ) { coord *= inputSize.xy; coord += outputFrame.xy; return coord; } vec2 unmapCoord( vec2 coord ) { coord -= outputFrame.xy; coord /= inputSize.xy; return coord; } vec2 warpAmount = vec2( 2.0 / 34.0, 1.0 / 16.0 ); vec2 warp(vec2 pos) { pos = pos * 2.0 - 1.0; pos *= vec2( 1.0 + (pos.y * pos.y) * warpAmount.x, 1.0 + (pos.x * pos.x) * warpAmount.y ); return pos * 0.5 + 0.5; } void main() { vec2 coord = vTextureCoord; coord = mapCoord(coord ) / outputFrame.zw; coord = warp( coord ); coord = unmapCoord(coord * outputFrame.zw); gl_FragColor = texture2D( uSampler, coord ); } `); } } Edited January 17, 2020 by Oliver Zhou ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
Oliver Zhou Posted January 17, 2020 Share Posted January 17, 2020 I have rewritten the code as https://github.com/pixijs/pixi.js/wiki/v5-Creating-filters suggested. Please help Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted January 17, 2020 Share Posted January 17, 2020 (edited) Hello, @Oliver Zhou ! Please post your code in codepen, jsfiddle or pixi-playground OH, wait, I see you posted it here. Edited January 17, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
Oliver Zhou Posted January 17, 2020 Share Posted January 17, 2020 22 minutes ago, ivan.popelyshev said: Hello, @Oliver Zhou ! Please post your code in codepen, jsfiddle or pixi-playground OH, wait, I see you posted it here. Hi Ivan, I created a pixi-playground at here for you: https://www.pixiplayground.com/#/edit/Y6TocuLkUOTfl7HrfcZFp ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted January 17, 2020 Share Posted January 17, 2020 Dear @Oliver Zhou ! What can I say? Welcome to the forums! I'm glad you tried that thing and get the result. I can help with small problems. OK, here it is: https://jsfiddle.net/Hackerham/0vftxLzn/17/ 1. There is a problem with precision - same uniforms used in vertex/fragment (inputSize, outputFrame) require same precision. If you use old devices that dont have highp - well, we can always stuff them in "dimensions" uniform like before to get rid of that. Honestly, its one of new problems that were spawned in v5. We try to fix old ones - get new ones However you either solved that on your own either you used legacy mode and "filterArea" uniform that comes with it, the real help follows: 2. To center coords by center of sprite - I removed "-=" from mapping , it doesnt work with screen pixels anymore, its filterArea pixels. 3. To get rid of bleeding problem you encountered - "filter.padding=1; filter.autoFit = false". And, like for any other v5 filters thread, I recommend to look at https://pixijs.io/examples/#/mesh-and-shaders/triangle-textured.js in case you need only one sprite affected and not whole container - UV manipulation is easier than those renderTexture inputs/outputs. We had a thread today where I posted the result for different shader, Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted January 17, 2020 Share Posted January 17, 2020 Oh, I see your playground. I don't know why didnt you encounter precision issue, its a miracle. Btw, one of other problems is that "precision" in second line (not first one) actually forces pixi to spawn one more "precision" before that and maybe it somehow works... Yes, just apply 2 and 3 to your playground and you'll get good result. Quote Link to comment Share on other sites More sharing options...
Oliver Zhou Posted January 17, 2020 Share Posted January 17, 2020 10 minutes ago, ivan.popelyshev said: Oh, I see your playground. I don't know why didnt you encounter precision issue, its a miracle. Btw, one of other problems is that "precision" in second line (not first one) actually forces pixi to spawn one more "precision" before that and maybe it somehow works... Yes, just apply 2 and 3 to your playground and you'll get good result. Thanks for you immediate help, Ivan. I see it finally works well?. I can understand 2, could you please elaborate 3 a little bit for me? I don't quite get it. Thanks in advance. 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.