WebGL
GLSL

シェーダエディタを利用してシェーダをリアルタイムデバッグしたいことがもしかしたらあるかもしれない人向けの無駄に長い文章

More than 1 year has passed since last update.

ブラウザ上でのシェーダデバッグ

WebGL や GLSL のデバッグは、通常の JavaScript のフロントエンド開発とは少々異なる趣があります。

というのは、WebGL や GLSL を利用した開発には、GPU という本来なら JavaScript が干渉することのできない領域が大きく関わってきます。その閉ざされた世界のなかでいったい何が起こっているのかについては、ブラックボックス化されており容易には見通せない場合が往々にしてあります。

より正確には、WebGL の調査系のメソッドを適切に呼び出してやるなどすれば、GPU などのハードウェアに関することも含めて、WebGL に関連する情報をある程度は収集することができます。まあしかし、要はいちいち調べないとわからないわけですから、ちょっと面倒です。必然、「案件の性格上実行されるデバイスが限定されている場合」を除いて、大抵は「まあこんくらいならいけるやろ」的なところに落ち着くように実装していく場合が多いのではないでしょうか。

もちろん、逐一動作環境のスペックを調べて、適切に分岐したり、パフォーマンスを調整したりすることが最も望ましい実装の形であることは間違いありません。ただ、WebGL や OpenGL に詳しくないと、どういうことが制限される可能性があるのか、それを調べるのさえも大変ですね。このあたりは、もう経験値でしかないので、いろいろ試して、トライ・アンド・エラーを繰り返していくしかありません。

WebGL のデバッグ

WebGL のデバッグ という観点で言えば、既に Qiita 内にも非常に有用な多くの記事が書かれています。

個人的には、rootx さんの書かれた以下の記事が非常によくまとまっており、これを参考にするのが最適な選択だと思います。

WebGLの開発やデバッグに便利なブラウザ拡張機能をつかってみよう - Qiita

WebGL 全般に及ぶデバッグのための情報はありがたいですね。

上手に活用しましょう。

さて、上記は WebGL 全般のデバッグに関するエントリでしたが、こと GLSL に限って考えてみた場合に、どのようにデバッグを行っていくのが望ましいでしょうか。今回の記事では、そのあたりを主題に考えてみたいと思います。

そもそもちゃん

WebGL のデバッグは、まあブラックボックスだなんだと言っても、なにかしらの方法で状態を予測する手段とそれを閲覧する手段の両方が提供されています。JavaScript 上で動作しているわけですから、console.log 等を利用したいわゆる print デバッグや、開発者ツールを用いたデバッグができるわけです。

しかし GLSL の場合には、そう簡単にはいきません。

まず GPU という特殊なハードウェア上で動作する GLSL には、当然ながら print デバッグに相当する機能はありません。GPU 内部では文字列処理なんて行うことはできませんし、一瞬で何十万、何百万、下手したらそれ以上の回数実行されるシェーダから console.log なんてしたら大変なことになるのはちょっと考えてみればわかりますね。

そういった都合上、基本的にシェーダのデバッグは 色デバッグ で行う場合がほとんどになります。

値をスクリーンに色として出力することによって、中身のデータが意図したとおりのものになっているのかを調べるわけです。

この色デバッグは大変香ばしいデバッグ方法ではありますが、なんか知らんけど慣れてくると別にあんまり苦じゃなくなってきます。ただ、どうしても色でなんとなく察するというデバッグ方法になるので、アバウトな感じでしか調査できない場合が多いです。そのあたりも、ちょっと残念というか、まあ難しいところではあります。

いろいろと制約が多くつらい作業になりがちなシェーダのデバッグですが、工夫することによって多少はその負担を軽減することはできます。

ブラウザにシェーダエディタを導入する

シェーダのデバッグの難しいところとして、GLSL のソースコードを事前にコンパイルしておく必要がある、という点が挙げられると思います。

C 言語などのコンパイルが必要なプラットフォームなんかもまさにそうですが、毎回毎回ゼロから実行しなおしてやらないと結果がわからんというのは面倒ですよね。

この問題を解決してくれるのが、ブラウザに組み込むタイプのシェーダエディタです。

Google Chrome を利用している場合は拡張機能をブラウザに導入します。Firefox には、開発者モードにすることで利用できるシェーダエディタが最初から組み込まれています。

Shader Editor - Chrome ウェブストア

シェーダーエディター - 開発ツール | MDN

Chrome の Extension はウェブストアから簡単にインストールでき、すぐに使い始めることができます。Firefox は組み込みでこのような機能を最初から持っていますが、開発者モードとしてシェーダエディタを有効化しないといけないため、やはりいずれの場合もちょっとした一手間は必要です。

ただどちらもそれほど大きな手間というわけではないと思いますので、ぜひ導入してデバッグの準備を整えておきましょう。

リアルタイムに値を変更

シェーダエディタを導入すれば、実際のレンダリング結果をリアルタイムに確認しながらのデバッグが行えるようになります。これで万事解決というわけではありませんが、その場ですぐに修正した結果を確認することができるので、多少は楽になります。

Chrome 拡張も Firefox のシェーダエディタも、いずれもコード整形やリアルタイムなソースコードの書き換えに対応しています。読みやすい状態に整えてからデバッグすることができるのはとても便利ですね。

しかし、リアルタイムに値が変更できるのはいいとして、じゃあ具体的にどのような部分に修正を加え、さらにそこから何を察してやればいいのでしょうか。

