スクリーンショット_2019-04-05_22

プログラミング初心者からthree.jsに慣れるまで

こんにちは。
私は現在クリエイティブディベロッパーという、フロントエンド+WebGL 実装する仕事を2年半ほどやっています。

1年半東京の会社で働いたあと半年間フリーランスをして、その後アムステルダムの会社に入社して現在8ヶ月経ちます。

three.jsで絵を作るのが好きで、仕事でもプライベートでもこんなかんじのものを作っています。ほとんどtwitterにあげてるので、興味がある方はぜひ見てみてください。

最近ツイッターのDMでどうやってthree.jsを勉強すればいいかアドバイスが欲しいというのをもらうことが多くなってきたんですが、この質問に答えるのは難しいなと感じています。

人によって得意不得意があるし、始めようと思った時点でどのくらいプログラミングや数学に精通しているか人それぞれすぎて、これがベストな勉強法!これをやれば誰でも大丈夫とは言えないです。

この記事では、私が初心者レベルから勉強する過程で苦しんだ部分と良かった部分をだらだらと書いていきます。

コツというか気負わずにやっていく方法についてなにか参考になればいいなと思います。

three.js(WebGL)に興味を持ったきっかけ

2015年夏にどこかの記事でWebGLを使ったすごいサイト集をやっていて、そこではじめてWebGLと言う技術を知りました。

見たのはだいぶ前なので今はちょっと違う感じなんですが、homunculusという会社のサイトを見た時の感動を今でも覚えています。

webなのにマウスの動きでぐにゃぐにゃしたり、画像が折り紙みたいになったりして、一体どうなってるんだろうってすごく興味を惹かれました。

ただ、その時のプログラミング力は基礎中の基礎で、jQueryをコピペして使う程度のレベルだったので自分でthree.jsをやってみようとは思わなかったです。

three.jsをやりたいと強く思ったのは、今まで見たことのないおしゃれチュートリアルを見つけた時です。いい意味でプログラミング感とwebサイト感を出していないこの雰囲気にすごく憧れて、私もthree.jsで何か良い感じの物を作りたいって思いました。

あれから3年経ちますが、今でも素晴らしい作品だと思います。

プログラミング初心者にとってソースコードが長い

three.jsはWebGLを簡単に扱えるライブラリとして知られています。
そんなお手軽ライブラリでも、プログラミング初心者にとってはソースコードが長いです。立方体を出すのにunityの場合は動作一つでぽんっと出せるのに、three.jsの場合はなんて長いんだと思っていました。

50行でも難しく感じるので、さっきのチュートリアルは途中で諦めてcanvas2Dから始めてみることにしました。3Dよりも2Dのほうがとっつきやすそうだと思ったので、最初にcanvas2Dで楽しくプログラミングに慣れて、慣れた頃にまたthree.jsを始めようと思いました。

canvas2Dも苦戦した

とは言ったものの、最初はcanvas2Dも難しく感じました。休日や平日夜にずっと写経をしていましたが、全然効果が出ないなと思いました。コードを上から下に写すだけでは、自分ではそのプロセスは到底思いつけないと言う気持ちになるだけで、理解したのかしてないのかもやもやしたままになってしまうことが多かったです。

そもそも、どれがjavascriptのビルドインオブジェクトなのかどれがオリジナルのオブジェクトなのかすら分からず、どうやってググればいいかも分からず、加えてforやifは単体では理解できるものの複数組み合わさると実行順番が分からなくなり、どうすれば理解できるのかこれからどう進めていけばいいのか悩みました。

javascriptをまずは勉強しろという話になっちゃいますが、当時はドットインストールしか知らなくて(当時はprogateあったのかな)そこからどうやって発展的なことをやればいいのかも分からなかったです。

その時適切な勉強法は分からなかったですが、よく分からなくてもデモの見た目が良いとモチベーションが上がったのでチュートリアル記事を写経し続けてました。

魔法のようなチュートリアルビデオ

写経し始めて半月くらい経った時に、海外のとあるcanvas2Dのチュートリアル記事で「もしも数学や物理に不安ならこれを見ると良い」とyoutubeチャンネルをおすすめしているのを発見して、そこからその動画で勉強し始めました。

その動画の投稿者はKeith Petersという、海外ではプログラミングを教えるのがすごくうまいことで有名な人です。日本ではFlashのアニメーションの本の著者として有名です。ゲームプログラミングに必要な数学と物理を教えてくれるのですが、javascript初心者でもついていけるほど易しいです。たくさん動画があるんですが、ひとつひとつ噛み砕いて説明してくれるので、ほとんどの動画を苦しまずに見ることができました。

もっとも有名なのはDaniel Shiffmanだと思いますが、私はそのとき彼を知らなかったのでこれ一つで勉強しました。Daniel Shiffmanのポップな感じとは違って終始落ち着いた語り口なんですが、さらっと説明してさらっと頭に入ってきて、あんなに苦労していたのに簡単なものをやっているかのような錯覚になる不思議なチュートリアルでした。

