【Unity】カリング制御可能な標準シェーダーを作る

2018-08-29

Unityの標準シェーダーでカリングの制御をできるようにしたかったので調べてみた。

試したバージョン:Unity 2018.2.4f1

標準シェーダーのソースのダウンロード

Unity - Download Archive のダウンロードのドロップダウンに「ビルトインシェーダー」という項目があり、クリックすると.zipファイルをダウンロードできる。

ファイルを展開して DefaultResourcesExtra/Standard.shader が対象のソースコード。

シェーダーの修正

シェーダー名の修正

ここでは仮に、Custom/StandardCullとでもしてみる。 ファイル名もStandardCull.shaderとしておく:

StandardCull.shader
-Shader "Standard"
+Shader "Custom/StandardCull"

Unityのプロジェクトに突っ込むとマテリアルのShaderから選べるようになっている。

![1.png](/assets/unity-cull-shader/1.png)

シェーダーにカリングを制御するパラメータを追加

StandardCull.shader
 Shader "Custom/StandardCull"
{
Properties
{
...

+ [Enum(UnityEngine.Rendering.CullMode)]
+ _Cull("Cull", Float) = 0 // 0=Off

...

SubShader
{
Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
LOD 300

+ Cull [_Cull]

// 念のためLOD 150も同様に

UIの指定

カリングのパラメータを追加しただけではUnityエディタのインスペクタからいじれない。 .zipを展開した中にEditor/StandardShaderGUI.csというファイルがあるので、StandardCullShaderGUI.csなどとリネームしてAssetsのEditor以下につっこみ、変更する:

StandardCullShaderGUI.cs
 namespace UnityEditor
{
- internal class StandardShaderGUI : ShaderGUI
+ internal class StandardCullShaderGUI : ShaderGUI
{
...

private static class Styles
{
...
@@ -55,6 +55,7 @@
public static string renderingMode = "Rendering Mode";
public static string advancedText = "Advanced Options";
public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
+ public static string cullModeText = "CullMode";
}

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

...

public void FindProperties(MaterialProperty[] props)
{
...
@@ -123,6 +125,7 @@
detailNormalMapScale = FindProperty("_DetailNormalMapScale", props);
detailNormalMap = FindProperty("_DetailNormalMap", props);
uvSetSecondary = FindProperty("_UVSec", props);
+ cullMode = FindProperty("_Cull", props);
}

...

public void ShaderPropertiesGUI(Material material)
{
...
@@ -152,6 +155,7 @@
EditorGUI.BeginChangeCheck();
{
BlendModePopup();
+ m_MaterialEditor.ShaderProperty(cullMode, Styles.cullModeText);

...

シェーダ側に上記のGUIを使用するということを指定する:

StandardCull.shader
 Shader "Custom/StandardCull"
{
...

- CustomEditor "StandardShaderGUI"
+ CustomEditor "StandardCullShaderGUI"
}

するとマテリアルを選択するとインスペクタにCullModeというドロップダウンが追加され、変更できるようになる。

![2.png](/assets/unity-cull-shader/2.png)

スクリプトからの変更

スクリプトからマテリアルのカリングモードをいじるには、

using UnityEngine;
using UnityEngine.Rendering;

Material material; // 対象のマテリアル
CullMode cullMode = CullMode.Off;
material.SetFloat("_Cull", (float)cullMode);