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

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

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

0
分享至

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

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

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


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

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

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

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

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

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

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

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

針對以上問題,我們提出了一種“新瓶裝舊酒”的方案——Vertex Stream based Instance Data

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

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

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

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

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

GPU Driven

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

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


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

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

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

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

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

單DrawCall性能優(yōu)化

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

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

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

  • PSO切換優(yōu)化:主要取決于每個項(xiàng)目對shader變體數(shù)量和shader復(fù)雜度的權(quán)衡。RenderGroup渲染隊(duì)列會根據(jù)shader,material,mesh的優(yōu)先級排序,同時我們對陰影進(jìn)行特殊處理:無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。因此我們采用了以下三種針對性的策略,顯著減少了Buffer Upload:

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

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

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

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

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

    • 只需改變PerMaterialBuffer時,改用簡化后的專用接口。

優(yōu)化后,我們的CPU在在相同DrawCall下耗時減少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,耗時減少15%;

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

我們在低端安卓設(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。最終我們在DrawCall數(shù)量不變的前提下,讓CPU耗時減少到了原來的1/3以下。


其他優(yōu)化嘗試Benchmark場景測試結(jié)果

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

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

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

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

2. 光照方案

光照方案

  • 前向渲染管線:

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

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

在GLES下,F(xiàn)rameBufferFetch的兼容性也存在問題,不同芯片支持的fetch RT數(shù)量不同,有的只支持1張RT,需要改成通過PLS實(shí)現(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版本管線改進(jìn)

我們在未來的Vulkan版本的管線中增加了基于Subpass的Light Pre-Pass。

在Pre-Z Pass中,我們會輸出一張簡易的GBuffer RT并且store下來。由于我們的local light光照使用了無fresnel的簡化PBR模型,所以我們不需要在GBuffer中輸出specular或者Albedo,只將normal,roughness和一些特殊的材質(zhì)id或?qū)傩孕畔ack到一張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,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,對于需要更多Gbuffer通道的Lighting Model,還是需要采用Forward+。

不過我們提供了一個逐光源可選參數(shù),可以針對某個光源強(qiáng)行使用Standard Lit Model,對所有材質(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除了正常的逐物件單個采樣點(diǎn)的模式以外,我們還提供了一種多采樣點(diǎn)模式,能為每個物體設(shè)置多個采樣點(diǎn),依據(jù)線段、三角形或四面體的重心坐標(biāo)進(jìn)行插值。

在以下兩張對比圖中,左圖為單采樣點(diǎn)的效果,box的底部為統(tǒng)一的環(huán)境光照;右圖則為使用兩個采樣點(diǎ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。在實(shí)際渲染時,再用每個像素在反射方向上所受的實(shí)際環(huán)境光照與CubeMap像素相乘,還原出反射顏色。

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

3. 陰影優(yōu)化

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

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

  • 三級CSM+角色特寫陰影/多角色POSM:3級Cascade的CSM+1級角色專屬的特寫陰影,在某些多角色場景時會使用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信息。

距離剔除

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

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

半影區(qū)域檢測

我們增加了半影區(qū)域檢測功能,先在1/4分辨率下計(jì)算一次PCF,隨后在全分辨率Shadow Pass里采樣1/4 mask,僅對shadow值處于中間區(qū)域的像素執(zhí)行全分辨率PCF,在保證效果的同時降低計(jì)算量。

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

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


逐像素bias

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


利用偏導(dǎo)與PCF采樣偏移我們可以求出bias值。對于中心點(diǎn)來說,我們增加了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的最大最小范圍。

Scrolling Cached Shadow Map

針對DrawCall較多的場景,我們還嘗試了Scrolling Cached Shadow Map,具體包括:

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

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

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

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


1. 角色光照方案

在角色光照方案中,相信大家多多少少都會遇到以下幾類問題:


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


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

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

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

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

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

間接光我們使用Unity的LightProbe系統(tǒng)來創(chuàng)建探針,自己實(shí)現(xiàn)了保存間接光到探針里的部分,把場景的探針和角色的探針分開兩套,分別存儲和使用;

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


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

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


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

可銜接光效果如下所示:


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


2. 特寫陰影

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


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


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

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

  • 臉紅效果

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


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

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

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

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

  • 流汗效果

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

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

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

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

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


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


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


△模擬汗滴下落的軌跡


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


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

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

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

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

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

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

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


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

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

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

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

骨骼約束方案

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


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

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

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

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

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


布料與角色連接

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

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

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

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

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


碰撞方案

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

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

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


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

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

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

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


Face Collider

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


層間碰撞

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

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

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

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

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

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


層間穿透分離

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

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

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

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


△Cutscene Physcs Track 示例

SmoothBlendPose Track

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

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


Pose Track

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


Edit Param Track

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


Animation Track

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

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


Collider Track & Wind Track

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

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

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


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

Jobs + Burst + Mathematics

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

當(dāng)然,我們也針對性的在項(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ù)時每次都需要重新創(chuàng)建job,雖然可以提前發(fā)起任務(wù)緩解,但是依然會卡主線程。并且在執(zhí)行完成job還需要clear。基于以上的觀察,我們開發(fā)了Cache Job的方案,預(yù)先創(chuàng)建好job data,然后每次執(zhí)行時復(fù)用,避免每次重新創(chuàng)建job帶來的性能開銷。

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


Neon Intrinsics

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

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



Dot(float4)

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


Transpose(float4x4)

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

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

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


4. 碰撞檢測模塊

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

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

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

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

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


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

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

  • 定制化的Update和Trigger邏輯

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

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

查詢流程示例

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

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

因?yàn)榕鲎矙z測的功能目標(biāo)相對概括,對于精度要求沒有那么高,所以我們也適當(dāng)?shù)臓奚恍┚群喕艘恍┡鲎矙z測算法來提升性能。


觸發(fā)流程示例

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


特別聲明:以上內(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)推薦
熱點(diǎn)推薦
902km續(xù)航!新款小米 SU7 預(yù)售22.99萬起,現(xiàn)款車主怎么看?

902km續(xù)航!新款小米 SU7 預(yù)售22.99萬起,現(xiàn)款車主怎么看?

車圈小隆哥
2026-01-07 16:33:28
不到48小時,特朗普或下臺,印度多500%關(guān)稅,美國又搶千萬石油

不到48小時,特朗普或下臺,印度多500%關(guān)稅,美國又搶千萬石油

藍(lán)色海邊
2026-01-08 07:10:37
大交易要來了?特雷-楊與奇才三人今日均缺陣 名記稱談判顯著升級

大交易要來了?特雷-楊與奇才三人今日均缺陣 名記稱談判顯著升級

羅說NBA
2026-01-08 06:46:39
一夜3大消息!哈登傷情更新,勇士新決定,全明星次輪投票公布

一夜3大消息!哈登傷情更新,勇士新決定,全明星次輪投票公布

體壇小李
2026-01-07 10:02:21
比中國衛(wèi)星猛3倍!腦機(jī)接口+商業(yè)航天,6大龍頭藏不住了

比中國衛(wèi)星猛3倍!腦機(jī)接口+商業(yè)航天,6大龍頭藏不住了

Thurman在昆明
2026-01-07 13:42:37
弘一法師清醒法則:當(dāng)一個人總讓你煩躁不安,離開是最好的選擇

弘一法師清醒法則:當(dāng)一個人總讓你煩躁不安,離開是最好的選擇

杏花煙雨江南的碧園
2025-11-13 10:00:02
我那兄弟娶了個洋媳婦,天天哀嚎:摟著俄羅斯老婆睡,堪比抱刺猬

我那兄弟娶了個洋媳婦,天天哀嚎:摟著俄羅斯老婆睡,堪比抱刺猬

前沿天地
2025-12-29 11:22:33
前TVB男星參演電影《尋秦記》,因減磅變樣導(dǎo)致不連戲,自爆戲份被刪減

前TVB男星參演電影《尋秦記》,因減磅變樣導(dǎo)致不連戲,自爆戲份被刪減

TVB劇評社
2026-01-07 23:58:11
張雨綺穿搭終于找對風(fēng)格,我發(fā)現(xiàn):衣服在精不在多,這么穿更時髦

張雨綺穿搭終于找對風(fēng)格,我發(fā)現(xiàn):衣服在精不在多,這么穿更時髦

八分搭配
2026-01-05 23:46:22
伊朗總統(tǒng):每個公民少用10%電水氣,就能拯救伊朗90萬桶石油

伊朗總統(tǒng):每個公民少用10%電水氣,就能拯救伊朗90萬桶石油

桂系007
2026-01-07 03:27:21
祝賀國乒!新年開門紅連贏3個3-0,蒯曼橫掃世界亞軍約戰(zhàn)早田希娜

祝賀國乒!新年開門紅連贏3個3-0,蒯曼橫掃世界亞軍約戰(zhàn)早田希娜

全言作品
2026-01-07 23:03:16
雷軍:小米對待產(chǎn)品研發(fā)非常認(rèn)真 小產(chǎn)品想做好也不易

雷軍:小米對待產(chǎn)品研發(fā)非常認(rèn)真 小產(chǎn)品想做好也不易

手機(jī)中國
2026-01-08 09:38:50
血管堵塞的真兇是肉?是糖?都不是,而是它,比肥肉傷 10 倍!

血管堵塞的真兇是肉?是糖?都不是,而是它,比肥肉傷 10 倍!

神奇故事
2025-12-18 22:10:05
楊丞琳近況曝光!現(xiàn)身南昌,衣品卻被吐槽一言難盡,頭發(fā)又少又油

楊丞琳近況曝光!現(xiàn)身南昌,衣品卻被吐槽一言難盡,頭發(fā)又少又油

劉鑫染
2026-01-06 21:26:57
錢沒掙到人差點(diǎn)沒了!奧斯卡遭欠薪900萬,巴甲還不如中超

錢沒掙到人差點(diǎn)沒了!奧斯卡遭欠薪900萬,巴甲還不如中超

小金體壇大視野
2026-01-08 09:23:08
該國對華出口一夜之間幾乎歸零

該國對華出口一夜之間幾乎歸零

邊際財(cái)經(jīng)實(shí)驗(yàn)室
2026-01-07 11:01:52
諸葛亮最不該害死這6員大將,哪怕留1個,10個鄧艾也休想偷渡陰平

諸葛亮最不該害死這6員大將,哪怕留1個,10個鄧艾也休想偷渡陰平

銘記歷史呀
2026-01-08 07:07:21
向太爆料方媛三胎為郭富城生兒子,打破四大天王女兒魔咒

向太爆料方媛三胎為郭富城生兒子,打破四大天王女兒魔咒

胖子的勇氣
2026-01-06 19:47:36
大爺回應(yīng)拍“素顏巴黎”走紅:不會構(gòu)圖、修圖,現(xiàn)拍現(xiàn)發(fā)

大爺回應(yīng)拍“素顏巴黎”走紅:不會構(gòu)圖、修圖,現(xiàn)拍現(xiàn)發(fā)

都市快報(bào)橙柿互動
2026-01-08 00:15:42
扔醬潮來襲,閆學(xué)晶坑慘代言廠家,佐香園上架新包裝,法務(wù)行動了

扔醬潮來襲,閆學(xué)晶坑慘代言廠家,佐香園上架新包裝,法務(wù)行動了

銀河史記
2026-01-05 23:07:41
2026-01-08 10:20:49
游娛fan incentive-icons
游娛fan
精彩游戲資訊
1819文章數(shù) 463關(guān)注度
往期回顧 全部

游戲要聞

曝GTA6內(nèi)容尚未做完!連Bug都還沒來得及開始修

頭條要聞

牛彈琴:美國又干了件石破天驚的事 俄羅斯遭沉重打擊

頭條要聞

牛彈琴:美國又干了件石破天驚的事 俄羅斯遭沉重打擊

體育要聞

賣水果、搬磚的小伙,與哈蘭德爭英超金靴

娛樂要聞

《馬背搖籃》首播,革命的樂觀主義故事

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

農(nóng)大教授科普:無需過度擔(dān)憂蔬菜農(nóng)殘

科技要聞

雷軍:現(xiàn)在聽到營銷這兩個字都有點(diǎn)惡心

汽車要聞

燃油駕趣+智能電感雙Buff 試駕全新奧迪Q5L

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

本地
藝術(shù)
時尚
教育
公開課

本地新聞

“閩東利劍·惠民安商”高效執(zhí)行專項(xiàng)行動

藝術(shù)要聞

你不知道的“山麻紙”:書寫中竟藏著七重門的秘密!

藍(lán)色+灰色、紅色+棕色,這4組配色怎么搭都好看!

教育要聞

劉希婭:減少考試頻次并不直接等同于質(zhì)量提升,其關(guān)鍵在于同步推進(jìn)學(xué)習(xí)方式的系統(tǒng)性變革

公開課

李玫瑾:為什么性格比能力更重要?

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