Unityでシェーダーの記載方法を現役エンジニアが解説【初心者向け】

Unityの表現方法をぐっと広げるシェーダーの基本と実用的なサンプルシェーダーを紹介しています。 シェーダーの書き方も詳しく紹介しているので、Unityで表現の幅を広げたいひとにぜひお勧めです。

TechAcademyマガジンはオンラインのプログラミングスクールTechAcademy [テックアカデミー]が運営する教育×テクノロジーのWebメディアです。初心者でもすぐ勉強できる記事が2,000以上あります。

Unityではオブジェクトを画面に表示するためにシェーダー(Shader)というプログラムが使用されています。

このシェーダーを独自に作成・改造することで、表現の幅をぐっと広げることができます。今回の記事では、シェーダーとは何かという概念と、実開発でも役に立つシェーダーのサンプルを紹介します。

 

なお、本記事はTechAcademyのUnity入門オンライン講座の内容をもとにしています。

 

20163020-2

 

今回はUnityのシェーダーを書いていくよ。

 

20160620

 

田島メンター!! シェーダーってどういうところで使われているんですかー?

 

20163020-2

シェーダーはオブジェクトを画面に描画(表示)するのに使われているよ。色や陰影や透明度などを計算するプログラムなんだ。早速解説を見ていこう

 

 

目次

本記事では下記の流れでシェーダーについての説明を行っていきます。

 

シェーダーとは

シェーダーとは、オブジェクトの表示(主に陰影)を計算するためのプログラムです。

元々は3DCGの用語ですが、2Dのオブジェクトもシェーダーによって色やテクスチャや透過などが設定されています。処理としては、カメラから見たオブジェクトの角度、設定された色、貼り付けられたテクスチャ、光源から照らされている角度などを総合的に判断して、平面であるディスプレイにオブジェクトを表示する際の色や形を計算しています。

言葉では概念が掴みづらいので、実際に画面で確認してみましょう。準備として、3Dオブジェクト(Sphere)と新しいマテリアルを作成します。
 

 

次に、作成したマテリアルを、作成したスフィアのMesh Rendererコンポーネント・Materialsプロパティ・Element 0に設定します。これで準備は完了です。

 

シェーダーはマテリアルに対して設定するので、マテリアルを選択してインスペクタを確認します。上部の、Shaderというプロパティが、現在選択されているマテリアルに設定されているシェーダーです。

デフォルトではStandardシェーダーが設定されています。シェーダープロパティ以下のプロパティはすべて、選択したシェーダーのプロパティになっています。

 

試しにStandardシェーダーの値を編集してみましょう。まずはMetalicの値を0から1に増やしてみます。

陰影の丸みが強調されて金属的な質感になりました。

次に、オブジェクトの色を変更してみます。Standardシェーダーでは、オブジェクトの色はAlbedo(反射光)というプロパティで表現されています。他のシェーダーだと、Main Colorなどの名前で表現されていることもありますが、挙動としては同一になります。

オブジェクトの色が変化しました。反射光の特徴として、あくまで反射なので元の色より明るい色にはならないというものがあります。灰色のオブジェクトを黒にすることはできますが、灰色のオブジェクトを白にすることはできません。

次に、オブジェクトの発光色を変更してみます。Emissionにチェックを入れ、Colorの値を変更します。

Albedoの赤とEmission Colorの青が混ざって紫色になりました。発光色という名称ですが、周囲のオブジェクトを照らすことはありません。あくまでも自身の発光している色になっています。発光色の特徴として、元の色より暗くはできないというものがあります。

灰色のオブジェクトを白くすることはできますが、灰色のオブジェクトを黒くすることはできません。以上が基本的なシェーダーの設定方法です。

 

[PR] Unityを使ったゲーム開発で挫折しない学習方法を動画で公開中

シェーダーを書いてみる(サンプル1.既存のシェーダーを自分で書いてみる)

 

20160620

 

シェーダーの選び方と設定の仕方はなんとなくわかりました! でも、自分で作るイメージがまだわかりません・・・

 

20163020-2

 

1つ1つ進めていこう。まずはシェーダーの作成からやってみようか

 

20160620

 

わかりました!

 

 

シェーダーの作成は[Assets]->[Create]->[Shader]から行えます。今回は1からシェーダーを作成するため、どのシェーダーを選んでも中身を消してしまうのですが、Unlit Shaderを選んでみましょう。

 

