Stencil Glow Demo

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Stencil Glow Demo

Post by Assaf Raman » Fri Dec 29, 2006 12:40 am

Stencil Glow Demo
Image

The work described in this post is partially based on code by nebukadnezzar that was posted on this thread: http://www.ogre3d.org/phpBB2/viewtopic.php?t=25321

Thanks nebukadnezzar!

I have created a simple demo to show how to use the stencil to create two types of glow effects.

The main advantage of my glows is that you can apply them to a single object and not the whole scene.

Outline glow effect round a specific entity:
Image

A full body wrap glow effect round a specific entity:
Image

I did not find any other good demo of how to use the stencil in OGRE.

I recommend to add this demo (or similar) to the OGRE demos that come with the OGRE source download.

Here is the exe ready to run:
http://assaframan.googlepages.com/StencilGlow_exe.zip

Here is the code:
http://assaframan.googlepages.com/StencilGlow_src.zip

Here are some more screenshots:
Image
Image
Image
Image


This is my Xmas present to the OGRE community. :D

[EDIT]I updated the downloads with broli's normal fix.[/EDIT]
Last edited by Assaf Raman on Fri Dec 29, 2006 10:40 am, edited 2 times in total.
0 x
Watch out for my OGRE related tweets here.

User avatar
BRAINLESS
Goblin
Posts: 282
Joined: Tue Jan 04, 2005 6:56 pm
Location: The Netherlands

Post by BRAINLESS » Fri Dec 29, 2006 12:52 am

Oh my god, thanks! :D
0 x
Proud member of the OpenFRAG Game Development community

User avatar
Jerky
Orc Shaman
Posts: 791
Joined: Wed Mar 02, 2005 4:13 am
Location: Springville, Utah
Contact:

Post by Jerky » Fri Dec 29, 2006 3:05 am

Wow, that could be handy in any type of game. Very cool, thanks!
0 x
Erik Briggs (Jerky)
My Blog
Project Wish
Image

broli
Halfling
Posts: 48
Joined: Fri Mar 31, 2006 5:08 pm

Post by broli » Fri Dec 29, 2006 5:13 am

In your cg or hlsl file try using the normal and multiply it with the rest. And don't multyply your vertex position, something like this...

Code: Select all

cg:

mypos.xyz += size_value * (1.0 + (sin(time * 5.0) + 1.0)  / 5.0 ) * normal;

hlsl:

