#StackBounty: #webgl Problems rendering a plane via `drawElements`

Bounty: 50

I am generating plane vertices where the y values are generated by a heightmap (noise) algorithm. This is how I produce my vertex array:

for (let row = 0; row < noise.length; row++) {
    for (let col = 0; col < noise[0].length; col++) {
        color = noise[row][col];
        positions.push(row, color, col);
    }
}

After that I generate index values like this (I know that there is a lot of optimization that can be done here):

const height = noise.length + 1;
const width = noise[0].length + 1;

for (let row = 0; row < height - 1; row++) {
    if (row % 2 === 0) {
        if (row === height - 2) break;
        for (let col = 0; col < width - 1; col++) {
            indices.push(col + row * (width));
            indices.push(col - 1 + (row + 1) * (width));
        }
    } else {
        for (let col = width - 2; col >= 0; col--) {
            indices.push(col - 2 + (row + 1) * (width));
            indices.push(col - 2 + row * (width));
        }
    }
}

indices.pop();

Finally I draw the plane using:

gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);

So if I use POINTS as mode, the plane seem to look as it should:

enter image description here

Whereas if I am using TRINGLE_STRIP the result looks wrong:

enter image description here

First I thought wrong indices might be the reason but then I checked by scaling to a 3×3 grid/plane and the vertex and index output looked as I would have expected:

Vertices:

[-1, -43.89, -1, 
-1,  -82.27,  0, 
-1,  -23.06,  1, 
 0,  -43.43, -1, 
 0,  -54.85,  0, 
 0,  -66.27,  1, 
 1,  -61.89, -1, 
 1,  -27.43,  0, 
 1,  -59.89,  1]

Note:

The vertices might not exactly correspond to what you would have
expected from above loop. That is because I am centering the mesh
around origin after the loop.

Indices:

[0, 3, 1, 4, 2, 5, 8, 4, 7, 3, 6]

So my guess is that the problem is that I am pushing my triangles counterclockwise, that is why I tried to enable culling and depth testing but that did not help either:

gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);

enter image description here

Any guess what might be the reason for wrong TRIANGLE_STRIP rendering?

Update 1:

According to @PaulHK’s recommendation I changed my index creation loop to insert the last index of a single strip twice.

for (let row = 0; row < rows - 1; row++) {
    if (row % 2 === 0) {
        for (let col = 0; col < cols; col++) {
            indices.push(col + row * cols);
            indices.push(col + (row + 1) * cols);
        }
    } else {
        for (let col = cols - 1; col >= 0; col--) {
            indices.push(col + (row) * cols);
            indices.push(col + (row + 1) * cols);
        }
    }
}

For a 3×3 grid this produces:

Vertices:

[-1, -9.6, -1,
 -1, -64.6, 0,
 -1, -11.1, 1,
 0, -38.8, -1,
 0, -32.8, 0,
 0, -26.8, 1,
 1, -37.0, -1,
 1, -1, 0,
 1, -47.5, 1]

Indices:

[0, 3, 1, 4, 2, 5, 5, 8, 4, 7, 3, 6]

Unfortunately the rendered object still looks the same.

Update 2:

I use the Diamond-square algorithm to generate the mesh. This requires a grid of size (2^n) + 1.
I.e.:

2, 3, 5, 9, 17, 33, 65, 129, 257, 513 …

Maybe it’s just a coincidence but it seems to me that the grid can be displayed correctly for sizes 3 - 129 with the procedure from Update 1. For a size of 257 and above the mesh has errors.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.