【SIGGRAPH 2013】Playing with Real-Time Shadows

本文是對Crytek引擎在Siggraph 2013年上關于陰影實施技術陳述的學習文稿,前面是一系列的效果圖,這里就不展示了,請有需要的同學自行查看原始PDF

這里是本文的主題框架,包含一系列陰影實現(xiàn)方案。

這里是實時渲染中陰影部分的預算范圍,包括時間消耗與內存占用等。

第一種要介紹的是延遲陰影(Deferred Shadows)方案。這種方案的具體實施與光源類型有關:

  1. 對于方向光如太陽光而言,通常是采用陰影mask方式來實現(xiàn)的(上圖中左邊的小圖)。
    1. 所謂的陰影mask實際上是一種對陰影occlusion數(shù)據進行累加計算的特殊RT
    2. 在實際的著色計算之前,陰影mask會將多種陰影計算結果(如VSM,per-object shadows以及clouds shadows等)按照從上到下的方式組織起來
  2. 對于點光而言,其陰影將不需要進行這么復雜的中間過程,而是直接渲染到light buffer中(上圖中右邊的小圖)。

CSM是最常見的陰影實現(xiàn)方式了,將view frustum按照距離遠近分割成多個有輕微重疊的shadow frustum,之后為每個shadow frustum分配一張陰影貼圖,從而得到由多個陰影cascade組成的陰影貼圖組。

這里介紹了cascade的一些屬性:

  1. 各級陰影貼圖像素密度基本上呈對數(shù)分布(如果各級陰影貼圖分辨率相同的話,那么其覆蓋的范圍將呈對數(shù)分布);
  2. 相鄰兩級陰影frustum需要有輕微重疊,避免區(qū)域遺漏
  3. 陰影frustum的朝向是固定的,因為光源方向是不變的

不論是點光陰影,還是CSM,都是以一種延遲渲染的方式得到。

以CSM為例,通過對frustum volume的繪制,會在各級shadow map對應的stencil上添加標記,標記出相機可見的像素,也就是陰影接收像素的范圍,這樣做的好處是:

  1. 可以使得cascade劃分更為合理
  2. 可以在屏幕空間像素被多個cascade覆蓋時,挑選出最高分辨率shadow map對應的cascade
  3. 可以提高陰影貼圖空間的利用率

當光照方向恒定時,其實不需要每幀都進行全量陰影繪制,只需要對超出相機邊界的區(qū)域以及動態(tài)物件進行陰影貼圖更新即可,而一些遠距離cascade則可以考慮分幀更新;對于最后一級陰影貼圖而言,其對應的都是一些遠距離物體,可以考慮使用VSM算法(由于距離較遠,因而不需要考慮VSM導致的漏光問題)與shadow mask相結合的方法來得到一個大尺寸的軟影效果。

點光陰影通常是采用將點光所覆蓋的球體拆分成類似cubemap的六個2D區(qū)域,每個cube face對應于一張shadow map的方式計算得到。

每個cube face對應的陰影貼圖的scale數(shù)值是不一樣的:

  1. scale是基于陰影覆蓋范圍計算得到的
  2. 實際上,最終的scale數(shù)值實際上是陰影貼圖密度分布函數(shù)的對數(shù)表示,這個函數(shù)會使用陰影覆蓋范圍作為參數(shù)

對于一些覆蓋范圍實在太大的cube face,還可以考慮CSM。

在shadow map scaling完成后,可以考慮將多張shadow map組合到一張texture atlas上面,避免進行多次shadow map綁定,也有利于降低陰影計算的DP數(shù)。

同樣,對于每個陰影貼圖而言,依然需要如前面CSM所說的,先用view frustum繪制對stencil進行標志以縮小有效陰影貼圖的區(qū)域,降低陰影繪制的消耗。

CSM以及點光陰影對于一些大尺寸的幾何數(shù)據的陰影有很好的展示效果,但是對于一些小尺寸的幾何細節(jié),其計算得到的陰影效果可能比較差。因此,對于一些需要展示其精細陰影細節(jié)的模型比如FPS中的槍械以及一些展館場景中的物件而言,其常用的實現(xiàn)方式為per-object shadow。