vec3 Pos = gl_Vertex.xyz +  ( (size_value * (1.0 + (sin(time * 5.0) + 1.0)  / 15.0 ) * normal );
It would clear up that offset issue you currently have since the vertices arn't shifted trough their normals.
0 x

User avatar
Kentamanos
Minaton
Posts: 980
Joined: Sat Aug 07, 2004 12:08 am
Location: Dallas, TX

Post by Kentamanos » Fri Dec 29, 2006 5:16 am

You're saying for instance, that would make the glow around the teeth match up, right?
0 x

broli
Halfling
Posts: 48
Joined: Fri Mar 31, 2006 5:08 pm

Post by broli » Fri Dec 29, 2006 5:23 am

That's correct.
0 x

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Post by Assaf Raman » Fri Dec 29, 2006 10:38 am

broli: You are right - it is much better with the normal.

I updated the downloads in the first post.

Redownload if you want it.

Here is how it looks now:
Image
Image

Thanks broli!
0 x
Watch out for my OGRE related tweets here.

User avatar
Kentamanos
Minaton
Posts: 980
Joined: Sat Aug 07, 2004 12:08 am
Location: Dallas, TX

Post by Kentamanos » Fri Dec 29, 2006 10:41 am

Very sweet now...

Nice tip broli, and good work Assaf!
0 x

Ajare
Goblin
Posts: 282
Joined: Sat May 14, 2005 9:20 pm

Post by Ajare » Fri Dec 29, 2006 3:44 pm

I'm getting a problem with this when I try to turn the effect 'off'. I have a 'select object' function as follows:

Code: Select all

void ActorRepresentation::setHighlighted (bool active)
{
	if (active)
	{
        mEntity->setRenderQueueGroup
                (RENDER_QUEUE_OUTLINE_GLOW_OBJECTS);
		mHiliteEntity = mEntity->clone (mEntity->getName () + "Hilite");
		mHiliteEntity->setRenderQueueGroup (RENDER_QUEUE_OUTLINE_GLOW_GLOWS);
		mHiliteEntity->setMaterialName ("Editor/Glow_CG");
		mNode->attachObject (mHiliteEntity);
	}
	else
	{
		Ogre::SceneManager *scm = Ogre::Root::getSingleton ().getSceneManager ("SceneManager");
		mEntity->setRenderQueueGroup (mDefaultRenderQueueGroup);
		scm->destroyEntity (mHiliteEntity);
		mHiliteEntity = 0;
	}
}
However, when de-highlighted, the original entity (mEntity) is now being rendered with no depth-checking.
0 x

User avatar
SpannerMan
Gold Sponsor
Gold Sponsor
Posts: 446
Joined: Fri May 02, 2003 10:05 am
Location: UK
Contact:

Post by SpannerMan » Fri Dec 29, 2006 5:43 pm

Wow thats a really cool effect Assaf, I agree this will be very useful for many things.

So if its using the Stencil buffer and shaders, can you tell me what are the minimum hardware requirements for this effect?
0 x

broli
Halfling
Posts: 48
Joined: Fri Mar 31, 2006 5:08 pm

Post by broli » Fri Dec 29, 2006 5:56 pm

The material file says vertex shader 1.1/pixel shader 2.0.
0 x

User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
Contact:

Post by Falagard » Fri Dec 29, 2006 6:08 pm

It would be easy to get it to work with only pixel shader 1.1, and then have a fallback (through code and material) that uses scaling and works with fixed function.
0 x

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Post by Assaf Raman » Fri Dec 29, 2006 6:49 pm

This effect can be done without any shaders.
You can use scale (a modified scale that scales in the direction of the normal) and color change.

I guess it can be modified so it will work on any hardware that supports the stencil buffer.
0 x
Watch out for my OGRE related tweets here.

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Post by Assaf Raman » Fri Dec 29, 2006 7:52 pm

Ajare: To disable the effect - just detach the glow entity from the node.

For outline glow:

Code: Select all

actualOutlineGlowNode->detachObject(actualOutlineGlowEntity);
For full glow:

Code: Select all

alphaFullGlowNode->detachObject(alphaFullGlowEntity);
glowFullGlowNode->detachObject(glowFullGlowEntity);
To enable the effect re-attach the glow entity.
0 x
Watch out for my OGRE related tweets here.

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Post by jacmoe » Fri Dec 29, 2006 8:33 pm

What a great present! :D

This looks awesome and seems to be efficient and easy to use. Useful in many situations! Thanks! :)
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

broli
Halfling
Posts: 48
Joined: Fri Mar 31, 2006 5:08 pm

Post by broli » Fri Dec 29, 2006 11:11 pm

Assaf Raman wrote:This effect can be done without any shaders.
You can use scale (a modified scale that scales in the direction of the normal) and color change.
Why would you use the CPU and extra code with some nasty work arounds instead of a simple Ogre material+GPU method that everybody can use out of the box. This goes for alot of things that are made here on these forums.
0 x

Aiursrage2k
Greenskin
Posts: 120
Joined: Wed May 18, 2005 6:40 pm

Post by Aiursrage2k » Fri Dec 29, 2006 11:54 pm

Looks great. Are you able to change the color/thickness of the glow?
0 x

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Post by Assaf Raman » Sat Dec 30, 2006 1:44 am

You can very easily – just change it in the shaders. The shaders are very basic shaders and I think you can change them without any knowledge in shaders.
0 x
Watch out for my OGRE related tweets here.

User avatar
BRAINLESS
Goblin
Posts: 282
Joined: Tue Jan 04, 2005 6:56 pm
Location: The Netherlands

Post by BRAINLESS » Sat Dec 30, 2006 10:17 am

