日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

ue4集合类型_UE4粒子系统渲染管线概述

發布時間:2023/12/20 windows 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ue4集合类型_UE4粒子系统渲染管线概述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文基于UE4版本4.25.3,對Cascade粒子系統的移動端渲染管線進行簡單的概括和描述。

Game Thread部分

粒子系統Actor被Spawn(或所在的Level被加載)的時候,UParticleSystemComponent注冊和初始化,并通過CreateSceneProxy函數注冊和創建FParticleSystemSceneProxy。

UParticleSystemComponent的主要數據成員是TArray<struct FParticleEmitterInstance*> EmitterInstances,包含粒子系統的所有粒子發射器。每一個粒子發射器對應一個FParticleEmitterInstance,管理當前發射器下所有的粒子。

FBaseParticle為粒子數據結構,保存粒子的Location、Rotation、Size和Velocity等數據。FParticleEmitterInstance用uint8* ParticleData指向保存FBaseParticle類型數據集合的連續內存空間。

UParticleSystemComponent關聯的所有粒子數據內存空間只由GameThread訪問。在幀結束的時候通過UpdateDynamicData函數創建一份包含粒子內存數據的拷貝——FParticleDynamicData,并異步傳遞給FParticleSystemSceneProxy,供RenderThread渲染使用。

大部分情況下,UE4通過給渲染線程生成一份渲染數據拷貝和函數線程專用(比如函數后綴加_RenderThread)的方式來防止出現多線程渲染的Race Condition問題。

GameThread部分調用示意圖

Render Thread部分

在FParticleDynamicData被GameThread傳遞過來之后,粒子系統的渲染真正開始。

粒子系統的渲染始于FParticleSystemSceneProxy::GetDynamicMeshElements函數,輸出FMeshBatchs。FMeshBatch是FParticleSystemSceneProxy到MeshDrawCommand之間的一個中間數據結構,主要包含頂點數據流(FVertexStream)、IndexBuffer和材質等。

粒子系統渲染用到的頂點數據流主要有兩個:索引為0的幾何數據流和索引為1的Instanced數據流,由FParticleSpriteVertexFactory創建和關聯。幾何數據流描述每個粒子的幾何結構為4個頂點構成的單位大小的正方形。Instanced數據流為粒子數據集合,用于以Instanced的方式繪制這些粒子正方形。

Instanced數據流由FParticleDynamicData初始化而來。因為FParticleDynamicData的數據內容主要是GameThread使用的FBaseParticle類型數據集合的拷貝,所以RenderThread通過FDynamicSpriteEmitterData::GetVertexAndIndexData函數把原類型數據集合轉換成渲染使用的FParticleSpriteVertex類型數據集合。FParticleSpriteVertex定義了需要傳入GPU的頂點數據結構,與ParticleSpriteVertexFactory.ush 定義的頂點輸入類型FVertexFactoryInput對應。

為什么GameThread和RenderThread要分別定義粒子數據結構?GameThread對粒子的抽象是一個Pivot點,更新的是這個Pivot點的位置、旋轉和Size等信息。而RernderThread把粒子點幾何化為一個4個頂點,2個面構成的單位正方形,渲染的時候基于粒子Pivot點的位置、旋轉和Size等信息把粒子的4個頂點計算并繪制出來。

FMeshBatch生成后,進入到MeshDrawCommand的構建階段。FMeshBatch與MeshDrawCommand可理解為一對n的關系,n的值取決于該Mesh會被多少個EMeshPass處理。比如,產生實時陰影的不透明Mesh會被DepthPass、CSMShadowDepth和BasePass 三個EMeshPass處理來分別構建MeshDrawCommand。

為什么需要定義不同的EMeshPass?不同的EMeshPass繪制關聯的頂點數據流,Shader和渲染狀態等不一樣,比如DepthPass的繪制只需要設置頂點位置數據流(PositionOnlyStream),關聯的Shader主要功能為Vertex的空間變換和Pixel的深度輸出,不用做光照計算等。

對粒子系統來說,一般不寫場景深度,不產生陰影,所以DepthPass和CSMShadowDepth的MeshDrawCommand構建過程會被過濾掉。BasePass的構建始于FMobileSceneRenderer::SetupMobileBasePassAfterShadowInit函數,在關聯好Shader,設置好TaskContext渲染狀態等之后,調用BuildMeshDrawCommands函數真正進行MeshDrawCommand的構建。

所有相關EMeshPass的MeshDrawCommand構建好之后,開始MeshDrawCommand的提交和繪制。BasePass的繪制始于FMobileSceneRenderer::RenderMobileBasePassBasePass函數,然后根據構建階段生成的TaskContext渲染狀態設置PipelineState,根據MeshDrawCommand關聯的頂點數據流設置StreamSource等,最后調用RHICmdList::DrawIndexedPrimitive完成繪制。

構建MeshDrawCommand階段引擎默認是渲染線程起Work線程來并發執行,可以設置Console命令r.MeshDrawCommands.ParallelPassSetup=0來關掉并發,最后的Mesh繪制可以設置r.RHIThread.Enable=0來關掉RHI線程平臺相關的繪制API的調用,這樣上述所有階段都在RenderThread依次順序執行,方便調試。

RenderThread部分調用示意圖

PS:UE4引擎的代碼量巨大,流程龐雜,單扣一個小細節就可能要研究上好幾天,想要用短短幾頁文字把渲染管線描述清楚難度很大,而且還需要一些寫作技巧使得描述不失偏頗,有點理解官網文檔的“言簡意賅”了(doge~~~

參考文獻:

  • Mesh Drawing Pipeline
  • Threaded Rendering
  • 總結

    以上是生活随笔為你收集整理的ue4集合类型_UE4粒子系统渲染管线概述的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。