How to use the stencil in TypeA AnimeShader

TypeA AnimeShaderのステンシルを使って前髪を透ける眉毛や目の設定をする方法です。
設定次第で好みの状態を作れます。


一番簡単なのは単純にくり抜いて全て透過する方法です。
又、マテリアルはそれぞれ別のものにする必要があり、適用部分の構造を把握しておいて下さい。

サンプルモデルのインポート時の設定は、
・眉毛と睫毛が完全透過
・白目・目(ハイライト部分も目の扱い)が半透明
の設定になっています。

以下全てサンプルモデルの作りで説明します。

各数値などもサンプルモデルで設定したもので説明しますが、その関係が望む条件を満たすならば何でも大丈夫で、もう少し単純な設定も可能です。

サンプルでは顔本体もマスクとしていますが必要ないはずなのですが、制作途中で色々確認している際にマスクしておかないと一部がおかしな描画になったので一応設定してあります。
説明は省くので必要に応じてマテリアルを分けてReferenceValueを、その他に設定したものとゼロ以外にして設定してください。

以下が各値のデフォルト値になりますが、変更する部分だけ記載します。

ReferenceValue : 0~255
ReadMask : 255
WriteMask : 255
ComparisonFunction : Alweys
PassOperation : Keep
FailOperation : Keep
ZFailOperation : Keep

全て完全透過の方法

仕様するのは TypeA/Toon02(TypeA/Toon02Edge) です。
Rendering Settings のZWriteは全てOnにして下さい。

マテリアルが、白目と目と睫毛と眉毛 / 前髪で最低2個必要になります。
サンプルモデルではそれぞれ別に調整出来るように5個になっています。

  1. 透けさせたいもの 白目 / 目 / 眉毛 / 睫毛
    ReferenceValue : 6
    PassOperation : Replace
    この設定で値6でのマスクとなります。
  2. 前髪
    ReferenceValue : 6
    ComparisonFunction : NotEqual
    この設定で6ではない部分だけ描画する設定になります。
  3. 描画順が次の順になるようにRenderQueueを調整します。
    眉毛 / 睫毛 Geometry (2000)
    白目 Geometry+10 (2010)
    目 Geometry+20 (2020)
    前髪 Geometry+225(2225)
    この設定で、眉毛 / 睫毛・白目・目・前髪の順番で描画されるようになり、前髪がNotEqualでマスクされます。

もし設定があっているのにうまくいかない場合はRendaringModeが正しく設定されているか確認してください。
又、マテリアルのシェーダーを取り換えた時、RenderQueueがリセットされてしまうのでFromShaderか手動で設定しなおしてください。

全て半透明の方法

前髪のみTypeA/Toon02Fade(TypeA/Toon02FadeEdge)を使用します。

半透明の実装方法ですが、一旦全てNotEqualでくり抜いて、その中の半透明にしたい部分だけをEqualで判定して追加で描画する、という方法にしました。

全て半透明の場合、シェーダーを変えるだけで設定は全て完全透過と同じです。

一部を半透明にする方法

ReferenceValue / ReadMask / WriteMaskの組み合わせで、あるビットがOnなら完全透過、別のあるビットがOnなら半透明で描画、という状態に設定します。

サンプルモデルの「眉と睫毛は完全透過、他は半透明」の説明をします。
分かりやすいように数値を揃えていますが別の設定でも条件を満たせば可能です。

サンプルモデルの設定の場合、2進数で言うと、完全透過部分に10を書き込み、半透明にしたい部分には11を書き込み、11と比較して、10の部分をくり抜いて、01の部分に半透明描画、という設定になります。

