シーングラフとブループリント

像を囲んで円形に立ち、それぞれ剣を像に向ける16人の騎士は、手で配置した16回の読み込みではありません。グラフです:読み込み、そのリング、注視、そして2体として同じにならないための少しのばらつき。16人を24人にするのは数字1つの変更です。

新規プロジェクトのシーングラフ:出力に接続された読み込みノード。左にノードライブラリ

シーンステップのシーングラフパネルにそのグラフがあります。スタイルステップのスタイルグラフと同じキャンバス(ボックス、ワイヤー、本体の設定)ですが、独自の種類のワイヤーを持つため、ルックのノードをそこに落とすことはできず、その逆もできません。メモは、スタイルグラフと同様にメモを置きます:ノードの背後にあるボックスにあなたの言葉を書き、中のノードを一緒に動かします。

これを一度も開かず、シーンに何も追加しないプロジェクトは、グラフをまったく保存せず、読み込んだものをレンダリングします。

シーンに追加するものはすべて、このグラフのノードです:別のモデル(アイテム)、ボーン上の小道具、スプリング、シェイプ、画像、文字、ボリューム、ランプ、エフェクト、そしてワールドの地形、草、水、空(D49)。アウトライナーの+は、チェーンの最後にノードを追加します。アウトライナーはグラフのものを一覧表示し、行とそのノードは同じものです:どちらを選んでももう一方が選ばれ、インスペクターはそのすべてのコントロールを表示し、どちらを削除しても両方が削除されます。グラフ自身の追加メニューから追加したノードは、すぐにアウトライナーの行になります。グループ内のもの(キットのランタン)はグループの行の下に表示され、選ぶとグループがその場で開き、中のノードが選ばれます。

これらのノードのすべての設定はプロパティです(ノードを参照):左にポートがある行で、ノード上で設定するか、値から接続します。1つの数値をリングと行の数に接続すると、両方が一緒に増えます。ワールドのノード(地形、水、空、雲、風…)にもプロパティがあります。1つの数値や語でないもの(パッチが独自の色を持つか、風がほかに何を動かすか、時間帯)は、ノード上のコントロールのままです。

ノード

