LightWave で NPR:筆描き表現を目指して #1

再挑戦

LightWave4年前に挫折した表現への再挑戦。ノンフォトリアリスティック・レンダリング (Non-Photorealistic Rendering; NPR) として、3DCGで水墨画風というか、筆で描いたようなモノクロ画を出力する試み。

もともとは以下の v11.5 機能紹介動画で水墨画風を実現しているように見えたので、どうすればこれができるのかと思ったのがきっかけ。

この動画で使われているのは[Turbulent Noise]ノードで、これを[Edge]ノードの[Silhouette Edges Opacity]へと繋げていることまでは動画の画面から見て取れる。そして「背景を白にしてオクルージョンノードと組み合わせることで、水墨画のような表現もおこなうことができます」と解説されており、どうやらサーフェイスでのノード編集も必要そうなのだが、この動画だけでは詳細が不明だった。そこで LightWave 日本版販売元である D-STORM のテクニカルサポートへ問い合わせてみたところ、解説付きでデータを頂けた(感謝)。以下はエッジのノード編集設定。

そこで分かったが、ここでは[Occulusion2]ノード([Shaders]>[Diffuse]>[Occulusion2])を[Surface]ノードの[Color]入力へ繋げている。[Occulusion2]ノードの編集パネルでは、[Color Mapping]を[Backdrop]にしてある。

そして[レンダー]タブ>[オプション]>[レンダーオプション](ショートカット【Ctrl+p】)>[大域照明]タブの[ラジオシティ有効]にチェックを入れて、ラジオシティを利用するようにと解説されていた。だが、受け取ったデータでレンダリングしてみたところ問題が生じた。

……あまり水墨画っぽくない。さらに言えば、筆で描いたようにもそこまで見えない。画像の上方が薄くなっているのは、よくわからないが何かの設定が原因だろう。しかしこの際それは問題ではない。

動画内でも見られるVPR (Viewport Preview Renderer) 、つまり簡易レンダリング画面ではざらついた様子でかなり好ましい印象なのだが、実際にレンダリングしてみると「これじゃない」感じを受けてしまった。[Occulusion2]ノードを使った薄墨表現にあたる部分も単なるぼけたグレーに見えてしまい、墨っぽい粒子感は消えている。

そこで、もう少し「それっぽい」表現ができないか試行錯誤してみた結果、最終的にこのような画を出力することができた。

簡単な直方体(モノリス)と球、歯車、そして以前に紹介し再配布している『終りなき戦い』のコンバットシェル(改変版)を利用している。なお、テクスチャは面倒なので使用していない。ソフトウェアの使用バージョンは LightWave 2015.3 日本語版である。以下にその Layout における手順を記しておく。

手順

あらかじめ、Layout のビュー表示をVPRにしておく。そしてオブジェクトとカメラの位置を決める。さらに、背景を標準の黒から白にしておく。Layout 画面左上の[ウィンドウ]>[背景オプション](ショートカット【Ctrl+F5】)>[特殊効果]ウィンドウ>[背景]タブ>[背景色]で、カラーボックスをクリックして白 (RGB: 255, 255, 255) に設定。済んだら[特殊効果]ウィンドウは閉じてよい。

出したいエッジを決める

まず、出す輪郭線の種類を決める。左下で[オブジェクト]を選択して右の[プロパティ]から[オブジェクトのアイテムプロパティ]ウィンドウを出し(ショートカット【p】)、[輪郭(Edges)]タブの欲しい輪郭線項目にチェックを入れて有効化する。線の太さは任意だが、太めの方が分かりやすいので、よく分からなければ20-25ピクセル程度にしてみるとよいだろう。ウィンドウの上部にある[現在のオブジェクト]から続けて選択して、すべてのオブジェクトごとに欲しい輪郭線項目を設定する。しかし、このままだと均一な線になってしまうので、この線に手を加えていく。

ところで、曲面については浅めの角度でスムージング設定していても、分割数が低いとカメラ距離が近い場合にカクついた輪郭線が出力されるので、多少は細かく割ったもののほうがよい。今回の例でいえば、球体は[サイド]が「48」、[分割数]が「24」のボールとして作成し、コンバットシェル含めてサーフェイスの[スムースしきい値]は「30.0°」にしてある。[サイド]が「24」、[分割数]が「12」だとカクカクな輪郭の球になった。

輪郭線のノード編集