数学と物理をメインで教えてるんですが、コードの途中で何をやっているのか、何を目指してこのコードを書いているのかを一つ一つ説明してくれたので、あんなに悩んでたアルゴリズムの組み立て方が分かるようになってました。今まで内容が分かっているのかどうかも分からなかった写経していたソースコードも、理解できたと自信を持って言えるようになりました。 

始める前は、高校の時にやってた三角関数も忘れていて物理は苦手意識を持っていたんですが、もう三角関数も思い出したし物理も大丈夫だと思うようになってました。

canvas2D作品作り

インプットを十分にしたら今度は自分で考えて作ってみようと思って、まずは三角関数と高校の時に習ったのを思い出した数列を組み合わせた小さいデモを作りました。小さいデモですがこれは初めて自分で考えて作った当時の自分にとってすごく大きな一歩でした。

これはcodepenに投稿しました。codepenに投稿したものを運営に報告すると、トップページのファーストビューに表示してくれるというのを知っていたので、運営に知らせるためにtwitterアカウントを開設しました。

ラインナップを見るとあまり難易度なく採用されるようです。 当時フォロワーはいませんでしたが、@CodePenを入れると運営の人が私の作品を見つけてくれます。トップページに表示されて、いろんな人が見にきてくれることがすごく新鮮でした。そして思った以上に、コメントをくれるひとが優しくて褒めてくれることが多いことに驚きました。

これは自分の感覚ですが、日本国内よりも海外の人の方がおおげさに褒めてくれる気がします。プログラミング強者の世界のあの独特なとっつきにくい雰囲気ではないので、codepenは初心者にとってすごく優しい環境だなと思います。
その後も定期的に作品をcodepenにあげて、twitterに投稿するのを続けていました。

フロントエンドエンジニアに転職

説明が遅れたんですがこの勉強をし始めたのは、webデザイナー見習いとして新卒で入った会社がweb部門が潰れてしまい次の新しい配属が決まるまで暇をしていた時です。暇でダメ人間になりそうだったので勉強をしてフロントエンドエンジニアに転職したいなと思っていました。

それでダメ元で、WebGLを知るきっかけになったhomunculusという会社にwantedlyでエントリーして、タイミングも良かったらしくポテンシャル採用されました(今は辞めて別の会社にいます)。業務でcanvas2Dは使わないんですが、私のcodepenを見てモチベーションを評価されたらしいです。
フロントエンドエンジニアとして働き始めたのは2016年の夏です。javascriptにもだいぶ慣れてきて、ここから本格的なthree.jsの勉強が始まりました。

three.jsにはshaderが欠かせない

「three.jsにはshaderの勉強は必須だ」とある方のツイートを見てから、shaderというものをやらなきゃなと思いました。それからはshaderをやっていましたが、正直言うとshaderが何者なのかはっきり分かってきたのはここ最近な気がします。

mvp行列もラスタライズもフラグメントシェーダのderivative関数も、その後のdepth testやalpha blendingも最近になって分かるようになってきました。それまでは使い方は分かるけど、なんとなーくこういう仕組みなのかなというイメージで2年ほどthree.jsをやっていたことになります。

なので、振り返ると、今は理解があいまいでも使っていくうちに理解するかもしれないと思って進んでもどうにかなるものだなと思います。周りを見てみるとみんなそんな感じでやってる気がするので、そんなに気負いせずにやっていけばいいと思います。

話を戻すと、shaderは必須かどうかは、慣れてきた私からすると、すごく必須だと思います。three.jsを始めるのにいきなりjavascript以外のことをやるのはとっつきにくいかもしれないですが、やってみると自由度が上がって楽しいです。
(でもこれも人それぞれかもしれないです。もしかしたらapiに慣れてからshaderをやるほうがうまくいく人もいるかもしれないです。これはやってみて自分にとっていい方向を決めるのが一番だと思います)

私の場合は、カメラとシーンとレンダラーを用意してボックスを出すことができたら、次に自分でshaderを書いてみることを始めました。shaderは描画が行われる現場みたいなものなので(jsはデータを用意してshaderに送信する担当)、そこに触れるともっと自分が表現したい色合いやエフェクトを作れるようになります。

ここでshaderについてポジティブなイメージを持って勉強できたリファレンスを紹介します。おかげでshader言語の文法については引っかかることはあまりなかったです。

この本は序盤に「WebGLは学ぶのも使うのも簡単だ」と言ってくれています。心強いです。「簡単だ」って言われると「安心して」と言われている感じがしていいなと思います。
shaderの紹介はチャプター6にあります。「shaderで使われるvecやmatはコンピュータグラフィックの計算で役に立つ。shader言語は3DCG描画をするのに便利だ」とポジティブなこと言ってくれています。

界隈では有名なフラグメントシェーダの解説サイト。雰囲気が柔らかくなんとなく親しみやすいです。

