これまで GLSL
(とほんの少しのHLSL
)を書いてましたが、フラグメントシェーダーしか書いていないことに気づいた。
もう一つの頂点シェーダー(バーテックスシェーダー)にも触れてみたい。
サンプルは全然見つからないし情報自体が少ないので gl-react
のソースを見ながらバーテックスシェーダーの動作を確認します。
今回は基本的な確認までです。
gl-react
のvert
定義
gl-react
というライブラリを使って GLSL
を実行しています。
バーテックスシェーダー(vert
)はオプション引数で必須ではないです。
だからこそ今まで気にしなかったわけですが。
ソースコードから定義とデフォルトのシェーダーを見てみます。
1 2 3 4 |
type ShaderDefinition = {| frag: GLSLCode, vert?: GLSLCode |}; |
1 2 3 4 5 6 |
attribute vec2 _p; varying vec2 uv; void main(){ gl_Position=vec4(_p,0.,1.); uv=vec2(.5,.5)*(_p+vec2(1.,1.)); } |
uv
の計算を見ると gl_Position.xy
の値域は [-1<1, -1<1]
でいいんだろうか。
動作確認
単純な画像を表示させるシェーダーで確かめてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//vert attribute vec2 p; void main(){ gl_Position=vec4(p,0.,1.); } // frag precision highp float; uniform vec2 resolution; uniform sampler2D t; void main(){ vec2 r=resolution,p=(gl_FragCoord.xy)/min(r.x,r.y); gl_FragColor=texture2D(t,p); } |
p
をずらして gl_Position
を定義してみます。
1枚目は想定通り、2枚目はなぜか謎の欠け方をしています。
もう少し基本から深堀りしていきます。
attribute vec2 p;
ってなに?
.js
と .vert
、.frag
間での値のやり取りはストレージ修飾子※を付けています。
const
: 定数を定義します。attribute
: 頂点ごとに異なる値が渡されます。uniform
: 名前通りどの点でも同じ値を持ちます。verying
: シェーダー間の受け渡しに使います。
これらの性質と各シェーダーのビルトイン入出力を大まかに図にするとこんな感じ。
なので js
側での設定を確認します。
1 2 3 4 5 |
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 4, 4, -1]), // see a-big-triangle gl.STATIC_DRAW ); |
これを元に考えると先ほどの右上が書けた画像も納得できます。
1枚のポリゴンで表示領域を確保している感じなんでしょうか。
となると、もしや gl-react
であまり複雑な処理は出来ないのでは。
何かできないかもう少しいじってみます。