<ruby id="9ue20"></ruby>

  1. 
    

      国产午夜福利免费入口,国产日韩综合av在线,精品久久人人妻人人做精品,蜜臀av一区二区三区精品,亚洲欧美中文日韩在线v日本,人妻av中文字幕无码专区 ,亚洲精品国产av一区二区,久久精品国产清自在天天线
      網易首頁 > 網易號 > 正文 申請入駐

      UE5 Chaos物理|物理查詢的實現

      0
      分享至


      【USparkle專欄】如果你深懷絕技,愛“搞點研究”,樂于分享也博采眾長,我們期待你的加入,讓智慧的火花碰撞交織,讓知識的傳遞生生不息!

      這是侑虎科技第1977篇文章,感謝作者南京周潤發供稿。歡迎轉發分享,未經作者授權請勿轉載。如果您有任何獨到的見解或者發現也歡迎聯系我們,一起探討。(QQ群:793972859)

      作者主頁:

      https://www.zhihu.com/people/xu-chen-71-65

      射線檢測接口

      游戲業務常見的需求就是做各種射線檢測/Overlap檢測/Sweep檢測,比如Character Movement Component。

      下面例子是使用Visibility Channel做Line Trace,StaticMesh對其是Block的。




      各種Trace,最終都調用到SceneTrace。


      使用的TraceChannel,ObjectType等條件,最終都編碼成四個4B的Word,下面是TraceChannel的例子。


      物理查詢,主要就是對AABB Tree的查詢。

      SceneTrace

      ReadLock

      要對物理場景做查詢,首先加讀鎖。可以和其他Trace請求同時執行,但和寫物理場景操作互斥。



      然后獲取加速結構Collection,里面有Static AABBTree和Dynamic AABBTree。


      最后進到TSpatialAccelerationCollection::RaycastFast。

      這里Types就是Buckets,TypeIdx是從0開始的下標,會逐個遍歷Buckets,然后對里面的每個AABBTree,調用RaycastFast函數。


      注意第一個Bucket存了非常大的AABB,也就是說如果場景內有很多大的物體,是會拖慢射線檢測效率的。

      TAABBTree::QueryImpl

      比較大的函數,做AABBTree的遍歷。

      AABBTree非葉節點的遍歷

      經典的BVH檢測方式,先檢查射線和左右子樹AABB是否相交,然后根據相交情況,不斷對左右子樹做遍歷。加速方式為SIMD的應用,以及非遞歸的遍歷AABBTree。


      示意圖如下:


      SIMD版本的Slab算法值得一看,判斷射線與AABB是否相交,并計算射線在AABB內經過的距離。全程無if...else...。


      里面的VectorMax和VectorSwizzle的組合比較巧妙,用于在三個數中取最大的。

      Slab算法簡介

      Slab算法(Slab Method)是計算機圖形學和物理引擎中用于檢測射線(Ray)與軸對齊包圍盒(AABB)是否相交的最經典、最高效的算法。

      它的核心思想非常簡單直觀:將3D的AABB盒子看作是三組無限大的“平板對”(Slabs)的交集。

      假設射線的起點為P,方向為Dir,把射線寫成時間t的方程:


      射線進入每個“平板對”,都會有進入時間t0和離開時間t1,如果要與AABB發生重疊,三組t0和t1必定有都重疊的部分。

      示意圖如下:


      處理葉節點

      對于一個Leave節點,射線檢測會執行RaycastFastSimd。


      每個Leave節點默認最多有8個Element,它們沒有位置關系,因此要逐個對這些Element做射線檢測了。

      對于Leave中的一個Element,計算和射線是否相交,會經過三道判斷。第一道是檢查Shape的AABB和射線是否相交,第二道是檢查Shape的Channel和QueryChannel是否是Overlap或者Block關系,第三道是真正檢查射線和Sphere、Box、凸包等幾何體是否相交。前兩道是輕量的,算BroadPhase,第三道很重,是NarrowPhase。



      把Channel Response檢查放到中間也是挺有意思的。按照正常人類思考邏輯,應該是射線碰到一個Geometry后,再判斷這個Geometry對射線Channel響應是Block還是Overlap,但判斷射線和Shape相交的操作比較重,尤其是面對凸包。因此從代碼效率邏輯出發,就變成了不管Shape和射線是否真的相交,先判斷Geometry對Channel的響應,如果是Ignore,就直接不管了。具體做法如下:

      第一道,射線和AABB Bounds檢查是否相交。

      同樣的,用SIMD判斷射線和AABB是否相交,不再贅述。

      第二道,射線檢測用的Channel和Geometry的ResponseChannel & BlockChannel是否有重疊。

      ResponseChannel & BlockChannel是兩個int32,本身是每個Geometry的屬性,但AABBTree為了效率,在Payload里都緩存了一份,為UnionQueryFilterData和UnionSimFilterData,CachedUniqueIdx則是所屬UObject的UniqueIdx緩存。

      具體的Channel Response過濾方法。

      PrePreQueryFilter


      首先從Word0中獲取射線檢測使用的Channel,然后檢查Geometry自身的Word1和Word2,分別是BlockingChannel和OverlapChannel,做bit and操作,看是否有交集。


      注意這里的函數名是PrePreQueryFilter,說明后面還有PreQueryFilter流程。

      射線和各種幾何體相交判斷

      第三道,真正的射線和幾何體相交檢測。


      PreQueryFilter

      幾何檢測前,先執行一些自定義邏輯的Filter做過濾,判斷是否要做對Shape的射線檢測,可以做游戲業務相關的操作。注意到例子中的射線檢測是按照LineTrace BlockChannel做的,但目前OverlapChannel的Shape也還沒被排除,排除操作就是在PreQueryFilter階段做的,實際會調用FCollisionQueryFilterCallback::PreFilterBaseImp函數。

      首先對比查詢的Channel,和Shape的OverlapChannel & BlockingChannel,判斷這次查詢是Touch還是Block,稱為CollisionQueryHitType。

      如果是LineTraceSingle,那么只關心BlockingChannel,TouchChannel的Shape可以忽略。


      查詢的Touch/Block和Shape的ResponseChannel比對通過后,再判斷IgnoreActors和IgnoreComponents是否需要過濾,LineTrace時通常會設置IgnoreActors。


      FCollisionQueryFilterCallback::PreFilter檢查通過后,正式進入射線和幾何體相交計算。

      世界空間坐標和Geometry局部空間坐標

      此時射線的起點和方向都是世界坐標,在檢測前先變換到Geometry的坐標空間,后面計算起來會更加方便。比如對Box檢測時,直接用AABB射線檢測算法即可。


      射線和不同幾何體相交計算

      這里不僅要判斷是否相交,還要得到射線接觸的位置,初次接觸幾何體的距離,以及接觸點的法線。每個幾何體都實現了Raycast函數,觀察不同幾何體的實現。

      TSphere

      球形判斷是最簡單的。


      令直線起點為P,方向為dir,直線方程為:


      設圓心為C,半徑為R,直線和圓相交,需要滿足以下方程:


      這是關于t的一元二次方程,用公式求出t即可。

      有了時間t,就能快速求出交點坐標和交點法線了。


      Tbox

      最終執行的AABB,計算開銷比球體高些。


      對于三組Slab,都分別計算進出時間t0、t1,然后取交集,得到時間t,再得到交點。法線總是XYZ三個方向,計算t0屬于哪個面即可。


      FCapsule


      Capsule可以想象成,到線段最短距離為r的點,形成的距離場,線段作為Capsule的軸心。


      那么判斷射線和膠囊體是否相交,計算這個軸心線段到射線的最短距離即可,具體計算上,需要找出一對距離最近的點。

      真正困難的地方在于,線段上的最近點,位于線段中間。直接貼一個已有算法,核心是找出兩個平面的相交線,理解起來需要點時間,但計算步驟并不多。

      參考:

      https://johnmayhk.wordpress.com/2012/02/02/shortest-distance-between-two-skew-lines/


      如上所示,最短距離就是BD在MN上投影的長度,而MN同時垂直AB和CD,另外ABXCD得到的向量也同時垂直AB和CD,因此MN與(ABXCD)平行。由此可得到最短距離。

      有了距離,就能解出兩個點了。

      UE也實現了這個算法,封裝于SegmentDistToSegmentSafe函數,主要步驟如下:


      當射線與Capsule相交后,還需要進一步求交點和normal。

      分兩種情況:

      1. 與上下兩個半球相交,normal從球心出發

      2. 與中間圓柱體相交,計算圓柱體的normal

      FConvex凸包

      最復雜,使用了GJK算法,不再展開


      和Shape發生碰撞后怎么辦?

      當前的Hit類型是ChaosInterface::FLocationHit,先填充Hit的這幾個屬性:


      之后再給個機會執行FCollisionQueryFilterCallback::PostFilter,如處理bDiscardInitialOverlaps過濾等。

      然后把Time作為Distance記下,表示射線已經打了多遠,對后續Shape做射線檢測時,將從最新的Distance開始,繼續往后打射線。

      回到AABB子樹的遍歷,如果要判斷多個子樹,但射線在之前已經Block了,就不用判斷之后的子樹了。


      FHitResult的填充

      FHitResult展開后有如下屬性,其中大部分在之前射線發生碰撞時已經可以得到,只有黃線畫出的幾個需要看下如何獲取。


      PhysMat

      命中點的物理材質,物理材質可以理解為類似渲染用的材質,只不過描述的是物體表面的摩擦力、密度等屬性。當前已經有了FaceIndex,而Geometry中記錄了FaceIndex和PhysicsMaterial的對應關系,因此可以得到PhysicsMaterial。


      BoneName

      命中點所屬骨骼的名稱。

      對于示例中的StaticMesh,是沒有骨骼的,因此是None,只有對于SkeletalMesh,這個BoneName才有意義。


      觀察SkeletalMesh的PhysicsAsset,多個骨骼上會掛接RigidBody,它們有各自對應的BodySetup,BoneName就存在BodySetup里。射線檢測時,可以根據命中的GeometryParticle獲取到BodyInstance,再獲取到BodySetup,最終得到BoneName。


      HitItem & ElementIndex

      都屬于一些Extra數據,不太重要。

      HitItem是BodyInstance在整個PhysicsAsset中的序號,針對SkeletalMesh的情況。ElementIndex是Trace中Shape在Geometry的Shape數組中下標。對于示例中的StaticMeshComponent,它們都是0。


      完整的LineTrace流程如下:


      Overlap檢測

      第二種碰撞檢測是Overlap檢測,比LineTrace更復雜些,會判斷一個體積內有沒有和其他物體相交。這里以Box碰撞體為例,需要傳入Box的位置和大小,區別于之前的LineTrace使用TraceChannel,這里使用了ObjectTypes,查詢Box范圍內重疊的其他Actor。但對于物理引擎而言,TraceChannel和ObjectTypes本質都是一樣的,都是CollisionChannel。



      首先,把查詢的Geometry計算一個AABB包圍盒,傳入AABBTree做BroadPhase的檢測。


      AABBTree的左右子樹Overlap

      對左右子樹分別做AABB的碰撞檢測。



      Leaf節點的處理

      TAABBTreeLeafArray.OverlapFast

      對Leaf中每個Payload Geometry,同樣先做AABB碰撞檢測。用了SIMD技術,四個Payload為一組。當AABB檢測通過后,依然先執行PrePreFilter,做Channel之類的判斷,再針對具體的Geometry Shape形狀,做Narrow Phase的Overlap檢測。


      Shape可以有Sphere、Box、Capsule、凸包等各種幾何形狀,但它們都屬于凸包。要判斷兩個凸包是否Overlap,就要用GJK算法,UE的實現是GJKIntersection函數,自然也是SIMD實現。


      GJK算法

      關于GJK算法的詳細介紹,可以看這里:

      看似簡單的復雜問題,奇怪而優雅的解決方式(GJK算法)

      https://www.bilibili.com/video/BV16P4y1q7GZ/?spm_id_from=333.337.search-card.all.click&vd_source=43d3ce94d2854f1bf3d667631d4a0e98

      總體過程是不斷通過Support函數,在兩個凸包上找一對點,計算閔可夫斯基差,然后讓形成的三角形包含原點。GJK算法有點復雜,不展開了,但不同Shape的Support函數實現可以看下,具體就是每個Shape的SupportCore函數。


      所謂Support函數,就是給定一個方向,找到Shape在這個方向上最遠的一個點,下圖就是兩個例子。

      簡單起見只看SupportCore普通版本,SIMD版本思想類似。

      TBox

      等價于對一個AABB求Support點。不難理解,AABB在某個方向上的最遠點必定是8個頂點之一,因此只要依次判斷三個軸,做三次方向二分即可,2^3 = 8。



      TSphere

      最簡單,球的中心加上半徑*方向即可。



      FCapsule

      看似復雜,實則和Sphere一樣簡單。Capsule的Support點必定出現在兩個半球上,因此首先根據Direction方向確定是哪個半球,然后類似Sphere處理即可。



      FConvex

      需要遍歷所有凸包的頂點,與方向做點乘,找到最遠的點。


      這里實現也比較有意思,尋找凸包的Support點,理論上用啟發式的“爬山法”更快,即從上個Support點往后找鄰接點,不用遍歷所有頂點,而且UE是保存了邊的連接關系的:


      那為什么不用爬山法?個人猜測是以下幾個原因:

      • 直接遍歷Vertices數組,CPU Cache更友好,在頂點數量不多(也是大部分情況)情況下可能更快。

      • 爬山法需要記錄上一次的Support點序號,但碰撞檢測可能多個線程并行,這樣就需要為每個線程都記錄一份上次的Support點了,實現有點麻煩,而且得保證線程安全。

      如果要得到Overlap深度,就要使用GJKPenetration算法, 結合了GJK與EPA,這里不展開了。

      Sweep檢測



      最復雜的情況,以Box Sweep為示例,會得到Sweep路徑上發生重疊的物體。

      BroadPhase

      類似Overlap,但把Sweep經過的整個路徑,作為AABB,查詢與左右子樹的碰撞情況。



      NarrowPhase

      對于Leaf節點中的每個Geometry,同樣經過PrePreFilter,AABB檢測,PreFilter。

      對Geometry中每個Shape的Sweep檢測,最后依然使用GJK算法。


      如果是TriangleMesh復雜碰撞怎么辦?


      首先,Shape就變成了FTriangleMeshImplicitObject,類似Mesh,沒有凸包的限制,可以表示任何形狀。因此,類似GJK這種精妙的幾何碰撞算法都不再適用,只能回歸最原始的三角形相交判斷。


      Raycast & Overlap & Sweep

      BroadPhase相同,使用AABBTree。

      NarrowPhase不使用GJK算法了,而是每個TriangleMesh自己有一個BVH樹,用BVH的碰撞檢測方式。BVH子節點存儲了三角形,在檢測子節點內部碰撞時,采樣逐三角形檢測方式。

      比如這個例子,BVH樹有379個節點,模型總共有5760個面,還是非常復雜的。

      Tips

      綜合上述碰撞檢測流程,可以對物理場景優化做一些指導:

      • 游戲中物體都設置專門的Simple Collision,避免查詢復雜碰撞

      • Shape的碰撞檢測效率排序:Sphere > Capsule > Box >> Convex >>>> Triangle Mesh,盡量用效率高的Shape做近似

      • 避免太長的LineTrace,以及范圍太大的Overlap和Sweep

      • LineTrace查詢的開銷最低,玩法上盡量用它

      文末,再次感謝南京周潤發的分享, 作者主頁:https://www.zhihu.com/people/xu-chen-71-65, 如果您有任何獨到的見解或者發現也歡迎聯系我們,一起探討。(QQ群: 793972859 )。

      近期精彩回顧



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

      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.

      相關推薦
      熱點推薦
      滿城臭味中準備對烏大空襲,俄軍展示縮水版“火烈鳥”導彈

      滿城臭味中準備對烏大空襲,俄軍展示縮水版“火烈鳥”導彈

      鷹眼Defence
      2026-05-13 17:21:14
      美以伊戰爭期間以總理密訪阿聯酋

      美以伊戰爭期間以總理密訪阿聯酋

      財聯社
      2026-05-14 01:24:11
      快速入睡無成癮!又一國產安眠新藥即將落地,3億失眠人有解了?

      快速入睡無成癮!又一國產安眠新藥即將落地,3億失眠人有解了?

      思思夜話
      2026-05-12 16:51:58
      謝暉現狀:重返上海申花,俄羅斯妻子風韻猶存,兒女雙全財富自由

      謝暉現狀:重返上海申花,俄羅斯妻子風韻猶存,兒女雙全財富自由

      梁岱愛玩車
      2026-05-03 18:54:17
      太二門店圍擋火出圈,創意根本沒有瓶頸期

      太二門店圍擋火出圈,創意根本沒有瓶頸期

      4A廣告網
      2026-05-11 17:49:20
      越來越多的縣城,只剩下體制內經濟了!

      越來越多的縣城,只剩下體制內經濟了!

      黯泉
      2026-05-13 11:15:55
      別光盼特朗普專機,魯比奧突抵北京,信號遠超訪問本身

      別光盼特朗普專機,魯比奧突抵北京,信號遠超訪問本身

      老鵜愛說事
      2026-05-14 06:14:37
      今夏最值錢自由球員誕生!四隊瘋搶陳盈駿,頂薪被鎖何去何從?

      今夏最值錢自由球員誕生!四隊瘋搶陳盈駿,頂薪被鎖何去何從?

      寶哥精彩賽事
      2026-05-14 00:34:11
      熱搜!上海迪士尼優速通惹爭議,誰花錢多讓誰進?“奇夢之地也遵循商業邏輯”

      熱搜!上海迪士尼優速通惹爭議,誰花錢多讓誰進?“奇夢之地也遵循商業邏輯”

      北京商報
      2026-05-13 15:40:21
      夜景中的美女,身材真好

      夜景中的美女,身材真好

      藍色海洋009
      2026-05-13 17:06:46
      性生活不足,原來會短壽!每周多少次比較合適?研究告訴你答案

      性生活不足,原來會短壽!每周多少次比較合適?研究告訴你答案

      醫學原創故事會
      2026-05-12 15:34:03
      長得帥在生活中有多大優勢?網友:特別舍得給老公花錢

      長得帥在生活中有多大優勢?網友:特別舍得給老公花錢

      另子維愛讀史
      2026-05-13 22:40:33
      開15年汽修店老板揭秘:保養車最坑的2個智商稅,90%車主都交過

      開15年汽修店老板揭秘:保養車最坑的2個智商稅,90%車主都交過

      老特有話說
      2026-05-13 21:38:29
      加速糖尿病惡化的行為:甜食排第7,第1名很多人都沒意識到

      加速糖尿病惡化的行為:甜食排第7,第1名很多人都沒意識到

      冷眼看世界728
      2026-05-13 21:26:22
      編外人員“清退”開始,城管協管、輔警、護士教師都在其中

      編外人員“清退”開始,城管協管、輔警、護士教師都在其中

      巢客HOME
      2026-05-14 05:55:06
      重慶何主任:穿高跟開車撞飛8人,多重身份被扒,丈夫是電力領導

      重慶何主任:穿高跟開車撞飛8人,多重身份被扒,丈夫是電力領導

      小鋭有話說
      2026-05-13 15:51:53
      馬斯克點贊宇樹載人機甲:很酷!

      馬斯克點贊宇樹載人機甲:很酷!

      時間財經
      2026-05-13 20:12:22
      程維高并非被一擼到底,下臺后享受副省級待遇,活了78歲

      程維高并非被一擼到底,下臺后享受副省級待遇,活了78歲

      史不語
      2026-05-13 08:10:10
      扛住壓力了!馬刺替補中鋒為文班亞馬爭取到了10分鐘的出場時間?

      扛住壓力了!馬刺替補中鋒為文班亞馬爭取到了10分鐘的出場時間?

      稻谷與小麥
      2026-05-13 23:58:11
      孫穎莎奪冠第一個抱住的人,不是馬琳不是邱貽可,而是當陪練的她

      孫穎莎奪冠第一個抱住的人,不是馬琳不是邱貽可,而是當陪練的她

      白面書誏
      2026-05-13 17:25:06
      2026-05-14 08:04:49
      侑虎科技UWA incentive-icons
      侑虎科技UWA
      游戲/VR性能優化平臺
      1575文章數 987關注度
      往期回顧 全部

      科技要聞

      阿里年營收首破萬億,AI終于不再是畫大餅

      頭條要聞

      中東戰火燒痛印度 莫迪六天訪五國要外交“救國”

      頭條要聞

      中東戰火燒痛印度 莫迪六天訪五國要外交“救國”

      體育要聞

      14年半,74萬,何冰嬌沒選那條更安穩的路

      娛樂要聞

      白鹿掉20萬粉,網友為李晨鳴不平

      財經要聞

      美國總統特朗普抵達北京

      汽車要聞

      C級純電轎跑 吉利銀河"TT"申報圖來了

      態度原創

      本地
      時尚
      游戲
      公開課
      軍事航空

      本地新聞

      用蘇繡的方式,打開江西婺源

      專欄 | 進入心流后,不被洪流裹挾

      三角洲行動那些玄學設定,很多玩家可能都經歷過這些事情

      公開課

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

      軍事要聞

      美以伊戰爭期間以總理密訪阿聯酋

      無障礙瀏覽 進入關懷版 主站蜘蛛池模板: 亚洲最大成人AV在线天堂网| 人妻少妇久久中文字幕| 亚洲无人区码一码二码三码的含义| 国产精品日韩欧美一区二区| 国产精品无码翘臀在线看纯欲| 国产福利深夜在线播放| 最新精品国偷自产在线美女足 | 日韩AV无码精品| 亚洲娇小与黑人巨大交| 天天摸天天碰天天添| 国产亚洲精品第一综合| 国产乱淫a∨片免费观看| 一本色道综合久久欧美日韩精品| 亚洲AV乱码毛片在线播放| 亚洲高清国产成人精品久久| 五月天丁香网| 老湿视频国产二区| 黄色三级A片| 久久精品国产男包| 久久午夜无码鲁丝片直播午夜精品 | 国产在线你懂| 美女A级毛片永久地址| 图片小说视频一区二区| 久热99热这里只有精品| 亚洲日韩乱码中文无码蜜桃臀| 日本三级电影网| 国产亚洲精品综合在线网址| 国产精品免费视频网站| 亚洲天堂一区二区三区四区| 大地资源免费视频观看| 中文字幕av久久爽一区| 人妻偷人精品| 亚洲成a人片77777国产| 极品白嫩少妇无套内谢| 91亚洲一线产区二线产区| 中国成人XXXX高清视频| 欧美色综合| 欧美三级不卡在线观看视频 | 久久精品波多野结衣| 亚洲二区av| 奇米影视777四色米奇影院|