texture caching
by ますお
テクスチャはメモリ食いの王者です.
リアルタイムレンダリングでは,テクスチャメモリの容量に制限があるため,あるシーンで使えるテクスチャの量に大きな制限があるのが一般的ですが,実はソフトウエアレンダリングでもメモリを圧迫する一番の要因はテクスチャです.
我々が製作する映像の場合,テクスチャは4Kで描かれる事が多く,各チャンネル8bitだとしてもそのデータサイズは約50MB,alpha付きだと約67MBにもなります.
もちろん1オブジェクトにつき1枚ではありませんから,シーン全体だと相当な量になります.”CATWOMAN”ではvirtual CATWOMANに約40枚のテクスチャが使われました.全てが4Kではありませんでしたが,確か全部で1.2GBくらいあったと思います.
この量を全部メモリに展開してしまうと,ジオメトリや計算に必要なメモリが全く足りなくなってしまい,レンダリングが不可能になってしまいます.
これを防ぐために,大規模な製作で使われる事を想定しているレンダラは,texture cachingと呼ばれる機能を持っています.
これは単に読み込んだテクスチャをキャッシュしておくのではなく,テクスチャの部分読みをし,その断片をキャッシュして再利用する仕組みです.
どのように断片化するかは実装の仕方が色々とあると思いますが,大抵はグリッドで区切るだけでも十分効果があると思います.あとはshading pointのUV座標に従って,そのグリッドの中から一つの領域のみを読み込むようにします.
こうする事で,どんなに巨大なテクスチャファイルでも,あるshadingの計算で必要な部分のテクスチャだけを読み込こむ事が可能になり,メモリの消費を最小限に抑える事ができます.
これは非常に重要な機能の一つで,これがサポートされていないと正直言って製作には使えません.それだけcriticalな機能です.
テクスチャのキャッシュに使われるメモリの量は,レンダリング時のパラメターで,このサイズから溢れた場合は一番優先度の低い物から順に削除され,再度必要になった場合はまたファイルから読み出す必要がありますから,キャッシュに使用できるメモリサイズがあまりに少ないと,レンダリング時間が長くなってしまいます.
関係ありませんが,「これが解決しないとこの作品は完成できない!」というくらい重要な事柄を,”show-stopper”と呼びます.凄く重要そうでしょ?texture cachingはまさにshow-stopperです.
ますおさん、syoyo と申します。
昔の PRMan の CAT(coherent access texture)は単純にブロック状 + ピラミッド状に切るだけだった気がしますが、最近ではそれなりに sophisticated なテクスチャキャッシュも提案されているかと思います(特に GPU には。ちょうどテクスチャキャッシュについては某所で取り上げようかと考えていましたので、いずれまとめて掲載したいと思います)。
テクスチャキャッシュは、テクスチャが coherent に張られる場合は十分なほどのパフォーマンスを示すと思います。
しかし、たとえばシェーダ内部で UV に変動を与えてテクスチャを引いたり、バンプ反射などでランダムな方向からテクスチャを引いたりと、テクスチャアクセスが incoherent な状況になる場合は、キャッシュミスが大きくなってパフォーマンスに響いてきそうな気がします。
これは複雑なシェーダと大量のテクスチャを扱うプロダクションで特に顕著に生じるのではないかと思うのですが、実際のところそのような経験とかあったりしますでしょうか?
syoyoさん,こんにちは.コメント有り難うございます.
開発日記,大好きです.よく拝見しています:-)
なるほど,確かに仰るようにincoherentな状況はいとも簡単に発生しますね.
でも,texture loadingの速度が問題になった事はないです.速度よりもメモリの方が問題になる事が多いです.(今のところ)
きちんと試した事が無いので飽くまで推測ですが,恐らく一枚の絵をレンダリングするうち,シェーダが複雑とは言え,そのような状況が現れる場所はそれ程多くないのと,テクスチャをロードする時間はトータルのレンダリグ時間に比べれば小さな割合なのだと思います.
自分はリアルタイムレンダリングにはあまり明るくないのですが,CPUでも使えそうなテクニックがあったりするんでしょうか.syoyoさんの記事,楽しみにしています.
ますおさん、syoyo です。
うーむ、そうですか、私の杞憂のようです。
ギガバイト級のテクスチャを扱う状況でも、それなりにテクスチャキャッシュが効いていれば問題ないのですね。
やはりこの問題は、 GPU などのテクスチャパフォーマンスがシビアな限られた世界でのお話のようです。
リアルタイム向けのキャッシュ機構を、CPU に実装する場合は、ますおさんの言うようにそれほど違いを生まないような気がしてきました。
とはいえ、通常の CPU がそなえるようなメモリキャッシュ機構を実装するだけでも、オフラインレンダラの要所要所で応用があると思います。たとえばテクスチャ以外にも、メモリに入り切らないジオメトリや空間データ構造の処理などが可能になりますね(もちろん商用レンダラではすでに実装されているでしょう)。
なるほど,テクスチャに限らず,データを全て同じような考え方の元でキャッシュシステムに入れるのですね.
mentalrayは似たような機能を持っていたと思います.自分はそこまで大量なオブジェクトを一度にレンダリングした事が無いので効果の程が分かりませんが… (殆どのシーンは大量のレイヤに分けられてしまう)
# ところでこのコメント欄見辛いですね.時間ができたら直そう…