許多人可能直接拿一些水插件就直接套上專案,但在開發中後期可能會發生許多整合方面的問題,這時候花些時間理解其中組成的模組是必要的,甚至還可以達到客製化的目的,而projected grid就是無限大海水方案的基礎模組之一。
與食人魔獸之間的恩怨情仇
遊戲引擎研發,遊戲開發,遊戲程式,3D程式,Ogre3d
2023年2月21日 星期二
2023年2月10日 星期五
關於FairyGUI或GUI以StackingCamera受到RenderScale影響的解決方案
自從URP問世之後,ScaleRender便在Unity成為主流,他是優化行動裝置3D渲染的一個好方法,當然之前也是有不少人在默認管線下做過這類的應用…
後來URP也加入了類似默認管線疊合(Stacking)渲染的處理流程,但稍微有研究的人就會發現他會受RenderScale參數的影響,如果拿來畫UI的話,那有關字及ICON的顯示可能會是場災難。
有人說那就用Overlay模式來畫UI就好,但專案還是會有一些特殊的需求要用Camera來畫,另外像FairyGUI大部份都是用Camera來渲染的系統,就影響很大了,也總不能為了UI的品質來禁用RenderScale的參數。
之前沒使用過FairyGUI,因為工作關係接觸了之後,發現他與URP整合上有一些問題,主要是大部份都是用Camera來畫,這樣一來就得走StackingRender的流程,不像UGUI還有Overlay模式可用,於是開啟了FitRenderScaleURP之旅。
2023年1月9日 星期一
簡單的FragmentShader light culling forward plus(面向行動平台)
最近Forward plus成為比較熱門的渲染管線之一,連Unity在新版本也在開發中,他採用的方式是用Job來做culling,我自己實作的方式是用ComputeShader來做culling,相關連結如下:
AkilarLiao / ForwardPlusURP
但目前這些主流的做法,幾乎都會用到SSBO,另外內存的使用也比較大,想一想其實上帝視角Z值的疊合狀況不是那麼嚴重,所以在想有沒什麼簡單的方式,可以單純使用一個FragmentShader來處理像素等級的剃除,於是開啟了FragmentShader light culling forward plus之旅…
2022年12月31日 星期六
用MRT來優化SSAO在行動平台的性能
對於行動平台使用深度貼圖,有經驗的人應該都知道Unity曾經不管三七二十一,只要是gles,一律走perDepthPass,而不走CopyDepth的流程,其實這個限制應該只是有在使用硬件MSAA的時候,才有這個問題,這曾經困擾了許多人,後來官方在新的版本做調整,讓大家鬆了口氣…
我在測試官方的ScreenSpaceAmbientOcclusion時,發現他的Depth Normals模式,不管是不是AfterOpaque,一律都走perDepthNormalPass,這對行動行台非常不友善,就跟perDepthPass是一樣的問題,雖然他有提供純Depth模式+AfterOpaque可以避免這個問題,但沒有normal效果就是比較差,所以便開啟了MRT + SSAO之旅(許多人把MRT跟延遲渲染畫上等號,但其實是可以應用在優化處理上)
2022年12月26日 星期一
VRM and QT初體驗(QT+VRM+UDP+Unity)
最近VTuber+VRM蠻紅的,想說也來把玩一下,另外很久沒有做embed 3d engine into native application,於是開啟了QT+VRM+UDP+Unity之旅,雖然之前是有開發過Ogre3D+MFC的工具,但embed Unity into QT還是第一次,由於Unity沒提供任何對外溝通訊息接口,在Google上找得到的解決方案,都是導向本機UDP訊息傳輸的做法,所以只好硬著頭皮做QT+VRM+UDP+Unity…
關於VRM整合的部份,請參考vrm-c / UniVRM,由於VRM1.0有整合自動撥放表情,所以就以整這個為主,但由於目前的版本只支持runTime parse的做法,所以這邊另外寫了一個可以輸出prefab的相關功能,並將相關的貼圖、mesh、材質保存出來(跟univrm插件差不多),這樣可以大大減少runTime parse的時間及達成資源共用的目標。
相關視頻結果如下:(可選擇右邊的QT button來切換動作撥放的狀態)
後記:之後再來看看動捕的部份…
Dream continues in...
2022年6月8日 星期三
關於超大地圖Recastnavigation尋路資料建立的做法
由於專案有複雜超大地圖(unity單位15000*15000)的需求,在Recast資料建立上遇到了一些問題…
- 整塊大地建立不出來,發生了以下的錯誤…
if (maxVertices >= 0xfffe)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many vertices %d.", maxVertices);
return false;
} - 就算是分了區塊,但因為Recast底層建立的函式,無法並行建立,所以造成了建立時間過久的狀況(超過一天以上)
- 自行實作一個建立console工具程式,並用批次檔來運行多個執行檔,來達到並行建立區塊的目的。
- 最後將相關的區塊移到unity裡來進行彙整,並輸出跨區域尋路的整塊地圖。
2021年10月27日 星期三
關於GPUInstance與GPU VS CPU culling的恩怨情仇
大家應該都知道GPUInstance是拿來畫大量物件的重要利器,但他最大的問題,就是沒有處理Culling,當拿來畫同一種巨量草之類的,面數少的話,應該是沒什麼問題(同種類,只需傳送一次Mesh資料,數量多的話,因為面數少,所以vertex shader處理次數少,也還ok)。但當我們把鏡頭拉近的時候,其實剔除處理就變得很重要,否則有可能GPU instance會比一般用page culling的drawMesh API性能還來得差…
那我們如果幫GPUInstance也切page的話,情況就會變好嗎?其實不一定,在拉近的時候,太多數的情況是還蠻OK的,但如果有拉遠鏡頭的需求,會導致DrawInstance的API呼叫次數變多,進而導致mesh傳輸量增加,這種狀況下反而切page變成是一種負優化…
最近比較流行的是直接使用GPU+ComputeShader來做GPU culling,並搭配DrawMeshInstancedIndirect這個API來畫,聽起來似乎是蠻理想的方案,但他最大的問題,就是當鏡頭拉近的時候,如果種類非常多,由於數量是由GPU直接算出來的,CPU完全不知道,所以還是得直接呼叫DrawMeshInstancedIndirect這個API來畫,就算GPU算出來的數量是零,還是導致了把mesh傳輸到GPU,造成了負優化,尤其是當種類越多,這個問題會越嚴重…另外還有硬體支持度的問題…
所以種類物件越多的場景,如果想全場景GPU instance化來提升性能,目前可以想得到的方式就是使用CPU+JobSystem來處理剔除,整個處理流程如下:
- Page Culling,看是要用八元樹還是四元樹,請隨意
- 依CullingPageList,將其送到JobSystem來進行剔除處理
- 等Job IsCompleted後,將其資料拷貝到相關要畫的陣列中(動態蒐集陣列資料)
- 畫出所有instancer的物件(這時候只會畫真正在視野範圍內的物件)
試著在紅米三,種類高達127種,測試物件數量高達到30000個左右的正式場景,物件面數約幾百面到2000面左右,有搭配LOD來優化,鏡頭不論遠近,FPS幾乎都頂在60(在優化前,是使用一般的DrawMesh+PageCuling,性能從35~40提升到頂60),目前也支持跨硬體API的架構(也就是會視硬體狀況,自動切換DrawMeshInstancedProcedural、DrawMeshInstanced、DrawMesh API,而且Shader都是同一個,目前的狀況是會多了一個變體),以下的測試案例是100個種類,250000個物件,相關運作狀況的影片,請參考…