ライセンスについて

Spineランタイムをアプリケーションに組み込むにはSpineライセンスが必要です。

spine-unityランタイム ドキュメント

レンダリング

マテリアル

各アトラスページのTextureは、スケルトンインポート時に自動的に作成される独自のMaterialを必要とします。Normal(通常) 以外のSlotブレンドモードを使用する場合は、ブレンドモードごとに追加のMaterialも作成されます(PMA使用時の Additive(加算) は除きます。これは通常のマテリアルでレンダリングが可能です)。MeshRendererのMaterials配列は、現在割り当てられているアタッチメントと、それらが含まれているAtlasAssetsに応じて、毎フレームごとにSkeletonRendererによって管理され、現在割り当てられているアタッチメントとそれらが含まれるAtlasAssets、およびSlotで使用されているブレンドモードに依存します。

注意: Materialsの配列を直接変更しても、次の LateUpdate() で上書きされてしまうので、効果はありません。マテリアルをオーバーライドするには、SkeletonRendererCustomMaterialsまたはSkeletonGraphicCustomMaterialsコンポーネントを使用してください。また、_Atlasアセットで異なるマテリアルを割り当てて、すべてのインスタンスのマテリアルを変更することもできます。_Atlasアセットを変更した後は、SkeletonRenderer コンポーネントの SkeletonData Asset パラメーターで Reload を押して新しいアトラスマテリアルを使用してスケルトンを再ロードする必要があります。

注意: SkeletonGraphic コンポーネントでは Spine/SkeletonGraphic* シェーダーを持つマテリアルのみを使用してください。URP、LWRP、または Spine/Skeleton のような通常のシェーダーを SkeletonGraphic コンポーネントで使用しないでください。詳しくは SkeletonGraphic - マテリアルの重要な要件 をご覧ください。

マテリアルの切り替えとドローコール

割り当てられたアタッチメントが複数のアトラスページに分散している場合、あるいはマテリアル A とマテリアル B のように異なるブレンドモードを持っている場合、Materials配列はマテリアルが必要とされる表示順序に従って設定されます。

例えば、もし表示順序が以下のようになっているとしたら:

  1. Aからのアタッチメント
  2. Aからのアタッチメント
  3. Bからのアタッチメント
  4. Aからのアタッチメント

マテリアルの配列は以下のようになります:

  1. Material A (アタッチメント1と2用)
  2. Material B (アタッチメント3用)
  3. Material A (アタッチメント4用)

Materials配列のすべてのマテリアルはドローコールに対応しています。そのため、マテリアルの切り替え量が多いとパフォーマンスに悪影響を及ぼしてしまいます。

Dragonの例では、多くのドローコールがある残念なユースケースを紹介しています:

そのため、アタッチメントは可能な限り少ないアトラスページでパックすることや、表示順序に応じてアタッチメントをアトラスページにまとめて不要なマテリアルの切り替えを防ぐことが推奨されています。 Spineアトラスのアトラス領域の配置方法についてはSpineテクスチャ・パッカー: フォルダ構造をご覧ください。

インスタンスごとにマテリアルを変更する

注意: SkeletonRendererのMaterials配列を直接変更しても次の LateUpdate() で上書きされてしまうので、効果はありません。以下の方法が適切でない場合は、SkeletonAnimation.OnMeshAndMaterialsUpdatedコールバックデリゲートを使用して、手動で毎フレーム MeshRenderer.Materials をオーバーライドすることができます。このコールバックは、アトラスマテリアルが割り当てられた後、LateUpdate() の最後に呼び出されます。

CustomMaterialOverrideとCustomSlotMaterials

SkeletonRendererでは、特定のスロットのマテリアルをオーバーライドしたり、結果のマテリアルをオーバーライドすることができます。

SkeletonRendererインスタンスの実行時にオリジナルのマテリアルを新しいマテリアルに置き換えるには、以下のように SkeletonRenderer.CustomMaterialOverride を使用します:

C#
// プログラムでオリジナルのマテリアルを照会するには、以下のコードを使用してください(下記注意も参照)。
// MeshRenderer.materialは動作しません。また、 MeshRenderer.sharedMaterialも場合により失敗する可能性があります。
if (originalMaterial == null)
   originalMaterial = skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial;

skeletonAnimation.CustomMaterialOverride[originalMaterial] = newMaterial; // 置換を有効にする。
skeletonAnimation.CustomMaterialOverride.Remove(originalMaterial); // 置換を無効にする。

注意: .material はマテリアルそのものではなく、プライマリマテリアルのインスタンスコピーを返すので、originalMaterial = skeletonAnimation.GetComponent<MeshRenderer>().material は使用しないでください。また、originalMaterial = skeletonAnimation.GetComponent<MeshRenderer>().sharedMaterial を使用することもお勧めしません。 アクティブなフレームにアクティブなアタッチメントが無い場合など、プライマリマテリアルがまだ割り当てられていないときにNULLを返す可能性があるからです。

特定のスロットだけに置換マテリアルを使用するには SkeletonRenderer.CustomSlotMaterials を使用します:

C#
skeletonAnimation.CustomSlotMaterials[slot] = newMaterial; // 置換を有効にする。
skeletonAnimation.CustomSlotMaterials.Remove(slot); // 置換を無効にする。