マテリアルは半透明の分が一つ増えて最低3つ必要になります。
説明はサンプルモデルのマテリアル5個の説明です。

  1. 完全透過にしたいもの 眉 / 睫毛
    ReferenceValue : 6
    ReadMask : 4
    WriteMask : 4
    PassOperation : Replace
    この設定で値4になるビットを読んで値6を値4になるビットに書くマスクとなります。
  2. 半透明にしたい物の非透過物 白目
    ReferenceValue : 6
    ReadMask : 6
    WriteMask : 6
    ComparisonFunction : NotEcual
    PassOperation : Replace
    この設定で値6になるビットを読んで値6の値6になるビットがNotEcualなら、値6を値6になるビットに書くマスクとなり、眉毛と睫毛を避けて描画します。
  3. 半透明にしたい物の透過物 目
    ReferenceValue : 6
    ReadMask : 2
    WriteMask : 6
    ComparisonFunction : Ecual
    PassOperation : Replace
    この設定で値2になるビットを読んで値6の値2になるビットがEcualなら、値6を値6になるビットに書くマスクとなり、値2になるビットには白目だけが書き込んでいるので白目が書かれた部分だけ描画します。
  4. 前髪
    ReferenceValue : 6
    ReadMask : 4
    ComparisonFunction : NotEcual
    FadeのReadMask : 2
    この設定で値4になるビットを読んで値6の値4になるビットとNotEcualなら描画せず、値2になるビットを読んで値6の値2になるビットとEqualなら半透明で描画します。

Use with VRChat

現在はマテリアル設定時に指定したレンダータイプ及びレンダーキューが使用されているようなので、VRChatでの特別な手順は必要ありません。

※以下の作業は不要です。

VRChatで利用する時の注意点と必須の手順の説明です。

RenderQueue指定の為の必須の手順

VRChatで利用する場合、現在のVRCの仕様(?)でファイルに記載されているRenderTypeとRenderQueue(=FromShaderの値)を使うので、Inspectorで設定した値になるようにファイルで指定したシェーダーを用意する必要があります。

サンプルモデルの目に利用しているTypeA/Toon02_Geometry+20_cutoutを例にします。

  1. エクスプローラーなどで元になるシェーダーのファイルをコピーする。
    シェーダー名を変更する前にUnityをアクティブにすると(Unityに読み込ませると)シェーダー名が同じなので誤動作します。
  2. 適切にファイル名を付けたらVSなどのエディターで開き先頭にあるシェーダー名を変更する。
    画像は変更後のものです。
  3. 70行目辺りにあるSubShaderのTagを適切に変更します。
    Geometry+20というのがRenderQueueで2020を意味します。
    Geometry : 2000 / AlphaTest : 2450 / Transparent : 3000
    RenderTypeはTypeAAnimeShaderのRendering Modeです。
    Rendering Mode : RenderType
    Opaque : Opaque / Cutout : TransparentCutout
    Fade : Transparent / Transparent : Transparent
  4. 2か所を書き換えたら保存してUnityに読み込ませます。
    設定したシェーダー名のシェーダーが追加されているはずです。
    追加されていたらProjectタブでシェーダーをクリックしてInspectorに表示させ、RenderQueueを確認してください。

    正しく変更出来ていればRenderQueueが画像のように指定した値になっています。
  5. 目のマテリアルをTypeA/Toon02から変更したシェーダー名のシェーダーに切り替えます。
    例ではTypeA/Toon02_Geometry+20_cutout
    Rendering ModeとRenderQueueを確認してください。
    RenderQueueでFromShaderを選択すると指定したものになります。

同様に、必要な分のシェーダーを用意して付け替えてからアバターをアップロードしてください。

ステンシル機能使用時の注意点

ゲーム内ではミラーに映した場合なども含めて問題ないのですが、アバター選択画面で表示される時に表示がおかしくなる場合があります。
サンプルモデルをそのままの設定でアップロードした場合、目が表示されません。

ワールド内にステンシルバッファを利用した物がある場合、ステンシルの設定値によっては、透けないはずの部分が透ける場合があります。
全ては確認しきれないのではっきりとは言えないのですが、自分が遭遇したのはステンシルを利用している可能性のある透過物と前髪が重なった時、前髪全体が半透明になってしまった、という物です。
この時前髪のファイル上のRenderType指定はTransparentCutoutだったのですが、各Mask値を調整しても透け方や何と重なると透けるかという所は変化したのですが解決しませんでした。
そこでRenderTypeをOpaqueにした所、影響を受けなくなり解決しました。

別の例だとunity上ではSceneタブ、Gameタブ、どちらでも希望通りの描画になっているのに、VRCにアップロードしたら目が表示されない場合があったり、完全透過と半透明のエリアが重なっている部分の描画がおかしくなる、というような事があったりしました。

いずれの場合も各設定値を変える事で望む結果を得られましたが、どの設定値でもUnity上では変化が無い=望む表示なので、VRCにアップロードしたら描画がおかしいとなった場合、各設定値を変えて試してください。