per-object shadow是指為特定物件單獨制作一張高分辨率的陰影貼圖,最終會通過max()算子對全局陰影貼圖與per-object陰影貼圖進行混合,并將結果輸出到shadow mask中。

而為了消除低分辨率全局陰影貼圖(CSM,點光陰影)導致的自陰影噪聲,可以考慮為存在per-object shadow的物體使用一個大數(shù)值的bias(用在繪制全局陰影貼圖時)。

  1. 雖然低分辨率全局陰影貼圖依然會考慮物件投射的陰影,但是大的bias數(shù)值,會過濾掉其self shadow
  2. self shadow主要來自于高分辨率的per-object shadow

下面介紹下軟陰影的實現(xiàn)方式。

crytek engine的軟影是通過PCF + 樣本陰影空間隨機旋轉的方式實現(xiàn)的。

在運行時調整PCF的采樣半徑可以為不同區(qū)域制定不同程度的軟影效果,這種方式可以得到很好的軟影效果。

crytek引擎軟影的基本思想:根據當前采樣點到陰影caster之間的距離比例來調整當前位置陰影的軟化效果(與原始的PCF想法類似)。

軟影算法實現(xiàn):

  1. 基于泊松分布的采樣點會提前根據到中心點的距離進行排序
  2. 初始的filter半徑是根據最大軟影范圍計算出來的
  3. 根據初始的filter半徑,計算出平均距離比例(average distance ratio)
  4. 最終所使用的的采樣點數(shù)目與平均距離比例是成正比的
    1. 由于采樣點已經提前計算并排序完成了,那么減少采樣點數(shù)目,就會同步縮小filter半徑
  5. 根據前面計算得到的采樣點數(shù)目計算最終的陰影值

CSM需要為每一級陰影提供單獨的filter調整機制,一方面可以兼顧不同cascade的陰影質量,另一方面也需要保證兩級陰影之間能夠平滑過渡

PCF可以交給computer shader來實現(xiàn),在這個過程中,可以將所有的預結算的采樣點放到CS的共享存儲空間,不論是filter距離計算還是后面的陰影數(shù)值計算,都可以重用。

crytek engine的面光源陰影是通過voxel-based的方法實現(xiàn)的。

整個場景會被轉換成具有不同分辨率的uniform voxel數(shù)據:

  1. 能夠實現(xiàn)大尺寸volume高效遮擋計算
  2. 能夠為ray traversal進行分辨率自適應調整
  3. 可以考慮根據距離將場景分割成多個cascade來進行處理

需要實現(xiàn)對動態(tài)場景的體素化(voxelization)與下采樣(這里說的下采樣是對于directional occlusion數(shù)值的下采樣)

下采樣算法自適應:

  1. 避免每幀對場景中的靜態(tài)數(shù)據進行更新處理
  2. 通過將bit-mask與前一幀bit-mask數(shù)據進行XOR(異或),根據bit位變動來決定是否需要進行下采樣

場景體素化結果

directional occlusion下采樣計算方法

體素數(shù)據下采樣結果

面光源陰影可以通過cone tracing計算得到,從當前點朝著面光源所覆蓋區(qū)域發(fā)射若干射線,通過統(tǒng)計這些射線中無阻擋比例即可得到當前點被光源點亮的程度。

通過cone tracing來計算遮擋射線數(shù)目的消耗通常比較高,這里給出一種近似的算法,那就是沿著從當前采樣點P到光源位置的方向,分層次采集當前層次的遮擋面積占比,最終取遮擋面積比例最高的一層作為最終的陰影輸出數(shù)值。

不過這個算法可能會存在誤差,如上面兩張圖中的兩種情況,其實都會導致計算結果不精確。

這里給出面光源陰影計算的效果與時間消耗,從性能消耗上來看還是挺讓人震撼的。

此外,通過對8個均勻分布的圓錐進行如前面所說的voxel-based cone tracing采樣,還可以得到世界空間中的Ambient Occlusion效果(要比SSAO效果更為逼真)