バッチングを維持しながらスケルトンをティント(着色)する

スケルトンインスタンスに異なる MaterialsMaterialPropertyBlocks を使用すると、バッチングが発生します。個々のスケルトンインスタンスを異なる方法でティント(着色)したいだけで、他のマテリアルプロパティを変更する必要が無い場合は、Skeleton.R .G .B .A カラープロパティを使用できます。ティントを適用するには、SkeletonRendererのInspectorで Advanced - PMA Vertex Colors を有効にする必要があります。

C#
public Color color = Color.white;
...
skeleton = GetComponent<SkeletonRenderer>().Skeleton;
...
skeleton.R = color.r;
skeleton.G = color.g;
skeleton.B = color.b;
skeleton.A = color.a;

これらのスケルトンカラーの値は、頂点カラーを設定するもので、マテリアルプロパティには影響しません。

個々のアタッチメントをティントする場合も同様です。:

C#
slot = skeleton.FindSlot(slotname);
...
slot.R = slotColor.r;
slot.G = slotColor.g;
slot.B = slotColor.b;
slot.A = slotColor.a;

注意: アニメーション内でアタッチメントカラーの値を変更している場合は、アニメーションが適用された後に、SkeletonAnimation.UpdateCompleteコールバックなどでスロットカラーの値を必ず設定してください。

MaterialPropertyBlocks

Renderer.SetPropertyBlockを使って、1つの MeshRenderer のマテリアルプロパティ値を上書きすることができます。

C#
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
mpb.SetColor("_FillColor", Color.red); // "_FillColor" is a named property on the used shader.
mpb.SetFloat("_FillPhase", 1.0f); // "_FillPhase" is another named property on the used shader.
GetComponent<MeshRenderer>().SetPropertyBlock(mpb);

// to deactivate the override again:
MaterialPropertyBlock mpb = this.cachedMaterialPropertyBlock; // assuming you had cached the MaterialPropertyBlock
mpb.Clear();
GetComponent<Renderer>().SetPropertyBlock(mpb);

注意: MaterialPropertyBlock で使用するパラメーター名(_FillColor_FillPhaseなど)は、それぞれシェーダー変数名と一致していなければなりません。なお、シェーダー変数名は、Inspectorで表示される名前(Fill ColorFill Phase など)とは異なりますのでご注意ください。シェーダー変数名を確認するには、.shader ファイルを開き(マテリアルの歯車アイコンメニューから Edit Shader を選択)一番上の Properties { .. } を確認してください。そこには、すべてのパラメーターのリストがあります。以下のようなパラメーター行で一番左にある名前 _FillColor が変数名です:

_FillColor ("Fill Color", Color) = (1,1,1,1)
^^^^^^^^^^

シェーダー変数名は通常、_ で始まり、スペースは含まれません。Inscpectorに表示されるのは、"Fill Color" のような隣の文字列です。

サンプルシーンの Spine Examples/Other Examples/Per Instance Material Properties では、インスタンスごとのマテリアルプロパティのデモをご確認いただけます。

最適化の注意点

  • Renderer.SetPropertyBlockを異なるMaterial値で使用すると、レンダラー間のバッチングが発生します。MaterialPropertyBlockパラメーターが同じであれば、レンダラー間でのバッチングは行われます(例:すべてのレンダラーがティントカラーを同じ緑色に設定する)。
  • MaterialPropertyBlockのプロパティ値を変更または追加する際には必ず SetPropertyBlock を呼び出す必要があります。しかし、そのMaterialPropertyBlockをクラスの一部として保持しておけば、プロパティを変更するたびに新しいものをインスタンス化する必要はありません。
  • プロパティを頻繁に設定する必要がある場合は、静的メソッドを使用することができます: Shader.PropertyToID(string) を使うと、MaterialPropertyBlockのセッターの文字列オーバーロードを使わずに、そのプロパティのint IDをキャッシュすることができます。

透明度と表示順序

すべてのspine-unityシェーダーは、アルファブレンディングを使用して、アタッチメントの境界に半透明のトランジションをきれいに描きます。アルファブレンディングを使用しないと(ハードな透明度しきい値を使用して)、エイリアシングアーティファクトのような硬いギザギザのアウトラインができてしまいます。

残念ながらアルファブレンディングには古典的な問題があり、zバッファを自動深度ソートに使用できません。代わりに、三角形を後ろから前の順にレンダリングし、パーツを重ねてペイントする必要があります。各SkeletonRendererはそれに応じてメッシュを生成し、三角形はSpineで定義されたスロットの表示順序に従います。1つのメッシュ内では、1回のドローコールでも、正しく順序付けられたスケルトンパーツを描くことができます。

複数メッシュ間では、どのメッシュがどのメッシュの上に来るべきかを決定するために、spine-unityはUnityの描画順序システムの多くを利用しています。標準的なspine-unityの設定では、スケルトン全体のメッシュは、以下の複数の要素によって決定された順序でレンダリングされます:

  1. Camera depth マルチカメラの設定に関連しています。
  2. Material.renderQueue 設定すると、シェーダーのQueueタグを上書きします。
  3. シェーダーのQueueタグ デフォルトでは、他のスプライトと同様にSpineシェーダーで"Transparent"のキューに入っています。
  4. Sorting Groupコンポーネント MeshRendererのGameObjectや親のGameObjectsに配置された場合
  5. レンダラーのSortingLayerおよびSortingOrder within a layer
  6. カメラからの距離 カメラは平行投影(planer)または透視投影(perspective)のどちらを使用するかを設定できます

