溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

發(fā)布時(shí)間:2021-11-15 16:42:01 來源:億速云 閱讀:581 作者:柒染 欄目:大數(shù)據(jù)

這篇文章給大家介紹Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

說到實(shí)時(shí)陰影的實(shí)現(xiàn),一般比較容易想到使用ShadowMap,通過投射燈光空間的深度圖,并在投射物體上進(jìn)行深度比較,判斷是否處于陰影的范圍,以此來渲染陰影。深度圖投射到接受陰影的物體上的效果如圖所示:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

深度圖投射

你所需要做的就是在燈光空間渲染一張深度紋理,并投射到接受陰影的物體上,并和接受陰影的物體上對應(yīng)像素位置的深度(燈光空間)進(jìn)行比較,來確定當(dāng)前像素是否處于陰影即可,此外還要考慮深度圖的精度以及以此會造成的ZFighting等,當(dāng)然這并不是本文討論的重點(diǎn)。

本文主要介紹一種直接投射燈光空間攝像機(jī)的Rendertexture來實(shí)現(xiàn)陰影的方法,并將在稍后將其和projector結(jié)合。當(dāng)然同時(shí)熟悉這兩項(xiàng)技術(shù)的開發(fā)者應(yīng)該已經(jīng)清楚,使用projector實(shí)現(xiàn)陰影意味著你將會消耗額外的drawcall,實(shí)際上被投射projector并且未在shader中使用"IgnoreProjector"="true"的物體都會在自身shader渲染完(也可能是渲染前,具體看自身渲染隊(duì)列和projector的shader的渲染隊(duì)列的先后順序)后再次使用projector的shader渲染一次。

首先比較一下這種技術(shù)和shadowmap技術(shù),實(shí)際上個(gè)人感覺很大程度上兩者的技術(shù)其實(shí)差不多,都需要用到屏幕投影,只不過shadowmap投射的是深度圖(深度緩沖),而本文介紹的是直接投射屏幕紋理(幀緩沖),因此投射的紋理是帶Alpha通道的,

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

注意燈光空間的攝像機(jī)背景顏色的Alpha因?yàn)?,否則會把背景色也投射到接受陰影的物體上

和shadowmap不同的是,燈光空間的攝像機(jī)應(yīng)該只看到投射陰影的物體:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

此時(shí)投射后的效果大致如圖所示:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

當(dāng)然使用這種方式投射rendertexture必然造成的一個(gè)問題是,由于沒有投射接受陰影的平面,導(dǎo)致一旦投射陰影的物體穿透接受陰影的物體時(shí)會造成陰影的穿幫:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

陰影投射物體穿透陰影接受物體

接受陰影物體Shader主要實(shí)現(xiàn)代碼:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

其中viewMatrix為燈光空間攝像機(jī)的worldToCameraMatrix,projMatrix為燈光空間攝像機(jī)的投影矩陣。

當(dāng)然使用這種方式實(shí)現(xiàn)陰影的不足之處在于需要明確的知道投射陰影的物體和接受陰影的物體。

接下來將嘗試將其與Projector結(jié)合,注意之前已經(jīng)討論過,使用projector意味著額外的drawcall,尤其是場景中物件很多且全部都是分離的物體時(shí),不建議使用這種方式。當(dāng)然如果場景中只有極少部分物體需要接受陰影,比如只有主要地形,則不妨可以嘗試使用這種方式,因?yàn)槭褂胮rojector,你可以很方便的在shader中加入IgnoreProjector標(biāo)簽來忽略投影機(jī)的作用,或者直接在projector上修改projector影響的層。

從unity標(biāo)準(zhǔn)資源包中的projector shader我們大致可以了解,projector shader中需要兩個(gè)4階矩陣,分別為_Projector和_ProjectorClip,其中后者主要用于近遠(yuǎn)裁面的淡入淡出,并不是必須的。而前者的_Projector,注意這個(gè)矩陣應(yīng)該區(qū)別于攝像機(jī)的projection矩陣(盡管攝像機(jī)和projector在很多參數(shù)上很相似),原因是官方的projector shader中直接通過:o.uvShadow = mul (_Projector, vertex);計(jì)算得到投影紋理坐標(biāo),這意味著_Projector矩陣應(yīng)該同時(shí)實(shí)現(xiàn)將vertex轉(zhuǎn)換到世界空間,再轉(zhuǎn)換到projector的局部空間,最后轉(zhuǎn)換到projector的投影空間的功能,所以其性質(zhì)應(yīng)該類似UNITY_MATRIX_MVP矩陣,所以使用projector實(shí)現(xiàn)投射rendertexture的效果,只需要添加一個(gè)腳本,其會創(chuàng)建一個(gè)攝像機(jī),并使用projector的參數(shù),并將這個(gè)攝像機(jī)的rendertexture傳遞給projector的material,具體實(shí)現(xiàn)如下:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

其中_FadeTex是一張表示陰影衰減的貼圖,其r、g通道效果如下:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

這是實(shí)現(xiàn)后的陰影效果:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

這里由于使用的RT是原始攝像機(jī)尺寸的1/2所以陰影質(zhì)量有所下降

另外由于投射的是帶Alpha通道的Rendertexture,意味著可以方便的對其使用模糊shader完成模糊效果,這里是我自己編寫的模糊腳本效果圖:

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影

關(guān)于Unity Shader如何結(jié)合Projector和Rendertexture來實(shí)現(xiàn)實(shí)時(shí)陰影就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI