共用方式為


串聯陰影對應

串聯陰影圖 (CSM) 是對抗陰影處理最普遍錯誤之一的最佳方式:透視鋸齒。 本技術文章假設讀者熟悉陰影對應,可處理 CSM 的主題。 具體來說,它:

  • 說明 CSM 的複雜性;
  • 提供 CSM 演算法可能變化的詳細數據;
  • 描述兩種最常見的篩選技術:更接近篩選的百分比(PCF),以及使用變異陰影對應進行篩選(VSM):
  • 識別並解決與將篩選新增至 CSM 相關聯的一些常見陷阱;和
  • 示範如何將 CSM 對應至 Direct3D 10 到 Direct3D 11 硬體。

本文中使用的程式代碼可以在 CascadedShadowMaps11 和 VarianceShadows11 範例的 DirectX 軟體開發工具包 (SDK) 中找到。 本文在實作技術文章所涵蓋的技術之後,會證明最有用,實作改善陰影深度地圖的常見技術。

串聯陰影對應和檢視方塊別名

陰影圖中的檢視方塊別名是克服的最困難問題之一。 在技術文章中,會說明改善陰影深度地圖的常見技術、檢視塊別名,並識別出一些減輕問題的方法。 實際上,CSM 通常是最佳解決方案,而且通常會在現代遊戲中使用。

CSM 的基本概念很容易理解。 相機形圖的不同區域需要具有不同解析度的陰影對應。 最接近眼睛的物件需要比更遠的物件更高的解析度。 事實上,當眼睛接近幾何時,最接近眼睛的圖元可能需要這麼多解析度,即使 4096 × 4096 陰影圖也不足。

CSM 的基本概念是將 frustum 分割成多個 frusta。 會針對每個子系轉譯陰影對應;然後,圖元著色器會從地圖取樣最符合所需解析度(圖 2)。

圖 1. 陰影地圖涵蓋範圍

陰影圖涵蓋範圍

在圖 1 中,質量會顯示從最高到最低。 代表陰影貼圖的一系列網格線與檢視 frustum (紅色反圓錐)顯示圖元涵蓋範圍如何受到不同解析度陰影圖的影響。 當視圖中的像素與陰影貼圖中的像素以1:1比例對應時,陰影品質(白色像素)是最高的。 當太多像素對應到相同的陰影紋素時,檢視方塊別名會以大型區塊紋理對應(左影像)的形式發生。 當陰影圖太大時,它就會取樣。 在此情況下,會略過紋素、引進閃閃發光的成品,並影響效能。

圖 2. CSM 陰影品質

csm 陰影品質

圖 2 顯示圖 1 中每個陰影圖中最高品質區段的剪下圖。 陰影圖與最接近放置圖元的像素(位於頂點)最接近的眼睛。 從技術上看,這些是大小相同的地圖,白色和灰色用來示範串聯陰影圖的成功。 白色很理想,因為它會顯示良好的涵蓋範圍,也就是眼睛空間圖元和陰影地圖紋素的 1:1 比例。

CSM 需要每個畫面的下列步驟。

  1. 將 frustum 分割成 subfrusta。

  2. 計算每個子複本的正則投影。

  3. 轉譯每個子節點的陰影對應。

  4. 轉譯場景。

    1. 系結陰影對應和轉譯。

    2. 頂點著色器會執行下列動作:

      • 計算每個光線子圖形的紋理座標(除非在圖元著色器中計算所需的紋理座標)。
      • 轉換和點亮頂點等等。
    3. 像素著色器會執行下列動作:

      • 判斷適當的陰影圖。
      • 視需要轉換紋理座標。
      • 取樣串聯。
      • 將圖元點亮。

分割 Frustum

分割 frustum 是建立 subfrusta 的動作。 分割 frustum 的其中一個技巧是計算 Z 方向的間隔從零到百分之一百。 然後,每個間隔都會以 Z 軸的百分比表示接近平面和遠平面。

圖 3. 任意檢視分割的 frustum

檢視任意分割的 frustum

