Fast Silhouettes Article

Started by
18 comments, last by Jason Z 17 years, 6 months ago
have u all guys actually seen Silhouette Textures by M$? Fastest ever, on GPU too.

regards
Edwin
Advertisement
I ran the demo and I noticed that there are some internal lines being marked as edges. Probably if its only for edges though, but seriously, these "lines" are not some of the type of silhouettes that some algorithms actually needed.

For example, there are 2 beams in the demo that forms a corner. Because the algorithm tries to follow the actual silhouette definition, the surfaces between the 2 beams that form the corner will have a line marked. But those surfaces have approximately the same surface normals since I could see that the surfaces try to touch each other.

So far, I am using the per-pixel method but with an Early-Z pass to kill off >98% of the fragments before executing a very expensive silhouette detection filter.

There are 2 other things I tried to look out in your algorithm (which I needed):
a)Are silhouettes marked only on occluding surfaces?
b)Is a there a way to directly compute a silhouette tangent?

Edwin
Quote:Original post by Jason Z
Thanks a bunch for the demo - I will have to dig into the code later on tomorrow. Did you ever adapt your method to be able to render ridges and valleys as well? This was one of the main drivers behind my implementation - to be able to render ridges, valley, and silhouettes all at once.

Thanks again for the post, I'll give you some feedback on it as soon as I can.


No, I never did. I was only trying to get true silhouettes. But I assume ridges an d valleys just have a different cutoff point for not rendering. For those the fixed-width line might become a problem though.

I did another search for the article I mentioned, and it *might* be the article in ShaderX. That article does require more than just a single added vert though, so either I'm mistaken, or it's not the article I was thinking about. They use the 0.f/1.f trick for extruding the fins though.
Quote:Original post by edwinnie
I ran the demo and I noticed that there are some internal lines being marked as edges. Probably if its only for edges though, but seriously, these "lines" are not some of the type of silhouettes that some algorithms actually needed.

For example, there are 2 beams in the demo that forms a corner. Because the algorithm tries to follow the actual silhouette definition, the surfaces between the 2 beams that form the corner will have a line marked. But those surfaces have approximately the same surface normals since I could see that the surfaces try to touch each other.

So far, I am using the per-pixel method but with an Early-Z pass to kill off >98% of the fragments before executing a very expensive silhouette detection filter.

There are 2 other things I tried to look out in your algorithm (which I needed):
a)Are silhouettes marked only on occluding surfaces?
b)Is a there a way to directly compute a silhouette tangent?

Edwin
Is this directed to me or to rick appleton?

well, your demo, off course =)
I am not really clear on what issues you have found - maybe you could post a screenshot with the area highlighted that you think is in error?
ok, but first, can u update ur demo to show different colors for silhouettes, ridges, and valleys. I need to be sure that what I saw in error is not a ridge nor valley first.

regards
Edwin
Hello Edwin. Replace the 'Edge_Mesh.fx' file in the Data/Effects folder with the following text file:

//-----------------------------------------------------------------------------// Edge_Mesh.fx////-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// Parameters//-----------------------------------------------------------------------------float4x4 Transform : WorldViewProjection;float4x4 ModelWorld : World;float4 CamPosition : ViewPosition;float4 scale : ViewParm0 = float4(0.1,0.1,0.1,0.1); //-----------------------------------------------------------------------------// Structures//-----------------------------------------------------------------------------struct vertex{    float3 position	: POSITION;    float3 normal   : NORMAL;    float3 tangent  : TANGENT;	float  ridge    : TEXCOORD0;};//-----------------------------------------------------------------------------struct fragment{    float4 position : POSITION;	float4 color    : COLOR;};//-----------------------------------------------------------------------------struct pixel{	float4 color : COLOR;};//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// Vertex shaders//-----------------------------------------------------------------------------fragment VS( vertex IN ){    fragment OUT;	float4 WorldPos = mul( float4(IN.position, 1), ModelWorld );	float3 P = WorldPos.xyz; 		float3 N = mul(IN.normal, (float3x3)ModelWorld);	// world space face 1 normal	float3 T = mul(IN.tangent, (float3x3)ModelWorld);	// world space face 2 normal	float3 E = P - CamPosition.xyz;				// un-normalized world space eye to position	OUT.color = 0;	float EdotN = dot(E,N);		// positive for forward facing, negative for back facing	float EdotT = dot(E,T);		// positive for forward facing, negative for back facing	//float extend = 0.1 * (length(E) / 75);	float extend = scale.x * (length(E) / 75);	float3 newPos = IN.position + IN.normal * extend;	if ( ( EdotN * EdotT ) < 0 )		// silhouette detection	{		OUT.color.a = 1;			// make this visible		OUT.color.rgb = float3( 0, 1, 0 );		if ( EdotN > 0 )			// extend only the front facing vertices		{					// in the opposite direction			newPos = IN.position-IN.normal*extend;		}	}	OUT.color.a += IN.ridge;		// set visibility for ridges and valleys (pre-computed)	OUT.position = mul( float4( newPos, 1), Transform );	// output the final vertex position	return OUT;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// Pixel Shader//-----------------------------------------------------------------------------pixel PS( fragment IN ){	pixel OUT;	OUT.color = IN.color;	return OUT;}//-----------------------------------------------------------------------------// Techniques//-----------------------------------------------------------------------------technique EdgeMesh{    pass P0    {		AlphaTestEnable = true;		AlphaRef = 0x00000001;	      AlphaFunc = Greater;		VertexShader = compile vs_1_1 VS();		PixelShader  = compile ps_1_1 PS();    }}//-----------------------------------------------------------------------------

That essentially just writes a color whenever a silhouette edge is detected. Let me know if you still see a problem... [grin]
ok, here's the image with the problem:
Free Image Hosting at www.ImageShack.us

The small red arrows are pointing to the part of the green lines. That part is not a silhouette.

regards
Edwin
Yes, I see now. This was actually intended when I created the model. That section is a welded cross section on a machine that I was modelling, and it was desired to have it stand out as a separate piece. This could be eliminated by changing the MS3D file to have those two planes share vertices in that corner.

Sorry - that was my fault for not clearing that up sooner...

This topic is closed to new replies.

Advertisement