見出し画像

【Unity】StandardShaderを改造する

StandardShaderはUnityに標準でビルトインされているシェーダーで、オブジェクトに対して光や影の計算を行ってくれます。今回はこのStandardShaderをカスタマイズする方法を解説します。

環境

Unity 2021.3.4f1 Windows 10

1. StandardShaderのダウンロード

StandardShaderはUnityにビルトイン(=組み込まれている)されているシェーダーのため、直接編集することができません。しかしながら、シェーダー自体はUnity社から公開されているので、これをコピーしてカスタマイズしていきます。

ビルトインシェーダーはUnity ダウンロード アーカイブからダウンロードすることができます。

ビルトインシェーダーのダウンロード

2. StandardShaderと関連ファイルのインポート

StandardShaderはいくつかのファイルで構成されています。ビルトインシェーダーがダウンロードできたら以下の4つのファイルを使用するUnityプロジェクトへインポートします。

インポートが完了したら区別ができるようにこれらのファイル名を上から順に以下のように変更します。(末尾にCustomを付加)

3. StandardShaderの改造

ここからが実際の改変内容になります。今回はStandardShaderの処理にグレースケールの機能を追加してみたいと思います。それぞれのファイルを以下のように変更します。

StandardCustom.shader

-Shader "Standard"
+Shader "StandardCustom"
 {
     Properties
     {
@@ -45,6 +45,8 @@ Shader "Standard"
         [HideInInspector] _SrcBlend ("__src", Float) = 1.0
         [HideInInspector] _DstBlend ("__dst", Float) = 0.0
         [HideInInspector] _ZWrite ("__zw", Float) = 1.0
+
+        _Brightness("Brightness", Range(0.0, 1.0)) = 1.0
     }

     CGINCLUDE
@@ -90,7 +92,7 @@ Shader "Standard"

             #pragma vertex vertBase
             #pragma fragment fragBase
-            #include "UnityStandardCoreForward.cginc"
+            #include "UnityStandardCoreForwardCustom.cginc"

             ENDCG
         }
@@ -126,7 +128,7 @@ Shader "Standard"

             #pragma vertex vertAdd
             #pragma fragment fragAdd
-            #include "UnityStandardCoreForward.cginc"
+            #include "UnityStandardCoreForwardCustom.cginc"

             ENDCG
         }
@@ -191,7 +193,7 @@ Shader "Standard"
             #pragma vertex vertDeferred
             #pragma fragment fragDeferred

-            #include "UnityStandardCore.cginc"
+            #include "UnityStandardCoreCustom.cginc"

             ENDCG
         }
@@ -256,7 +258,7 @@ Shader "Standard"

             #pragma vertex vertBase
             #pragma fragment fragBase
-            #include "UnityStandardCoreForward.cginc"
+            #include "UnityStandardCoreForwardCustom.cginc"

             ENDCG
         }
@@ -288,7 +290,7 @@ Shader "Standard"

             #pragma vertex vertAdd
             #pragma fragment fragAdd
-            #include "UnityStandardCoreForward.cginc"
+            #include "UnityStandardCoreForwardCustom.cginc"

             ENDCG
         }
@@ -344,5 +346,5 @@ Shader "Standard"


     FallBack "VertexLit"
-    CustomEditor "StandardShaderGUI"
+    CustomEditor "StandardShaderGUICustom"
 }

UnityStandardCoreCustom.cginc

@@ -425,6 +425,8 @@ VertexOutputForwardBase vertForwardBase (VertexInput v)
     return o;
 }

+float _Brightness;
+
 half4 fragForwardBaseInternal (VertexOutputForwardBase i)
 {
     UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
@@ -443,6 +445,8 @@ half4 fragForwardBaseInternal (VertexOutputForwardBase i)
     half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect);
     c.rgb += Emission(i.tex.xy);

+    c.rgb = Luminance(c.rgb).xxx * _Brightness;// モノクロ化
+
     UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
     UNITY_APPLY_FOG(_unity_fogCoord, c.rgb);
     return OutputForward (c, s.alpha);

UnityStandardCoreForwardCustom.cginc

@@ -16,7 +16,7 @@
     half4 fragBase (VertexOutputBaseSimple i) : SV_Target { return fragForwardBaseSimpleInternal(i); }
     half4 fragAdd (VertexOutputForwardAddSimple i) : SV_Target { return fragForwardAddSimpleInternal(i); }
 #else
-    #include "UnityStandardCore.cginc"
+    #include "UnityStandardCoreCustom.cginc"
     VertexOutputForwardBase vertBase (VertexInput v) { return vertForwardBase(v); }
     VertexOutputForwardAdd vertAdd (VertexInput v) { return vertForwardAdd(v); }
     half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseInternal(i); }

StandardShaderGUICustom.cs

@@ -55,6 +55,7 @@ namespace UnityEditor
             public static string renderingMode = "Rendering Mode";
             public static string advancedText = "Advanced Options";
             public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
+            public static string brightnessText = "Brightness";
         }

         MaterialProperty blendMode = null;
@@ -83,6 +84,7 @@ namespace UnityEditor
         MaterialProperty detailNormalMapScale = null;
         MaterialProperty detailNormalMap = null;
         MaterialProperty uvSetSecondary = null;
+        MaterialProperty brightness;

         MaterialEditor m_MaterialEditor;
         WorkflowMode m_WorkflowMode = WorkflowMode.Specular;
@@ -126,6 +128,7 @@ namespace UnityEditor
             detailNormalMapScale = FindProperty("_DetailNormalMapScale", props);
             detailNormalMap = FindProperty("_DetailNormalMap", props);
             uvSetSecondary = FindProperty("_UVSec", props);
+            brightness = FindProperty("_Brightness", props);
         }

         public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
@@ -176,6 +179,8 @@ namespace UnityEditor
                     m_MaterialEditor.ShaderProperty(highlights, Styles.highlightsText);
                 if (reflections != null)
                     m_MaterialEditor.ShaderProperty(reflections, Styles.reflectionsText);
+
+                m_MaterialEditor.ShaderProperty(brightness, Styles.brightnessText);

4. カスタムStandardShaderの適用

修正が完了したらStandardCustom.shaderを右クリックして[Create] > [Material]でマテリアルを新規作成するか、既存のマテリアルにStandardCustom.shaderを割り当てます。

カスタムしたStandardShader

インスペクタでパラメータを確認すると、追加した「Brightness」パラメータが追加されいることがわかります。

SceneビューやGameビューでカスタムシェーダーを割り当てたオブジェクトの色がモノクロになったり、追加したパラメータがを変更して明るさ(色の濃さ)が変わることを確認します。

CubeにカスタムStandardShaderを割り当てた様子 (左:カスタム、右:標準)

5. おわりに

StandardShaderをカスタマイズする方法を見てきました。StandardShaderは光や影の計算を行ってくれるため、お手軽に使えますが自分でカスタマイズしようとするとやや骨が折れることが分かります。

(インスペクターから独自のパラメータを変更できるようにする必要がない場合はStandardShaderGUICustom.csは不要になります)

恐らくStandardShaderはユーザによるカスタマイズが元々想定されておらず、光や影の処理込みでお手軽に独自の処理を組み込みたい場合は、SurfaceShaderを使うことが想定されているのでしょう。

しかしながらStandardShaderとSurfaceShaderでは処理が異なることからも、やや見た目が異なるため、StandardShaderの質感で独自の処理を組み込みたい場合は今回のようなアプローチが必要になってきます。ニッチな記事にはなりましたが参考になれば幸いです。🌱


6. 参考


この記事が気に入ったらサポートをしてみませんか?