對于陰影與透明物體的作用,可以分成如下兩種情況進行考慮:

  1. 對于半透的陰影接收者而言:可以在前向渲染pass中通過shadow map計算出對應像素的陰影數(shù)值
  2. 對于半透陰影投影者而言(比如煙,霧等):會需要沿著光照方向累計對應的shadow map像素上的alpha數(shù)值,并將之存儲在一個與shadow map同分辨率的8bit貼圖(稱之為半透貼圖)中

這里給出了透明投影物的半透貼圖生成算法:

  1. 半透貼圖像素的寫入需要先對不透明物體生成陰影貼圖所對應的depth進行深度測試,不通過的可以跳過后續(xù)步驟
  2. 對于那些不處于半透陰影之中的陰影貼圖像素進行alpha累計(這個應該在上一步中就被深度測試所拒絕了)
  3. 需要添加一個alpha blend pass來對此前累計的alpha數(shù)值(需要保證順序是從后往前)進行累加
  4. 對于CSM,應該要為每級陰影增加一張半透貼圖
  5. 最終輸出的陰影數(shù)值需要同時考慮到陰影貼圖的遮擋關系與半透貼圖的alpha數(shù)值,最終輸出結果以二者陰影中較大的為準

對于所有的光源+環(huán)境光(ambient),都會通過SSDO方法(可以看成是SSAO的加強版)計算出contact shadows。

SSDO的核心思想:

  1. 通過計算出來的屏幕空間occlusion對光照結果進行調制
  2. 可以實現(xiàn)軟影效果
  3. 同時可以移除由于shadow map bias過大導致的peterpan現(xiàn)象(陰影細節(jié)通過SSDO得到)
  4. 其實施效果要優(yōu)于SSAO(相對于SSAO,考慮了輸入光源的光照方向)

directional occlusion(DO)信息可以通過一種延遲的方式獲?。ㄆ聊豢臻g):

  1. 跟當前的光照管線能夠很好的匹配起來
  2. 由于實現(xiàn)高效,能夠適應多光源的應用場景

遮擋信息計算:

  1. 在SSAO計算的過程中,同步存儲bent normal N^`,這個法線指的是每個像素的平均未遮擋方向
  2. 這里需要剔除self-occlusion(為什么要剔除這一項?)之后的干凈SSAO計算過程,且需要使用一個相對較大的處理半徑(半徑過小,遮擋效果看不到)

對于每個光源:

  1. 先計算cos\theta_1 = dot(N ,L)
  2. 再計算cos\theta_2 = dot(N^`, L)
  3. 中心位置的采樣點depth是全分辨率的,而其他采樣點則是FP16的半分辨率depth(啥意思)
  4. 將occlusion比例(這個應該是SSAO的輸出結果)乘以clamp(abs(cos\theta_1 - cos\theta_2), 0, 1)(這一項大概是用來表示當前點所在的平面受周圍像素遮擋影響的幅度。也就是Directional Occlusion中的Direction部分)得到的結果用于對光照數(shù)據進行attenuate處理。

屏幕空間自陰影實現(xiàn)方法使用了一個小小的trick來實現(xiàn)近似模擬:

  1. 沿著屏幕空間中光照向量的方向進行ray casting計算
  2. 指定受影響的depth buffer的范圍
  3. 射線長度追蹤還可以用于計算輸出一定的軟影效果

體積霧效果實現(xiàn)算法是以Real-time Volumetric Lighting in Participating Media(TOTH09)為基礎實現(xiàn)的,不同的是,這里不再是對in-scattering light進行累加,而是沿著視線射線對陰影貢獻值(shadow contribution,大概就是射線上每一點是否處于光照中的意思吧)進行累加。

