Geom. shader, almost there?

Started by
4 comments, last by cozzie 8 years, 2 months ago

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);

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

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?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

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.

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.
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'

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

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

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement