国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁 > 網(wǎng)易號 > 正文 申請入駐

揭秘疊紙游戲黑科技!《戀與深空》如何打造影視級渲染管線

0
分享至

在 2025 年 10 月 24 日的游戲案例專場中,《戀與深空》制作組的引擎負(fù)責(zé)人阮天龍和技術(shù)美術(shù)負(fù)責(zé)人秦平帶來了演講《打造影視級渲染管線》,詳細(xì)闡述了如何在移動端實現(xiàn)影視級渲染效果。

阮天龍:大家好,我是疊紙游戲《戀與深空》的制作人阮天龍,很榮幸能夠站在 Unite 的講臺上。今天我們要給大家介紹的是“我們是如何在戀與深空這款游戲中打造影視級渲染管線”的。我叫阮天龍、是 2010 年進(jìn)入的游戲行業(yè),之前先后在盛大、完美和網(wǎng)易,從事過引擎開發(fā)相關(guān)工作,2018 年入職的疊紙,目前擔(dān)任《戀與深空》制作組的引擎負(fù)責(zé)人。


《戀與深空》作為一款超現(xiàn)實 3D 沉浸戀愛互動手游,自 2024 年 1 月 18 日上線以來,目前全球玩家的數(shù)量已經(jīng)突破了 7000 萬、并榮獲了科隆游戲展 2025 最佳移動游戲。我們是基于 Unity 2019 開發(fā)的,并且對引擎源碼進(jìn)行了深度修改,開發(fā)了一套自定義的 SRP 管線。Android線 上版本是基于 GLES3.1,未來也即將上線 Vulkan 版本。持續(xù)提升性能,滿足玩家對高品質(zhì)游戲的需求。

接下來,看一段實機(jī)畫面的混剪視頻。

這次分享分為兩個部分:第一部分由我為大家介紹《戀與深空》的渲染管線設(shè)計與優(yōu)化。主要涵蓋場景渲染的優(yōu)化、光照的方案與管線設(shè)計、陰影優(yōu)化這三個部分內(nèi)容。第二部分將由我們的 TA 負(fù)責(zé)人秦平為大家介紹如何聚焦高質(zhì)量角色表演核心渲染技術(shù),來打造影視品質(zhì)的效果。

渲染管線設(shè)計與優(yōu)化

場景渲染優(yōu)化

前面我們對《戀與深空》這個項目有了整體了解?,F(xiàn)在,我們將聚焦到游戲開發(fā)中至關(guān)重要的一環(huán)——場景渲染優(yōu)化。我們開發(fā)了一套場景渲染系統(tǒng),稱之為 RenderGroupRenderer。我們將每個渲染批次稱之為一個 RenderGroup。RenderGroupRenderer 主要做了三件事情。首先是自定義靜態(tài)場景描述,去除 GameObject,避免了更新大量的 GameObject 時帶來的性能損耗。其次我們對 CPU 上 GPU 的 Upload 的頻率做了優(yōu)化,主要包括了 Instance Data 和 Constant Buffer 的 Upload。Constant Buffer 的 Upload 優(yōu)化方面,我會在后面介紹單 draw call 性能優(yōu)化時詳細(xì)解釋。關(guān)于 Instance Data 的 Upload 優(yōu)化,我們在項目初期主要針對室內(nèi)小規(guī)模的場景,采用的是靜態(tài)生成 InstanceDataBuffer,配合 BVH 分割裁剪的形式。隨著項目的推進(jìn),我們的場景精度要求不斷地提高,后期便轉(zhuǎn)向在 GPU 端完成裁剪與 Instance 的填充。最后我們對靜態(tài)物件的 CPU 側(cè)裁剪也做了對應(yīng)的優(yōu)化。通過 Burst + Job System 實現(xiàn)了一套高度并發(fā)的裁剪系統(tǒng),同時只在 CPU 側(cè)進(jìn)行粗略的裁剪,將細(xì)粒度的裁剪任務(wù)交由 GPU 完成。


接下來想介紹一下我們的 InstanceData 的數(shù)據(jù)形式。大家常用的應(yīng)該都是 Constant Buffer 形式的 InstanceData。但是它也有一些缺點。首先它有一個尺寸限制,通常是 64kb;其次常量緩存通常都比較小。當(dāng)我們聲明的 buffer 比較大,并且通過 Instant ID 對它做動態(tài)索引時,即使沒有超過最大尺寸,也容易發(fā)生緩存擊穿,導(dǎo)致性能顯著下降。另一種常用的形式是用 SSBO 來傳遞 InstanceData,這種方法也存在一些缺點。首先它的讀取性能通常是不如緩存未擊穿情況下的 ConstantBuffer,甚至通常不如 Texture。很多移動設(shè)備芯片會為 Texture 設(shè)計更高效的緩存。其次,一些安卓設(shè)備在 GLES 下不支持在 Vertex Shader 中讀取 SSBO,這也限制了它的兼容性。最后這兩個方案都有一個共同的問題,就是都需要使用動態(tài)索引。在低端手機(jī)上,這是一種對緩存非常不友好的操作。針對以上問題我們提出了一種“新瓶裝舊酒”的方案。使用 PerInstance Step 的 Vertex Stream 作為 Instance Buffer。這是一種在 GPU Instancing 誕生之初就被支持的 Instance 方法,既可避免動態(tài)索引帶來的性能問題,也可避免 SSBO 的兼容性問題;還可以通過 Compute Shader 向 Instance Vertex Buffer 輸出,來實現(xiàn) GLES 下兼容性較高的 GPU 積累。最后因為 Unity 引擎的底層沒有支持 PerInstance Step 的 Vertex Stream,所以我們對引擎做了相應(yīng)的定制。最終暴露給上層的是 CommanBuffer 中添加的一個 DrawMeshInstancedTraditional 接口。它需要將另一個 mesh 作為 instance data 傳進(jìn)來。我們也加了相應(yīng)的接口來配置 instance mesh 中各個數(shù)據(jù)段對應(yīng)的頂點 semantic。


