Skip to content

カスタムシェーダーの作り方

基本的な流れ

カスタムシェーダー用テンプレート(Template.zip)を元に作成していきます。基本的には以下の5つのファイルのみを編集するだけで完結するようになっています。

  • Shaders/custom.hlsl
  • Shaders/custom_insert.hlsl
  • Shaders/lilCustomShaderDatas.lilblock
  • Shaders/lilCustomShaderProperties.lilblock
  • Editor/CustomInspector.cs
  • Editor/TemplateFull.asmdef

バリエーション数が多いため、適宜不要なバリエーションを削除してください。またルートのフォルダ名(Template)はわかりやすいように任意の名前に変更してください。

シェーダー名の設定

シェーダー名を変更するには以下の3箇所を編集します。

ファイル該当箇所
Shaders/lilCustomShaderDatas.lilblockShaderName ""タグ内
Editor/CustomInspector.csshaderName変数
Editor/TemplateFull.asmdefnameおよびファイル名自体

マテリアル変数の追加

まず、lilCustomShaderProperties.lilblock内に任意のプロパティを追加してください。ShaderLabsのPropertiesブロックと同様の書式で記述します。今回は例として以下のものを追加します。

        //----------------------------------------------------------------------------------------------------------------------
        // Custom
        [lilVec3]       _CustomVertexWaveScale      ("Vertex Wave Scale", Vector) = (10.0,10.0,10.0,0.0)
        [lilVec3]       _CustomVertexWaveStrength   ("Vertex Wave Strength", Vector) = (0.0,0.1,0.0,0.0)
                        _CustomVertexWaveSpeed      ("Vertex Wave Speed", float) = 10.0
        [NoScaleOffset] _CustomVertexWaveMask       ("Vertex Wave Mask", 2D) = "white" {}

続いてcustom.hlslを編集します。変数は#define LIL_CUSTOM_PROPERTIES、Texture2DやSamplerStateは#define LIL_CUSTOM_TEXTURESというマクロで挿入できます。

hlsl
#define LIL_CUSTOM_PROPERTIES \
    float4  _CustomVertexWaveScale; \
    float4  _CustomVertexWaveStrength; \
    float   _CustomVertexWaveSpeed;

#define LIL_CUSTOM_TEXTURES \
    TEXTURE2D(_CustomVertexWaveMask);

関数やincludeの追加

通常はcustom.hlsl内に記述できますが、Unityの関数や変数に依存する場合はcustom_insert.hlsl内に関数やincludeを記述してください。特定パスでエラーが出る場合はそのパスで#undefし、必要な場合は宣言し直すと良いでしょう。パスごとに以下のマクロ宣言されるため、#if defined(LIL_PASS_FORWARD)のような形で条件分岐できます。

名前パス名
LIL_PASS_FORWARDForwardBase、UniversalForward、ForwardOnly、SRPDefaultUnlit
LIL_PASS_FORWARDADDForwardAdd(BRPのみ)
LIL_PASS_SHADOWCASTERShadowCaster
LIL_PASS_DEPTHONLYDepthOnly(URP、HDRPのみ)
LIL_PASS_DEPTHNORMALSDepthNormals(URPのみ)
LIL_PASS_MOTIONVECTORSMotionVectors(HDRPのみ)
LIL_PASS_METAMETA

頂点シェーダーの入力の追加(appdata構造体)

以下のキーワードを#defineすることで対応した入力が追加されます。

キーワード追加される変数名セマンティクス
LIL_REQUIRE_APP_POSITIONpositionOSPOSITION
LIL_REQUIRE_APP_TEXCOORD0uvTEXCOORD0
LIL_REQUIRE_APP_TEXCOORD1uv1TEXCOORD1
LIL_REQUIRE_APP_TEXCOORD2uv2TEXCOORD2
LIL_REQUIRE_APP_TEXCOORD3uv3TEXCOORD3
LIL_REQUIRE_APP_TEXCOORD4uv4TEXCOORD4
LIL_REQUIRE_APP_TEXCOORD5uv5TEXCOORD5
LIL_REQUIRE_APP_TEXCOORD6uv6TEXCOORD6
LIL_REQUIRE_APP_TEXCOORD7uv7TEXCOORD7
LIL_REQUIRE_APP_COLORcolorCOLOR
LIL_REQUIRE_APP_NORMALnormalOSNORMAL
LIL_REQUIRE_APP_TANGENTtangentOSTANGENT
LIL_REQUIRE_APP_VERTEXIDvertexIDSV_VertexID

