vertices: array[ m * n ] m*n-m ... m*n-1 -------------------------- | (j+1)*m+i (j+1)*m+i+1 | | j *m+i j *m+i+1 | 0 <= j < n -------------------------- 2m .... 3m-1 [...2m] m m+1 m+2 .... 2m-1 [... m] 0 1 2 3 4 .... m-1 [... 0] 0 <= i < m d--c | /| |/ | a--b If we are replicating the same vertex value on left and right columns: face: array [ 2 * (m-1) * (n-1) ] faces = []; for (var j = 0 ; j < n-1 ; j++) for (var i = 0 ; i < m-1 ; i++) { var a = j * m + i; var b = j * m + i + 1; var c = (j+1) * m + i + 1; var d = (j+1) * m + i; faces.push( [ a, b, c ] ); faces.push( [ c, d, a ] ); } If we are NOT replicating the same vertex value on left and right columns: face: array [ 2 * m * (n-1) ] faces = []; for (var j = 0 ; j < n-1 ; j++) for (var i = 0 ; i < m ; i++) { var a = j * m + i; var b = j * m + (i + 1) % m; var c = (j+1) * m + (i + 1) % m; var d = (j+1) * m + i; faces.push( [ a, b, c ] ); faces.push( [ c, d, a ] ); } Wrap both ways (eg: Torus): face: array [ 2 * m * n ] faces = []; for (var j = 0 ; j < n ; j++) for (var i = 0 ; i < m ; i++) { var a = j * m + i; var b = j * m + (i + 1) % m; var c = ((j+1)%n) * m + (i + 1) % m; var d = ((j+1)%n) * m + i; faces.push( [ a, b, c ] ); faces.push( [ c, d, a ] ); } Vertex = { point : [x,y,z], normal: [x,y,z], uv : [u,v], };