接下來介紹一下我們的 GPU Driven 系統(tǒng)。首先我們會依據(jù) Group 的數(shù)量和 Instance 的數(shù)量,提前分配 IndirectParameter Buffer 與 Instant Data Buffer,注意這里 Instance Data Buffer 只是提前分配了空間,實際的數(shù)據(jù)是在 GPU Cull 的時候填入的。同時我們會預(yù)計算每個 Group 的 instance offset,并將其存儲到 Parameter 的 InstanceStart 項。這樣我們就可以全程只綁定一份 instance buffer。此外我們還需要生成逐物件的信息 buffer,其中包含了 Group ID、LOD Distance Range、Bounds、Transform 等信息,用于在 GPU 裁剪時獲取每個物件的屬性。


在 GPU 裁剪之前,我們會先執(zhí)行一次 CPU 粗裁剪,CPU 裁剪僅判斷 Group 整體是否可見,從一個根包圍盒開始,比較物件包圍盒體積總和與合并后包圍盒的體積比值,低于閾值就遞歸分裂包圍盒。這個主要是為了避免兩個物件距離很遠(yuǎn),拉出一個超大的總包圍盒這種情況。同時我們還會配合 PVS 進(jìn)一步判斷 Group 的可見性,因為我們沒有類似 DX12 的 IndirectExecute,我們的 GPU 裁剪只能減少 instance 數(shù),并不能消除 Group 整體的 drawcall,因此需要 CPU 裁剪盡可能準(zhǔn)確地剔除掉完全不可見的 Group。GPU 裁剪則通過一次 dispatch 對所有 Group 進(jìn)行逐物件裁剪,包含視錐裁剪、LOD 裁剪、Hiz 遮擋剔除這 3 段裁剪,通過裁剪就將 Parameter 的 Instance Count 加 1,并輸出 InstanceData。對于陰影剔除,我們參考了龍之教條分享的方法,將畫面深度重投影到陰影空間作為 Shadow Receiver Mask,若 shadow caster 投出的 volume 與 Mask 不相交,就可剔除,避免多余陰影渲染。另外想解釋一下我們?yōu)槭裁礇]有實現(xiàn) Cluster/Meshlet。首先它不是免費(fèi)的,在移動端存在比較大的基礎(chǔ)開銷。其次在 GLES 下實現(xiàn) cluster 也存在一些兼容性問題,同樣是之前提過的 Vertex Shader 訪問 SSBO 的問題。綜合考慮之下,我們認(rèn)為優(yōu)先優(yōu)化單 draw call 的性能更能為我們帶來免費(fèi)且直接的性能提升。


接下來介紹一下我們對 draw call 調(diào)用本身做的性能優(yōu)化。為什么我們今天要著重介紹這塊內(nèi)容呢?因為我發(fā)現(xiàn)我們周圍有很多同事或同行對于渲染的 CPU 耗時優(yōu)化這塊,往往過于關(guān)注 draw call 的數(shù)量,而忽視了每個 draw call 本身的耗時。降低 Draw Call 數(shù)量只是一種優(yōu)化方法,最終的 CPU 耗時才是唯一的衡量指標(biāo)。而且現(xiàn)代移動設(shè)備與圖形標(biāo)準(zhǔn),其實早就可以勝任大量的 drawcall,這塊 HypeHype 引擎的團(tuán)隊在 Siggraph 2023 有過一個分享,他們在 iPhone 6s 上測試了一萬個不同 mesh 與材質(zhì)的 drawcall,結(jié)果耗時僅有 11.27ms。其他同等的安卓設(shè)備也都基本能維持在 60 幀以上。另外在 2014 年,蘋果的 Metal 剛剛誕生時,也早就提出過比 GLES 多畫 10 倍 draw call 的口號。如果當(dāng)年大家已經(jīng)入行了的話,一定聽不少人說過,等新的圖形標(biāo)準(zhǔn)普及了以后就不需要合批了之類的話。那么 11 年后的今天,我們?yōu)槭裁慈栽跒?draw call 過多而苦惱?原因在于多方面的開銷。我們總結(jié)了一下,主要包括 PSO 切換過多、Buffer 提交與拷貝、引擎渲染邏輯以及過多 RHI 調(diào)用的開銷,都會增加 CPU 負(fù)擔(dān)。所以性能優(yōu)化不能只盯著 draw call 數(shù),而要綜合考量這些因素。


首先關(guān)于 PSO 切換的開銷,其實主要取決于每個項目對 shader 變體數(shù)量和 shader 復(fù)雜度的權(quán)衡。我們的 RenderGroupRenderer 也只是做了一些基本的渲染隊列排序。不過我們對于陰影做了一個特殊處理,沒有 AlphaTest 的材質(zhì)統(tǒng)一用相同 shader 渲染 Shadow Depth,可以減少陰影渲染時的 PSO 切換頻率。相對而言我們在 Buffer 提交方面做了更多優(yōu)化。在 GLES 下,Map/Unmap buffer 會帶來顯著開銷,現(xiàn)代 RHI 支持的 persistent map 雖能顯著減少 upload 耗時,但仍無法避免數(shù)據(jù)從主線程到渲染線程,再到 buffer 內(nèi)存的多次拷貝以及 memcmp。我們采用了三種針對性的策略:PerRendererBuffer 將逐 Renderer 的參數(shù),比如物體所受的環(huán)境光 SH,存放在由 Renderer 對象維護(hù)的 Uniform Buffer 中,渲染時直接綁定;PerShaderBuffer 針對不需要逐材質(zhì)變化的 Uniform Buffer,只在 shader 切換時提交一次,相比 PerRendererBuffer 來說,PerShaderBuffer 更加靈活,可以支持不同的 shader 變體;最后針對 PerMaterialBuffer,我們借用了 SRP Batcher 代碼預(yù)生成逐材質(zhì) buffer 并直接綁定,通過這些方法顯著減少了 buffer upload。