這里給出實施細節(jié):

  1. 與原算法一樣,也是在光源空間也就是shadow space中進行
  2. 依然采用interleaved sampling算法來降低渲染消耗
    1. 每個pixel block包含8x8個相鄰屏幕空間像素
    2. pixel block上的所有采樣點在射線上的位置是均勻分布的
    3. 為了進一步降低渲染消耗,將累加過程輸出RT分辨率降為屏幕Native Resolution的一半(1/2 * 1/2)
  3. 最終輸出的shadow數(shù)值還需要通過一個gather pass對pixel block中的shadow contribution進行累加得到
    1. 通過雙邊線性濾波算法消除物件或者相機移動帶來的重影,以及采樣過程中的孔洞
    2. shadow contribution存儲在一張8bit的depth貼圖中
    3. 最終輸出到屏幕空間上的結果,會采集周邊8個相鄰像素shadow depth數(shù)據與當前像素depth比對的結果通過加權平均作為輸出(類似PCF)
  4. 支持對最大采樣距離進行配置(150~200m)
  5. 最終輸出的結果還會將Cloud產生的陰影考慮進去
  6. 最終輸出的顏色結果需要考慮到fog height與徑向顏色數(shù)值。

這里給出了兩種上采樣算法的實施效果對比,可以看到雙邊濾波上采樣算法給出的結果更優(yōu),Naive Upscale算法會導致處于fog中的物體被模糊的瑕疵。

在CSM模式下體積霧算法的適配細節(jié):

  1. 射線從相機出發(fā),終點為屏幕空間像素對應的surface position,這個射線的投射過程全程放在shadow space中完成
  2. 對于射線上靠近相機近平面的位置,會給出更多的采樣點
  3. 多個shadow frustum以級聯(lián)的方式存在
  4. 相鄰shadow frustum應該要有一定的重疊區(qū)域,避免出現(xiàn)數(shù)據缺漏
  5. 在shadow frustum重疊區(qū)域,總是選擇分辨率較高的frustum數(shù)據進行計算
  6. 使用全局參數(shù)坐標來存儲當前射線與當前shadow frustum的交點位置(沒太明白這樣做的目的,可以在上一級frustum shadow終止之后判定是否需要進行下一級shadow frustum的ray marching)
  7. 不需要在多級shadow map中進行re-project
  8. 給出了一個優(yōu)化過的射線clip函數(shù),可以直接對全局的參數(shù)坐標進行修正,可以實現(xiàn)隨時ray marching終止。

下面來看下CSM算法中各級shadow frustum的在不同劃分模式下的表現(xiàn):

這里給出了隨CSM覆蓋范圍變化而變化的劃分結果,主要是兩組數(shù)據對比,第一組固定遠裁剪平面,第二組固定近裁剪平面。

這里給出的是第一組對比數(shù)據的圖形化展示,共6個劃分結果,橫坐標是劃分級別,縱坐標為劃分距離。

這里給出了CSM劃分的一些考慮要點:

  1. 需要考慮劃分后的cascade之間的重疊問題
    1. 對于靠近近平面的cascade,如果直接使用精確的對數(shù)劃分算法,會存在一定的困難(意思是重疊問題會比較明顯吧?)
    2. 因此,對于靠近近平面的cascade劃分,可以考慮人為調整
  2. 相機近平面距離以及FOV對于劃分的cascade表現(xiàn)有很重要的影響
    1. FOV越大,劃分后的shadow frustum的重疊區(qū)域就越大
    2. FOV越大,場景中不可見部分在陰影貼圖中的占比就越大,浪費就越嚴重(是這樣嗎?shadow frustum中超出view frustum的區(qū)域占比越高)
    3. 近平面距離相機越近,shadow frustum的重疊區(qū)域就越大(從前面的數(shù)據與圖表中很難直觀得出此結論,可能需要添加一個輔助公式進行說明)
  3. 對于有限的相機深度范圍,最終劃分得到的CSM box應該要盡可能的緊湊(啥意思?意思是盡可能的縮小shadow frustum的有效包裹范圍,比如剔除shadow frustum一前一后的空白區(qū)域,所謂的空白區(qū)域指的是在相機空間中沒有接受陰影物件的區(qū)域)

這里給出了縮小shadow frustum包裹范圍的效果對比,陰影質量有明顯的提高。

