當(dāng)前的陰影技術(shù)
在過去十年中,實(shí)時(shí)渲染陰影的流行方法是使用陰影貼圖。這是場景從光源視角再次渲染到離屏深度緩沖區(qū)(稱為陰影貼圖)的地方,然后在著色過程中對(duì)陰影貼圖進(jìn)行采樣,以使用深度比較計(jì)算可見性。雖然這種方法已經(jīng)成功地應(yīng)用于許多應(yīng)用中,但它也有一些缺點(diǎn)。
最常見的問題是陰影鋸齒——這是在陰影貼圖的分辨率過低的地方,導(dǎo)致出現(xiàn)塊狀陰影。雖然可以通過使用更高分辨率的陰影貼圖來解決,但會(huì)增加內(nèi)存占用和帶寬利用率,可能會(huì)對(duì)性能產(chǎn)生負(fù)面影響,尤其是在移動(dòng)設(shè)備上。即使使用更高分辨率的陰影貼圖,某些微觀細(xì)節(jié)也很難保留,這要后續(xù)的屏幕空間陰影通道來細(xì)化。但是,在使用光線追蹤時(shí),可以在屏幕上為每個(gè)像素分配一條光線,這將產(chǎn)生像素完美的硬陰影。
光線追蹤管線
光線生成
當(dāng)在命令緩沖區(qū)調(diào)用 vkCmdTraceRaysKHR ,將為當(dāng)前綁定的光線追蹤流水線調(diào)用用戶定義的光線生成著色器。追蹤光線的命令允許開發(fā)人員為調(diào)度的線程設(shè)置各種參數(shù)。我們的演示是完全光線追蹤的,這意味著最好為屏幕上的每個(gè)像素分配一個(gè)光線生成著色器線程。
每次調(diào)用光線生成著色器都必須指定將主光線發(fā)射到場景中所需的變量。光線需要有原點(diǎn)(視點(diǎn))和行進(jìn)方向。可以通過將逆視圖矩陣應(yīng)用于(0,0,0,1)來計(jì)算原點(diǎn)。要計(jì)算方向,需要當(dāng)前像素的屏幕空間位置。可以使用 gl_LaunchIDEXT 從光線生成著色器查詢分派坐標(biāo)。使用此內(nèi)置擴(kuò)展,屏幕空間坐標(biāo)和光線方向可以按如下方式計(jì)算:
const vec2 pixelCenter = vec2(gl_LaunchIDEXT.xy) + vec2(0.5);const vec2 inUV = pixelCenter / vec2(gl_LaunchSizeEXT.xy);vec2 screenspace = inUV * 2.0 - 1.0;vec4 target = mInvProjectionMatrix * vec4(screenspace.xy, 1, 1);vec4 direction = mInvViewMatrix * vec4(normalize(target.xyz), 0);
從這里,我們可以使用 traceRayEXT 函數(shù)將主光線發(fā)射到場景中。然后,它將遍歷加速結(jié)構(gòu),在該結(jié)構(gòu)中,它將命中或錯(cuò)過場景中的幾何體,并調(diào)用相應(yīng)著色器組。執(zhí)行的著色器組將取決于其命中內(nèi)容,并將像素顏色存儲(chǔ)在有效負(fù)載結(jié)構(gòu)中。“未命中”著色器只是將光線的顏色設(shè)置為硬編碼的清除顏色。
命中組著色器
一旦光線與場景中的對(duì)象發(fā)生碰撞,就會(huì)執(zhí)行命中著色器。頂點(diǎn)緩沖區(qū)、索引緩沖區(qū)和材質(zhì)等模型數(shù)據(jù)都附著到“命中組”著色器。光線追蹤擴(kuò)展允許我們獲取命中對(duì)象的實(shí)例ID。在本演示中,每個(gè)模型都是唯一的,因此實(shí)例ID直接對(duì)應(yīng)于模型ID。模型ID可用于查找上述緩沖區(qū)。
// Since each object is unique in this scene, instance ID is enough to identify which buffers to look upuint objID = gl_InstanceID;// indices of the triangle we hitivec3 ind = ivec3(indices[nonuniformEXT(objID)].i[3 * gl_PrimitiveID + 0], //indices[nonuniformEXT(objID)].i[3 * gl_PrimitiveID + 1], //indices[nonuniformEXT(objID)].i[3 * gl_PrimitiveID + 2]); //// Vertices of the hit triangleVertex v0 = vertices[nonuniformEXT(objID)].v[ind.x];Vertex v1 = vertices[nonuniformEXT(objID)].v[ind.y];Vertex v2 = vertices[nonuniformEXT(objID)].v[ind.z];
gl_PrimitiveID可以用來告訴我們使用哪些索引來查找命中的頂點(diǎn),然后使用重心插值系數(shù)在它們之間進(jìn)行插值,該插值系數(shù)來自命中著色器中聲明為hitAttributeEXT類型的全局變量。然后,我們使用世界矩陣將插值頂點(diǎn)值轉(zhuǎn)換到世界空間,并旋轉(zhuǎn)法線值。
// Get the interpolation coefficientsconst vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);// Interpolate the position and normal vector for this rayvec4 modelNormal = vec4(v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z, 1.0);vec4 modelPos = vec4(v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z, 1.0);// Transform the position and normal vectors from model space to world spacemat4 worldTransform = transforms[nonuniformEXT(objID)];vec3 worldPos = (worldTransform * modelPos).xyz;// Don't translate the normal vector, only rotate and scalemat3 worldRotate = mat3(worldTransform[0].xyz, worldTransform[1].xyz, worldTransform[2].xyz);vec3 worldNormal = worldRotate * modelNormal.xyz;
使用擊中點(diǎn)的法線和世界位置,我們可以計(jì)算光線相對(duì)于場景中靜態(tài)光源的Phong照明分量。然后,我們使用一個(gè)新的命中和未命中組從該點(diǎn)向光源發(fā)射另一條光線。我們可以將次光線的最大長度設(shè)置為擊中點(diǎn)和光源之間的距離。如果光線在這個(gè)距離內(nèi)與加速度結(jié)構(gòu)中的任何物體碰撞,我們可以得出結(jié)論,在碰撞點(diǎn)和光源之間有一個(gè)物體,因此該點(diǎn)處于陰影中。如果次光線未擊中距離集內(nèi)的任何對(duì)象,則會(huì)執(zhí)行“未命中”著色器,我們可以假定該點(diǎn)不在陰影中。

