おもちゃラボ

Unityで遊びを作ってます

【Unityシェーダ入門】フラットシェーディングでローポリっぽく見せる

シェーディングの方法は大きく分けると、次の二つの方法があります。

  • スムースシェーディング
  • フラットシェーディング

f:id:nn_hokuson:20170213195605p:plain:w400

スムースシェーディングは少ないポリゴン数でも、表面がなめらかに見えるように法線情報を補間して表示する方法です。

一方フラットシェーディングは法線情報を補間せずにエッジを強調したシェーディングです。
ほとんどのゲームではスムースシェーディングを使うと思いますが、ローポリのモデルを利用した味のある表現をしたい場合は、わざとフラットシェーディングにすることもあります(↓こんなのとか)

Unityでフラットシェーディングの設定をするには

UnityはBlenderなど3DCGソフトで設定したシェーディング方法でモデルをインポートします
スムースシェーディングで提供されているモデルをUnity上でフラットシェーディングに変更するには次のようにします。

プロジェクトビューでモデルを選択して、インスペクタから「Normal & Tangents」の「Normals」 を「Import」から「Calculate」に変更し、続けて「Smoothing Angle」を「0」に設定してください。
右下のApplyボタンを押すとモデルがフラットシェーディングで表示されます。

f:id:nn_hokuson:20170213194138g:plain

ゲーム実行時にフラットシェーディングに変更する

ゲームの実行中にスムースシェーディングからフラットシェーディングに変更したい場合は、スクリプトを使って変更することができます。
次のスクリプトを作成してモデルにアタッチしてください。

f:id:nn_hokuson:20170213194405p:plain:w250

public class Flat : MonoBehaviour 
{
	void FlatShading ()
	{
		MeshFilter mf = GetComponent<MeshFilter>();
		Mesh mesh = Instantiate (mf.sharedMesh) as Mesh;
		mf.sharedMesh = mesh;

		Vector3[] oldVerts = mesh.vertices;
		int[] triangles = mesh.triangles;
		Vector3[] vertices = new Vector3[triangles.Length];

		for (int i = 0; i < triangles.Length; i++) 
		{
			vertices[i] = oldVerts[triangles[i]];
			triangles[i] = i;
		}

		mesh.vertices = vertices;
		mesh.triangles = triangles;
		mesh.RecalculateNormals();
	}
	
	void Update () 
	{
		if (Input.GetMouseButtonDown (0))
		{
			FlatShading ();
		}
	}
}

このスクリプトでは、現在のメッシュから新しいメッシュを作成し、最後にRecalculateNormalsを読んでいます。
RecalculateNormalsメソッドではスムースされていない法線情報が生成されるため、結果的にフラットシェーディングのモデルが生成されます。

f:id:nn_hokuson:20170213194425g:plain

スクリプトからシェーディングを変更する方法は、こちらの記事を参考にさせていただきました。
answers.unity3d.com

RecalculateNormalsの仕組みについてはこちらの記事が詳しかったです。
schemingdeveloper.com

まとめ

Unityでフラットシェーディングをするための設定方法を紹介しました。
ローポリのモデルを使ったゲームを作るときは参考にしてみてくださいね。