【WebGL】GLSLの頂点シェーダー(vertexShader バーテックスシェーダー)と頂点データ(attribute,頂点属性)とは?

2023年11月28日WebGL & Three.js

WebGL(GLSL)を扱うときに必ずでてくる頂点シェーダー(vertexShader、バーテックスシェーダー)とは何か、何に使うのかについて説明します。
また、 attributeについても説明します。

頂点シェーダー(vertexShader、バーテックスシェーダー)とは

頂点シェーダー(vertexShader、バーテックスシェーダー)とは物体の頂点の位置を決定するためのプログラムのことです。
vertexは、頂点という意味の英語です。
具体的にはgl_Positionという特別な変数に格納された値が頂点の位置になります。
三角形なら3点の頂点の位置を決定するというイメージです。
それをGPUの特性を活かして、それぞれの頂点ごとに実行されます。

GPUの特性について、不明な場合は、WebGLとThree.jsの違いって何?を確認してみてください。

頂点の位置が決まるときの処理の流れ

JavaScriptから頂点データを転送して、GPU側に描画指示をします。
頂点シェーダが実行されます。たとえばJavaScriptで頂点数を3とした場合、3つの頂点の位置をgl_Positionに代入することでそれぞれの頂点の位置が決定されます。

頂点シェーダーのサンプルコード

attribute vec3 position;
void main() {
	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 0.6);
}

上のような形で頂点シェーダーを記述します。
物体の各頂点ごとに上の頂点シェーダのコードが実行されるという点は、頭に残しておいた方が後々わかりやすくなると思います。
上のgl_Positionという変数に代入された値が、最終的な頂点の位置となります。

positionは頂点データ

上のコードのpositionは、頂点データと言われ、頂点ごとに保持できるデータをさします。
つまり、頂点データ名です。
三角形なら、3点の頂点データがあります。

頂点データ(頂点属性)とは

頂点データ(attributes of vertices, 頂点属性)とは、頂点ごとに保持できる頂点の値のことです。
頂点シェーダそれぞれで異なる値を渡すときに使います。
attributeはWebGLにおいて、データを受け渡しする一つの方法です。
他にも、varyingやuniformがあります。

頂点データ(頂点属性)の特徴

頂点データは、ユーザーが定義することができます。
定義できるデータにはたとえばposition(位置座標)、color(色の情報)、normal(法線ベクトル)、uv(UV座標)などがあります。
normalは、法線という面を直行する線の情報が入っています。
UV座標というのは、テクスチャを読み込むことに必要な座標です。
position, uv, normalはすでにThree.jsで定義されていて使うことができます。
BoxGeometryなどのジオメトリのattributesの中にposition,normal,uvがあります。

また、頂点ごとに違う値を設定することができます。

attributeというキーワードで定義

頂点データ(属性)は、attributeというキーワードで定義します。

vec3は型の情報

vec3は、3つの要素を持つ変数(3次元のベクトルを持つ)として定義しています。

クリップ座標(クリップ領域)

WebGLの学習をすすめると、クリップ座標(クリップ領域、Clip Coordinates)という言葉を聞くようになります。
WebGLでブラウザに(canvas要素に)映し出される座標、領域のことです。
x軸、y軸、z軸それぞれを-1から1の範囲で指定します。
-1から1の範囲を超える値を指定した場合、たとえば2と指定すると、画面からその頂点は見えなくなりますが、-1から1の範囲は見える状態になります。

頂点位置決定後にフラグメントシェーダが実行

頂点位置決定後に、その後の処理であるフラグメントシェーダが実行されます。
フラグメントシェーダについては、フラグメントシェーダとはを参考にしてみてください。

まとめ

  • 頂点シェーダー(vertexShader、バーテックスシェーダー)とは、物体の頂点の位置を決定するためのプログラムのこと
  • gl_Positionに渡した値が頂点の位置
  • 頂点ごとに頂点データ(attribute,頂点属性)を渡すことができる
  • 頂点データは、頂点ごとに違う値に設定できる
  • 頂点データは、ユーザーが定義できる
  • 頂点位置決定後にフラグメントシェーダが実行される