 # manipulation of primitives in shader

I’m drawing some triangles like so:
graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, theVertices, 0, theVertices.Length / 3);

Can a custom shader (vs_4_0 and ps_4_0) re-orient one or more of the triangles (i.e. make them face the camera directly)?

Yes, the vertex shader can do that. I’m not the best with shaders, but they basically work like this:

1. The vertex shader is run for each vertex, taking your VertexDeclaration (usually some combination of Position, Normal, Texture Coordinates, Color) as input, and producing vertex output (Position + any custom info like Normal, Color, Position in a different reference frame).
2. The pixel shader is run for each pixel of the triangle, taking the input from the vertex shader output (Position, Normal, etc.) interpolated between the values for the corner vertices, and producing a Color.

So the easiest way to re-orient your triangles is to do some transformation in the vertex shader based on the normal and the camera position. If you only want to reorient some triangles with this shader, then maybe also set a flag in the shader per mesh, or even a flag on the VertexDeclaration per triangle.

Thanks for your explanation, jnoyola.

Since the Vertex shader is operating on one vertex at a time, how can it see the other two vertices in order to compute the normal?

It cannot. Usually you’ll want to compute the normal in advance and have your VertexDeclaration include the Position and the Normal.

Note that although each computation may be slower to perform on the CPU, you’ll only need to do it 1/3 as many times since you can compute once per triangle and assign to all 3 vertices.

The way you do this is you make your quad or triangle as you would normally so that it is aligned with x y plane then you use Matrix.CreateBillBoard you pass to the shaders World matrix before drawing the quad or triangle this then orients the world plane of the triangle or quad to the camera.

There are a couple different createbillboards calls you can use.

Something like this could be done on the vertex shader to displace the vertices based on distance from a world position but it would likely make no sense to do so as well as distort the geometry poorly for 3d models it makes no sense at all whatsoever. As well it would probably require extra data per vertex and possibly extra parameter variables sent in just prior to drawing in 2d ect…