てんちょーの技術日誌

自分がつまづいたこととかメモ

【Unity】Fragment Shader と Surface Shader を一緒につかってみた【Shader】

引っ越しました。インターネットがありません。

はじめに

凹みさんの記事が読めればできます。 おわり。

tips.hecomi.com

この記事は先述の凹みさんの記事からいくつか抜粋して、簡略化したもの です。

簡易版というか最低限のコードを描くと、最終的にはこうなります。

そもそもなんで

Unity で使えるShaderはいろいろありますが、よく使うのは

  • Vertex Shader (以下 Vertex)
  • Surface Shader (以下 Surface)
  • Fragment Shader (以下 Fragment)

あたりだとおもいます。 で、これらを使うときには

  • Vertex + Surface
  • Vertex + Fragment

のペアで使うのが一般的だと思います。というかこれしか出来ない と思っていました。 ですが、ふと

Vertex + Fragment + Surface

はできないのかな と思っていろいろ調べて、先程の凹みさんの記事をよんでいたらできることがわかったので、かいておこうかなとおもいます。

今回は Shaderとは? みたいな説明は省略します。いろいろ良い記事があるので、そちらを参照ください。

コード

先にコードをはります。

gist.github.com

とこのように Surface, Vertex, Fragment がならんでおります。

簡単なせつめい

まず見通しをよくするためにForward Baseしか計算していません

Surfaceは人類がShaderを書く時に楽ができるようにしてくれている やつなので、「内部的にはfragmentに展開している」 と考えればそんなに難しくないかな とおもいます。

Vertex

Vertexは普段とほとんどやることはほぼ変わらないので、よいかとおもいます。
ただUNITY_TRANSFER_LIGHTINGがちょっとよくわからなかったので、だれか教えて…

surface

Fragmentに行く前に、surfaceを見ておきましょう
といってもStandard Surfaceと同じなので、ここは問題ないかなとおもいます

fragment

さて、今回の見どころはここです

ざっくり流れを説明すると

  1. Surface用の初期化と設定
  2. Surf関数を呼ぶ
  3. Lightの減衰 atten を取得
  4. GIの初期化と設定
  5. Standard用Lightningの計算

という感じです。こんなことができるんだ…

ほぼお作法みたいな感じな気がしますが。
Surfaceの関数だけ使いたいなら、上二つまででよいです。

せっかくならGIも と思って書いてあります。

これのいいところ

fragment で surface の展開ができる ということは、

  • 手元で書いてるのは fragment だけど、みつけたsample は surface だった
  • Unity GI を自前で計算できる

あたりかな…
GIを自前計算するときにsurfaceで使ってる情報が必要になってくるのでsurface周りの処理は省略はできなさそう。

個人的には冒頭の凹みさんの記事にある

機能単位(ライトマップ、リアルタイムGI、ライトプローブ、リフレクションプローブなど)を把握していれば、どこで何が行われているのか、ということを理解できるのではないでしょうか。これを理解するだけでも、自分の好みの絵作りをしたいときに役に立つよう使うことは可能だと思います。ということを示せるよう、どこかでトゥーンシェーディングに PBR の結果をブレンディングする内容を書いてみたいと思っています。

トゥーンシェーディングに PBR の結果をブレンディングする

にべんりかなぁ とおもいました。そのきっかけになれば〜

まとめ

SurfaceはFragment内で展開できる
トゥーンシェーダーにPBRの結果を混ぜられそう

なにかあれば Twitterで〜

twitter.com

引っ越し祝いも待ってます💕