2015-07-30 23:57:27 +00:00
|
|
|
|
# 初めの一歩
|
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
## フラグメントシェーダーとは
|
2015-07-30 23:57:27 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
前章ではシェーダーがグーテンベルグの活版印刷に匹敵すると書きました。どういう意味でしょう。そもそもシェーダーとは何でしょうか。
|
2015-07-30 23:57:27 +00:00
|
|
|
|
|
|
|
|
|
![From Leter-by-Leter, Right: William Blades (1891). To Page-by-page, Left: Rolt-Wheeler (1920).](print.png)
|
|
|
|
|
|
2015-07-31 02:21:30 +00:00
|
|
|
|
コンピュータで絵を描いたことがあれば、円や長方形、線、三角などを組み合わせて自分の描きたいものを作る方法を知っているでしょう。コンピュータへの指示ごとに手順を一つ一つ繰り返していくという意味で、これは文字や本を手で書いていく方法によく似ています。
|
2015-07-30 23:57:27 +00:00
|
|
|
|
|
2015-07-31 02:21:30 +00:00
|
|
|
|
シェーダーもコンピュータへの指示の集まりですが、全てのピクセルに対する指示が同時に実行される点が違います。そのためには書かれたコードが画面上のピクセルの位置によって違った振る舞いをする必要があります。プログラムは画面上の位置を入力にしてピクセルの色を返す関数として働き、一度組まれた活版が一度にページ印刷できるのと同じように、コンパイルされたシェーダは非常に速く処理を行うことができます。
|
|
|
|
|
|
2015-07-30 23:57:27 +00:00
|
|
|
|
![Chinese movable type](typepress.jpg)
|
|
|
|
|
|
2015-07-31 02:21:30 +00:00
|
|
|
|
## シェーダはなぜ速いのか
|
2015-07-30 23:57:27 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
秘密は並列処理にあります。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
コンピュータのCPUを太い土管のようなパイプだと想像してみてください。全てのタスクは工場のようにパイプを通って流れて行きます。幾つかのタスクは他のものよりも大きくて、より多くのエネルギー、つまりコンピュータの処理能力を必要とします。コンピュータは仕事を順番に扱い、ひとつずつ終わらせていくように設計されています。最近のコンピュータはたいていパイプの役割をするプロセッサーを四つセットで持っていて、タスクを一つ一つ、全体がスムーズに流れるように終わらせていきます。このパイプはスレッドとも呼ばれています。(訳注:CPU=パイプ=スレッドのように読めますが、実際にはスレッドはCPUを通る処理の単位として分けて考えた方が正確だと思います。[Wikipedia:スレッド (コンピュータ)](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)参照。この後の方にも同様の部分が出てきますがおよその意味は通じると思うのでそのまま訳します。)
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
2015-07-30 23:57:27 +00:00
|
|
|
|
![CPU](00.jpeg)
|
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
ビデオゲームや画像を扱うアプリケーションは他のプログラムに比べてずっと多くの処理能力を必要とします。画像コンテンツのために非常に多くの処理をピクセルごとに行わなくてはならないのです。全てのピクセルは計算を必要とし、3Dのゲームではさらにオブジェクトの形状や遠近法のための計算も必要になります。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
パイプとタスクの比喩を思い出しましょう。それぞれのピクセルは小さくて簡単なタスクです。個々のピクセルはCPUにとってなんの問題もありません。でもこの小さなタスクは画面上の全部のピクセルの分だけあるのです!昔の800x600のスクリーンなら480,000個のピクセルを処理する必要があり、一秒あたりの計算は14,400,000回になります(訳注:秒間30フレームの場合)。これは一個のプロセッサーには重たい仕事です。2880x1800pxもある今時のレティナディスプレイで秒間60フレームでは、311,040,000回にもなります。グラフィックエンジニアはどうやってこれを解決するのでしょう。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
2015-07-30 23:57:27 +00:00
|
|
|
|
![](03.jpeg)
|
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
ここで並列処理が活躍します。数個の大きくて強力なプロセッサー(パイプ)の代わりに、たくさんの小さなプロセッサーを同時に働かせるのが賢いやりかたです。これがGPU(Graphic Processor Unit)の正体です。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
2015-07-30 23:57:27 +00:00
|
|
|
|
![GPU](04.jpeg)
|
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
たくさんの小さいプロセッサーをパイプをずらりと並列に並べたものを思い浮かべて、ピクセルごとのデータはピンポン玉だと考えてみてください。一秒に14,400,000個のピンポン玉を流せばどんなパイプでも詰まってしまいますが、800x600本の小さいパイプなら480,000個を一秒間に30回スムーズに流すことができます。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
解像度が大きくなっても理屈は同じです。並列に処理できる数が多いほど、より大きなデータの流れを扱うことができるのです。
|
|
|
|
|
|
|
|
|
|
もうひとつGPUの凄いところは、特定の数学的な関数がハードウェアで高速に処理されることです。複雑な計算がソフトウェアではなく直接チップによって処理されるので、三角関数や行列演算を非常に速く行うことができます。
|
|
|
|
|
|
|
|
|
|
## GLSLとは
|
2015-07-30 23:57:27 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
GLSLはopenGL Shading Languageの略で、標準化されたシェーディング言語の一つです。ここからの章ではこの言語を扱います。他にもハードやOSによって異なるシェーダー言語があります。
|
|
|
|
|
ここからは[クロノスグループ](https://www.khronos.org/opengl/)によって策定されたOpenGLの仕様に基づいて話を進めます。OpenGLの歴史を知っておくと奇妙な(訳注:プログラミング、言語仕様上の)慣習を理解する助けになるかもしれません。[openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html)に軽く目を通しておくと良いでしょう。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
|
|
|
|
## なんでシェーダーは厄介だと思われているのか
|
2015-07-30 23:57:27 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
スパイダーマンの父親がわりだったベンおじさんは「大いなる力には、大いなる責任が伴う」と言い残しましたが、並列処理にも当てはまります。強力なGPUの設計の裏にはそれに応じた制約と制限があります。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
|
|
|
|
全てのパイプ、またはスレッドを並列で走らせるためには、それぞれが他のスレッドから独立していなければなりません。つまりスレッドにはほかのスレッドがしていることが見えないのです。全てのデータが同じ向きに流れなくてはならず、ほかのスレッドの結果をチェックしたり、入力データを変えたり、あるスレッドの結果を別のスレッドに渡したりすることはできないのです。スレッド間のやりとりを可能にしてしまうと、データ全体としての一貫した処理を損なうことになりかねません。
|
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
GPUは並列なプロセッサーをずっと忙しいまま保とうとします。仕事が終わったプロセッサーはすぐに新しい処理のための情報を受け取ることになります。スレッドは前の瞬間にやっていたことを覚えていません。OSのUI上のボタンを描いていたかと思えばゲームの中の空の一部を、次にはメールの文章の表示をしているかもしれません。スレッドには周りが見えないだけでなく、記憶もないのです。ピクセルの位置に応じて結果を変えられるような汎用的な関数を書くために考えをうまく取りまとる必要があることに加えて、ほかのスレッドや前の状態がわからないという制限のおかげでシェーダーはプログラム初心者にはあまり人気がありません。
|
2015-07-31 02:21:30 +00:00
|
|
|
|
|
2015-07-31 03:00:40 +00:00
|
|
|
|
でも大丈夫です!この後につづく章では簡単なことから高度なシェーディングまで一歩一歩学んでいきます。今時のブラウザーで読んでいれば、サンプルを試してみることがとても役にたつでしょう。さあ、楽しいことを先延ばしににするのはやめて、「Next」を押してコーディングを始めましょう。
|