まあこれは実装やそのときの状況によって全然内容が違ってくる部分ではあると思うのですが、比較的あるあるなパターンについて考えてみましょう。

絵が出ない YO!

WebGL などで狙ったとおりの描画結果にならない場合のうち、特に初心者のころに起こりやすいのが なにも表示されない という涙無しには語れない事件です。大丈夫です。誰でもこの道を通ってます。

この何も表示されないという状態にもまあいろいろあると思うのですが、ことシェーダが関わっている部分に関しては、シェーダエディタ等を利用すればなにかヒントが得られる場合があります。

というのは、WebGL などの 3DCG API 全般に言えることですが、絵が出ない原因というのはいろいろな要因が複雑に絡み合っている場合が多いです。そもそも描画命令を発行してないといういかにもうっかりさんな凡ミスもあれば、カリングの設定が誤っており見えなくなっているなんてこともありますね。

このような絵が出ない状態には、シェーダエディタによるシェーダのリアルタイム編集が役に立つ場合があります。

たとえば、スクリーンへ出力する色を表す gl_FragColor に、シェーダエディタで完全な白などを強制的に出力するようにシェーダエディタ上で変更を加えてみたとしましょう。このとき、真っ黒だった画面上に、なにかしら白い物体が見えている場合は、少なくとも頂点がそこにあることは確認できます。

反対に、もし真っ暗なままだったとしたら、そもそも頂点が描かれていない可能性が高いということになりますね。少なくとも、原因の切り分けには役に立ちます。

ライトの当たり方が変だ YO!

ライティングなどの、シェーダによって頂点やポリゴンの色が変化するような処理を書いているときも、シェーダエディタが役に立つ場面があります。

特によくあるのが、法線を使ってベクトルを算出する系の処理なんかの場合。たとえばバンプマッピングとかですかね。

バンプマッピングでは、法線を使って接線ベクトルなどの別のベクトルを生成していきます。このときの計算結果が正しく行えているのかは、新しく生成した接線ベクトルを色として可視化してみることで、ある程度は検証できます。

シェーダエディタを使って接線ベクトルに相当する値を色として出力してみたら、明らかに値が大きすぎるように見えてベクトルの正規化をしていなかったことに気がつく……なんてこともあるかもしれません。

私の経験的には、そもそも法線ほんとにちゃんと計算できてんのコレ事件のときに、シェーダ内の値を可視化するのにシェーダエディタが役立ったことがありました。なんだったかなあ……Matcap かなんかを勘で実装したときだったかもしれない。

テクスチャをオン・オフしたい YO!

その他にも、たとえばテクスチャをオン・オフしたりするのにシェーダエディタを使い、検証作業を行うなんてこともあるかもしれませんね。

わざわざ uniform 変数としてテクスチャの表示・非表示を変更するフラグを用意しなくても、シェーダエディタがあればササッとテクスチャなしの状態に切り替えたりすることができちゃいます。

これはテクスチャだけに言える話ではありません。本来なら、制作を行っている段階では、パラメータを操作できるような開発者用インターフェースを設けておくのがベストでしょう。スライダやチェックボックスを仕込んでおき、簡単に調整できるようにしておくわけです。

ただこのインターフェースを用意するにしても、uniform 変数を増やすとなれば、シェーダだけでなく JavaScript で構築しているアプリケーション側にも手をいれる必要が出てきます。本当にサッと確認したいだけなのに! という場合は、シェーダエディタを活用することで、手軽にデバッグや検証が行えることもあるかなとは思います。

アニメーションを調整したい YO!

上記のことはアニメーションをシェーダ側で制御している場合にも言えますね。

大抵の場合、シェーダでアニメーションさせるという場合は時間の経過を uniform とかで送ってると思うのですが、この時間の経過を早くしたり遅くしたりしながらアニメーションの調整を行なったりするときに、シェーダエディタがあるといろいろと便利です。

イージング系の処理を行ってる場合なんかは、結構頻繁に、かなり細かい調整が必要なケースもありますよね。そういうときには、わざわざソースコードのほうを修正してページをリロードするよりも、シェーダエディタでさっくり直してしまうほうが、確認を行いやすいでしょう。

まとめ

さて、シェーダエディタを利用することによって、シェーダのデバッグが多少やりやすくなるかもしれないという可能性が、ちょっとくらい感じられたでしょうか。だとしたら、この無駄に長い文章も、本当の意味で無価値ではなかったということですので、私としては嬉しいです。

フロントエンド界隈のみなさんなら、常日頃から、開発者ツールでサッと CSS を変更し外見を調整したりなさってると思います。今回ご紹介したシェーダエディタは、まさにそういった、とりあえずちょっと内容変えたい、という要望に応えてくれるツールだと思います。

GLSL のデバッグはツライという話をよく見聞きしますし、私も実際苦しいと感じることがあります。ただこれは、まあシェーダコーディングの宿命みたいなものなのかなと最近では思っています。なんとなくね、慣れてくると、なんで思った通りの絵が出ないのか当たりがつくというか、察せるようになってきます。たぶん。

シェーダエディタにはウェブ上に転がっている大量の有用なリソースを手軽に覗き見できるという、楽しく卑しい使い方もありますし、これを機会にぜひ導入しておきましょう。WebGL のサイトを開いたらまずシェーダエディタから見る……そんな生活を知らぬ間に強いられている。それがシェーダ書きたくてしょうがないマンになる第一歩です。