實際上,重新計算每個畫面的 frustum 分割會導致陰影邊緣閃閃發光。 一般接受的做法是為每個案例使用一組靜態的串聯間隔。 在此案例中,Z 軸上的間隔是用來描述分割 frustum 時所發生的子伺服器。 判斷指定場景的正確大小間隔取決於數個因素。

場景幾何的方向

相對於場景幾何,相機方向會影響串聯間隔選取。 例如,非常接近地面的相機,例如足球比賽中的地面相機,具有與天空中相機不同的靜態串聯間隔集。

圖 4 顯示一些不同的相機及其各自的分割區。 當場景的 Z 範圍非常大時,需要更多的分割平面。 例如,當眼睛非常接近地面平面,但遙遠的物件仍然可見時,可能需要多個串聯。 分割 frustum,使更多的分割接近眼睛(其中透視鋸齒正在變更最快)也是有價值的。 當大部分的幾何被塞進社區段(例如額外負荷檢視或飛行模擬器)檢視 frustum 時,需要較少的串聯。

圖 4. 不同的組態需要不同的 frustum 分割

不同的組態需要不同的 frustum 分割

(左)當 geometry 在 Z 中具有高動態範圍時,需要許多串聯。 (中心)當幾何在 Z 中具有低動態範圍時,多個 frustum 沒有什麼好處。 (右)當動態範圍是中度時,只需要三個數據分割。

光線和相機的方向

每個串聯的投影矩陣會緊密配合其對應的子系。 在檢視相機和光線方向為正交的設定中,串聯可以緊密配合很少重疊。 當光線和檢視相機進入平行對齊時,重迭會變大(圖 5)。 當光線源和攝像機幾乎相對(面對面)時,這種情況被稱為「dueling frusta」,對大多數陰影生成演算法來說,這是一個非常困難的情境。 限制光線和相機並不罕見,因此這種情況不會發生。 不過,CSM 在此案例中,效能優於許多其他演算法。

圖 5. 重疊重疊隨著光線方向與相機方向的平行增加

隨著光線方向與相機方向的平行處理,串聯重疊增加

許多 CSM 實作都使用固定大小的frusta。 圖元著色器可以使用 Z 深度,在固定大小間隔中分割 frustum 時,將索引編製成串聯陣列。

計算 View-Frustum 系結

選取 frustum 間隔之後,子frusta 會使用兩者之一來建立:適合場景並符合串聯。

符合場景

所有frusta都可以使用相同的近平面來建立。 這會強制重迭串聯。 CascadedShadowMaps11 範例會呼叫適合場景的這項技術。

符合級聯

或者,可以使用實際分割間隔建立frusta做為近遠平面。 這會導致更緊密的配合,但在決鬥弗魯斯塔的情況下,變質成適合場景。 CascadedShadowMaps11 範例會呼叫適合重疊的這項技術。

圖 6 顯示這兩種方法。 適合串聯浪費較少的解析度。 符合串聯的問題在於,正向投影會根據檢視方向成長和縮小。 適合場景技術會藉由檢視畫面大小上限填補正視投影,以移除檢視相機移動時出現的成品。 改善陰影深度地圖的常見技術 解決在「以紋素大小遞增移動光線」區段中光線時所出現的成品。

圖 6. 符合場景大小與重疊大小

符合場景與重疊

轉譯陰影圖

CascadedShadowMaps11 範例會將陰影對應轉譯成一個大型緩衝區。 這是因為紋理陣列上的PCF是 Direct3D 10.1 功能。 針對每個串聯,會建立一個檢視區,其涵蓋對應至該串聯的深度緩衝區區段。 Null 像素著色器系結,因為只需要深度。 最後,每個串聯都會設定正確的檢視區和陰影矩陣,因為深度對應會一次轉譯成主要陰影緩衝區。

轉譯場景

包含陰影的緩衝區現在會系結至圖元著色器。 有兩種方法可用來選取 CascadedShadowMaps11 範例中實作的串聯。 這兩種方法會使用著色器程式代碼來說明。

Interval-Based 串聯選取