ノード 働き
読み込み 読み込んだもの、その位置:小道具を含むモデルです。
オブジェクト 小道具を含むモデルとその位置。どのノードも指定しないものはレンダリングされません。
アイテム 読み込んだモデルの横に置く、ファイルから読み込む別のモデル:置く位置、回転とスケール、独自のクリップ。形状と同じように追加され、リストを次に渡しつつ自身のコピーを1つ追加します(--item)。
小道具 読み込んだモデルのボーンが持つモデル(剣、たいまつなど)。ボーン上での位置、回転、スケールと、ボーンがつかむそのモデルのノードを指定します(--add-prop)。モデルの一部なので、読み込んだモデルのすべてのコピーがこれを持ちます。そのため独自のコピーは追加せず、リストをそのまま次に渡します。
スプリング 動きに合わせて揺れるボーンとその下のすべて(髪、マント、しっぽ)。硬さ、減衰、重力を指定します(--spring)。小道具と同じく、モデルのすべてのオブジェクトでモデルの一部になります。
シェイプ Pixor独自のシェイプ(ボックス、円柱、文字)で、位置、サイズ、回転、色、ベベルをノード上で設定します。受け取ったリストをそのまま渡し、自分自身のオブジェクトを加えます。何も接続されていなければリストを開始するので、シェイプをリングにつなげば、そのシェイプのリングになります。
画像、テキスト 平面上の画像、またはカード上のピクセルフォントの文字(画像と文字)。シェイプと同じように追加します。
ボリューム 煙、炎、液体(ボリューム):出力に届くノードのオブジェクトごとに1つ、そのオブジェクトの位置に置かれます。
ランプ 位置を持つライト:出力に届くオブジェクトごとに1つなので、ランプの後にRowを置けばランプが並びます。どこにも接続されていないランプは何も照らしません。
エフェクト パーティクル(爆発、火花、雨、ホタル)。出力に届くオブジェクトごとに1つ。
リング オブジェクトを円周上に並べます:個数、中心からの距離、最初の1つの位置、中心を向くかどうか。
行 一定間隔で一列に並べたオブジェクト。
グリッド オブジェクトをグリッドに並べます。横にいくつ、奥にいくつ。
散布 オブジェクトをボックス内にシード付きで散らします。2つが互いにそれ以上近づかない距離を指定します。
注視点 すべてのオブジェクトを1点に向けます。さらに回転で、武器が前方軸上にないモデルの向きを合わせます。
ばらつき 各オブジェクトに、その番号とシードから独自のクリップの位相、回転、サイズを与えます。
再生 シートのほかの部分が何を再生していても、これらのオブジェクトが再生するクリップ:攻撃する騎士の隣で揺れる木など。すべてのアクションで、そのアクションのフレームにわたって再生します。止まった家の隣で回る風車は、アクションステップでの新しいアクションと、風車への再生ノードで作ります。アクションはここではなく、そちらで作ります。
見るカメラ 1台のカメラだけが見るオブジェクトとフレーム(下記)。
マージ 2つのオブジェクトのリストを1つに。
移動、ミラー すべてのオブジェクトを移動・回転・拡大縮小し、平面に対する各オブジェクトの鏡像を加えます。
細分化 すべてのオブジェクトのすべての三角形を4つに分割します(1回から最大4回)。これで「ずらす」が動かせる点ができます。
ずらす すべてのオブジェクトの表面を、シード付きノイズで、メートル単位の量まで、指定のサイズ間隔の凹凸で押し出したり引っ込めたりします。コピーごとに凹凸が変わるので、ボックスの列は、それぞれ違う岩の列になります。
ハイトフィールド すべてのオブジェクトの表面を、上から見たシード付きのハイトフィールドでまっすぐ持ち上げます。細分化の後に置けば、平らな面が起伏のある地面になります。地面は上がるだけです。
ベベル すべてのオブジェクトのボックスの辺を45度で面取りします。
地面に置く すべてのオブジェクトを、真下にある一番高い面の上へまっすぐ落とします。面とは、シーンのほかのもの(またはその1つ)や、チェーン内でそれより前にある地形のことです。上に持ち上げる量や、斜面に合わせてどこまで傾けるかも指定できます。
面の上 渡されたもののオブジェクトを、面積に応じてシード付きで、ものの表面に散らします。上面だけにも、全面にもできます。
点の上 渡されたもののオブジェクトを、対象のすべての頂点に置きます。
差分 1つ目の入力のオブジェクトから、2つ目の入力のオブジェクトをその位置でくり抜きます:壁の窓、木箱の切り欠き。2つ目の入力は穴の形だけで、レンダリングされません。
結合 2つのオブジェクトのリストを1つのパーツとして描くので、接する部分に線が引かれません:箱を積んだ塔が1つの建物に見えます。
シェイプを設定 すべてのオブジェクトのシェイプの設定1つ(サイズ(倍率)、幅、高さ、奥行き、セグメント、ベベル、色相)を、属性×数値+数値で設定します。
属性 すべてのオブジェクトに数値を書き込み、後のノードで使えるようにします(下記)。
選択 属性がテストを通るオブジェクトを残します。
出力 カメラの前に立つもの:グラフの唯一の結果。

ワールドのノード(地形、小枝、葉、水、雲、空、風、光の筋、時間帯、チャンク)も同じ追加メニューにあります。ワールドを参照してください。値ノード(数値、オン/オフ、角度、文字列、それらの間の計算)がプロパティに値を送ります。

レイアウトノードは、渡されたコピーごとに1回実行されます。行のリングは、リングのコピーごとに1行です。入れ子はこれだけで、2つ目のルールはありません。

ばらつきはコピーの番号とグラフのシードからだけ生まれます。ほかの何にも左右されないので、同じグラフからは、どのマシンでも、どちらのバックエンドでも、毎回同じ群衆ができます。

16人の騎士

リングを追加し、数を16、半径を3にして、中心を向くをオフにし、注視点を追加して方向を像に向けます。ばらつきを追加してクリップの位相を1にすると、全員が歩行の違う時点にいるようになります。キャンバス下部の数字はグラフが作るコピーの数を示し、横のスプライトにそれが表示されます。

その横の像はアイテムノードです。ファイルから読んだ別のモデルで、置いた場所に立ちます。ほかのすべての物のノードと同じく、渡されたものを渡し、自分のコピーを1つ加えるので、チェーンのどこに立つかで何がそれを繰り返すかが決まります。Ringの後のItemは16人の騎士の中の1体の像、前なら16体の像になります。アプリでは、アウトライナーの+ › アイテム › モデルファイルから…で、チェーンの末尾、リングの後に置かれます。

スクリプトから、ノード1つずつ:

pxr project scene game.pixor ring --count 16 --radius 3 --face-out
pxr project scene game.pixor look-at --at 0,0.8,0
pxr project scene game.pixor vary --phase 1 --seed 3
pxr project scene game.pixor --set ring.count=24
pxr project scene game.pixor            # prints the graph and the count