WebGL界で有名な@thespiteさんの記事です。私にとってこれが初めてのshaderチュートリアルでした。

gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

最初はこの一行の意味がわからずコピペでやってました。そんな感じで始めてもなんとかなるので、理解しなきゃ先に進めない!と気負わず使い倒してみてもいいと思います。

3DCGプログラミングはやることがたくさん

three.jsは便利なapiがたくさんあって、3DCGの知識がなくても3D描画できる便利なライブラリです。そのため、自作shaderの道を選ぶと勉強することが多くなります。 three.jsが内部でやってくれていたフォグ、ライティング、シャドウマッピング、ポストエフェクト等などを自分で実装をする必要があるので大変そうですが、ちょっとずつ勉強をして作品をあげてを繰り返していけばいいのかなと思います。

たとえば、最初にあげたチュートリアルの中で綺麗なフォグがthree.jsによって実装されています。これを自分で実装してみたいと思ったときに、「フォグ WebGL」とググると有名な日本語WebGL解説サイトwgld.orgが出てきます。

解説を読んで、途中に出てくるshaderを自分のソースコード内に写して実行してみます。無事にフォグが出てきたらあとは自分でカスタマイズしていけば大丈夫だと思います。もしも解説を読んでも理解ができないときは、別のサイトと見比べたり、英語で調べてみたりするといいと思います。私は途中でわからないと思ったらすぐに閉じてもっと易しくてわかりやすいサイトを探します。

こんな感じで、フォグが終わったら次はライティングを挑戦してみようとか、シャドウマッピングをやってみようとか、作品ごとにひとつ新しい技術に挑戦すると作品もできるし理解も深まって一石二鳥です。

個人的にフォグやライティングなどシンプルな処理はあまり難しくはなかったですが、シャドウマッピングに苦戦しました。WebGLやOpenGLの解説サイトを読んでもどうしてもシャドウがずれる(ピーターパン現象というらしい)のを直せずに、諦めては再度やってみたりを繰り返していました。結局少し別の方法で試して落ち着きました(デプスマップをレンダリングする時とシーンをレンダリングする時でカリングの裏表を切り替える方法にしました)。

自分で実装したシャドウマッピングです。影が描画されている部分に模様が出るようにしています。こういうのが自作シェーダでしかできない表現かなと思います。

これはライティング実験のための小さいデモです。
ライティングの仕方は最初にあげたチュートリアルに大きく影響されています。directional lightと複数のhemisphere lightを組み合わせて絶妙な色を作りたいなと思いました。directional lightとhemisphere lightはthree.jsのソースコードを辿って参考にしました。


フォグ&シャドウマップのためのデモ。

今でも気になる技術があれば作品に取り入れてみることを続けています。最近は、現在勤めている会社のexperimentsに更新しています。

あと、他にどんな技術があるか知るために、three.jsのexampleを見るかhttps://wgld.org/を読むようにしています!

シャドウマッピングのときのようにバグを解決できない時があったら、一旦放っておいて別の技術に方向転換します。調べて1週間経っても分からなかったら一旦諦めて、時間をおいて再度頑張るようにしています。

さいごに

最後に、わたしができるアドバイスは、なるべくつらくない勉強を心がけることです。

まずは手を動かして見て、分からなくて先に進めなかったら分かる説明に出会うまでググる難しい解説文に出会ったらブラウザバックする、そして日本語だけでなく英語でもググること(簡単な説明が多い気がする)を心がけると勉強が続きやすいと思います。難しい解説はレベルアップした時に読めば大丈夫です。

英語で検索するコツは、方法を知りたい時はtutorialを、動かない時はdoesn't workをキーワードと一緒に検索するとだいたい出てきます。もしもヒットしなかったらキーワードを追加したり違う言い回しに変えたりすると良いです(英語が読めなかったらgoogle翻訳を使えばいいんです)。

これならどのレベルの人にも当てはまるアドバイスかなと思います。分かりやすい解説に出会うまでググりまくるというアドバイスは雑だと分かってるんですが、誰かから教えてもらった後も結局自分の力で勉強を続けなければいけないので、ググり力を鍛えるというのは基本的に大切かなと思います。

体感としては、解決の糸口があるところはStack Overflowかthree.jsのissue、quora、あとはOpenGLの掲示板みたいなところ(名前忘れました)に多くあります。あと、画像検索も有効です。良い説明画像があるサイトは良い解説をしていることが多いなと思います。

できない自分を責めずに、自分でも分かるやさしいものをひたすら探すのに注力することで、自信を無くさずにやっていけるのかなと思います。
たまに私は自分をポンコツだと自己嫌悪するので、私もこの心がけを忘れないことを頑張っています。
これを読んでいる人でthree.jsの勉強に悩んでいる人にとって、ネット上のどこかに自分がわかるものがあると信じて気楽に取り組むきっかけになればいいなと思います!

この記事が気に入ったらサポートをしてみませんか?