Skip to content

Library overview

Anton Chekulaev edited this page Jun 18, 2020 · 16 revisions

The library's goal is to provide a simple yet flexible framework to work with post-processing OpenGL shader effects in a LibGDX application. On top of it, there is a bunch of most common out-of-the-box effects included in the library. So it should be a breeze to pick up the library and start using it straight away.

Library module structure

  1. gdx-vfx-core - Core classes.
  2. gdx-vfx-effects - Collection of the out-of-the-box filters and effects. Read more about this module at Built-in Effects page.
  3. gdx-vfx-gwt - Platform specific code for GWT backend.

Post-processing workflow

These three stages should happen to any post-processing engine:

  1. Capture the game's scene into an off-screen buffer for further processing (or just provide a static image).
  2. Apply a chain of shader effects to the image data provided in the first step.
  3. Render the result to the screen or another buffer (e.g., to save the result to an image).

Most of all, the library focuses on the second step. But to some extent, it covers them all, as there are tools provided for scene capturing and rendering the result out.

General use case

This is how the library is intended to be used in the code:

  1. You create and configure required Effects and add them to a Manager.
  2. Inside render code, this happens:
    1. The Manager starts capturing into an off-screen buffer.
    2. You render your scene.
    3. The Manager stops capturing into an off-screen buffer.
    4. The Manager applies Effect chain to the captured result.
    5. The Manager renders the result into the screen or to another frame buffer (if you specify one).
    6. When no longer needed, the Manager and all the Effects should be disposed manually. Please read the notes about this stage here.

Library architecture

These are the most important elements of the library:

VfxManager aka Manager

The core of the library. The Manager maintains and applies post-processing Effect queue to the scene provided. Also, the Manager provides functionality to capture the scene into an off-screen buffer and to render the result to the screen or to another buffer.

VfxEffect aka Effect

Is the base interface for any visual effect. It's important to note that VfxEffect interface derivatives are not necessary OpenGL shader effects, they can be anything, and it's up to the implementation to decide what to do with the graphics data. Thus these are the most important built-in interfaces/classes that implement VfxEffect interface:

  1. ChainVfxEffect A base interface for any effect that can participate in the Manager's effect chain.
  2. ShaderVfxEffect It's an abstract base class for any OpenGL shader-based effects. It lets you create an interface between GLSL code and Java and expose properties/methods to control the shader from the game code. Most of the built-in effects from gdx-vfx-effects extend this class (NOTE: not all the ShaderVfxEffects are ChainVfxEffects, there are some utility ones that can only be used manually).
  3. MultipassEffectWrapper Most of the ChainVfxEffects are made to be "single pass" effects, and this a simple wrapper that helps to run the same effect multiple times.
  4. CompositeVfxEffect A utility effect implementation that helps easily compose multiple other effects together (e.g. BloomEffect is a mix of three different Effects).

Implementation specifics

These are the things that are important to know about before you start using the library code.

VFX frame buffer

The library imposes to use VfxFrameBuffer class over regular FrameBuffer whenever you need to deal with the off-screen rendering during capturing or applying effects chain stages. Please read about VfxFrameBuffer justification on this page.

Ping-pong rendering

As there is a chain of Effects to be applied to the scene one after another, we use the ping-pong buffer rendering approach. Ping-pong buffer basically stands for two buffers where one is used as an input for an Effect (aka src buffer), and the other one as the buffer where the Effect will render the result to (aka dst buffer). Once any Effect is rendered, the two buffers should be swapped, so now the result will be held in the src buffer and ready to be used as an input for another Effect.

Resource disposal

As we are dealing with OpenGL related stuff, most of the library classes implement Disposable interface and shall be properly disposed when no longer needed.

It's important to note, that although a Manager maintains a chain of Effects, it doesn't manage their life-cycle. Means you have to manually call VfxEffect#dispose() when you no longer need it (e.g., application termination).

You create Effect instances outside of the Manager, add/remove them to the Manager whenever you need them to participate in the effect chain, and you're responsible for disposing them yourself.

Custom OpenGL calls

The library relies on an extended set of OpenGL functions, that are not yet available/implemented for all of the official LibGDX backends. Thus VfxGlExtension interface is introduced. Different implementations help to maintain cross-platform support. However, the same implementation is shared among almost all the backends - DefaultVfxGlExtension, except for GWT backend we use GwtVfxGlExtension due to WebGL specifics.

At the runtime, current VfxGlExtension instance is available through VfxGLUtils#glExtension.