透過物が絡む場合は要注意のように思います。

Sample using Blender

Creation of texture for TyprAAnimeShader with Blender
blenderを使ってTypeA Animeshader向けのテクスチャ作成をする場合の例

サンプルファイル / SampleFailes

TAAS_blenderFiles01.7z  Download

TAAS.blend
ToonGenerate.blend
Weight2vcolor.py

TAAS.blend

使用方法。
テクスチャを作成したいモデルのUV展開をしてこのマテリアルを指定。
テクスチャペイントモードで描画対象を画像にしてスロットで各画像を選択。
BaseColor / ShadowColor / HilightMap は好みの色で、
ShadowMap / Hilight_A は 白 / 黒 で書き込みます。

HilightMap以外は画像を保存して完成、
HilightMapはレンダリングする事でHilightMap_Aがアルファチャンネルに組み込まれます。

blender本体の保存と各画像の保存は別扱いなので、各画像の保存を忘れないようにしてください。

sphereにはアウトライン表示用の厚み付けモデファイヤ・専用のマテリアル(ノード使用)がセットしてあり、3Dビューの裏面の非表示にチェックしてあります。
頂点グループと頂点カラーが作ってありWeight2vcolor.pyが読み込んであるのでこちらも参考にして下さい。
ペイント時に厚み付けが邪魔になるので表示をOffにしてあります。

サンプルのSphereで試してみて下さい。

  1. TypeAAnimeShaderのinspector内プロパティに相当する部分を纏めたフレームで、unity/blenderで設定を同じにする事でほぼ同等の描画状態になります。
  2. HilightMap作成時に合成途中を見れる方が作りやすかったので出力を3通りに切り替え出来るようにしてあります。
    出力のいずれかを右クリックでアクティブすると、その出力に切り替わって描画されます。
    上から、最終結果 / Toon適用 / hailightMapのAlpha(出現エリア設定)適用
  3. コンポジットノードにHilightMap(rgb)とHilightMap_A(a)を一つの画像にして出力するように設定してあるので、レンダリング(F12)するとhilightmapが出力されます。
    ここで出力するテクスチャのサイズを設定します。
  4. テクスチャモードに切り替えて書き込みします。
  5. 画像から保存や再読み込みなど。
    blender本体の保存と各画像の保存は別扱いなので、各画像の保存を忘れないようにしてください。

ToonGenerate.blend

TypeAAnimeShaderやその他のToon用テクスチャをBlenderで簡単に作成するサンプルです。
blenderのノードでtoon設定した場合カラーランプを使用する事が多いですが、
そのカラーランプの状態をそのままテクスチャに出力します。

  1. TypeAAnimeShaderのinspector内、BaseColor / ShadowColor / Toon / Lighting Direction に相当する部分です。
    Lightingのノードのつなぎを変更する事でTypeAAnimeShaderのLightingMode View / Light と同等の切り替えができます。
    ライトはhemiライトが配置してあります。
  2. このマテリアルに設定してあるblendテクスチャのカラーランプを調整してtoonを作成します。
    このカラーランプの状態がそのままテクスチャに出力されます。
  3. 出力した画像を適用する場合、その画像を使用したテクスチャを作成すれば、ここで選択してBlendと切り替えて表示出来ます。
    画像で1の部分のblendと見えている部分と対応しています。
  4. blendテクスチャなど生成テクスチャは通常リアルタイムでは表示されません。
    レンダリングモードをレンダーに変更する事でリアルタイムで変化を確認しながらtoonの作成が可能です。
    作成した画像を確認する場合、保存・再読み込みして3の所で切り替える事で確認出来ます。
    この場合はレンダリングモードはマテリアルやテクスチャでOKです。
  5. 画像から保存や再読み込みなど。
    blender本体の保存と各画像の保存は別扱いなので、各画像の保存を忘れないようにしてください。
  6. コンポジットノードにカラーランプの状態がそのまま出力されるように設定してあるので、レンダリング(F12)すると画像として出力されます。

Weight2vcolor.py

モデファイヤの厚み付けでリバースポリゴンのアウトライン表示が可能ですが、この時頂点グループを指定する事でモデファイヤの効果を調整出来ます。
これを利用してアウトラインの太さ制御を簡単に行えます。
(モデファイヤの設定はTAAS.blend内参照)
この時利用するウェイト値をTypeAAnimeShaderで利用する為に、頂点カラーのR成分に書き込むスクリプトです。