接下來是渲染邏輯的優(yōu)化。商業(yè)游戲引擎為保證靈活性與穩(wěn)定性,渲染時會進(jìn)行復(fù)雜的邏輯判斷。在 Unity 引擎內(nèi)部,每次調(diào)用 draw 的時候會先調(diào)用一個 ApplyMaterial 函數(shù),它負(fù)責(zé)在渲染之前更新所有的渲染狀態(tài)與參數(shù)。我們發(fā)現(xiàn)當(dāng) draw call 數(shù)量較多時,它存在一些較為可觀的耗時。因此我們嘗試對 ApplyMaterial 接口進(jìn)行了單獨(dú)拆分拆,僅在材質(zhì)或參數(shù)需要切換時才由上層主動調(diào)用,另外如果我們只需改變 PerMaterialBuffer,就改用簡化后的專用接口。做完上述優(yōu)化之后,相同 draw call 數(shù)下,CPU 耗時可以減少 1/3。RHI 調(diào)用優(yōu)化主要的目標(biāo)是減少除了 draw primitive 以外的其他圖形 API 調(diào)用。我們將相同 stride 的 Vertex&Index Buffer 合并到一個 buffer 里,通過 offset 渲染,可以避免逐 draw call bind VB/IB,耗時可以減少 15%。另一項優(yōu)化是當(dāng) Resource 未發(fā)生變化時,我們跳過了 DescriptorSet 設(shè)置。SetDescriptors 本身是個耗時很高的接口,而且切換 Descriptor 還會增加下一次 draw 的耗時,這個在 Arm 的 Best Practice Guide 里有過介紹。做完這個可以使耗時進(jìn)一步減少 30%。


我們在低端安卓設(shè)備上測試了 5000 個 drawcall 的耗時。使用引擎原生的渲染時,渲染線程的耗時是 34.79ms。當(dāng)我們對 Buffer 提交與渲染邏輯進(jìn)行優(yōu)化后,耗時降低到 22.97ms。在進(jìn)一步優(yōu)化 RHI 調(diào)用次數(shù)后,耗時進(jìn)一步大幅降至了 11.8ms。最終我們在 draw call 數(shù)量不變的前提下,讓 CPU 耗時減少到了原來的 1/3 以下。


我們還嘗試了一些新的 RHI 特性。首先是 MDI,它在支持的設(shè)備上能帶來明顯的優(yōu)化效果,還能在一定程度上改善 GPU 遮擋剔除可能提交空 draw call 的問題,因為不同的 mesh 被合成了一個 draw call,總的 CPU 端提交變少了。然而, Bindless 的表現(xiàn)卻不盡如人意,即便在最新的安卓設(shè)備上也出現(xiàn)了神秘的負(fù)優(yōu)化。結(jié)合 MDI 與 Bindless,我們可以實現(xiàn)幾乎用一個 draw call 渲染所有物件,但是 CPU 耗時卻比不合批時還更高。這也是一個過度關(guān)注 draw call 數(shù)量的反面案例。當(dāng)然,我們期待以后的移動芯片對 bindless 能有更好的支持?,F(xiàn)階段的話,我們嘗試基于 Unity Texture Streaming 擴(kuò)展出了一套無 Feedback SVT 系統(tǒng)作為替代方案,不過這個方案也還在驗證階段。從 Benchmark 場景測試結(jié)果來看,RenderGroupRenderer 對比原始無 instancing 渲染,draw call 數(shù)減少了 1/3,渲染線程耗時大幅減少 3/4,主線程耗時也減少了 2/3。雖然C,因為渲染與裁剪邏輯都移到 SRP 了,但是引擎原生裁剪與 GameObject 更新耗時減少,整體仍然帶來了大幅的優(yōu)化。

光照方案

前面我們探討了渲染性能的多方面優(yōu)化?,F(xiàn)在讓我們將目光轉(zhuǎn)向光照的實現(xiàn)方案。我們在項目中選擇使用前向渲染管線,這有多方面的理由。首先,前向管線在應(yīng)對美術(shù)復(fù)雜且多變的需求方面有其優(yōu)勢,我們不需要擔(dān)心一些材質(zhì)屬性的添加是否會導(dǎo)致 GBuffer 膨脹。其次,傳統(tǒng)的延遲管線對于移動平臺而言帶寬不太友好。 OnePassDeferred 則在靈活性方面存在一些局限,比如無法在 RenderPass 中間改變 RT 的尺寸,也不能 fetch 當(dāng)前位置以外的像素內(nèi)容。另外在 GLES 下, FrameBufferFetch 的兼容性也存在問題,不同芯片支持的 fetch RT 數(shù)量不同,有的只支持 1 張 RT,需要改成通過 PLS 實現(xiàn),但是我們測試 PLS 的性能并不是很理想。引擎自帶的逐物件 4 盞光源對于較大的物件來說不太夠用,因此我們嘗試了 Forward+。但是 Forward+ 在早期設(shè)備上耗時太高,若限制逐 tile 最大光源數(shù),鏡頭變化時,tile 內(nèi)光源數(shù)量不可控,超上限會帶來表現(xiàn) bug。為解決這些問題,我們采用了水平世界空間 Tile 劃分,默認(rèn) 2 米一格,分布于相機(jī)前方,逐 Tile 最多 4 盞光源,用一張 128*128 Index Map。這種劃分方式使 Tile 光源重疊狀態(tài)穩(wěn)定,便于在制作時及時發(fā)現(xiàn)超限問題。


