jeroen Posted June 7, 2017 Share Posted June 7, 2017 Hi, I'm trying to start sort of a drawing app where you can draw lines and show an image through those lines. Problem is, it is incredibly slow... So I have an "imageToReveal" sprite and mask it with the drawn lines. Now this does work in my project, but I cannot get it to work in JSFiddle. check it out here This should render the drawn shapes to a texture and set to texture to Sprite that's masking the image to reveal I don't know if this is the best way, but the simple way with a masked sprite and shapes as children didn't go well either: see this one So my question is, how do I make the first JSFiddle work? (and is it the best way) And if it is, how can I make it faster? since it drops from 60 to 40 after a single shape is put on stage. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 7, 2017 Share Posted June 7, 2017 you need only one renderTexture of the size of screen, filled with black. Add the sprite with blendMode=MULTIPLY. Now , every mousedown you have to render one more white dot there. only one dot, don't accumulate them, you dont need ParticleContainer. That's the same as masking, actually Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 8, 2017 Author Share Posted June 8, 2017 I got it to work with the mulitply blendmode! Although for some reason this JSFiddle doesn't show the renderTextureSprite, it does work on my end. Thank you! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 8, 2017 Share Posted June 8, 2017 "app.render" accepts only stage, it has no other params, "app.renderer.render" is what you need. Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 8, 2017 Author Share Posted June 8, 2017 Got it, working now Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 10, 2017 Author Share Posted June 10, 2017 Update! So I have this nice image appearing when the dots are drawn, but now I want a background layer behind it that is always showing. So you would sorta draw a new layer on top of it. I can't get my around it how to do that. With the multiply blendmode everything hidden needs to have black over it, but that means I can not put anything behind it. Is masking a better option again? or is there a filter where I can only let full alpha through, so I can have a transparent blended image. Hope I'm making sense Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 12, 2017 Share Posted June 12, 2017 You canput old stuff in separate container and assign VoidFilter to it - it will render that container into separate frameBuffer. If you put stuff before that container, whole container will be on top of it. That's how masking works - separate layer + MULTIPLY blendmode inside. var globalVoidFilter = new PIXI.filters.VoidFilter(); container.filters = [globalVoidFilter]; Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 12, 2017 Author Share Posted June 12, 2017 Thanks again Ivan, I applied the VoidFilter and put a red rectangle in the background which would need to appear behind the drawn layer. But I'm not sure how to get it to imitate a mask now. I still have this black color which needs to be transparent, see here How do I achieve that? Also, would this still be faster than regular masking? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 12, 2017 Share Posted June 12, 2017 I dont understand how do you want to do it without alpha. I thought red rectangle should appear in transparent parts of original image, but it doesnt have transparent parts. Please clarify where do you want to see that red rectangle Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 12, 2017 Author Share Posted June 12, 2017 Sorry if it was unclear, I updated the JSFiddle with a grassy background. So this one should be visible at first, and when you click the masked image on top should show up. Like this: ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 12, 2017 Share Posted June 12, 2017 Oh, shit. Yeah, now I realize that for that case MULTIPLY !== mask. We have to think. OK, that will work: https://jsfiddle.net/me2rqnd4/6/ That's my change: //renderTextureSprite.blendMode = PIXI.BLEND_MODES.MULTIPLY; container.mask = renderTextureSprite; Also i removed VoidFilter, we dont need it. I will try to improvise with BlendModes later, find something that'll work instead of multiply UPD. Yeah, we have to put that drawing demo into pixi examples!! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 12, 2017 Share Posted June 12, 2017 And that's our new demo: http://pixijs.github.io/examples/?v=v4.5.3#/demos/mask-render-texture.js Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 12, 2017 Author Share Posted June 12, 2017 Haha great! I'm happy it got made into an example, and this also gives me way better code to work off. Thank you! PS: I should say the performance is not optimal for mobile, it's about 35 fps when drawing on my iPhone 5 (but it's manageable for a drawing app) Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 12, 2017 Share Posted June 12, 2017 I think it can be done better with special blendMode, i'll try it later Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 13, 2017 Author Share Posted June 13, 2017 Looking forward to it! Didn't Matt also work on a drawing app? Maybe he's done something similar. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 13, 2017 Share Posted June 13, 2017 Well, if you are going for speed, this one has less operations, and mask is applied only when something is being drawn. But there can be artifacts on the edge of circle if its anti-aliased. // for this example you have to use mouse or touchscreen var app = new PIXI.Application(800, 600); document.body.appendChild(app.view); var stage = app.stage; //prepare circle texture, that will be our brush var brush = new PIXI.Graphics(); brush.beginFill(0xffffff); brush.drawCircle(0, 0, 50); brush.endFill(); PIXI.loader.add("t1", "required/assets/bkg-grass.jpg") PIXI.loader.add("t2", "required/assets/BGrotate.jpg") PIXI.loader.load(setup); function setup(loader, resources) { var background = new PIXI.Sprite(resources["t1"].texture); stage.addChild(background); background.width = app.screen.width; background.height = app.screen.height; var imageToReveal = new PIXI.Sprite(resources["t2"].texture); imageToReveal.width = app.screen.width; imageToReveal.height = app.screen.height; imageToReveal.mask = brush; var imageMasked = new PIXI.Container(); imageMasked.addChild(imageToReveal); imageMasked.addChild(brush); var renderTexture = PIXI.RenderTexture.create(app.screen.width, app.screen.height); app.renderer.render(background, renderTexture, false); stage.addChild(new PIXI.Sprite(renderTexture)); app.stage.interactive = true; app.stage.on('pointerdown', pointerDown); app.stage.on('pointerup', pointerUp); app.stage.on('pointermove', pointerMove); var dragging = false; function pointerMove(event) { if (dragging) { brush.position.copy(event.data.global); app.renderer.render(imageMasked, renderTexture, false); } } function pointerDown(event) { dragging = true; pointerMove(event); } function pointerUp(event) { dragging = false; } } Quote Link to comment Share on other sites More sharing options...
jeroen Posted June 14, 2017 Author Share Posted June 14, 2017 Thanks! That's a whole lot better, around 50fps now:) ivan.popelyshev 1 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.