シェーダーを作るまでの基礎の基礎


挨拶

もう少しで今年が終わりますね。
本記事では、私が今年ダラダラと触り続けたShaderについて少しお話します。
初歩的なことについて触れるつもりですが、わからない部分が多いかもしれません。
初歩だからといって、補足を全て入れるのは面倒くさいので
補足はあまり入れる余裕がなさそうなので、各々で補ってください。

では本題に入っていきましょう!!

目次!

  1. そもそもShaderて何?
  2. レンダリングパイプライン
  3. UnityにあるShaderの種類・違い
  4. これまでの振り返り
  5. それぞれのシェーダーの中身
  6. 何が言いたいのか
  7. 最後に

そもそもShaderて何?

Shaderと聞いて陰影処理を入れることなのかな?と思う方もいるかと思います。
shaderとはオブジェクトをディスプレイに映し出すためのプログラム全般のことです。
また、オブジェクトを描画するまでに行われる処理の流れをレンダリングパイプラインといいます。

レンダリングパイプラインについて

※今回紹介するのはBRPです。
この内容については、
こちらの動画の一部のスライドで以下のように説明されています。

引用です。

この中でプログラマブルな部分を紹介していきます。
       (重要な部分の紹介)

1 . ◎頂点単位の計算

頂点シェーダーと呼ばれる部分。
オブジェクトを現在のカメラから見たときの位置に調整するのがここのお仕事!
手順としては、オブジェクトをモデル空間からクリッピング空間に変換するのが基本です。
計算方法はここでは話しませんが、下におすすめの記事貼っておきます。

2 . ◎ピクセル単位の計算

フラグメントシェーダー(ピクセルシェーダー)と呼ばれる部分。
現在選ばれてるピクセルにどういう色を塗るかを決定する。
選ばれるピクセルとはラスタライズという処理によって決められる。
実際に書くときに複雑化しやすい部分です。

3 . そのほかのやつ

他にも、頂点の増減やCullingなどの設定をShaderで書くことができます。

頂点の増減(ジオメトリシェーダー)
ジオメトリシェーダーとは、フラグメントシェーダーに
渡される頂点の集合を加工する処理です。
端的に言うと、オブジェクトの頂点数を増減させることができたり
ポリゴンのプリミティブを変更することができます!
頂点シェーダー・フラグメントシェーダーは必須ですがジオメトリシェーダーは
よく使う処理ではないため、あまり聞いたことがない人が多いかも…

次にCullingです。
Cullingとは描画するべきポリゴンとしなくていいポリゴンを分けるのが役割です。
Unityのカメラを弄ったことがある人は、Culling Maskとかがイメージしやすいかも。

UnityにあるShaderの種類・違い

UnityのShaderにはいくつか種類があります。

1.サーフェスシェーダ 
2. vartex/fragmentシェーダー(unlit)
3.Shader Graph

Unityのバージョン、作成するProjectの種類によって使えるものが変わってきます。
(Projectの種類によってレンダリングパイプラインは変化します)
以下がそれぞれの詳細です、computeShaderは省きます。
あとShaderGraphについてもよくわからない部分が多いので、一括りにしますが実際はShader graphにも種類があるようです

それぞれのまとめ

サーフェスシェーダ vartex/fragmentシェーダー Shader Graph
特徴 ・Lightingやよく使う変数が用意されている。
・変数に値を渡せば簡単に見た目を調整できる
・用意されている変数が少ない
・Lightingが用意されていない
・ノードを作りそれらを
GUIで操作しShaderを作れる
柔軟性 割と高い、物理レンダリング適してる 柔軟性の塊 分からんけど高そう
触りやすさ 一番簡単 難しい 分からん
Projectの種類 Version: 2020.2以下のBRP、URP、SRP、HDRP どれでも使用可能 HDRP、SRP、URP

これまでの振り返り

ここら辺で「よくわからん」となった人のためのコーナ行きます!
・オブジェクトをディスプレイに移すためには、レンダリングパイプラインを通さなきゃいけない。
・レンダリングパイプラインでプログラマブルな部分は頂点シェーダーフラグメントシェーダー
・シェーダーには種類があり、それぞれ違う特徴などを持つ。
・頂点シェーダー、フラグメントシェーダーはShaderで処理を書く。

それぞれのシェーダーの中身

次にShaderの中身について少し触れていきましょう。
今までの話だと、ShaderにはVertexShaderとFragmenShaderがあり
そこに処理を書くイメージになってると思います。
実際にUnity内でCreateし確認しましょう。

 ↓サーフェスShader

 ↓v/fシェーダー

実際にUnityでサーフェスシェーダーとv/fシェーダーを作成してみました。
v/fシェーダーには、頂点シェーダー・フラグメントシェーダーぽいのがありますね。
サーフェスには頂点シェーダー・フラグメントシェーダーぽいのは見当たりませんね。
ここら辺の違いを次で解説します

中身の違いについて

結果から話します。そういうもんなんだ程度に思ってください。

サーフェスシェーダーには、fragmentシェーダーという処理はありませんが
それぞれ指定した値を使い処理を作ることで
後にUnity側がvartex/fragmentシェーダーに変換してくれます
Shader Graphも同様に、ノードを操作し処理を作ると
Unity側がvartex/fragmentシェーダーに変換してくれます

(サーフェスシェーダーでもvertex関数は使用できます)

タイミングは違いますが、どのShaderを使って作成してもコンパイルする前にはvartex/fragmentシェーダーに変換されるわけです。

何が言いたいのか

最初はvartex/fragmentシェーダー(unlitシェーダー)を書けるようになった方がいいかな。
理由としては、Projectやバージョンによっては
サーフェスシェーダは使えないことがちょいちょいあるみたい、
GUIベースのShader Graph君は、コード理解してる人が使えば便利なものだけど
コードが書けない人は結局、処理を組み立てにくいだろうって話。
初めてShaderをやる人はvartex/fragmentシェーダーで基礎を固めるべきだと思う。

あとはそれぞれ用途・目的に合わせて使っていこう。
時間が無くてとか、早くShaderを書きたい人はサーフェスシェーダでいい。
サーフェスシェーダは物理レンダリングに強いけど、ビジュアルエフェクトとか
物理ベース以外は難しいのであんまりオススメはしませんが。
それにサーフェスシェーダしか書けなかったら、一部のrpではShaderが書けなくなります。
あまり触れれなかったShader Graph君は、ノードを繋げてShaderを作れるのは簡単そうに見えるけど、
どうなんだろうって感じです。ある程度コード書けなきゃさすがに使えないだろうけど。

最後に

始めて記事書いてみたけど、むずいっす。
文字だらけで申し訳ない。
あとプレビュー画面とちょっと違うのなんでなん、、、、、
インデントが少し崩れてますが、今回はこれで勘弁してほしいです。

今度時間があれば、実際にコードに触れながら処理を解説していきます。。。
時間があれば

参考文献