Very thin lines look jagged, antialiasing not working

Hello,

I am loading in my scene a very thin line from a GLB file and the line looks very jagged. My renderer already has antialias:

renderer = new THREE.WebGLRenderer( { antialias: true, autoSize: true } );

And it doesnt seem like working. My mesh is being loaded normally with the GLB loader and no material is being applied to the lines.

Screenshot%20from%202019-04-08%2018-45-18

Any idea why this might be happening? Thanks!

Do you have post processing here?

Side note: autoSize is no parameter of THREE.WebGLRenderer.

Haha well that is strange xD

I do, I am using Bloom and Bokeh. Anyway, when disabling them, the lines still look jagged.
I will add you here some extra code:

renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( 0x1c2325, 1 ); // the default,
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window_innerWidth, window_innerHeight );
renderer.gammaOutput = true;
renderer.gammaFactor = 1.3;
renderer.shadowMap.enabled = false;
renderer.autoClear = false;

var bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window_innerWidth, window_innerHeight ), 1.5, 0.4, 0.85 );
bloomPass.renderToScreen = true;
bloomPass.threshold =  0.4 ;
bloomPass.strength = 1.5;
bloomPass.radius = 1.1;

var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat};
postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget( window_innerWidth, window_innerHeight, pars );
postprocessing.rtTextureColor = new THREE.WebGLRenderTarget( window_innerWidth, window_innerHeight, pars );

var bokeh_shader = THREE.BokehShader;

postprocessing.bokeh_uniforms = THREE.UniformsUtils.clone( bokeh_shader.uniforms );
postprocessing.bokeh_uniforms[ 'tColor' ].value = postprocessing.rtTextureColor.texture;
postprocessing.bokeh_uniforms[ 'tDepth' ].value = postprocessing.rtTextureDepth.texture;
postprocessing.bokeh_uniforms[ 'textureWidth' ].value = window_innerWidth;
postprocessing.bokeh_uniforms[ 'textureHeight' ].value = window_innerHeight;

bokehEffectController = {
    enabled: false, //
    jsDepthCalculation: false,
    shaderFocus: false,
    fstop: 0.1,
    maxblur: isMobile ? 0 : 2,
    showFocus: false,
    focalDepth: isMobile ? 0 : 1.8,
    manualdof: isMobile ? false : true,
    vignetting: true,
    depthblur: false,
    threshold: 0.0001,
    gain: 0,
    bias: 0,
    fringe: 0,
    // focalLength: 35,
    noise: false,
    pentagon: false,
    dithering: 0
};

Thanks!

To visit the website, please go to the following pastebin and navigate to the url inside.

https://pastebin.com/qsgigU3M

The lines appear when mouse-hovering the round buttons around the main mesh.

Thank you very very much!

1 Like

Anti-aliasing does only work if you directly render to screen (or the default framebuffer). It does not work for offscreen rendering, at least when using WebGL 1. I guess that was the reason why @pailhead asked in this direction^^.

You can solve this issue by using an additional post processing pass that performs FXAA.

There is an example demonstrating the approach:

https://threejs.org/examples/webgl_postprocessing_fxaa

Unfortunately FXAA pass doesnt seem to work with UnrealBloomPass. When adding both to my EffectComposer the scene turns black. I have tried upgrading UnrealBloomPass but it gives me:

THREE.Pass.FullScreenQuad is not a constructor

Any idea why both postprocessing pass dont work together?

Thanks!

Please try to upgrade EffectComposer and all other used passes in your app. The versions of the files from the repository always have to match. Besides, ensure to add FXAA always at the end of your pass chain.

I am trying to upgrade but I am receiving 2 types of warnings:

three.js:201 THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.

To avoid this warning, I have modified my render function from:

function render(){

    renderer.clear();
    renderer.autoClear = false;

    composer.render();

    // render scene into texture
    renderer.render( scene, camera, postprocessing.rtTextureColor, true );
    // render depth into texture
    scene.overrideMaterial = materialDepth;
    renderer.render( scene, camera, postprocessing.rtTextureDepth, true );
    scene.overrideMaterial = null;

    if(postprocessing.camera){
        // render bokeh composite
        renderer.render( postprocessing.scene, postprocessing.camera );
    }

    renderer.render(scene, camera)
    renderer2D.render(scene, camera);
}