我們在未來的 Vulkan 版本的管線中增加了基于 Subpass 的 Light Pre-pass。在 Pre-Z Pass 中,我們會輸出一張簡易的 GBuffer RT 并且 store 下來。由于我們的 local light 光照使用了沒有 fresnel 的簡化 PBR 模型,所以我們不需要在 GBuffer 中輸出 specular 或者 Albedo。我們只將 normal,roughness 和一些特殊的材質(zhì) id 或?qū)傩孕畔?pack 到了一張 RGBA8 的 Gbuffer 上。然后我們就可以跑一遍類似 deferred shading 的光源 volume 渲染流程,將幾何光照結(jié)果保存到 Tile Memory 上。之后在 shading pass 中,我們會把物件再畫一遍,然后 fetch 這些光照信息,再結(jié)合渲染時獲得的 albedo 等材質(zhì)屬性,就可以得到最終的光照結(jié)果。我們將 TAA 所需的 MotionVector Encode 為 RGBA8,R + G == 0 代表無有效速度。這樣某些不輸出速度的材質(zhì)可在 BA 通道存其他信息,比如我們針對一些簡易且大量的植被,會在 MotionVector 的 BA 通道上保存他們的 UV 信息,這樣在 shading pass 時我們就不需要再畫一遍植被,只需要一個后處理獲取 gbuffer 中的幾何信息與 MotionVector 中的 UV 信息即可還原出植被的材質(zhì)表現(xiàn)。


Vulkan 版本的管線大致是這樣的流程,首先由 PreZ Pass 輸出 Depth,GBuffe與 MotionVector。然后計算陰影的遮擋剔除,接著執(zhí)行陰影的深度渲染,再然后是一些 AO 和屏幕空間 SSS 之類的計算。然后我們就進(jìn)入了 NativeRenderPass,在 SubPass 中計算 ShadowMask,Light Pre-Pass,以及執(zhí)行正常的 Shading Pass。最后退出 RenderPass,再執(zhí)行其他后處理 Pass。Vulkan 版本管線改進(jìn)存在一定局限。Light Pre-Pass 只能替換默認(rèn) Lighting Model,對于需要更多 Gbuffer 通道的 Lighting Model,還是需要采用 Forward+。不過我們提供了一個逐光源可選參數(shù),可以針對某個光源強(qiáng)行使用 Standard Lit Model,對所有材質(zhì)統(tǒng)一處理,這樣可以在犧牲 lighting model 準(zhǔn)確性的條件下實現(xiàn)讓同 Tile 內(nèi)的像素受 4 盞以上燈的影響。


然后是 GI 部分。我們線上的 Diffuse GI 用的還是比較傳統(tǒng)的 Lightmap+light probe 的方式,我們的 Lightmap 只保存了間接光信息。另外我們正在開發(fā)一套實時 GI 系統(tǒng),相信不久就能和大家見面。我們的 Light Probe 除了正常的逐物件單個采樣點的模式以外,還提供了一種多采樣點模式。能為每個物體設(shè)置多個采樣點,依據(jù)線段、三角形或四面體的重心坐標(biāo)進(jìn)行插值。下面是兩張對比圖,左邊這張圖是單采樣點的效果,可以看到這個 box 的底部受到的是統(tǒng)一的環(huán)境光照。右邊的是用了兩個采樣點的結(jié)果,可以發(fā)現(xiàn)左右兩邊受到了不同的間接光照。Specular GI 方面,我們主要是基于使用了 AABB 校正的 Reflection Probe。另外對于一些特定的地板或水面,我們還會使用平面反射代理。大致可以看成一種專門用來畫反射的 HLOD。此外我們還參考了戰(zhàn)神的做法,對 Reflection Probe 的CubeMap 做了歸一化。具體來說就是我們會根據(jù) CubeMap 的像素生成一份環(huán)境光照的 SH 系數(shù),然后將 Cubemap 中的像素顏色與該方向的環(huán)境光照相除,就得到了歸一化的 Cubemap。實際渲染時,我們再用每個像素在反射方向上所受的實際環(huán)境光照與 Cubemap 像素相乘,還原出反射顏色。這么做的好處是,即使大量的物件采樣的都是同一個 Reflection Probe,不同區(qū)域的反射也能產(chǎn)生不同的明暗差別。


陰影優(yōu)化

前面我們探討了光照和渲染管線相關(guān)的內(nèi)容。接下來,我們來進(jìn)入“陰影優(yōu)化”這一環(huán)節(jié)。

我們陰影系統(tǒng)的基本設(shè)計是,最多 3 級 cascade 的 CSM 加上一級角色專屬的特寫陰影,或者在某些多角色場景時會使用 POSM,也就是 Per-Object Shadow Map。我們目前支持兩盞錐燈投影,上面所有陰影的結(jié)果都輸出到了一張 RGBA8的 ScreenSpaceShadowMask上,R 通道保存主光陰影,G 和 B保存了錐燈陰影,A 通道保存了 AO 信息。我們首先做了一個簡單的距離剔除,根據(jù)陰影距離修改 ScreenSpaceShadow 后處理三角形頂點的深度值。再用 ZTest Greater 渲染,剔除陰影距離外的 Shadow 計算。因為我們在計算陰影時需要采樣 depth,所以我們需要兩份 depth 分別用于 Test 與 Sample。我們在NativeRenderPass 中拷貝了一份 memoryless 的 depth buffer 用于 Test,盡量避免了額外的讀寫帶寬。


