ofVboMesh outperformed significantly by three.js

Hi lovely OF people,
This is getting quite frustrating.
I cant get ofVboMesh to perform as well as three.js mesh rendering.
I’m not sure about what’s going on behind the scenes in three.js but it is able to render faster and with way more vertices than OF before droppping the fps below 60.
Here is a test example for OF:


and here “the same” for three.js:

any idea on what might be going on? Am I doing something wrong?
The idea behind this
For a project that I already coded using OF, there’s a part in which I need to draw a terrain height map.
Everything runs fine except for the terrain rendering, that needs to be optimized.
After some research I decided to go for a Level Of Detail rendering.
I found out the following, that happens to work really well on three.js and suits my needs.


So I decided to port it to OF, which I guessed that would be straightforwards, but it has become a several days nightmare. [add frustration, despair and anger emoticon here.]
In essence the idea is to create a grid that decreases in resolution as it moves away from its center. All the rest goes on inside a shader. The problem is that I can’t even render the mesh, with no shader anywhere close to three.js in terms of resolution and fps.
Any idea on what might be going on? How to fix/improve? @arturo @tgfrerer?

Here’s an oF app that draws the LevelOfDetail mesh.


and here’s the three.js version that draws the same. Not sure if the internals are the same because the performaces is significantly better with three.js

So far I’ve tried using ofxScene (which is a scene graph implementation based on three.js), instanced rendering, and several other methods. None provides any performance boost.
Already read and tried this: Instanced Rendering with an array of ofMatrix4x4

additionally, I need to render as wireframe, which also drops the fps a lot.

I’m running this on a MacBookPro Retina 2014 2,5GHz i7, 16GBRam, NVIDIA GeForce GT 750M 2048 MB, mavericks 10.9.5

What’s going on behind the hoods in OF? is it a bug? How can it be that something that runs inside a browser runs better that a native app.

I will really appreciate any advice, guidance or kind words :smile:

Best!

1 Like

the title of the window is not thougth to be changed 60 times per second. setWindowTitle can be really slow try using bitmap string. otherwise everything in that example is mostly gpu bound so it shouldn’t be much difference which language you are using. using a scene graph won’t make drawing 1 vbo faster either

Yikes! Have you tried using the programmable renderer in oF?

hey roy, let’s assume you’re using the programmable renderer.

And forgive me when i make an educated guess here, i’m not at my regular machines, and don’t have easy access to oF source.

When you define a mesh as triangles, and then draw it as wireframe, internally, the mesh has to be re-calculated, because it will be optimised for triangle winding. In this case, on each draw call, the mesh vbo has to be re-calculated before submission to GL, and a new temporary vbo (and vao) will be issued. You could confirm this hypothesis by comparing the render speed of when you call a regular .draw instead of .drawWireframe

OpenGL (and ofVbo) itself has no internal method to draw wireframes from triangle meshes. So a temporary mesh has to be created where the mesh is broken up in lines, and submitted by the renderer, every frame. That’s bound to be slow. Also the draw methods for lines, as you mention, are comparatively slow.

It’s possible that three.js caches the lines vbo internally, and i could look into this and see if it would make sense for oF too, tomorrow morning London time.

Before I go to sleep, how about you try this - draw the vbo directly using GL_LINES by calling:

mesh.getVbo().draw(GL_LINES, 0, mVboBox.getVertices().size());

This should draw straight from your actual vbo, and bypass the programmable renderer trying to guess what to do with the mesh.

HI Arturo,
thanks for answering.
Unfortunately not using the window title to draw the fps and instead using a bitmap string doesn’t improve the performance.

best

@pants yes. No improvement.

Hi @tgfrerer.
Thanks for answering back.
The thing about drawing lines you mention makes a lot of sense.
None the less, three.js is also drawing lines, somehow, and performing much better.
I have also gone through the source of three.js but the typeless thing of javascript and it’s memory managment cofuse me.
Please let me know if you’ve found anything.
I’ll check your suggestion plus building the mesh optimized for line drawing.

Best =)

I don’t have much to add other than a link to this conversation Testing performance comparisons between OF and Three.js and perhaps @brannondorsey may have some additional insights?

hi @roymacdonald

really intersting to hear that people are getting better performance in three.js than oF
(although I never was about to match VVVV performance in oF either)
It definitely hints towards some of the more managed rendering situations that were being discussed in the dev list!

did you try @tgfrerer’s suggestion of seeing the performance of dropping in

mesh.getVbo().draw(GL_LINES, 0, mVboBox.getVertices().size());

instead of your existing draw call?

this wouldn’t give you the desired result, but if it was much faster then it would reveal where the slow-down was happening.

good luck!

Elliot

Hey,

I’m interested in this comparison as well. Maybe threejs automatically converts line geometry to triangles when using a ShaderMaterial?

I’ve used a geometry shader to do wireframe rendering with no fps drop (for OF/regular opengl). Works great for large number of vertices. Here’s an example- https://github.com/trentbrooks/WireframeShader

Also @davetowey recently did a OF workshop (Sydney) where he discussed using the new ‘tesselation shader’ (opengl 4) for adjusting LOD of terrrains. Here’s the example he posted- https://github.com/davetowey/ofxTessellationShader

I think I’ve managed to get OF to work fine!
@tgfrerer had the clue.
I can render several million vertices without fps dropping.
The problem was that I was using the ofPlanePrimitive to create the initial plane, which is either OF_PRIMITIVE_TRIANGLES or OF_PRIMITIVE_TRIANGLE_STRIP.
By manually creating a plane mesh that it’s mode is OF_PRIMITIVE_LINE_STRIP and setting the indices correctly the LOD mesh now runs super fast, actually much faster than what three.js provides (yet I guess that it is limited to vsync).

My guess is that three.js converts the geometry from triangles to lines, as @trentbrooks suggests.
Maybe something similar could be useful in OF.

@trentbrooks I’ll check out those links. Thanks.

I’ll create an addon out of all this once finished with my project. I’ll let you know once done.

Many thanks to you all. Trully.
This is what makes this community so awesome.

All the best!

5 Likes

Hey @elliotwoods,
I’m just curious about why vvvv performs better than OF. I would have thought it was the other way round.
What’s vvvv doing to perform better?

Best!