From the vertex id (simple GPU counter), we retrieve the cell position.

To normalize it (eg: fit in 0/1), we simply multiply by inverse resolution

We flip Y axis (for uv only)

Recenter positition (so our grid center is in 0,0 not in 0.5,0.5)

Done, that was so hard... :)

Now we need to generate our indices (since some vertices are shared).

We have few options here:

Set our Stream Output as triangle: This is not convenient at all, since grid geometry is quad based, so we'll need to replicate a lot of calculations, and flip triangle depending on vertex id, which is not very friendly.

Set our Stream Output as Quad: Instead of generating one triangle at a time in Vertex Shader, we will generate 2, which fits perfectly a cell expansion, and reuse calculations.

So obvious choice, quads

Here is our Vertex Shader output:

Code Snippet

struct vsOutputIndices

{

int3 t1 : TRIANGLE0;

int3 t2 : TRIANGLE1;

};

And the (extremely) hardcore Vertex Shader:

Code Snippet

vsOutputIndices VS_Indices(vsInput input)

{

vsOutputIndices o;

int j = input.iv / (colcount-1);

int i = input.iv % (colcount-1);

int rowlow = j * (colcount);

int rowup = (j+1) * (colcount);

o.t1 = int3(rowlow + i, rowup + i, rowlow + i + 1);

o.t2 = int3(rowlow + i + 1, rowup + i, rowup + i + 1);

return o;

}

Here we do more or less the same as generating positions, excluding we need to take care or row/column indices stride.

Here we are, generating a Grid without CPU.

Nice thing about it is since other geometries can also be interpreted as a parametric surface, we can easily modify shader to generate them (only shader to generate vertices needs modifications, index buffer builder is the same).