How to combine Fog with Outline Effect

Hi all,

As soon as I add Fog to my scene, the outline effect is gone. Is there a way to keep the effect and still add fog?

Are you talking about the class OutlineEffect or the outline effect achieved via post processing via OutlinePass?

The OutlineEffect - I totally love it, it is simpy the best edge rendering option out there. It was one of my top reasons to use THREE.JS for my project instead of Unreal, Unity or other WebGL engines. But it has not been an easy road to combine it with other stuff like the postprocessing stack…

This looks like a bug. I’ve tested with the webgl_loader_mmd example and get the following runtime error when using fog.

THREE.WebGLShader: Shader couldn’t compile.
three.js:16878 THREE.WebGLShader: gl.getShaderInfoLog() vertex ERROR: 0:202: ‘fogDepth’ : redefinition

Please file an issue at github. This needs to be fixed in OutlineEffect.

2 Likes

I made this really simple pass to use instead of the render pass that uses the outline effect and then its usable from the composer

import {
	Color
} from 'three';
import { OutlineEffect } from 'three/examples/jsm/effects/OutlineEffect';
import { Pass } from 'three/examples/jsm/postprocessing/Pass';

class OutlinePass extends Pass {

	constructor( scene, camera, overrideMaterial, clearColor, clearAlpha ) {

		super();

		this.scene = scene;
		this.camera = camera;

		this.overrideMaterial = overrideMaterial;

		this.clearColor = clearColor;
		this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0;

		this.clear = true;
		this.clearDepth = false;
		this.needsSwap = false;
		this._oldClearColor = new Color();

        this.effect = undefined;

	}

	render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
        
        if (this.effect == undefined){
            if (renderer){
                this.effect = new OutlineEffect(renderer, {
                    defaultThickness: 0.002,
                    defaultColor: [ 0, 0, 0 ],
                    defaultAlpha: 0.8,
                    defaultKeepAlive: true
                }); 
            }
        }else{
            this.effect.setRenderTarget( this.renderToScreen ? null : readBuffer );

            this.effect.render(this.scene, this.camera);
        }
        
        //renderer.render(this.scene, this.camera);
	}

}

export { OutlinePass };