shadow frustum對齊方向有兩種策略,分別是與光照方向一致(light space)以及與相機視線方向一致(view space),下面看一下兩者的區(qū)別。

  1. 相機方向對齊策略(接受陰影的物件的區(qū)域無重疊,為了保證陰影結果的正確性,投影區(qū)域還是有重疊的):

    1. 陰影空間利用率更高(因為重疊率低了,所以利用率高了?)
    2. shadow frustum重疊率更低
    3. 陰影貼圖采樣密度更高(采樣密度如何計算?陰影貼圖有效分辨率與對應的屏幕空間對應的陰影覆蓋范圍的分辨率的比值?按照這個定義來說,是符合此說法的,畢竟重疊率低了,陰影貼圖上的所有像素基本上都是有效的)
    4. 在陰影貼圖under-sampling(陰影貼圖分辨率過低,導致屏幕空間采樣時而采到上一個像素,時而采到下一個像素)的時候,會使得陰影質量不穩(wěn)定(當相機旋轉移動的時候,會導致陰影鋸齒或者抖動現(xiàn)象)(這個問題light space alignment策略也會存在,可以通過修正shadow map投影矩陣,使之按照整像素進行更新來修復,不過如果這里是相機旋轉的話,那么這種修復方法可能不一定能生效)
    5. 由于投影區(qū)域的重疊,所以同一個物件可能會出現(xiàn)在多個shadow frustum中,因此繪制shadow map所需的消耗會更高
  2. 光照方向對齊策略(考慮到陰影是通過正交投影方式產生的,因此shadow frustum的形狀多為立方體,因此投影區(qū)域跟承影區(qū)域都是有重疊的。):

    1. 由于shadow frustum重疊范圍的增加,陰影空間利用率降低
    2. 可以更好的兼容CSM Caching策略
    3. 支持按照shadow map整像素更新投影矩陣,修正相機移動旋轉導致的閃爍

CSM中導致陰影鋸齒的原因分析:

  1. 陰影貼圖采樣密度過低(可以直觀理解為陰影貼圖有效分辨率過低)
  2. 陰影貼圖格式精度較低(depth bits過少,導致浮點數(shù)精度不足)
  3. 光照方向與視線方向接近平行(導致投影到shadow map上的物體在shadow space中的depth range過大,從而使得同樣的浮點數(shù)精度,每一位對應的分辨率下降,即實際表達的浮點數(shù)精度不足)

應對陰影鋸齒問題的多種策略:

  1. 對于太陽光陰影而言:物體的投影采用front face渲染,渲染過程中開啟slope bias
  2. 對于點光陰影而言:采用back face渲染(針對室內場景,比如墻壁之類的,對于室內的其他物體,應該還是要使用front face渲染的)
  3. 對于遠距離物體,可以考慮使用VSM來模擬軟影實現(xiàn)(相對于PCF而言,消耗更低,缺陷在于會存在light bleeding,不過如果物體距離較遠,這個現(xiàn)象就不太明顯了),為了進一步降低light bleeding,建議開啟雙面渲染

在延遲陰影pass中,通過constant bias來規(guī)避或者減弱陰影貼圖精度不足導致的鋸齒問題

CSM算法在業(yè)界使用中的一些現(xiàn)狀特點:

  1. 游戲中所使用的陰影貼圖大多采樣密度較低
  2. CSM劃分策略不夠合理
  3. 為了保證陰影質量,通常會使用一些渲染小trick,比如說整像素shadow map更新以及單物件陰影等
  4. 沒有一套普適性的自動調整策略,大多需要為每個場景進行單獨的shadow map配置

這里給出本文嘗試解決的一些問題或者說希望能夠達成的目標:

  1. 消除或者降低shadow frustum之間的重疊程度
  2. 移除或者減少shadow map中的無效像素
  3. 縮小陰影貼圖中哪些在相機視角中不可見的部分
  4. 希望能夠得到較高的陰影貼圖采樣密度,從而避免陰影貼圖整像素更新的trick的使用
  5. 希望達成場景中的所有區(qū)域的陰影貼圖采樣密度基本一致的目標,這樣有助于減弱陰影鋸齒的影響

