Stange behavior of TIFF RGBA

by syoyo

RenderMan + TIFF RGBA とたわむれていたら不思議な挙動にぶつかりました.

RenderMan では, シェーダの Ci, Oi でそれぞれカラーとオパシティ(colored)を指定することができます.
RGBA 形式で TIFF を書き出すときは Ci が RGB に、Oi が A に割当たります.
(Oi -> alpha の変換は RI spec によれば単純に平均を取るとこのと)

ここで以下のシェーダと RIB を考えてみます.


surface
myshader()
{
  Oi = Os;
  Ci = Os * Cs;
}


Surface "myshader"
Color [1 1 1]
Opacity [0.5 0.5 0.5]
Polygon ...

ここで、Polygon のシェーディング結果は 0.5(50% gray)のピクセル色になることが期待されます.

TIFF RGB で書き出すと、実際 RGB = [127, 127, 127] となるのでこれはまず問題ありません.

TIFF RGBA で書き出すと, なぜかピクセル値は

RGB = [255, 255, 255], A = [127]

になります(prman/aqsis + gimp で確認). つまり RGB * A としたときに 50% gray となるように, レンダラ側でシェーディング結果色 Ci に対して結果オパシティ色 Oi の逆数をかけてから TIFF ディスプレイドライバに書き出されているらしい.

ためしにシェーダの方で Oi = 0.1, Ci = 0.1 とかすると RGB = [255, 255, 255], A = [26] になりますので、
やはり Oi の逆数を Ci にかけているようです. 
つまり Ci がそのまま RGB チャンネルに書き出されない. これってちょっとしたハマりポイントではないでしょうか.

さらに不思議なのが、A = 0 のとき.
A = 0, RGB=255 で TIFF を書き出しそれを gimp などで読み込むと、なぜか RGB=0 となってしまいます.
(lucille で直接 libtiff を使って確認)

つまり A = 0 のときは RGB のピクセル値が何であれ、RGB = 0 に libtiff 内部で上書き処理されてしまっているようです.
これだとせっかく頑張ってシェーディング色 Ci を計算して出しても、ついうっかり(?) Oi を 0 にしちゃうとまっさらな TIFF 画像が出来てしまうということになります.
こちらは libtiff 側の動作の問題(?)のようです.

Advertisements