Wednesday, November 28, 2007

Screen Space Ambient Occlusion

Crysis大受注目後, SSAO也開始紅了起來, 因此我上網查了一下資料, 想說寫一個DX10.1的sample, 藉此來展示一下新的multi-sample depth buffer的存取功能. 在網路上找到幾篇不錯的資料, 大致上找到三種作法.

第一種就是Crysis的做法, 使用depth buffer中的資料, 將pixel還原至世界座標, 然後在周圍空間中的點中取樣, 將取樣點的Z值跟viewport中對應pixel的Z值比較來決定出遮蔽的比例. 基本上這個做法物理上完全不正確, 但他可以在面的交接處產生陰影, 讓人"感覺"好像有AO. 我目前是使用這個方法, 之後還會再試試其它做法. 再這裡有完整的實作介紹. Crytek的原始文件可以在這裡找到, 不過只有短短18行, 所有些東西還是得自己try.

第二個做法則是類似deferred shader的做法, 使用兩個buffer來紀錄每個pixel的位置及法向量, 然後根據附近pixel的資料, 距離以及法向量的夾角, 求出相對應的遮蔽的比例. 接下來我會試驗看看這個方法, 在這裡有完整的實作介紹. 這個方法我感覺比較接近真正的AO, 也許效果會更好一些 . 不過跟第一種方法比就是要多花一些記憶體空間.

第三種做法則是將問題分為兩部分, 高頻與低頻. 高頻代表的就是物體面與面之間的交物作用, 也就是local的部分. 這部分可以使用SSAO解決, 上面兩種方法都可以. 至於彽頻部分則是物件與物件的交互作用部分, 也就是global的部分. 這部分則是使用object space的方式使用proxy來解決. 這個做法聽起來挺不錯的, 而且scaleable, 對於配備低的電腦就只用SSAO.這裡可以找到詳細的說明.

即時AO的好處除了節省記憶體外, 另一個最大好處就是可以做到動態AO. 另外在網路上也發現到一篇關於即時動態AO的文章, 有興趣的在這裡可以找到更詳細資料.

放上一段使用第一種方法在動態物件上的影片, 效果不是非常的滿意, 我想還需要再多做一些試驗. 之前有用R2VB做過動態AO, 但效能太差, 不太可能應用再真實遊戲上. 我覺得視覺上的70%正確比起物理上的90%正確更符合遊戲的需要.