
何故、輪郭検出にFreePencilというアドオンが必要なのか?
こんばんは、榊正宗です。
現在FreePencil v1.1の最終追い込みをやっています。公開までもうしばらくお待ち下さい!
(追記)
こちらの記事に関しまして、FreePencilをゴリ押ししているのではないかという意見を頂きました。こちらの記事は、FreePencilを開発する前に、数ヶ月かけて、シェーダーのみで輪郭検出できないか検証したときの情報の一部を紹介したものです。(実際にはもっといろいろ試しています)その上で、シェーダーをつかった輪郭検出には限界があると判断し、FreePencilを開発しました。そういった経緯がありますことをご理解下さいませ。また、わたしと同じようにシェーダーでの輪郭検出にチャレンジして時間を無駄にされることがないように、こちらの記事を参考にして頂けますと幸いです。
Blender3.4α版にリアルタイムコンポジターノードが実装されたことが話題になっていますよね。
Blender 3.4.0 Alphaのリアルタイムコンポジットで線画抽出フィルターのテスト。
— Samia (@samia_done) August 19, 2022
何番煎じかわからんけど、自分でも試してみたかったw pic.twitter.com/I1HrLxZPVA
↑こんな感じでリアルタイムに線が出ます。
さて、こちらの方は別にFreePencilを使っていません。シェーダーで出力したAOVから輪郭線だせばいいだけじゃない?と思ってる人も多いかと思います。
FreePencilは何故必要なのでしょうか?
まずはこちらの画像を御覧ください!

コンポジターで輪郭線を出す技法は、ノーマルシェーダーを使う方法が一般的です。
ノーマルシェーダーで出した色を、コンポジターのソーベルというノードを使って輪郭線に変換します。
このソベールというノードは、単に色が違うところを線として検出します。そのため、ノーマルで面の色を塗り分けてやると線が出るという単純な仕組みです。
しかし、よく見て下さい。

ノーマルは面の向きを色として表すシェーダーです。このように、凸面は違う色になりますが、凹面(凹んでいる面)は、同じ向きの面は同じ色になってしまうため、コンポジターで輪郭検出が出来ません。

↑ノーマルだけでは凹面に線が出ません。しかし、これを解決するアプローチは無いことはありません。
ノーマルを補うために深度情報を足すのが一般的です。

こちらおわかり頂けますでしょうか?

たしかに深度を使うと凹んだ面を少しだけ検出しますが、よく見て下さい浅い面は検出できません。これは深度情報が8ビットの色に変換されてしまうためです。情報不足で浅い凹面を検出出来なくなります。
そこで、次のアプローチとして、頂点座標を正規化した「生成」というデータを使う方法が出てきます。

深度より凹面を検出出来ました。しかし、斜めになった浅い面はこの方法でも検出は出来ません。生成は深度よりは情報が多いのですが、それでも、単に頂点と重心の距離を1という数字置き換えてXYZをRGBにしただけの情報ですので、斜めになった浅い凹面などは、塗り分けきれないのです。
凹面を検出するには、AOを使う方法もあります。

これで、なんとか凹面の輪郭が検出できました。

しかし、今度はAOが強く出すぎて線が潰れたり汚くなるところが出てきます。検出もよく見ると、惜しい感じで完全ではありません。
さらにAOは、レンダリングサイズではなく画面表示サイズで見た目が変わり、レンダリングもやや重くなってしまいます。かなり精度をあげないときれいにグラデーションにならず、ノイズだらけになってしまいます。そのため、輪郭検出には使いづらいところがあります。
シェーダーの色は、しょせん8ビットの情報に過ぎません。そのため、どこかで限界が出ます。シェーダーの深度をカラーにしたり、繰り返したりして8ビットの制限を水増しするという方法もありますが、深度も生成も斜めの面が苦手です。実際にわたしの言うことを信用できず、自分でも検証してみたいという方は、斜めの浅い凹面に線が出せるか試してみて下さい。かなり手強い形状であることがわかると思います。
この他にも方法はあるのですが、全部一長一短があり、シェーダーが複雑になるだけで、良い結果にはなりません。数ヶ月かけて、検証したのでたぶん間違いないと思います。
結論を言います。
シェーダーを使って、きれいな輪郭線を完璧に出す方法は、(おそらく)存在しません。
そこでFreePencilの出番です!

このようにFreePencilを使うと浅い面、斜めの面でも塗り分けることで輪郭線を出してくれます。
さらに、そもそも関節単位の塗分けなど、シェーダーでは絶対に不可能な塗分けにも対応しています。


↑シェーダーではこんな塗り方で、輪郭検出するのは、絶対無理だと思います。
つまりBlenderにリアルタイムコンポジターが実装されれば、FreePencilが必要になると思います。
もちろん、UVカラーを使ったり、頂点カラーを手塗りすれば、同じことが出来ます。しかし、とても面倒な手作業が発生します。それをかなりのレベルで自動化してくれるのがFreePencilなのです。
「#freepencil というレンダリングの速い輪郭線アドオンが出たそうですよ」
— 榊正宗@FreePencil開発者 (@megamarsun) August 1, 2022
「あ~ダメダメ、要するにコンポジットの輪郭線でしょ?昔からあるけど密度の高いところで線が潰れたりするから」
という会話が聞こえたような気がしたので今日は線が潰れないノードをご紹介します!https://t.co/pQiMxCQGtS pic.twitter.com/NM4oPZCe33
↑線がつぶれにくいノードも実装出来ます。
https://twitter.com/megamarsun/status/1559511530479452160
VRoidはちょっとテクスチャ濃いめなのでわかりにくいのですが、輪郭線は赤いところにでています。 pic.twitter.com/eMdzhWGJQe
— 榊正宗@FreePencil開発者 (@megamarsun) August 16, 2022
↑VRoid対応もほぼ出来ています(V1.1で対応します)
https://twitter.com/megamarsun/status/1549090320347832320
現在開発中のBlender輪郭線アドオンFreePencilは、Unity上ではリアルタイム表示が出来ます。 pic.twitter.com/WVhTAhIU6R
— 榊正宗@FreePencil開発者 (@megamarsun) July 18, 2022
↑Unityにも対応します。BlenderのFreePencilで作ったデータをUnityで輪郭検出する機能です。原理的には、Blenderのリアルタイムコンポジターと同じです。複雑なBlenderのシェーダーはUnityなどでは輪郭線を再現できませんが、FreePencilは頂点カラーを塗っているだけなので、他のソフトでも再現出来るのです。
↑こちらに支援についての記事を書いています。基本的にはアドオンは無料で公開しておりますが、開発のご支援をしていただけると、とてもありがたいです。
何故、輪郭検出にFreePencilというアドオンが必要なのか?あまり理解されていないようなので記事を作りました。従来のシェーダーによるコンポジターの輪郭検出より圧倒的に優れています。リアルタイムコンポジターと合わせれば最強のアドオンに進化します!マジで。 #note https://t.co/6bZ1ct2oNb pic.twitter.com/I7jysqpqet
— 榊正宗@FreePencil開発者 (@megamarsun) August 19, 2022