pxr graph addとpxr project sceneは、チェーンの末尾にノードを置きます。自分でコピーを作り、何も受け取らないノード(Object、Import)は、素の読み込みの代わりにチェーンの先頭になり、ほかに何かあればチェーンの横に置かれてマージされるので、レンダリングされていたものが失われることはありません。--aloneはどこにも接続しないノードを追加し、--inは別のノードをその入力の1つに接続します。

pxr graph add game.pixor --which scene --node object --set of=model           # the knight alone
pxr graph add game.pixor --which scene --node ring --set count=16 --set radius=3
pxr project set game.pixor --item statue.glb@0,0                            # an Item after the ring

どこにも接続されずに単独で立つItem(--alone)は独自のリストを始め、Merge、Scatter、Seen byがそれを受け取ります。オブジェクトが指定するのはモデルだけです。アイテム、シェイプ、画像はそれぞれ独自のノードで、Objectでそれらを指定するとエラーになります。

各カメラに見えるもの

カメラは、グラフが自分の前に置いたものをすべて写します。見るカメラは、ほかのカメラからは見えないコピーを1台のカメラに与えます。そのため、メインカメラとポートレートカメラを持つプロジェクトでは、一方のシートにリング全体を、もう一方に像を表示できます。単独で立つ像のItemを、Seen by portraitを通して、Mergeで残りと結合します。ポートレートカメラは、すべてのカメラが見るものと一緒に像を写し、メインカメラは像をまったく見ません。

pxr project new game.pixor --model knight.glb --force
pxr project scene game.pixor ring --count 16 --radius 3             # node 2
pxr project set game.pixor --add-camera portrait:three-quarter:64   # NAME:VIEW:SIZE[:ANGLE]
pxr graph add game.pixor --which scene --node item --set model=statue.glb --alone                   # node 3
pxr graph add game.pixor --which scene --node seen-by --set camera=portrait --alone --in objects=3   # node 4
pxr graph add game.pixor --which scene --node merge --in b=4        # the ring, and the statue for the portrait
pxr project scene game.pixor                                        # 17 objects

ここでは像のアイテムを--aloneで追加しているので、リングのチェーンの末尾には入りません(pxr graph listで番号が表示されます)。マージはチェーンの末尾に入るので、リングがその最初の入力に入ります。pxr renderは、リングだけのgame.pngと、像を囲むリングのgame_portrait.pngを書き出します。

1つのノードとして使うグラフ

像を囲む騎士の輪、並んだ露店、ばらつきのある群衆。シーングラフは1つのグループとして保存し、別のプロジェクトで使えます。グループを選ばずにバーのキットを保存…を押すとグラフ全体をキットとして書き出し(シーングラフをキットとして保存。そのOutputノードがグループの出力になります)、グループを選んでいればそのグループを書き出します(グループをキットとして保存)。キャンバスの追加メニューのキットを使う…(キットをグループとして追加)で、グループとして入れます。それは自分の名前を持つ1つの箱で、その矢印(またはダブルクリック)でその場で開いて、中身を見たり変えたりできます。矢印でまた折りたたみます。中のインノードは入力を表すので、保存したリングに、輪に並べるコピーを渡せます。

pxr graph save market.pixor --which scene -o stalls.pixorkit --name "Row of stalls"
pxr graph add town.pixor --which scene --kit stalls.pixorkit
pxr graph flatten town.pixor --which scene          # the nodes it stands for

グループはコードではなくデータです。中のノードができることしかできず、それらとまったく同じようにレンダリングされます。

1回のレンダリングから複数のシート

何を書き出すかは、このグラフの役目ではありません。チェーンの最後にある出力ノードがカメラの前に立つもので、それは1つだけです。2つ目のファイル(アイコンセット、宣伝用の静止画、線だけのシート)はアセットグラフの出力で、このグラフのコピーがレンダリングされたフレームを受け取ります。

複数のモデルからなる、アニメーションするシーン

アイテムもクリップと、それをずらす位相を受け取ります:

pxr project new patrol.pixor \
  --item knight.glb@-0.9,0.2,-20:walk \
  --item knight.glb@0.9,0.2,-20:walk,0.45 \
  --item chest.glb@-1.8,-1.6,25,1.2

クリップを持つアイテムはリグを持ち込んで再生します。持たないものは立っている場所でベイクされ、そのほうが軽く済みます。クリップは、Pixorのほかの場所と同じく、モデル自身のファイルか、そのname@clipの兄弟ファイルから来ます。