圖 7. 以間隔為基礎的串聯選取專案

以間隔為基礎的串聯選取

以間隔為基礎的選取範圍(圖 7),頂點著色器會計算頂點世界空間中的位置。

Output.vDepth = mul( Input.vPosition, m_mWorldView ).z;

圖元著色器會接收插補深度。

fCurrentPixelDepth = Input.vDepth;

以間隔為基礎的串聯選取會使用向量比較和點乘積來判斷正確的cacade。 CASCADE_COUNT_FLAG會指定串聯的數目。 m_fCascadeFrustumsEyeSpaceDepths_data會限制檢視 frustum 分割區。 比較之後,fComparison 會包含值 1,其中目前的圖元大於屏障,而當目前的串聯較小時,值為 0。 點產品會將這些值加總成數位列索引。

        float4 vCurrentPixelDepth = Input.vDepth;
        float4 fComparison = ( vCurrentPixelDepth > m_fCascadeFrustumsEyeSpaceDepths_data[0]);
        float fIndex = dot(
        float4( CASCADE_COUNT_FLAG > 0,
        CASCADE_COUNT_FLAG > 1,
        CASCADE_COUNT_FLAG > 2,
        CASCADE_COUNT_FLAG > 3)
        , fComparison );

        fIndex = min( fIndex, CASCADE_COUNT_FLAG );
        iCurrentCascadeIndex = (int)fIndex;

選取串聯之後,紋理座標必須轉換成正確的串聯。

vShadowTexCoord = mul( InterpolatedPosition, m_mShadow[iCascadeIndex] );

接著,這個紋理座標會用來使用 X 座標和 Y 座標取樣紋理。 Z 座標是用來進行最終深度比較。

Map-Based 串聯選取

地圖型選取專案 (圖 8) 會針對串聯的四側進行測試,以找出涵蓋特定圖元的最緊密地圖。 頂點著色器不會計算世界空間中的位置,而是計算每個串聯的檢視空間位置。 圖元著色器會逐一查看串聯,以便縮放和轉移紋理座標,以便為目前的串聯編製索引。 接著會針對紋理界限測試紋理座標。 當紋理座標的 X 和 Y 值落在串聯內時,它們會用來取樣紋理。 Z 座標是用來進行最終深度比較。

圖 8. 以地圖為基礎的串聯選取

地圖型串聯選取

Interval-Based 選取範圍與 Map-Based 選取範圍

以間隔為基礎的選取比地圖型選取專案稍微快一點,因為可以直接完成串聯選取。 以地圖為基礎的選取必須與串聯界限交集紋理座標。

當陰影圖不完全對齊時,以地圖為基礎的選取會更有效率地使用串聯(請參閱圖 8)。

串聯之間的混合

VSM(本文稍後討論)和 PCF 等篩選技術可以搭配低解析度 CSM 使用,以產生柔和陰影。 不幸的是,這會導致串聯層之間的可見接縫(圖 9),因為解析度不相符。 解決方案是在陰影對應之間建立一個帶狀,其中陰影測試會針對這兩個串聯執行。 接著,著色器會根據混合帶中圖元的位置,在兩個值之間線性插補。 CascadedShadowMaps11 和 VarianceShadows11 範例提供 GUI 滑桿,可用來增加和減少這個模糊帶。 著色器會執行動態分支,讓絕大多數圖元只能從目前的串聯讀取。

圖 9. 串聯接縫

串聯接縫

(左)可以看到串聯重疊的可見接縫。 (右)當串聯混合在兩者之間時,不會發生接縫。

篩選陰影對應

PCF

篩選一般陰影對應不會產生柔和模糊的陰影。 篩選硬體會模糊深度值,然後將這些模糊值與光空間紋素進行比較。 由於通過/失敗測試所產生的硬邊緣仍然存在。 模糊的陰影地圖只會錯誤地移動硬邊緣。 PCF 可讓您篩選陰影圖。 PCF 的一般概念是根據透過子取樣總數通過深度測試的子取樣數目,計算陰影中的圖元百分比。

