MichaelZ Posted March 10, 2016 Share Posted March 10, 2016 Hello, I'm trying to implement a fading buffer to use for rendering particle "trails". The effect is pretty much what is described here. Specifically the fiddle there makes it clear quickly. The core idea behind the approach is: Allocate 2 buffers (renderTextures) Render particles to active texture For fading then: clear the alternative texture, render the primary texture to the secondary one with alpha (the fade), swap primary/alt textures. Render active renderTexture to screen (after everything else that goes under it) Loop back to 2 and repeat... I have this working pretty much, but I am fighting 2 things: performance + weird bug that occurs only on-device (iPad3/4 ios8/9). Due to this I wanted to get some feedback on my approach. I'd like to ask 2 things. First, in the setup above, there are 2 options I can image for swapping the textures: either swap the textures on the sprites objects... or swap the sprites associated with them. Since it would be annoying to add/remove the wrapper sprites on each "swap" I choose to instead simply swap the texture references on the sprites. Any red flags around this? Seems ok to me. The 2nd question... is my PIXI setup around the high-level approach correct (using 2 renderTextures and 2 wrapper Sprites)? And of course, if anyone can think of a more optimal approach I'm all ears. It seems no matter how you slice it the "fade" requires touching each pixel in the buffer and therefore will be an expensive operation. The totally different approach of storing the trail history and rendering it out per frame.... no. Sincerely, Michael Z. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 10, 2016 Share Posted March 10, 2016 Swapping textures of sprites is ok. I need exact code of how you rendering one renderTexture into another. Quote Link to comment Share on other sites More sharing options...
MichaelZ Posted March 10, 2016 Author Share Posted March 10, 2016 Sure, here is one of the bunny examples hacked with this approach (so you can copy-paste this into any of the examples): var renderer = PIXI.autoDetectRenderer(800, 600,{backgroundColor : 0x1099bb}); document.body.appendChild(renderer.view); var currentTextureIsA; var renderTextureA; var renderTextureB; var displaySprite; var bufferSprite; // create the root of the scene graph var stage = new PIXI.Container(); // create a texture from an image path var texture = PIXI.Texture.fromImage('_assets/basics/bunny.png'); // create a new Sprite using the texture var bunny = new PIXI.Sprite(texture); // center the sprite's anchor point bunny.anchor.x = 0.5; bunny.anchor.y = 0.5; // move the sprite to the center of the screen bunny.position.x = 200; bunny.position.y = 150; //stage.addChild(bunny); currentTextureIsA = true; renderTextureA = new PIXI.RenderTexture(renderer, 800, 600); renderTextureB = new PIXI.RenderTexture(renderer, 800, 600); displaySprite = new PIXI.Sprite(renderTextureA); displaySprite.alpha = 1.0; bufferSprite = new PIXI.Sprite(renderTextureB); bufferSprite.alpha = 0.9; stage.addChild(displaySprite); // Needed because otherwise our bunny doesn't move... ??? var dummyContainerForBunny = new PIXI.Container(); dummyContainerForBunny.addChild(bunny); // Needed because otherwise the alpha is not honored when rendering to texture... ??? var dummyContainerForBuffer = new PIXI.Container(); dummyContainerForBuffer.addChild(bufferSprite); // start animating animate(); function animate() { requestAnimationFrame(animate); // just for fun, let's rotate mr rabbit a little bunny.position.x = (bunny.position.x + 1); bunny.position.y = (bunny.position.y + 1); renderTextureA.render(dummyContainerForBunny); var otherTexture = (currentTextureIsA === true) ? renderTextureB : renderTextureA; // Clear it to start fresh otherTexture.clear(); // Render our current sprite into our fresh texture, but with some alpha (fade) bufferSprite.texture = (currentTextureIsA === true) ? renderTextureA : renderTextureB; otherTexture.render(dummyContainerForBuffer); displaySprite.texture = otherTexture; // Other texture with fade now becomes our main texture with this flip! currentTextureIsA = !currentTextureIsA; // render the container renderer.render(stage); } Side-note: any easy way I can get this to run on an iPad (my own code in the samples)? I'm trying to reproduce a device-only bug with a minimal example (and think this should be it). Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 10, 2016 Share Posted March 10, 2016 Ok, I dont think its possible to speed up the rendering here Quote Link to comment Share on other sites More sharing options...
MichaelZ Posted March 11, 2016 Author Share Posted March 11, 2016 Ended up adding a scale factor to my trails buffer size since my trails don't need to be high res (and are small). The hope here was to optimize step 3 due to the smaller buffer size. The performance results on iPad4 were marginally better. This probably makes sense as there are also steps 2 and 4 which don't really get much better with the smaller buffer size. More importantly though this allowed me to get the buffer size under 2048 on iPad and this magically makes a very strange critical bug go away. Using a ratio of 0.5 and my buffer is roughly screen size. Thanks for the quick sanity checks! Quote Link to comment Share on other sites More sharing options...
Exca Posted March 11, 2016 Share Posted March 11, 2016 If you only need trailing then one option would be to say rendereroptions.clearBeforeRender = false; Then just draw some fullscreen 1px sprite with alpha and you have trailing rendering done without bufferswapping. If you want to render anything else without trails then this option is not going to work. 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.