共用方式為


重疊的陰影圖

重迭陰影貼圖 (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 中,品質會顯示 (從最高到最低) 由左至右。 代表陰影貼圖的一系列格線,其檢視外框 (紅色圓錐形) 顯示圖元涵蓋範圍如何受到不同解析度陰影圖的影響。 當光線空間中有 1:1 比例的圖元與陰影圖中的紋素時,陰影是最高品質的 (白色圖元) 。 當太多圖元對應至相同的陰影材質時,檢視方塊別名會以大型、封鎖紋理貼圖的形式 (左影像) 。 當陰影圖太大時,會進行取樣。 在此情況下,會略過紋素、引進填充成品,並影響效能。

圖 2. CSM 陰影品質

csm 陰影品質

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

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

  1. 將 frustum 分割成 subfrusta。

  2. 計算每個子集的正視投影。

  3. 轉譯每個子圖形的陰影圖。

  4. 轉譯場景。

    1. 系結陰影圖和轉譯。

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

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

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

分割 Frustum

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

圖 3. 任意檢視分割的 frustum

檢視任意分割的 frustum

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

場景幾何的方向

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

圖 4 顯示一些不同的相機及其各自的分割區。 當場景的 Z 範圍非常大時,需要更多分割平面。 例如,當眼睛非常接近地面平面,但遠距的物件仍然可見時,可能需要多個串聯。 分割 frustum,讓更多分割接近眼睛 (其中檢視別名會變更最快) 也很重要。 當大部分的幾何都壓縮成小型區段 (例如額外負荷檢視或飛行模擬器) 檢視 frustum 時,需要較少的串聯。

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

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

(Left) 當幾何在 Z 中有高動態範圍時,需要許多串聯。 (中心) 當幾何在 Z 中具有低動態範圍時,多個 Frustum 幾乎沒有好處。 (Right) 動態範圍為中時,只需要三個分割區。

淺色和相機的方向

每個串聯的投影矩陣會緊密配合其對應的子範圍。 在檢視相機和光線方向為正交的組態中,串聯可以緊密配合,且重迭很少。 當光線和檢視相機移到平行對齊 (圖 5) 時,重迭會變得更大。 當光線和檢視相機幾乎平行時,它會稱為「dueling frusta」,而且是大部分陰影演算法的困難案例。 限制光線和相機並不常見,因此不會發生此案例。 不過,CSM 的執行效能優於此案例中的其他許多演算法。

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

串聯重迭隨著光線方向與相機方向平行增加

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

計算View-Frustum系結

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

符合場景

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

調整為 Cascade

或者,您也可以使用實際分割間隔來建立 frusta,做為接近和遠平面。 這會導致更緊密地配合,但在因應 frusta 的情況下,會因應場景而變質。 CascadedShadowMaps11 範例會呼叫這項技術適合串聯。

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

圖 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 Selection 與 Map-Based Selection

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

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

在串聯之間混合

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

圖 9. 串聯接合

串聯接合

(左) 可以看到串連重迭的位置。 (Right) 當串聯混合時,不會發生接合。

篩選陰影對應

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 醒目提示發生的成品。 單一深度會與陰影圖中的三個鄰近材質進行比較。 其中一個深度測試錯誤失敗,因為它的深度不會與目前幾何的計算光線空間深度相互關聯。 此問題的建議解決方案是使用較大的位移。 不過,太大的位移可能會導致 Peter Panning。 計算緊密近平面和遠平面有助於減少使用位移的效果。

圖 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 作業來尋找光線空間位置的衍生專案。 這是非Trivial,因為衍生作業會傳回相對於螢幕空間的光線空間深度漸層。 若要將此值轉換成相對於光線空間的光線空間深度漸層,必須計算轉換矩陣。

著色器程式碼的說明

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

圖 13. 螢幕空間到光線空間矩陣

螢幕空間到光線空間矩陣

X 和 Y 中光線空間位置的衍生專案是用來建立此矩陣。

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

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

Direct3D 11 類別 GPU 會平行執行 2 × 2 四個圖元的四邊形,並針對 ddx 從 X 中的鄰近減去紋理座標,以及從 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,所有串聯都會儲存在一個大型紋理 atlas 中。

Derivative-Based位移

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

PCF 核心的填補

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

變異陰影圖

VSM (如需啟用 直接陰影圖篩選的詳細資訊,請參閱 Donnelly 和 Lau) 差異陰影圖。 使用 VSM 時,可以使用紋理篩選硬體的所有電源。 您可以使用三線性和非等向性 (圖 15) 篩選。 此外,VSM 可以透過卷積直接模糊。 VSM 確實有一些缺點;深度資料的兩個通道必須儲存 (深度和深度平方) 。 當陰影重迭時,淺色器很常見。 不過,它們可搭配較低的解析度運作,並可與 CSM 結合。

圖 15. 非等向性篩選

非等向性篩選

演算法詳細資料

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

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

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

執行深度比較。

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

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

        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 時,所需的對應數目會相當大。

此外,Andrew Lau) 與 VSM 共同撰寫的 VSM 檔,以及 LVSM 上的檔作者,討論如何結合指數陰影貼圖 (ESM) ,以在 Beyond3D 論壇中反轉光線混合。

使用 CSM 的 VSM

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

使用 CSM 的漸層

搭配 CSM 使用漸層可沿著兩個串聯之間的框線產生接合,如圖 17 所示。 範例指令會使用圖元之間的衍生來計算篩選所需的資訊,例如 Mipmap 層級。 這會導致 mipmap 選取或非等向性篩選發生問題。 當四邊形中的圖元採用著色器中的不同分支時,GPU 硬體所計算的衍生專案無效。 這會沿著陰影圖產生不規則的接縫。

圖 17. 串聯框線上的接縫,因為具有分量流程式控制制的不相等性篩選

串聯框線上的接縫,因為具有分位流程式控制制的不等性篩選

此問題的解決方式是計算光線檢視空間中位置的衍生專案;光線檢視空間座標不是選取的串聯所特有。 計算的衍生專案可以依投影紋理矩陣的縮放比例部分調整為正確的 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 );

與使用 PCF 的標準陰影比較的 VSM

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 結合以減少別名。

參考資料

Donnelly、W. 和 Lau,A. 變異數陰影圖。 在 SI3D '06:互動式 3D 圖形和遊戲的 2006 年活動繼續。 2006. pp. 161–165. 美國紐約紐約市:ACM Press。

Lau一、Andrew 和 McCool、Michael。 分層變異數陰影圖。 圖形介面 2008 年 5 月 28–30 日、2008 年 5 月 30 日、加拿大的繼續。

Engel, Wofl,F. 第 4 節。 串聯陰影圖。 ShaderX5 、進階轉譯技術、一文中 F.Engel、Ed。 Charles River Media、Boston、Riverts。 2006. pp. 197–206.