【Unity】Shaderことはじめ【Shader : 0】


概要

Shaderを断片的に触ると、久々に書こうとした時に微妙に忘れてしまっているので、継続的に記事にする事で覚えようと思いました。
この記事はShader記事の1つ目になります。

Shaderが何故分かりづらいか?

一応、私は少しC#を書いたりしますが、ShaderはC#に比べて分かりづらいという印象があります。
今まで断片的に調べたり見聞きした結果、Shaderが分かりづらいと感じる原因は以下の理由が考えられると思いました。

1.レンダリング(絵を出す)は、ハードウェアに依存している。
2.ゲームエンジンを使っていると、レンダリングパイプラインを意識する事なく3Dを表示できる(1からレンダリングの処理を見たり書いたりする事がない)
3.高級言語と違い原始的であり、常にピクセルの数だけ実行されるという特殊な前提があるから。

レンダリングは、ハードウェアに依存している

今でこそShaderが書けるのが一般的になりましたが、家庭用ゲーム機で最初にプログラマブルシェーダが採用されたのはXboxらしいです。(DirectX8)
あのプレイステーション2でさえ、固定機能のシェーダーを使っており…基本的には「半透明のテクスチャを大量に重ね書きする事により、シェーダーや特殊効果を実現」していたそうです。そうする事でメーカーごとの個性を出していた。
今から大体19年~18年前を長いと見るか短いと見るかはそれぞれですが…自分は割と最近になってプログラマブルシェーダが定着したんだなと感じました。
Wikipedia - PlayStation 2

現代でさえ、グラフィックボードのバージョンによってはサポートされてない機能などもあるので、最新版のグラボと古いグラボでは、表示の結果が異なる事があります。

この様に、ハード・レンダリング技術・言語仕様が一体となって日進月歩で進化しているので、学習においても体系化されづらいというのと。
日本語ベースの資料が少なく(もちろん存在する)CGの歴史とレンダリング技術の進化を体系的に追いかけるのが難しい?というのがあると思います。

ここら辺の歴史を俯瞰にするには西川 善司様の著書や記事を読むのがいいと思います。
(この方挙げとかないとマサカリ飛んでくるので挙げときます)

余談ですが、日本は海外に比べてCG研究を冷遇していたりします。
「絵を描いて遊んでいる」と言われた。それでも研究者のプライドがあった。

高校数学では行列も教えなくなるそうで、意外とCGに対して厳しい国だと感じます。そんな中、ゲーム/遊技機/映画などのエンタメ産業とか、個人のクリエイターなどを中心に頑張っている印象があります。
今後、VR、ARなんかでCGはより需要が増えると思うので、CGを学ぶ需要は低くないかもしれません。

レンダリングパイプラインを意識しない

主にゲームエンジンなどを使用している場合、基本的な表示に関してはモデルとカメラを配置する事で達成できます。
しかし、本来であればちゃんとこられの処理を書かないといけませんし、昔のゲーム会社は各社独自にレンダリングに必要なライブラリを蓄積し、それぞれの会社毎のゲームエンジン(今のUnityやUE4に相当するのをフルスクラッチ)として3Dの描画に必要な処理を作っていたわけです。
(ゲームエンジンはレンダリング以外の役割もありますが、ここで言いたいのは「本来はレンダリングの処理を1から書かないといけない」という事です)

3Dレンダリングのライブラリを作ろう!という説明となると…おそらくオライリーの 実例で学ぶゲーム3D数学 と同じ内容書く事になるので、書けないし書きません。
しかし、Shaderを語る以上、レンダリングパイプラインの話からは逃れられないので、俯瞰できる教材が必要です。

ちょうどよく、最近Unity道場でShaderに関する講座がありました。
レンダリングパイプラインが分からない方はまずこの講座を見てみるのがいいと思います。
また、見れば何故Shaderがとっつきづらいかも分かるかと思います。

Unity道場 2019.2 シェーダを書けるプログラマになろう #1 シェーダを理解しよう
Unity道場 2019.2 シェーダを書けるプログラマになろう #2 GPUの神秘

高級言語と違い原始的であり、常にピクセルの数だけ実行される

普通のプログラミング言語が様々なタスクを行うのに対して(得手不得手はあります)
Shaderとは、最終的にモニターに写すピクセルの色を決定するタスクのみを行う…と、目的がハッキリしていて範囲も限定的な言語です。
なので、この時点で一般的なプログラミング言語とは大きく異なるわけなので、分かりづらい要因になるわけです。

特に、ピクセルの回数だけ実行される関数があるにも関わらず、for文のように書くわけではない点が処理を追いにくい要因になってると思います。

そして、Shaderは非常に原始的な言語でもあります。
基本的な関数、システムで決まった変数、セマンティック 等しか用意されておらず、特殊な事をやろうとする場合ちゃんと数学を理解してそれらの処理を全部書く必要があります。
つまり、プログラミング言語として見た場合、馴染み深いようなものではないという事です。

まとめ

ものすごいざっくり、CGの歴史とレンダリングパイプラインについて触れました。
これで一応、自分の記事では説明している…という事にしてほしいです…。

というのも、ガチでCGの歴史を振り返ると大変な事になってしまうし、非常に難しいし、全然理解していないので…。
ただ、分からないなりに勉強した結果、その道中で見つけた教材や、思った事学んだ事についてなら書く事ができると思いますし、まったく知らない人よりは知ってると思うので、Shaderの記事を書いてゆきます。

最後に、上記で触れてない教材を紹介して終わろうと思います。

個人的に良かった教材

Unity Graphics Programming
難しいけど非常によい本。Vol.1~3で6000円しますが内容に対して非常に安い。
ちゃんと学術的?にCGの基礎を学ぶ事ができる。日本語で!

Unity Shader Programming Vol.01 (v.1.1.1)【PDF】
ちょうどVRChatでShader需要が増してる時に出た教材。
これはShaderLabに絞って、俯瞰して仕様を把握したりざっくり使えるようになるための本。
CGのアルゴリズムそのものは学ぶ事はできないけど、とりあえずShaderLabを使えるようにするという用途においてすごいお手頃な感じです。

Unityシェーダープログラミングの教科書 ShaderLab言語解説編
Unityシェーダープログラミングの教科書2【反射モデル&テクスチャマップ編】
Unityシェーダープログラミングの教科書3 ライティング&GI(大域照明)解説編
言語解説ではShaderLabそのものの基礎を、2の反射モデル&テクスチャマッピング編では実践的なシェーディングの考え方などを解説されています。
これも貴重な日本語ベースのShader本なので、おさえておきたい所です。

Unity、UnlitShader/textureのコードを追いかける【Shader : 1】