5

私は OpenGL ES 2.0 (Webgl) にコーディングしています。VBO を使用してプリミティブを描画しています。頂点配列、色配列、およびインデックスの配列があります。サンプル コード、書籍、チュートリアルを見てきましたが、得られないことが 1 つあります。頂点ごとに色が定義されている場合、それらの頂点に隣接するポリゴン サーフェスにどのように影響しますか? (私は OpenGL(ES) の初心者です)

例を挙げて説明します。描画する立方体があります。OpenGLESの本で読んだことから、色は頂点属性として定義されています。その場合、立方体の 6 つの面を 6 つの異なる色で描画したい場合、どのように色を定義すればよいでしょうか。私の混乱の原因は次のとおりです。各頂点は 3 つの面に共通ですが、頂点ごとに色を定義するのにどのように役立つのでしょうか? (または、インデックスごとに色を定義する必要がありますか?)。これらの面を三角形に分割する必要があるという事実は、この関係がどのように機能するかを理解するのを難しくしています. 同じ混乱がエッジにも当てはまります。三角形を描く代わりに、LINES プリミティブを使用してエッジを描きたいとしましょう。異なる色の各エッジ。その場合、色属性をどのように定義すればよいですか?

実際の例はほとんど見たことがありません。具体的には、このチュートリアル: http://learningwebgl.com/blog/?p=370

上記の例で、6 つの異なる色の面を持つ立方体を描画するために色配列がどのように定義されているかがわかりますが、そのように定義されている理由がわかりません。(たとえば、各色が unpackedColors に 4 回コピーされるのはなぜですか?)

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;
4

2 に答える 2

9

私が好んで見ているのは、各頂点は空間内の点ではなく、属性の束であるということです。これらには一般に (必ずというわけではありませんが) その位置含まれ、色、テクスチャ座標などが含まれる場合もあります。頂点ごとの値を線形補間することにより、各ピクセルの各属性。

Liam が言うように、そしてコメントで気づいたように、これは、複数のプリミティブの頂点 (立方体の角など) で使用される空間内のポイントが必要な場合、他の非-位置属性はプリミティブごとに異なるため、属性の組み合わせごとに個別の頂点が必要です。

これはある程度メモリを浪費しますが、他の方法で行うと複雑になるため、事態はさらに悪化し、グラフィックス ハードウェアはデータのアンパックと再パックにより多くの作業を行う必要があります。私には、無駄は、使用したいすべての色の「パレット」ルックアップテーブルを保持し、単に保存する代わりに、ビデオメモリの各ピクセルに 32 ビット RGBA 値を使用することによって得られる無駄に匹敵するように感じます。そのピクセルごとにインデックスを作成します (もちろん、これは RAM がより高価だったときに私たちが行っていたことです)。

于 2010-05-06T16:13:18.023 に答える
3

ポリゴンのセットの色が同じである場合、すべてのポリゴンで共有される頂点とその色を一度定義して、ポリゴンで共有することができます(インデックスを使用)。

ポリゴンの色が違うと、頂点の位置は共通していても色が違うので、頂点全体を共有することはできません。各ポリゴンの頂点を定義する必要があります。

于 2010-05-06T09:16:48.867 に答える