JavaScript
WebGL
GLSL
three.js

three.js超入門 第5回 シェーダー(GLSL)の基礎


概要

この記事では「three.js超入門」と題して、three.jsの基礎からシェーダーの利用までをやっていきます。

ターゲットは主に「canvas表現を触ったことがないフロントエンドエンジニア」を想定しているので、jsの構文などの説明は省略しています。

three.jsのバージョンは執筆時点で最新のr98を使用します。

three.js超入門 第0回 3Dコンピュータグラフィックスの基礎

three.js超入門 第1回 レンダリングまでの流れ

three.js超入門 第2回 アニメーションと時間ベースでの制御

three.js超入門 第3回 マウスやスクロールでのインタラクション

three.js超入門 第4回 DOM要素との連携

three.js超入門 第5回 シェーダー(GLSL)の基礎

three.js超入門 第6回 ShaderMaterialでメッシュを変形、着色する

three.js超入門 第7回 シェーダーに変数を渡す

three.js超入門 第8回 シェーダーをインタラクティブに動かす

three.js超入門 第9回 シェーダーでテクスチャにエフェクトをかける

リポジトリ

シリーズで書いてはいるものの、脱線して小ネタ集みたいになってきてしまったので、そろそろちゃんとした記事を書こうと思い、今回からGLSLをやろうとおもいます。。(着地点定まってないですが、、w)


GLSLとは

OpenGL Shading Language (OpenGLシェーディング言語)の略称です。

C言語がベースになっています。

「シェーディング」の名の通りモデルに陰影をつけるためのものですが、頂点やピクセル単位でいじれるので、陰影だけでなく様々な表現が可能です。

WebGL1.0では、「頂点シェーダー」「フラグメントシェーダー(ピクセルシェーダー)」の2つが利用可能です。

ファイルの拡張子は、頂点シェーダーは.vert(または.glsl)、ピクセルシェーダーは.frag(または.glsl)です。


人はなぜシェーダーを書くのか

CPUではなくGPUで処理される。

GPUは頂点やピクセルなど、大量の情報を一気に処理するのが得意。

CPUでやるとフレーム落ちするような重い処理を、GPUで実装するとサクサク動かせる。

「CPUはスポーツカー、GPUはバス」(堤さんのスライド(P.34)より)

ポストエフェクトが短いコードで作れる。(グリッチやディストーションなど)


シェーダーが実行されるタイミング

第0回のこの図を思い出してください。

DQ2P8qcUMAE3VK7.jpg

(画像は床井先生のTwitterから引用)

CPU(JavaScript)で作った図形データ(線や面)を画面に表示する際に、ラスタ化処理が実行されます。

実は、このフローの中にシェーダーが隠れています。


シェーダーの実行フロー


頂点データ

CPUで作成した頂点座標


(頂点シェーダー)

頂点データを処理(座標を動かしたり、パースをかけたり、)


ラスタライズ

頂点シェーダーで処理された頂点データを元に、線や面を画素データに変換


(ピクセルシェーダー)

ラスタライズされた画素データを処理(色を変えたり、テクスチャ座標をずらしたり、)


画素データ

ピクセルシェーダーで決定した画素データを表示


GLSLの書き方

頂点シェーダー、ピクセルシェーダー共にmain()関数の中にひとつの頂点(またはピクセル)に対する処理を書いていきます。

void main() {

// ここに処理
}


頂点シェーダー

gl_Positionvec4型の座標を入れることで頂点を決定します。

gl_Position = vec4( x, y, z, w );


ピクセルシェーダー

gl_Positionvec4型の色を入れることでピクセル色を決定します。

gl_FragColor = vec4( r, g, b, a );


GLSL変数の型について

int:整数

float:小数

vec2:2つの小数値からなるベクトル(xy

vec3:3つの小数値からなるベクトル(xyz, rgb

vec4:4つの小数値からなるベクトル(xyzw, rgba

mat22x2floatの行列

mat33x3floatの行列

mat44x4floatの行列

sampler2D:テクスチャ


vec型の要素へのアクセス

JavaScriptObjectと同じく、vec.x, vec.y, vec.z, vec.wでアクセスできるほか、vec.r, vec.g, vec.b, vec.aでも同じ数値にアクセスできます。

vec.xy, vec.xyzと書くことでvec型として値を取り出すこともできます。


コーディング時の注意点

型に厳密なので、floatを引数にとる型でvec2(1, 1)のように整数を書くとエラーになります。

floatが入るところには少なくとも小数点を書かないとコンパイルが通りません。(例:vec2(1., 1.)

GLSLで色を指定するときは、0 ~ 255ではなく、0.0 ~ 1.0で指定します。


参考URL

The Book of Shaders

第三回 WebGLスクール 「シェーダの基礎」

次回は実際にthree.jsでGLSLを利用する方法をやります。