第3回 マルチパスレンダリングとスクリプトを使ったイメージ編集
第3回 マルチパスレンダリングとスクリプトを使ったイメージ編集
みなさまこんにちは。「開発部より」第3回です。
ユーザの皆様のお話を伺っていると、古くから使っている方に意外と知られていない機能の一つに、「マルチパスレンダリング(Standard以上のグレードに搭載)」があります。この機能は、レンダリング後に画像処理ソフトを使用して編集する場合に特に効果的な機能です。今回は、その簡単な紹介と、せっかく「開発部より」なので、応用技としてマルチパスを使ったシェーディング計算をやってみようと思います。これについては、Pythonスクリプトでの説明になってしまいますので、難易度が上がってしまいますが、簡単な数学(ベクトル内積など高校数学程度)の範囲にとどめます。
マルチパスレンダリング(Standard以上のグレードに搭載)
マルチパスレンダリングは、Shade10.5で搭載された機能で、レンダリングで行われる各種計算をそれぞれの要素に分離して、画像編集ソフトでの後処理を便利にするものです。
使用するには、レンダリング設定にて、「マルチパス」タブの「マルチパスを保持する」チェックボックスをオンにし、その下のリストボックスから、必要なパスのチェックボックスをオンにします。レンダリング後に、「保存」ボタンから、「マルチレイヤー...」で保存すると、マルチパスを全て保存することが出来ます。psd形式で保存すれば、フォトショップなどのソフトでそのままレイヤとして開くことができます。
弊社制作スタッフがよく使用しているものとしては、
- Z値 (フィルタを使用して、被写界深度を再現できる)
- 影 (画像処理ソフト上で影を微調整できる)
- 形状ID・表面材質ID (選択範囲として使用できる)
などだそうです。その他のパスも、状況によっていろいろな使い方が可能です。
元のレンダリング画像です。
「Z値」(左)パスと「表面材質ID」(右)
「影」(左)と「光源:大域照明」(右)
スクリプトを併用した応用例
マルチパスの中には、あまり用途が想像できないものもあります。特に、種別が「データ」になっているパスは比較的プログラミング寄りの要素が出力でき、レンダリング結果の検証・確認用や、プラグイン・スクリプトによるエフェクトなどでの使用を目的としています。
ここからは、だんだんと応用編になります。
実際に、Pythonスクリプトを利用して、レンダリング結果に後がけのエフェクトで無限遠光源を追加する例を、スクリプトの内容の紹介を交えてながらやってみましょう。今回主に使用するのは、「法線」と「表面材質:拡散反射」パスです。
左から、それぞれ、「RGB」、「法線」、「表面材質:拡散反射」パス
「法線」パス
法線パスは「形状の面がどちらの方向を向いているかを表すベクトル(法線)」のX, Y, Zを、色のR, G, Bに置き換えたイメージです。そのまま見ただけではなんとなくカラフルなだけですが、レンダリングの計算では非常に大きな意味を持ちます。※1
※1 レンダリング時に形状の法線を元にして陰影付けを行います。バンプマップによるでこぼこの表現は、この法線を変化させる事で表現します。
ちなみに法線ベクトルのX, Y, Zの三次元座標で、数値にはマイナスが含まれます。これをそのままR, G, Bに置き換えるだけでは、画面表示での確認や画像編集ソフトへの受け渡しに不便です。このため、イメージウインドウでの表示や画像ファイルに保存のときは、0.5を中心とした0.0~1.0のRGB値の範囲に変換して色の変化を見ることができるようにしています。スクリプトで使用する場合はベクトル計算がしやすいよう、色の変換は行わずに、法線ベクトルのX, Y, Zの値をそのままR, G, B値から取得できるようになっています。
今回のサンプルの無限遠光源では、この法線パスを使って光源が物体を照らす明るさを計算します。無限遠光源によって照らされる明るさは、光源の照射方向のベクトルと面の法線のベクトルの内積に無限遠光源の色を乗算したものです。
「表面材質:拡散反射」パス
今回のスクリプトで使うもう一つのパスです。光源の効果を無視した形状の表面材質の拡散反射色を描画します。光源の明るさの計算結果にこのパスの色を乗算すれば、光源の効果に形状の色を反映させることができます。
実際のスクリプト
レンダリング設定のマルチパスタブで、「法線」パスと「表面材質:拡散反射」パスをオンにしてレンダリングしてから、下記のスクリプトをShadeのスクリプトウインドウにコピー&ペーストして実行してみてください。実行した後は、処理が終わるまで時間がかかる場合がありますので、メッセージウインドウに「終了」と表示されるまで、そのまま待って下さい。
本当に簡素なサンプルスクリプトということで、ユーザーインターフェイスとかエラー処理とかそういったものはありません。レンダリングされていなかったり、マルチパスの設定がされていなかったりするとスクリプトがエラーで止まります。
### ここから ###
l_dir = (0.577, 0.577, 0.577) # 無限遠光源の方向(X, Y, Z)
l_col = (0.8, 0.8, 0.8) # 無限遠光源の色(R, G, B)
r_image = xshade.scene().rendering.image # レンダリングイメージ
n_image = xshade.scene().rendering.image_layer("Normal").image # 法線パス
s_image = xshade.scene().rendering.image_layer("SurfaceDiffuse").image # 表面材質: 拡散反射パス
col = [0,0,0] # 色の計算結果の保持用の変数(R, G, B)
for y in range(r_image.size[1]):
for x in range(r_image.size[0]):
n_xyz = n_image.get_pixel(x, y) # 法線パスから面の法線を取得(X, Y, Z)
# 面の法線と光源の照射方向の内積で、拡散反射の影響率が求まる
i = n_xyz[0] * l_dir[0] + n_xyz[1] * l_dir[1] + n_xyz[2] * l_dir[2]
if i < 0.0: continue # マイナスのときは裏側なのでスキップ
r_col = r_image.get_pixel(x, y) # レンダリングイメージの色を取得
s_col = s_image.get_pixel(x, y) # 表面材質の拡散反射色を取得
# (光源の色 * 表面材質の拡散反射色 * 拡散反射の影響率)で
# 光源と形状の色を反映した照明の結果が求まる。
# 照明の計算結果と元の色を加算すると、光源を追加した色になる
col[0] = r_col[0] + l_col[0] * s_col[0] * i # R
col[1] = r_col[1] + l_col[1] * s_col[1] * i # G
col[2] = r_col[2] + l_col[2] * s_col[2] * i # B
r_image.set_pixel(x, y, col) # 計算結果をレンダリングイメージに戻す
xshade.scene().rendering.update_image() # イメージウインドウを更新
print '終了'
### ここまで ###
- 変数「l_dir」、変数「l_col」が光源のパラメータです。この数値を書き換えると物体の照らされ方が変わります。
- 変数「l_dir」は光源の方向です。無限遠光源ウインドウの方向半球をCTRL(win) or option(mac) + クリックして出てくる数値と同じです。
- 変数「l_col」は光源の色(× 明るさ)です。整数値のRGBの白(255, 255, 255)は(1.0, 1.0, 1.0)になります。
実行例はこんな感じ
実行前(左)と、実行後(右)
ちょうど、変数「l_dir」で設定した方向(この例の場合は向かって右上)に無限遠光源を設定したような感じの結果になります。影については単純なエフェクトだけで追加することは難しいので、ここでは影を考慮していません。
さらにいろいろ
- レンダリングイメージに直接上書きするのではなく、create_image_layerで作業用のレイヤーを追加して、そちらに描画すると試行 錯誤がしやすくなります。いくつもレイヤーを作成すれば、レンダリングをし直さずに複数の光源設定を試したり、光源のアニメーションをすることもできま す。
t_image = xshade.scene().rendering.create_image_layer("A342E214-DE44-422E-B75E-E4B4E2C2563A", "TESTIMAGE") # (識別UUID, レイヤー名)
※ ここでUUIDが必要になります。このUUIDとは、世界でたった1つとされる、ユニークな識別番号になります。Shadeでも、以下のスクリプトで何回でも生成することが出来ます。
import uuid
print uuid.uuid1()
- 他のパスを組み合わせると、Shade標準では出来ないシェーディング手法や、非現実的なシェーディング手法など、さらにいろいろな使い方をすることができます。
- 「座標値」パスは三次元座標値が入っていて、光源との距離や方向を計算すれば点光源、スポットライトを再現することができます。単純に距離で減衰しないカスタマイズされたオリジナルな光源を作ることも。
- 「形状マスク」、「表面材質マスク」パスを使えば、特定の形状に対してのみ光源の効果を与えることもできます。
このあたりはレンダラのプログラミングの入門編に当たる部分でもあり、光源の他にもパスの組み合わせでいろいろな効果を作ることができます。是非いろいろ試してみてください。
スクリプトに関する解説は、メニューの「ヘルプ」>「Shade Python Script Referenveマニュアル」か、スクリプトウインドウの「リファレンス」ボタンから、マニュアルを見ることが出来ます。
フィードバックをお寄せください
以下のフォームから、この記事やShade製品に関してお気づきの点やご意見、ご要望をお送りいただくことが可能です。みなさまの声をお待ちしております。