シーンのレンダラーが同じsorting layerとorderにあり、シェーダーの Queue タグが同じであれば、カメラまでの距離でSpine GameObjectのソートをコントロールすることができます。なお、カメラにはtransparencySortModeプロパティがあります。

Sorting LayerとOrder in Layer

SkeletonRenderer (またはサブクラスのSkeletonAnimationSkeletonMecanim)のInspectorには Sorting LayerOrder in Layer プロパティがあり、MeshRenderersortingLayerIDsortingOrderプロパティを実際に変更します。これらのプロパティは SkeletonRenderer の一部ではなく、MeshRenderer の一部として保存されます。

また、これらのプロパティにはコードからアクセスすることができます:

C#
GetComponent<MeshRenderer>().sortingOrder = 1; // Order in Layerを1に変更。

ソートの誤りを防ぐには

特に平行投影(orthographic)カメラを使用している場合、複数のアトラスページを使用しているスケルトンが誤ってソートされてしまうことがあります。 この問題を解決するには、スケルトンGameObjectにSorting Groupコンポーネントを追加する必要があります。また、カメラを少しだけ回転させるという方法もあります。例えば、カメラのトランスフォームY回転の値を0.001に設定するなどです。

スケルトンパーツ間のオブジェクト

例えば、キャラクターが木に突っ込んだ時に、片足を木の前に、片足を木の後ろに表示させるなど、キャラクターのパーツの間に他のGameObjectを表示させたい場合があります。

spine-unityでは、スケルトンを複数のパーツに分割するためにSkeletonRenderSeparatorコンポーネントを提供しています。

スケルトンのフェードイン、フェードアウト

残念ながら、アルファブレンディングでは、スケルトンのアルファ値を下げて半透明にするとスケルトンの下位のパーツが透けて見えてしまいます。これは、各三角形の描画時に透明度が適用されるためです。

この問題を解決する方法のひとつは、一時的なRenderTextureを使用することです。キャラクター全体を通常の不透明度でRenderTextureにレンダリングし、その後、このRenderTextureのコンテンツを任意のフェード不透明度でシーンに描画することができます。 また、これを実現するために提供されているSkeletonRenderTextureとサンプルコンポーネントSkeletonRenderTextureFadeoutを使用することができます。これらのコンポーネントのデモは、サンプルシーン Spine Examples/Other Examples/RenderTexture FadeOut Transparency で確認できます。

なお、これはフェードアウト効果を作成するための数ある方法のうちのひとつに過ぎません。スケルトンを徐々にソリッドカラーで染めたり、スケールを小さくするなど、他にも簡単な方法がある可能性があります。RenderTextureは負荷のかかる解決方法であり、従来はほとんど使用されてこなかったため、既存の2Dゲームを参考にしてみた方が良いかもしれません。

シェーダー

spine-unityランタイムにはいくつかの異なるシェーダーが同梱されています。デフォルトでは Spine/Skeleton シェーダーが新しくインポートされたスケルトンのMaterialに割り当てられます。シェーダーの変更は、通常通りMaterialのShaderパラメーターで行います。以下に、同梱されているSpineシェーダーのリストをご紹介します。

重要な注意事項: SkeletonGraphicコンポーネントでは、CanvasRendererと互換性のある特別なシェーダーのみを使用してください。詳細はSkeletonGraphic - マテリアルの重要な要件をご覧ください。

重要な注意事項: spine-unityランタイムパッケージは Built-In Render Pipeline 用のシェーダーのみ同梱しており、Universal Render Pipeline を使用しているプロジェクトとは互換性がありません。Universal Render Pipelineを使用している場合は、代わりにSpine URP Shaders 拡張UPMパッケージにて提供されているURP用のシェーダーを使用してください。