另外我們還做了一個半影區(qū)域檢測功能。我們先在 1/4 分辨率下計算一次 PCF,隨后在全分辨率 shadow pass 里采樣 1/4 mask,僅對 shadow 值處于中間區(qū)域的像素執(zhí)行全分辨率 PCF,這樣能在保證效果的同時,降低計算量。不過,這么做之后某些細(xì)節(jié)像素會存在檢測不準(zhǔn)確的問題。為此,我們分別依據(jù) 1/4 buffer 中 position 的偏導(dǎo)與全分辨率 gather 的 4 個深度值計算兩組法線。如果法線夾角大于閾值,就判定低分辨率像素不可靠,并強(qiáng)行執(zhí)行全分辨率 PCF。下面是一個祈煜畫室場景的 debug 視圖,紅色區(qū)域是被我們判定為半影區(qū)間的區(qū)域,只有這些像素才會執(zhí)行全分辨率的 PCF。


我們利用 Receiver Plane Depth Bias 算法實現(xiàn)了逐像素的 Shadow Bias。它的原理也比較簡單,首先我們求出屏幕空間 Shadow Coordinates 的偏導(dǎo),然后我們可以發(fā)現(xiàn),我們?nèi)绻褂闷聊豢臻g的 UV 偏導(dǎo)對陰影空間的深度偏導(dǎo)做個二維鏈?zhǔn)睫D(zhuǎn)換,就能得到屏幕空間的深度偏導(dǎo)。將鏈?zhǔn)睫D(zhuǎn)換描述為雅可比矩陣之后,輕易就能得出陰影空間的深度偏導(dǎo)等于雅可比矩陣的逆乘以屏幕空間深度偏導(dǎo)。這個偏導(dǎo)值可以近似描述像素在陰影空間深度的坡度,進(jìn)而就可以用它與 PCF 的采樣偏移量相乘,得到近似的 bias 值。對于中心點來說,我們增加了 1 個像素偏移的 bias 結(jié)果作為起始 bias。


下面是逐像素 bias 與固定 bias 的對比結(jié)果。左邊用的是固定的 bias 值,可以看到 box 的底部有一段漏光區(qū)域,并且與光照方向接近垂直的表面存在一些自陰影的走樣。用了逐像素 bias 之后,我們就只會在偏導(dǎo)較大的區(qū)域增加 bias,可以在保持細(xì)節(jié)投影的同時解決自陰影的走樣問題。不過,當(dāng)屏幕深度不連續(xù)時,逐像素 bias 可能算出錯誤結(jié)果,導(dǎo)致一些漏光現(xiàn)象。為了解決這一問題,需要美術(shù)手動指定 bias 的最大最小范圍。


另外我們針對 draw call 較多的場景,還嘗試了 Scrolling Cached Shadow Map。我們通過緩存 CSM 的深度,對于前后兩幀都被陰影視錐完全包含的對象,將上一幀的 CSM 滾動到當(dāng)前幀投影位置直接得到陰影深度,避免直接渲染對象。我們只對最后一級 cascade 應(yīng)用了 scrolling,當(dāng) cascade 范圍比較小時,大量物體與會與視錐相交,優(yōu)化效果就會受限。另外針對移動平臺的帶寬壓力,我們選擇間隔多幀來更新 CSM 緩存。最后在未來,我們還準(zhǔn)備支持 Local ShadowMap Atlas 以及緩存機(jī)制。我們將會支持兩盞以上的局部燈投影,并且根據(jù)光源的屏占比動態(tài)調(diào)整 ShadowDepth 精度。對于遠(yuǎn)距離的局部光源,也會引入靜態(tài)緩存支持。


以上是我本次分享引用的一些參考資料。下面將由我們的 TA 負(fù)責(zé)人秦平為大家介紹如何打造影視品質(zhì)的效果,謝謝大家!

打造影視品質(zhì)效果


秦平:各位朋友,大家好!前面我的搭檔分享了《戀與深空》項目渲染底層框架的一些內(nèi)容,接下來我來分享一下我們在這樣的框架下面是如何打造一個高品質(zhì)效果的。主要是一些方案相關(guān)的東西。我叫秦平,十七年游戲行業(yè)從業(yè)經(jīng)驗,曾經(jīng)有幸參與制作《神秘海域4》、《怪物獵人世界》等游戲項目的制作;2017 年加入疊紙成為疊紙的第一個 TA,參與開發(fā)了《閃耀暖暖》項目,現(xiàn)任《戀與深空》項目 TA 負(fù)責(zé)人;因為之前做過一些主機(jī)游戲,所以我對高品質(zhì)的游戲效果一直都有一些追求,今天借這個機(jī)會跟大家聊一聊《戀與深空》項目追求角色效果表現(xiàn)的路上遇到的一些問題和解決思路。

這里我大致總結(jié)了一下對我們角色表現(xiàn)影響比較大的幾個方面:首先就是分鏡,我們每一個劇情表演和每一個約會,都是采用了影視級的導(dǎo)演分鏡思維來指導(dǎo)創(chuàng)作的。一個好的分鏡思維對一個好的作品是必不可少的內(nèi)容。然后我們大量采用了真人動捕的技術(shù)來提升動作表現(xiàn)。有了這個增進(jìn)和動作之后,我們還需要一個專用的劇情編輯工具。這里我們工具組的同學(xué)花了大概大半年的時間,精心打造了一套專用的劇情表演工具,配合上 AI 組同學(xué)支持的一個口型和表情系統(tǒng)。最后是定制化的光照和渲染方案,這個也是我這次主要要跟大家分享的東西。

角色光照方案

