Performance of different antialiasing techniques

I am trying to optimize performance vs. rendering quality for my app and antialiasing is critical. There are many antialiasing techniques. In my case I realized that post-processing passes work much better than the default MSAA, however, they all come with some performance penalty. So, my question is how would you rank post-processing passes in terms of performance and quality?

My subjective perception is the following (slowest to fastest):

  1. SSAA - good quality when level is at least 3
  2. TAA - good quality when level is at least 3, level 2 is okay-ish.
  3. SMAA
  4. WebGLMultisampleRenderTarget
  5. FXAA - doesn’t work for me at all.
  6. MSAA - doesn’t work for me since I use post-processing.

So my questions are:

  1. Would you rate it the same?
  2. Are there any techniques that can help to remove pixelation while maintaining high fps on slow devices such as phones?
  3. Can I combine any of these techniques together to get better results?

Thank you in advance!

PS: Important note. I use glTF models and my model is not moving, i.e. I do not apply rotation or any other transformations to the model. Instead, I rotate camera around it.

You can use hardware (MSAA) antialiasing with postprocessing:

if ( renderer.getContext() instanceof WebGL2RenderingContext ) {
    composer.renderTarget1.samples = 8;
    composer.renderTarget2.samples = 8;
}

Would it make sense to use it with WebGLMultisampleRenderTarget? They seem to yield the same results.

I think multisample rendertarget has been rolled into main now… its just the regular rendertargets under webgl2 they are multisample by default? Not sure.

Setting the samples works but it might break some types of post passes… but it works for UnrealBloom and color stuff which is mainly what im using.

1 Like

You are right, I meant WebGLRenderTarget with samples. I use it in the following way:

  let renderTarget = undefined;
  if (WebGL.isWebGL2Available()) {
    const size = renderer.getDrawingBufferSize(new THREE.Vector2());
    renderTarget = new THREE.WebGLRenderTarget(size.width, size.height, {
      samples: 4,
    });
  }
  const composer = new EffectComposer(renderer, renderTarget);

Anyways, it is better than nothing, but still far from TAA or SSAA. Is there anything I can apply on top without killing performance?

Also a side question. Why do we always check for WebGL2 if I just tested ThreeJS on the very old device to check performance with no WebGL2 and it didn’t work. It wasn’t possible to create WebGLRenderer, errors while creating and ThreeJS published the message to the log saying that WebGL1 is deprecated and will be removed.

Yeah WebGL2 is pretty much universal at this point… so you’re right… we probably don’t even have to check for it anymore. WebGL 2.0 | Can I use... Support tables for HTML5, CSS3, etc

1 Like