0

I'm working on a heightmap algorithm using webgl. I thought I had it working but I realised a critical problem with my grid generation. If I set my grid size > 128 iterations, something strange happens: the grid stops growing on the z axis and I end up with a rectangular instead of a squared grid.

This is the code I'm using:

/*
v1---v0
|   / |
|  /  |
| /   |
v2---v3
*/
var size = 5;        // max size of terrain
var width = 128;     // texture width
var l = size/width;
this.vertices = [];

for(var j=0; j<width; j++){                             // y
    for(var i=0; i<width; i++){                         // x
        var p0 = new Point3D(l*(i+1), 0, l * (j+1));    // Upper right
        var p1 = new Point3D(l*i, 0, l * (j+1));        // Upper left
        var p2 = new Point3D(l*i, 0, l * j);            // Bottom left
        var p3 = new Point3D(l*(i+1), 0, l * j);        // Bottom right

        var base = this.vertices.length/3;              

        this.vertices.push(p0.x, p0.y, p0.z);       // v0
        this.vertices.push(p1.x, p1.y, p1.z);       // v1
        this.vertices.push(p2.x, p2.y, p2.z);       // v2
        this.vertices.push(p3.x, p3.y, p3.z);       // v3


        // Add indices
        this.indices.push(base);            // 0
        this.indices.push(base+1);          // 1
        this.indices.push(base+2);          // 2

        this.indices.push(base);            // 0
        this.indices.push(base+2);          // 2
        this.indices.push(base+3);          // 3
    }
}

/*** Later in my draw method: *****/
{....}
gl.drawElements(gl.LINE_STRIP, this.mesh.vjsBuffer.numItems, gl.UNSIGNED_SHORT, 0);

If I use size=128 it works fine; this is the result (the big vertical 'line' represents 0, 0, 0):

Image1: http://goo.gl/TxfM0R

The problem comes when I try to use a 256x256 or any higher image size:

Image2: http://goo.gl/12ZE4U

Notice how the image in the middle stopped growing in the z axis!

After some trial and error, I discovered that the limit is 128. If I use 129 or higher, the grid stops growing and starts shrinking.

genpfault
  • 51,148
  • 11
  • 85
  • 139
alx
  • 71
  • 8

1 Answers1

3

I finally found out what the issue was. It turns out that WebGL has a limit of 65536 indices per ELEMENT_ARRAY_BUFFER. So if you try to load objects with a lot of vertices it will result in unexpected behaviours.

There seems to be a couple solutions to solve this issue:

1) enable the gl extension "OES_element_index_uint" and use Uint32Array when you bind your index buffer.

2) Split your Mesh into chunks and render 1 at the time

3) Don't use gl.drawElements but gl.drawArrays instead.

I ended up using the 3rd alternative. Bear in mind that this may not be the most efficient way, as you need to define the same vertex multiple times.

The result now is a good looking terrain (after calculating normals and applying lighting): http://goo.gl/EhE815

alx
  • 71
  • 8