配置、変形、選択

シーングラフのノードは、並べる以上のことができます。移動はすべてのコピーを移動、回転、拡大縮小し、ミラーは各コピーを平面で反転したものを加えます。

属性は、すべてのコピーに数値を書き込みます(リスト内の番号、位置、回転、中心からの距離、シード付きノイズ)。選択は、属性がテストに合格したコピーを残し、残りを捨てます。この2つを組み合わせると、どれが奥にあるかを名指しせずに奥にあるものだけを半分のサイズでと表現できます(zはカメラ方向なので、奥は値の小さい側です):

pxr project new town.pixor --model chest.glb --force
pxr project scene town.pixor row --count 6 --step 1,0,0.5
pxr project scene town.pixor attribute --name depth --from z
pxr project scene town.pixor select --name depth --how below --at 1
pxr project scene town.pixor move --size 0.5

細分化とずらすは、コピー自身の表面の形を変えます。箱は岩になり、滑らかな崖はごつごつした崖になります。手で編集する三角形ではなく、コピーが持ち、パーツの作成に使われる設定なので、同じグラフからはどこでも同じ岩ができます:

pxr project new yard.pixor --add-shape rock=box:0.5 --size 64
pxr project scene yard.pixor row --count 3 --step 1.4,0,0
pxr project scene yard.pixor subdivide --times 3
pxr project scene yard.pixor displace --amount 0.12 --bumps 0.35 --seed 4

地面に置く、面の上、点の上は、グラフが物を配置するシーンを読みます。ボックス内の散布は、後に「地面に置く」をつなぎ、地形がそのリストに入っていれば、丘の上の散布になります:

pxr project new hill.pixor --model chest.glb --terrain 12:24:2                       # the terrain is node 2
pxr graph add hill.pixor --which scene --node object --set of=model --alone          # node 3
pxr graph add hill.pixor --which scene --node scatter --alone --in objects=3 --set count=14
pxr graph add hill.pixor --which scene --node merge --in b=4
pxr graph add hill.pixor --which scene --node drop-to-ground

そしてろうそくのシェイプノードと王冠の点の上で、王冠のすべての角にろうそくが立ちます。キャンバスは何かを作る前に面の上のコピーを数えます。点の上の数は、シーンができた時点でわかります。

差分は、2つ目に渡されたものでその位置をくり抜きます:長い壁に、3つ並んだ行の小さなボックスを通すと、窓が3つある壁になります。穴の内側は、そのパーツの大部分の色で縁取られます。リグに結び付いたパーツ(スキンモデル、ボーン上のシェイプ、キーを打ったシェイプ)は、くり抜くとリグに渡された頂点が変わるのでくり抜かれません。三角形が5,000個を超えるパーツも同様です。

pxr project new house.pixor --add-shape wall=box:4,2,0.2 --size 96      # the wall, node 2
pxr graph add house.pixor --which scene --node shape --set name=window --set size=0.4,0.5,0.4 --set at=-1.2,0.1,0 --alone   # node 3
pxr graph add house.pixor --which scene --node row --alone --in objects=3 --set count=3 --set step=1.2,0,0                 # node 4
pxr graph add house.pixor --which scene --node difference --in "cut by=4"
pxr render house.pixor -o out/house.png

シェイプはatを中心に立つので、最初の窓は壁の中央から1.2 m左にあり、Rowが残りの2つをそこから1.2 mずつ離して置きます。3つとも4 mの壁の内側に収まります。

Pixorが作るシェイプには独自の設定があり、シェイプを設定でグラフからそれを操作します:1つ前より背が高く、色相環で少しずつ回っていく木箱の列は、木箱のシェイプノード、行、各コピーが行のどこにあるかの属性、そして2つのシェイプを設定でできています。

pxr project new crates.pixor --add-shape 'crate=box:0.5:0,0,0:#c86432' --size 64   # an orange crate alone
pxr project scene crates.pixor row --count 5 --step 1.1,0,0
pxr project scene crates.pixor attribute --name x --from x
pxr project scene crates.pixor set-shape --setting height --from x --times 0.15 --plus 0.5
pxr project scene crates.pixor set-shape --setting hue --from x --times 40
pxr project scene crates.pixor bevel --width 0.06
pxr render crates.pixor -o out/crates.png

木箱は0~4.4mの位置にあるので、0.5mから約1.2mまで大きくなり、オレンジから黄、緑を経て青緑へと色が変わります。色相は色を回すので、色の付いた形には表れますが、灰色のものは灰色のままです。