Direct3D 10 和 Direct3D 11 硬體可以執行 PCF。 PCF 取樣器的輸入是由紋理座標和比較深度值所組成。 為了簡單起見,PCF 會使用四點選篩選來說明。 紋理取樣器會讀取紋理四次,類似於標準篩選條件。 不過,傳回的結果是通過深度測試的圖元百分比。 圖 10 顯示通過四個深度測試之一的像素在陰影中為 25%。 傳回的實際值是根據紋理讀取的子材質座標來產生平滑漸層的線性插補。 如果沒有這個線性插補,四點選PCF只能傳回五個值:{0.0、0.25、0.5、0.75、1.0}。

圖 10. PCF 篩選的影像,其中 25% 的所選圖元已涵蓋

pcf 篩選影像,其中 25% 的選取像素涵蓋

您也可以在沒有硬體支持的情況下執行PCF,或將PCF擴充至較大的核心。 某些技術甚至使用加權核心進行取樣。 若要這樣做,請為 N × N 方格建立核心 (例如 Gaussian)。 權數最多必須加 1。 紋理接著會取樣 N2 次。 每個範例都會依核心中的對應權數進行調整。 CascadedShadowMaps11 範例會使用此方法。

深度偏差

使用大型PCF核心時,深度偏差會變得更加重要。 只有將圖元的光空間深度與它對應至深度圖中的圖元進行比較才有效。 深度圖紋素的鄰居是指不同的位置。 此深度可能很類似,但視場景而定,可能會非常不同。 圖 11 醒目提示發生的成品。 單一深度會與陰影圖中的三個鄰近紋素進行比較。 其中一個深度測試錯誤地失敗,因為它的深度不會與目前幾何的計算光空間深度相互關聯。 此問題的建議解決方法是使用較大的位移。 然而,太大的位移可能會導致彼得·潘寧。 計算緊近平面和遠平面有助於減少使用位移的影響。

圖 11. 錯誤的自我遮蔽

錯誤的自我遮蔽

錯誤的自我遮蔽結果,是將光線空間深度中的圖元與陰影圖中的紋素相比較,而不會相互關聯。 淺空深度與深度圖中的陰影紋素 2 相互關聯。 紋素 1 大於光空間深度,而 2 相等,3 則較少。 紋素 2 和 3 通過深度測試,而紋素 1 失敗。

使用 DDX 和 DDY 計算大型 PCF 的 Per-Texel 深度偏差

針對大型PCF,使用 ddxddy 計算每個紋素深度偏差,是計算相鄰陰影圖紋素的正確深度偏差的技術。

這項技術使用衍生資訊,將比較深度與平面相配。 因為這項技術在計算上很複雜,所以只有在 GPU 有可備援的計算週期時,才應該使用它。 使用非常大的核心時,這可能是唯一可移除自我陰影成品而不會產生Peter Panning的技術。

圖 12 醒目提示問題。 光空間的深度以比較的一個紋素而聞名。 對應至深度地圖中鄰近紋素的光空間深度未知。

圖 12. 場景和深度地圖

場景和深度地圖

轉譯的場景會顯示在左側,而具有範例紋素區塊的深度圖會顯示在右側。 眼空紋素會對應到區塊中央標示為 D 的圖元。 此比較正確。 眼部空間中與鄰近 D 圖元相互關聯的正確深度未知。 只有當我們假設圖元與 D 相同的三角形相關時,才能將鄰近紋素對應回眼部空間。

深度以與光空間位置相互關聯的紋素而聞名。 深度圖中鄰近紋素的深度未知。

概括而言,這項技術會使用 ddxddy HLSL 作業來尋找光空間位置的衍生專案。 這是非有趣的,因為衍生作業會傳回相對於螢幕空間的光空間深度漸層。 若要將這個轉換成光空間深度相對於光空間的漸層,必須計算轉換矩陣。

著色器程式代碼的說明