[輪郭(Edges)]タブの[ノード編集]ボタン右隣のチェックボックスをオンにし、[ノード編集]ボタンを押して[Node Editor]を開く。

左に並んだ中から[3D Textures(3Dテクスチャ)]>[Turbulent Noise]を選択して、[Turbulent Noise]ノードを出す。Turbulent は「乱れの、乱流の」という意味。この[Turbulent Noise]ノードを使うと、フラクタルノイズのプロシージャルテクスチャ(計算で自動生成されるテクスチャ)を追加できる。要するに、ここでは線に手描きっぽい粗(「太さの乱れ」や「濃淡」)を加えられるということである*1

[Turbulent Noise]ノードの右にある[Alpha]から矢印をドラッグし、[Edge]ノードに並んでいる[Silhouette Edges Taper]と[Silhouette Edges Opacity]、[Sharp Creases Taper]と[Sharp Creases Opacity]など、手を加えたい線の項の[~Taper]と[~Opacity]に矢印をそれぞれ接続していく。ちなみに今回の例では[Intersection Edges Opacity(交差エッジの不透明度)]に繋げていないが、これは結果を見たら交差エッジの線が消えていたので、それを出すためにあえて外してある。

なお、[Edge]ノードのパネル表記と日本語訳との対応は以下。Silhouette Edges 以下それぞれに Taper(先細り)、Color(色)、Opacity(不透明度)等の項目がついて並んでいる。

  • Lines Taper:点/線の太さ
    • ここへの入力は0-1の範囲に値を変更されて「点/線の太さ」に乗算される。つまりエッジに対する影響ではなく、影響するのは1頂点と2頂点ポリゴン。
  • Silhouette Edges:シルエットエッジ
  • Unshared Edges:共有しないエッジ
  • Sharp Creases:鋭角の折り目
  • Surface Borders:サーフェイス境界
  • Patch Borders:パッチ境界
  • Other Edges:その他エッジ
  • Intersection Edges:交差エッジ
    • Intersection Edges Angle:交差エッジ角度

その後、[Turbulent Noise]ノード自体をクリックして編集パネルを出し、VPRを見ながら細かな設定を詰めていく。[Blending]は「Multiply(乗算)」にして、[Opacity(不透明度)]は100%だと薄く、200%だと濃い気がしたので150%にした。[Blending]で設定するブレンドモード (Blending Mode) の詳細についてはリファレンスマニュアル参照のこと。下部の[Scale(スケール)]値もいじる。

[Turbulent Noise]ノードの編集パネル中央に並んでいるのはフラクタル関係のパラメータ。以下の説明は相当ざっくりなので、詳細はリファレンスマニュアル参照のこと。

  • Increment(増加、増分):連続する細部間の振幅、つまり強度。
  • Lacunarity(空隙性):連続する細部間における穴や隙間の変化量。高くするとフラクタルに隙間や穴が多くなる。
  • Octaves(オクターブ):Lacunarity が細部間の変化量を決めるのに対して、Octaves は細部の数を決める。「1」のときは基本パターンのみが使われ、増やすと[Lacunarity]値に合わせてサイズを変えたパターンが重ねられていく。
  • Noise Type(ノイズ種):パーリンノイズ、バリューノイズ、グラディエントノイズ等々といったノイズ形式を決める。
  • Bump Amplitude(バンプ振幅):よくわからない。

VPRのビューは全表示にした方が分かりやすいが、あくまでプレビューなので、最終的には「1枚試しにレンダリング→ノードの入力値を微調整」という作業をして最適な値を見つければよい。

ちなみに、[Turbulent Noise]以外でもノイズ系の3Dテクスチャであれば似たような効果を得られる。例えばよく似た[Turbulence(乱流)]ノード、そして[Crumple(しわ)]ノード、[MultiFractal]ノード、[Crackle(ひび)]ノードなど、色々と試してみると面白いだろう。

別のノードでも可能

なお、[Turbulent Noise]ノードではなく、[Scalar Layer]ノードを使ってもおそらく同様のことが設定できるようなのでメモしておく。

[Layers]>[Scalar Layer]を選択して、[Scalar Layer]ノードを出したら、右にある[Alpha]から矢印をドラッグし、[Edge]ノードに並んでいる[Silhouette Edges Taper]と[Silhouette Edges Opacity]、[Sharp Creases Taper]と[Sharp Creases Opacity]など、手を加えたい線の項の[~Taper]と[~Opacity]に矢印をそれぞれ接続していく。

