はじめに
今回はStandardShaderを置き換えて軽量化しようという記事になります!
まずStandardShaderは様々な機能を持つ万能なシェーダです。
公式にあるお堅い言葉にするとこんな感じ。
Unity の Standard Shader は、包括的な機能を持つビルトインシェーダーです。
Standard Shader によって、すべてのマテリアルタイプで使用できるよう、様々なシェーダータイプ(Diffuse、Specular、Bumped Specular、Reflective など)が 1 つのシェーダーに結合されます。
普段シェーダーを触ったことがない方は基本的にはこちらを無意識に利用しているはずです。(デフォルトがこれのため)

ただし万能が故に、使わない機能も多く無駄な処理がなされている可能性も大いにあります。
特にモバイルゲームではここを改善することでパフォーマンスが向上したりするかもしれません。
そこで今回は実際にStandardShaderを置き換えてみましょう。
自作シェーダー
まずはStandardShaderでいうAlbedo(テクスチャではなく色)のみを持つシェーダーを書いて、置き換えてみます。

その前に、StandardShaderのプロパティがどのように実装されているかをみてみましょう。
Properties {
_Color ("Color", Color) = (1.000000,1.000000,1.000000,1.000000)
_MainTex ("Albedo", 2D) = "white" { }
_Cutoff ("Alpha Cutoff", Range(0.000000,1.000000)) = 0.500000
_Glossiness ("Smoothness", Range(0.000000,1.000000)) = 0.500000
_GlossMapScale ("Smoothness Scale", Range(0.000000,1.000000)) = 1.000000
[Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0.000000
[Gamma] _Metallic ("Metallic", Range(0.000000,1.000000)) = 0.000000
_MetallicGlossMap ("Metallic", 2D) = "white" { }
[ToggleOff] _SpecularHighlights ("Specular Highlights", Float) = 1.000000
[ToggleOff] _GlossyReflections ("Glossy Reflections", Float) = 1.000000
_BumpScale ("Scale", Float) = 1.000000
[Normal] _BumpMap ("Normal Map", 2D) = "bump" { }
_Parallax ("Height Scale", Range(0.005000,0.080000)) = 0.020000
_ParallaxMap ("Height Map", 2D) = "black" { }
_OcclusionStrength ("Strength", Range(0.000000,1.000000)) = 1.000000
_OcclusionMap ("Occlusion", 2D) = "white" { }
_EmissionColor ("Color", Color) = (0.000000,0.000000,0.000000,1.000000)
_EmissionMap ("Emission", 2D) = "white" { }
_DetailMask ("Detail Mask", 2D) = "white" { }
_DetailAlbedoMap ("Detail Albedo x2", 2D) = "grey" { }
_DetailNormalMapScale ("Scale", Float) = 1.000000
[Normal] _DetailNormalMap ("Normal Map", 2D) = "bump" { }
[Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0.000000
[HideInInspector] _Mode ("__mode", Float) = 0.000000
[HideInInspector] _SrcBlend ("__src", Float) = 1.000000
[HideInInspector] _DstBlend ("__dst", Float) = 0.000000
[HideInInspector] _ZWrite ("__zw", Float) = 1.000000
}
この一番上にある_Colorが今回の目的のAlbedoという文字の右にある色のことです。

ちなみになんですが、StandartShaderは50871行もコードがあるみたいでした。
行が長いから重いとは限りませんが、想像以上にすごくてビックリです。

追記)このようなご指摘をいただきました。
モバイルだとシェーダ言語はGLSLになる(スクショの言語は別)ため、
— SpearSoft@個人ゲーム開発者 (@SpearSoftGames) March 4, 2020
このシェーダプログラムは変換されて全てが使われるわけではないとは思います。
本当に50000行なら現行のモバイル端末では全く動かない気がします
これをSurface Shaderで書いてみましょう。
Shader "Custom/Simple" { Properties{ _Color ("Albedo", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3.0 struct Input { float2 uv_MainTex; }; fixed4 _Color; void surf (Input IN, inout SurfaceOutputStandard o) { o.Albedo = _Color.rgb; } ENDCG } FallBack "Diffuse" }
あとはマテリアルのシェーダーをCustom -> Simpleに置き換えれば、自動的に色も引き継がれます。


モバイル用シェーダーに置き換える
実はUnityはモバイル用にシンプルなシェーダーを事前に用意してくれています。
docs.unity3d.com
場所はMobileカテゴリ以下にある奴です。

これらはたとえモバイルでなくとも用いることができ、よりパフォーマンスを出すことができます。
しかし機能に制限がつくことだけは注意してください。
- シェーダーに色合いを加えるマテリアルの色や主要な色はありません
- シェーダーが法線マップを取得するために、ベーステクスチャからタイリングとオフセットが使用されます
- パーティクルシェーダーは AlphaTest と ColorMask をサポートしません
- 制限された特性とライティングのサポート - 例えば、シェーダーの中には 1 つのディレクショナルライトしかサポートしないものがある、など
さいごに
今回自作のシェーダーも作りましたが、実際にどれくらいのパフォーマンスの改善があったかは計測していないのでわかっていません。
ただしモバイルシェーダーは確実に効果があるはずなので、まずはそちらを利用してみると良いかもしれないですね。
ではまた。