Awful aliasing when using post processing

Hi,
I want to use an outline effect, so I used postprocessing for my render, but the problem is it adds awful aliasing. Adding an FXAA or SMAA pass doesn’t help, it’s still very ugly.
Is there a way to use postprocessing and retain the built-in antialiasing? Why does it stop working in the first place when using postprocessing?

Here’s without post processing:

Here’s with post processing and FXAA

Any suggestions ? Is there a way to render normaly, then have an EffectComposer render my outline effect ? I would only have to render the transluscent red meshes in that Composer, so I guess it wouldn’t be too heavy

2 Likes

I have a few of suggestions for you

  • don’t use very thin geometry. This is a common thing, if you have a look at pretty much any AAA video game - you will see that they avoid having very thin geometry, because of aliasing mostly, it also can create shadow artifacts and various other nasty things, all because of aliasing, pretty much
  • use muti-sampled render targets, they allow for higher resolution, so you will see less aliasing
  • try other anti-aliasing techniques

there’s a really good article by Emil Perrson in SIGGRAPH 2012 that mentions thin geometry AA, here’s a relevant piece:

2 Likes

I don’t get it, even if you make your thin geometry thicker, eventually if you move back the camera enough they will get sub-pixel size, aren’t they ? How can you ensure something will never be sub-pixel size ?

1 Like

Not at all, but this is rather about the size, by being long and thin. Thin geometry is bad since even when it isn’t too long like phone wires, they go subpixel very quickly.

For the case of the OP i would suggest making these parts with repeated textures.

3 Likes

Thanks Usnul for your answer but:

  • The geometry is out of my control, the models are building converted from IFC files. We use them to show the buildings and the location of appartments in the building on a website where we sell appartments.
  • Multi sampled render targets could be a solution, but we target the best performance possible, we have to asume some of our customers will have old integrated graphics or not-so-great smartphones
  • I will try other AA techniques, but like I just said, performance is an issue so I may end up leaving the bad aliasing :confused:

What about rendering to the backbuffer, then render my outline effect in a texture that I will then render on top of the rest?

Be aware that it’s necessary to configure the resolution uniform of FXAAShader for a proper result. I’ve seen several users who missed this in their app.

I managed to get what I wanted, using the technique I described above:

  1. Render my scene with renderer
  2. Render composer with OutlinePass, to a renderTarget
  3. Render composer renderTarget texture on a quad in screen space

I had to tweak a few things in the OutlinePass to get it to render properly in the renderTarget, clear when needed, as well as changing the shader so that it drew the correct alpha (I was getting a black image with just the outline otherwise )

3 Likes

hello,i have same question,but i dont know how to resolve to it,could you some code demo? thank you

I would love to see some code for this.

You do not need post processing for the outline.
You can do

const outline = new OutlineEffect(this.renderer as WebGLRenderer, {
  defaultThickness: 0.01,
  defaultColor: [0, 0, 0],
  defaultAlpha: 1.0,
  defaultKeepAlive: true // keeps outline material in cache even if material is removed from scene
});
this.outline = outline;

and then later

this.renderer.clear();
this.renderer.render(this.scene, this.camera);

this.outline.renderOutline(this.scene, this.camera);

Note that in that case, the whole scene will be outlined. If you want to outline to outline specific objects, you’ll need to manage a separated scene, this scene will contains the outlined objects

2 Likes

The thickness of their wires is dynamic. They only define the spline, so the center of the cylinder, the radius is adjusted based on distance.

2 Likes

This answer saved me so much frustration! I’d been wrestling with the effects post processing for a long time before finding this. Thank you.

I had this exact issue and stumbled upon this thread. Since all I wanted was an outline effect on a few meshes in my scene, I decided to avoid post processing altogether. I didn’t want to eat the cost of additional render targets and passes just to outline a couple of objects. The outline effect suggested by Chabbey_Francois didn’t work for me as that effect simply moves the vertices along the normals, and my objects use vertex normals aligned with face normals, so moving a vertex along the normal would just explode the object. I need to use face aligned normals for faceted rendering.

I thought about it for a while, and finally implemented the following solution that has been working really well so far:

  1. Create new buffer geometry from the source mesh’s buffer geom, but with averaged normals. Basically, all normals associated with a vertex position are averaged and assigned to those vertices instead of the face aligned normals that those vertices had.

  2. Create a shader material with a vertex shader that moves the vertices along the normal direction (similar to the OutlineEffect mentioned above). This displacement determines the thickness of the outline in world space. I modulated this distance by distance of the object from the camera (length(modelViewMatrix[3].xyz)) to maintain a somewhat constant outline thickness. Set the depth write for this material to false. The pixel shader for this material simply returns a solid color.

  3. Create a new mesh with the newly created buffer geometry and shader material.

  4. Add the new mesh to the parent of the mesh that needs outline.

  5. Set the render order of the mesh that needs outline to 1. This makes it render after the new solid color and scaled version of itself that we just created and added to the scene.

This approach works better for me as I only need to outline a few hand picked objects in the world. If you need to arbitrarily outline hundreds of objects, you need to be aware of the video memory cost of duplicate buffer geoms. Also, if you don’t use faceted rendering, you don’t need to use this approach as OutlineEffect may work just fine for you.

Thought I’d share if anyone stumbles upon this page like I did.

4 Likes

With the latest THREEJS, WebGL2 is the default, and WebGL2 allows antialising on offscreen rendertargets… so this may/will no longer be an issue for webgl2 supporting browsers.