演演算法其餘部分的詳細數據會以執行這項作業的著色器程式代碼說明來提供。 您可以在 CascadedShadowMaps11 範例中找到此程式代碼。 圖 13 顯示光線空間紋理座標如何對應至深度地圖,以及如何使用 X 和 Y 中的衍生專案來建立轉換矩陣。

圖 13. 屏幕空間到淺色空間矩陣

螢幕空間到淺色空間矩陣

X 和 Y 中光空間位置的衍生專案可用來建立這個矩陣。

第一個步驟是計算光線檢視空間位置的衍生。

          float3 vShadowTexDDX = ddx (vShadowMapTextureCoordViewSpace);
          float3 vShadowTexDDY = ddy (vShadowMapTextureCoordViewSpace);

Direct3D 11 類別 GPU 會以平行方式執行 2 × 2 個圖元四分之二的圖元,並將 X 中的紋理座標減去 ddx,並從 Y 中的鄰居減去 ddy。 這兩個衍生項目組成 2 × 2 矩陣的數據列。 在此矩陣目前的形式中,這個矩陣可用來將螢幕空間鄰近圖元轉換成光空間斜率。 不過,需要此矩陣的反轉。 需要將光空間鄰近圖元轉換成螢幕空間斜率的矩陣。

          float2x2 matScreentoShadow = float2x2( vShadowTexDDX.xy, vShadowTexDDY.xy );
          float fInvDeterminant = 1.0f / fDeterminant;

          float2x2 matShadowToScreen = float2x2 (
          matScreentoShadow._22 * fInvDeterminant,
          matScreentoShadow._12 * -fInvDeterminant,
          matScreentoShadow._21 * -fInvDeterminant,
          matScreentoShadow._11 * fInvDeterminant );

圖 14. 淺色空間到螢幕空間

光空間到螢幕空間

接著,這個矩陣會用來轉換目前紋素上方和右邊的兩個紋素。 這些鄰居會以目前紋素的位移表示。

          float2 vRightShadowTexelLocation = float2( m_fTexelSize, 0.0f );
          float2 vUpShadowTexelLocation = float2( 0.0f, m_fTexelSize );
          float2 vRightTexelDepthRatio = mul( vRightShadowTexelLocation,
          matShadowToScreen );
          float2 vUpTexelDepthRatio = mul( vUpShadowTexelLocation,
          matShadowToScreen );

矩陣所建立的比例最後乘以深度衍生值,以計算鄰近圖元的深度位移。

            float fUpTexelDepthDelta =
            vUpTexelDepthRatio.x * vShadowTexDDX.z
            + vUpTexelDepthRatio.y * vShadowTexDDY.z;
            float fRightTexelDepthDelta =
            vRightTexelDepthRatio.x * vShadowTexDDX.z
            + vRightTexelDepthRatio.y * vShadowTexDDY.z;

這些權數現在可以用於PCF迴圈中,以將位移新增至位置。

    for( int x = m_iPCFBlurForLoopStart; x < m_iPCFBlurForLoopEnd; ++x ) 
    {
        for( int y = m_iPCFBlurForLoopStart; y < m_iPCFBlurForLoopEnd; ++y )
            {
            if ( USE_DERIVATIVES_FOR_DEPTH_OFFSET_FLAG )
            {
            depthcompare += fRightTexelDepthDelta * ( (float) x ) +
            fUpTexelDepthDelta * ( (float) y );
            }
            // Compare the transformed pixel depth to the depth read
            // from the map.
            fPercentLit += g_txShadow.SampleCmpLevelZero( g_samShadow,
            float2(
            vShadowTexCoord.x + ( ( (float) x ) * m_fNativeTexelSizeInX ) ,
            vShadowTexCoord.y + ( ( (float) y ) * m_fTexelSize )
            ),
            depthcompare
            );
            }
     }

PCF 和 CSM

PCF 不適用於 Direct3D 10 中的紋理陣列。 若要使用PCF,所有串聯都會儲存在一個大型紋理圖集中。

Derivative-Based 位移