To this one:

function render(){

    renderer.clear();
    renderer.autoClear = false;

    composer.render();

    // render scene into texture

    renderer.setRenderTarget( postprocessing.rtTextureColor );
    renderer.clear();
    renderer.render( scene, camera );


    // render depth into texture
    scene.overrideMaterial = materialDepth;

    renderer.setRenderTarget( postprocessing.rtTextureDepth );
    renderer.clear();
    renderer.render( scene, camera );

    scene.overrideMaterial = null;

    if(postprocessing.camera){
        // render bokeh composite
        renderer.setRenderTarget( null );
        renderer.clear();
        renderer.render( postprocessing.scene, postprocessing.camera );
    }

    renderer.setRenderTarget( null );
    renderer.clear();
    renderer.render(scene, camera)
    renderer2D.render(scene, camera);
}

This latest code leads me to an error in the first renderer.render( scene, camera );
three.js:138 Uncaught TypeError: Cannot read property 'texture' of undefined at ch.updateRenderTargetMipmap (three.js:138)

And finally this warning, but I do not use forceClear anywhere.
THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.

Any idea why is not working?

Thanks!

Um, your code looks fine! Apart from the line renderer.autoClear = false; but that should not be responsible for the warnings (you should autoClear to false only once when creating your renderer).

Any chances to share a link to this version of your app?

Sure! https://pastebin.com/fJkGryiT (link will expire).

Thank you very much

Maybe with an unminified version of three.js? :innocent:

Done :slight_smile:

Your variable postprocessing does not have a rtTextureColor and rtTextureDepth property when the error occurs. I think this happens because you execute initPostprocessing() too late. Try to execute this function before your initial call of animate() or consider to start animating when all parts of your scene are loaded and ready.

Thank you so much for your suggestion, calling initPostprocessing() before animate() solves the issue. Still, my postprocessing isnt working at all nor any of the textures…Am I missing something in the migration?

Try it with this render function:

function render(){

    renderer.clear();

    composer.render();

    // render scene into texture

    renderer.setRenderTarget( postprocessing.rtTextureColor );
    renderer.clear();
    renderer.render( scene, camera );


    // render depth into texture
    scene.overrideMaterial = materialDepth;

    renderer.setRenderTarget( postprocessing.rtTextureDepth );
    renderer.clear();
    renderer.render( scene, camera );

    renderer.setRenderTarget( null );
    scene.overrideMaterial = null;

    if(postprocessing.camera){
        // render bokeh composite
        renderer.render( postprocessing.scene, postprocessing.camera );
    }

    renderer.render(scene, camera)
    renderer2D.render(scene, camera);
}

It seems you perform some unnecessary clears right now.

Still no luck…I will have a look at the code but from the previous version to this one I just changed the render() function due to this setRenderTarget, clear and render new functions. Regarding the texture of the main big meshes I wonder if the GLTF loader has changed somehow and the way I recognize the meshes do not work anymore, but about the postprocessing I have no clue why they dont work.

Well, in order to solve your original issue, it’s actually not necessary to upgrade the library. If this causes to many trouble right now, I would revert the latest changes and ensure FXAA works with your previous version.

So, after playing with my old version of the code, seems like the one that is giving the issue is the postprocessing, since when I remove the line renderer.autoClear = false; the postprocessing doesnt take place and the lines look pretty smoooth.

Screenshot%20from%202019-04-09%2021-19-14

I have discarded the UnrealBloomPass from the problem, which leads me to the THREE.BokehShader, I followed the online example. I have added GUI to my local version of the website but there seems to be no way for me to make the edges of any line smooth with this type of porstprocessing, even when they are focused and I remove all blur…

Have you tried to add an FXAA pass after the bokeh pass? The shader requires a correct configured resolution uniform in order to see the antialiasing effect. The respective example demonstrates how this setup looks like.