Complex shape character outline

Say I have this character and I want allow user to select it, so when it s selected I want to show an outline around it.

enter image description here enter image description here

the character is an object3D with some meshes. I tried to clone and set a backside material, but it did NOT work, the problem was each cube in the shape was render with backside separately so the outline was wrong.

do I need to create another mesh for the outline, is there an easier way?



What @spassvolgel wrote is correct;

What I suspect needs to be done is something like this: 1. First the background needs to be rendered 2. Then, on a separate transparent layer, the character model with a flat color, slightly bigger than the original, 3. On another transparent layer the character with its normal material / texture 4. Finally, the character layer needs to go on top of the outline layer and them combined need to be placed in the bg

You just create multiple scenes and combine them with sequential render passes:

renderer.autoClear = false;
. . . 

renderer.render(scene, camera); // the entire scene
renderer.render(scene2, camera); // just the selected item, larger, in a flat color
renderer.render(scene3, camera); // the selected item again

Here is a fiddle implemented with GPU picking, but it could just as easily be implemented with the more-familiar Raycaster:


Screenshot of selected item outlined



An generic solution that applies to geometries of any complexity might be to apply a fragment shader via the ShaderMaterial class in three.js. Not sure what your experience level is at, but if you need it an introduction to shaders can be found here.

A good example where shaders are used to highlight geometries can be found here. In their vertex shader, they calculate the normal for a vertex and a parameter used to express intensity of a glow effect:

uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main() 
    vec3 vNormal = normalize( normalMatrix * normal );
    vec3 vNormel = normalize( normalMatrix * viewVector );
    intensity = pow( c - dot(vNormal, vNormel), p );

    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

These parameters are passed to the fragment shader where they are used to modify the color values of pixels surrounding the geometry:

uniform vec3 glowColor;
varying float intensity;
void main() 
    vec3 glow = glowColor * intensity;
    gl_FragColor = vec4( glow, 1.0 );

I found something on that could be useful. They talk of a stencil buffer. I have no idea on how to apply this to THREE.js though..


You can get good results by rendering your outlined object(s) to a texture that is (ideally) the size of your destination framebuffer, then render a framebuffer-sized quad using that texture and have the fragment shader blur or do other image transforms. I have an example here that uses raw WebGL, but you can make a custom ShaderMaterial without too much trouble.


I haven't found the answer yet but I wanted to demonstrate what happens when I create multiple meshes, and put another mesh behind each of these meshes with

side: THREE.BackSide

as you can see, it's not the desired effect. I would like a clean outline behind ALL three meshes, that doesn't overlap. My level of programming shaders is really non-existent, but on most online resources people say to use this approach of cloning the meshes.


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.