Complex shape character outline
Asked Answered
D

5

13

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?

Depoliti answered 19/7, 2013 at 6:51 Comment(5)
You could just clone and set normal material, then scale the clone slightly and move it away from the camera. So the outline is just bigger model behind the actual model. Just an idea, I remember reading some game having done it that way...Underpart
well, thanks yaku. I ll try moving the clone from the camera to test your way, but the thing is that my characters are more complex than this, and they are walking on the ground i guess just becoz the camera is looking from the top, the outline clone will go behind the ground and mess everything!Depoliti
Did you manage to get this to work eventually? I am very interested in the solution.Amiraamis
Im offering a bounty because I would really like to know how to do this. Like Ashkan, the problem with creating a clone with backside material appears because the shape is complex. What I suspect needs to be done is something like this: 1. First the background needs to be rendered 2. Then, on a seperate 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 bgAmiraamis
Ashkan - Please remember to "accept" answers by clicking on the check mark. Thank you.Bouncy
B
19

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.clearDepth();
renderer.render(scene2, camera); // just the selected item, larger, in a flat color
renderer.render(scene3, camera); // the selected item again

three.js.r.129

Bouncy answered 18/2, 2014 at 19:4 Comment(5)
Thanks so much! This looks very promising. The bounty will expire soon but I'm a bit short on time to dive into the code so I will award it to you. Thx again!Amiraamis
thanks for your answer, the demo was also great. but there is something still bothering me. the point of my question was that the objects are not a single mesh...Depoliti
@AshkanGhodrat Were you unable to get this approach to work with an object having child meshes?Bouncy
Well I couldn't modify your code for meshGroup but do you think it solves the problem from this image? s30.postimg.org/oxpnl0xsx/shaders.jpgDepoliti
I think you should post a new question with your additional requirements clearly stated.Bouncy
P
1

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 );
}
Packston answered 13/2, 2014 at 17:39 Comment(1)
Look at this image, this is my problem with shaders s30.postimg.org/oxpnl0xsx/shaders.jpgDepoliti
A
1

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

https://gamedev.stackexchange.com/questions/59361/opengl-get-the-outline-of-multiple-overlapping-objects

Amiraamis answered 18/2, 2014 at 18:21 Comment(0)
M
1

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.

Maddy answered 14/12, 2018 at 5:44 Comment(0)
A
0

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  

http://jsfiddle.net/GwS9c/8/

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.

Amiraamis answered 15/2, 2014 at 22:57 Comment(1)
I think the result of shaders wouldn't be much different unless you write some complicated shaders, which i can't :D and yeah backside is not the best idea for this matter...Depoliti

© 2022 - 2024 — McMap. All rights reserved.