Skip to content

Effect Merging

Raoul v. R edited this page Mar 8, 2021 · 19 revisions

How It Works

The Effect framework defines a simple shader format for easy merging via the EffectPass. Effects are merged into a single compound shader by gathering and prefixing shader functions, varyings, uniforms and macros. The shader is then used to process texels from an input buffer which usually contains the rendered scene colors. Texels pass through the effect function chain and intermediate results are blended with previous results. The final result is written to an output buffer or to screen.

Effect Execution Order

Effect merging can drastically improve performance by reducing the amount of fullscreen render operations, but it's sometimes necessary to split effects into separate passes to achieve optimal results. For instance, SMAA is usually applied first to avoid conflicts with other effects but some effects can introduce new aliasing artifacts at a later stage. If that's the case, it can be better to run these effects in a separate pass before SMAA.

The EffectPass sorts effects based on whether or not they read data from the input buffer or rely on depth. Other effects will be rendered in the order in which they were added. The recommended order for common effects is as follows:

  • SMAA
  • SSR (NYI)
  • SSAO
  • DoF
  • Motion Blur (NYI)
  • Chromatic Aberration
  • Bloom
  • God Rays
  • Vignette
  • Tone Mapping
  • LUT / Color Grading
  • Noise / Film Grain

Effect Compatibility

The EffectPass prevents bad combinations of effects and informs the user about potential issues.

Convolution effects and effects that transform texture coordinates inside the fragment shader cannot be merged with each other. To use such effects together, you'll need to use multiple EffectPass instances. While it's technically possible to merge all effects, some combinations will produce undesired results in the form of visual discontinuities and artifacts.

The following example shows a problematic combination of a PixelationEffect that transforms texture coordinates and an SMAAEffect that reads data from the input buffer:

SMAA with Pixelation Exaggerated Pixelation
uv01 uv02 uv03

The SMAAEffect calculates its own coordinate offsets to blend texels with neighboring texels from the input buffer and is unaware of the fact that the main coordinates have been warped. As a result, the antialiased lines show up as artifacts in the final image. To better highlight the artifacts, the image on the right shows an extreme case where the PixelationEffect reduces the scene into a single grey pixel.

There is no feasible way to ensure that all custom texture coordinate calculations go through the same transformation. The best solution is to render these effects in separate passes.

Clone this wiki locally