おもちゃラボ

Unityで遊びを作ってます

【Unityシェーダ入門】Unityのシェーダで遊んでみよう

Unityのシェーダって、かっこ良い表現ができるらしいけど、難しそう・・・
というイメージがありますよね。

f:id:nn_hokuson:20160911214243p:plain

実際に、C#のプログラムとかと比べると
すこしトリッキィーに感じる部分も沢山あります。

ですが、基本的には高校レベルの数学と画像処理の簡単な知識があれば(この大前提がそもそも難しいわけですが)なんとかなります。

これから何回かにわたって、シェーダの面白さを紹介していきたいと思います。
まとめ記事はコチラです。
nn-hokuson.hatenablog.com

下準備

最初にシェーダの実験をするプロジェクトの土台を作ります。

といっても、モデルを配置してキューブマップを設定するだけですので、ここでは下ごしらえが終わったUnityプロジェクトを下のリンクからダウンロードして下さい。

Unityプロジェクトファイル

プロジェクトビューで右クリック→「Create」→「Shader」→「Standard Surface Shader」でシェーダファイルを作ります。名前はsampleにしておきましょう。

続けて、いま作成したsampleシェーダを選択した状態で「Create」→「Material」マテリアルを作成します。こちらも名前はsampleにしておきます(シェーダファイルと違う名前でも問題ないです)

f:id:nn_hokuson:20160911221022p:plain:w300

いま作成したマテリアルを3Dモデルにアタッチした後、インスペクタからマテリアルのシェーダをCustom/sampleに変更します。

f:id:nn_hokuson:20160911220810p:plain

見た目は変わりませんが、モデルにはsampleマテリアルにアタッチしたsampleシェーダが適用されています。

このように、Unityではマテリアルとシェーダが一対一でひも付きます

f:id:nn_hokuson:20170401085640p:plain:w350

サーフェイスシェーダの流れ

Unityのサーフェイスシェーダの流れは次の図のようになります。

f:id:nn_hokuson:20170401094055p:plain

詳しくは今後説明しますが、Unityのサーフェイスシェーダには3つの工程があります。Vertexシェーダでは頂点情報を処理します。Surfシェーダではオブジェクトの表面の色を定義し、Lightingではオブジェクトの陰影を決めます。

これからしばらくはピンク色のSurfシェーダの部分だけを扱います。VertexとLightingの工程はUnityが自動生成してくれるので、おまかせしちゃいましょう!

VertexやLightingの工程はトゥーンシェーダ(toon shader)や頂点カラーシェーダ(vertex color shader)の回に書き換えます。
nn-hokuson.hatenablog.com
nn-hokuson.hatenablog.com

シェーダの中身をみてみよう

では、プロジェクトビューのsampleシェーダを開いて中身を見てみましょう。

f:id:nn_hokuson:20170401092738p:plain:w500

いろいろ書いてあって難しそうに見えるかもしれませんが、大きく分けると3つのパートにわかれます。

  • Parameters
  • Shader Settings
  • Surface Shader

Parametersのパートにはインスペクタに公開する変数を書きます。C#スクリプトのpublic変数のようなものと考えれば理解しやすいと思います。
Shader Settingsのパートにはライティングや透明度などのシェーダの設定項目を記述します。
Surface Shaderのパートにはシェーダ本体のプログラムを書きます。この部分を修正して目的のシェーダを作ります。

シェーダを書き換えてみよう

プロジェクトビューのsampleシェーダを開いて、surf関数を次のように修正してください。

void surf (Input IN, inout SurfaceOutputStandard o) {
	// Albedo comes from a texture tinted by color
	fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = fixed4(0.1f, 0.1f, 0.1f, 1);
	// Metallic and smoothness come from slider variables
	o.Metallic = _Metallic;
	o.Smoothness = _Glossiness;
	o.Alpha = c.a;
}

ここで書き換えたのは「o.Albedo=〜」の行だけです。Albedoに代入する値をテクスチャの値ではなく黒色にしています。

f:id:nn_hokuson:20160911230711p:plain

Albedoはオブジェクトの基本色を定義するものです。AlbedoにRGB(0.1, 0.1, 0.1)にしたことでドラゴンが黒色になりました。

ここでドラゴンの表面の色として同じ色を指定しているんだから「もっとのっぺりした影のようなドラゴンになるんじゃないの?」と思ったかたは鋭い!!

f:id:nn_hokuson:20170401094055p:plain

サーフェイスシェーダの流れ図を見るとsurfシェーダでオブジェクトの表面色を指定した後に、ライティングをする工程があることに注目して下さい。
これによりsurfシェーダ直後は真っ黒なドラゴンでも、Lightingの工程で光が当たることで陰影がつき上図のような立体感がでるのです。

今回は一般的なシェーダの中身を簡単に眺めました。次回は、最小限のシェーダを書いてみます。

nn-hokuson.hatenablog.com