In the latest version of our Vortex Studio simulation platform, CM Labs took major steps to upgrade our already innovative graphics engine and further push the boundaries of what our simulation suite can achieve. Built to grow with the performance needs of our simulation business, this updated graphics engine was designed with the latest reduced-overhead/multi-threaded rendering technologies (Vulkan and DirectX 12) in mind. As a result, it provides rendering improvements, while simplifying how Graphics Extensions are built. While this blog post is meant to provide a short introduction to the changes, we have written a white paper that guides users and introduces the new structures introduced.
A data object is a structure that has no functionality or side-effects. It has properties similar to standard C++ primitives such as int and double. In this latest update to the graphics engine, we’ve introduced various data object classes: Image, Texture, Uniform, Effect, Draw, LevelOfDetail, Mesh. We use the copy-on-write design pattern to achieve this in the code. Unlike other engines, data objects are now completely agnostic data classes — with no direct association to GPU objects. The best example of the difference with data objects is that you cannot request the OpenGL ID for a Texture. This disconnect is important when multi-threading the graphics engine; an extension can safely change the vertex position of a mesh in every frame while the graphics engine is still rendering the previous frame.
A New Approach to Rendering
We have also changed the way rendering information is aggregated; extensions now declare “snapshots” that contain what they are adding to the graphics engine. A snapshot is a graphical declaration that introduces a value into the graphics pipeline. For example, the Spline extension creates a Draw-snapshot that contains a mesh data-object, its vertex/geometry/fragment shaders, and the effect data-object to apply. Another example, the Mirror extension declares a View-snapshot that describes the offscreen-texture data-object to draw-unto and the reflected-camera placement. Now, the Graphics Module will iterate through the list of extensions that implement the Snapshotable interface—at every frame— and request a snapshot when the snapshotable class invalidates it, generating the snapshot-world. The snapshot-world is crunched by the renderer to individual draw calls, organized in render queues, ready to be uploaded to the video card. Because some of these operations are multi-threaded, snapshots must be fire-and-forget, with this change creating overall rendering speed improvements.
Creating Graphics Extensions
One of the major changes implemented is in how graphics extensions are designed. For those who have built graphics extension in previous versions of Vortex Studio, they will need to be redesigned. However, this change is meant to make creating graphics extensions easier in general. Data objects can now be created at any time within the extension, so there’s no need to wait to be attached to the Graphics Module to prepare them. For more information on how this works with Snapshot objects, please see the technical white paper section on Snapshots. Implementing these ideas in our rendering engine has already proven to be very beneficial. On development machines, samples that were CPU-bound in previous versions of Vortex Studio are now GPU-bound; this has led to a halving of the processing time. This engine will be important for future updates, so make sure to check back for future improvements. Vortex Studio 2018a can be downloaded right now. If you have an active maintenance and support contract, upgrade for free –- simply download the new installer through your online account page. And don’t forget you can also post your questions, feedback or ideas on our Community forum!