颜色属性如何在VBO中起作用?

Jay*_*esh 5 opengl-es webgl

我正在编写OpenGL ES 2.0(Webgl).我正在使用VBO来绘制基元.我有顶点数组,颜色数组和索引数组.我查看了示例代码,书籍和教程,但有一点我没有得到 - 如果每个顶点定义颜色,它如何影响与这些顶点相邻的多边形表面?(我是OpenGL(ES)的新手)

我将用一个例子来解释.我有一个立方体画.根据我在OpenGLES书中所读到的,颜色被定义为顶点属性.在这种情况下,如果我想用6种不同颜色绘制立方体的6个面,我应该如何定义颜色.我混淆的根源是:每个顶点对3个面都是通用的,那么它如何帮助定义每个顶点的颜色?(或者应该根据索引定义颜色吗?).我们需要将这些面细分为三角形的事实使我更难理解这种关系是如何工作的.边缘也是同样的混乱.不是绘制三角形,而是说我想用LINES原语绘制边.每个边缘都有不同的颜色.在这种情况下,我该如何定义颜色属性?

我见过很少的工作实例.特别是本教程:http://learningwebgl.com/blog/?p = 370

我在上面的例子中看到如何定义颜色数组以绘制具有6个不同颜色面的立方体,但我不明白为什么这样定义.(例如,为什么每种颜色都会被复制4次到unpackedColors中?)

有人可以解释颜色属性在VBO中是如何工作的吗?

[上面的链接似乎无法访问,因此我将在此处发布相关代码]

cubeVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
vertices = [
  // Front face
  -1.0, -1.0,  1.0,
   1.0, -1.0,  1.0,
   1.0,  1.0,  1.0,
  -1.0,  1.0,  1.0,

  // Back face
  -1.0, -1.0, -1.0,
  -1.0,  1.0, -1.0,
   1.0,  1.0, -1.0,
   1.0, -1.0, -1.0,

  // Top face
  -1.0,  1.0, -1.0,
  -1.0,  1.0,  1.0,
   1.0,  1.0,  1.0,
   1.0,  1.0, -1.0,

  // Bottom face
  -1.0, -1.0, -1.0,
   1.0, -1.0, -1.0,
   1.0, -1.0,  1.0,
  -1.0, -1.0,  1.0,

  // Right face
   1.0, -1.0, -1.0,
   1.0,  1.0, -1.0,
   1.0,  1.0,  1.0,
   1.0, -1.0,  1.0,

  // Left face
  -1.0, -1.0, -1.0,
  -1.0, -1.0,  1.0,
  -1.0,  1.0,  1.0,
  -1.0,  1.0, -1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW);
cubeVertexPositionBuffer.itemSize = 3;
cubeVertexPositionBuffer.numItems = 24;

cubeVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexColorBuffer);
var colors = [
  [1.0, 0.0, 0.0, 1.0],     // Front face
  [1.0, 1.0, 0.0, 1.0],     // Back face
  [0.0, 1.0, 0.0, 1.0],     // Top face
  [1.0, 0.5, 0.5, 1.0],     // Bottom face
  [1.0, 0.0, 1.0, 1.0],     // Right face
  [0.0, 0.0, 1.0, 1.0],     // Left face
];
var unpackedColors = []
for (var i in colors) {
  var color = colors[i];
  for (var j=0; j < 4; j++) {
    unpackedColors = unpackedColors.concat(color);
  }
}
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(unpackedColors), gl.STATIC_DRAW);
cubeVertexColorBuffer.itemSize = 4;
cubeVertexColorBuffer.numItems = 24;

cubeVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
var cubeVertexIndices = [
  0, 1, 2,      0, 2, 3,    // Front face
  4, 5, 6,      4, 6, 7,    // Back face
  8, 9, 10,     8, 10, 11,  // Top face
  12, 13, 14,   12, 14, 15, // Bottom face
  16, 17, 18,   16, 18, 19, // Right face
  20, 21, 22,   20, 22, 23  // Left face
]
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new WebGLUnsignedShortArray(cubeVertexIndices), gl.STATIC_DRAW);
cubeVertexIndexBuffer.itemSize = 1;
cubeVertexIndexBuffer.numItems = 36;
Run Code Online (Sandbox Code Playgroud)

Gil*_*mas 9

我喜欢看它的方式是每个顶点不是空间中的一个点,而是一组属性.这些通常(但不总是)包括其位置,并且可以包括其颜色,纹理坐标等等.通过指定一组顶点,然后生成值来定义三角形(或线或其他基元).每个像素的每个属性通过线性插值每顶点值.

正如Liam所说,正如你在评论中所认识到的那样,这意味着如果你想在一个顶点用于多个图元的空间中有一个点 - 例如,一个立方体的角 - 与其他非 - 位置属性在每个基元的基础上变化,每个属性组合需要一个单独的顶点.

这在某种程度上浪费了内存 - 但是以任何其他方式执行它所涉及的复杂性会使事情变得更糟,并且需要图形硬件执行更多的工作来解压缩和重新打包数据.对我来说,感觉浪费与我们通过在视频内存中为每个像素使用32位RGBA值而获得的浪费相当,而不是保留我们想要使用的每种颜色的"调色板"查找表,然后只存储一个索引到每像素(这当然是我们以前在RAM更昂贵时所做的事情).