什么是索引缓冲区?它与顶点缓冲区有何关系?


11

我有一个这样的顶点缓冲区:

0.0, 0.0,
1.0, 0.0,
0.0, 0.6,
1.0, 0.6,
0.5, 1.0

我有以下索引缓冲区:

0, 2,
2, 4,
4, 3,
3, 2,
2, 1,
1, 0,
0, 3,
3, 1

我知道我想gl.LINES使用WebGL 进行绘制,这意味着多个分开的线段。

gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, indexBuffer);

似乎可以在WebGL的一次绘制调用中绘制多个线段。

有人可以给我ELI5吗?什么是索引缓冲区?它与顶点缓冲区有何关系?如何从我的原语生成索引缓冲区?

Answers:


12

有人可以给我ELI5吗?什么是索引缓冲区?它与顶点缓冲区有何关系?

您的顶点缓冲区包含5个顶点的X和Y坐标。他们是:

index |  X  |  Y
  0   | 0.0 | 0.0 
  1   | 1.0 | 0.0
  2   | 0.0 | 0.6
  3   | 1.0 | 0.6
  4   | 0.5 | 1.0

您的索引缓冲区包含有关在这些顶点之间绘制哪些线的信息。它使用顶点缓冲区中每个顶点的索引作为值。

由于您正在绘制线,因此索引缓冲区中的每对连续值都表示一条线段。例如,如果索引缓冲区以开头0, 2,则意味着在顶点数组的第0个顶点与第2个顶点之间绘制一条线,在这种情况下,这将绘制一条从[0.0, 0.0]到的线[0.0, 0.6]

在下面的图形中,每对索引与它指示的线进行颜色协调:

在此处输入图片说明

同样,如果您绘制的是三角形而不是直线,则需要提供一个索引缓冲区,其中每个3个连续值表示顶点缓冲区中三个顶点的索引,例如

0, 1, 2,
2, 1, 3,
2, 3, 4,

5

如果您有一个这样的顶点缓冲区:

var vertices = [
  0.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.5, 1.0, 0.0
]

并按原样绘制:

// Create an empty buffer object
var vertex_buffer = gl.createBuffer();

// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 5);

每个线段都需要两个专用坐标。使用上述vertices定义,只能绘制两条线

两行

如果定义了以下索引:

var indices = [
  0, 2,
  2, 4,
  4, 3,
  3, 2,
  2, 1,
  1, 0,
  0, 3,
  3, 1
]

可以一次又一次地绘制与相同顶点相交的线。这减少了冗余。如果您绑定索引缓冲区并告诉GPU按照indecies数组中指定的顺序绘制连接顶点的线段:

var index_buffer = gl.createBuffer();

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

// draw geometry lines by indices
gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, index_buffer);

一个人可以绘制更复杂的图形,而不必一遍又一遍地重新定义相同的顶点。结果如下:

一个房子

要获得没有索引的相同结果,顶点缓冲区应如下所示:

var vertices = [
  0.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.5, 1.0, 0.0,
  0.5, 1.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.0, 0.0
]

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 16);

结果相同的图像:

另一个房子

注意存储的顶点中的大量冗余。


2
如果您打算立即回答自己的问题,请至少在问题中提及该问题,以免其他人浪费时间。
Rotem

2
每个好的问题应该有2或3个好的答案。您没有浪费时间,我非常感谢您的努力。我需要此线程向项目合作伙伴解释逻辑,您的帖子将极大地帮助他。
AFR

1
@ 5chdn 强烈建议自己回答。感谢您添加此答案。如果您在发布问题时牢记一个答案,则问题下方会有一个勾号框,可让您在发布问题之前写下您的答案,因此两者将同时出现。这只是为了让您知道它是否有用-您当然不需要这样做,并且在发布问题后的任何时间间隔仍然非常欢迎您提供自我答案。
trichoplax
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.