アセットフォルダに新しいシェーダーが作成されました。ダブルクリックして開いてみましょう。デフォルトでコードが書かれていますが、今回は全て選択して削除してしまいます。

コードを削除したら、下記のコードをコピー&ペーストします。

 

Shader "Custom/SampleShader1"
{
	// インスペクタに表示される設定項目
	Properties {
		_Texture("Texture", 2D) = "white" { }
		_Color ("Color", Color) = (1,1,1,1)
	}
	// 描画計算の記述
	SubShader {
		// 一連の計算
		Pass {
			// 陰影計算を行う
			Lighting On
			// 質感を反映
			Material {
				// インスペクタで設定した色をディフューズカラーに設定
				Diffuse [_Color]
			}
			// テクスチャを反映
			SetTexture [_Texture] {
			Combine texture * previous
			}
		}
	}
}

コードの説明はこの後行っていくので、一旦このコードを画面に反映させる準備をしてみましょう。シェーダーを設定するためのマテリアルを作成します。

[Assets]->[Create]->[Material]

マテリアルのShaderプロパティに、先程作成した[Custom/SampleShader1]シェーダーを設定します。

3Dオブジェクトのキューブを作成します。

[GameObject]->[3D Object]->[Cube]

作成したキューブに、作成したマテリアルを設定します。

これで画面への反映の準備は完了です。
試しにマテリアルのインスペクタから、Colorの項目を編集してみましょう。

オブジェクトの色が変わりました。

次に、以下の画像をダウンロードしてUnityプロジェクトに追加し、マテリアルのTextureに設定してみましょう。

テクスチャが反映されました。これでテストも完了です。それではコードを1行ずつ見ていきましょう。

 

Shader "Custom/SampleShader1"

最初の行には、シェーダーの名前を入力します。スラッシュで区切ることで、階層構造として記述することができます。

シェーダー名とファイル名は同じである必要はありませんが、わかりやすさのために同じにしておくことを推奨します。

  Properties {
    _Texture("Texture", 2D) = "white" { }
    _Color ("Color", Color) = (1,1,1,1)
}

次にPropertiesというブロックがあります。これはインスペクタに表示される設定項目です。今回は基本となるテクスチャと色の設定項目を定義しています。構文は以下のようになっています。

変数名(“インスペクタでの表示名”, 型) = 初期値

