SSAA + GammaCorrection - dark colors issue

Hey, im using post processing to improve realism in my scene. This works more or less. The main problem is that dark colors have a weird behavior when SSAA is enabled. Here a before/after demo. Left is with renderPass, GammaCorrection & FXAA, right is with SSAA, GammaCorrection & SAO. See the black suit or the brown pants in the bottom right corner. Or this jsFiddle

This is my code

My renderer:

        this._renderer = new THREE.WebGL    Renderer( { antialias: true, alpha: true } )
        this._renderer.setPixelRatio(this.ratio)
        this._renderer.setSize( this.w, this.h )
        this._renderer.setClearColor(0xffffff)
        this._renderer.outputEncoding = THREE.sRGBEncoding
        this._renderer.shadowMap.enabled = true
        this._renderer.shadowMap.type = THREE.PCFSoftShadowMap
        this._renderer.toneMapping = THREE.Uncharted2ToneMapping

Postprocessing:

        this.composer = new EffectComposer(this._renderer)
        this.composer.setSize(this.w, this.h)

        this.ssaaRenderPass = new SSAARenderPass(this._scene, this.camera, 0x000000, 0)
        this.ssaaRenderPass.setSize(this.w, this.h)
        this.ssaaRenderPass.unbiased = true
        this.ssaaRenderPass.sampleLevel = 4

        this.renderPass = new RenderPass(this.scene, this.camera)
        this.renderPass.setSize(this.w, this.h)

        this.SAO = new SAOPass(this._scene, this.camera, true, true)
        this.SAO.resolution.set(2048, 2048)
        this.SAO.params.saoBias = .01
        this.SAO.params.saoIntensity = .0014
        this.SAO.params.saoScale = .3
        this.SAO.params.saoKernelRadius = 43
        this.SAO.params.saoBlurRadius = 4
        this.SAO.params.saoMinResolution = 0

        this.gammaCorrection = new ShaderPass(GammaCorrectionShader)

        this.FXAA = new ShaderPass(FXAAShader)
        this.FXAA.material['uniforms']['resolution'].value.x = 1 / (this.w)
        this.FXAA.material['uniforms']['resolution'].value.y = 1 / (this.h)

        this.composer.addPass(this.renderPass)
        this.composer.addPass(this.ssaaRenderPass)
        this.composer.addPass(this.SAO)
        this.composer.addPass(this.gammaCorrection)
        this.composer.addPass(this.FXAA)

Postprocessing seem to overall alter the colors and contrast. Maybe try adjusting gammaFactor in the original renderer, lower it a bit?

https://threejs.org/docs/#api/en/renderers/WebGLRenderer.gammaFactor

(May be related: https://github.com/mrdoob/three.js/issues/18451)

Edit: I may be wrong on this one, but GammaCorrection pass should always be at the end of the postprocessing pipeline - moving it may also help?

Nope, FXAA should always be done in the final color space. So it usually comes at the very end of the pass chain.

@Fluqz Do you really need SSAA and FXAA? Isn’t it sufficient to just use FXAA?

1 Like

i am terribly sorry to hijack this topic with a small question, but this looks stunning for something that’s presented on the web. could you recommend any resources that go into baking? the ones that i have seen don’t seem to yield results like that, not even close. yours looks actually real. :dizzy_face:

I’m not sure why adding or removing SSAA would cause any color issues like you’re showing but I notice that you’re setting the renderer outputEncoding to sRGBEncoding and also adding a gamma correction pass. You should just be doing one or the other:

this._renderer.outputEncoding = THREE.sRGBEncoding

// ...

this.gammaCorrection = new ShaderPass(GammaCorrectionShader)
1 Like

I do not use baking at all, because every part of the scene is dynamically positioned. I have multiple lights that I tried to configure to have a very soft shadow. Also using the SAO to generate a Ambient Occlusion effect works quite well, but it costs a lot of performance. For that reason I have two render states: While moving Im rendering without SAO and on mouse up I render with SAO, so the user has no lag when orbiting. Its not the most elegant way, but the only one I see right now.

1 Like

I forgot to mention that I only use one at a time. In code the passes were disabled, but that wasnt clear enough sry. I changed the description.
Left picture is with renderPass, gammaCorrection & FXAA, the right picture is with SSAA, SAO & GammaCorrection, in that order. I change betweent the two onMouseMove/onMouseUp.

I tested it and didnt see any effect

Deleting the this._renderer.outputEncoding = THREE.sRGBEncoding did not work as well. I also removed it from the textures. texture['encoding'] = THREE.sRGBEncoding makes no difference.

I also removed the unrelated passes from the chain.

this.composer.addPass(this.ssaaRenderPass)
this.composer.addPass(this.gammaCorrection)

SSAA and GammaCorrection together seems to be the problem.

I will try to make a jsFiddle as soon as possible.

Could you use SSAO instead?
Also, you can try SMAA instead of FXAA.

1 Like

Here is a jsFiddle which shows the problem. OnMouseUp the Shark gets way darker and has less gradient. Also see the cube reflection from the spotlight. The gradient is also getting smaller

@looeee I tried the SSAO before but it didnt look good at all. I will look into the SMAA, thanks

1 Like

Does anyone have an idea where this comes from? https://jsfiddle.net/f3qksgnj/

1 Like

Lowering SSAA.sampleLevel to 1 enhanced greatly the color problem, while keeping AA. Adding a background color to the scene stopped the background color changing problem. See here : https://jsfiddle.net/oj8914ph/

Jun-03-2020 09-07-23

1 Like

Thanks, setting the sampleLevel to 1 fixes the colors, but decreases antialiasing as well.
So this is not really a solution for me.

Tried SMAAPass, but is also kinda stairy

So when increasing the sampleLevel of SSAA, it seems like its loosing contrast.
Is this even a desired behavior of SSAA? Why would it change colors? Isnt it for antialiasing only?

2 Likes