注意: ディファードシェーディングレンダリングパスは、Spineシェーダーではまだサポートされていません。

  1. Spine/Skeleton (デフォルトシェーダー)
    ライティングを反映しないUnlit透明シェーダー。Zバッファ(深度バッファ)への書き込みは行いません。

  2. Spine/Skeleton Graphic (SkeletonGraphic用のデフォルトシェーダー)
    SkeletonGraphicで使用される、ライティングを反映しないUnlit透明シェーダー。Zバッファ(深度バッファ)への書き込みは行いません。CanvasGroup で使用する場合、Additive(加算) ブレンドモードはサポートされていないため、代わりにSpine/Skeleton Graphic Tint Black を使用する必要があります。CanvasRendererの制限により、1つのテクスチャに限定されます。

  3. Spine/Skeleton Lit
    シンプルなLit透明シェーダーで、ノーマルマップ(法線マップ)はサポートしていません。Zバッファ(深度バッファ)への書き込みは行いません。

  4. Spine/Skeleton Lit ZWrite
    シンプルなLit透明シェーダーで、ノーマルマップ(法線マップ)はサポートしていません。Zバッファ(深度バッファ)への書き込みを行います。

  5. Spine/Skeleton Fill
    カスタマイズ可能なカラーオーバーレイを備えたUnlit透明シェーダー。Zバッファ(深度バッファ)への書き込みは行いません。 FillColor はオーバーレイの色を、FillPhase はオーバーレイの色の強さを決定します。

  6. Spine/Skeleton Tint
    カスタマイズ可能な2色のティント(暗色と明色を別々に着色すること)を備えたUnlit透明シェーダーで、ティントブラックと呼ばれます。Zバッファ(深度バッファ)への書き込みは行いません。

    テクスチャの明るい色は Tint Color で染められ、テクスチャの暗い色は Black Point カラーで染められます。これにより、着色されたテクスチャは、通常の乗算カラーブレンドと比較して、元の色よりも明るくなります。Tint ColorBlack Point の両方を同じ色に設定すると、ソリッドカラー(べた塗り)のオーバーレイになります。Tint Color を黒に、Black Point を白に設定すると、テクスチャの色を反転することができます。

  7. Spine/Skeleton Tint Black

    Spineでアニメーションされているスロットごとのティントブラックの機能を持つ、Unlit透明シェーダーです。 Zバッファ(深度バッファ)への書き込みは行いません。 Spineはスロットにティントブラック機能を提供し、アニメーションによるブラックティントを可能にします。

    以下の追加の設定ステップが必要です(ティントカラーの頂点データの場合):

    • SkeletonAnimationのInspectorの Advanced セクションで Tint Black を有効にしてください:

  8. Spine/Skeleton Tint Black Additive
    Spineでアニメーションされているスロットごとのティントブラックの機能を持つ、Unlit透明シェーダーです。 Additive(加算)ブレンドモードを使用します。 Zバッファ(深度バッファ)への書き込みは行いません。

  9. Spine/SkeletonGraphic Tint Black
    SkeletonGraphic用の Spine/Skeleton Tint Black シェーダーの派生です。CanvasGroup と一緒に使用する際に Additive(加算) ブレンドモードをサポートします。

    以下の追加の設定ステップが必要です(ティントカラー頂点データの場合):

    1. SkeletonAnimationのInspectorの Advanced セクションで Tint Black を有効にします。
    2. SkeletonGraphicのMaterialを、CanvasGroupのサポートの有無に関わらず、PMAまたはストレートアルファテクスチャのワークフローに適した Spine/Runtime/spine-unity/Materials のそれぞれのサブフォルダにあるSkeletonGraphicTintBlack マテリアルに設定します。
    3. 親キャンバスを選択し、Additional Shader ChannelsTexCoord1TexCoord2 を有効にします。

    CanvasGroup での Additive(加算) ブレンドモードのためには以下の追加手順が必要です: 4. SkeletonGraphicのInspectorの Advanced セクションで Canvas Group Tint Black を有効にします。 5. a) spine-unity 4.2以降の場合: SkeletonGraphicのInspectorの Advanced セクションで CanvasGroup Compatible を有効にします。 b) 古いバージョンの場合: SkeletonGraphicのInspectorの Advanced セクションで Canvas Group Tint Black を有効にします。 6. シェーダーで CanvasGroup Compatible を有効にしてください。

  10. Spine/Sprite
    これらは設定変更が可能な洗練されたシェーダーで、Spine/Skeleton Lit シェーダーよりも高度なライティングが可能です。 Spine/Sprite/Vertex Lit シェーダーのデモは、サンプルシーン Spine Examples/Other Examples/Sprite Shaders で確認できます。

    1. Spine/Sprite/Unlit
      ブレンドモード、オーバーレイカラー、色相、彩度、明るさの調整が可能なUnlitシェーダーです。Zバッファ(深度バッファ)への書き込みの設定を変更可能です。Fog(フォグ)をサポートしています。
    2. Spine/Sprite/Vertex Lit
      ブレンドモードの設定変更が可能な洗練されたVertex-Litシェーダーです。 ノーマルマップ(法線マップ)、セカンダリアルベド、メタリック、エミッションマップをサポートしています。 カラーランプによるセルシェーディング風の外観と法線に基づくリムライティング、 オーバーレイの色、色相、彩度、輝度の調整、 Zバッファ(深度バッファ)への書き込みの設定を変更可能です。Fog(フォグ)をサポートしています。
    3. Spine/Sprite/Pixel Lit
      Spine/Sprite/Vertex Lit シェーダーのPixel-litバージョンです。これはピクセルごとのリアルタイムシャドウを受けることが出来る唯一のシェーダーです。 このシェーダーは、常にZバッファ(深度バッファ)に書き込みます(ForwardAdd パスを使用するため、ZWrite が有効になっています)。
  11. Spine/Special

    1. Spine/Special/Skeleton Grayscale
      Intensityをカスタマイズできるグレースケールレンダリング用のUnlit透明シェーダーです。Zバッファ(深度バッファ)への書き込みは行いません。
    2. Spine/Special/Skeleton Ghost
      SkeletonGhostコンポーネントがトレイルレンダリングに使用する特別なシェーダーです。
  12. Spine/Blend Modes
    これらのシェーダーは、Spineエディターでブレンドモードに Additive(加算)Multiply(乗算)Screen(スクリーン) が割り当てられているスロットを対象としています。インポート時に、提供されているSkeletonData Blend Mode Materialsを介して、ブレンドモードマテリアルを自動的に割り当てることをお勧めします。

    1. Spine/Blend Modes/Skeleton PMA Additive
      ライティングを反映しないUnlit透明シェーダー。Additive(加算)ブレンドモードを使用します。Zバッファ(深度バッファ)への書き込みは行いません。
    2. Spine/Blend Modes/Skeleton PMA Multiply
      ライティングを反映しないUnlit透明シェーダー。Multiply(乗算)ブレンドモードを使用します。Zバッファ(深度バッファ)への書き込みは行いません。
    3. Spine/Blend Modes/Skeleton PMA Screen
      ライティングを反映しないUnlit透明シェーダー。Screen(スクリーン)ブレンドモードを使用します。Zバッファ(深度バッファ)への書き込みは行いません。
  13. Spine/Outline
    上記のすべてのシェーダーには Outline パラメーターがあり、これを有効にすると、それぞれの Spine/Outline シェーダーのバリエーションに切り替わり、スケルトンの周囲に追加のカラーアウトラインが描画されるようになります。 Spine/Outline シェーダーのデモはサンプルシーンの Spine Examples/Other Examples/Outline Shaders でご覧いただけます。

    1. Spine/Outline/OutlineOnly-ZWrite
      アウトラインのみをレンダリングする特殊なシングルパスシェーダーです。アタッチメントが重なった時にアウトラインのオクルージョンを適切に処理するために、Zバッファ(深度バッファ)への書き込みを行います。また、スケルトンに複数のマテリアルが必要で通常のアウトラインシェーダーではスケルトン全体ではなく各サブメッシュのアウトラインをとってしまうという場合にもこちらのシェーダーを使用することで解決できます。例えば、RenderCombinedMesh コンポーネントを使用して、結合されたスケルトンメッシュをこのアウトラインのみのシェーダーで再レンダリングし、スケルトンの後ろにアウトラインを追加することができます。