[Scalar Layer]ノードをクリックして編集パネルを開く。[レイヤー種]を[プロシージャル]にする。[プロシージャル種]で[Turbulent Noise]を選択すると、前述した[Turbulent Noise]ノードと同じ設定項目が出るので、[増加]、[空隙性]、[オクターブ]、[ノイズ種]等を設定し、[スケール]もいじる。上と同じならやはり[ブレンドモード]は「乗算」にして、[レイヤー不透明度]は150%。[Texture Value(テクスチャ値)]は、テクスチャパターンの最もはっきりした部分における値。正の数も負の数も指定可能。


サーフェイスを設定する

輪郭線の[ノード編集]パネルを閉じ、サーフェイスのノード編集に移る。[色・質感編集]>[Surface Editor](ショートカット【F5】)を開いて任意のサーフェイスを選択し、[基本]タブの一番上[ノード編集]ボタン右隣のチェックボックスをオンにし、[ノード編集]ボタンをクリックして[Node Editor]を開く。なお、今回は簡略化のため、コンバットシェルのサーフェイスはすべて1つにまとめている。

ここでサーフェイスを白くする。ひとつの方法としては、サーフェイスの[自己発光度]を100%にすること。[Surface Editor]にて[自己発光度]を100%に変更してもよいが、すでに設定してあるサーフェイス設定をこのために変えたくなければ、[Surface]ノードを使うのがよい。ノード欄で[Constant]>[Scalar]を選択し、[Scalar]ノードを出す。ダブルクリックし、値が「1.0」になっていることを確認して閉じたら、[Scalar]ノード右端の緑の丸をクリックし、[Surface]ノードの[Luminosity]へとドラッグして繋ぐ。これでサーフェイスの[自己発光度]が 100% になり、真っ白になる。

もうひとつの方法として、[レンダー]タブ>[オプション]>[レンダーオプション](ショートカット【Ctrl+p】)>[大域照明]タブ>[ラジオシティ有効]にチェックを入れる手法もある。ラジオシティとは、サーフェイスに当たった光を乱反射させて、それを現実世界と同じく間接光の光源にするという効果。レンダリング時間は長くなるのだが、今回は自己発光度をいじるよりもラジオシティを使った方が好みの画が出力できたため、後者にした。

さて、陰となる部分に薄墨っぽい表現を加えたいので、ノード編集でアンビエントオクルージョン機能を使う。アンビエントオクルージョンとは、シーン内の「どの部分が環境光 (ambient) をどの程度さえぎられる (occlusion) か」を計算して陰影を作るレンダリング方法。裂け目・折り目のような凹部では環境光がさえぎられるため、陰影が強めに出る。

今回はフリーで配布されているアンビエントオクルージョンノードのプラグイン「SG_AmbOccNode」を利用した。標準搭載の[Occlusion II]ノード([Shaders]>[Diffuse]>[Occlusion II])でも似たような結果を得られるのだが、出力画を比較した結果、こちらの方が好ましかった。調べると標準搭載のオクルージョンノードよりも陰部分のノイズが目立たないらしいが、今回はあまり関係ない。ただしこのノード、いい加減な繋ぎ方をするとクラッシュするので注意。

なお、アンビエントオクルージョン機能の外部プラグインとしては他にも「DP Kit」の「Amb Occlusion」ノードと「Dynamic AO」ノード、そしてノードではないが「KP_LSCollecton」の「Occlusion」シェーダがある。また、標準搭載のシェーダにある「gMIL」というのも使えるかもしれないが、よく知らない。

ダウンロードしたらいつものように[プラグイン追加]で導入すると、[ノード編集]パネルの[Shaders]>[Diffuse]に[SG_AmbOccNode]が追加され、ノードとして利用できるようになる。もし追加されない場合は再起動してみること。[SG_AmbOccNode]ノードを出したら、その[1-Occlusion]出力を[Surface]ノードの[Color]もしくは[Diffuse Shading]に繋ぐ。ノードをクリックして編集パネルを開く。

  • Rays:光線の数。この値は高くすると陰のフチがボケて滑らかになるので、墨のようにざらついた粒子感を出すためには低くすればよい。なお、0にしてみたらクラッシュした。今回は5にしてみた。
  • Angle:光線の最大散乱角。この値が高いと陰の面積が広がるので全体がグレーになる。ここでは下げ、5°にした。
  • Range:光線の最大範囲。光線がこの値よりも離れた距離のサーフェイスに当たった場合は、当たってないように扱われる。この値を下げると陰が小さく薄くなるので、今回は0.5-1.0m程度がよい感じだった。

