2011-07-19 23 views
4

我目前正在將陰影映射(準確地說是級聯陰影映射)編程到我的C++ opengl引擎中。因此,我想要一個包含我的光源與陰影貼圖中每個像素之間距離的紋理。我應該使用哪種紋理類型?將頂點深度信息存儲在opengl陰影映射中的紋理

我看到有一個GL_DEPTH_COMPONENT紋理內部格式,但它縮放我想給紋理[0,1]的數據。我應該在創建陰影貼圖時將我的長度反轉一次,然後在最終渲染過程中第二次返回真實長度?這似乎很無用!

有沒有辦法使用紋理來存儲長度而不反轉它們兩次? (一次在創建紋理時,一次在使用過程中)。

+1

我將您的舊帳戶合併到此帳戶中,以便您可以編輯自己的帖子並留下評論。 –

+0

非常感謝:)我終於接受了他的解決方案! – Tuxer

回答

4

我不確定你的意思與反轉(我敢肯定你不能意味着反轉距離,因爲這將無法正常工作)。你所做的是將距光源的距離轉換到[0,1]範圍內。

這可以通過爲光源視圖構建通常的投影矩陣並將其應用於陰影貼圖構造階段中的頂點來完成。這樣它們與光源的距離被寫入深度緩衝區(您可以通過glCopyTexSubImage或FBO將紋理連接到GL_DEPTH_COMPONENT格式)。在最後一遍中,您當然會使用相同的投影矩陣來使用投影貼圖(在使用GLSL時使用sampler2DShadow採樣器)來計算陰影貼圖的紋理座標。

但是這種轉換不是線性的,因爲深度緩衝區在觀看者(或者這種情況下的光源)附近具有更高的精度。另一個缺點是你必須知道距離值的有效範圍(光源影響的最遠點)。使用着色器(我假設你這樣做),可以通過將距離與光源的距離除以該最大距離來進行線性變換,並手動將其分配給片段的深度值(GLSL中的gl_FragDepth),這可能意味着通過「反轉」。

可以通過對光距使用浮點紋理並僅將距離寫爲顏色通道,然後自己在最後一遍中執行深度比較來防止分區(以及最大距離的知識)(使用一個正常的sampler2D)。但是,線性過濾浮點紋理僅在新硬件上受支持,而且我不確定這是否會比每個片段的單個劃分更快。但是這種方式的好處是,這會爲像「方差陰影貼圖」這樣的事物打開道路,對於正常的Ubyte紋理(由於精度低)以及深度紋理都不會很好。所以總結起來,GL_DEPTH_COMPONENT只是在ubyte紋理(缺少必要的精度,因爲GL_DEPTH_COMPONENT應該至少具有16位精度)和浮點紋理(在舊硬件上並不那麼快或完全支持)之間的良好折衷, 。但由於它的固定點格式,你不會繞過[0,1]範圍的變換(不管它是投影線性的)。我不確定浮點紋理是否會更快,因爲您只需要劃分一個分區,但如果您使用的是支持浮點紋理和1或2個分量浮點紋理和渲染目標的線性(甚至三線)濾波的最新硬件,這可能值得一試。

當然,如果您使用的是固定功能流水線,您只有GL_DEPTH_COMPONENT作爲選項,但對於您的問題,我假設您使用着色器。