ポストプロセスエフェクト

被写界深度(DoF)のようないくつかのポスト処理エフェクトは、シェーダーがZバッファ(より正確には、深度プリパス深度バッファ)に書き込む必要があります。Spineシェーダーのいくつかは、マテリアルで有効にできる Depth WriteZWriteとも呼ばれる)パラメーターを提供し、他のものはデフォルトでZバッファに書き込みます。提供されている SpineシェーダーのどれがZバッファに書き込むかについては、上記のドキュメントを参照してください。

URP-HighFidelity をレンダーパイプラインアセットとして使用している場合など、プロジェクトのGraphics設定(または Render Pipeline Asset Settings)によっては、シェーダーがZバッファに書き込むだけでは不十分な場合があります。この場合、Materialの Render QueueTransparent から AlphaTest に変更する必要があります。

提供されているシェーダーに制限を感じる場合は、修正したいSpineシェーダーをコピーして、ZWrite Off と書かれている行をすべて ZWrite On に変更し(各Passセクションで発生)、タグ "Queue"="Transparent""Queue"="AlphaTest" に変更した自作シェーダーを作ることが可能です。これを行う場合、命名の衝突を避けるために、ファイルの最初の行でシェーダーの名前を変更することを忘れないでください。

URP Shaders 拡張パッケージ

Universal Render Pipeline (URP)シェーダーは、別のUPM (Unity Package Manager)パッケージとして提供されています。このパッケージをダウンロードしてインストールする方法についてはオプションの拡張UPMパッケージセクションを、アップデートする方法については拡張UPMパッケージのアップデートセクションをご覧ください。

URPシェーダーのUPMパッケージは、2D Renderer機能を含む、Unityの Universal Render pipeline用に作られたシェーダーを提供します。

注意: SkeletonGraphic コンポーネントではURPシェーダーを使用しないでください。詳しくはSkeletonGraphic - マテリアルの重要な要件 をご覧ください。

注意: Universal Render Pipelineに最近追加されたデファードレンダリングパスは、Spine URPシェーダーではまだサポートされていません。

2Dレンダラーを使用するURPシェーダー (URP (3D)フォワードレンダラーとは一緒に使用しないでください)

  1. Universal Render Pipeline/2D/Spine/Skeleton
    Spine/Skeleton シェーダーのユニバーサル2D Rendererバージョンです。
  2. Universal Render Pipeline/2D/Spine/Skeleton Lit
    Spine/Skeleton Lit シェーダーのユニバーサル2D Rendererバージョンです。
  3. Universal Render Pipeline/2D/Spine/Sprite
    Spine/Sprite/Vertex Lit および Pixel Lit シェーダーのユニバーサル2D Rendererバージョンです。

3Dフォワードレンダラーを使用するURPシェーダー (URP 2Dレンダラーとは一緒に使用しないでください)

  1. Universal Render Pipeline/Spine/Skeleton
    Spine/Skeleton シェーダーのユニバーサルバージョンです。
  2. Universal Render Pipeline/Spine/Skeleton Lit
    Spine/Skeleton Lit シェーダーのユニバーサルバージョンです。ピクセルごとのリアルタイムシャドウを受けるように設定することもできます。
  3. Universal Render Pipeline/Spine/Sprite
    Spine/Sprite/Vertex Lit および Pixel Lit シェーダーのユニバーサルバージョンです。ピクセルごとのリアルタイムシャドウを受けます。
  4. Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly
    Spine/Outline シェーダーのユニバーサルバージョンです。URPはシェーダーごとに複数のパスを許可していないため、別のマテリアルが必要になります。本パッケージに含まれるサンプルシーン Outline Shaders URP で紹介している通り、RenderExistingMeshコンポーネントを使用した方が良いでしょう。スケルトンに複数のマテリアルが必要な場合は、RenderExistingMesh コンポーネントの代わりに RenderCombinedMesh コンポーネントを使用できます。

