読者です 読者をやめる 読者になる 読者になる

AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

ToonLitOutlineとステンシルによるOutlineの違い

シェーダー

今後もトーンシェーダーを中心に使っていきたいので勉強中なんですが、
漫画にはペン入れという文化があって、デジタルの世界のでもペンの入りと抜きとかで、絵の雰囲気がずいぶん違う。
ただし、3DCGの世界でペン入れを考えるとどうなんだろう?
既存のToonOutlineの描画を見てもなんか無機質でいまいちな感じがします。

以下の記事を見てアウトラインに興味が出た。
tarowork.hatenablog.jp



f:id:yasu9780:20170207011928p:plain

右がStandardAssetsのToonLitOutlineによるアウトライン描画
左がステンシルを用いたアウトライン描画
 ステンシルってのは描画のシルエットを2D的に抜いてマスク表現できる技術のようです。


右はキャラと重なる部分もアウトラインが出る。要するにメッシュの表面にアウトラインが出ている。
ステンシルの左は、キャラと重なる部分はアウトラインが出ない(その分すっきりする)

分かりやすいようにわざとアウトラインは紫にしました。
後ろのキューブもステンシルアウトラインを使っているので、重なる部分にアウトラインが出ていない。


ToonLitOutLineは、本体は以下。

v2f vert(appdata v) {
		v2f o;
		o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

		float3 norm   = normalize(mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal));
		float2 offset = TransformViewToProjection(norm.xy);

		o.pos.xy += offset * o.pos.z * _Outline;
		o.pos.z += _OutlineZOffest;
		o.color = _OutlineColor;
		return o;
	}
ENDCG

頂点を法線方向に線の太さだけ膨らませて、そこにOutlineColorの色を書き込んでいる。
なのでキューブの角みたいに法線ベクトルが不明(?)なところはアウトラインが出なかったりする。

ステンシルの方は、
描画したシルエットを2D的に保存しておいて、描画が無かったところの枠を広げて枠線描くみたいな感じ。

v2f vert(appdata v) {
	v2f o;
	float4 vert = v.vertex;
	vert.xyz += v.normal * _Outline;
	o.pos = mul(UNITY_MATRIX_MVP, vert);
	return o;
}

細かい行列計算はよくわかりませんが(´・ω・`)
お約束的な表現でコピペでGO



昨日デカール対応で改造したToonShaderの前に

			
			Stencil{
				Ref 128
				Comp always
				Pass replace
			}

を入れて、後ろに

Pass{
	Stencil{
		Ref 128
		Comp NotEqual
	}
	Cull Off
	ZWrite Off
	Blend SrcAlpha OneMinusSrcAlpha

を入れて、その後、枠線表示する部分入れたらいけた。

CullOffだから表面、裏面関係なく描画。

Comp Equal 使えばシルエット抜けるし、シルエットの外なら、Comp NotEqual


https://www.assetstore.unity3d.com/jp/#!/content/7475

AssetStoreで$40で売られているKayacのSugiyamaShaderの解説動画を見てみると
カメラ距離に応じて枠線の太さを調整しているようで

  • 通常カメラから遠くなると枠線も写像変換で細くなるところを、遠くても変わらない。
  • テクスチャの色を見て自動的に枠線をテクスチャにマッチした色に変更できる

これが売りらしい。


これはありますね。たしか戦車の漫画で、戦車はCGで人物が手書きの漫画があったんですが、戦車の枠線は戦車が小さい(遠い)と細くなって明らかに違和感がありました。
もっと昔で、絵をコピーして貼るような時代でもコピーして貼る場合、縮小すると枠線が細くなるので、すぐわかるわけです。
人物が遠いなら小さくなるのは遠近法的に当たり前ですが、枠線は細くなってはダメなんですね。
そういう意味では枠線は記号表現であって、その記号は遠近法に縛られないのか?
それとも、物理的にペン入れの太さは決まっているので、遠いキャラでも枠線が細くならないことに、漫画を読むことで慣れてしまって、
その結果、CG表現の遠くは枠線が細くなることに違和感を感じるのか?
よく理由は分からない(´・ω・`)


距離に応じて枠線を太くするのは、簡単にできそう。
テクスチャのUVに応じて枠線の色を変えるのはよさそうですね。通常は枠線は1色指定ですけど、周囲に合わせると和らかい表現になる。
これは影色も同じで、青い服なら影は黒より濃紺のほうがいい。これは環境色の映り込みと考えると納得できる。


tsubakit1.hateblo.jp

ninagreen.hatenablog.com

onoty3d.hatenablog.com

tips.hecomi.com

広告を非表示にする