在這個(gè)圖中,我們可以看到兩個(gè)例子。光線從視口(1)發(fā)射,第一條光線擊中點(diǎn)3,第二條光線發(fā)射,在到達(dá)光源的途中不會(huì)擊中任何幾何體。視點(diǎn)的第二條光線在點(diǎn)4處照射,但在到達(dá)光源的過程中,在點(diǎn)5處再次發(fā)生碰撞。因此,我們可以得出結(jié)論,點(diǎn)4在陰影中,但點(diǎn)3不在陰影中。
優(yōu)化
雖然光線追蹤陰影提供了比傳統(tǒng)方法更高的逼真度,但它們?nèi)匀徊煌耆昝馈R虼耍蛯?shí)時(shí)計(jì)算而言,光線追蹤算法需要更多的硬件,這是一個(gè)明顯的缺點(diǎn)。除此之外,還可以采取一些不同的優(yōu)化措施來改進(jìn)本文概述的技術(shù)。
陰影檢查
我們可以減少第一組用來檢查硬陰影的二次光線的數(shù)量;這是通過首先檢查已計(jì)算的Phong光照分量來完成的。如果由于曲面背向光源,光照分量已為0,則檢查硬陰影沒有意義,因?yàn)樵擖c(diǎn)已處于黑暗中。
這將光線預(yù)算從屏幕上像素?cái)?shù)的大約1.8倍減少到大約1.5倍。這顯然取決于場景和其中的對(duì)象,因?yàn)樗S未命中場景的主光線的比例以及通過或未通過陰影檢查的主光線的比例而變化。
混合渲染一般來說,光線追蹤核心將比傳統(tǒng)的光柵化流水線慢(至少目前是這樣)。有幾個(gè)可能的原因,但主要的原因是光線追蹤硬件仍然相對(duì)較新,因此與光柵化相比,GPU仍然沒有為其投入更多的空間。這意味著可以計(jì)算一個(gè)標(biāo)準(zhǔn)的G緩沖區(qū),并使用位置附件來定位從哪個(gè)位置發(fā)射陰影檢查光線。G緩沖區(qū)在《Vulkan中的環(huán)境遮擋》中有介紹,所以如果你還沒有看到,一定要看一看。簡而言之,G緩沖區(qū)可以替代主光線,從而產(chǎn)生更好的任務(wù)重疊和更小的光線預(yù)算。
結(jié)束
雖然完全光線追蹤的硬陰影在寫這篇博文的時(shí)候可能不是最佳解決方案,但它們?nèi)匀惶峁┝藗鹘y(tǒng)流水線難以模擬的細(xì)節(jié)和準(zhǔn)確性。一如既往,我們強(qiáng)烈建議大家看看PowerVR SDK及其代碼示例,以了解我們?nèi)绾螌?shí)現(xiàn)這些技術(shù)和實(shí)現(xiàn)這些算法的確切機(jī)制。我們也總是通過支持門戶或論壇發(fā)送電子郵件。
如果您有興趣了解更多關(guān)于各種圖形技術(shù)的信息,請(qǐng)查看我們的文檔網(wǎng)站,或者在SDK Github中探索我們的其他代碼示例。
原文標(biāo)題:Vulkan完全光線追蹤硬陰影
文章出處:【微信公眾號(hào):Imagination Tech】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
審核編輯:湯梓紅
-
代碼
+關(guān)注
關(guān)注
30文章
4968瀏覽量
73970 -
Vulkan
+關(guān)注
關(guān)注
0文章
31瀏覽量
6129 -
光線追蹤
+關(guān)注
關(guān)注
0文章
185瀏覽量
22096
原文標(biāo)題:Vulkan完全光線追蹤硬陰影
文章出處:【微信號(hào):Imgtec,微信公眾號(hào):Imagination Tech】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
自動(dòng)駕駛場景生成方法及優(yōu)選方案:康謀aiSim 3DGS方案重塑行業(yè)標(biāo)準(zhǔn)
DLInfer聯(lián)手沐曦股份實(shí)現(xiàn)數(shù)據(jù)生成場景的實(shí)際落地
如何選擇適合的智駕仿真工具進(jìn)行場景生成和測試?
桂花網(wǎng)M1000:輕量型藍(lán)牙網(wǎng)關(guān)的場景落地與客戶實(shí)踐
物聯(lián)網(wǎng)RFID物流追蹤技術(shù)是什么?其技術(shù)原理和應(yīng)用場景
目標(biāo)追蹤的簡易實(shí)現(xiàn):模板匹配
拼多多商品推廣鏈接生成API:社交裂變的轉(zhuǎn)化追蹤利器
CoolSiC? MOSFET G2如何正確選型 硬開關(guān)與軟開關(guān)場景解析
生成式 AI 重塑自動(dòng)駕駛仿真:4D 場景生成技術(shù)的突破與實(shí)踐
光線跳線怎么用
資產(chǎn)追蹤與室內(nèi)導(dǎo)航
超125款游戲和應(yīng)用支持DLSS 4多幀生成
光線追蹤及降噪技術(shù)綜述
一種多模態(tài)駕駛場景生成框架UMGen介紹
如何生成具有硬陰影的完全光線追蹤場景
評(píng)論