シェーダーは通常通りマテリアルに割り当てることができ、Project Settings - Graphics で割り当てられた UniversalRenderPipelineAsset の設定が反映されます。

URPシェーダーのデモは、UPMパッケージの中のサンプルシーン com.esotericsoftware.spine.URP-shaders/Examples にある、3D/URP 3D Shaders.unity2D/URP 2D Shaders.unityOutline Shaders URP.unity で確認できます。

LWRP Shaders 拡張パッケージ

Lightweight Render Pipeline (LWRP)シェーダーは、別のUPM (Unity Package Manager)パッケージとして提供されています。このパッケージをダウンロードしてインストールする方法についてはオプションの拡張UPMパッケージセクションを、アップデートする方法については拡張UPMパッケージのアップデートセクションをご覧ください。

LWRPシェーダーのUPMパッケージは、以下のUnityの軽量レンダーパイプライン用に作られたシェーダーを提供します。

注意: SkeletonGraphic コンポーネントでは、LWRPシェーダーを使用しないでください。詳しくはSkeletonGraphic - マテリアルの重要な要件を参照してください。

  1. Lightweight Render Pipeline/Spine/Skeleton
    Spine/Skeleton シェーダーのLightweightバージョンです。
  2. Lightweight Render Pipeline/Spine/Skeleton Lit
    Spine/Skeleton Lit シェーダーのLightweightバージョンです。
  3. Lightweight Render Pipeline/Spine/Sprite
    Spine/Sprite/Vertex Lit および Pixel Lit シェーダーのLightweightバージョンです。

シェーダーは通常通りマテリアルに割り当てることができ、Project Settings - Graphics で割り当てられたLightweightRenderPipelineAsset の設定が反映されます。

LWRPシェーダーのデモは、解凍したパッケージの中にあるサンプルシーン com.esotericsoftware.spine.lwrp-shaders-4.2/Examples/LWRP Shaders.unity で確認できます。

Shader Graph

現在、公式のShader Graph Spineシェーダーやシェーダーノードはありません。なお、ストレートアルファ設定を使用してSpineからテクスチャをエクスポートする場合は、Spine以外のシェーダーを使用することができます。Spineシェーダーにしかない機能を再現したい場合は、フォーラムのこちらの投稿を参考にしてください。[1]、[2]。ご質問がある場合は、Unityサブフォーラムに新しいスレッドを立ててください。

Amplify Shader Editor

Amplify Shader Editorには公式に提供されているシェーダーテンプレートはありませんが、ユーザーの Hana さんがフォーラムのこちらの投稿でテンプレートコードを公開してくれています。

シェーダーを自作する

まず前提として、一般的なUnityのカスタムシェーダーの書き方を理解してください。特にTutorial: Weiting vertex and fragment shadersは良い概要となっており、speine-unityシェーダーの各部分が何をしているかをより簡単に理解することができます。

既存のspine-unityシェーダーから始める

まずは既存のspine-unityシェーダーをコピーすることから始めることを強くお勧めします。その後、すでに動作しているシェーダーを徐々に修正して、求めていた効果を得るように調整することができます。例えば、最終的な色を返す前に追加の色処理を加えることができます。例えば次のコードは、グレースケール機能で拡張された SkeletonGraphic シェーダーの調整バージョンを作成する方法の簡単な例を示しています:

Properties
{
   _GrayIntensity("Intensity", Range(0, 1)) = 1 // この行はMaterialプロパティを提供するために追加しました
   [..]
}
sampler2D _MainTex;
float _GrayIntensity; // このパラメーターを追加しました
..
fixed4 frag (VertexOutput IN) : SV_Target
{
   ..
   color.rgb = lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayIntensity); // この行を追加しました
   return color;
}

Spineシェーダー以外のシェーダーやビジュアルシェーダーエディタを使用する際の注意点

典型的なspine-unityシェーダーとその他の非Spineシェーダーの以下のような違いに注意してください:

  1. Spineスケルトンをレンダリングする場合には、Cull Off を設定して必ずバックフェースカリングを無効にするようにしてください。
  2. Spineシェーダーは通常、法線を必要としないため、Litシェーダーを使用する場合はコンポーネントで Advanced - Add Normals を有効にする必要があります。
  3. Spineシェーダーは通常、接線を必要としないため、ノーマルマップ(法線マップ)を使用する場合はコンポーネントで Advanced - Solve Tangents を有効にする必要があります。
  4. Spineシェーダーはデフォルトで乗算済みアルファテクスチャを使用します。そのため、以下のいずれかを行ってください a) アトラステクスチャをストレートアルファとしてエクスポートする b) シェーダーのブレンドモードをPMAブレンドモードである Blend One OneMinusSrcAlpha に変更する
  5. Spineの頂点の色は、通常、PMA頂点の色です。透明または Additive(加算) スロットを使用する場合、次のいずれかを行うことができます
    a) シェーダーのブレンドモードをPMAブレンドモードである Blend One OneMinusSrcAlpha に変更し、PMAアトラステクスチャを使用する、または b) コンポーネントでAdvanced - PMA Vertex Colorsを無効にする(Additive(加算)スロットをレンダリングしない場合)

