<cite id="ffb66"></cite><cite id="ffb66"><track id="ffb66"></track></cite>
      <legend id="ffb66"><li id="ffb66"></li></legend>
      色婷婷久,激情色播,久久久无码专区,亚洲中文字幕av,国产成人A片,av无码免费,精品久久国产,99视频精品3
      網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

      《戀與深空》引擎工程師的一次純技術(shù)分享

      0
      分享至

      在今天舉行 的 第十屆Unite開(kāi)發(fā)者大會(huì),《戀與深空》的引擎工程師們首次對(duì)游戲進(jìn)行深度技術(shù)分享,這是疊紙非常少有的在公開(kāi)場(chǎng)合的內(nèi)容分享,現(xiàn)場(chǎng)可以說(shuō)是座無(wú)虛席。

      會(huì)議結(jié)束后,疊紙官方也將今天現(xiàn)場(chǎng)的內(nèi)容發(fā)到了官方公眾號(hào)【疊紙游戲招聘】中,我們將本文完整的轉(zhuǎn)發(fā)出來(lái),希望有更多的行業(yè)精英可以看到這次的技術(shù)“干貨”。

      以下為《戀與深空》技術(shù)分享完整內(nèi)容回顧:


      《戀與深空》渲染底層框架的分享內(nèi)容主要涵蓋【場(chǎng)景渲染優(yōu)化、光照方案與管線設(shè)計(jì)、陰影優(yōu)化】三部分。在開(kāi)發(fā)過(guò)程中,我們基于Unity 2019對(duì)引擎源碼進(jìn)行深度修改,開(kāi)發(fā)了一套自定義的SRP管線。目前Android線上版本為GLES 3.1,未來(lái)也將上線Vulkan版本,持續(xù)提升性能,滿足玩家對(duì)高品質(zhì)游戲的需求。

      1. 場(chǎng)景渲染優(yōu)化

      在場(chǎng)景渲染優(yōu)化中,我們開(kāi)發(fā)了一套名【RendererGroupRenderer】的場(chǎng)景渲染系統(tǒng),將每個(gè)渲染批次稱之為一個(gè)RenderGroup。通過(guò)這套系統(tǒng)我們實(shí)現(xiàn)了以下功能:

      • 自定義靜態(tài)場(chǎng)景描述:我們?nèi)コ鼼ameObject,避免了更新大量GameObject時(shí)帶來(lái)的性能損耗。

      • 優(yōu)化CPU→GPU Upload 頻率:主要包括InstanceData和ConstantBuffer的Upload。關(guān)于InstanceData的Upload優(yōu)化,我們?cè)陧?xiàng)目初期針對(duì)室內(nèi)小規(guī)模場(chǎng)景,采用的是靜態(tài)生成InstanceDataBuffer,配合BVH分割裁剪的形式。隨著項(xiàng)目推進(jìn),場(chǎng)景精度要求不斷提高,后期便轉(zhuǎn)向在GPU端完成裁剪與instance填充。ConstantBuffer的Upload優(yōu)化將在后面【單DrawCall性能優(yōu)化】部分進(jìn)行詳細(xì)說(shuō)明。

      • CPU側(cè)Burst+Job System并行粗裁剪:對(duì)靜態(tài)物件我們通過(guò)Burst+Job System實(shí)現(xiàn)了一套高度并發(fā)的裁剪系統(tǒng),同時(shí)只在CPU側(cè)進(jìn)行粗略的裁剪,將細(xì)粒度的裁剪任務(wù)交由GPU完成。

      InstanceData數(shù)據(jù)形式

      業(yè)界常用Constant Buffer形式的InstanceData存在一些缺點(diǎn),比如64KB 尺寸限制、常量緩存小、動(dòng)態(tài)索引時(shí)容易發(fā)生緩存擊穿導(dǎo)致性能下降等。另一種常用形式是用SSBO來(lái)傳遞InstanceData,但這種方法讀取性能通常不如緩存未擊穿情況下的ConstantBuffer,并且部分安卓設(shè)備在GLES下不支持在vertex shader中讀取SSBO,這也限制了它的兼容性。同時(shí)這兩個(gè)方案都有共同的問(wèn)題:依賴動(dòng)態(tài)索引,對(duì)低端手機(jī)性能不友好。

      針對(duì)以上問(wèn)題,我們提出了一種“新瓶裝舊酒”的方案——Vertex Stream based Instance Data。

      • 使用PerInstance Step的Vertex Stream作為Instance Buffer;

      • 走Vertex Fetch緩存,無(wú)需動(dòng)態(tài)索引,Cache命中率高,無(wú)兼容性問(wèn)題;

      • 通過(guò)ComputeShader向Instance VertexBuffer輸出,實(shí)現(xiàn)GPU Driven。

      使用PerInstance Step的Vertex Stream作為Instance Buffer——這是一種在GPU Instancing誕生之初就被支持的Instance方法,既可以避免動(dòng)態(tài)索引帶來(lái)的性能問(wèn)題,也避免了SSBO的兼容性問(wèn)題。我們還可以通過(guò)ComputeShader向Instance VertexBuffer輸出來(lái)實(shí)現(xiàn)GLES下兼容性較高的GPU Driven。

      最后,由于Unity引擎在底層沒(méi)有支持PerInstance Step的Vertex Stream,我們對(duì)引擎也做了相應(yīng)的定制,最終暴露給上層的是CommandBuffer中添加的一個(gè)DrawMeshInstancedTraditional接口,它需要將另一個(gè)mesh作為instance data傳進(jìn)來(lái)。我們也加了相應(yīng)的接口來(lái)配置instance mesh中各個(gè)數(shù)據(jù)段對(duì)應(yīng)的頂點(diǎn)semantic。

      GPU Driven

      我們會(huì)依據(jù)Group數(shù)量與Instance數(shù)量,提前分配IndirectParameter Buffer與Instance Data Buffer(這里Instance Data Buffer只是提前分配了空間,實(shí)際的數(shù)據(jù)為GPU Cull時(shí)填入)。

      同時(shí),我們會(huì)預(yù)計(jì)算每個(gè)Group的Instance Offset,并將其存儲(chǔ)到Parameter的InstanceStart項(xiàng),全程只綁定一份Instance Buffer。


      此外,我們還需要生成逐物件信息Buffe(包含GroupID、LOD Distance Range、Bounds、Transform等信息),用于在GPU裁剪時(shí)獲取每個(gè)物件的屬性。

      • CPU剪裁:在GPU裁剪之前,我們會(huì)先執(zhí)行一次CPU粗裁剪,以判斷Group整體是否可見(jiàn)。從一個(gè)根包圍盒開(kāi)始,比較物件包圍盒體積總和與合并后包圍盒的體積比值,低于閾值就遞歸分裂包圍盒(主要目的為避免兩個(gè)物件距離過(guò)遠(yuǎn),拉出一個(gè)超大總包圍盒的情況發(fā)生)。同時(shí)結(jié)合PVS進(jìn)一步判斷Group的可見(jiàn)性,因?yàn)槲覀儧](méi)有類似DX12的IndirectExecute,我們的GPU裁剪只能減少instance數(shù),并不能消除Group整體的drawcall,因此需要,通過(guò)CPU裁剪盡可能準(zhǔn)確地剔除掉完全不可見(jiàn)的Group。

      • GPU剪裁:GPU裁剪則通過(guò)一次dispatch對(duì)所有Group進(jìn)行逐物件3段裁剪,包含視錐裁剪、LOD裁剪、Hiz遮擋剔除,通過(guò)裁剪將Parameter的Instance Count加1,并輸出InstanceData。

      • 陰影剔除:我們參考了龍之教條分享的方法,將畫面深度重投影到陰影空間作為Shadow Reveiver Mask,若Shadow Caster投出的Volume與Mask不相交,就可剔除避免多余陰影渲染。

      此外關(guān)于我們“為什么沒(méi)有實(shí)現(xiàn)Cluster/Meshlet”部分,首先它在移動(dòng)端存在較大基礎(chǔ)開(kāi)銷,其次在GLES下實(shí)現(xiàn)Cluster也存在兼容性問(wèn)題。綜合考慮下,我們認(rèn)為優(yōu)先優(yōu)化單DrawCall的性能更能為我們帶來(lái)免費(fèi)且直接的性能提升。

      單DrawCall性能優(yōu)化

      在過(guò)往的觀察中,我們發(fā)現(xiàn)許多對(duì)于渲染的CPU耗時(shí)優(yōu)化往往過(guò)于關(guān)注DrawCall數(shù)量,而忽視了每個(gè)DrawCall本身的耗時(shí)。我們認(rèn)為降低DrawCall數(shù)量只是一種優(yōu)化方法,最終的CPU耗時(shí)才是唯一的衡量指標(biāo)。

      現(xiàn)代移動(dòng)設(shè)備與圖形標(biāo)準(zhǔn)其實(shí)早就可以勝任大量drawcall,這部分在HypeHype引擎團(tuán)隊(duì)在Siggraph 2023中也有過(guò)分享——他們?cè)趇phone 6s上測(cè)試了一萬(wàn)個(gè)不同Mesh與材質(zhì)的DrawCall,耗時(shí)僅有11.27ms。其他同等的安卓設(shè)備也都基本能維持在60幀以上。而在2014年Metal剛剛誕生時(shí),也提出過(guò)比GLES多畫10倍DrawCall的口號(hào)。

      11年后的今天,我們?nèi)詾镈rawCall過(guò)多而苦惱的原因,主要來(lái)自多方面的開(kāi)銷,包括PSO切換過(guò)多、Buffer提交與拷貝、引擎渲染邏輯以及過(guò)多RHI接口調(diào)用,都會(huì)增加CPU負(fù)擔(dān)。因此我們認(rèn)為性能優(yōu)化不能只盯著DrawCall數(shù)量,而要綜合考量這些因素。

      • PSO切換優(yōu)化:主要取決于每個(gè)項(xiàng)目對(duì)shader變體數(shù)量和shader復(fù)雜度的權(quán)衡。RenderGroup渲染隊(duì)列會(huì)根據(jù)shader,material,mesh的優(yōu)先級(jí)排序,同時(shí)我們對(duì)陰影進(jìn)行特殊處理:無(wú)AlphaTest的材質(zhì)統(tǒng)一用相同shader渲染Shadow Depth,減少陰影渲染時(shí)的PSO切換頻率。

      • Buffer提交優(yōu)化:在GLES下,Map/Unmap buffer會(huì)帶來(lái)顯著開(kāi)銷,現(xiàn)代RHI支持的persistent map雖能顯著減少upload耗時(shí),但仍無(wú)法避免數(shù)據(jù)從主線程到渲染線程,再到buffer內(nèi)存的多次拷貝以及memcmp。因此我們采用了以下三種針對(duì)性的策略,顯著減少了Buffer Upload:

        • PerRendererBuffer將逐Renderer的參數(shù)(如物體所受的環(huán)境光SH),存放在由Renderer對(duì)象維護(hù)的Uniform Buffer中,渲染時(shí)直接綁定;

        • PerShaderBuffer針對(duì)不需要逐材質(zhì)變化的uniform buffer,只在shader切換時(shí)提交一次,相比PerRendererBuffer來(lái)說(shuō),PerShaderBuffer更加靈活,可以支持不同的shader變體;

        • 針對(duì)PerMaterialBuffer,我們借用了SRP Batcher代碼預(yù)生成逐材質(zhì)buffer并直接綁定。

      • 渲染邏輯優(yōu)化:商業(yè)游戲引擎為保證靈活性與穩(wěn)定性,渲染時(shí)會(huì)進(jìn)行復(fù)雜的邏輯判斷。比如在Unity引擎內(nèi)部,每次調(diào)用Draw時(shí)會(huì)先調(diào)用一個(gè)ApplyMaterial函數(shù),它會(huì)在渲染之前更新所有的渲染狀態(tài)與參數(shù),當(dāng)DrawCall數(shù)量較多時(shí)存在可觀的耗時(shí)。因此我們進(jìn)行了以下優(yōu)化:

        • 對(duì)ApplyMaterial接口進(jìn)行了單獨(dú)拆分,僅在材質(zhì)或參數(shù)需要切換時(shí)才由上層主動(dòng)調(diào)用;

        • 只需改變PerMaterialBuffer時(shí),改用簡(jiǎn)化后的專用接口。

      優(yōu)化后,我們的CPU在在相同DrawCall下耗時(shí)減少1/3。

      • RHI調(diào)用優(yōu)化:RHI調(diào)用優(yōu)化主要的目標(biāo)是減少除了Draw Primitive以外的其他圖形API調(diào)用,具體優(yōu)化包括:

        • 合并相同stride的Vertex&Index Buffer,避免逐Draw Call bind VB/IB,耗時(shí)減少15%;

        • Resource未發(fā)生變化時(shí),跳過(guò)DescriptorSet設(shè)置,耗時(shí)進(jìn)一步減少30%;SetDescriptors本身耗時(shí)較高時(shí)候,而且切換Descriptor還會(huì)增加下一次draw的耗時(shí),這個(gè)在Arm的Best Practice Guide里有過(guò)介紹。

      我們?cè)诘投税沧吭O(shè)備上測(cè)試了5000個(gè)DrawCall的耗時(shí)。使用引擎原生的渲染時(shí),渲染線程的耗時(shí)是34.79ms。當(dāng)我們對(duì)Buffer提交與渲染邏輯進(jìn)行優(yōu)化后,耗時(shí)降低到22.97ms。在進(jìn)一步優(yōu)化RHI調(diào)用次數(shù)后,耗時(shí)進(jìn)一步大幅降至了11.8ms。最終我們?cè)贒rawCall數(shù)量不變的前提下,讓CPU耗時(shí)減少到了原來(lái)的1/3以下。


      其他優(yōu)化嘗試Benchmark場(chǎng)景測(cè)試結(jié)果

      我們還嘗試了一些新的RHI特性,包括:

      • Multi-Draw Indirect(MDI):在支持的設(shè)備上能夠帶來(lái)明顯優(yōu)化,一定程度上改善GPU遮擋剔除可能會(huì)提交空DrawCall的問(wèn)題(CPU端提交減少);

      • Bindless:然而,Bindless的表現(xiàn)卻不盡如人意,即便在最新的安卓設(shè)備上也出現(xiàn)了神秘的負(fù)優(yōu)化。結(jié)合MDI與Bindless,我們可以實(shí)現(xiàn)幾乎用一個(gè)DrawCall渲染所有物件,但是CPU耗時(shí)卻比不合批時(shí)還更高。這也是一個(gè)過(guò)度關(guān)注DrawCall數(shù)量的反面案例。當(dāng)然,我們期待以后的移動(dòng)芯片對(duì)bindless能有更好的支持。現(xiàn)階段的話,我們嘗試基于Unity Texture Streaming擴(kuò)展出了一套無(wú)Feedback SVT系統(tǒng)作為替代方案,這個(gè)方案也還在驗(yàn)證階段。

      從Benchmark場(chǎng)景測(cè)試結(jié)果來(lái)看,RenderGroupRenderer對(duì)比原始無(wú)instancing渲染,DrawCall減少了1/3,渲染線程耗時(shí)大幅減少3/4,主線程耗時(shí)也減少了2/3(雖然C,但引擎原生裁剪與GameObject更新耗時(shí)減少,整體仍然帶來(lái)了大幅的優(yōu)化)。

      2. 光照方案

      光照方案

      • 前向渲染管線:

      我們?cè)陧?xiàng)目中選擇使用前向渲染管線,包含以下多方面考慮:首先,前向管線在應(yīng)對(duì)美術(shù)復(fù)雜且多變的需求方面有其優(yōu)勢(shì),我們不需要擔(dān)心一些材質(zhì)屬性的添加是否會(huì)導(dǎo)致GBuffer膨脹。

      其次,傳統(tǒng)的延遲管線對(duì)于移動(dòng)平臺(tái)而言帶寬不太友好。OnePassDeferred則在靈活性方面存在一些局限,比如無(wú)法在RenderPass中間改變RT的尺寸,也不能fetch當(dāng)前位置以外的像素內(nèi)容。

      在GLES下,F(xiàn)rameBufferFetch的兼容性也存在問(wèn)題,不同芯片支持的fetch RT數(shù)量不同,有的只支持1張RT,需要改成通過(guò)PLS實(shí)現(xiàn),但是我們測(cè)試PLS的性能并不理想。

      另外,引擎自帶的逐物件4盞光源對(duì)于較大的物件來(lái)說(shuō)不太夠用,因此我們嘗試了Forward+。但是Forward+在早期設(shè)備上耗時(shí)太高,若限制逐tile最大光源數(shù),鏡頭變化時(shí),tile內(nèi)光源數(shù)量不可控,超上限會(huì)帶來(lái)表現(xiàn)bug。

      為解決這些問(wèn)題,我們采用了水平世界空間Tile劃分——默認(rèn)2米一格,分布于相機(jī)前方,逐Tile最多4盞光源,128*128 Index Map。這種劃分方式使Tile光源重疊狀態(tài)穩(wěn)定,便于在制作時(shí)及時(shí)發(fā)現(xiàn)超限問(wèn)題。


      • Vulkan版本管線改進(jìn)

      我們?cè)谖磥?lái)的Vulkan版本的管線中增加了基于Subpass的Light Pre-Pass。

      在Pre-Z Pass中,我們會(huì)輸出一張簡(jiǎn)易的GBuffer RT并且store下來(lái)。由于我們的local light光照使用了無(wú)fresnel的簡(jiǎn)化PBR模型,所以我們不需要在GBuffer中輸出specular或者Albedo,只將normal,roughness和一些特殊的材質(zhì)id或?qū)傩孕畔ack到一張RGBA8的Gbuffer上,然后就可以跑一遍類似Deferred Shading的光源Volume渲染流程,將幾何光照結(jié)果保存到Tile Memory上。

      之后在Shading Pass中,我們會(huì)把物件再畫一遍并fetch這些光照信息,再結(jié)合渲染時(shí)獲得的albedo等材質(zhì)屬性,得到最終的光照結(jié)果。

      我們將TAA所需的MotionVector Encode為RGBA8,R + G == 0代表無(wú)有效速度,這樣某些不輸出速度的材質(zhì)可在BA通道存其他信息。

      比如我們針對(duì)一些簡(jiǎn)易且大量的植被,會(huì)在MotionVector的BA通道上保存他們的UV信息,這樣在Shading Pass時(shí),我們只需要后處理獲取gbuffer中的幾何信息與MotionVector中的UV信息,即可還原出植被的材質(zhì)表現(xiàn)。

      Vulkan版本的管線流程大致如下:首先由PreZ Pass輸出Depth,GBuffer與MotionVector,然后計(jì)算陰影的遮擋剔除,接著執(zhí)行陰影的深度渲染,再然后是一些AO和屏幕空間SSS之類的計(jì)算然后我們就進(jìn)入NativeRenderPass,在SubPass中計(jì)算ShadowMask,Light Pre-Pass,以及執(zhí)行正常的Shading Pass。最后退出RenderPass,再執(zhí)行其他后處理Pass。


      Vulkan版本管線改進(jìn)也存在一定局限,比如Light Pre-Pass只能替換默認(rèn)Lighting Model,對(duì)于需要更多Gbuffer通道的Lighting Model,還是需要采用Forward+。

      不過(guò)我們提供了一個(gè)逐光源可選參數(shù),可以針對(duì)某個(gè)光源強(qiáng)行使用Standard Lit Model,對(duì)所有材質(zhì)統(tǒng)一處理,這樣可以在犧牲Lighting Model準(zhǔn)確性的條件下實(shí)現(xiàn)讓同Tile內(nèi)的像素受4盞以上燈的影響。

      • GI

      Diffuse GI部分,我們采用了較為傳統(tǒng)的Lightmap+Light Probe的方式,Lightmap只保存間接光信息,Light Probe除了正常的逐物件單個(gè)采樣點(diǎn)的模式以外,我們還提供了一種多采樣點(diǎn)模式,能為每個(gè)物體設(shè)置多個(gè)采樣點(diǎn),依據(jù)線段、三角形或四面體的重心坐標(biāo)進(jìn)行插值。

      在以下兩張對(duì)比圖中,左圖為單采樣點(diǎn)的效果,box的底部為統(tǒng)一的環(huán)境光照;右圖則為使用兩個(gè)采樣點(diǎn)的結(jié)果,可以發(fā)現(xiàn)左右兩邊受到了不同的間接光照。


      Specular GI方面,我們主要是基于使用了AABB校正的Reflection Probe。另外對(duì)于一些特定的地板或水面,我們還會(huì)使用平面反射代理。大致可以看成一種專門用來(lái)畫反射的HLOD。

      此外我們還參考了戰(zhàn)神的做法,對(duì)Reflection Probe的CubeMap做了歸一化。具體來(lái)說(shuō)就是根據(jù)CubeMap的像素生成一份環(huán)境光照的SH系數(shù),將CubeMap中的像素顏色與該方向的環(huán)境光照相除,得到歸一化的CubeMap。在實(shí)際渲染時(shí),再用每個(gè)像素在反射方向上所受的實(shí)際環(huán)境光照與CubeMap像素相乘,還原出反射顏色。

      這種做法的好處是,即使大量物件采樣同一個(gè)Reflection Probe,不同區(qū)域的反射也能產(chǎn)生不同的明暗差別。

      3. 陰影優(yōu)化

      功能設(shè)計(jì)

      我們陰影系統(tǒng)的基本設(shè)計(jì)為:

      • 三級(jí)CSM+角色特寫陰影/多角色POSM:3級(jí)Cascade的CSM+1級(jí)角色專屬的特寫陰影,在某些多角色場(chǎng)景時(shí)會(huì)使用POSM(Per-Object Shadow Map);

      • 可支持兩盞錐燈投影;

      • ScreenSpaceShadowMask:將以上陰影的結(jié)果都將輸出到了一張RGBA8的ScreenSpaceShadowMask上;

      • R:Directional Shadow, G: Local Shadow 1, B: Local Shadow 2, A: AO:R通道保存主光陰影,G和B保存了錐燈陰影,A通道保存了AO信息。

      距離剔除

      我們首先做了一個(gè)簡(jiǎn)單的距離剔除,根據(jù)陰影距離修改ScreenSpaceShadow后處理三角形頂點(diǎn)的深度值,之后再用ZTest Greater渲染,剔除陰影距離外的Shadow計(jì)算。

      因?yàn)樵谟?jì)算陰影時(shí)要采樣depth,我們需要兩份depth分別用于Test與Sample,我們會(huì)在NativeRenderPass中拷貝一份Memoryless的Depth Buffer用于Test,盡量避免額外的讀寫帶寬。

      半影區(qū)域檢測(cè)

      我們?cè)黾恿税胗皡^(qū)域檢測(cè)功能,先在1/4分辨率下計(jì)算一次PCF,隨后在全分辨率Shadow Pass里采樣1/4 mask,僅對(duì)shadow值處于中間區(qū)域的像素執(zhí)行全分辨率PCF,在保證效果的同時(shí)降低計(jì)算量。

      為了避免這樣做之后存在某些細(xì)節(jié)像素檢測(cè)不準(zhǔn)確的問(wèn)題,我們會(huì)分別依據(jù)1/4 Buffer中Position的偏導(dǎo)與全分辨率Gather的4個(gè)深度值計(jì)算兩組法線。若法線夾角大于閾值,則判定低分辨率像素不可靠,強(qiáng)行執(zhí)行全分辨率PCF。

      以下為場(chǎng)景的Debug視圖,紅色區(qū)域被我們判定為半影區(qū)間,只有這些像素才會(huì)執(zhí)行全分辨率的PCF。


      逐像素bias

      我們利用Receiver Plane Depth Bias算法實(shí)現(xiàn)了逐像素的Shadow Bias。它的原理也比較簡(jiǎn)單,首先對(duì)屏幕空間shadow coordinates偏導(dǎo)應(yīng)用二維鏈?zhǔn)椒▌t,求出陰影空間偏導(dǎo)。


      利用偏導(dǎo)與PCF采樣偏移我們可以求出bias值。對(duì)于中心點(diǎn)來(lái)說(shuō),我們?cè)黾恿?個(gè)像素偏移的bias結(jié)果作為起始bias。

      下圖為固定bias與逐像素bias的對(duì)比結(jié)果:


      左圖使用固定bias值,可以看到box的底部有一段漏光區(qū)域,并且與光照方向接近垂直的表面存在部分自陰影走樣;使用逐像素bias之后(右圖),我們只會(huì)在偏導(dǎo)較大的區(qū)域增加bias,可以在保持細(xì)節(jié)投影的同時(shí)解決自陰影的走樣問(wèn)題。

      不過(guò),當(dāng)屏幕深度不連續(xù)時(shí),逐像素bias可能算出錯(cuò)誤結(jié)果,導(dǎo)致一些漏光現(xiàn)象。為了解決這一問(wèn)題,需要美術(shù)手動(dòng)指定bias的最大最小范圍。

      Scrolling Cached Shadow Map

      針對(duì)DrawCall較多的場(chǎng)景,我們還嘗試了Scrolling Cached Shadow Map,具體包括:

      • 緩存CSM深度,對(duì)于前后兩幀都被陰影視錐完全包含的對(duì)象,將上一幀的CSM滾動(dòng)到當(dāng)前幀投影位置直接得到陰影深度,避免直接渲染對(duì)象;

      • 只對(duì)最后一級(jí)cascade應(yīng)用Scrolling,當(dāng)cascade范圍比較小時(shí),大量物體與會(huì)與視錐相交,優(yōu)化效果就會(huì)受限;

      • 間隔多幀更新緩存,減緩帶寬壓力。

      在未來(lái),我們還準(zhǔn)備支持Local ShadowMap Atlas以及緩存機(jī)制。我們將會(huì)支持兩盞以上的局部燈投影,并且根據(jù)光源的屏占比動(dòng)態(tài)調(diào)整ShadowDepth精度了,對(duì)于遠(yuǎn)距離的局部光源,也會(huì)引入靜態(tài)緩存支持。


      1. 角色光照方案

      在角色光照方案中,相信大家多多少少都會(huì)遇到以下幾類問(wèn)題:


      對(duì)這些問(wèn)題進(jìn)行拆解,則可以總結(jié)為以下3個(gè)需求:


      基于以上需求,我們進(jìn)行了具體角色光照方案設(shè)計(jì)。

      光照是由【直接光】和【間接光】組成的,一般情況下我們只會(huì)有一個(gè)平行光——我們習(xí)慣稱之為主光。主光正常照亮場(chǎng)景,但在照亮角色的時(shí)候我們保留它的方向,用一個(gè)類似后處理盒子的方式覆寫主光的顏色和亮度。具體實(shí)現(xiàn)方式為:

      • 給Shader多傳一份角色主光顏色,角色的Shader在獲取主光時(shí)獲取到的顏色為角色主光顏色;

      • 給角色提供了一盞額外的不投影的平行光用來(lái)做輪廓光;

      • 同時(shí)預(yù)留了兩個(gè)額外光給角色,額外光可以是任意的點(diǎn)光和射燈組合,可以正常照亮范圍內(nèi)的角色和場(chǎng)景物件( 因?yàn)橐粋€(gè)2米的格子最多四盞額外光,所以將2個(gè)燈光劃分給角色)。

      間接光我們使用Unity的LightProbe系統(tǒng)來(lái)創(chuàng)建探針,自己實(shí)現(xiàn)了保存間接光到探針里的部分,把場(chǎng)景的探針和角色的探針?lè)珠_(kāi)兩套,分別存儲(chǔ)和使用;

      環(huán)境光高光我們使用同一個(gè)反射探針,但對(duì)于一些特殊的材質(zhì),我們提供了材質(zhì)上輸入CubeMap覆蓋環(huán)境的反射探針的選項(xiàng)。


      我們把這些影響角色的光照信息存到一個(gè)Scriptableobject里,由燈光師調(diào)整好之后保存為一個(gè)模板;下方右圖為角色燈光方案保存的信息,包含了上面提到的兩盞平行光,兩個(gè)額外光,還有探針保存下來(lái)的sh,以及一些后處理盒子上可以額外調(diào)整的信息和是否使用自定義的反射探針。

      最后用一個(gè)manager使用類似棧的方式去管理,這里選用棧的管理方式跟具體使用強(qiáng)相關(guān)——通常情況下除了加載新的燈光方案之外,最常用的一個(gè)功能就是還原上一個(gè)燈光方案效果,因此我們采用了棧的管理方式。


      到這里,這個(gè)方案已經(jīng)具備了角色/場(chǎng)景分開(kāi)、可實(shí)時(shí)切換、支持定制保持模板這些功能。最后我們把切換燈光方案定義成劇情編輯器上的一個(gè)事件行為,支持了可銜接光照動(dòng)畫。

      可銜接光效果如下所示:


      下圖為項(xiàng)目專用劇情編輯工具,基本上所有的燈光和陰影相關(guān)的參數(shù)及部分后處理、物理效果都可以在這個(gè)劇情編輯器控制。


      2. 特寫陰影

      光和影一直都是密不可分的。如前文所提到,我們的陰影方案為三級(jí)CSM加特寫陰影,實(shí)現(xiàn)原理就使用角色身上的一根可指定的骨骼做球心,構(gòu)成一個(gè)指定半徑的球,用這個(gè)球來(lái)構(gòu)建和生成這張陰影圖,在屏幕空間陰影的時(shí)候會(huì)進(jìn)行精度比較,使用這張陰影圖和級(jí)聯(lián)陰影中精度較高的一張作為這個(gè)像素的Shadow Map。


      通過(guò)以下動(dòng)圖可以看到,角色原本整個(gè)都在主光陰影里,打開(kāi)特寫陰影的時(shí)候變成了可以被主光正常照亮,就是因?yàn)樘貙戧幱靶薷牧私们衅矫妫灰簿褪钦f(shuō)我們的特寫陰影是一張單獨(dú)可調(diào)參數(shù)的陰影圖,具體參數(shù)包括遠(yuǎn)近裁切平面,最遠(yuǎn)距離,還有使用哪一盞光和往往最讓人頭疼的bias。


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

      皮膚上我們聚焦一些細(xì)節(jié)表現(xiàn),具體以臉紅效果和流汗效果為例。

      • 臉紅效果

      通常來(lái)講,臉紅的過(guò)程是一個(gè)逐漸變化并且不同區(qū)域變紅程度不一樣的過(guò)程,比如大部分人在臉紅的時(shí)候會(huì)先從耳朵開(kāi)始紅,然后是臉頰,偶爾會(huì)有整張臉變紅的表現(xiàn)。


      為了模擬這個(gè)過(guò)程,我們采取了以下方式,使畫面更加生動(dòng)和真實(shí):

        • 手繪遮罩:基于遮罩紋理控制臉紅區(qū)域、顏色梯度與強(qiáng)度;

        • 多通道獨(dú)立:可分別調(diào)節(jié)面部、耳朵、鼻子等不同區(qū)域的紅暈效果;

        • 預(yù)存變化過(guò)程:臉紅的過(guò)渡過(guò)程分通道記錄在對(duì)應(yīng)曲線上,實(shí)現(xiàn)自然的情緒表達(dá)。

      • 流汗效果

      我們游戲里提供了運(yùn)動(dòng)陪伴功能,男主會(huì)進(jìn)行一些運(yùn)動(dòng)訓(xùn)練的陪伴,因此也就需要提供相應(yīng)的流汗效果。具體實(shí)現(xiàn)主要通過(guò)以下三個(gè)方面:

      • 材質(zhì)與粒子結(jié)合:材質(zhì)著色器模擬皮膚表面光澤與濕潤(rùn)度,汗珠效果提供附著在皮膚上的材質(zhì)實(shí)現(xiàn)和vfx實(shí)現(xiàn)可供選擇;

      • 遮罩控制流汗區(qū)域:使用遮罩圖確定材質(zhì)流汗區(qū)域,增強(qiáng)流汗效果的真實(shí)性和藝術(shù)性;

      • 數(shù)據(jù)自動(dòng)化傳遞:主控參數(shù)變化自動(dòng)驅(qū)動(dòng)材質(zhì)與粒子參數(shù)。

      下圖為一些具體的計(jì)算方式與最終效果示意。


      △計(jì)算汗滴生成位置并修改汗滴位置粗糙度


      △通過(guò)uv格子id生成隨機(jī)數(shù)


      △模擬汗滴下落的軌跡


      △運(yùn)動(dòng)陪伴系統(tǒng)流汗效果


      物理效果的分享主要圍繞四個(gè)方面,包括布料模擬實(shí)現(xiàn)、實(shí)時(shí)表演控制、基于Unity DOTS的開(kāi)發(fā)、碰撞檢測(cè)模塊。

      1. 布料模擬實(shí)現(xiàn)

      為了解決項(xiàng)目中的一些針對(duì)性的問(wèn)題,我們內(nèi)部自研了一套布料模擬的系統(tǒng)。

      基于骨骼的布料模擬系統(tǒng):StrayCloth

      StrayCloth采用XPBD結(jié)合sub step的模擬方式。相比PBD,XPBD的優(yōu)點(diǎn)是擺脫了迭代次數(shù)和時(shí)間步長(zhǎng)的依賴,結(jié)合Substep可以顯著提升解算的收斂效果。

      比較特殊的地方在于,我們使用骨骼作為模擬粒子,也就說(shuō)每個(gè)粒子除了位置以外還帶旋轉(zhuǎn)信息。

      在具體的substep實(shí)現(xiàn)中,我們針對(duì)不同性能壓力場(chǎng)景采用動(dòng)態(tài)的子步幅時(shí)間,在1/200 -1/300之間。并且對(duì)場(chǎng)景中的運(yùn)動(dòng)對(duì)象進(jìn)行運(yùn)行插值,這樣碰撞的效果會(huì)更加穩(wěn)定。事實(shí)上運(yùn)動(dòng)插值雖然性能開(kāi)銷不是很高,但是由于類型眾多,比如有靜態(tài)粒子,碰撞體,風(fēng)場(chǎng)等,實(shí)踐起來(lái)還是非常麻煩的。


      為什么使用骨骼而不是代理網(wǎng)格?主要出于以下三個(gè)原因:

      • 戀與深空在劇情、戰(zhàn)斗、換裝中的表現(xiàn)需求復(fù)雜,骨骼方案可以很好的過(guò)渡動(dòng)畫和解算;

      • 在可控性需求和移動(dòng)端性能限制下,骨骼方案給美術(shù)的自由調(diào)節(jié)空間更大;

      • 使用骨骼+約束可以構(gòu)建類似Mesh的結(jié)構(gòu)來(lái)達(dá)到相近的效果。

      骨骼約束方案

      在已有的骨骼布料方案里,骨骼約束實(shí)現(xiàn)常采用基于Local和Global形狀約束的實(shí)現(xiàn)方式,雖然簡(jiǎn)單快速,但是也有明顯的缺點(diǎn)——在用來(lái)做布料模擬時(shí),效果偏向卡通風(fēng)格,不符合《戀與深空》追求的3D寫實(shí)風(fēng)格;而且它的參數(shù)調(diào)整不直觀,因?yàn)樗術(shù)loabl和local兩個(gè)彎曲強(qiáng)度參數(shù),不利于美術(shù)調(diào)整以及在不同場(chǎng)景下的效果匹配。


      因此,我們?cè)诠趋兰s束方案上,選擇了基于Cosserat Rod的骨骼約束。它的優(yōu)點(diǎn)包括:

      • 效果上更加自然,貼近戀與深空整體的寫實(shí)美術(shù)表現(xiàn)風(fēng)格

      • 參數(shù)調(diào)整上更加直觀,并且三個(gè)軸向強(qiáng)度分離,在一些場(chǎng)合比如模擬裙子的時(shí)候,可以通過(guò)各向異性的彎曲強(qiáng)度來(lái)近似裙撐的效果。

      • 頭發(fā)模擬中可以直接復(fù)用,所以我們頭發(fā)和衣服也可以共用一套約束。

      具體效果可以參考最新日卡的表現(xiàn):


      布料與角色連接

      布料和角色的連接主要通過(guò)兩種方式:

      • 層級(jí):靜態(tài)骨骼直接受角色的骨骼動(dòng)畫影響,根據(jù)層級(jí)關(guān)系進(jìn)行移動(dòng)。

        這種方式比較簡(jiǎn)單,在一些偏向于剛性的連接部位時(shí)表現(xiàn)良好。但是對(duì)于一些骨骼交界有多個(gè)骨骼影響或者存在一定幅度拉伸和收縮的較為復(fù)雜的位置,例如手肘、肩部、腰部,表現(xiàn)上容易出現(xiàn)布料和角色分離。

      • 吸附:靜態(tài)粒子受角色模型的錨定三角形控制。并行bake mesh,通過(guò)重心坐標(biāo)每幀計(jì)算更新。

      對(duì)于三角形存在的退化的特殊情況,我們使用三角形頂點(diǎn)的蒙皮骨骼的變換,進(jìn)行加權(quán)平權(quán)來(lái)更新靜態(tài)粒子的transform。


      碰撞方案

      碰撞方案上,我們使用一個(gè)dynamic Bvh來(lái)作為場(chǎng)景碰撞的broad phase管理,每個(gè)角色作為sub tree包含其內(nèi)部的碰撞體作為sub tree node。

      同時(shí),我們通過(guò)角色id,分享可見(jiàn)性還有部件類型,這個(gè)三個(gè)規(guī)則來(lái)實(shí)現(xiàn)不同角色、不同部件的碰撞規(guī)則的共享規(guī)則管理。

      在narrow phase 當(dāng)中,我們不直接生成contact,而是緩存碰撞體對(duì),在substep中再具體的解決,因?yàn)槲覀儾捎玫膕ub step的優(yōu)點(diǎn),大多數(shù)情況下直接使用DCD就可以避免一些快速運(yùn)動(dòng)下造成的穿透問(wèn)題,不需要引入ccd或者predictive contact等一些操作。


      • Mesh Collider實(shí)現(xiàn)

      對(duì)于參數(shù)化的幾何碰撞體,例如plane、capsule、box,可以比較簡(jiǎn)單的解決它們和粒子以及edge的碰撞。在肩頸和胸背部等復(fù)雜部位,參數(shù)化的幾何體難以準(zhǔn)確的表達(dá)角色模型形態(tài),表現(xiàn)上容易發(fā)生穿透,所以在這些部位我們大量的使用Mesh collider。

      但是mesh collider作為不規(guī)則的凹體,有時(shí)也可能是非閉合的,想達(dá)到精準(zhǔn)的碰撞效果相對(duì)參數(shù)化幾何體就比較困難,特別是在移動(dòng)設(shè)備下,因此我們采用散列哈希來(lái)作為三角形的粗略查找方式,結(jié)合緩存的鄰近三角形結(jié)果,在迭代開(kāi)始前生成一次粒子-三角形碰撞對(duì),后續(xù)的迭代中判讀粒子是否在三角形的范圍,如果超出三角形的范圍,通過(guò)模型的三角形鄰接關(guān)系進(jìn)行限制步幅的三角形查找,來(lái)獲取最近的三角形,并且緩存結(jié)果作為下一次使用。

      下方的動(dòng)圖是項(xiàng)目中的一些具體表現(xiàn)示例,可以看到表現(xiàn)上是比較穩(wěn)定的。


      Face Collider

      面部碰撞體可以看作是特殊的Mesh collider,相對(duì)于基本的mesh collider,它形態(tài)較為固定,也較為平滑,從模型中心出發(fā)基本上沒(méi)有三角形重疊,所以我們使用16x16的CubeMap來(lái)預(yù)計(jì)算各個(gè)方向上的三角形,這樣碰撞計(jì)算時(shí)可以快速查找到鄰近的三角形。


      層間碰撞

      游戲當(dāng)中布料模擬的自碰撞是最難處理的部分,出于性能上的考慮,我們給出的方案如下:

      • 使用spatial hashing作為查找加速結(jié)構(gòu)

      • 由美術(shù)預(yù)先分層,只考慮層之間粒子和三角形碰撞

      • 避免層之間卡住的情況,只計(jì)算粒子和三角形單法線方向的碰撞

      由美術(shù)預(yù)先對(duì)布料進(jìn)行分層,只考慮這些層之間的碰撞。使用散列哈希作為查找的加速結(jié)構(gòu),并且為了避免層之間卡住的情況,我們只考慮單法線方向的碰撞,如果已經(jīng)穿透了則略過(guò),交給后面的步驟來(lái)修復(fù)。

      實(shí)際實(shí)踐中,我們使用上一次substep的粒子位置來(lái)和當(dāng)前的粒子位置進(jìn)行碰撞,這樣可以很簡(jiǎn)單的就解耦數(shù)據(jù)避免依賴。


      層間穿透分離

      對(duì)于層碰撞已經(jīng)穿透的部分,我們參考了untanging cloth的方式,使用了一個(gè)輕量的解決辦法,通過(guò)布料分層,從布料的固定點(diǎn)出發(fā),計(jì)算不同層級(jí)的邊和三角形的交點(diǎn),因?yàn)槲覀兊馁Y產(chǎn)結(jié)構(gòu)必定為一個(gè)uniform的網(wǎng)格,因此可以通過(guò)網(wǎng)格交點(diǎn)比較簡(jiǎn)單的推測(cè)出其它粒子的推出三角形,最后對(duì)穿透的粒子-三角形對(duì)施加彈簧約束來(lái)解決穿透。在實(shí)踐中由于substep的關(guān)系,穿透的概率相對(duì)不大,因此我們采用分幀分塊執(zhí)行來(lái)減輕性能壓力。

      2. 實(shí)時(shí)表演控制

      戀與深空劇情表現(xiàn)中大部分的物理表現(xiàn),都是依托于cutscene來(lái)實(shí)現(xiàn)的各種物理效果的控制和調(diào)節(jié)。我們的工具同學(xué)開(kāi)發(fā)和維護(hù)了一套非常強(qiáng)大的cutscene工具,在他們的基礎(chǔ)上我們開(kāi)發(fā)了多種的功能軌道來(lái)具體調(diào)控物理效果。

      這邊是我們一個(gè)動(dòng)卡的Cutscene Physcs Track的例子,因?yàn)槲覀兠佬g(shù)同學(xué)對(duì)于畫面表現(xiàn)扣的非常細(xì),所以可以看到整個(gè)物理軌道的配置還是非常復(fù)雜的。


      △Cutscene Physcs Track 示例

      SmoothBlendPose Track

      在表現(xiàn)當(dāng)中,一個(gè)非常常見(jiàn)的問(wèn)題就是動(dòng)作瞬切切換帶來(lái)的物理抖動(dòng),無(wú)論是在劇情表演中還是換裝中,都經(jīng)常出現(xiàn)。

      我們開(kāi)發(fā)了一個(gè)較為通用的辦法,通過(guò)記錄初始物理姿態(tài),在切換的時(shí)候在初始姿態(tài)和當(dāng)前姿態(tài)進(jìn)行姿態(tài)插值計(jì)算,這樣就可以大幅度的緩解抖動(dòng),當(dāng)然這個(gè)會(huì)帶來(lái)一些時(shí)間開(kāi)銷,一般會(huì)在幾十毫秒左右,在大多數(shù)情況下都可以接受,提供一些參數(shù)例如插值次數(shù),插值的步幅大小來(lái)讓美術(shù)可以根據(jù)實(shí)際需要來(lái)去調(diào)整。


      Pose Track

      當(dāng)然,SmoothBlendPose存在局限性,不能保證的完全順暢,特別是在一些劇情表演的復(fù)雜鏡頭切鏡下。我們還提供了一個(gè)比較直接的方案——離線直接保存某個(gè)時(shí)間幀的物理狀態(tài),在播放時(shí),將保存的物理狀態(tài)直接應(yīng)用到布料上,這樣就可以完美避免切鏡帶來(lái)的問(wèn)題。


      Edit Param Track

      單一的物理資產(chǎn)是很難滿足劇情當(dāng)中的各種不同場(chǎng)景下的表現(xiàn)的,比如有的時(shí)候希望布料軟一些硬一些,阻尼大一些小一些。我們提供編輯參數(shù)的軌道,通過(guò)這個(gè)軌道來(lái)實(shí)時(shí)的編輯修改參數(shù),絕大部分的參數(shù)都可以覆蓋大,可以非常方便的針對(duì)一小段時(shí)間幀進(jìn)行修改。這個(gè)參數(shù)修改還可以用來(lái)做一些特殊的效果,比如動(dòng)圖當(dāng)中的利用編輯約束參數(shù)來(lái)實(shí)現(xiàn)的斷裂的效果。


      Animation Track

      完全的物理效果實(shí)際上不足以支持起整個(gè)畫面方方面面的表現(xiàn)的,很多時(shí)候表現(xiàn)上需要?jiǎng)赢嫼臀锢淼慕Y(jié)合來(lái)做一些互動(dòng)。我們通過(guò)動(dòng)畫軌道來(lái)實(shí)現(xiàn)動(dòng)畫和物理的銜接和融合,精細(xì)的控制不同時(shí)間幀范圍下的表現(xiàn)。在實(shí)際制作流程當(dāng)中,動(dòng)作在dcc里和最終進(jìn)引擎的表現(xiàn)差異是比較大的,包括一些引擎的實(shí)時(shí)rig系統(tǒng)修改后,動(dòng)畫可能和其它地方有穿透,所以我們?cè)趧?dòng)畫融合的基礎(chǔ)上,可以疊加上物理的碰撞效果,來(lái)避免一些穿插。

      動(dòng)圖當(dāng)中展示是項(xiàng)鏈在物理和動(dòng)畫的交互效果,包括從物理到動(dòng)畫的狀態(tài)切換以及在不同動(dòng)畫之間的切換。


      Collider Track & Wind Track

      Collider Track與Wind Track可以在cutscene中動(dòng)態(tài)的創(chuàng)建、銷毀碰撞體和風(fēng)場(chǎng)。根據(jù)不同畫面需求,靈活改變碰撞體和風(fēng)場(chǎng)的狀態(tài)。通過(guò)角色、部件類型、還有布料的層分組來(lái)細(xì)節(jié)控制所要影響的對(duì)象范圍。

      并且,碰撞體和風(fēng)場(chǎng)軌道的絕大部分參數(shù)可以添加動(dòng)畫幀控制,包括碰撞體的形態(tài)大小、風(fēng)場(chǎng)的方向、范圍、強(qiáng)度、湍流等,方便美術(shù)把控物理效果,精準(zhǔn)控制變化。

      動(dòng)圖當(dāng)中是軌道膠囊體和風(fēng)場(chǎng)的一些表現(xiàn)例子。


      3. 基于Unity DOTS的開(kāi)發(fā)

      Jobs + Burst + Mathematics

      DOTS這套工具非常強(qiáng)大,在C。我們的物理系統(tǒng)使用DOTS完全構(gòu)建在C,功能迭代和debug都非常便利。目前來(lái)說(shuō)我們最高可以支持2000+骨骼粒子的模擬。

      當(dāng)然,我們也針對(duì)性的在項(xiàng)目中,做了一些優(yōu)化進(jìn)一步提升性能。


      Cache Job

      模擬中的job數(shù)量和依賴關(guān)系確定,job data并不頻繁變化,幀內(nèi)一般為相同數(shù)量和依賴關(guān)系的job組多次循環(huán)執(zhí)行,Unity Jobs 在發(fā)起任務(wù)時(shí)每次都需要重新創(chuàng)建job,雖然可以提前發(fā)起任務(wù)緩解,但是依然會(huì)卡主線程。并且在執(zhí)行完成job還需要clear。基于以上的觀察,我們開(kāi)發(fā)了Cache Job的方案,預(yù)先創(chuàng)建好job data,然后每次執(zhí)行時(shí)復(fù)用,避免每次重新創(chuàng)建job帶來(lái)的性能開(kāi)銷。

      實(shí)現(xiàn)上比較簡(jiǎn)單,因?yàn)槭且粋€(gè)專用的結(jié)構(gòu),只考慮一些固定的使用場(chǎng)景。額外添加了一個(gè)Atomic Queue用來(lái)存cache job,使用fetch and add array 來(lái)存具體的job。右邊是worker執(zhí)行cache job的流程示意圖。


      Neon Intrinsics

      Burst會(huì)針對(duì)不同平臺(tái)生成高性能的simd code,在Burst Inspector中可以非常方便的查看。經(jīng)過(guò)檢查Burst Inspector和實(shí)機(jī)測(cè)試,在某些場(chǎng)合下也可以通過(guò)手寫Arm Neon Intrinsics來(lái)進(jìn)一步提升性能。

      這里給出例子是判斷向量是否存在大于0的元素的實(shí)現(xiàn)。



      Dot(float4)

      對(duì)于點(diǎn)乘,我這里列出了3種方式,使用neon intrinsics相比于mathematics在測(cè)試用例中可以獲得約30%的性能提升。如果目標(biāo)機(jī)型支持armv8.2的話,可以使用新增的規(guī)約加法指令,來(lái)進(jìn)一步的提升性能。一般來(lái)說(shuō)現(xiàn)在市面上的大部分流行機(jī)型都是支持armv8.2的。


      Transpose(float4x4)

      對(duì)于轉(zhuǎn)置計(jì)算,可以看到mathematics生成的assembly code看起來(lái)性能是非常低的,通過(guò)手寫neon intrinsics, 可以得到一個(gè)巨大的性能提升。

      如果只是純粹的需要轉(zhuǎn)置,可以直接使用交錯(cuò)讀,這里這樣實(shí)現(xiàn)因?yàn)樵谖乙话愕膶?shí)際使用中是通過(guò)對(duì)4個(gè)float4轉(zhuǎn)置來(lái)將點(diǎn)乘變成矢量乘。

      這里只是給出這兩個(gè)項(xiàng)目里比較常用的例子。因?yàn)閙athematics的代碼一般被內(nèi)聯(lián),在具體優(yōu)化時(shí)還需要根據(jù)代碼的上下文進(jìn)行具體的優(yōu)化,可以結(jié)合burst inspector和真機(jī)測(cè)試來(lái)進(jìn)行具體的性能測(cè)試。


      4. 碰撞檢測(cè)模塊

      為什么要脫離Unity成熟的物理模塊重新開(kāi)發(fā)?

      Unity 本身具有基于physx的一套成熟的物理模塊,而脫離Unity成熟的物理模塊重新開(kāi)發(fā),主要基于以下考慮:

      • 戀與深空有相當(dāng)多的不同種類的玩法,玩法間的layer設(shè)置相對(duì)獨(dú)立,非常希望能夠各自維護(hù)一套layer設(shè)置。

      • 有些模塊例如戰(zhàn)斗需要特殊的Trigger觸發(fā)和退出機(jī)制希望在底層就可以支持,對(duì)于執(zhí)行流程也希望有更靈活的控制。

      • 最后是在性能探索上我們也有一些想法,就是在僅需要碰撞檢測(cè)的情況下,利用DOTS能否提升性能?


      《戀與深空》中的實(shí)現(xiàn)包括:

      • 基本實(shí)現(xiàn)了所有原生的碰撞查詢功能

      • 定制化的Update和Trigger邏輯

      • 線程安全的查詢接口,上層可以無(wú)負(fù)擔(dān)調(diào)用

      • 結(jié)合DOTS的輕量化結(jié)構(gòu)實(shí)現(xiàn),在性能測(cè)試中,最高可獲得~15%的提升

      查詢流程示例

      由于真機(jī)上,我們實(shí)際的線程數(shù)量是固定的為4,所以對(duì)于memory allocator可以預(yù)先按照線程數(shù)量分配好,在分配時(shí)可以直接根據(jù)當(dāng)前線程索引來(lái)獲取。

      使用基于SAH的dynamic bvh作為broadphase加速結(jié)構(gòu),在插入、刪除以及超出范圍的移動(dòng)時(shí),對(duì)當(dāng)前操作節(jié)點(diǎn)的鄰近的幾個(gè)層級(jí)節(jié)點(diǎn)進(jìn)行旋轉(zhuǎn)平衡。

      因?yàn)榕鲎矙z測(cè)的功能目標(biāo)相對(duì)概括,對(duì)于精度要求沒(méi)有那么高,所以我們也適當(dāng)?shù)臓奚恍┚群?jiǎn)化了一些碰撞檢測(cè)算法來(lái)提升性能。


      觸發(fā)流程示例

      為了滿足戰(zhàn)斗模塊的需求,我們?cè)O(shè)計(jì)了特殊的trigger觸發(fā)邏輯,Trigger的 Enter 和 Exit必須要成對(duì)出現(xiàn),可以看到以下流程示意圖中,在a觸發(fā)b的函數(shù)中移除b后,會(huì)觸發(fā)所有和b存在overlap的collider,這里和unity原生的有所不同——原生的unity中在trigger邏輯中刪除掉b是不會(huì)觸發(fā)其它碰撞體的trigger的。最后,我們通過(guò)History計(jì)數(shù)來(lái)標(biāo)記collider的版本,解決復(fù)用邏輯可能會(huì)導(dǎo)致的一些潛在問(wèn)題。


      特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(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)推薦
      熱點(diǎn)推薦
      李在明為濟(jì)州航空空難道歉

      李在明為濟(jì)州航空空難道歉

      參考消息
      2025-12-29 21:50:19
      羅永浩“科技春晚”遲到40多分鐘,本人現(xiàn)場(chǎng)宣布門票全退

      羅永浩“科技春晚”遲到40多分鐘,本人現(xiàn)場(chǎng)宣布門票全退

      第一財(cái)經(jīng)資訊
      2025-12-30 23:44:08
      6場(chǎng)1勝!英超爭(zhēng)冠豪門斷崖下滑,10億豪陣成擺設(shè),瓜帥偷著樂(lè)

      6場(chǎng)1勝!英超爭(zhēng)冠豪門斷崖下滑,10億豪陣成擺設(shè),瓜帥偷著樂(lè)

      阿泰希特
      2025-12-30 09:30:53
      中國(guó)駐歐盟使團(tuán)就歐盟對(duì)外行動(dòng)署發(fā)言人涉臺(tái)聲明答記者問(wèn)

      中國(guó)駐歐盟使團(tuán)就歐盟對(duì)外行動(dòng)署發(fā)言人涉臺(tái)聲明答記者問(wèn)

      澎湃新聞
      2025-12-31 04:21:23
      3-0!非洲杯頭號(hào)奪冠熱門誕生:20場(chǎng)比賽獲18勝2平!改寫68年歷史

      3-0!非洲杯頭號(hào)奪冠熱門誕生:20場(chǎng)比賽獲18勝2平!改寫68年歷史

      球場(chǎng)沒(méi)跑道
      2025-12-30 10:07:25
      “小寶探花”案件回顧:瘋狂約會(huì)上百名女性,一人拍攝,一人販賣

      “小寶探花”案件回顧:瘋狂約會(huì)上百名女性,一人拍攝,一人販賣

      就一點(diǎn)
      2025-12-30 21:32:02
      47歲宋曉峰豪宅曝光!兩層樓,有室內(nèi)電梯,高檔實(shí)木家具應(yīng)有盡有

      47歲宋曉峰豪宅曝光!兩層樓,有室內(nèi)電梯,高檔實(shí)木家具應(yīng)有盡有

      小徐講八卦
      2025-12-29 08:53:07
      梅西是神!亞馬爾:C羅能有今天的成就在于他不跟任何人比較

      梅西是神!亞馬爾:C羅能有今天的成就在于他不跟任何人比較

      陸盼盼
      2025-12-30 22:51:42
      烏克蘭突襲俄羅斯精銳部隊(duì)格魯烏的指揮部!打掉俄軍彈藥庫(kù)

      烏克蘭突襲俄羅斯精銳部隊(duì)格魯烏的指揮部!打掉俄軍彈藥庫(kù)

      項(xiàng)鵬飛
      2025-12-29 19:34:39
      北京肖哥突發(fā)去世,年僅45歲,家里原石成堆開(kāi)大奔,十幾套房出租

      北京肖哥突發(fā)去世,年僅45歲,家里原石成堆開(kāi)大奔,十幾套房出租

      墨印齋
      2025-12-30 18:04:36
      12個(gè)老同學(xué)退休后組織旅游團(tuán),我嫌麻煩不去,半個(gè)月后他們質(zhì)問(wèn)我

      12個(gè)老同學(xué)退休后組織旅游團(tuán),我嫌麻煩不去,半個(gè)月后他們質(zhì)問(wèn)我

      懸案解密檔案
      2025-12-23 10:06:37
      三國(guó)外長(zhǎng)挽手臂 柬泰還需“中和”!

      三國(guó)外長(zhǎng)挽手臂 柬泰還需“中和”!

      看看新聞Knews
      2025-12-29 23:53:02
      炸鍋了!中年婦女真的很容易被殺豬盤啊,評(píng)論看的一陣后怕

      炸鍋了!中年婦女真的很容易被殺豬盤啊,評(píng)論看的一陣后怕

      有趣的火烈鳥(niǎo)
      2025-12-30 14:14:31
      前港姐冠軍承認(rèn)和交往八年富豪男友分手,并表示不涉及第三者

      前港姐冠軍承認(rèn)和交往八年富豪男友分手,并表示不涉及第三者

      瀲滟晴方DAY
      2025-12-31 06:14:47
      72歲老戲骨濮存昕官宣外孫女出道,尖嘴猴腮,長(zhǎng)相遭吐槽:太丑了

      72歲老戲骨濮存昕官宣外孫女出道,尖嘴猴腮,長(zhǎng)相遭吐槽:太丑了

      深析古今
      2025-12-08 12:29:36
      必須拆除!這座用中國(guó)“血肉”堆起的“妖塔”,是亞洲的恥辱

      必須拆除!這座用中國(guó)“血肉”堆起的“妖塔”,是亞洲的恥辱

      布拉旅游說(shuō)
      2025-12-16 08:21:02
      女子稱在杭州旅游時(shí)遭面館老板騷擾,對(duì)方對(duì)其長(zhǎng)相打分,還稱“把絲襪露出來(lái)就免單”,警方回應(yīng)

      女子稱在杭州旅游時(shí)遭面館老板騷擾,對(duì)方對(duì)其長(zhǎng)相打分,還稱“把絲襪露出來(lái)就免單”,警方回應(yīng)

      極目新聞
      2025-12-30 16:03:57
      中央特科最美傳奇女特工被判槍決,毛主席拍案大怒:她是全黨的恩人

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

      睡前講故事
      2025-12-21 16:15:28
      孟小冬究竟有多漂亮?一嫁梅蘭芳二嫁杜月笙,美得讓人移不開(kāi)眼!

      孟小冬究竟有多漂亮?一嫁梅蘭芳二嫁杜月笙,美得讓人移不開(kāi)眼!

      阿胂是吃瓜群眾
      2025-12-26 15:46:17
      Manus被收購(gòu)前最后一次訪談:季逸超還不知道Meta即將來(lái)敲門

      Manus被收購(gòu)前最后一次訪談:季逸超還不知道Meta即將來(lái)敲門

      AI進(jìn)化論花生
      2025-12-30 21:35:06
      2025-12-31 07:08:49
      游娛fan incentive-icons
      游娛fan
      精彩游戲資訊
      1811文章數(shù) 463關(guān)注度
      往期回顧 全部

      游戲要聞

      魔壇節(jié)奏|魔超聯(lián)賽S2哈漫喜迎開(kāi)門紅,KK電競(jìng)真人秀報(bào)名開(kāi)啟

      頭條要聞

      轟-6K飛行員:已到達(dá)任務(wù)空域?qū)棞?zhǔn)備完畢 可以發(fā)射

      頭條要聞

      轟-6K飛行員:已到達(dá)任務(wù)空域?qū)棞?zhǔn)備完畢 可以發(fā)射

      體育要聞

      聯(lián)盟第一人倒下了!掘金還有底牌嗎?

      娛樂(lè)要聞

      林俊杰女友被扒 父親涉經(jīng)濟(jì)案卷款13億?

      財(cái)經(jīng)要聞

      朱光耀:美關(guān)稅政策正使WTO名存實(shí)亡

      科技要聞

      估值150億的智元,開(kāi)始批量"制造"小獨(dú)角獸

      汽車要聞

      標(biāo)配華為乾崑ADS 4 Pro 華境S明年上半年上市

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

      手機(jī)
      教育
      親子
      旅游
      軍事航空

      手機(jī)要聞

      雷軍直播拆YU7,小米17還有新機(jī)

      教育要聞

      輔修專業(yè)別亂選!3步高效規(guī)劃雙專業(yè)

      親子要聞

      笑發(fā)財(cái)了!終于知道為什么孩子喜歡舅舅了,網(wǎng)友:有求必應(yīng)

      旅游要聞

      外媒:大批國(guó)際游客涌向中國(guó)過(guò)新年

      軍事要聞

      福建海警艦艇與臺(tái)海巡船對(duì)峙航行

      無(wú)障礙瀏覽 進(jìn)入關(guān)懷版 主站蜘蛛池模板: 影音先锋大型av资源| www.欧美精品| 沂源县| 曰批免费视频播放免费| 玩弄白嫩少妇xxxxx性| 精品无码国产日韩制服丝袜| 亚洲第一男人天堂| 汕尾市| 色偷偷偷久久伊人大杳蕉| 无码国产精品一区二区免费式直播| 亚洲色大成网站www永久男同| 91免费视频观看| 一本之道AV无码专区| 在线天堂www在线| 国产成人久久av免费看| 精品91在线| 成人亚洲精品一区二区三区嫩花| 精品国产一区二区三区四区| 精品一区二区久久久久久久网站| 国产欧美日韩精品第二区| 超碰在线观看91| 成人乱人伦精品小说| 无码孕妇孕交在线观看| 国产成人精品一区二区秒拍1o| 昌江| 孕妇怀孕高潮潮喷视频孕妇| 香蕉久久国产AV一区二区| 色婷婷影院| 通州区| 国产网红女主播精品视频| 影音先锋人妻啪啪av资源网站| 成人AV天堂| 色吊丝av中文字幕| 亚洲精品国精品久久99热| 囯产精品久久久久久久久久妞妞| 3p在线视频| 国产欧美久久久久久| 男女裸体影院高潮| 一区二区三区放荡人妻| 成人国产综合| 影音先锋中文字幕无码|