Odd behavior of retained geometry in RIB spec

by syoyo

RenderMan では、ObejctBegin/ObejectEnd で物体定義を囲み、
その後 ObjectInstance を呼ぶことでオブジェクトインスタンス化を行うことができます.
この仕組みにより、たとえば群衆など同じような形状で位置が違うだけ、というような状況を、
ジオメトリデータのマスターは一個だけであってあとはそれを参照するようにすることで実現できます.
これにより大規模データを効率的に扱うことができます.

が、この仕様がどうにも不可思議です(仕様にもまともに振る舞いが書いていない).
まあ元々スタックベースのプロトコルに無理矢理継ぎ足した感バリバリの仕様なのでしょうがないのかもしれません.

ネストできない

ObjectBegin/End はネストして定義することができません.


ObjectBegin 1
Sphere 1 -1 1 360
  ObjectBegin 2   # NG!
  Translate 1 0 0
  Sphere 1 -1 1 360
  ObjectEnd
ObjectEnd

たとえば aqsis だと

Invalid state for RiObjectEnd [World]

とエラーとなってしまいます.
ただ、ObjectBegin/End 内で ObjectInstance はコールできますので、
この方法で無理矢理ネスト定義することは可能ですが… あまり美しくないですね 🙂

AttributeBegin/End, TransformBegin/End みたいにネストして定義できると便利だと思うのですけどね.
まあ、C 言語バインディングとの整合性の関係もあるのかもしれません.

Instance 時の state は RIB 仕様通り? に変更される.

以下のような RIB があったとすると、ObjectInstance の前の Transform 宣言は ObjectBegin/End ペア内の Transform で上書きされる(aqsis の場合).


ObjectBegin 1
Transform [ 1 0 0 0
            0 1 0 0
            0 0 1 0
            1 0 0 1 ]
Sphere 1 -1 1 360
ObjectEnd
TransformBegin
Transform [ 1 0 0 0
            0 1 0 0
            0 0 1 0
            -1 0 0 1 ]
ObjectInstance 1
TransformEnd

RIB の元々の仕様では Transform は現在のマトリクスを置き換えるので、
(OpenGL で言えば LoadMatrix 操作)
これはまあ正しい動作なのでしょうが、ちょっと違和感がありますよね.

なので、インスタンス物体の相対変換をしたい場合は、
ObejctBegin/End 内での変換には ConcatTransform を使うようにすることで期待する結果が得られます.
(OpenGL で言う MultMatrix)

また、3delight ではそもそも ObjectBegin/End 内での Transform 系の呼び出しはエラーになります. はて?

Transformations, and even Motion blocks, may be used inside an Object block
(from RI spec 3.2)

んー、”may” だから実装依存ってことでしょうか?

OpenGL とかシーングラフ階層になじみのあるひとには、ObjectBegin/End のふるまいには ??? と思ってしまいます.

ObjectBegin に指定できる ID は 0 から 65535 まで

今時16bit ぶんしか ID が振れないというのは物足りない気がします.
ILM あたりが描画する物量を考えたとして, あれが ObjectInstance とか使っている場合, 16bit ぶんだと Object ID 足りないんじゃない?…

Advertisements