為 CSM 新增衍生型位移,會帶來一些挑戰。 這是因為分流控制內的衍生計算。 發生此問題的原因是 GPU 運作的基本方式。 Direct3D11 GPU 在 2 × 2 個像素四邊形上運作。 若要執行衍生專案,GPU 通常會從鄰近圖元的相同變數複本減去目前圖元的變數複本。 這種情況的發生方式會因 GPU 而異。 紋理座標取決於以地圖為基礎的或以間隔為基礎的串聯選取。 圖元四方中的某些像素選擇與其餘圖元不同的串聯。 這會導致陰影圖之間的可見接縫,因為衍生型位移現在完全錯誤。 解決方案是在光線檢視空間紋理座標上執行衍生專案。 每個串聯的座標都相同。

PCF 核心的填補

如果陰影緩衝區未填補,PCF 核心會在串聯分割區之外編製索引。 解決方案是將串聯的外部邊緣填補PCF核心大小的一半。 這必須在選取串聯的著色器中實作,而且必須在投影矩陣中實作,此矩陣必須轉譯足以保留框線的大小。

變異數陰影對應

VSM(如需詳細資訊,請參閱 Donnelly 和 Lauritzen 差異陰影圖)啟用直接陰影地圖篩選。 使用 VSM 時,可以使用紋理篩選硬體的所有功能。 可以使用三線性和異向性(圖 15) 篩選。 此外,VSM 也可以透過卷積直接模糊。 VSM 確實有一些缺點;必須儲存兩個深度數據的通道(深度和深度平方)。 當陰影重疊時,光出血很常見。 不過,它們的運作效果良好,解析度較低,而且可以與 CSM 結合。

圖 15. Anisotropic 篩選

異向性篩選

演算法詳細數據

VSM 的運作方式是將深度和深度平方到雙通道陰影圖。 然後,這個雙色板陰影圖可以模糊化並篩選,就像一般紋理一樣。 演算法接著會在圖元著色器中使用 Chebychev 的不等式來估計通過深度測試的圖元區域分數。

圖元著色器會擷取深度和深度平方值。

        float  fAvgZ  = mapDepth.x; // Filtered z
        float  fAvgZ2 = mapDepth.y; // Filtered z-squared

執行深度比較。

        if ( fDepth <= fAvgZ )
        {
        fPercentLit = 1;
        }

如果深度比較失敗,則會估計點亮的圖元百分比。 變異數會計算為平方的平均值減去平均平方。

        float variance = ( fAvgZ2 ) − ( fAvgZ * fAvgZ );
        variance = min( 1.0f, max( 0.0f, variance + 0.00001f ) );

fPercentLit 值是以 Chebychev 的不等比較來估計。

        float mean           = fAvgZ;
        float d              = fDepth - mean;
        float fPercentLit    = variance / ( variance + d*d );

光出血

VSM 的最大缺點是輕出血(圖 16)。 當多個陰影投手沿著邊緣互相遮蔽時,就會發生光出血。 VSM 會根據深度差異來遮蔽陰影的邊緣。 當陰影彼此重疊時,深度差異存在於應遮蔽的區域中央。 這是使用 VSM 演演算法的問題。

圖 16. VSM 光出血

vsm 光出血

問題的部分解決方案是將 fPercentLit 提升為電源。 這有抑制模糊的效果,這可能會導致深度差異很小的成品。 有時有一個神奇的價值,可以減輕問題。

fPercentLit = pow( p_max, MAGIC_NUMBER );

將百分比提升為電源的替代方法是避免陰影重疊的設定。 即使是高度微調的陰影組態,在光線、相機和幾何上也有數個限制。 使用解析度較高的紋理也會降低光出血。

分層變異數陰影圖 (LVSM) 會以犧牲將 frustum 分解成與光線垂直的圖層來解決問題。 使用 CSM 時,所需的對應數目會相當大。

此外,VSM 論文的共同作者安德魯·勞裡森,以及LVSM的論文作者,討論了將指數陰影圖(ESM)與 VSM 相結合,以對抗 Beyond3D 論壇的光線混合。

使用 CSM 的 VSM