通常通り、UI用および非UI用シェーダーにおける一般的なルールが適用されます:

  1. SkeletonAnimation または SkeletonMecanim に対してUI用シェーダーを使用しないでください。
  2. SkeletonGraphic に対して非UI用シェーダーを使用しないでください。
Spine/Skeletonシェーダーの解析

次のセクションでは、Spine/Skeleton シェーダーの解析を行います。このシェーダーは、Spineテクスチャアトラスのインポート時にMaterialが生成されると、デフォルトで適用されます。 Spine/Skeleton シェーダーはかなり短くて典型的なもので、次のような特徴があります:

  • 乗算済みアルファ(PMA)ブレンディング
  • 深度バッファの書き込み無し
  • ライティング無し
  • バックフェースカリング無し
  • Fog(フォグ)無し
  • 頂点カラーを使って乗算でテクスチャを染める
  • オプションでPMAテクスチャの代わりにストレートアルファを使用する
  • "ShadowCaster" パスを持ち、リアルタイムに影を落とすことができる
  • Materialプロパティ:
    • _MainTex "メインテクスチャ"
    • _StraightAlphaInput "ストレートアルファテクスチャ"
    • _Cutoff "シャドウアルファのカットオフ"
    • 高度なパラメーター:
      • _StencilRef "ステンシルの参照"
      • _StencilComp "ステンシルの比較"
      • アウトラインパラメーター (_OutlineWidth "アウトラインの線幅"、その他。)