SubShader {

次にサブシェーダーブロックがあります。このブロックがシェーダーの本体になっており、サブシェーダーブロックは1つ以上のパス(レンダリングパス)ブロックを含みます。

Pass {

パスブロックの中に、実際の描画計算処理を書いていきます。

Lighting On

ライティング(光源計算)を行う設定の記述です。こうした設定はパスもしくはサブシェーダーの最初に記述します。サブシェーダーに記述した場合、全てのパスに適用され、パスに記述した場合、サブシェーダーよりも優先度が高くなり、そのパスの中にのみ適用されます。

主な設定項目は以下のようなものがあります。

  • Cull : カリング。ポリゴンの裏もしくは表を描画しない設定ができます。両方とも描画することも可能です。
  • AlphaTest : アルファテスト。アルファ値の比較によって画面に描画するピクセルを設定することができます。アルファが0以下のピクセルを描画しない設定にすることで、オブジェクトに透明部分を設定することができます。
  • Blend : 半透明オブジェクトの色計算方法です。すでに描画されている色に対する処理と、新しく描画される色に対する処理を記述することができます。
Material {
  Diffuse [_Color]
}

次にマテリアルブロックがあります。質感に関わる設定を行うことが出来、Diffuseの他にも以下の設定ができます。

  • Ambient : 環境光からの影響
  • Shininess : 光沢
  • Specular : 鏡面色
  • Emission : 発光色

また、[_Color]と書かれている部分がPropertiesで定義した_Color変数への参照です。このように変数は[]で囲んで使用します。

SetTexture [_Texture] {
  Combine texture * previous
}

最後にテクスチャ設定コマンドがあります。先程のマテリアルブロック同様、Propertiesで定義した_Textureに対して処理を行っていきます。
Combineコマンドは色、テクスチャ、アルファ値を結合します。構文としては、以下のようになります。

  • Combine 色の値, アルファの値

また、SetTextureコマンドに指定したテクスチャ(ここでは_Texture)がtextureという名前で使用でき、1つ前の計算結果(ここではMaterialの計算結果)がpreviousという名前で使用できます。

シェーダーの記述にはこのように暗黙のルールが多いので、一度は公式のリファレンスに目を通すことをおすすめします。
(公式リファレンス:https://docs.unity3d.com/ja/current/Manual/SL-Reference.html)

 

シェーダーを書いてみる(サンプル2.実用的なシェーダーを書いてみる)

20160620

 

田島メンター!! 覚えることが多すぎて、シェーダーを書けるようになる気が全然しません!

 

20163020-2

 

シェーダーを書くには3DCGの知識がある程度必要だからね。構文が簡単でもまずは概念を理解していないと中々難しいかもしれないね

 

20160620

 

3DCGについても勉強してみます・・・でも簡単に使える便利なシェーダーとかはないんでしょうか・・・

 

20163020-2

 

では実用的なシェーダーをもう一つ例として見てみよう

 

 

Shader "Custom/SampleShader2"
{
  Properties {
    _Texture ("Texture", 2D) = "white" {}
    _Albedo ("Albedo", Color) = (1,1,1,1)
    _Emission ("Emission", Color) = (0,0,0,1)
    _Alpha ("Alpha", Range(0.0, 1.0)) = 1.0
  }
  SubShader {
    Tags {
      // 透過オブジェクトとして描画キューに入れる
      "Queue" = "Transparent"
      "RenderType"="Transparent"
    }
    Pass {
      // 両面を描画
      Cull Off
      // 透過の設定
      AlphaTest Greater 0
      Blend SrcAlpha OneMinusSrcAlpha
      // 反射色を計算
      SetTexture [_Texture] {
        constantColor [_Albedo]
        Combine texture * constant
      }
      // 発光色を計算
      SetTexture [_Texture] {
        constantColor [_Emission]
        Combine previous + constant
      }
      // 透明度を計算
      SetTexture [_Texture] {
        constantColor (1, 1, 1, [_Alpha])
        Combine previous, texture * constant
      }
    }
  }
}

このシェーダーには、以下の機能があります。

  • 光源の影響を受けず、テクスチャをそのまま出力できる
  • 色乗算(色をつけて暗くできる)
  • 色加算(色をつけて明るくできる)
  • 透明度の設定(設定項目が独立している)
  • 裏表両方が描画される

どれもゲーム開発で非常によく使う機能なので、このままでも実際のアプリ開発に使えるようになっています。デフォルトでは上記全ての機能を含めたシェーダーがないので、1つ用意しておくことをおすすめします。

前半でコードの内容を紹介したので、後半ではこのシェーダーの挙動を紹介していきます。

ライトの向きが変わっても、光源の影響を受けません。

色を付けて暗くすることができます。この色設定では明るくすることはできません。

色を付けて明るくすることができます。この色設定では暗くすることはできません。

透明度を設定することができます。テクスチャの透明度は描画に反映されますが、AlbedoとEmissionのAlphaは反映されません。

ひっくり返すと裏も描画されています。2Dやスプライトとして使う場合は裏面は描画しなくて良いので、

Cull Off → Cull Back

と変更しましょう。裏面のみが描画されなくなります。

まとめ

今回の記事は以上です。記事本文でも書きましたが、シェーダーは3DCGの知識が前提として必要なため、なかなかすぐに理解できるものではないかもしれません。

・3DCGの理解
・公式リファレンスの確認

を繰り返してすこしずつ理解していきましょう。
(公式リファレンス:https://docs.unity3d.com/ja/current/Manual/SL-Reference.html)

 

20163020-2

 

シェーダーの基本については以上だよ

 

20160620

 

表示について細かい設定ができるってことがわかりました

 

20163020-2

 

シェーダーはアセットストアでもいろいろなものが公開されているから、高度な画面表示を行いたい場合はそちらもお勧めだよ

 

20160620

 

他の人が作ったシェーダーも使えるんですね! いろいろ見てみます!

 

(アセットストアの使い方:https://techacademy.jp/magazine/2222

 

[お知らせ]TechAcademyではオリジナルゲームアプリが公開できるUnityオンラインブートキャンプを開催しています。現役Unityエンジニアのサポートで効率的に学びたい場合はご検討ください。