ばうあーろぐ TOP へ戻る

3Dグラフィックスのド素人がGLSLについて調べてみた

こちらの記事は、LL/ML Advent Calendarの21日目の記事です。

#LLAdventJPとは?

僕も知りません。なごやって素敵ですね!

(※時間がどうしてもなくて、紹介記事止まりでごめんなさい!)

この記事を書こうと思ったわけ

“L”と”L”、もしくは”M”と”L”がつけばなんでもOKとのことだったので、最悪HTMLのことなんか書けばいいかーと思いつつ、悶々としていたのですが、CSS3 custom filterのデモを見ていて、

-webkit-filter: custom(
  url(shaders/vertex/page-curl.vs) mix(url(shaders/fragment/page-curl.fs) normal source-atop),
  50 50 border-box,
  transform perspective(1000) scale(1) rotateX(0deg) rotateY(0deg) rotateZ(0deg),
  curlPosition 0 0,
  curlDirection 135,
  curlRadius 0.2,
  bleedThrough 0.59
);

この page-curl.vs とか page-curl.fs ってなんぞ?と思ったのがきっかけで、いろいろ調べてみたらGLSLというキーワードにぶち当たったので、なんだろうと思って軽めに調べてみました。

以下、こんな感じで話が進みます。

ちなみにタイトルにもあるように、3Dグラフィックスの周りはド素人であるため、専門でやられている方にはつまらなく感じるかもしれません。もし間違いとかありましたら、叩かれるのはこわいのでやさしく指摘してくだされば幸いです。


CSS filter、CSS custom filterについて

CSS filter

昨今のモダンブラウザの高速リリースによって、ビジュアル面でもFlashと同等レベルのことが出来るようになってきました。

特にJavaScriptではなく、CSSで出来ることの幅がぐんと広がってきており、CSSで様々なエフェクトがかけられるCSS filterは、その最たる例と言ってもいいのかもしれません。

CSS filterに関しては、こちらのページが分かりやすいです。

Understanding CSS Filter Effects – HTML5 Rocks

グレースケール(灰色っぽくする)とか、コントラスト比をいじるとか、Flashで普通に出来たことが、同じようにHTMLに出来るようになっただけでしょ?と思われる方もいるかもしれません。

ただ、僕はそうは思っていなくて、任意のDOM要素に対して使えるというのがかなりのメリットではないかと考えています。

試してみましょう!

試しにお使いのブラウザ(Chromeなど)の開発者ツールで、このページの下にあるであろう『いいね!』ボタンのiframeを選択し、以下のようなスタイルをあててみてください。

-webkit-filter: grayscale(100%);

どうですか?いいねボタンが白黒になりましたか?まるでFBのお葬式のようですね!

これってかなりすごいことで、例えばbodyに対してブラーエフェクト(blur、ぼかしのエフェクトのこと)を先にかけておいて、ちょっと間を置いてエフェクトを消してやれば、ぼやけていたWebコンテンツがしゅっと見えるような表現が出来たりしますよね!

こういった今までつまんない感じだったWebコンテンツを、少しのCSSの記述だけでとても簡単にカッコイイ感じに変身させることができちゃうのです。

※もちろん、色んな要素にエフェクトかけまくっちゃうとレンダリング負荷は高まりますので、それだけあれば何でも解決するかというとそんなことはありません。

公式の仕様は以下に載ってます。僕もまだこれからちゃんと読まないといけないレベルですが、一応紹介までに。

Filter Effects 1.0(仕様)

CSS filter の custom filter

この css filter の種類の1つに、customというのがあります。エフェクトのかけ方を、こちらで自由に制御できちゃうみたいなんですねー。これはすごい。

とりあえずデモを見て、「おー、すげー!」でもしてみましょうか。

CSS shaders: Cinematic effects for the web | Adobe Developer Connection

「おー、すげー!」

css custom filter も、css filter の1つであるため、任意のDOM要素に対してエフェクトがかけられるわけですね。

見る限り、以下のようなことが出来そうです。

  1. 色の塗り分け
  2. 影の付け方をいじる
  3. 3Dを2Dに対応付けして、3Dっぽく見せる

