sanojian Posted August 5, 2015 Share Posted August 5, 2015 Am I doing something wrong? I am trying to draw "pixels" onto a small graphics object every frame. Even with a very small number of pixels (169), it is slowing down to a crawl after a few seconds and leaking memory like crazy. Here is a JSFiddle Here is the code:function init(){ var width = 100; var height = 100; var canvas = document.getElementById("view"); var stage = new PIXI.Stage(0x000000); var renderer = new PIXI.autoDetectRenderer(width, height, canvas, null, true); var colors = [0x00FFFF, 0xFF0000, 0x00FF00, 0x0000FF]; var colorIndex = 0; var graphics = new PIXI.Graphics(); stage.addChild(graphics); renderer.render(stage); var PIXEL_SIZE = 8; function update() { for (var y=0; y<height/PIXEL_SIZE; y++) { for (var x=0; x<width/PIXEL_SIZE; x++) { colorIndex += 1; if (colorIndex >= colors.length) colorIndex = 0; graphics.beginFill(colors[colorIndex]); graphics.drawRect(x*PIXEL_SIZE, y*PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE); } } renderer.render(stage); stats.end(); requestAnimationFrame(update); } requestAnimationFrame(update);} Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 5, 2015 Author Share Posted August 5, 2015 I see my problem, but it raises a new one. I was not calling graphics.clear() at the beginning of update() so it is leaking all of the graphics data on every render. So now my problem is, how to redraw Graphics without generating a new GraphicsData array since my geometry never changes? Quote Link to comment Share on other sites More sharing options...
bubamara Posted August 5, 2015 Share Posted August 5, 2015 I would try to generateTexture() from it and then use it as texture for my tiling sprite Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 5, 2015 Author Share Posted August 5, 2015 Thanks for the suggestion. But then how do I update the texture every frame? Do I draw to the canvas using the standard HTML5 API? I am trying to avoid using the standard canvas drawing API by using Pixi Quote Link to comment Share on other sites More sharing options...
bubamara Posted August 5, 2015 Share Posted August 5, 2015 If you want to achieve effect like the one you showed at jsfiddle, then you don't need to update texture every frame.Before main loop create texture, apply it to tiling sprite and then in render loop just move myTilingSprite.tilePosition.x Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 5, 2015 Author Share Posted August 5, 2015 The jsfiddle was just an example of the problem I saw. What I am trying to accomplish is to update the lava example in my cellauto.js project to use WebGL so I can increase the resolution and the frame rate. Drawing thousands of rectangles per frame is too slow using Canvas. Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 5, 2015 Author Share Posted August 5, 2015 I sort of hacked it by doing the following: I draw the graphic like you see in the original update() function and then I just update the graphicsData array on every frame.function update() { for (var y=0; y<height/PIXEL_SIZE; y++) { for (var x=0; x<width/PIXEL_SIZE; x++) { colorIndex += 1; if (colorIndex >= colors.length) colorIndex = 0; graphics.graphicsData[x + y*width/PIXEL_SIZE].fillColor = colors[colorIndex]; graphics.dirty = true; graphics.clearDirty = true; } } renderer.render(stage); requestAnimationFrame(update);}Those two dirty flags were what was tripping me up. They are necessary or the graphic will not re-render. Now it is much faster, but not the magic bullet I was hoping for. I still can't get better than about 20 fps when rendering about 55000 rectangles. I think I have much more to learn about WebGL to get this optimized. Or is this the best I could realistically hope for? Quote Link to comment Share on other sites More sharing options...
xerver Posted August 5, 2015 Share Posted August 5, 2015 If you are doing pixel manipulation, and you want to use webgl, then just write a shader for it. Now it is much faster, but not the magic bullet I was hoping for. I still can't get better than about 20 fps when rendering about 55000 rectangles. I think I have much more to learn about WebGL to get this optimized. Or is this the best I could realistically hope for? I'd say 55k different geometries all dynamically updating on the CPU each frame, drawing at 20fps, in a browser, is pretty baller. If you are drawing pixels with graphics that just seems wrong. Pixel manipulation should be done in a fragment shader. If you can't use a shader and only webgl, then you can generate a texture for each array of colors you have and then just swap between them. Even better would be to draw each of those textures to a single canvas object, use the canvas in a base texture, then define textures with frames for each of the color arrays (all sharing that base texture), then just swap textures each frame (or whenever). I don't think drawing graphics and live updating it is the best way to do this. Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 6, 2015 Author Share Posted August 6, 2015 just write a shader for it. define textures with frames for each of the color arrays (all sharing that base texture) Nice suggestions, I will have to learn how to do these things first and then compare them. If any are interested, here is a jsFiddle with the solution I described above. It starts to drop below 60fps once you get up to about 10,000 rectangles. Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 6, 2015 Author Share Posted August 6, 2015 If you can't use a shader and only webgl, then you can generate a texture for each array of colors you have and then just swap between them. Even better would be to draw each of those textures to a single canvas object, use the canvas in a base texture, then define textures with frames for each of the color arrays (all sharing that base texture), then just swap textures each frame (or whenever). I don't think drawing graphics and live updating it is the best way to do this. I tried the first part of this approach and it was much slower. Here is a jsFiddle. Maybe I am doing it wrong? I really don't know how to ensure everything is done in the GPU. I am a total newbie to WebGL. Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 6, 2015 Author Share Posted August 6, 2015 Tried the second part of your suggestion, generating a base texture and using frames. BINGO!!!!! 60fps with 70,000 rectangles! jsFiddle Thanks so much for the awesome advice! Some day I will learn to use shaders and compare that as well. Quote Link to comment Share on other sites More sharing options...
xerver Posted August 6, 2015 Share Posted August 6, 2015 You might also want to investigate TIlingSprite since it seems like you generate so many because you are tiling it. TilingSprite supports texture atlases as well so your code would be basically the same but instead of many sprites you would just use one TilingSprite. Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 7, 2015 Author Share Posted August 7, 2015 You might also want to investigate TIlingSprite since it seems like you generate so many because you are tiling it. TilingSprite supports texture atlases as well so your code would be basically the same but instead of many sprites you would just use one TilingSprite. I need to change textures on individual tiles, though. It is my understanding that TilingSprite does not allow this. Quote Link to comment Share on other sites More sharing options...
xerver Posted August 7, 2015 Share Posted August 7, 2015 I need to change textures on individual tiles, though. It is my understanding that TilingSprite does not allow this. Ah yes, sorry I assumed from the fiddle that they were all the same! Good luck! Quote Link to comment Share on other sites More sharing options...
sanojian Posted August 7, 2015 Author Share Posted August 7, 2015 I am sure that more optimization is possible but I'm quite happy with this solution in Pixi.js for now. If you want to see it live, go to the http://sanojian.github.io/cellauto/ project. This is the lava demo. Thanks so much for your help! Quote Link to comment Share on other sites More sharing options...
xerver Posted August 7, 2015 Share Posted August 7, 2015 Very cool man, looks awesome. Glad you got it working! 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.