3Dプリンタ的表現 ~メッシュの空洞をどう埋める?~

はじめに

上の動画は、3Dプリンタでのフィギュア生成のタイムラプス動画です。

こんな感じの表現をCGでやろうとすると、Meshの内側の空洞部分を埋める必要があることに気づきます。今回は、それを簡単にやる一つの方法を紹介します!(途中で触れますが制約もあります…)

また、ここで説明する内容を実装したサンプルデータを以下で提供しているので、実際に動くデータがすぐに欲しい方は、確認してみてください(最後に記載してあるおまけの実装データも入ってます)。

https://heyyohanashima.gumroad.com/l/nlujvf

環境

Unreal Engine 5.2.0

方法

結論から話すと、断面に板ポリを配置し、スクリーン上の対象Meshの裏側が表示されている所以外を透明にして見えなくするという方法をとっています。

実装

  1. MeshとStencil Valueのセットアップ
  2. Stencil Valueを使い、板ポリをMaterialで透明にする
  3. 制約

1. MeshとStencil Valueのセットアップ

まずは、作業しやすくするため、BPで必要なMeshをまとめます。

  • Front:対象Meshの前面だけ描画する用のMesh(Two Sidedオフのマテリアルをアサイン)
  • Back:対象Meshの裏面を描画する用のMesh(Two Sidedオンのマテリアルをアサイン)
  • Cover:対象Meshの内側を埋めて見える用にする板ポリMesh

そして、BackのMeshにStancil Valueを設定します。以下のように、Render CustomDepth Passをオンにし、CustomDepth Stencil Valueに好きな値(今回は2)を入れます。この値は、後にCoverのマテリアルで使います。

また、Frontの方も、Render CustomDepth Passをオンにします。
そして、Backの方はNormal方向に少し縮めて、前面はFrontより少し内側にくる(=カメラから見えない)ようにします(TwoSidedSignで裏面だけ表示する方法は、後述の影を描画するのが正しくならないので使いません)。

これで、丁度対象Meshの裏側が表示されている所だけ、設定したStencil ValueがBufferに書き込まれます。

※ Custom Stencilを使う場合は、Project Settings>Rendering>ProstprocessingのCustom Depth-Stencil PassをEnabled with Stencilに変える必要があるので注意してください。

デフォルトだとMeshの裏面は影を落とさないので、BackのShadow Two Sidedにチェックを入れて、影が正しく出るようにします。

2. Stencil Valueを使い、板ポリをMaterialで透明にする

次に、このStencil Valueをマスクとして使い、Coverのマテリアルで対象Meshの裏面をカバーする部分のみが描画されるようにします。

処理自体はとてもシンプルで、SceneTextureノードでCustomStnecilを取得します。そして、それがBackのMeshに設定したStencil Value(今回は2)と一致していたら1、それ以外だったら0以下になるように処理し、Opacityにつなぎます。

これで、Coverがちょうど対象Meshの裏面部分だけに描画されるので、空洞部分を埋める簡易的な表現ができました。

3. 制約

割とお手軽に空洞を埋める表現ができるものの、上手く調整しづらい部分もあり、大きく分けて2つの制約があります。

① 空洞を埋める板ポリに半透明しか使えない

Stencil Value(GBuffer)をマテリアルから取得するには、半透明以下の描画順でしかできないので、この方法を使う場合、埋めている空洞部分が半透明になってしまいます。

半透明だと、Lighting周りの処理が不透明と異なってくるので、質感がうまく出しづらいです。

これの回避方法としては、SceneCapture2Dを使う方法が一応あります。チューニングをしっかりしてあげれば、SceneCapture2Dを使っても、今回のケースなら負荷はある程度抑えられるので、やりようとしてはありかもしれません。

② 対象Meshに貫通があると破綻する

Meshに貫通している部分があると、Meshの内部に表側のMeshが入り込んでしまうので、その部分はStencil Valueが書き込まれず、板ポリも描画されないので、空洞を埋める表現としては破綻が起きてしまいます。

現状これの回避策はあまり思いつかないので、AnimationのあるMeshにこの方法を使うのは現状難しいかなと思います。

おまけ

埋める部分が半透明になってしまう問題は、SceneCapture2Dを使うことで回避できます。

以下は、SceneCpature2Dを使って、空洞を埋める板ポリに不透明マテリアルを割り当て、Normalを軽く付けてみたものです。

また、以下のように向きを自由に調整できるようにもしてみました。

以下で提供しているデータは、上記で解説したものに加え、おまけのSceneCapture2Dを使用したものと向きを調整できるようにしたものも含んでいるので、実装が気になる方は見てみてください!

https://heyyohanashima.gumroad.com/l/nlujvf