# Why are triangle fans not supported in Direct3D 10 or later?

As covered in the documentation, triangle fans not supported in Direct3D 10 or later.

Why? Are there inherent drawbacks to working with triangle fans?

• My understanding is that because triangle fans often result in very skinny long triangles resulting in interops causing artifacts. Also I think it requires separate draw calls to render any tries that are not connected with a fan. Where as its possible with a Strip. I don't think there is anything fans can do that strips can't do better. Sep 5 '12 at 5:14
• Fans can be connected using indexes so no separate calls needed. The same also applies to strips (and you can even connect fans with strips) which is much more flexible, doesn't require degenerate tris, and more lightweight in terms of bandwidth. Sep 5 '12 at 13:44

For well over a decade hardware vendors have been pushing triangle strips, indexed triangle lists and indexed triangle strips as the fastest primitive types to use. Why? Strips have better cache locality (reusing the last 2 verts submitted instead of having to continually jump back to the first one) and indexing allows hardware vertex caches to actually work, as well as being more effective for eliminating duplicate verts.

If all hardware vendors say "do it this way and you're going to be faster" then there's a pretty good chance that if you do it this way you actually will be faster.

So D3D10+ just formalizes this; if that's the fast path then that's the path you're going to use and other paths won't exist. This is in keeping with one of the design philosophies of D3D10+, which is to put you onto the fast path and keep you there.

I do not know how much this actually affects the development but as with any such changes, it's been told that they will let driver developers write better drivers. The complexity of GPU drivers is amazing but I'm not sure if this exact change will help much.

In either case, it's possible to replace triangle fans for most of your needs (like convex polygon rendering) with strips, often with better results.

// A simplified API interface is presented for the purposes of having readable pseudocode
// Push( pos ) - pushes position data to make a new vertex
// TRIANGLE FANS:
for( i = 0; i < vertices.count; ++i )
Push( vertices[ i ] );

// TRIANGLE STRIPS:
for( i = 0; i < vertices.count; ++i )
{
if( i % 2 == 0 )
vertex = i / 2;
else
vertex = vertices.count - 1 - i / 2;
Push( vertices[ vertex ] );
}


EDIT: forgot to mention - if you need to change winding order - just reverse the test in that "if" (== to !=).

(This particular question warrants an opinion answer:)

Subjectively, I'd say its architecture astronauticism. OpenGLES also threw-out lots of stuff to make it 'less complex' whilst actually just pushing complexity onto each and every developer with legacy code instead.

Of course, even when the hardware doesn't support it natively it would have been trivial to provide compatibility with people sequencing triangle fans by converting them to strips or triangles.

WebGL run-times and such have to keep track of validated buffers and such all the time, and drivers could easily manage people sending them fans despite them not supporting it.

So the whole throwing out of FFP and such is just a big annoyance IMO.

• 10 or more years ago this would have been a good answer. Today, the vertex pipeline is almost always implemented in hardware, and vertex data is more likely to be stored in buffer objects in GPU memory, so a hypothetical fan-to-strip implementation in a driver would require pulling the vertex data back to CPU memory for reordering, then reloading it to GPU memory. That not only wrecks the whole point of using buffer objects (since you no longer have static vertex data) but it requires a readback from GPU memory, so hello pipeline stalls and low performance. Nov 8 '12 at 17:09
• @mh01 what hardware doesn't support fan natively? The HW has to work with the full OpenGL after all...
– Will
Nov 10 '12 at 15:15
• The vertex data might be stored in the GPU memory, but it has to get there from the system memory somehow in the first place (at least once). That's through the driver. (Assuming the data originated CPU side, which, except for specialized hardware demos, it almost always does). Apr 27 '14 at 9:39