我這邊先分享的是“角色光照方案”,這里講的“光照方案”不是大家熟知的前向渲染、延遲渲染這些管線相關(guān)的內(nèi)容。我這個方案指的是一個解決思路,比如我角色應(yīng)該受哪些光,怎么管理這些光。經(jīng)常有美術(shù)的同學(xué)報怨,我的場景和角色割裂感很重;我一個近幀打光打好了之后效果還可以,但是鏡頭和角色一動起來效果就崩了,這些問題經(jīng)常會困擾我們。其中最突出的幾個點:

第一是場景氛圍和角色燈光要求沖突。比如夜晚場景需要冷色調(diào)營造氛圍,但是角色面部一般都需要暖色調(diào)保持自然膚色,如果想要用一個冷色調(diào)去著重表現(xiàn)當(dāng)前是一個夜晚的氛圍,就很容易讓角色顯得不自然或者失去立體感;第二個跟前面這個是息息相關(guān)的,就是場景和角色的美術(shù)同學(xué)需要反復(fù)溝通。比如一個室內(nèi)場景做好了,但是角色入場之后發(fā)現(xiàn)這個表演的位置透不進(jìn)光,想在這個角色附近開個窗,透一個光進(jìn)來;或者補(bǔ)一個光源,比如臺燈。場景補(bǔ)好之后劇情編輯的時候可能又發(fā)現(xiàn)這新增的物體會在表演過程當(dāng)中遮擋鏡頭,或者是角色動作會穿到這個物體里面,反反復(fù)復(fù)增加了很多溝通成本;三就是如果每一張卡,每一個劇情、每一個表演都要從零開始的話,會帶來海量的工作內(nèi)容;最后就是我們希望我們提供的作品每一幀都經(jīng)得起反復(fù)觀看,這就需要燈光和效果逐幀精修。


有了這些問題,我們就可以把具體需求拆解出來了,我們需要角色和場景可以分開調(diào)整,盡量互不影響;要支持逐幀調(diào)整燈光參數(shù);還需要支持把調(diào)整好的效果保存成模板,支持編輯和切換功能。


有了明確的需求就可以開始干活了:我們知道光照是由直接光和間接光組成的,直接光正常就是平行光、射燈和點光。一般情況下我們只會有一個平行光,我們習(xí)慣稱之為主光。對這個主光,我們讓他正常照亮場景,但在照亮角色的時候我們保留了它的方向,然后用角色 PPV(Post Process Volume)去復(fù)寫它的顏色和強(qiáng)度。具體實現(xiàn)方式就是給 shader 多傳了一份角色主光顏色,角色的 shader 在獲取主光的時候獲取到的顏色就是這個角色主光顏色;另外我們給角色提供了一盞額外的不投影的平行光用來做輪廓光;此外我們預(yù)留了兩個額外光給角色,他可以是任意的點光和射燈組合,這兩個額外光就是正常的光源,他們可以正常照亮范圍內(nèi)的角色和場景物件。因為我們一個 2 米的格子最多可以有四盞額外光,所以在這里劃分了一下,角色兩盞,場景兩盞。間接光我們使用 Unity 的 LightProbe 系統(tǒng)來創(chuàng)建探針,自己實現(xiàn)了保存間接光信息到探針里的部分。我們把場景的環(huán)境光和角色的環(huán)境光分開存儲,分成了兩套;至于環(huán)境光高光還是使用的同一個反射球,但是我們在特殊的材質(zhì)上支持了一些 cubemap 的覆蓋收入。


然后我們把這些影響角色的光照信息存到一個 scriptableobject 里,由燈光師調(diào)整好之后保存成一個模板;大家可以看最右邊這張圖就是我們保存下來的 scriptableobject。它包含了我上面提到的兩盞平行光,兩個額外光,還有探針保存下來的 sh 信息,以及一些后處理盒子上可以額外調(diào)整的信息。比如主光顏色、額外光顏色;最后用一個 manager 去用一種類似棧的方式去管理起來,這里選用棧的管理方式跟它的使用關(guān)系很大,通常情況下除了加載新的燈光方案之外,“?!本秃芎玫臐M足了這個特性、我們就用這個方式把它管理了起來。


到這里角色燈光方案基本上就完成了,它實現(xiàn)了我們拆分出來的需求。比如:角色和場景可以分開調(diào)整,還可以實時的切換。這個動圖就是切換不同的光照方案時這個角色的表現(xiàn)。

我們把切換燈光方案這個事情定義為一個劇情編輯器上的一個事件,這樣它就天然支持后續(xù)可以銜接光照動畫。因為只有在切換這個事件發(fā)生的那一幀,然后修改了當(dāng)前的這些參數(shù),后續(xù)就可以對這些參數(shù)額外進(jìn)行 K 幀。下面是一段劇情編輯器上動態(tài) K 幀的一個視頻,給大家展示一下我們可以逐幀調(diào)整光照動畫的內(nèi)容。可以看到,這個視頻上面很多的參數(shù)都是被 K 了偵的、包括一些后處理、燈光、陰影,那些藍(lán)掉的地方全部都是 K 了幀的。但是不僅是光會用,劇情編譯器是我們所有表演的入口,比如:物理之類的東西,也是在這個地方 K 進(jìn)去的。

特寫陰影

光和影一直都是密不可分的,前面介紹了光,接下來介紹一下陰影。前面我的搭檔也有提到,我們的陰影方案是三級 CSM 加特寫陰影,這里我著重介紹一下特寫陰影。我們特寫陰影就是在角色身上選一根骨骼,然后作為一個球心,然后用這個球心來指定一個指定半徑的球??梢钥吹竭@里有一個子系統(tǒng),子系統(tǒng)上面有這個包圍球半徑,還有這個負(fù)節(jié)點,這個節(jié)點就是指定的這根骨骼,然后用它作為球心,然后用這個 0.85 作為半徑來構(gòu)建一個球。如果有兩個角色的話,我們會對這兩個球進(jìn)行一個包裹,用算法求一個包裹球,然后用這個球來計算最終的 ShadowMap。