TypeA AnimeShader Inspector

TypeA/Toon02

Rendering Settings

Rendering Mode
レンダリングモードを設定します。
RenderQueue
RenderQueueを設定します。

SrcBlend
レンダリングモードが、CutOut,Fade,Transparentの時のブレンド方法を指定します。

DstBlend
レンダリングモードが、CutOut,Fade,Transparentの時のブレンド方法を指定します。

AlphaCutoff
レンダリングモードが、CutOutの時のカットオフ値を設定します。

ColorMask
書き込みチャンネルの設定。チェック有りで書き込み。

AlphaToMask
アルファチャンネルをマスクするかどうか。チェックでマスク有り。

ZWrite
デプスバッファに書き込むかどうかを設定します。

Culling
カリングの仕方を指定します。

ZTest
デプステストの方法を設定します。

ObjectColor
オブジェクトの色を指定します。
通常は(r,g,b)=(1.0,1.0,1.0)=白から変更する必要はありません。
レンダリングモードが透過の場合、アルファが透明度として使用出来ます。

Stencil Settings

ReferenceValue
マスクする時・される時に参照する値を設定します。

ReadMask
ステンシルバッファを読み込む時、どのビットから影響を受けるかを指定するマスク値を指定します。

WriteMask
ステンシルバッファを書き込む時、どのビットに影響させるかを指定するマスク値を指定します。

ComparisonFunction
バッファの現在の内容と基準値を、どのように比較するかを設定します。

PassOperation
各テストにパスした場合、バッファの内容をどうするかを設定します。

FailOperation
ステンシルテストに失敗した場合、バッファの内容をどうするかを設定します。

ZFailOperation
デプステストに失敗した場合、バッファの内容をどうするかを設定します。

Toon02Fade / Toon02FadeEdge の追加設定項目

FadeMask settings

readMask
フェードさせたいビットを設定します。
このマスク値から漏れた部分は通常の完全透過のマスク結果となります。
一部を半透明化させたい場合に使用します。
Stencil Fade
フェードの強さを設定します。

Main Color Settings

BaseColor
基本色のテクスチャを設定します。
テクスチャが未指定の場合、カラーピッカーで設定した色が使用されます。

ShadowColor
影色のテクスチャを設定します。
テクスチャが未指定の場合、カラーピッカーで設定した色が使用されます。

ShadowMap
手動で影を付けたい場所を指定する為に使用します。
影にしたい部分を黒又は黒に近い色にし、明るくしておきたい部分は白にします。
ライティングの結果やシステムシャドウの値などと合成した後の値がToonの色分けに使用されます。
このマップは2値の必要はなくグラデーションさせれば影の付き方が半固定のようになります。

Toon
このテクスチャで基本色と影色に振り分けます。
テクスチャの状態でくっきり分けたり暈したり出来ます。

Lighting Direction
ライティングの方法を指定します。
0でView方向、1でLight方向、からのライティングになります。
スライダーで双方を混合出来ます。

View
システムシャドウ以外、常に視点方向から照らしているようになります。

Light
BasePassで利用可能なライト情報全ての中で一番明るい方向に光源があるものとして陰影付けをします。
追加のピクセルライティング(AddPass)で処理されるライトは情報が取れない為、これに含まれません。

光源判断に含まれるもの
・メインのライト(一番明るいDirectional Light)
・頂点シェーディングされるポイントライト
(4つまでのNotImportantのもの)
・LightProbから得られる環境光。
Unityマニュアルの「フォワードレンダリングパスの詳細」の説明でPer-VertexとSHに含まれるものとメインのライトです。

複数ライティングによって塗り分け部分が何重にも重なる現象防止の為、Viewを含めた各方向(強さ含む)情報から、一番影響の強い方向に光源があるものとして陰影付けします。

Lightに設定していて方向を示す情報が無い場合、ワールド空間上でカメラの上方に光源があるものとして処理します。

Viewが混合されていて方向を示す情報が無い場合、View方向(0に設定)の扱いになります。

AnchorPoint v1.0.7で追加
メッシュに設定したアンカーオーバーライドが効かない場合の応急処置。
メッシュの属するFBXファイルに含まれるもの以外は効果が無いようなので設定できるようにしましたが、変形には対応できないため、あくまでも応急処置です。