VPRとレンダリングもして比較したら、[Surface]ノードの入力は[Diffuse Shading]ではなく[Color]の方が好みの画だったので、そちらに決めた。

レンダリング

いつものようにショートカット【F9】でレンダリングして、画像に出力。

ふと、オブジェクトをまとめて360°回転させる動画にしてみようと思い立ったのでやってみた。自分はふだん静止画のみで動画作成しないので、手順をメモしておく。

左下[アイテム]でオブジェクトを選択し、アイテム名の右横にあるボタンを押してアイテムピッカーウィンドウを出したら、【Shift】を押しながらオブジェクトを複数まとめて選択する。もしくは[アイテム]タブ>[選択]>[全て]>[すべてのオブジェクトを選択]で選択。

右下のフレーム数に任意の値を入力する。デフォルトだと30フレーム/秒だが、今回は160フレームにした。そしてオブジェクトを回転させてキーフレームを打つ。下部の[自動キー:全モーション]にチェックが入っていればオブジェクトを動かした時点で勝手にキーが打たれるので、最終フレーム目で選択オブジェクトを360度回転させればよい。

右下(トランスポート・コントロール)の再生ボタンで動きを確認。このときビューはVPRではない方がよい。

問題なければ[レンダー]タブ>[オプション]>[レンダーオプション](ショートカット【Ctrl+p】)>[出力]タブで保存形式を選択する。[アニメ保存]にして直接動画を作成してもよいが、今回は静止画像も取得したかったので、[RGB保存]を選択し、連番のRGB画像として新規フォルダに出力。今回は160フレームにしたら自分の環境では総レンダリング時間が4時間程度だった。

CLIP STUDIO PAINT でアニメーション動画を作成

連番で出した複数の静止画からアニメーション動画を作成できるならソフトは何でもよいが、今回は CLIP STUDIO PAINT を使用した。ざっくり手順をメモしておく。

[ファイル]>[新規]で作品の用途「アニメーション」を選択。基準サイズを設定(今回は1920×1080、解像度72)して[OK]。[フレームレート](=1秒あたりのフレーム数)の設定や、[再生時間]ではフレーム数も設定できるので、ここで決めておくと楽。

レイヤーパネルに[アニメーションフォルダー]ができてその中に1枚新規レイヤーが作成されているが、このレイヤーは不要なので削除する。

[アニメーションフォルダー]を選択して[ファイル]>[読み込み]>[画像]から、読み込みたい画像を全部選択して[開く]で[アニメーションフォルダー]内に読み込める。

[アニメーション]>[タイムライン]>[設定変更]で、[終了フレーム]の値を任意に変更できる。注意点として、例えば全部で240フレームあるならここの値は241にする。また、[アニメーション]>[タイムライン]>[フレームレートを変更]で、フレームレートを変更できる。

[アニメーションフォルダー]を選択して、[アニメーション]>[セル指定]>[セルを一括指定]から[既存のアニメーションセル名から指定]を選択して[OK]で、一括してタイムラインに登録される。[フレーム数]で、各画像を何フレーム続けて並べていくかを指定できる。

タイムラインを右にスクロールして見れば分かるが、[用紙]はファイル新規作成時に設定したフレーム分までしか出ないので、もし総フレーム数を変更した場合はレイヤーパレットで[用紙]レイヤーを削除し、[新規レイヤー]から再び作成すると全フレーム分に出る。

タイムラインの[再生]ボタンでアニメーションを確認し、問題がなければ[ファイル]>[アニメーション書き出し]>[ムービー]から、ファイル名とファイル形式(AVIかMP4)を決めて保存。


光に影響された線の強弱

ここからさらに、光源の方向や位置に影響されて線に強弱がつくようにしてみる。要するに、光の当たる方向に向いた線を細くする。

輪郭線のノード編集

[輪郭(Edges)]タブから[Node Editor]を開き、先ほど[Turbulent Noise]ノードから[Edge]ノードへと繋げた矢印を全て外す。

左に並んだ中から[Layers]>[Scalar Layer]ノードを出す。

さらに、[Math]>[Scalar]>[Multiply]ノードを出す。

