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);
}
}
之后,我生成像这样的索引值(我知道可以在这里进行很多优化) :
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();
最后我使用以下方式绘制平面:
gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);
所以如果我使用
POINTS
作为模式,飞机看起来应该是这样的:如果我使用的是
TRINGLE_STRIP
,结果看起来是错误的:首先我以为索引可能是错误的原因,但是随后我通过缩放到3x3的网格/平面进行了检查,顶点和索引的输出看起来像我期望的那样:
顶点:
[-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]
注:
顶点可能与您从上述循环中所期望的不完全对应。这是因为在循环之后,我将
mesh
居中放置在原点附近。
索引:我的猜测是问题是我正在逆时针推动三角形,这就是为什么我尝试启用剔除和深度测试,但是却无济于事的原因:
[0, 3, 1, 4, 2, 5, 8, 4, 7, 3, 6]
您猜猜是什么原因导致
TRIANGLE_STRIP
渲染错误?更新1:
根据@PaulHK的建议,我更改了索引创建循环两次将单个条的最后一个索引插入。
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);
对于3x3网格,它产生:
顶点:
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);
}
}
}
>索引:
[-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]
不幸的是,渲染的对象看起来仍然相同。
更新2:
我使用Diamond-square算法生成网格。这需要一个大小为
(2^n) + 1
的网格。即:
2、3、5、9、17、33、65、129、257、513 ...
也许这只是一个巧合,但在我看来,可以使用Update 1中的步骤正确显示大小为
3 - 129
的网格。对于大小为257及以上的网格,有错误。 :257x257似乎不正确:
#1 楼
这看起来像是您的indice缓冲区中16位截断的情况。对于257x257的网格,您将要处理65536个以上的顶点,因此您将需要使用32位索引缓冲区。>
gl.drawElements(gl.TRIANGLE_STRIP, buffers.numIndices, gl.UNSIGNED_SHORT, 0);
还要更改缓冲区分配代码以匹配此类型(Uint16Array-> Java的Uint32Array)。
评论
$ \ begingroup $
您可能要提到的是,在JavaScript / WebGL中,包含索引的数组必须是Uint32Array而不是Uint16Array。
$ \ endgroup $
– indexoutofbounds
18/09/10'9:19
$ \ begingroup $
感谢您的建议,我已经修正了答案。我想使答案语言不可知,因为这在任何GL实现中都可能发生。
$ \ endgroup $
–PaulHK
18/09/11在2:59
评论
您是否打算将其绘制为一条条?您应该将其绘制为一系列条带。仍然可以在1个绘制调用中完成此操作,但是您需要在每个带状列的末尾插入一个退化的三角形(复制最后一个顶点)。@PaulHK对于3x3的飞机,它应该是[0、3、1、4、2、5、5、8、4、7、3、6],对吗?但它似乎仍然无法正常工作。
它应该是[Col(n),Col(n)+ 1,Col(n + 1),Col(n + 1)+ 1,Col(n + 2),Col(n + 2)+1,.. .. Col(n + 8)+1,Col(n + 8)+1] ..因此,对于每对索引,我们为当前列取一个顶点,从其相邻列取一个顶点,这与您的带区相同。最后,我们插入一个重复的顶点,这将创建一个退化的三角形。这将导致下一组带状索引开始新的带状,而没有任何三角形连接到最后一列。
computergraphics.stackexchange.com/questions/3746/…
好的,有趣的3x3版本有效,而257x257无效。您是否正在使用16位索引?因为您只能使用16位索引来寻址256x256。对于您的情况,您需要使用32位索引。