Tuesday, July 1, 2014

WebGL and Performance 1 - Intro

I am not a web developer, and though I have a passing familiarity (a.k.a., distant experience) with Javascript, the last useful thing I probably wrote with a scripting language was VB Scripts for the Windows shell.

Nevertheless, I am experienced with OpenGL, and excited that it is now available inside most browsers.

I digress...but for good reason


As a bit of a historical aside, I have been building a video game in my spare time as a sort of hobby.  I started in Java, using JOGL as an interface library to OpenGL.  After much tweaking and optimizing of the rendering pipeline, and having read too many highly opinionated posts about whether JOGL (used largely by Aerospace and modeling apps) or LWJGL (used more by games such as Minecraft) was better, I decided to do a port from the former to the latter and compare results.

I ended up staying with LWJGL as I like the API better, but the results matched my intuition: the performance was identical, and any declaration that one API is "better" is largely a matter of personal preference (notwithstanding JOGL's ability to use multiple windows, which LWJGL has historically lacked).

Not much later I ran across some libraries such as GLFW which, to my great surprise and excitement, make it much easier to write cross-platform OpenGL-centric apps in C++ than it used to be.  A few quick experiments later and I ported the entire mess to C++ and haven't looked back, C++ being by far my favorite language and C++ 11 a very real love of mine.

Again, matching my intuition, the frame-rate on all of my tests matched what I got from the Java builds.  The [not yet optimized for C++] code for non-GL things, such as world creation, physics and meshing all  ran about one order of magnitude faster, and will probably pick up another order with some optimization.

The moral of the story was simple: since OpenGL 2.0, it is possible to put nearly all assets into the GPU and then use them with a fairly small number of API calls to render your scenes.  Had I been using OpenGL 1.0, I would expect Java to be far slower because each API call has to cross the JNI interface and perform additional marshalling that isn't necessary in C++.

Consequently, the switch to the UHD monitors I spoke about in the last post was a great help in testing my game engine.  Whereas at HD resolution, my GPU was always geometry or texture bound, but with all extra screen realestate I can scale up the game window until I am fill-rate bound, which helps me simulate different types of bottlenecks.

And now onto WebGL

I really wanted to port the engine to WebGL and see what sort of performance I could get there as well. However, it is a big project, and my Javascript skills are much rustier than the others.

Then, the other day at work I discovered one of our teams is working on a web UI centered around the familiar "circles on springs" visual effect, and I decided to use something similar to that for this experiment.  Although this isn't as technically interesting as a full 3D world, my goal is to experiment with optimizations and see if I can get anywhere near the same performance out of a well written WebGL app as I could a native one.  For that use, this will make a perfect study because:
  1. I have many projects laying around with such code in them (in other languages, but I can pirate)
  2. It is simpler to both build and understand
  3. It will be simple for me to make a comparable C++ version

So this is what I'm going to do

I will build a simple UI consisting of  "circles on springs" that can be moved and will interact physically.

I will start with the most obvious (and simple) implementation, and then iteratively improve the design by applying various optimizations.

I will test the usability and performance at each stage in three browsers: Chrome, FireFox and Opera.

I will write a parallel C++ app against which to benchmark performance; the goal will be for the web app to approach the frame rate of the native one, testing the hypothesis that where OpenGL rendering is concerned, it is more important how you write your app than it is where you write it.

I will use no complex 3rd party scripts (such as three.js), as I want to understand performance without having to read a lot of someone else's code.  I may include trivial scripts like gl-matrix.js or other things one can understand at a glance.

This should be fun, as I have no idea how it will work out.  At the end of each post I will lay out what I think should be looked at or changed next, and try to make some sort of prediction as to how effective it will be.  Then, with the next post we will see what the actual result was.

Stay tuned; the first installment will not be far off.

No comments:

Post a Comment