What is Order Independant Transparency ?
When rendering translucent geometry, the draw order matters because each fragment’s final color depends on the value already stored in the framebuffer. To obtain the correct results, geometries must be sorted and rendered back-to-front relative to the camera. However, this comes at the cost of sorting each geometry prior on the CPU and rendering them in the correct order. This is also incompatible with custom vertex shaders that may do whatever transformations they want to do.
Instead, Flywheel uses an Order Independant Transparency technique based on wavelets, as detailed in this blog post. Colorwheel reuse the same implementation.
This has the advantage of not requiring any sorting, but at the cost of more work on the GPU and an increase in memory usage.
Wavelet-Based OIT
Section titled “Wavelet-Based OIT”For a more detailed explanation, you may refer to the blog post, but here is a general overview:
The idea consists of creating a function that approximates the transmittance-over-depth from the camera’s perspective.
- An initial pass computes the depth ranges of all translucent geometries.
- A second pass creates the transmittance-over-depth function for the depth range computed in the first pass. This function is stored as coefficients of a wavelet in coefficients buffers.
- Translucent geometries are then rendered and blended using additive blending, which is order-independent because addition is commutative. The results are weighted using the transmittance-over-depth function and stored in accumulation buffers.
- Finally, the accumulation buffers are composited onto the final buffers using the usual blending mode (
SRC_ALPHA ONE_MINUS_SRC_ALPHA ONE ONE_MINUS_SRC_ALPHA
).
The transmittance-over-depth function is an approximation, with the precision level determined by the ranking used, which specifies the number of coefficients stored. The formula used is 2^(R+1)
, where R is the rank of the coefficients buffer.
Configuration
Section titled “Configuration”Shaderpack developers can configure the OIT in the colorwheel.properties file. By default, this feature is disabled and geometries will be rendered in random order.
When enabled, all buffers are treated as frontmost by default. This mode do not generate the transmittance-over-depth function, and only the frontmost fragments are displayed (using the depth range generated in the first pass). This mode is useful for buffers storing data that shouldn’t be blended (like normals) or for the shadow render pass.
For proper blending, coefficients buffers must be declared by listing their ranks. Once done, you can assign a coefficients buffer to a buffer. If multiple buffers have the same alpha value, they can share the same coefficients buffer to save memory.
Valid ranks range from 1 to 3, with 3 being the recommended value. However, smaller values may be used to reduce memory usage at the cost of precision.
You may also configure the accumulation buffers texture format, which is RGBA16F
by default. When doing so, make sure to use a texture format with an alpha channel.