範例 VarianceShadow11 結合了 VSM 和 CSM。 組合相當簡單。 此範例遵循與 CascadedShadowMaps11 範例相同的步驟。 由於未使用PCF,因此陰影會在雙階段可分隔的捲積中模糊。 不使用PCF也可讓範例使用紋理陣列,而不是紋理圖集。 紋理陣列上的PCF是 Direct3D 10.1 功能。

具有CSM的漸層

搭配 CSM 使用漸層可以沿著兩個串聯之間的框線產生接縫,如圖 17 所示。 範例指令會使用圖元之間的衍生值來計算篩選所需的資訊,例如 Mipmap 層級。 這會導致特別針對 mipmap 選取或異向性篩選造成問題。 當四邊形中的像素採用著色器中的不同分支時,GPU 硬體計算的衍生項目無效。 這會導致陰影圖上的鋸齒狀接縫。

圖 17. 串聯邊界上的接縫,因為具有不同流量控制的非正向性篩選

由於具有不同流量控制seams on cascade borders due to anisotropic filtering with divergent flow controlseams on cascade borders due to anisotropic filtering with divergent flow control的非等性篩選,串聯框線上的接縫

此問題可藉由計算光線檢視空間中位置的衍生值來解決:光線檢視空間座標並非選取的串聯所特有。 計算的衍生專案可由投影紋理矩陣的縮放部分調整為正確的Mipmap層級。

        float3 vShadowTexCoordDDX = ddx( vShadowMapTextureCoordViewSpace );
        vShadowTexCoordDDX *= m_vCascadeScale[iCascade].xyz;
        float3 vShadowTexCoordDDY = ddy( vShadowMapTextureCoordViewSpace );
        vShadowTexCoordDDY *= m_vCascadeScale[iCascade].xyz;

        mapDepth += g_txShadow.SampleGrad( g_samShadow, vShadowTexCoord.xyz,
        vShadowTexCoordDDX, vShadowTexCoordDDY );

VSM 與 PCF 的標準陰影比較

VSM 和 PCF 都會嘗試近似通過深度測試的像素區域分數。 VSM 可與篩選硬體搭配使用,而且可以使用可分隔的核心來模糊。 可分離的捲積核心比完整核心便宜得多。 此外,VSM 會比較一個光空間深度與光空間深度地圖中的一個值。 這表示 VSM 與 PCF 沒有相同的位移問題。 從技術上看,VSM 會針對較大的區域進行取樣深度,以及執行統計分析。 這比PCF更精確。 在實務上,VSM 在混合方面做得非常好,因此需要較少的位移。 如上所述,VSM 的第一個缺點是輕出血。

VSM 和 PCF 代表 GPU 計算能力與 GPU 紋理頻寬之間的取捨。 VSM 需要執行更多數學來計算變數。 PCF 需要更多紋理記憶體頻寬。 大型PCF核心可能會因紋理頻寬而快速成為瓶頸。 隨著 GPU 計算能力比 GPU 頻寬更快成長,VSM 正變得越來越實用這兩種演算法。 由於混合和篩選,VSM 在解析度較低的陰影對應中看起來也更好。

總結

CSM 提供檢視方塊別名問題的解決方案。 有數個可能的組態可取得標題所需的視覺逼真度。 PCF 和 VSM 廣泛使用,應該與 CSM 結合以減少別名。

引用

唐納利、W. 和勞裡森,A. 變異數陰影圖。 在 SI3D '06: 2006 年互動式 3D 圖形和遊戲研討會的論文。 2006年。第161–165頁。 紐約,紐約,美國:ACM出版社。

勞裡森、安德魯和麥考爾,邁克爾。 階層變異數陰影圖。 圖形介面 2008 年 5 月 28-30 日、2008 年 5 月 30 日、溫莎、加拿大安大略。

恩格爾, 沃夫剛 F. 第 4 節。 串聯陰影對應。 ShaderX5、進階轉譯技術、沃爾夫岡 F. Engel、Ed。 查理斯河媒體,波士頓,馬薩諸塞州。 2006年。第197–206頁。