GLSL で始めるシェーダグラフィック

シェーダだけで描く不思議な世界で遊んでみよう!

あなた誰なの

  • すぎもと まさひろ (doxas)
  • twitter: @h_doxas
  • WebGL 開発支援サイト wgld.org 管理人

doxas

最近の活動など

最近の活動など

  • 2014年6月:Tokyo WebGL Meetup 登壇
  • 2014年9月:3DCG Meetup #04 登壇 ※今回二度目、ありがとうございます!
  • 2014年9月~:WebGL 総本山という WebGL 総合情報サイト立上げ
  • 2014年11月~:WebGL スクールを開講

本日のテーマ

本日のテーマ

シェーダだけを用いてグラフィックを描画する、そんな不思議な世界で皆さんと一緒に遊んでみたいと思います。

本日のテーマ

シェーダだけを用いてグラフィックを描画する、そんな不思議な世界で皆さんと一緒に遊んでみたいと思います。

まずはシェーダだけで描くとはどういうことなのか、そしてどんなことができるのか、そのあたりから始めていきましょうか。

いわゆる普通の WebGL の場合

いわゆる普通の WebGL の場合

WebGL に限らず、一般的な 3D プログラミングや、Unity などを用いた 3D シーンの製作には、大抵の場合カメラや 3D モデル、ライトなどが出てきますね。

いわゆる普通の WebGL の場合

WebGL に限らず、一般的な 3D プログラミングや、Unity などを用いた 3D シーンの製作には、大抵の場合カメラや 3D モデル、ライトなどが出てきますね。

三次元空間に 3D モデルを置いて、それを撮影するカメラを設置して、ライトの光はどんな風にあたるのか指定して……という具合に処理していきます。

いわゆる普通の WebGL の場合

WebGL に限らず、一般的な 3D プログラミングや、Unity などを用いた 3D シーンの製作には、大抵の場合カメラや 3D モデル、ライトなどが出てきますね。

三次元空間に 3D モデルを置いて、それを撮影するカメラを設置して、ライトの光はどんな風にあたるのか指定して……という具合に処理していきます。

今回のようなシェーダのみで描くグラフィックを考えるときは、三次元であれ二次元であれ、こういう処理手順とはまったく異なるアプローチで物事を考えます。

全てのピクセルを走査する

全てのピクセルを走査する

たとえば一般的な WebGL のプログラムで画面上に何かを描くとき、頂点(ポリゴン)がひとつも描かれない部分には初期化したときの色がそのまま出てきます。

全てのピクセルを走査する

たとえば一般的な WebGL のプログラムで画面上に何かを描くとき、頂点(ポリゴン)がひとつも描かれない部分には初期化したときの色がそのまま出てきます。

このブランクな領域に対してはいかなる処理も基本的には行われません。

全てのピクセルを走査する

一方で、シェーダのみでグラフィックを描画する上では、先ほどのようにブランクとなる領域が出ないように、画面全体を覆う板状のポリゴンを一枚レンダリングします。

全てのピクセルを走査する

一方で、シェーダのみでグラフィックを描画する上では、先ほどのようにブランクとなる領域が出ないように、画面全体を覆う板状のポリゴンを一枚レンダリングします。

そうすることで、スクリーン上のすべてのピクセルに対して、何かしらの処理を行うことができるようになります。そのような状態を作ったうえで、すべてのピクセルに対して一律の計算を行い、その結果画面に何かを描こうというのが今回のテーマです。

極端な例

極端な例

たとえば、スクリーンがすごく小さな、2px 四方の矩形だと想像してみます。

極端な例

たとえば、スクリーンがすごく小さな、2px 四方の矩形だと想像してみます。

極端な例

この状態で、左から 0 番目のピクセルに対してのみ、赤い色を塗りたいとしますね。そんなときは、こんなふうにシェーダを書きます。

極端な例

この状態で、左から 0 番目のピクセルに対してのみ、赤い色を塗りたいとしますね。そんなときは、こんなふうにシェーダを書きます。

if(処理しようとしているピクセル.x == 0){color = red;}

極端な例

この状態で、左から 0 番目のピクセルに対してのみ、赤い色を塗りたいとしますね。そんなときは、こんなふうにシェーダを書きます。

if(処理しようとしているピクセル.x == 0){color = red;}