這個視頻里面我們可以看到,就是原本因為在室內(nèi)整個都在陰影里面的這個角色,因為我打開了特寫陰影,然后他的面部被照亮了。我這里展示的主要就是想要說明我們這個特寫陰影的很多參數(shù)都可以單獨(dú)的調(diào)整。比如說這個近裁切平面,近裁切平面往前推室內(nèi)的墻就被不投影了,然后這個角色就被照亮了。這個特寫陰影上面這些參數(shù)都是可以改動的,我希望調(diào)整到一個角色最好的效果,然后呈現(xiàn)給玩家。


皮膚細(xì)節(jié)

說完了光影,接下來聊一聊角色的皮膚、臉上細(xì)節(jié)相關(guān)的內(nèi)容。皮膚分了兩檔:高配就是屏幕空間的 3S,SSS 圖降了分辨率,就相當(dāng)于做了一次模糊。低配的其實是用了一個工具,去實時地擬合和保存這預(yù)積分圖,這里不做過多展開。接下來,我們聚焦一些細(xì)節(jié)的表現(xiàn)。例如:臉紅、流汗的效果,當(dāng)然我們也做了一些張嘴、閉嘴的 AO,以及可以 k 幀的眼睛高光,睜眼閉眼的雙眼皮的一些效果。由于時間有限,這里先聊一下臉紅和流汗的效果。這里我錄了一張卡,可以展示角色的臉紅的表現(xiàn)。當(dāng)女主和男主進(jìn)行一些互動的時候,如果我改變臉上皮膚的顏色、可以很明顯地讓畫面看起來更加的生動和更真實。

通常來講,“臉紅”的過程是一個逐漸變化、并且不同區(qū)域變化程度不一樣的過程。大部分的人在臉紅的時候會從耳朵先開始紅,然后臉頰,偶爾會有整張臉變得通紅的情況。為了模擬這個過程,我們把“臉紅”做成了一個可以區(qū)分通道的遮罩圖。每一個通道對應(yīng)一個區(qū)域。這里也分別提供了對應(yīng)的色塊,去改變臉紅的顏色。如果逐幀去 K 的話,這個工作量也會非常大。這里我們也是采用了模板的思路,美術(shù)同學(xué)可以根據(jù)不同的男主,定制不同的臉紅的曲線做成模板。我們只要在 K 臉紅效果的時候,調(diào)用對應(yīng)的模板、就可以做到對應(yīng)的臉紅效果。


臉紅到一定程度,比如:我現(xiàn)在是在運(yùn)動,運(yùn)動的時候臉非常的紅,可能我接下來就會流汗。如果只有臉紅沒有流汗的效果還是不夠真實,接下來我們做了流汗的效果。我們的流汗有兩種:一種是粒子,主要用的是 vfx,用 skinmeshrender 發(fā)射粒子出來,用來描述一些“甩汗”的效果。材質(zhì)上的實現(xiàn),也分為兩部分:一是修改粗糙度,讓皮膚看起來比較濕潤。第二個就是凝聚成的汗珠,這個凝聚汗珠的實現(xiàn)思路與 Unite2019 閃耀暖暖里分享的實現(xiàn)思路是一樣的,它詳細(xì)介紹了一個閃點,有興趣的同學(xué)可以翻一翻當(dāng)年的這篇分享。這就是大概的一個實現(xiàn)思路。


下圖最上面這個部分就是計算汗滴生成位置,并根據(jù)汗滴的位置修改粗糙度。我們先把 uv 劃分成格子,然后把格子的 ID 做成材質(zhì)的輸入。這樣每個格子里所有的 uv 就會返回同一個隨機(jī)數(shù),我們把這個隨機(jī)數(shù)處理當(dāng)成汗滴生成的位置,詳細(xì)代碼如下圖。下方的視頻就是最終實現(xiàn)出來的流汗效果。流汗時汗滴流下來就是 uv 動畫。但為了讓汗滴流下來的過程更真實,我們做了一個模擬它軌跡的很小的算法實現(xiàn)(下圖右下角)。


謝謝大家,我的分享結(jié)束了。

Unity 官方微信

第一時間了解Unity引擎動向,學(xué)習(xí)進(jìn)階開發(fā)技能

每一個“點贊”、“在看”,都是我們前進(jìn)的動力


特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點推薦
為什么我們不再熱衷過圣誕節(jié)了?

為什么我們不再熱衷過圣誕節(jié)了?

小卿情感說
2025-12-24 21:16:17
詩妮娜趴地跪拜給蘇提達(dá)行禮,泰王犀利看蘇提達(dá),讓她別太得意

詩妮娜趴地跪拜給蘇提達(dá)行禮,泰王犀利看蘇提達(dá),讓她別太得意

笑傲春秋
2025-12-25 14:48:05
被爆生下早夭畸形兒不到48小時,闞清子評論區(qū)淪陷,后續(xù)來了!

被爆生下早夭畸形兒不到48小時,闞清子評論區(qū)淪陷,后續(xù)來了!

喜歡歷史的阿繁
2025-12-27 00:55:38
山東88-94廣東 球員評價:2人優(yōu)秀,2人及格,8人低迷

山東88-94廣東 球員評價:2人優(yōu)秀,2人及格,8人低迷

籃球資訊達(dá)人
2025-12-26 23:27:00
唏噓!廣西平果無緣準(zhǔn)入:曾創(chuàng)中甲第一球市,坐擁皇馬外援!

唏噓!廣西平果無緣準(zhǔn)入:曾創(chuàng)中甲第一球市,坐擁皇馬外援!

