連載
» 2012年11月28日 18時00分 公開

Webグラフィックをハックする(最終回):WebGLの能力を引き出すプログラマブルシェーダー (3/5)

[伊藤 千光,WebOS Goodies]

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のいずれかを取ることができ、同じ型の値を返します。ベクトルに適用した場合は各要素に対して演算を行って、結果を返り値の対応する要素に格納します。

関数 説明
radius(x) xを度数からラジアンに変換する
degrees(x) xをラジアンから度数に変換する
abs(x) xの絶対値を返す
sign(x) xが正なら+1.0、0.0なら0.0、負なら-1.0を返す
floor(x) x以下の最大の整数を返す
ceil(x) x以上の最小の整数を返す
fract(x) x-floor(x)を返す
mod(x, y) x-y*floor(x/y)を返す
min(x, y) xとyのより小さい値を返す
max(x, y) xとyのより大きい値を返す
clamp(x, a, b) min(max(x, a), b)を返す
mix(x, y, a) x(1-a)+y*aを返す(つまり線形補間)
step(a, x) x
smoothstep(e0, e1, x) エルミート補完を行う
sin(x) 正弦を返す
cos(x) 余弦を返す
tan(x) 正接を返す
asin(x) 逆正弦を返す
acos(x) 逆余弦を返す
atan(y, x) 逆正接を返す
pow(x, y) xのy乗を返す
exp(x) eのx乗を返す
log(x) xの自然対数を返す
exp2(x) 2のx乗を返す
log2(x) xの底2のlogを返す
sqrt(x) xの平方根を返す
inverssqrt(x) 1/sqrt(x)を返す

 オーソドックスなベクトル演算も用意されています。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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。