傾斜投影(oblique projection)的定義:

  1. 這是平行投影的一種(正交投影也是平行投影,不過投影方向與投影平面垂直)
  2. 從三維物體上引出平行線,將平行線與投影平面相交,得到的結果就是傾斜投影
  3. 與正交投影不同的是,傾斜投影的平行線與投影平面不垂直

傾斜投影可以通過兩個角度參數(shù)來定義投影行為,這兩個角度參數(shù)與含義給出如下:

\alpha,指的是被投影點(x, y, z)與投影點(x_p, y_p, z_p)在xy平面上的投影點的連線(x, y, x_p, y_p)與投影平面之間的夾角

\lambda,指的是被投影點(x, y, z)與投影點(x_p, y_p, z_p)在xy平面上的投影點的連線(x, y, x_p, y_p)與x軸的夾角。

如果用L表示(x, y, x_p, y_p)的長度,L1 = L / z的話,那么傾斜投影的投影矩陣可以給出如上圖所示。

關于投影公式,這里有兩個疑點:

這個矩陣揭露的規(guī)律顯示,投影只跟\alpha有關而跟\lambda無關,這是第一個疑點 —— 實際上L的計算與\alpha有關,令L_{3d} = Distance(Vector(x, y, z), Vector(x_p, y_p, z_p)),那么有如下的計算公式:L_{3D} * cos(\alpha) = L。

根據投影矩陣可以得到:x_p = x + L*cos(\alpha), y_p = y + L*sin(\alpha),而實際上根據兩個角度的定義,正確的公式應該是:x_p = x + L*cos(\lambda), y_p = y + L*sin(\lambda),這是第二個疑點(猜測應該是書寫錯誤)

從這個定義來理解傾斜投影,可以將之理解成,xy存在一定的偏移,偏移量與投影方向的傾斜程度有關,實際上正交投影可以看成是一種特殊的傾斜投影,即投影方向與平面的法線方向重合,xy無偏移下的傾斜投影

在CSM中應用傾斜投影的具體做法:

  1. 使用前面定義的傾斜投影計算矩陣
  2. 將view frustum的裁剪平面(這里的裁剪平面并不僅僅是遠近裁剪平面,實際上應該包括上下左右前后共六個平面的裁剪平面)看成是傾斜投影的投影平面
  3. 從5個view frustum平面中選出當前cascade的投影平面(不考慮遠裁剪平面)
  4. 根據光照方向選擇陰影投影的傾斜投影平面
    1. 平面法線跟光照方向的點乘結果的符號相同的多個平面用作傾斜投影的平面(為了能夠完整覆蓋view frustum,需要選取多個view frustum平面作為傾斜投影平面,具體實例見下圖)

對于這樣的view frustum跟light direction而言,可以選取左裁剪平面,下裁剪平面以及近裁剪平面等三個裁剪平面用作shadow frustum的傾斜投影平面。

傾斜投影實現(xiàn)細節(jié):

  1. 根據對數(shù)分布,將投影平面分割成不同的plane segment(細分平面)
    1. 每個plane segment對應于一個shadow map cascade
  2. 各個plane segment對應的shadow map分辨率相同,且距離(相機原點)越遠的segment覆蓋的范圍越大
  3. 在CPU上使用一系列的傾斜frustum完成對投影物件的culling處理

按照這三個傾斜投影平面,可以將整個view frustum分割成L4+B4+N1等9個plane segments,也就對應于9個shadow cascade,其中8個(L4,B4)shadow frustum傾斜投影平面是梯形的,1個(N1)shadow frustum傾斜投影平面是長方形的。

下面看下?lián)Q個光照方向下的plane segments劃分:

在這種情況下,view frustum的裁剪平面并不能當成是shadow frustum的遠裁剪平面,因此還需沿著光照方向繼續(xù)向前延伸到更遠的位置(比如延伸到view frustum的遠裁剪平面等),以保證view frustum中的相關物件的投影表現(xiàn)是正常的。

