Saturday, April 18, 2009

Aeon render module progress (Display List vs. VAO vs. VBO)

It has been quite a while since my last progress report. I have been busy designing, implementing and testing the render module of our graphics engine, Aeon. In this report, I will describe what I have found about several advanced rendering techniques that will be applied to the Aeon render module.

First, the most efficient display lists. Display list is rather an old rendering technique. It is most efficient for rendering pure static objects. It is simply a pre-compiled immediate mode rendering. The obvious disadvantage is that you cannot modify the content once it is compiled and sent to the rendering server. However, it is the most efficient way of rendering static objects. Aeon render module detects the render mode of objects based on developer set hint flags. And if the flag is set to pure static, then the object will be rendered using display list for best raw performance.

Second, VAOs or vertex array objects. VAO is derived from VAR or vertex arrays. Since OpenGL 1.4, buffer objects have been implemented to better support client/server model for use of vertex arrays. VAOs are not as efficient as display lists, however, they do provide the functionality to support dynamic objects whose data content changes over time. VAOs is implemented on top of VARs with buffer objects on the rendering server end. The data content of an object is stored locally in the client memory space and sent to rendering server every time the object is drawn via glXXXPointer(..., dataBuffer/pointer). VAOs are very good for a local rendering system, like a typical game engine where the client and server are on the same machine (Game application as client, graphics card as server). The transfer cost from system memory to VRAM is considered relatively cheap. However, it is not very efficient for distributed rendering where the client and server are located on different physical machines. Since each render call requires the data content to be sent from the client to the server, this implies that the data content needs to be transfered via network for every render invocation, which could easily use up the transfer bandwidth. And the latency of transferring the data content over the network can also hinder performance. Also, if only a small portion of object data changes, VAOs still require all data contents to be transfered including the static portion. This obviously wastes sources and can hinder performance.

Lastly, VBOs or vertex buffer objects. VBOs are very similar to VAOs. The power of VBOs comes from its flexible implementation. Compare to VAOs, VBOs do not require data content to be sent to server for every single render invocation if the data does not change. In fact, for pure or partial static objects, the static portion of an object can be buffered once and referenced using an name ID later on. This allows data to be only transfered to the server when needed, which in turn reduces transfer latency and improves application performance. However, due to the fact that VBOs require more bookkeeping than VAOs (binding buffers via glBindBufferARB(...) calls), it is not as efficient as VAOs if all the data requires to be transfered for every single frame. This implies that for true dynamic objects or even some highly dynamic objects that change multiple times every frame or at lease once every frame, VAOs may be a better choice over VBOs. The true power of VBOs comes into play when rendering objects that change relatively infrequently. In real world game applications, this is usually the case. For instance, an skeletal animated character usually changes its vertex data 24 or 30 frames per second. If the rendering frame rate is higher than this (Typically 60 frames per second with vertical synchronization), the data only needs to be transfered every 2 or 3 frames. By reducing the number of data transfers, VBOs can significantly improve the application performance. Also a big portion of animated character data usually does not change at all. Typically, only the vertex position and normal data need to be transfered when using VBOs, where as VAOs require all data to be transfered every frame.

Aeon render module will support all three rendering methods and apply them as it sees fit based on developer given hint flags. The following is a summary list of what each method is best suited for.

Display Lists: Best for pure static objects that do not change at all. Such as static rocks in the scene.
VAOs (Vertex Array Objects): Best for high resolution dynamic models with update rates significantly higher than the actual rendering frame rate and all or most data contents change frequently.
VBOs (Vertex Buffer Objects): Best for standard resolution dynamic models with update rates lower than the actual rendering frame rate and only a small portion of data contents change over time.

Finally an update on the current status of the editor project. The character perspective has been completed, we are finishing up with some final tests and bug fixes. Once we finish these final touches and a tutorial video, the character perspective will be released to the public open source. I would like to thank Tim for his hard work on the particle system for the past a few weeks.

No comments:

Post a Comment