RGB三角形

頂点ごとに違う色の三角形

RGB triangle

 今回はRGB三角形がテーマです。頂点ごとに違う色を指定しようというわけですね。フラグメントシェーダがどのように色を決めているのかを知るのにすごく便利です。ちなみにRGB三角形はWebGLの定番メニューで、h_doxasさんのサイトでも最初の課題として取り組んでいるんですが、あっちはそれよりはるかに難しい話題であるアトリビュートや行列まで駆使しているので大変ですね...こっちではそこまで高度なことはしないで、せっかくWebGL2なので、インデックスでゆっくりやろうかと思います。

コード全文

作品2のリンク

プログラムの説明について

 プログラムを作る過程についての解説はしません。前回やったからね...今回のコードはシェーダー以外ほとんど前回と一緒なので、主にシェーダー部分の解説をします。新しい関数も、出てきません。前回2つの記事の復習プラスアルファって感じですね。最後にちょっと正方形を作るバリエーションを説明して終わりです。

バリイング

 WebGL1の知識がある人ならわかると思いますが、varyingというのがあって、バーテックスシェーダからフラグメントシェーダに値を渡すことができます。具体的に言うと、バーテックスシェーダで頂点ごとに情報を決めるんですが、それですね。フラグメントシェーダに渡すとそれが適当に補間されて色になったりするわけです。その受け渡しは入出力ととらえることができます。なので、WebGL2ではずばりそのものであるout/inでこれを表現しています。

バーテックスシェーダ:

out vec3 vColor;

フラグメントシェーダ:

in vec3 vColor;

 バーテックスシェーダでvColorを決めて、フラグメントシェーダに送ります。

位置と色

 今回位置は正三角形になるように決めています。円周率をPIで決めています。組み込まれていないので、こういうのは自前で用意する必要があります。角度は何となくわかると思います...右が0で真上がPI/2なので。それと同時に色の定数を用意しています。

const vec3[3] color = vec3[](
  vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0)
);

 赤、ライム、青です。ライム?そうです。まあ普通の緑ではないですね...位置と同様、gl_VertexIDを引数としてvColorに渡します。

  vColor = color[gl_VertexID];

 これで0,1,2番にそれぞれ色が決まります。そうしたうえで、フラグメントシェーダでそれを受け取り、色とします。

void main(){
  fragColor = vec4(vColor, 1.0);
}

 位置と色の対応がわかったでしょうか。そういうことです。なお背景を暗い緑にしてます。特に意味は無いんですが、復習ですね。

  gl.useProgram(pg);
  gl.clearColor(0.0, 0.2, 0.1, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  gl.drawArrays(gl.TRIANGLES, 0, 3);
  gl.flush();

 解説は以上です。

応用:正方形の各頂点を違う色にする

 最後に約束通り、応用として、正方形を描いて、頂点ごとに違う色にしてみようと思います。バーテックスシェーダだけを次のように変更します:

#version 300 es
const float PI = 3.14159265358;
const vec2[4] pos = vec2[](
  vec2(-0.8, -0.8), vec2(0.8, -0.8), vec2(-0.8, 0.8), vec2(0.8, 0.8)
);
const vec3[4] color = vec3[](
  vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0), vec3(1.0, 1.0, 1.0)
);
out vec3 vColor;
void main(){
  vec2 p = pos[gl_VertexID];
  vColor = color[gl_VertexID];
  gl_Position = vec4(p, 0.0, 1.0);
}

 フラグメントシェーダは一緒です。ドローコール部分を次のように変更します。

  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  gl.flush();

 いずれやりますが、TRIANGLE_STRIPといいます。0,4なので使われる整数は0,1,2,3の4つです。これはどういうドローコールかというと、「0,1,2」と「2,1,3」で三角形を1枚ずつ作りなさいよ...という意味です。たとえばTRIANGLESで0,6なら「0,1,2」と「3,4,5」で三角形を...となります。STRIPとは「細長い一切れ」という意味で、これは文字通りそういう風に頂点が並んでいる場合の指定方法です。具体的にはx軸正方向(右)に向かって上、下、上、下、...またはy軸正方向(上)に向かって左、右、左、右、...と並んでいる場合に、それらが作る帯を実現するように三角形が組まれていきます。この作例では後者ですね。
 描画結果はこちらになります。

colored square

 しっかり指定した順に青、シアン、マゼンタ、白となっています。きれいですね~。
 と、こんなところまでとしましょう。またいつか...