・・・と、ここまで調べてみると、3Dグラフィックスの専門用語がそれなりにわんさか出てきます。GLSLに触れるとともに一通り調べてみました。

GLSLとは?そもそもシェーダーとは?

まずGLSLについて。

GLSL (OpenGL Shading Language) はGLslangとしても知られ、C言語をベースとした高レベルシェーディング言語である。これはアセンブリ言語やハードウェアに依存した言語を使わないで、開発者がグラフィックスパイプラインを直接制御できるようにOpenGL ARBで策定された。最新版は、GLSL 4.10(米国時間2010年7月28日)である。

wikipedia: GLSLより引用

はい、OpenGLシェーディング言語なわけですね。わかりません。

GLはGraphics Libraryの略なので、2D, 3Dのグラフィックスが扱えるとしても、シェーディングシェーダーとはなんでしょうか?

シェーディング(英: shading)は、3次元コンピュータグラフィックスやイラストレーションなどで明暗のコントラストで立体感を与える技法である。絵画では陰影画法と呼ぶ。

wikipedia: シェーディングより引用

ほほう、これはデモで見て予想した通りのことが出来る技法ですね。

コンピュータグラフィックスのシェーダ(英: shader)は、主にライティング(光源計算)・シェーディング(陰影処理)とレンダリング(ピクセル化)を実行するためにグラフィック リソースに対して使用するソフトウェア命令の組み合わせである。

wikipedia: シェーダより引用

シェーディング(光や影、ピクセルの色や位置などの変化)をシェーダーが担当してくれているのですね。

・・・なるほど。

ということは、一番最初に見たCSSの記述は、シェーダーのことを表しているようです。もう一度見てみます。

-webkit-filter: custom(
  url(shaders/vertex/page-curl.vs) mix(url(shaders/fragment/page-curl.fs) normal source-atop),
  50 50 border-box,
  transform perspective(1000) scale(1) rotateX(0deg) rotateY(0deg) rotateZ(0deg),
  curlPosition 0 0,
  curlDirection 135,
  curlRadius 0.2,
  bleedThrough 0.59
);

このpage-curl.vs の vs は、vertex shader の略のようです。また page-curl.fs の fs は、fragment shader の略のようです。

点と面のシェーダーがあるよ、と考えておけばいいのかもしれません。

つまり・・・

あとおまけで、

あたりが分かりました。

GLSLのHelloWorld

さて、WebGLはクロノス・グループという団体が標準化を行っています。

そちらにGLSL 1.0の仕様がありましたので、紹介しつつ少しだけ読んでみようと思います。

The OpenGL ® ES Shading Language ※PDFです

・・・。

・・・・・・。

やばい、予想以上にC言語っぽい。

しっかり読んで紹介していると21日目のブログ記事が間に合わなくなってしまうので、ちょっと落としどころを探りたいと思いますw

WikipediaのGLSLの項目に、一番シンプルであろう fragment shader の例が載っていたので、それについてだけ調べてみます。

void main(void)
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

gl_FragColor や gl_FragData に代入することで、フラグメントシェーダーとして書き出しますよーということを表します。

ちなみにとても良いサイト見つけました。 そのままGLSLを書いて試せるっぽいです。(GLSL Sandbox)上記コードは1〜3までの引数でカラー指定をしているようですね!(第4引数はなんだろう、透明度なのかな・・・?)

「おー、すげー!」

まとめ

って感じで、とりあえずHelloWorldまで行くだけでもだいぶ長くなってしまいましたが、ここまで調べられればこの後の導入が比較的スピーディーに行けるのでは?と思っています。

これで色んなGLSLを書いて、オリジナルのエフェクトとか作れたらかなり表現の幅が広がりそうです!

おまけ

僕は余力がなくて参加できてないのですが、 GraphicalWeb (CSS, SVG, WebGL etc) Advent Calendar 2012 の中のyomotsuさんが書かれたCSS shaderに関する一連の記事はかなり勉強になります。時間作ってしっかり読みたいなーと思いました。

もし記事内に誤りなどございましたら、 @girigiribauer までご一報いただけると助かります。