以下の4つの設定で法線を変化させ、影の付き方を調整出来ます。

Expand Spherically
面法線を球状に拡張します。1で完全な球状。

Spherical Center
球状に拡張する際の中心位置を指定。0でMeshの中心位置。
同一オブジェクト内でMeshが分かれている場合、MeshRenderer>>Bounds>>Centerの値を指定する事でそのMeshの中心を指定出来ます。

Normal Scale X,Y,Z
頂点の法線を指定座標毎に拡大縮小します。
この設定を変えると本来のモデルよりも凹凸が大きい又は小さいような陰影になります。

Normal Rotation X,Y
頂点の法線を指定座標軸毎に回転させます。
この設定を変えるとライトが回転したかのように陰影の付き方が変化します。

MainLighting Affect
GIを含めたメインライティングの影響度を設定します。

AmbientLight Color
MainLightingAffcetに含まれる環境光の成分をそのまま使うか明るさ情報のみとして利用するか指定します。
メインのライティングはそのままに環境光の色成分だけ弱めたい時などに調整します。
0で明るさのみ、1で通常の色。

AmbientTilt v1.0.7で追加
人体モデルなどで足元付近(上下先端付近)の影響が強すぎて見える場合などの調整用。
様々な要因や好みもありますが人体モデルだと0.7前後が程よいと思います。

AddLighting Affect
追加のライトがある場合、追加ライトの影響度を設定します。

上記2つをゼロにした場合、影とならない場所はテクスチャの色がそのまま使用されます。

Saturate Value
ライティングによる白飛び飽和値を調整します。
1.0以上の値をいくつまで反映させるかを1.0~10.0範囲で設定します。
アニメ調の塗分けではすぐに白飛びするので1.25程度がおすすめです。

Shadow Affect
ライティング計算の陰影とShadowMapで指定した部分の影の影響度を設定します。

SystemShadow Affect
unityのシステムシャドウを使用している場合、その影響度を設定します。

AddSystemShadow Affect
追加のライトのシステムシャドウを使用している場合、その影響度を設定します。

Handl Shadow
システムシャドウをディフューズの陰影に含めるかどうかを設定します。

IncludeInDiffuese
ディフューズの陰影に合成され影色で描画されます。

DropAsAShadow
ディフューズの陰影とは別に影として描画され、個別に色指定します。

SystemShadowColor
ShadowColorと同様にテクスチャでシステムシャドウの色指定が出来ます。
テクスチャが未指定の場合、カラーピッカーで設定した色が使用されます。
(アルファは無効)

Hilight Settings

HilightMap
ハイライトの出現するエリアとその周りに滲む色を指定するテクスチャを設定します。
テクスチャが未指定の場合カラーピッカーで指定した色が使用され、出現エリアは全面となります。

Toon(Hilight)
ハイライトの出方とその周りの色の滲み方を指定します。

Hilight Intensity
ハイライトの総合での強さを設定します。

Hilight in Shadow
影になる部分でのハイライト強さを設定します。
ゼロにすると影の部分ではハイライトが出なくなります。

Hilight Hardness
ハイライトの硬さを設定します。
Toonを通す前の値は、数値が小さいとぼやけた感じ、大きくするとクッキリした感じになります。

Hilight Power
ハイライトの部分の強さを調整します。

Color Spread
ハイライトの周りの色の滲みの強さを設定します。
ゼロにすると滲みの色が出なくなります。
Toonでの設定で滲み部分を弱くしている場合効果は殆どありません。
Toonで調整しても強すぎるという場合に調整します。

Toon02Edge / Toon02FadeEdge

Outline Edge Settings

Edge Color
アウトラインの色を設定します。

BaseColorMixing
アウトラインに基本色を合成するかどうかを設定します。

Mixing strength
合成する場合、その強さを設定します。

ShadowColorMixing
アウトラインに影色を合成するかどうかを設定します。

Mixing strength
合成する場合、その強さを設定します。

Edge Tchickness
アウトラインの太さを設定します。

VColor(R) to Edge
頂点カラーの赤色成分を利用してアウトラインの入り抜きなどの太さ制御を利用するかどうかを設定します。
1の時最大でEdgeTchicknessで設定した太さ、
ゼロの時アウトラインが消えます。