前面說過,部分plane segments的投影平面形狀是梯形的,部分是長方形的,這里就有兩種shadow map規(guī)劃策略:

將投影平面形狀以長邊為準,擴展成長方形(如下圖所示),有如下的一些特點

  1. 需要較多的plane segments才能得到對數(shù)劃分CSM效果的近似模擬(啥意思?)
  2. 因為增加了不可見區(qū)域在shadow map上的占比,會導致shadow map的浪費

使用view camera透視變換方式將梯形適配到矩形shadow map中

  1. 通過對相機的近裁剪平面進行shift & expansion(相當于將近平面形狀拉伸成與遠平面形狀一致,使得原有的透視投影轉變成正交投影?),實現(xiàn)適配
  2. 不會導致shadow map的浪費
  3. 在shadow map采樣密度足夠高的情況下,也不會因為相機的移動與旋轉而導致陰影的抖動

plane segments的劃分按照對數(shù)規(guī)律實現(xiàn)。

下面看下傾斜投影實施過程的示意圖:

這里將一個茶壺通過傾斜投影的方式投影到了多個plane segments上

之后在渲染場景物件的時候,根據當前物件所對應的plane segments,取用不同的shadow map來進行陰影的計算與繪制。

移除掉不相關的plane segments之后,展示效果如上圖所示。

這里給出的是選擇的另外一種plane segments時的傾斜投影效果展示。

傾斜投影shadow map實施的一些特點:

  1. 所有的shadow map能夠完整的覆蓋整個view frustum空間
  2. 投影到shadow map上的相機不可見區(qū)域較小,因此shadow map的浪費也相應得到降低
  3. shadow cascade之間的重疊率大大降低,進一步縮小了shadow map的浪費
  4. 由于每個投影物體都被投影到了最為合適的shadow map上,因此對應shadow map上的采樣密度將得到保證,足以消除此前因為采樣密度不足導致的陰影鋸齒問題
  5. 不論光照方向如何,都能保證接近于常數(shù)的shadow map的采樣密度(此前在光照方向與視線方向接近一致的時候,會因為shadow volume尺寸交到而使得采樣密度不足,從而引發(fā)鋸齒問題,而在這種情況下,通過傾斜投影,shadow volume的尺寸并不會存在太大的差異,使得采樣密度能夠得到很好的保證),從而降低因此導致的鋸齒問題。

下面看下傾斜投影方案的一些實施細節(jié),分為陰影貼圖繪制階段與陰影貼圖采樣渲染階段兩塊:

陰影貼圖繪制:

  1. 每個plane segment都是單獨處理,與其他plane segments不構成耦合關系
  2. 在必要的時候,會通過GS對那些同時處于多個plane segments覆蓋范圍的面片進行復制處理(從而實現(xiàn),一遍繪制,多個shadow map輸出,避免DP增加?)
  3. 根據view space中的Z坐標在view frustum plane中選擇對應的plane segment

陰影貼圖采樣使用,根據渲染方式的不同,有不同的用法。

在延遲陰影繪制中:

  1. 根據當前像素所處的位置,采取對應的傾斜投影shadow map
  2. 由于shadow map之間不存在重疊,因此不再需要通過stencil來對屏幕像素進行標記
  3. 使用texture array來實現(xiàn)多張shadow map之間的組織

在前向陰影繪制中,直接根據當前被繪制物體表面上的像素所對應的shadow segment區(qū)域采取對應的shadow map進行繪制即可。

在Clustered前向/延遲著色管線中:

  1. shadow frustum依然沒有重疊
  2. 依據cluster與shadow map之間的一一對應關系進行采樣處理即可

傾斜投影相對于傳統(tǒng)CSM的一些優(yōu)勢:

  1. 貼圖利用率更高
  2. 陰影鋸齒問題得到更好的抑制
  3. 陰影貼圖采樣密度得到很好的保障
  4. 如果陰影貼圖分辨率足夠高的話,可以做到完全消除陰影鋸齒問題

下面給出一些實施效果圖展示:

這里給出本文的內容回顧。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容