Assaf Raman wrote:You can very easily – just change it in the shaders. The shaders are very basic shaders and I think you can change them without any knowledge in shaders.
I agree, I have no knowledge of shaders and was able to change the workings of these 2 :) I ran up to a problem though, which your demo doesn't seem to suffer from. Perhaps that's because the Ogre model is more complex, but if I use a simple box model and this shader there's an obvious seam between the vertices of the glow. It looks a bit odd, so I'm going to try using a scaled scenenode instead.
0 x
Proud member of the OpenFRAG Game Development community

big_o
Goblin
Posts: 279
Joined: Sun Feb 19, 2006 1:08 am

Post by big_o » Sun Dec 31, 2006 2:39 am

Very cool, and very useful, I might be able to find a use for this down the road. :D

[edit] just noticed that it grows and shrinks, evenmore awesome! :)
0 x

Nakiks
Gnoblar
Posts: 15
Joined: Wed May 24, 2006 5:00 pm

urmmmm

Post by Nakiks » Wed Jan 03, 2007 3:04 pm

or just duplicate the mesh rescale & use another material with scene_blend add for the first head result and for the second just flip normals. Oldest trick in the book, way before shaders
0 x

jintal
Gnoblar
Posts: 4
Joined: Fri Nov 24, 2006 10:37 am

Post by jintal » Wed Jan 03, 2007 4:23 pm

BRAINLESS wrote:
Assaf Raman wrote:You can very easily – just change it in the shaders. The shaders are very basic shaders and I think you can change them without any knowledge in shaders.
I agree, I have no knowledge of shaders and was able to change the workings of these 2 :) I ran up to a problem though, which your demo doesn't seem to suffer from. Perhaps that's because the Ogre model is more complex, but if I use a simple box model and this shader there's an obvious seam between the vertices of the glow. It looks a bit odd, so I'm going to try using a scaled scenenode instead.
this problem also occurs with the robot.mesh. seems that the faces are translated a bit outward according to their normals only. so a right angle or close to one would have gaps in the glow.

i dont know how to do cg, anyone care to fix this? :D
0 x

User avatar
BRAINLESS
Goblin
Posts: 282
Joined: Tue Jan 04, 2005 6:56 pm
Location: The Netherlands

Post by BRAINLESS » Wed Jan 03, 2007 4:47 pm

I've asked around and apparently that's not possible with vertex shaders. I'm no expert though (this is my first experience with shaders :P) so I may be wrong :)
0 x
Proud member of the OpenFRAG Game Development community

User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
Contact:

Post by Falagard » Wed Jan 03, 2007 4:48 pm

It's not possible to fix without modifying the original mesh normals. The problem is that at angular seams in the mesh, normals usually point in different directions. This is because when you generate normals for a mesh in a 3d modeller you usually define an angular threshold for "smoothing" the normals - if the threshold is exceeded the normals will point in different directions at seams (otherwise your sharp corners would appear smooth-ish when you render them in Ogre). You could fix this by making an actual copy of the geometry and then smoothing all normals without this threshold, but it probably isn't worth it.

You can't do anything about this in a vertex shader because per vertex the shader doesn't know anything about the surrounding vertices, so you can't change the normal direction in the shader.

If you want to avoid this, you have to use the scale approach, instead of moving the verts out along their normals. You can do the scale inside a shader as well instead of calling setScale on the mesh. Also, you should get the center of the bounding box and pass it to the shader, then get the direction from this position to the vertex position and move the verts out along this vector. If you just pass a scale matrix and use the origin of the mesh, unless the origin is directly in the center of the mesh it will scale out in a less friendly manner.
0 x

User avatar
BRAINLESS
Goblin
Posts: 282
Joined: Tue Jan 04, 2005 6:56 pm
Location: The Netherlands

Post by BRAINLESS » Wed Jan 03, 2007 5:03 pm

So which one is better? Either way we'll have to move the vertices out from the center and multiply them by a scale matrix. Using a shader this would have to be done every frame, but that may not be a problem as it's done on the GPU. I don't know if setScale() is done on the GPU, but I expect it isn't... it would be a one-time-only job though.

With my limited experience I'd say option 2 (using setScale rather then a shader) would be more efficient...
0 x
Proud member of the OpenFRAG Game Development community

Post Reply