3ds Max のスキャンライン レンダラーにより、カラー、テクスチャの座標、法線、透明度、速度、適用範囲などについての情報を提供する多数の追加データ チャネルが生成されます。これらのチャネルはすべて、MAXScript 経由で読み取ることができます。
下に示してある単純なスクリプトで、Z-バッファの深度情報を含むイメージがレンダリングされます。そしてこのイメージが、単独のイメージ ピクセルを表すジオメトリを生成するための深度データを使用して、いわゆる「ボクセルの横置き」に変換されます。 このスクリプトでは、シーン内にジオメトリが存在している必要があります。
関連トピック:
グレースケール マスクとしての Z-バッファ チャネルへのアクセス
全体の流れ:
現在のレンダラーをスキャンラインに設定します。
最後のセッションからすべてのオブジェクトを削除します。
Z-バッファ情報を使用して現在のビューをビットマップにレンダリングします。
レンダリングされたイメージ内のすべてのラインおよび各ライン内のすべてのピクセルを巡回します。
ピクセルごとに、カラーと Z-深度値を取得し、そのピクセルを表すボックスを作成します。 その際、オブジェクトのワイヤフレーム カラーに対応するカラー、ボックスの高さに対応する Z - 深度を使用します。
必要なときに簡単に削除できるように、各オブジェクトに固有の名前を付けます。
進行状況バーを表示して、すべてのピクセルを処理するのにかかる時間がわかるようにします。
MAXScript
renderers.current = Default_Scanline_Renderer()
delete $VoxelBox*
rbmp = render outputsize:[32,32] channels:#(#zdepth) vfb:off
z_d = getchannelasmask rbmp #zdepth
progressstart "Rendering Voxels..."
for y = 1 to rbmp.height do
(
if not progressupdate (100.0 * y / rbmp.height) then exit
pixel_line = getpixels rbmp [0,y-1] rbmp.width
z_line = getpixels z_d [0,y-1] rbmp.width
for x = 1 to rbmp.width do
(
b = box width:10 length:10 height:(z_line[x].value/2)
b.pos = [x*10,-y*10,0]
b.wirecolor = pixel_line[x]
b.name = uniquename "VoxelBox"
)--end x loop
)--end y loop
progressend()
renderers.current = Default_Scanline_Renderer()
まず、スキャンライン レンダラーが現在のレンダラーであることを確認します。3ds Max (Arnold)の既定のレンダラーは、同じ方法で zDepth を出力しません。
delete $VoxelBox*
過去のセッションのすべてのボクセル オブジェクトが削除されていることを確認します。名前が「VoxelBox」で始まるすべてのオブジェクトを、名前の残りの文字にかかわらず削除します。
rbmp = render outputsize:[32,32] channels:#(#zdepth) vfb:off
ここで、32x32 の解像度でアクティブなビューポートをレンダリングし、その結果を変数 rbmp
に格納します。追加の Z-深度チャネルの生成を要求します。仮想フレーム バッファは、レンダリング中に無効になります。
z_d = getchannelasmask rbmp #zdepth
イメージをレンダリングした後に、グレースケール マスクとして ZDepth チャネルのコピーを要求します。コピーは、ビットマップの z_d
に格納されます。
progressstart "Rendering Voxels..."
指定したキャプション付きの新しい進行状況インジケータを起動します。 これは、UI の一番下のステータス バーに表示されます。
for y = 1 to rbmp.height do
(
次に、レンダリングされたビットマップ内ですべてのラインを巡回するループを開始します。変数 y は、1 からビットマップの高さまで変化します。
progressupdate (100.0 * y / rbmp.height)
progressupdate
メソッドには、パーセント値が必要です。現在のビットマップ ライン番号の y
を合計ライン数の rbmp.height
で割ります。この結果の範囲は、0.0 から 1.0 までの間です。
それに 100.0 を乗算すると、0.0 から 100.0 までの間のパーセント値が返されます。
pixel_line = getPixels rbmp [0,y-1] rbmp.width
z_line = getpixels z_d [0,y-1] rbmp.width
次に、RGBA ビットマップと Z-バッファの両方から、ピクセルから成るライン全体を読み取ります。ビットマップのインデックスは 0 を基点とし、高さから 1 を引いた数までであることに注意してください。つまり、垂直の位置の値が「1 引かれて」います。
for x = 1 to rbmp.width do (
1 からビットマップの幅を数えることで、現在のスキャンラインの各ピクセルにアクセスします。
b = box width:10 length:10 height:(z_line[x].value/2) pos:[x*10,-y*10,0]
次に、幅と長さが 10、高さが Z-バッファのグレースケール値の半分のボックスを作成します。さらに、ピクセルの座標に基づいて、10 番目のワールド単位ごとに X と Y の位置を設定します。ボックスの左上隅が左上に表示されるように、y には負の値を使用する必要があります。ビットマップは左上から始まりますが、MAX ワールド スペースの正の四分円は左下から始まります。そのため、ビューポート内で有効なビットマップ表示を行うために垂直座標を逆にします。
b.wirecolor = pixel_line[x]
レンダリングされたピクセルの RGB カラーを使用して、新しいワイヤフレーム カラーを新しいボックスに割り当てます。
Viewport_related_node_properties
b.name = uniquename "VoxelBox"
また、ボックスの名前に「VoxelBox」で始まる固有の名前を設定します。
)--end x loop
)--end y loop
progressend()
ループが終了した後に進行状況の表示を終了することができます。
スクリプトを実行するには、単に [Ctrl]+[E]を押すか、MAXScript エディタのメニューで[ツール] (Tools) > [すべてを評価](Evaluate All)を選択します。または、ファイル/すべてを評価を実行します。レンダリングする目的のビューが現在のビューポートに表示されていることを確認します。進行状況バーによって、スクリプトが機能しているのがわかります。 このスクリプトを実行した結果、ワールド原点の左上に、レンダリングされたカラーと深度を表しているボックスのグループが表示されます。
このスクリプトを手始めとして、Sphere や Cylinder などの別のタイプのオブジェクトを作成することができます。 さらに上級のバージョンでは、リアルなハイトマップ評価のために、カメラの Z-深度に基づいたメッシュ グリッド内で頂点の Z 位置を変更することができます。
戻る