特定条件下ではレイトレはGPUラスタよりも高速?

gpuppur2007-03-06

GPUPPURはGPUとPPUを活用して高速化を狙ってたのですが、PPUに必要なAPIがまだ公開されていないために結局GPU+CPUでレンダリングを行なっています。
それで実際には、多くの場合OpenGLDirect3Dを使ったほうが高速にレンダリングできるのですが、特定の条件下ではGPUPPURのGPUPPURayはそれらよりも高速にレンダリングできます。
レイトレーシングには大き過ぎる512x512サイズの画像へ少な過ぎる70kトライアングルのStanford bunnyをレンダリングする場合では、もちろんGPUによるラスタライズ法には敵いません。しかし、縦横が数十ピクセルの画面へ100k~1000kトライアングルのモデルをレンダリングする場合ではどうでしょうか。実際に実験してみました。

実験に用いたモデル:
sphere.obj
頂点数 98306
三角形数 196608

leg6.obj
頂点数 528753
三角形数 1057344

GPUPPURayではレイトレーシングPhysX SDKに用意されている関数(raycastClosestShape)を使っていて、その関数でポリゴンを扱うにはCooking APIで前処理してから使わないといけません。
本当はThe Stanford 3D Scanning RepositoryのArmadilloを使おうと思ってたのですがCooking APIがうまく処理できず、結局自分でモデルを作りました。
ハイポリなモデルでは滑らかな形じゃないと駄目っぽいですね。

実験PC:
Core2Duo T5500 (1.66GHz)
Geforce Go 7600 256MB
memory 1GB
windows vista

実験方法:
sphere.objとleg6.objをそれぞれ解像度を変化させながらレイトレーシング法、ラスタライズ法でレンダリングし、1frameの平均レンダリング時間を測定します。
レイトレーシングにはGPUPPURayを使い、ラスタライズにはGPUPPURasを改造したもの(単純にメッシュをレンダリングするだけ)を使います。
ラスタライズするときは頂点単位でライティングの計算を行ないます。(今回の場合、ピクセル単位でライティングしたほうが高速かも)

実験結果
数値は1frameをレンダリングするのに掛かった時間(㍉秒)です。

		sphere.obj	leg6.obj
		Raytracing	Raytracing
8x8		0.54		0.45
16x16		1		1.3
32x32		3.4		4.7
64x64		14		17
128x128	48		63
256x256	190		240

		sphere.obj	leg6.obj
		Rasterizing	Rasterizing
8x8		1.9		13
16x16		1.9		13
32x32		1.9		13
64x64		1.9		13
128x128	1.9		13
256x256	1.9		13

結果:
実験結果をグラフにしたものが右上の図です。(小さくて見難いですが)
ちなみに両対数グラフになっていて、横軸が画像サイズ、縦軸が時間となっています。
右上斜め(/)になっているのがレイトレーシング法でレンダリングしたときの時間変化で、2本の線の上のほうがsphere.obj、下のほうがleg6.objをレンダリングしたときのものです。
水平な2本の線がラスタライズでレンダリングしたときのものです。頂点処理が多くてピクセル単位の処理が少ないので画像サイズが変わっても処理時間はほとんど変化無いです。

ラスタライズではトライアングル数が増えると大きく処理時間が変化していますが、レイトレーシングではそれほど大きく変化していません。
画像サイズが小さいとき(グラフの左側)では処理時間がレイトレーシングのほうが短くなっています。
それにトライアングル数が多い方では32x32までのサイズでラスタライズよりも高速です。


今回の実験では実用的でないような小さい画像、ハイポリでの実験だったのですが、トライアングル数と処理効率がもっとあがればレイトレーシングが実用的なサイズでラスタライズを上回ることができるかもしれません。ですが、GPUもどんどん高速になっているのでラスタライズが高速という状況がずっと続くかもしれません。
でも、特定の条件ではレイトレーシングがラスタライズより高速だということが実験で示すことができてよかったです。