頂点シェーダーの出力の追加(v2f構造体)

構造体のメンバーは#define LIL_CUSTOM_V2F_MEMBERから追加できます。もともと構造体に含まれるものは#define LIL_V2F_FORCE_(キーワード)で強制的にメンバーにさせることができます。

頂点シェーダーに処理を挿入する

以下のようなマクロで処理を挿入できます。

hlsl
#define LIL_CUSTOM_VERTEX_OS \
    float3 customWaveStrength = LIL_SAMPLE_2D_LOD(_CustomVertexWaveMask, sampler_linear_repeat, input.uv0, 0).r * _CustomVertexWaveStrength.xyz; \
    positionOS.xyz += sin(LIL_TIME * _CustomVertexWaveSpeed + dot(positionOS.xyz, _CustomVertexWaveScale.xyz)) * customWaveStrength;

LIL_CUSTOM_VERTEX_OS(オブジェクト空間での処理)

利用できる変数説明
inout appdata inputappdata構造体
inout float2 uvMain計算済みUV座標
inout float4 positionOS頂点のオブジェクト座標

LIL_CUSTOM_VERTEX_WS(ワールド空間での処理)

利用できる変数説明
inout appdata inputappdata構造体
inout float2 uvMain計算済みUV座標
inout lilVertexPositionInputs vertexInput頂点座標の構造体(positionWS、positionVS、positionCS、positionSS)
inout lilVertexNormalInputs vertexNormalInputワールド空間のベクトルの構造体(tangentWS、bitangentWS、normalWS)

ピクセルシェーダーに処理を挿入する

BEFORE_(キーワード)OVERRIDE_(キーワード)で処理を挟んだり上書きしたりできます。

hlsl
#define BEFORE_UNPACK_V2F \
    fd.uv0 = input.uv0;

現在対応しているキーワードは以下の通りです。

名前説明
UNPACK_V2Fv2f構造体の展開
ANIMATE_MAIN_UVメインUVのアニメーション処理
ANIMATE_OUTLINE_UV輪郭線UVのアニメーション処理
PARALLAX視差マップの処理
MAINメインカラーの処理
OUTLINE_COLOR輪郭線の色の処理
FUR(ファーシェーダー用) ファーの処理
ALPHAMASKアルファマスクの処理
DISSOLVEDissolveの処理
NORMAL_1STノーマルマップの処理
NORMAL_2NDノーマルマップ2ndの処理
ANISOTROPY異方性反射の処理
AUDIOLINKAudioLinkの処理
MAIN2NDメインカラー2ndの処理
MAIN3RDメインカラー3rdの処理
SHADOW影の処理
BACKLIGHT逆光ライトの処理
REFRACTION屈折の処理
REFLECTION反射の処理
MATCAPマットキャップの処理
MATCAP_2NDマットキャップ2ndの処理
RIMLIGHTリムライトの処理
GLITTERラメの処理
EMISSION_1ST発光の処理
EMISSION_2ND発光2ndの処理
DISSOLVE_ADDDissolveの境界の発光処理
BLEND_EMISSION発光の合成
DISTANCE_FADE距離フェードの処理
FOGフォグの処理
OUTPUT最終書き出し

拡張Inspector

編集手順は以下の通りです。

  1. Editor/CustomInspector.csでクラス名を変更、Shaders/lilCustomShaderDatas.lilblock内のEditorNameタグを設定したクラス名に置き換え
  2. MaterialPropertyを宣言
  3. LoadCustomProperties()をオーバーライドして、FindPropertyでプロパティを取得
  4. DrawCustomProperties()をオーバーライドしてGUIを実装

lilToonのGUIStyleとして以下のものが利用できます。

名前説明
boxOuterプロパティボックスの外側
boxInnerHalfプロパティボックスの内側(ラベル描画用に上部が角ばっています)
boxInnerプロパティボックスの内側(ラベルなしの場合に綺麗になるように上部が角丸になっています)
customBoxUnityデフォルトのboxに近いですが視認性を上げるために縁取りがされています
customToggleFontプロパティボックスのラベルに使われる太字のフォント

またlilToon独自のEditor拡張として以下のような関数が使えます。

名前説明
bool Foldout(string title, string help, bool display)Foldoutの描画
void DrawLine()区切り線の描画
void DrawWebButton(string text, string URL)ウェブボタンの描画
void LoadCustomLanguage(string langFileGUID)カスタム言語ファイルの追加読み込み

作例

Released under the MIT License.