詳細:

  • 乗算済みアルファ(PMA)ブレンディング

    hlsl
    Blend One OneMinusSrcAlpha

    (Spine-Skeleton.shader:27)

    ブレンディングは、result_rgba = frag_output_rgba * src_factor + framebuffer_rgba * dst_factorで定義されます。 PMAの非標準的なブレンドモードBlend One OneMinusSrcAlphaでは、Additive(加算)ブレンドモードに設定されているスロットを、Normal(通常)レンドモードのスロットと一緒に1回のレンダリングパスで描画することができます。これは、上の行でSrcFactorに(SrcAlphaの代わりに)Oneを使うことで実現しています。これにより、修正されていないfrag_output_rgbaの値が、OneMinusSrcAlphaでウェイト付けされたframebuffer_rgbaに追加されます:
    a) Normal(通常)ブレンドでは、フラグメントシェーダーはRGBAを乗算し、Aはそのままにします。 b) Additive(加算)ブレンドでは、RGBにアルファを乗算せずにA0に設定してresult_rgba = frag_output_rgba + (1-0) * framebuffer_rgbaを受け取ります。

    SkeletonRenderer または SkeletonGraphic コンポーネントでAdvanced - PMA Vertex Colorsが有効になっている場合、Normal(通常) および Additive(加算) スロットブレンドモードは、頂点カラーとしてシェーダーに暗黙的に渡されます:

    hlsl
    struct VertexInput {
        float4 vertexColor : COLOR
    }

    (Spine-Skeleton.shader:50)

    PMAの頂点カラーとサンプリングされたPMAのテクスチャカラーを掛け合わせる際、スロットの Normal(通常) または Additive(加算) ブレンドモードが自動的に適用されます:

    hlsl
    return (texColor * i.vertexColor);

    (Spine-Skeleton.shader:74)

    そのため、シェーダーで適切な Normal(通常)Additive(加算) PMAブレンドモードをサポートする必要があります:

    1. Blend One OneMinusSrcAlpha としてブレンド関数を定義する。
    2. テクスチャの色と頂点の色を掛け合わせる。
    3. コンポーネントでAdvanced - PMA Vertex Colorsを有効にする。

    標準的なブレンドモード Blend SrcAlpha OneMinusSrcAlpha を使用したシェーダーを使用し、Additive(加算) スロットを必要としない場合、使用したアトラステクスチャをSpineからストレートアルファとしてエクスポートする必要があります。

  • 深度バッファの書き込み無し

    hlsl
    ZWrite Off

    (Spine-Skeleton.shader:26)

    深度バッファへの書き込みが無いのは、アルファブレンディングされた2Dスプライトシェーダーの典型です。透明なオブジェクトは、深度バッファでの深度ソートに頼らず、Camera.transparencySortModeに従って、前後の順序で描画されます。Spine/Skeleton は、この特性をUnity独自の Sprites/Default シェーダーと共有しています。

    深度への書き込みを有効にしたシェーダーを使用する際は、特にライティングを使用している場合Z-Fightingを防ぐために SkeletonRenderer またはSkeletonGraphic コンポーネントで Advanced - Z-Spacing0 以外の値に設定してください。 なお、深度バッファを使用すると、エッジのエイリアシング効果など、半透明領域の周囲で望ましくない結果が生じることがあります。

  • ライティング無し
    Spine/Skeleton シェーダーは、シーンに配置されているLightsの影響を受けず、常に texColor * i.vertexColor のフル輝度でレンダリングされます。

    シェーダーでライティングを適用するには、実際に使用されているLitシェーダーから始めて、自分のコピーを適宜変更することをお勧めします。 単純に Lighting Off から Lighting On に変更しただけでは期待した効果は得られず、ご自身の頂点シェーダー(頂点ごとのライティングの場合)やフラグメントシェーダー関数(ピクセルごとのライティングの場合)でライトを評価し、それに応じて色のIntensity(強度)を乗じる必要があります。また、URP、URP-2D、標準パイプラインシェーダーは、それぞれ異なるライティング評価設定を使用しているので、それに合わせてリファレンスシェーダーを選択することに注意してください。

  • バックフェースカリング無し

    hlsl
    Cull Off

    (Spine-Skeleton.shader:25)

    Spineスケルトンをレンダリングするための唯一の厳格な条件は、2Dシェーダーによく見られるバックフェースカリングを無効にすることです。

    ほとんどの3Dシェーダーでは、バックフェースカリングが有効になっています。Spineメッシュでは、パーツがマイナスにスケールされたり、スケルトンの方向を反転させたりすると、この処理によって一部の三角形が見えなくなってしまいます。

  • Fog無し
    Spine/Skeleton シェーダーはFog(フォグ)の影響を受けません。

    シェーダーでFogを有効にするには、シェーダーコードに追加の頂点パラメーターと関数呼び出しが必要です。以下 UnityCG.cginc より:

    hlsl
    multi_compile_fog Will compile fog variants.
    UNITY_FOG_COORDS
    (texcoordindex) Declares the fog data interpolator.
    UNITY_TRANSFER_FOG
    (outputStruct,clipspacePos) Outputs fog data from the vertex shader.
    UNITY_APPLY_FOG
    (fogData,col) Applies fog to color "col". Automatically applies black fog when in forward-additive pass.
    Can also use UNITY_APPLY_FOG_COLOR to supply your own fog color.

    シェーダーでFogを適用する方法については、Spine/Sprite/Unlit シェーダーを参考にしてください。:

    hlsl
    #pragma multi_compile_fog

    (SpritesUnlit.shader:72)

    hlsl
    UNITY_FOG_COORDS(1) // to declare it at the free attribute TEXCOORD1

    (SpriteUnlit.cginc:L34)

    hlsl
    UNITY_TRANSFER_FOG(output,output.pos);

    (SpriteUnlit.cginc:64)

  • 頂点カラーを使って乗算でテクスチャを着色する
    前述の「乗算済みアルファ(PMA)ブレンディング」をご覧ください。

  • オプションでPMAテクスチャの代わりにストレートアルファを使用する
    Spine/Skeleton シェーダーのブレンドモードは常にPMAブレンディングに設定されているため、入力テクスチャが乗算済みアルファカラーを持っていない場合、サンプリング後にPMAカラーに変換する必要があります。以下の行ではこの機能を実装しています:

    // bool Material parameter, enables the _STRAIGHT_ALPHA_INPUT shader keyword when enabled
    [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
    ..
    // compiles the shader in two variants so that shader keywords can switch between both variants
    #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
    ..
    // when enabled, multiply texture rgb values by the texture alpha value.
    #if defined(_STRAIGHT_ALPHA_INPUT)
    texColor.rgb *= texColor.a;
    #endif
  • "ShadowCaster"パスを持ち、リアルタイムに影を落とすことを可能にする
    Tags { "LightMode"="ShadowCaster" }を持つセカンドパスは LightMode によって自動的にShadowCasterパスとして識別されます。 ShadowCaster パスは、RGB カラーを一切書き込まず、代わりに深度情報をシャドウバッファに書き込みます。そのため、必ず ZWrite On を使用します。 半透明の深度を書き込むことはできないので、フラグメントは深度バッファに書き込まれるか、影を落とさないように破棄されます。これは、しきい値関数コールで行います:

    hlsl
    clip(texcol.a * i.uvAndAlpha.a - _Cutoff);

    (Spine-Skeleton.shader:114)

    ここでは、_Cutoff Materialパラメーターがアルファのしきい値を定義しており、x < 0の場合、clip(x) によってフラグメントが破棄されます。

  • Materialプロパティ:

    • _MainTex "メインテクスチャ"
      メインのテクスチャ。
    • _StraightAlphaInput "ストレートアルファテクスチャ"
      前述の「オプションでPMAテクスチャの代わりにストレートアルファを使用する」を参照してください。
    • _Cutoff "シャドウアルファのカットオフ"
      前述の"ShadowCaster"パスを持ち、リアルタイムに影を落とすことができる」を参照してください。
    • 高度なパラメーター:
      • _StencilRef "ステンシルの参照"
        マスク・インタラクションに使用します。
      • _StencilComp "ステンシルの比較"
        マスクインタラクションに使用され、SkeletonRenderer または SkeletonGraphic コンポーネントが Mask Interaction プロパティに従って設定されます。
      • アウトラインパラメーター(_OutlineWidth "アウトラインの線幅"、その他。)
        アウトラインシェーダーバリアント Spine/Outline/Skeleton に切り替えたときに使用されます。通常の非アウトラインシェーダーバリアント Spine/Skeleton では使用されません。

次: Timeline 拡張UPMパッケージ 前: ユーティリティコンポーネント