邱澤云
2025-12-26 22:11:34
霍去病二十四歲病逝,武帝哭三日,第四日卻殺盡其十七名貼身侍衛(wèi)

霍去病二十四歲病逝,武帝哭三日,第四日卻殺盡其十七名貼身侍衛(wèi)

掠影后有感
2025-12-25 12:38:58
王勇已任南海區(qū)委書記,曾先后任順德區(qū)區(qū)長、南海區(qū)區(qū)長

王勇已任南海區(qū)委書記,曾先后任順德區(qū)區(qū)長、南海區(qū)區(qū)長

南方都市報
2025-12-26 22:08:22
孩子生父真相大白一月后,奚美娟低調(diào)露面,手足無措,落寞呆坐

孩子生父真相大白一月后,奚美娟低調(diào)露面,手足無措,落寞呆坐

丁丁鯉史紀(jì)
2025-12-24 17:03:30
姜昆翻車,美國境內(nèi)唱紅歌,早年抵制洋節(jié)掛在嘴邊,回應(yīng)未移民!

姜昆翻車,美國境內(nèi)唱紅歌,早年抵制洋節(jié)掛在嘴邊,回應(yīng)未移民!

你食不食油餅
2025-12-26 06:13:35
定居美國13年回國撈金遭驅(qū)逐,52歲被笑話

定居美國13年回國撈金遭驅(qū)逐,52歲被笑話

白日追夢人
2025-12-24 04:30:11
終于讓步?俄愿簽署保證書,當(dāng)威脅消失,美國的大棒將落向何方?

終于讓步?俄愿簽署保證書,當(dāng)威脅消失,美國的大棒將落向何方?

科普100克克
2025-12-24 00:02:38
獨(dú)生女不愿接班,天津老板套現(xiàn)7.2億,把家族產(chǎn)業(yè)賣給了安徽國資

獨(dú)生女不愿接班,天津老板套現(xiàn)7.2億,把家族產(chǎn)業(yè)賣給了安徽國資

素衣讀史
2025-12-23 17:03:03
罕見!這一平臺上,比特幣突發(fā)閃崩:8.76萬美元瞬間跌到2.41萬美元,跌幅超70%!什么情況?

罕見!這一平臺上,比特幣突發(fā)閃崩:8.76萬美元瞬間跌到2.41萬美元,跌幅超70%!什么情況?

每日經(jīng)濟(jì)新聞
2025-12-26 07:32:05
中央特科最美傳奇女特工被判槍決,毛主席拍案大怒:她是全黨的恩人

中央特科最美傳奇女特工被判槍決,毛主席拍案大怒:她是全黨的恩人

睡前講故事
2025-12-21 16:15:28
雨果公開銳評國乒,暴露王勵勤真實處境,一切都在劉國梁計劃之中

雨果公開銳評國乒,暴露王勵勤真實處境,一切都在劉國梁計劃之中

千言娛樂記
2025-10-04 21:36:17
皇馬900萬歐即可簽意甲第5身價球星 阿根廷前腰21歲 身價6500萬歐

皇馬900萬歐即可簽意甲第5身價球星 阿根廷前腰21歲 身價6500萬歐

智道足球
2025-12-26 10:44:30
河南天氣再度反轉(zhuǎn)!河南人或迎雪跨年?河南最新天氣發(fā)展趨勢詳情

河南天氣再度反轉(zhuǎn)!河南人或迎雪跨年?河南最新天氣發(fā)展趨勢詳情

另子維愛讀史
2025-12-26 16:24:09
體檢是一場巨大的“人間騙局”!

體檢是一場巨大的“人間騙局”!

功夫財經(jīng)
2025-07-23 08:37:29
49年軍區(qū)政委想回鄉(xiāng)報殺母之仇,毛主席:把425團(tuán)也帶上

49年軍區(qū)政委想回鄉(xiāng)報殺母之仇,毛主席:把425團(tuán)也帶上

青途歷史
2025-12-26 23:56:31
北京開打!重組帶狀皰疹疫苗擴(kuò)齡

北京開打!重組帶狀皰疹疫苗擴(kuò)齡

北青網(wǎng)-北京青年報
2025-12-26 16:27:03
2025-12-27 02:00:49
Unity incentive-icons
Unity
Unity中國官方帳戶
2412文章數(shù) 6729關(guān)注度
往期回顧 全部

游戲要聞

會員費(fèi)沒白交!PS+年度佳作盤點 都是必玩清單

頭條要聞

老人婚宴上被提醒孫女非親生 做鑒定后忍3年忍不了了

頭條要聞

老人婚宴上被提醒孫女非親生 做鑒定后忍3年忍不了了

體育要聞

開翻航母之后,他決定親手造一艘航母

娛樂要聞

王傳君生病后近照變化大,面部浮腫

財經(jīng)要聞

投資巨鱷羅杰斯最新持倉:只留四種資產(chǎn)

科技要聞

收割3000億!拼多多"土辦法"熬死所有巨頭

汽車要聞

兩大CEO試駕 華為乾崑*啟境開啟首款獵裝轎跑路測

態(tài)度原創(chuàng)

本地
藝術(shù)
親子
手機(jī)
教育

本地新聞

云游安徽|踏訪池州,讀懂山水間的萬年史書

藝術(shù)要聞

你絕對想不到,佛陀微笑隱藏的秘密竟然是!

親子要聞

小小的身體大大的能量!被4歲萌娃的深情告白打動?? #睡個好覺

手機(jī)要聞

vivo藍(lán)河:以開源和賽事,撬動AGI時代底層技術(shù)生態(tài)

教育要聞

最新:一批學(xué)校期中考試成績曝光!民辦和公辦的差距巨大!

無障礙瀏覽 進(jìn)入關(guān)懷版