WebGLの能力を引き出すプログラマブルシェーダー:Webグラフィックをハックする(最終回)(3/5 ページ)
プログラマブルシェーダーの基本的な書き方と、Three.jsの各機能に組み込む方法を解説します
GLSLの組み込み変数
引き続き、GLSLについて解説していきます。文法については前ページでおおむねカバーしたので、ここからは標準で使える変数や関数について解説します。
まずは頂点シェーダーで使える組み込み変数を以下に示します。いずれも出力用で、特にgl_Positionはポリゴン(三角形)の頂点座標として使われるので、必ず有意な値を書き込まなくてはなりません。
変数名 | 型 | 説明 |
---|---|---|
gl_Position | vec4 | 座標変換後の頂点座標 |
gl_PointSize | float | ポイントスプライトのサイズ |
フラグメントシェーダーで定義される組み込み変数は以下になります。gl_FragColorのみ出力用で、他は入力(読み込み専用)です。gl_FragColorにピクセルへの描画色を出力することが、フラグメントシェーダーの主な目的になります。
変数名 | 型 | 説明 |
---|---|---|
gl_FragColor | vec4 | ピクセルの描画色 |
gl_FragCoord | vec4 | ピクセルの座標 |
gl_PointCoord | vec2 | ポイントスプライト内の座標 |
gl_FrontFacing | bool | 表面ならtrue、裏面ならfalse |
GLSLの組み込み関数
GLSLは、頂点処理やライティング処理などでよく使用する計算を組み込み関数として提供しています。それらを使うことで実装の手間を省き、さらに利用可能であればGPUのネイティブな機能を呼び出して演算を高速に処理してくれます。GLSL組み込み関数のリファレンスは以下のページで公開されています。
OpenGL ES Shading Language (GLSL ES) Reference Pages
組み込み関数のうちで代表的なものを簡単に見ていきましょう。まずはJavaScriptでもおなじみの算術関数です。実行する演算はJavaScriptとほぼ同じですが、引数としてfloat、 vec2、 vec3、 vec4のいずれかを取ることができ、同じ型の値を返します。ベクトルに適用した場合は各要素に対して演算を行って、結果を返り値の対応する要素に格納します。
オーソドックスなベクトル演算も用意されています。dot3()以外は引数としてfloat、vec2、vec3、vec4のいずれかを取れます。dot3()の引数はvec3型のみです。
関数 | 説明 |
---|---|
length(x) | xの長さをfloatで返す |
distance(x, y) | xとyの距離をfloatで返す |
normalize(x) | xを正規化した値を返す |
dot(x, y) | xとyの内積をfloatで返す |
cross(v1, v2) | vec3型の引数v1とv2の外積をvec3で返す |
faceforward(N, I, R) | dot(R, I) < 0ならNを返し、それ以外は-Nを返す |
reflect(I, N) | Nを法線として、Iの反射方向をIと同じ型で返す |
refract(I, N, eta) | Nを法線、eta(常にfloat型)を屈折率として、Iの屈折方向をIと同じ型で返す |
ベクトル値同士の比較演算を行う関数もあります。any()、all()、not()は引数としてbvec2、bvec3、bvec4のいずれかを取ります。返り値はany()、all()がbool、not()は引数と同じ型です。それ以外の関数はvec2、vec3、vec4、ivec2、ivec3、ivec4のいずれかを引数として取り、同じ要素数のbvecを返します。
関数 | 説明 |
---|---|
lessThan(x, y) | 要素ごとの x < y の比較結果を返します |
lessThanEqual(x, y) | 要素ごとの x <= y の比較結果を返します |
greaterThan(x, y) | 要素ごとの x > y の比較結果を返します |
greaterThanEqual(x, y) | 要素ごとの x >= y の比較結果を返します |
equal(x, y) | 要素ごとの x == y の比較結果を返します |
notEqual(x, y) | 要素ごとの x != y の比較結果を返します |
any(x) | xのすべての要素がfalseならfalseを、それ以外ならtrueを返します |
all(x) | xのすべての要素がtrueならtrueを、それ以外ならfalseを返します |
not(x) | xの全要素の真偽値を反転して返します |
テクスチャのフェッチも組み込み関数を通して行います。用途に応じて複数用意されていますが、ここでは通常の2次元テクスチャからの読み込みと、キューブテクスチャの読み込みのみを挙げておきます。sampler引数にはsampler2D型もしくはsamplerCube型のuniform変数を指定してください。
関数 | 説明 |
---|---|
texture2D(sampler, coord) | vec2型のcoordが示す座標の色をvec4型で返します |
textureCube(sampler, coord) | vec3型のcoordの方向の色をvec4型で返します |
Three.jsが定義する変数
WebGLの組み込み変数に加えて、Three.jsが自動的に定義する変数もあります。例えば頂点シェーダーでは以下の変数が必ず定義されます。
変数定義 | 説明 |
---|---|
uniform mat4 modelMatrix | モデル座標系からワールド座標系への変換行列 |
uniform mat4 viewMatrix | ワールド座標系からビュー座標系への変換行列| |
uniform mat4 modelViewMatrix | modelMatrixとviewMatrixを乗算したもの |
uniform mat4 projectionMatrix | 透視変換行列 |
uniform mat3 normalMatrix | 法線をビュー座標系に変換する行列 |
uniform vec3 cameraPosition | ワールド座標系でのカメラ座標 |
attribute vec3 position | 頂点座標 |
attribute vec3 normal | 頂点法線 |
attribute vec2 uv | UV座標 |
フラグメントシェーダーでは以下の変数が定義されます。
変数定義 | 説明 |
---|---|
uniform mat4 viewMatrix | ワールド座標系からビュー座標系への変換行列 |
uniform vec3 cameraPosition | ワールド座標系でのカメラ座標 |
これらの変数によって、Three.js上で指定した座標変換などを自作のシェーダーでも利用できます。ここに挙げられていない情報はマテリアルの種類によって定義が変化するため、Three.jsにおけるマテリアルの扱いを理解する必要があります。この記事の最後に部分的にですが取り上げているので、参考にしてください。
Copyright © ITmedia, Inc. All Rights Reserved.