シェイプの設定は、ノードの順序にかかわらず、細分化やずらすより前に適用されます。設定から作り直したシェイプは、自身の表面から始まるからです。設定を受けるのは単独で立つシェイプだけで、ボーンに吊るしたシェイプはモデルの一部です。

スキンに結び付いたパーツやモーフターゲットを持つパーツは、ずらされますが細分化はされません。辺の中央の新しい点には正しいウェイトがないからです。風に揺れるパーツも同様です。

コピーが隣と違うのは、番号、属性、シードによるか、まったく違わないかのどちらかです。名前で違うことはありません。1つに名前を付けると、グラフがシーンファイルになってしまうからです。

ブループリント

プロジェクトはこのモデルを指します。ブループリントは同じものから、パスを取り出して名前と型を与えたもの(ルック、上のグラフ、クリップ、書き出し)です。そのため1つのレシピを、20回コピーしてそのたびに編集する代わりに、フォルダー内のモデルに一括で実行できます。

プロジェクト › ブループリントとして保存…で.pixorblueprintを書き出します。開くと(プロジェクト › プロジェクトを開く…)入力を尋ね、その後は普通のプロジェクトと同じように振る舞います。出てくるものは無題なので、保存してもレシピを上書きすることはありません。

コマンドラインから:

pxr project blueprint game.pixor -o four-way.pixorblueprint
pxr run four-way.pixorblueprint --in model=hero.glb -o out/hero.png
pxr batch models/ --blueprint four-way.pixorblueprint --out out/
pxr run four-way.pixorblueprint --in model=hero.glb --set ring.count=12
pxr graph set four-way.pixorblueprint --which style --node 0 --set dither=0.5   # change the recipe itself

--set NODE.SETTING=VALUEは、1つのノードの設定を1つ変更します:シーングラフにそのノードがあればそこで、なければそのノードを持つすべてのアセットパイプラインとスタイルで変更します(--set hold.times=4:すべてのアセットパイプラインのホールドノード)。--set PIPELINE/NODE.SETTING=VALUEは、そのパイプラインだけで変更します。ノードはラベルを小文字にし、語の間をハイフンでつないだ名前で指定します(リングならring、注視点ならlook-at。pxr project sceneで一覧表示されます)。ラベルそのもの("Look at")も使えます。各スタイルのパレットファイルは独立したスロットです:最初のスタイルはpalette、ほかはpalette:NAME。スロットがない、または型が違う場合は、何かを読み込む前に、そのスロットと求められた型を表示します。

Pixorにはassets/blueprints/にいくつか付属しています:4方向のキャラクターシート、インベントリのアイコン、宣伝用の静止画です。

前回のビルドからの変更点

すべての書き出しにはレシピ(シートの作り方)が含まれるので、ビルドのデータベースがなくても2つのビルドを比較できます:

pxr diff out-yesterday/ out-today/

どのファイルが新しく、どれがなくなり、どれが何ピクセル違うのか、そしてどの設定、どの入力、どのブループリントが原因なのかを表示します:

changed  ring.png     36598 of 82944 pixels (44.12%)
         scene.nodes[3].settings.count: 16 -> 12

--exactは、何か変化があると1で終了します。再現可能であるべきビルド向けです。

書き出しが書くレイヤー

ペーパードールのピース、影のシート、パララックスレイヤーは別々のファイルです。アセットステップの2Dビューで、レイヤーセレクトのすべてを重ねてを選ぶと、エンジンと同じようにシートのレイヤーを奥から手前へ重ねて表示します。レイヤーごとの切り替えと、すべてのレイヤーがベースと同じサイズかを示す行が付きます。先に書き出す必要はありません。レイヤーは、すでにレンダリングされたフレームから、それを書き出すのと同じコードで描かれ、選んだスプライトシート出力のレイアウトどおりに並びます:完成したスプライト(base)、その影、線、フラットカラー、法線、深度、発光、スタイルグラフの追加出力です。最初はスプライトとその影がオンになっています。スプライトの上にノーマルマップを重ねると隠れてしまうからです。ファイルからは、代わりに書き出しで実際に書き出されたものを読み戻します。エンジンが読み込むのと同じファイルで、ペーパードールのピースやパララックスレイヤーも含みます。

このページで説明している内容は製品版の機能です。無料のブラウザーデモで使えるのは、デフォルトのルックとPNGシートだけです。

ブラウザーで試す Pixorを入手