Outline shader

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
mdoublej
Gnoblar
Posts: 2
Joined: Fri Jul 17, 2009 3:09 pm

Outline shader

Post by mdoublej »

Hi , everyone,

Can anyone suggest me the best way to achieve an outline effect looks like this:

Image

thanks in advance!
bharling
Gremlin
Posts: 166
Joined: Fri Jun 30, 2006 1:04 pm

Re: Outline shader

Post by bharling »

probably in a compositor:

render the scene normally
render just the characters with coloured materials ( use a renderqueue group )
blur that rendertarget
render that onto the final image, using the previous stencil buffer to get the outlines of the characters.

bet there are other better ways to do it though?
Was here
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 49

Re: Outline shader

Post by madmarx »

Here is a try :

first pass : draw your model with depth write off, depth check off. cull_software none. cull_harware none.
add a vertex shader :
original2DPos = calculate the projected position of vertex in screen space
new3DPos = move the input position along the normal of the vertex (in object space) (it will bigger slightly the model along it's normal).
new2DPos = calculate the projected position of new3DPos in screen space
DiffPose = calculate abs(original2DPos -new2DPos)
OutputColorAlpha = clamp between 0 and 1 ( somecoeff * 1.0-DiffPose ) => that way, the vertex on the silhouette will be more transparent than those facing, but because of no cull, the interior of the mesh should be more visible.
OutputColor = RGB,OutputColorAlpha
OutputPosition = new2DPos

second pass :
draw your model on top of this.

I suppose you would get an effect not far from the one that is shoot, with the difference that the outlines seen through the walls would be drawn without knowing which one is before/next the other, and the whole outilne of the seen through wall would be filled.
If you don't want it to be filled, I suppose the whole thing is highly doable in geometry shader, though I have not much time / experience on this to do a try.

I think you can find other example on the forum of such effect, done with the stencil buffer.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
mdoublej
Gnoblar
Posts: 2
Joined: Fri Jul 17, 2009 3:09 pm

Re: Outline shader

Post by mdoublej »

yop,

Thanks a lot for your answers.
I haven't yet tried the first solution, but the second looks pretty good! (otherwise, either I don't understand for the alpha colour, or I haven't yet found the correct coef... i should enable a scene_blend option in material?)

When I tried to make this effect, I used the back faces but i forgot to disable the depth_write and depth_check options , so I saw all outlines, in the middle too... (stupid :D )
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 49

Re: Outline shader

Post by madmarx »

Yes, i forgot to mention :
scene_blend alpha_blend
should do the trick.

Funny is that I have never done this effect myself. So this is pure guessing/trying.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 49

Re: Outline shader

Post by madmarx »

Ok, I tried it, and it does not work, because dependent of screen space dimension.
I will re-try it by using the orientation of the normal to determine the alpha.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
nikki
Old One
Posts: 2730
Joined: Sat Sep 17, 2005 10:08 am
Location: San Francisco
x 13
Contact:

Re: Outline shader

Post by nikki »

Luckily, the work's already done:-
Linky
Vectrex
Ogre Magi
Posts: 1266
Joined: Tue Aug 12, 2003 1:53 am
Location: Melbourne, Australia
x 1
Contact:

Re: Outline shader

Post by Vectrex »

nikki wrote:Luckily, the work's already done:-
Linky
and luckily it was updated here to be even better ;) http://www.ogre3d.org/forums/viewtopic.php?p=194816
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 49

Re: Outline shader

Post by madmarx »

The link is interesting, but there is no good solution with alpha (as seen in the thread posted by Nikki).
Without alpha, this would be to easy :lol: (this is a joke). For example :

in Madmarx_outline.cg

Code: Select all

void outline_vp(float4 position : POSITION,
				float4 normal : NORMAL,
				out float4 oPosition : POSITION,
				out float4 oColour    : COLOR,
				
				uniform float4x4 worldViewProj)
{
	float4 position3Dnew = position - normal*0.2; // size of the outline
	float4 position2DOld  = mul(worldViewProj, position);
	oPosition = mul(worldViewProj, position3Dnew);
	
	float4 diff = abs(position3Dnew - position2DOld);
	float squaredDist = dot(diff,diff);
	
	// now set the colour of the outline
	oColour = float4(0.8,1,1,1.0);
}
and then the material :
_madmarx_outline.material

Code: Select all

vertex_program madmarxOutline_vp cg
{
	source Madmarx_outline.cg
	entry_point outline_vp
	profiles arbvp1
	default_params
	{
		param_named_auto worldViewProj worldviewproj_matrix
                // this one was when I was projecting the normal in screen space to do the alpha effect. It was working OK, but not on the ears of the ogrehead.
		//param_named_auto worldViewIT inverse_transpose_worldview_matrix 
	}
}

// this could have been done with an abstract pass for more clarity, but this is just an example ...
material madmarxOutLine
{
	technique
	{
		pass
		{
			scene_blend alpha_blend
			cull_hardware none
			cull_software none
			depth_write off
			depth_check on
			vertex_program_ref madmarxOutline_vp
			{
			}
		}
		
		pass
		{
			// just to get an idea
			// put your pass here...
			emissive 0.973 0.043 0.043
		}
	}
}
With RTT, the effect is simplier to do(with alpha), but it will use far more resources.

I think the optimal would be to use a geometry shader to generate the 'strips of glow' around the mesh, adding a new UV coord on the whole mesh, that would allow the use of a 1D tex to manipulate the alpha on the silhouette of the original character. This would allow rendering in only 1 pass (fast), but it is by far the hardest to code IMHO.

The best tests I have done with alpha give :

Code: Select all

void outline_vp(float4 position : POSITION,
				float4 normal : NORMAL,
				out float4 oPosition : POSITION,
				out float4 oColour    : COLOR,
				
				uniform float4x4 worldViewIT,
				uniform float4x4 worldViewProj)
{
	float4 position3Dnew = position - normal*0.2; // it depends on your normal highly
	float4 position2DOld  = mul(worldViewProj, position);
	oPosition = mul(worldViewProj, position3Dnew);
	
	float3 normalViewSpace = mul(worldViewIT,normal);
	float alpha = clamp(normalViewSpace.z*normalViewSpace.z,0.0,1.0);
	
	// now calculate the colour
	oColour = float4(1,1,1,alpha);
}
But this is not homogeneous. For example the ears of the Ogre are to bright because it is very sharp edges.

The setLineWidth technique is another possibility (cf nikki link), because if I remember correctly, you can draw with setting aliasing on the Line. I suppose this would slow thougth depending on the graphic card, because these techniques are said to be often emulated in the drivers.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
nikki
Old One
Posts: 2730
Joined: Sat Sep 17, 2005 10:08 am
Location: San Francisco
x 13
Contact:

Re: Outline shader

Post by nikki »

Vectrex wrote:
nikki wrote:Luckily, the work's already done:-
Linky
and luckily it was updated here to be even better ;) http://www.ogre3d.org/forums/viewtopic.php?p=194816
I think there he's simply scaling the model up instead of moving the vertices along normals.

EDIT: Yeah, he fixes that later, didn't change the first post screenshots though...

Maybe you could accumulate all glow objects on a single texture (each time multiplying by its own black sillouette to lose the 'inside' parts), then apply a small blur compositor and then render it.
Post Reply