[Multiply]ノードを使えば、ひとつのスカラー値を他の値で乗算できる。要するにノードの出力結果を掛け合わせられるので、今回は線を筆描きっぽく加工できる[Turbulent Noise]ノードと、光の影響による強弱(というよりも正しくは勾配、グラディエント)をつけられる[Scalar Layer]ノードの出力結果を掛け合わせることを目指す。

[Turbulent Noise]ノードの右にある[Alpha]から矢印をドラッグし、[Multiply]ノードの[A]入力に繋ぐ。そうしたら[Scalar Layer]ノードの右にある[Alpha]から矢印をドラッグし、[Multiply]ノードの[B]入力に繋ぐ。

[Multiply]ノードの[Result]から矢印をドラッグし、[Edge]ノードに並んでいる[Silhouette Edges Taper]と[Silhouette Edges Opacity]、[Sharp Creases Taper]と[Sharp Creases Opacity]など、手を加えたい線の項の[~Taper]と[~Opacity]に矢印をそれぞれ接続していく。

[Scalar Layer]ノードをクリックして編集パネルを開く。[レイヤー種(Layer Type)]を[グラディエント(Gradient)]にする。[入力パラメータ(Input Parameter)]を[Light Incidence](ライトの入射)にして、[ライト(Light)]で適用するライトを選択。グラディエントバー(左にある縦長の帯)をクリックしてグラディエントのキーを1つ作成する。キーの[値(Value)]は「0.4」、[パラメータ(Parameter)]は「90.0」にして、白から黒(というかグレー)へのグラデーションを設定する。

[輪郭(Edges)]タブで各輪郭線の幅を調整し、いつものようにショートカット【F9】でレンダリングして画像に出力。[ラジオシティ有効]のチェックは外してある。

それなりの画にはなっているが、線の強弱もはっきりせず、いまいち足りないのでいろいろと調整してみた。

上でも記したように、[Turbulent Noise]ノードではなく[Scalar Layer]ノードでも同じようなノイズ設定ができるので、そちらに変えてみることにする。

[Layers]>[Scalar Layer]を選択して、[Scalar Layer]ノードを出したら、クリックして編集パネルを開く。[レイヤー種]を[プロシージャル]にする。[プロシージャル種]で[Turbulent Noise]を選択すると、前述した[Turbulent Noise]ノードと同じ設定項目が出るので、[増加]、[空隙性]、[オクターブ]等を設定し、[スケール]もいじる。上と同じならやはり[ブレンドモード]は「乗算」にして、[レイヤー不透明度]は150%。

設定したら右にある[Alpha]から矢印をドラッグし、[Multiply]ノードの[A]入力に繋ぐ。すでに[Turbulent Noise]ノードからの矢印が繋がっているだろうが、いちいち外さなくともそのまま新しい矢印を被せれば繋ぎ替わる。

F9】でレンダリングして画像に出力。

かなりよい雰囲気になったが、白飛びしている箇所が気になった。[レンダー]タブ>[オプション]>[レンダーオプション]>[ライト]タブ>[ライトの明るさ]を「10%」にしてレンダリングしてみる。

ふたたび動画化してみた。

以上、面倒なので画像テクスチャを使わずにそれっぽい画を出そうとしてみた結果をまとめたが、画像テクスチャを使えばもっと水墨画っぽい画を出力できるはず。今後の課題としておく。

(2018-09-22追記)以下に続きを書いた。

蛇足

VPR のざらついた画像がとてもよいのでこれをそのまま出力できないものかと思っていたのだが、裏技的な方法を紹介している記事を見つけた。

ライセンス

本記事に使用したオブジェクトの元データは、作成者の rogerharkavy 氏によりクリエイティブコモンズ・ライセンスの「Attribution-NonCommercial-ShareAlike(表示-非営利-継承)」で配布されているため、その派生物である本記事内の出力画像にも同じライセンスを適用する。

クリエイティブ・コモンズ・ライセンス
rogerharkavy, Ditty を著作者とするこの 記事内の画像クリエイティブ・コモンズの 表示 - 非営利 - 継承 4.0 国際 ライセンスで提供されています。
http://www.thingiverse.com/thing:21308にある作品に基づいています。

*1:線以外でも、均一にしたくないものに対して使えるノードなので、例えばノードを使ったインスタンスの際に複製のスケールをばらけさせる等にも使える……はず。