M3nace Posted October 31, 2014 Share Posted October 31, 2014 Hello , Actually, I'm trying to develop a parallel coordinates graphe using a WebGL rendering. Like http://bl.ocks.org/syntagmatic/raw/5023284/ but with Pixi.js, since webgl-2D is not maintened anymore. Except I don't have the same amount of data. I have more, a hell more, 100 000 lines minimum . I already read some topics here and on Github, where recommandations are to use Sprite instead of Graphics. But the performance are worse . Switching to canvas ? The render is as smooth as a baby butt. The WebGL rendering of 100 000 lines uses 1,50Go of GPU RAM, which seems to be a lil' too much. Here some code and explanations: var rtContainer = new PIXI.DisplayObjectContainer();var stageFG = new PIXI.Stage(null, true);var renderFG = new PIXI.autoDetectRenderer(foreground.width, foreground.height, { view:foreground, transparent:true, antialias:true, clearBeforeRender:false, preserveDrawingBuffer:true });stageFG.addChild(rtContainer);draw();Here my context. foreground is just a <canvas> element and rtContainer will only contains new graphics to display in the stage. The function draw() will begin to render the stage when data are received.var render_loop = 0;function draw() { var requestAnimationId = requestAnimationFrame(draw); renderFG.render(stageFG); render_loop += rtContainer.children.length; rtContainer.removeChildren(); if (render_loop == data_length) { cancelAnimationFrame(requestAnimationId); }}; Function draw(), rendering the stage and deleting the graphics which have just been drawed. data_length is the number of data I will receive, which means I draw(), not until I received everything, but only when I rendered everything.var update_loop = 0;this.update = function(new_data) { path(new_data, rtContainer, color(new_data.classification)); ++update_loop;};I receive data asynchronously, with server-side events, triggering the update function.The new_data is a dictionary. I use the key classification for ordering. The function path() create the line under a graphic object: function path(d, ctx, color, lineWidth) { var graphics = new PIXI.Graphics(); var lineWidth = lineWidth || 1; graphics.lineStyle(lineWidth, color.replace('#', '0x'), opacity); var x = xscale(dimensions[0]) - 15, y = yscale[dimensions[0]](d[dimensions[0]]); // left edge graphics.moveTo(x, y); dimensions.map(function(p) { x = xscale(p), y = yscale[p](d[p]); graphics.lineTo(x, y); }); graphics.lineTo(x + 15, y); // right edge ctx.addChild(graphics); delete graphics;};Pretty much the same function of the example. d is the data, ctx the rtContainer. My graphics is a line, with multiple points, and different colors. So each lines are differents. And voila. Little benchmark :Canvas rendering 120 000 lines : ~20sec, very smooth. Memory is happy.WebGL rendering 120 000 lines : ~20sec, not so smooth, depends a lot of the number of lines. Huge amount of memory used.I tried to use generateTexture() in the path() and use a SpriteBatch, but my comp crashed around 1000 lines... Not a good idea obviously. My questions are :- Do I use Pixi.js correctly ?- Is there a way to improve performance of WebGL ? Any idea ?- Is it normal to use this quantity of memory when using WebGL ? If you need more code or more explanations, I can provide it (although, I'm not english, I apologise for any tears, vomiting, eye-gouging caused by my prose) Quote Link to comment Share on other sites More sharing options...
agamemnus Posted November 1, 2014 Share Posted November 1, 2014 Really hard to say. I need to fix my memory use too. It is just a jigsaw game but a lot of phones explode... uses over 500mb of texture memory I guess... One idea is to use filters or shaders instead of textures for different colors. It might seem wasteful but it is the way to go in opengl/webgl land. Quote Link to comment Share on other sites More sharing options...
DavidBM Posted November 2, 2014 Share Posted November 2, 2014 Maybe this link can help you: http://www.html5gamedevs.com/topic/776-pixijs-now-draws-primitives-webgl-and-canvas/ Pixi computes polygons from lines to have nice corners. Draw lines in webgl (openGL ES) in windows are not trivial. In my post I have similar problems: http://www.html5gamedevs.com/topic/10124-mmo-strategy-game-drawing-graph-map/ Quote Link to comment Share on other sites More sharing options...
M3nace Posted November 3, 2014 Author Share Posted November 3, 2014 Thanks for the reply =) Found this one : http://www.html5gamedevs.com/topic/9395-can-i-haz-gllines-and-glline-strip/ on the forum. Not a bad idea. Delete the computation of the polygon to speed up the render. Quote Link to comment Share on other sites More sharing options...
M3nace Posted November 4, 2014 Author Share Posted November 4, 2014 Small feedback.The render is speeded up, but the memory allocation is still the same.PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData){ // TODO OPTIMISE! var i = 0; var points = graphicsData.points; if (points.length === 0) return; // if the line width is an odd number add 0.5 to align to a whole pixel if (graphicsData.lineWidth % 2) { for (i = 0; i < points.length; i++) { points[i] += 0.5; } } var verts = webGLData.points; var indices = webGLData.indices; var length = points.length / 2; var indexCount = points.length; var indexStart = verts.length / 6; // sort color var color = PIXI.hex2rgb(graphicsData.lineColor); var alpha = graphicsData.lineAlpha; var r = color[0] * alpha; var g = color[1] * alpha; var b = color[2] * alpha; var p1x, p1y, p2x, p2y; for (i = 1; i < length - 1; i++) { p1x = points[(i - 1) * 2]; p1y = points[(i - 1) * 2 + 1]; p2x = points[i * 2]; p2y = points[i * 2 + 1]; verts.push(p1x , p1y); verts.push(r, g, b, alpha); verts.push(p2x, p2y); verts.push(r, g, b, alpha); } indices.push(indexStart); for (i = 0; i < indexCount - 4; i++) { indices.push(indexStart++); } indices.push(indexStart - 1);};PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession){ ... else { webGLData = webGL.data[i]; renderSession.shaderManager.setShader( shader );//activatePrimitiveShader(); shader = renderSession.shaderManager.primitiveShader; gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); gl.uniform2f(shader.projectionVector, projection.x, -projection.y); gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); gl.uniform1f(shader.alpha, graphics.worldAlpha); gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); // set the index buffer! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); gl.drawElements(gl.LINE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); } ...}; DavidBM 1 Quote Link to comment Share on other sites More sharing options...
DavidBM Posted November 4, 2014 Share Posted November 4, 2014 Umm, I tried your code and with one Graphics object with 2.000 points only got 15 FPS. Javascript only takes 0.1ms to draw the object, but seem that the graphic card can't draw 2000 vertexs. May need a special shader?. ¿What are you performance? pd: With my intel 4600 -> 1 graphic object with 2.000 lines -> 15FPS. With my nvidia 650 -> 1 graphic object with 20.000 lines 55FPS Quote Link to comment Share on other sites More sharing options...
M3nace Posted November 4, 2014 Author Share Posted November 4, 2014 I don't mesure it with FPS, since I just want a smooth render in real time. Althouth, I just want to draw line on a canvas, I think to implement it without library : http://www.codeproject.com/Articles/594222/LineplusinplusWebGLplusandpluswhyplusyouplusgonnap Thanks for your reply and your feedback Quote Link to comment Share on other sites More sharing options...
DavidBM Posted November 4, 2014 Share Posted November 4, 2014 pd: What project are you doing? Quote Link to comment Share on other sites More sharing options...
M3nace Posted November 5, 2014 Author Share Posted November 5, 2014 Nothing in particular, tryin' to fix the performance issue in this case. Quote Link to comment Share on other sites More sharing options...
DavidBM Posted November 6, 2014 Share Posted November 6, 2014 I have wrote a little library that extend the pixi's Graphics object.If you make '1px' line, it uses GL_LINES.If you make '>1px' line, it uses the pixi algorithm.https://github.com/DavidBM/pixi-nativeGLlineI tried to use GL_LINES instead of GL_LINE_STRIP, because GL_LINE_STRIP can't paint separate lines. The problem is that now you need to add 3 points per line, when the correct would be 2 points. I don't know why. Anyway, I'll keep updating it and improving it. M3nace 1 Quote Link to comment Share on other sites More sharing options...
DavidBM Posted November 6, 2014 Share Posted November 6, 2014 Bug fixed. Now you can draw lines with 2 points. M3nace 1 Quote Link to comment Share on other sites More sharing options...
M3nace Posted November 7, 2014 Author Share Posted November 7, 2014 Woohoo \o/Solved the memory rape. My bad, create a new Graphics object in the function path() was NOT a good idea. New code :function draw() { var requestAnimationId = requestAnimationFrame(draw); renderFG.render(stageFG); render_loop += rtContainer.children.length; if (render_loop == data_length) { cancelAnimationFrame(requestAnimationId); }};var graphics = new PIXI.Graphics();function path(d, ctx, color, lineWidth) { var lineWidth = lineWidth || 1; graphics.lineStyle(lineWidth, color.replace('#', '0x'), opacity); var x = xscale(dimensions[0]) - 15, y = yscale[dimensions[0]](d[dimensions[0]]); // left edge graphics.moveTo(x, y); dimensions.map(function(p) { x = xscale(p), y = yscale[p](d[p]); graphics.lineTo(x, y); }); graphics.lineTo(x + 15, y); // right edge ctx.addChild(graphics);};Don't need to clear the graphics, dunno why... And if i clear it, my whole scene goes blank.With your library, benchmark:120k line in 16s, as smooth as canvas, GPU memory doesn't flinch. Thanks a lot for your help David DavidBM 1 Quote Link to comment Share on other sites More sharing options...
DavidBM Posted November 7, 2014 Share Posted November 7, 2014 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.