Eugene Fitzher
Eugene Fitzher

Reputation: 163

Outline Effect to Target Object

I’m looking for an way to set outlines for objects.

I’m using ‘OutlineEffect’ instead of ‘EffectComposer’( OutlinePass and etc. ), because when I use effect composer, resolution quality is low even use FXAAShader, SSAA Shader and OutlinePass cannot use ‘dark’ color.

On OutlineEffect, it said:

/*
 * 1. Traditional
 *
 * var effect = new THREE.OutlineEffect( renderer );
 *
 * function render() {
 *
 *  effect.render( scene, camera );
 *
 * }
*/

and when I use it even skybox get outline.

var outlinePass;
function init()
{
    ...
    outlinePass = new THREE.OutlineEffect(renderer);
    ...
}

function animate()
{
   ...
   outlinePass.render(scene, camera);
   ...
}

The problem is I don’t want to let it draw a outline on skybox.

So I used effect.setRenderTarget(objects) bottom line of the outlinePass = new THREE.OutlineEffect(renderer);, and an error occured:

three.js:18819 Uncaught TypeError: Invalid value used as weak map key
    at WeakMap.set (<anonymous>)
    at Object.get (three.js:18819)
    at WebGLTextures.setupRenderTarget (three.js:22177)
    at WebGLRenderer.setRenderTarget (three.js:25956)
    at THREE.OutlineEffect.setRenderTarget (OutlineEffect.js:563)

What I want to do is, create 'black' outline for select objects, without skybox.

Thank you for your help!

Upvotes: 1

Views: 3112

Answers (1)

Eugene Fitzher
Eugene Fitzher

Reputation: 163

I created 2 scenes, one for Don't have outline and the other for Have outline.

Let's create sub scene for without outline objects.

skyBox = {
    scene: new THREE.Scene(),
    camera: new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 20000 )
//camera has same properties with main camera.
};

Now the objects, which should not have outline, should add in skyBox.scene, and skyBox.camera will show them.

For the objects, I need to add the objects like:

skyBox.scene.add(object);

And I copied sub camera's additional controls(e.g orbit controls, ...) from main camera's so I will feel having only '1' camera.

So now, I need to let sub camera have same condition with main camera.

//controls for camera control; e.g. orbit control.

controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener('change', camRender2 );  // for controls2
...
controls2 = new THREE.OrbitControls( skyBox.camera, renderer.domElement );
controls2.addEventListener('change', camRender );  // for control
... // other condition for your own controls.

Now, the settings are done. I just need to add OutlineEffect

outlineEffect = new THREE.OutlineEffect(renderer);

And now, I just need to render it.

...
renderer.autoClear = false;   // If miss it, only main camera will render.
...
function render()
{
    //let sub camerafollow the main camera.
    skyBox.camera.quaternion = camera.quaternion;

    outlineEffect.render(scene, camera);           //render for outline scene.
    renderer.render(skyBox.scene, skyBox.camera);  //render for without outline scene.
}

Adding outline objects, you just need to scene.add(object);.

Dont Forget! You need to control the objects with your camera and scene WHERE the objects are added, attached.

( like hover event, click event, what you need to raycast with scene that including the objects. )

Upvotes: 2

Related Questions