標題的功能是公司以前專案中的新加的功能,之前的滑鼠物體拾取是通過cpu計算射線和物體aabb相交來判斷,但這種方式存在很大弊端,如果物體成長條形,那麼在某些角度下aabb就比物體大的多,再者像一些鏤空很多的物體,如蜘蛛、柵欄等,會遮擋後面物體的拾取,要能夠精確的判斷的話,就需要做射線和模型三角網格的相交檢測,由於可選擇的物體可能很多,模型也可能會很複雜,所以在沒有簡化網格的情況下這個計算量可能非常大,耗時長。討論解決辦法時同事建議在畫素級別來做這個操作,於是眼前一亮,想了下覺得可行,然後下來經過幾番思考,最後結合專案得到如下解決方案,可以作為3d遊戲拾取方案的參考。
在涉及具體方案前先說下幾個專案涉及到的問題
1、物體拾取時有型別優先順序,比如:npc要優先選擇,如果npc被周圍玩家完全遮擋,那麼npc要優先能被選中。
2、拾取邏輯和後續事件處理邏輯的協調。
3、效率及優化
先說下畫素拾取方法,原理很簡單,通過額為的渲染將物體的指標或者id號作為顏色傳給pixel shader輸出到texture,cpu回讀這個texture,然後通過獲取畫素點顏色值,確定被選中的物體。
完整的解決方案分如下幾步:
1、視錐體裁剪不可見物體(一般渲染步驟會包含這個操作)
2、按物體型別,進行射線和aabb相交,進一步裁剪,並記錄哪些物體和型別需要做拾取判斷
3、按型別進行拾取渲染,每種型別用乙個rtt,跳過不需要拾取的型別的渲染
4、回讀需要判斷型別的texture到記憶體,按型別優先順序判斷是否有物體被拾取到,如果有選中則可以跳過後續型別的判斷,沒有則繼續判斷下一型別
5、如果最終有選中物體,則進行滑鼠事件處理
上述步驟中,第五步涉及到前面提到的問題2和3,原因是:按照一般的幀迴圈邏輯,是先framemove後render,而畫素拾取必須要render後才能得到結果。當然等畫素拾取後再處理滑鼠事件也可行,但是這樣會讓cpu和gpu相互等待,破環工作的非同步性,更優化的辦法是把獲取結果和滑鼠事件處理放到下一幀的開始去做。根據具體情況,可能還需要和ui滑鼠事件協調,如果有ui滑鼠事件,則可以忽略結果獲取和處理。
在整個解決方案中還有個非常需要優化的地方,就是texture的回讀,因為cpu回讀gpu資料是乙個非常耗時的操作,所以進行了兩個處理:
1、為了提高cpu和gpu並行性,每種有拾取判斷型別的texture都會完整回讀到記憶體,而不是直接到gpu中去取畫素點的值,同時為了減少回讀資料,每個texture大小為3x3的9個畫素(理論上1個畫素點就夠了,但覺得有點不踏實)。
2、為了只記錄以滑鼠點為中心的9個畫素值,追加了一次2d的二次投影。
總的來說畫素拾取可以很精確的的進行拾取操作,對幀率的影響也很小,經測試專案以70幀的話會有1、2幀的影響,當然畫素拾取也並非完美,比如:對渲染出來很小或很細的物體很難拾取,對蛇這種帶動畫的物體也有同樣問題,可以考慮渲染拾取畫素時加個矩形等等,這個問題還沒有想到完美的解決辦法。就目前來說還有個問題就是由於沒有進行射線三角形相交測試,所以不能確定滑鼠點中點的世界座標,要解決這個問題只要在拾取渲染同時將畫素3d座標也輸出就可以實現,專案沒有這個需求,解決方案就沒加這點。
從這個解決方案也可以看出,其實用畫素來進行物體拾取判斷的技術本身非常簡單,但是要作為乙個功能模組整合到專案中或引擎中則還需要做很多任務作,這也是ce、ue等通用引擎難得的地方:把很多簡單的技術或方法整合到一起相互協調並高效的工作。
D3D 滑鼠拾取技術
d3d 滑鼠拾取技術對用directx編寫網路遊戲的愛好者,尤其是初學者來說是一項非常重要的藥掌握的技術。開始學寫遊戲時,它總是困擾著初學者.我這會兒剛完成了,寫點心得 新手分享 就說說思想,畢竟,有了思想,技術上很好實現.首先呢,我們可以通過獲得視窗上滑鼠的然後呢,將它轉化到世界矩陣裡.呵呵,這點...
不要為3d而3d
和以前的幾個朋友聊天,也有做game的。發現大家對3d技術都非常熱衷,但是這種熱衷顯得刻意的 為3d而3d,就有點捨本逐末。1 遊戲最重要的是策劃,需要具體的滿足人心底的某種需求,2 3d需要 好顯示卡的支援,這樣就將一部分使用者排斥在外面了。3 現在3d engine已經 很成熟了,通過這些上面的...
滑鼠移動3D翻轉動畫特效
好久沒有更新文章咯,今天我為大家帶來乙個酷炫的3d翻轉特效效果例子 該效果是用的純html css3實現的哦 特別指示 1 用到咯 perspective 2 transform style 該屬性也是3d效果中經常使用的,其兩個引數,flat preserve 3d.前者flat為預設值,表示平面...