処理しようとしているピクセルの横位置を色変化の判断基準にしているわけですね。

もう少し大きめのスクリーン

もう少し大きめのスクリーン

では先ほどの要領で、もう少し大きなスクリーンの場合を考えてみましょう。

もう少し大きめのスクリーン

では先ほどの要領で、もう少し大きなスクリーンの場合を考えてみましょう。

スクリーンの大きさが仮に 10px 四方だとします。このとき、横位置(x)が奇数の場合だけ色を変化させるには、どういうシェーダを書けばいいでしょうか。

もう少し大きめのスクリーン

もう少し大きめのスクリーン

mod という除算の余りを返す関数を使えば簡単です!

もう少し大きめのスクリーン

if(mod(処理しようとしているピクセル.x, 2) > 0){color = orange;}

全ては同じコードから生み出される

全ては同じコードから生み出される

このように、すべての処理対象のピクセルに対してまったく同じ処理を行い、結果的に何かを描き出そうというのが GLSL シェーダコーディングです。

全ては同じコードから生み出される

このように、すべての処理対象のピクセルに対してまったく同じ処理を行い、結果的に何かを描き出そうというのが GLSL シェーダコーディングです。

どうでしょう。簡単なことなら意外とできそうという気がしませんか?

全ては同じコードから生み出される

このように、すべての処理対象のピクセルに対してまったく同じ処理を行い、結果的に何かを描き出そうというのが GLSL シェーダコーディングです。

どうでしょう。簡単なことなら意外とできそうという気がしませんか?

工夫を凝らすとかなりいろんなことができます!

シェーダコーディング実例

シェーダコーディング実例

実際に、GLSL だけを用いてどのようなものがレンダリングできるのか、いくつか例を見てみましょう。

シェーダコーディング実例

実際に、GLSL だけを用いてどのようなものがレンダリングできるのか、いくつか例を見てみましょう。

なにはともあれやってみよう

なにはともあれやってみよう

とても難しいことをやろうとするとそれなりに大変ですが、簡単な二次元でのシェーダコーディングなら、それほど難しくはありません。

なにはともあれやってみよう

とても難しいことをやろうとするとそれなりに大変ですが、簡単な二次元でのシェーダコーディングなら、それほど難しくはありません。

皆さんも一緒に、ハンズオン形式でシェーダコーディングをやってみましょう。

なにはともあれやってみよう

とても難しいことをやろうとするとそれなりに大変ですが、簡単な二次元でのシェーダコーディングなら、それほど難しくはありません。

皆さんも一緒に、ハンズオン形式でシェーダコーディングをやってみましょう。

お手元に PC ある方は一緒にどうぞ! たぶん iphone とかでもがんばればできます。

オンライン GLSL エディタ

オンライン GLSL エディタ

js4k intro - GLSL editor

http://jp.wgld.org/js4kintro/editor/

今回目指す完成品

今回目指す完成品

demo

実は結構手軽でしょ

実は結構手軽でしょ

GLSL でシェーダを書くなんていうとすごく難しそうなイメージがあると思いますが、意外にも結構簡単ではなかったでしょうか。

実は結構手軽でしょ

GLSL でシェーダを書くなんていうとすごく難しそうなイメージがあると思いますが、意外にも結構簡単ではなかったでしょうか。

HTML や javascript 部分を含めても、本当に数キロバイトという小さなファイル容量で驚くほど美しい映像を生み出すことができたりします。

実は結構手軽でしょ

GLSL でシェーダを書くなんていうとすごく難しそうなイメージがあると思いますが、意外にも結構簡単ではなかったでしょうか。

HTML や javascript 部分を含めても、本当に数キロバイトという小さなファイル容量で驚くほど美しい映像を生み出すことができたりします。

URL を簡単に共有できるように作ってありますので、気軽にシェーダコーディングを楽しんでみてください。

イベント開催中

イベント開催中

先ほどもチラッと出てきましたが、今まさにシェーダコーディングのイベント、js 4k intro を開催中です。

イベント開催中

先ほどもチラッと出てきましたが、今まさにシェーダコーディングのイベント、js 4k intro を開催中です。

シェーダのソース込みで 4k 以下になるようにすること以外に、小難しい条件はありません。よろしければみなさんご参加ください。待ってます!

javascript 4k intro

ありがとうございました。