- Shadow Ray 概述
-
Distance Field Soft Shadows(DFSS)
- 計(jì)算安全角度
- DFSS 算法過(guò)程
-
Contact Shadows
- Shadow Map Space Contact Hardening Shadows [2023]
-
其它常見(jiàn) Ray Tracing
- Height Field Ray Tracing
- Voxel Cone Tracing
- SDF Tracing
- Hardware Ray Tracing
-
Hybrid Frustum-Traced Shadows(HFTS)[2016]
- Irregular Z-Buffer(IZB)Pass
- Frustum Tracing Pass
- Shadow Map Z-Prepass
- Hybrid
-
Shadow Volumes 概述
- Point in Polygon Strategies
- Z-Fail
- CC Shadow Volumes [2004]
- 是否過(guò)時(shí)?
-
總結(jié) & 思考 & 改進(jìn) [TODO]
- 結(jié)合 VSM 和 Shadow Volumes
- 結(jié)合 Shadow Map 和 Shadow Ray
- 結(jié)合 Precomputed Shadow Map 和 Occlusion Culling
- 更多...
- 參考
Shadow Ray 概述
shadow mapping 系列技術(shù)(PCF、PCSS、VSSM 等)的原理在于從光源發(fā)出 ray(通過(guò)光柵化方式實(shí)現(xiàn))來(lái)記錄最近的物體深度,并將與 shading point 的深度比大小來(lái)判定 shading point 是否被遮蔽;而 shadow ray 思路恰好相反,但更直觀:從 shading point 出發(fā)向光源發(fā)射 ray 來(lái)檢測(cè) shading point 是否被遮蔽。
兩種方式各有利弊,前者的主要缺陷在于記錄的 shadow map 分辨率是有限的,容易精度不夠;后者的主要缺陷在于 ray tracing 的開(kāi)銷可能會(huì)很大。當(dāng)然,在一些工業(yè)界方法也存在結(jié)合兩種方式的混合方法。本文將主要講解 shadow ray 相關(guān)技術(shù),并適當(dāng)擴(kuò)展一些。
Distance Field Soft Shadows(DFSS)
DFSS 是一種依賴 SDF 的 shadow ray 技術(shù),它將點(diǎn) \(o\)(Shading Point)與光源面中心點(diǎn) \(p_{light}\) 相連形成一條方向?yàn)?\(l\) 的中心線段,而這條中心線上各個(gè)點(diǎn) \(p_i\) 都可以通過(guò) SDF 查得與其最近幾何物體的距離并且推算出安全角度(點(diǎn)\(o\) 能打到光源面的直線與中心線的最大夾角)為 \(\theta_i = arcsin \frac{\operatorname{SDF}(p_i)}{p_i-o}\)
那么所有這些點(diǎn)中對(duì)應(yīng)的安全角度之中取最小的安全角度 \(\theta = min\{\theta_i\}\) ,這個(gè)安全角度與最大角度的比例決定了光源面的光照覆蓋率,也就決定了點(diǎn) \(o\) 的Visibility。
使用 Distance Field Soft Shadows 的好處很多:
- 計(jì)算陰影很快(假設(shè)已經(jīng)生成了SDF的情況下,比傳統(tǒng)Shadow Mapping類技術(shù)是要快的多)
- 陰影質(zhì)量很高,而且完美解決 Shadow Ance / Peter Panning / 采樣噪聲等傳統(tǒng)Shadow Mapping會(huì)出現(xiàn)的問(wèn)題
然而代價(jià)是:
- SDF 需要預(yù)計(jì)算,這就意味著場(chǎng)景物體需要是靜態(tài)的,當(dāng)然也可以使用一些算法使能和動(dòng)態(tài)物體相結(jié)合,盡量減少重新生成SDF的成本。
- SDF 需要較大的存儲(chǔ)空間(一般采用三維數(shù)組表示空間各個(gè)網(wǎng)格的SDF值,但是可以使用八叉樹(shù)等空間數(shù)據(jù)結(jié)構(gòu)或者其它方法做進(jìn)一步優(yōu)化)。
- 仍可能會(huì)導(dǎo)致錯(cuò)誤的陰影效果:不能把安全角度與最大角度的比例簡(jiǎn)單地當(dāng)成是光照覆蓋率,例如一條細(xì)長(zhǎng)的線碰到了 marching 路徑從而導(dǎo)致安全角度為 0,但此時(shí)不能認(rèn)為 shading point 沒(méi)有光照(因?yàn)橐粭l細(xì)線只是占了一點(diǎn)點(diǎn)光照面積)。
計(jì)算安全角度
計(jì)算某個(gè)點(diǎn) \(p_i\) 的安全角度時(shí),直觀的幾何關(guān)系便是:
而在實(shí)踐中,往往會(huì)使用:
這樣的近似公式實(shí)際效果相當(dāng)接近原幾何關(guān)系,而且也能減少?gòu)?fù)雜的 arcsin 運(yùn)算開(kāi)銷,最后它還能通過(guò) \(k\) 這個(gè)參數(shù)來(lái)調(diào)整陰影的硬軟程度。
如下圖分別為 \(k=32\) 、\(k=8\)、\(k=2\) 的效果:
DFSS 算法過(guò)程
具體算法過(guò)程:
-
將 \(o\) 點(diǎn)(shading point)設(shè)為第一個(gè)步進(jìn)點(diǎn),即 \(p_0 = o\)
-
每次算出下一個(gè)步進(jìn)點(diǎn) \(p_{i+1} = p_{i} + l \cdot SDF(p_{i})\) 并記錄安全角度 \(\theta_i = \min \left\{\frac{k \cdot \operatorname{SDF}(p_i)}{p_i-o}, 1.0\right\}\)
-
重復(fù) "步驟2",直到滿足 \(l \cdot (p_{i+1}-p_{light}) < 0\) (即意味著已經(jīng)步進(jìn)到光源點(diǎn)背面了)
-
取所有次步進(jìn)的最小安全角度 \(\theta = min\{\theta_i\}\) ,則可見(jiàn)度則為 \(Visibility = \frac{\theta}{c}\) (其中 \(c\) 為點(diǎn) \(o\) 與光源面連接的最大角度)
Contact Shadows
contact shadows,其實(shí)就是利用 SSRT(screen space ray tracing)技術(shù)來(lái)實(shí)現(xiàn) shadow ray,不過(guò)在具體的 marching 實(shí)現(xiàn)上它往往采用大步走的 linear marching 而非基于 hi-z 的 marching,其效果如下圖:
- contact shadows 往往是一種補(bǔ)充高精度陰影的手段:因?yàn)槠聊恍畔⑹怯邢薜?,它不能承?dān)完全的陰影效果職責(zé)。
例如主流的搭配方式是 shadow map + contact shadows:shadow map 因?yàn)槠潢幱吧疃确直媛视邢蓿陔x攝像機(jī)近的物體上呈現(xiàn)的陰影效果往往是大顆鋸齒狀,此時(shí)利用 contact shadow 可以補(bǔ)充 pixel 粒度(高精度)的陰影效果。
- 大步 linear marching 相比基于 hi-z 的方法,在性能上往往更好但效果可能不那么精確。但是因?yàn)?shadow ray 是不需要知道精確的 hit point,而只需要知道是否相交了,因此常用于 contact shadow。
Shadow Map Space Contact Hardening Shadows [2023]
來(lái)自GDC2023《戰(zhàn)神:諸神黃昏》Santa Monica Studio 的分享。
傳統(tǒng) PCSS 是一種實(shí)現(xiàn)軟陰影的 trick,真正 ground truth 的軟陰影效果應(yīng)當(dāng)是對(duì)整個(gè)光源面積進(jìn)行采樣,而非用固定單個(gè)樣本點(diǎn)來(lái)計(jì)算(shadow map 就是從光源中心點(diǎn)來(lái)生成的,只考慮了單個(gè)點(diǎn)的 visibility 關(guān)系)。因此要實(shí)現(xiàn)接近 ground truth 的軟陰影最好使用方便在光源面積上采樣的 shadow ray 技術(shù)。
在古早的 paper 中,也有人嘗試過(guò)生成多個(gè) shadow map(相當(dāng)于光源面積上的幾個(gè)樣本點(diǎn)),但是很容易想象到其性能開(kāi)銷有多爆炸。
Santa Monica Studio 采用了 shadow map space 的 ray marching 技術(shù)來(lái)實(shí)現(xiàn) shadow ray,但稍微不同的是每次 marching 后,并不是簡(jiǎn)單的直接根據(jù)和 shadow depth 比大小的結(jié)果來(lái)判斷是否被遮蔽,而是:
- shading point 的 z 值和 marching 后對(duì)應(yīng)的 shadow depth 比大小的結(jié)果記為 \(b_{s}\)
- marching 后的 z 值和 marching 后對(duì)應(yīng)的 shadow depth 比大小的結(jié)果記為 \(b_{m}\)
- 只有 \(b_s \neq b_m\) 時(shí)才視為該次 marching 被遮蔽。
如下圖,左邊和中心兩條 shadow ray 都在 marching 過(guò)程中出現(xiàn)遮蔽情況,而右邊 shadow ray 怎沒(méi)有被遮蔽。
這種遮蔽判斷方法,在比較多細(xì)物體(如繩子、樹(shù)葉)的情況下可以更加 ground truth 的表示軟陰影。
其它常見(jiàn) Ray Tracing
暫時(shí)不展開(kāi),具體可見(jiàn)博主以前的 ray casting 博客。
Height Field Ray Tracing
利用 height field ray tracing 技術(shù)來(lái)實(shí)現(xiàn) shadow ray。
- 依賴高度場(chǎng)信息:一般是地形
- marching 方式:與 contact shadow 類似,大步 linear
Voxel Cone Tracing
SDF Tracing
Hardware Ray Tracing
Hybrid Frustum-Traced Shadows(HFTS)[2016]
該方法被應(yīng)用于育碧的《全境封鎖》游戲中。
Irregular Z-Buffer(IZB)Pass
傳統(tǒng) shadow map 方法中,pixels 和 ligth space(其實(shí)就是 shadow map 空間)texels 的對(duì)應(yīng)關(guān)系往往不是平衡的:可能會(huì)多個(gè) pixels 映射到同一個(gè) light space 的 texel 中,從而造成采樣率不夠的現(xiàn)象。
最直觀的做法就是增大 shadow map 分辨率以讓每個(gè) light space texel 被盡可能少的 pixel 所映射,當(dāng)然這種通過(guò)增加分辨率來(lái)無(wú)腦增加采樣數(shù)的做法肯定是不可取的。而在 frustum-traced shadows 方案中,將會(huì)利用 IZB 來(lái)讓每個(gè) light space texel 都擁有自己的 pixels list,并通過(guò)后續(xù)的 frustum tracing 遍歷列表來(lái)增加采樣數(shù),實(shí)現(xiàn)高質(zhì)量陰影。
首先,我們有一張屏幕空間的 list node map + light space 的 list head map。
- list head map 需初始化每個(gè) texel 值為 null 標(biāo)記。
IZB Pass 所做的便是進(jìn)行一次 full-screen pass,該 pass 需要依賴 depth buffer 的輸入:
- 將 pixel 變換到 light space 后會(huì)對(duì)應(yīng)某個(gè) light space texel,然后當(dāng)前 pixel 位置與該 light space texel 中的內(nèi)容進(jìn)行原子交換操作,交換后得到的值實(shí)際相當(dāng)于 next node(可能是 null 標(biāo)記,也可能是別的 pixel 位置)。
- 將本 pixel 得到的 next node 值寫(xiě)入到 list node map。
當(dāng)生成了 IZB 后,相當(dāng)于知道了 light space 每個(gè) texel 對(duì)應(yīng)有哪幾個(gè) pixels。
Frustum Tracing Pass
不過(guò)這里需要強(qiáng)調(diào),pixel 在世界空間中的實(shí)際形式是 quad。我們?nèi)ビ?jì)算 pixel 的 shadow factor 實(shí)際上就相當(dāng)于在進(jìn)行 frustum tracing:pixel quad 有多少面積比例被 casters 遮擋(更具體地,一般是在 quad 上放置有限的樣本點(diǎn),測(cè)試有多少樣本點(diǎn)被遮擋)。
首先,我們有一張屏幕空間的 visibility mask texture 來(lái)表示每個(gè) pixel 的 visibility。
Frustum Tracing Pass 所做的便是在 light space 下對(duì)所有 casters 進(jìn)行保守光柵化(conservative rasterization),然后在 fragment shader 中遍歷對(duì)應(yīng)的 pixels list,依次對(duì)每個(gè) pixel quad:
- 進(jìn)行 frustum-triangle test,這個(gè)操作比較費(fèi)計(jì)算量,因此 paper 采用了如下實(shí)現(xiàn):
- 每個(gè)三角形的邊投影到 quad 上,并將投影后的邊(已經(jīng)變成了2D向量)扔去 LUT 查表直接得到 quad 上各個(gè)樣本點(diǎn)的可見(jiàn)性。
- 將通過(guò)測(cè)試的樣本結(jié)果利用原子OR操作寫(xiě)入到 visibility mask texture 對(duì)應(yīng)的 pixel 位置。
通過(guò) frustum tracing pass,我們就有了一張屏幕空間的 visibility mask texture(來(lái)決定每個(gè) pixel 的 visibility)。
甚至可以在后續(xù)計(jì)算直接光照時(shí)啟用 early stencil test 來(lái)剔除掉不必要計(jì)算直接光照的 pixels。
Shadow Map Z-Prepass
但是可以想到, frustum tracing pass 的計(jì)算復(fù)雜度是 casters 所產(chǎn)生的 light space fragments 數(shù)量乘上單個(gè) list 里 pixel quads 的數(shù)量。
- 為了避免過(guò)多的 fragments,作者建議應(yīng)當(dāng)在 Frustum Tracing Pass 之前 先進(jìn)行一個(gè) Shadow Map Z-Prepass(這個(gè)實(shí)際上和正常的 shadow map depth pass 沒(méi)啥區(qū)別,也不需要保守光柵化)
- 通過(guò) shadow map z-prepass 先繪制一遍深度后,后續(xù)的 frustum tracing pass 就可以開(kāi)啟 early-z 剔除掉大量 fragments。這樣計(jì)算復(fù)雜度就變成了 light space pixels 數(shù)量乘單個(gè) list 里 pixel quads 的數(shù)量。
Hybrid
- Frustum-traced IZB 雖然效果準(zhǔn)確,但是只能提供硬陰影效果。
- 而 HFTS 實(shí)際上就是根據(jù)與的 occluder 距離,來(lái)混合 Frustum-traced IZB 和 PCSS 的結(jié)果。
- Frustum-traced IZB 開(kāi)銷較為昂貴,因此在 frustum tracing pass 中最好只處理部分重要的 casters 而非所有 casters。
Shadow Volumes 概述
實(shí)際上,除了 shadow map 和 shadow ray 兩大類方法,還有第三類更古老的方法:shadow volumes。其算法核心在于為計(jì)算出每個(gè) caster 所遮擋的體積(陰影體積),在判定 shading point 是否被遮擋時(shí),實(shí)際上就是在計(jì)算 shading point 是否在 shadow volumes 內(nèi)部(在內(nèi)則意味著被遮蔽,在外意味著沒(méi)有被遮蔽)。
Point in Polygon Strategies
為了判斷 shading point 是否在 volumes 內(nèi)部,實(shí)際上就是一個(gè) point in polygon 問(wèn)題(判斷點(diǎn)是否在一個(gè)多邊形內(nèi)部)。
而圖形學(xué)中一個(gè)最常用的算法是基于 ray casting,其思路是:作一射線從該點(diǎn)往任意方向投射,如果射線與多邊形邊的相交次數(shù)為奇數(shù),則點(diǎn)在多邊形之內(nèi);否則,點(diǎn)則在多邊形之外。
當(dāng)然針對(duì) point in polygon 問(wèn)題,還可以有其它算法(例如另一個(gè)更常見(jiàn)的算法則是 winding number)或者改進(jìn)策略(Point in Polygon Strategies (realtimerendering.com))。但是本文將主要介紹基于 ray casting 的 point in polygon 算法,這是因?yàn)轱@卡提供了光柵化硬件,利用光柵化與光線追蹤的對(duì)偶性,可以讓我們高效使用該算法:
將 shadow volumes 視為 mesh 并進(jìn)行兩次 draw(如圖所示),
- 第一次 draw 只繪制正面,并設(shè)置模板測(cè)試狀態(tài)為深度測(cè)試成功時(shí)將模板值+1(其實(shí)就是將深度測(cè)試通過(guò)的點(diǎn)視為相交點(diǎn),利用 stencil 來(lái)增加計(jì)數(shù))。
- 第二次 draw 只繪制背面,并設(shè)置模板測(cè)試狀態(tài)為深度測(cè)試成功時(shí)將模板值-1(因?yàn)橛布械哪0鍦y(cè)試不包含判斷奇數(shù)偶數(shù),因此這里使用了減法來(lái)抵消計(jì)數(shù))
這兩次 draw call 的 pixel shader 內(nèi)容均為空,因?yàn)橹皇菃渭冊(cè)诶蒙疃葴y(cè)試&模板測(cè)試硬件,無(wú)需寫(xiě)入別的東西。
最后得到的 stencil buffer 中,若模板值為 0 意味著該 pixel 不被遮蔽,若模板值為其他數(shù)值則意味著該 pixel 在陰影體積內(nèi)部。這樣就可以給后續(xù)的直接光照著色階段使用。
Z-Fail
然而上述 naive 光柵化方法是存在 failure case 的,即一旦 shadow volumes 與攝像機(jī)的 near plane 相交時(shí), 很可能會(huì)錯(cuò)誤地被光柵化硬件剔除了正面,從而導(dǎo)致 stencil 計(jì)數(shù)錯(cuò)誤。
如下圖所示,該點(diǎn)位于 shadow volumes 內(nèi)部,本應(yīng)該是被遮蔽的,卻因?yàn)樘蕹袅?volume 的正面,計(jì)數(shù)并沒(méi)有呈現(xiàn)出所期望的“1”。
z-fail 算法:其實(shí)只要稍微逆轉(zhuǎn)一下思維,我們將之前 naive 方法中的 “深度測(cè)試成功時(shí)” 統(tǒng)統(tǒng)換成 “深度測(cè)試失敗時(shí)”,將可以解決該問(wèn)題:深度測(cè)試失敗的點(diǎn)意味著射線是往遠(yuǎn)平面投去,并且因?yàn)檫h(yuǎn)平面往往設(shè)置在較遠(yuǎn)的位置,基本上 shadow volumes 是不會(huì)接近遠(yuǎn)平面的(更何談相交)。
該算法最早于 1998 至 2000 間被多人使用,而后 John Carmack 將其發(fā)揚(yáng)光大并集成于 Doom3 的引擎中,因此也被稱為 Carmack's Reverse 算法??ㄉ瘢质悄?.
CC Shadow Volumes [2004]
由于每個(gè)物體都會(huì)產(chǎn)生 shadow volume,在復(fù)雜場(chǎng)景下 shadow volume 的 draw call 次數(shù)會(huì)變得很多,并且每個(gè) volume 都可能生成大量的 fragments。我們初衷本來(lái)是想通過(guò) shadow volumes 的方式減少需要計(jì)算直接光照的 pixels 數(shù)量(減少 pixel shader 負(fù)載),但是卻為此大幅度增加了光柵化與深度&模板測(cè)試的負(fù)載(太多 fragments 生成了),這是非常不劃算的。
CC Shadow Volumes 旨在利用各種 culling/clamping 技巧來(lái)盡可能減少 volume 的體積,從而減少 fragments 數(shù)量的生成。
步驟:
-
一開(kāi)始,場(chǎng)景中的所有物體都是潛在的 caster 和 receiver。
-
Shadow Volume Culling【CPU 方法】
- receivers culling:在 eye space 下對(duì)所有 receivers 進(jìn)行視錐剔除和遮擋剔除。
- casters culling:在 light space 下對(duì)所有 casters 進(jìn)行遮擋剔除(相當(dāng)于剔除大 volume 里涵蓋的小 volumes)。
-
Continuous Shadow Clamping【CPU 方法】:在 light space 下,對(duì) shadow volume 建立 AABB,并找到與之相交的 receiver AABBs,并根據(jù)這些 receivers 的 zmin & zmax 來(lái)在 z 軸上對(duì)該 shadow volume 進(jìn)行切分。
-
Discrete Shadow Clamping【GPU 方法】:在 eye space 下,按 tile 劃分來(lái)切分成若干層 slice,slice 和一個(gè) shadow volume 的交集稱為 interval;在 light space 下按從底層到上層的順序繪制各層 slice 的 clipping planes;每繪制一層 slice,就利用硬件 occlusion query 來(lái)判斷是否有物體在 interval 之中,并在 CPU 獲取 occlusion query 結(jié)果(只要沒(méi)有 fragment 通過(guò)深度測(cè)試則意味著可以剔除本 empty interval)。
是否過(guò)時(shí)?
缺陷:
- CPU 壓力大:需要在 CPU 上構(gòu)造 shadow volume mesh。
- 性能可控性差:shadow map 開(kāi)銷與其分辨率相關(guān),比較固定;shadow volume 開(kāi)銷則與視角相關(guān),容易出現(xiàn)性能波動(dòng)。
- 光柵化與深度&模板測(cè)試的負(fù)載加重:見(jiàn) CC Shadow Volumes 開(kāi)頭分析。
- 只支持硬陰影。
雖然 shadow volume 有很多嚴(yán)重缺陷,但是這些都是基于整個(gè)場(chǎng)景都使用 shadow volume 的缺陷分析;在現(xiàn)代管線中,我們完全可以使用 hybrid 方法結(jié)合 shadow map,shadow ray 以及 shadow volume 的優(yōu)點(diǎn),這里就拋磚引玉部分想法:
- 如果光源和物體都不動(dòng),那么 shadow volume 沒(méi)必要每幀重新構(gòu)造。
- 只對(duì)大型遮擋物生成 shadow volumes,并將 shadow volume 中的 casters 剔除掉,減少 shadow map 的 draw call。
- shadow map 不善于處理半透明陰影,可以嘗試為半透明物體生成 shadow volume。
- shadow volume pass 和 shadow depth pass 一樣是光柵化負(fù)載和帶寬負(fù)載多(fragment shader 無(wú)內(nèi)容),可以與計(jì)算負(fù)載多的 compute shader pass 一起并行(async compute)。
- 現(xiàn)在 GPU driven pipeline 越來(lái)越流行,可以利用 compute shader 來(lái)構(gòu)造 shadow volume mesh 及 cluster culling,這樣會(huì)大大提升 shadow volume 的性能。
- shadow volume 在 per-object shadows 技術(shù)中得到應(yīng)用,詳見(jiàn)我博客里的實(shí)時(shí)陰影系列(1)Shadow Map。
- ...
總結(jié) & 思考 & 改進(jìn) [TODO]
real-time shadows 的技術(shù)有很多,能結(jié)合的角度也很多,當(dāng)自己需要針對(duì)項(xiàng)目制定 shadows 管線時(shí)可以盡情發(fā)揮自己的創(chuàng)造力和想象力,以下我就拋磚引玉一些可能的 idea(當(dāng)然僅供參考,不一定可行)。
結(jié)合 VSM 和 Shadow Volumes
由前面 virtual shadow map 的流程可知,減少 page 的訪問(wèn)就可以減少 page fault 的發(fā)生。
那么針對(duì)城市場(chǎng)景,我們可以:
- 為每個(gè)大型 caster(尤其是建筑)生成一個(gè)簡(jiǎn)化模型 proxy,并根據(jù) proxy 生成對(duì)應(yīng)的 shadow volume。
- 繪制 shadow volumes,對(duì)被 volume 覆蓋的 pixels 寫(xiě)入 mask。
- 再進(jìn)行一個(gè) full-screen pixel shader 來(lái)對(duì)剩下來(lái)未遮蔽的 pixels 提交對(duì)應(yīng)的 page 訪問(wèn)請(qǐng)求。
- ..
實(shí)際上就是利用 shadow volume 技術(shù)來(lái)避免相當(dāng)部分的全陰影區(qū)域生成 shadow map。
結(jié)合 Shadow Map 和 Shadow Ray
shadow map 分辨率/精度有限,可以利用更高精度的 shadow ray 來(lái)補(bǔ)充 shadows 細(xì)節(jié)。
我們可以通過(guò)一套類似流水線的流程去計(jì)算 shadows:
- 使用 shadow map 來(lái)進(jìn)行陰影測(cè)試:
- 若光源自帶 shadow map 且 shading point 在 map 范圍內(nèi)的,可以使用 shadow map 來(lái)進(jìn)行陰影測(cè)試:
- 若為陰影:結(jié)果視為陰影,終止流程。
- 若不為陰影(性能友好的做法):結(jié)果視為非陰影,終止流程。
- 若不為陰影(補(bǔ)充高精度陰影的做法):繼續(xù)轉(zhuǎn)入下一個(gè)流程。
- 若光源沒(méi)有 shadow map,亦或者 shading point 不在 shadow map 的范圍內(nèi),則直接轉(zhuǎn)入下一個(gè)流程。
- 若光源自帶 shadow map 且 shading point 在 map 范圍內(nèi)的,可以使用 shadow map 來(lái)進(jìn)行陰影測(cè)試:
- 使用性能開(kāi)銷低的 software ray tracing 技術(shù):
- 針對(duì)屏幕范圍內(nèi)的著色點(diǎn),可以嘗試進(jìn)行 screen space ray tracing/contact shadows,若命中則結(jié)果視為陰影,終止流程。
- 如果場(chǎng)景含有 height field,可以嘗試進(jìn)行 height field ray tracing,若命中則結(jié)果視為陰影,終止流程。
- 若未命中,則轉(zhuǎn)入下一個(gè)流程。
- 使用離屏的 ray tracing 技術(shù)來(lái)做最后的陰影測(cè)試(命中則結(jié)果視為陰影,否則為非陰影):
- 其它軟件光追。
- 硬件光追:ray query。
工業(yè)界常見(jiàn)的組合為:shadow map + contact shadows。當(dāng)然 shadow ray 技術(shù)還有很多種,完全可以根據(jù)自己需要進(jìn)行組合,甚至是 shadow map + 多種 shadow ray 技術(shù)的組合。
結(jié)合 Precomputed Shadow Map 和 Occlusion Culling
移動(dòng)端設(shè)備上可能對(duì) occlusion query 支持不是很好,往往都采用軟件光柵化的方式進(jìn)行 occlusion culling;而基于軟件光柵化的 occlusion culling 往往是先對(duì)重要的或大型的 casters 進(jìn)行光柵化,再對(duì)所有小型 casters 進(jìn)行光柵化,也就是兩輪光柵化。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-777038.html
然而既然都有了 precomputed shadow map,何不如加載場(chǎng)景是時(shí)讀取 precomputed shadow map 并生成一張對(duì)應(yīng)的 mipmap(只需加載時(shí)生成一次),將 mipmap 用于替代掉第一輪光柵化的結(jié)果?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-777038.html
更多...
參考
- [1] [GAMES202-高質(zhì)量實(shí)時(shí)渲染-閆令琪
- [2] Inigo Quilez :: Distance Field Soft Shadows (iquilezles.org)
- [3] Contact Shadows in Unreal Engine | Unreal Engine 5.3 Documentation
- [4] GDC 2023 | Rendering 'God of War Ragnarok'
- [5] 實(shí)時(shí)光線追蹤(3)Ray Casting - KillerAery - 博客園 (cnblogs.com)
- [6] GDC 2016 | NVIDIA | Advanced Geometrically Correct Shadows for Modern Game Engines
- [7] Symposium on I3D Graphics and Games 2015 | Frustum-Traced Raster Shadows: Revisiting Irregular Z-Buffers
- [8] Wm. Randolph Franklin, "PNPOLY - Point Inclusion in Polygon Test" (2000)
- [9] Joseph O'Rourke, "Point in Polygon" in Computational Geometry in C (2nd Edition) (1998)
- [10] Graphics Gems IV | Point in Polygon Strategies (realtimerendering.com)
- [11] Real-Time Rendering 4th Edition
- [12] EGSR2004 | CC Shadow Volumes
到了這里,關(guān)于實(shí)時(shí)陰影技術(shù)(2)Shadow Ray & Shadow Volume的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!