Sign in to follow this  

Geom. shader, almost there?

This topic is 679 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all,

I'm trying to 'extrude' 4 sides of a cube, from a linestrip with 4 vertices.

After playing around I think I'm almost there, but I'm missing something crucial.

 

This is what I do:

- create 4 vertices (VTX buffer)

- draw them as a linestrip

- execute my Geometry Shader, taking line[2] as input and a trianglestream as output

 

The result so far is that 2 of the 4 sides of the extracted cube (without 'caps'/ top-bottom) are drawn correct.

It might be something with the normals, not sure.

 

Here's the code, can someone help me out?

[maxvertexcount(4)]
void GSStrip(line VertexOut gin[2], inout TriangleStream<GeoOut> stream)
{
	/* 4 vertices as input, 1 linestrip

	1	.-----------.	2		0 = -1, 0, -1
		|			|			1 = -1, 0,  1
		|			|			2 =  1, 0,  1
		|			|			3 =  1, 0, -1
	0	.-----------.	3

	create 4 new vertices 'above' 0 to 3 and draw sides of the cube using trianglestrips
	the input linestrip is dimension[2] -> meaning the GS processes 'per line' / 2 connected vertices

	2 .---------. 3
	  |			|		Y = up (2 and 3 are XZ == 0 and 1)
	  |			|
	0 .---------. 1

	Strip1: 2, 3, 0
	Strip2: 3, 0, 1

	*/
	float4 v[4];
	v[0] = float4(gin[0].CenterW, 1.0f);
	v[1] = float4(gin[1].CenterW, 1.0f);

	v[2] = v[0];
	v[2].y = 15.0f;

	v[3] = v[1];
	v[3].y = 15.0f;

	GeoOut gout;
	[unroll]

	for(int i = 0;i<4;++i)
	{
		gout.PosH     = mul(v[i], gViewProj);
		gout.PosW     = v[i].xyz;
		gout.NormalW  = float3(-1.0f, 0.0f, 0.0f);
		gout.Tex      = gTexC[i];
		
		stream.Append(gout);
	}
//	stream.RestartStrip();
}

// in the code, creating the vtx buffer
	vertices[0].Pos = XMFLOAT3(-5.0, 0.0f, -5.0f);
	vertices[1].Pos = XMFLOAT3(-5.0, 0.0f, 5.0f);
	vertices[2].Pos = XMFLOAT3(5.0, 0.0f, 5.0f);
	vertices[3].Pos = XMFLOAT3(5.0, 0.0f, -5.0f);

Share this post


Link to post
Share on other sites

Been thinking about it, could it be that the Geometry shader executes per 2 vertices, not knowing the others.

That could explain that sharing vertices will not work.

 

If so, wouldn't a linestrip be able to solve this in the first place?

Share this post


Link to post
Share on other sites

Sharing verts should work fine. Are you using an indexed line strip? Otherwise what are you doing to connect v0 to v3? Normal attributes being wrong won't stop the side from rendering unless you're discarding in your ps.

 

If you're using a line list then yeah it will use two verts at a time.

Edited by Dingleberry

Share this post


Link to post
Share on other sites
I'm not entirely sure, but it looks like you problem could be the winding order of your output. With triangle strips you have to swap the order for every other triangle. You can also just output as a triangle list by restarting your strip after every three vertices (but you will have to output 6 instead of 4). Here is some more info on topology in direct3d msdn.

You can also test this by turning off back face culling and seeing if all of your geometry becomes visible.

Share this post


Link to post
Share on other sites
Thanks both, I'll do the check on culling tonight.

In the meantime I double checked, input type line is for both line lists and strips. In my code I've set the topology to linestrip, so I don't know where I might have accidentally used 'line list'

Share this post


Link to post
Share on other sites

I've tried disabling culling, now 3 out of 4 sides turn up.

The same result I achieve when drawing using 2 triangle lists (and a RestartStrip in between), with maxvertexcount[6].

Fixing the winding order for the strip also gives we 3 out of 4 sides of the cube now.

 

One conclusion of this is that the drawing order can indeed be an issue, I've tacked this now (using the initial Strip approach).

 

There's just one thing I don't understand, where's the 4th side?

Maybe I need to have the 1st vertex twice in the vtx buffer and use 5 vertices (ending with the one I started with).

 

Update: this does work. It seems all good now.

Now I should be able to change the 4 (/5) vertices into a list of vertices making up a circle. Using the same GS, that will finish the exercise I'm doing :)

Thanks for helping out

Edited by cozzie

Share this post


Link to post
Share on other sites

This topic is 679 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this