移動端草海的渲染方案(二)

書接上文

前文介紹了Unity內(nèi)置 Terrain 刷草的一些缺陷,并且介紹了3款插件:

  1. uNature

  2. Advanced Terrain Grass

  3. Nature Renderer

下面就簡單介紹一下這幾款插件的做法萨醒,以及我們的選擇。

如何刷草

Unity內(nèi)置的刷草工具還是很好用的芦瘾,Advanced Terrain GrassNature Renderer 沿用 Terrain 的刷草,只是接管了渲染集畅。

參考一下 TerrainData 的API近弟,我們可以通過腳本獲取刷草信息,然后自己來做渲染牡整。

沿用 Terrain 的刷草方式有兼容性上的好處藐吮,但是這里就強迫你必須選擇 Terrain 來做地表了。

uNature 和上面兩個插件不太一樣逃贝,作者自己提供了刷草工具,刷草的對象不局限于 Terrain迫摔,也可以是 普通模型沐扳。

比如下圖,我不但在地表刷了草句占,也在Cube上刷了草沪摄。

image

GPU Instancing

渲染大面積草,GPU Instancing 是非常合適的纱烘。

然而杨拐,Unity的渲染方案是把地表分成一個一個的 Patch,每個 Patch 的草合并成一個大的Mesh擂啥,以此來降低 Drawcall哄陶,但是 多個Patch 的渲染是無法通過 GPU Instancing 提速的。

我們看一下 GPU Instancing 需要滿足的條件:

Use GPU Instancing to draw (or render) multiple copies of the same Mesh
at once, using a small number of draw calls. It is useful for drawing objects such as buildings, trees and grass, or other things that appear repeatedly in a Scene.

這里每個 Patch 生成的Mesh顯然是不同的......

當(dāng)然哺壶,我們可以突破這個限制屋吨。

既然要求 相同的Mesh,那我們可以 把Mesh的計算從CPU移到GPU:把影響 Mesh差異 的因素 ( 比如 Noise高度 ) 編碼到紋理山宾,然后在 頂點著色器 采樣紋理再把這些差異應(yīng)用到頂點至扰。

這樣我們就可以用相同的Mesh來渲染,即滿足 GPU Instancing 的開啟條件资锰,又可以滿足表現(xiàn)上的多樣性敢课,順帶把前文提到的 運行時合并Mesh產(chǎn)生的CPU峰值 也優(yōu)化掉了。

uNature 為例,場景依然會被柵格化直秆,如下圖:

image

這里的 藍色格子 類似 TerrainPatch濒募,處于同一個 紫色格子 內(nèi)的藍色格子是可以通過 GPU Instancing 來渲染提速的。

如果不考慮 LOD密度 的差異切厘,每個 藍色格子 的Mesh是一樣的萨咳,最終表現(xiàn)上的差異被編碼到了 頂點uv 以及 GrassMapHeightMap 這2張紋理中去了。

HeightMap 一覽:

image

具體的編碼方式我就不細說了疫稿,大家可以參考源碼培他。

事實上,Unity在 2018.3 及以后的版本遗座,對 Terrain 的渲染也加了 GPU Instancing 的支持舀凛,原理和我上面說的差不多:

When enabled, Unity transforms all of the heavy terrain data, like height maps and splat maps, into textures on the GPU. Instead of constructing a custom mesh for each terrain patch on the CPU, we can use GPU instancing to replicate a single mesh and sample the height map texture to produce the correct geometry. This reduces the terrain CPU workload by orders of magnitude, as a few instanced draw calls replace potentially thousands of custom mesh draws.

不過,一直到我目前在用的版本 2019.3途蒋,Unity對于 地形草(Terrain Detail) 的渲染方式還是老樣子......

GPU Instancing 的 API

關(guān)于 GPU Instancing猛遍,如果通過腳本來操作,Unity提供了如下2個接口:

  • Graphics.DrawMeshInstanced

  • Graphics.DrawMeshInstancedIndirect

考慮到移動設(shè)備的兼容性号坡,我們一般會選擇 Graphics.DrawMeshInstanced 這個接口懊烤,不過 Graphics.DrawMeshInstanced 有一個最大數(shù)量 1023 的限制:

Note: You can only draw a maximum of 1023 instances at once.

如果我們以每一株草為單位來渲染,很容易就會突破這個限制宽堆。

Advanced Terrain Grass 就是這么做的腌紧,所以最后他用了 Graphics.DrawMeshInstancedIndirect 接口。

uNature 則是對草先做一定程度的 Mesh合并畜隶,回想一下下圖的 藍色格子壁肋,我們可以通過控制格子的粒度,從而把每個 紫色格子 內(nèi)的 藍色格子 數(shù)控制在 1023 以內(nèi)籽慢,然后就可以通過 Graphics.DrawMeshInstanced 接口一次完成渲染浸遗。

image

Nature Renderer 的作者并沒提供源碼,不過從反編譯的結(jié)果來看箱亿,他也是用了 Graphics.DrawMeshInstanced 這個接口跛锌,只是對 GPU InstancingDrawcall 做了更細致的管理,如下圖:

image

每個相同顏色的格子屬于同一個 Drawcall极景,和 uNature9宮格 管理方式并不相同察净。

我們的選擇

好了,插件就介紹到這里盼樟。

最后氢卡,說一下我們的選擇:基于 uNature 做改進。

  • 不選擇 Advanced Terrain Grass晨缴,主要因為它是基于 Graphics.DrawMeshInstancedIndirect 的實現(xiàn)译秦。此外,如果你想實現(xiàn)類似 塞爾達的割草 效果,整個 ComputeBuffer 的數(shù)據(jù)都要重建筑悴,這個開銷在運行時難以承受们拙。

  • 不選擇 Nature Renderer 的原因則更簡單阁吝,作者并不提供源碼。

不過 uNature 本身的問題也不少突勇,如果大家要用這個插件装盯,你得有心里準(zhǔn)備:

  • 作者已經(jīng)很久沒有更新了甲馋。
  • 代碼有不少bug。
  • 針對移動端還要做很多優(yōu)化定躏。

無論如何账磺,二次開發(fā)是必不可少的。

不過痊远,有了 GPU Instancing垮抗,大面積的草海已經(jīng)變得可行了。下面會繼續(xù)介紹草海的其他渲染技巧以及模仿 塞爾達 的一些好玩的效果碧聪。

個人主頁

本文的個人主頁鏈接:https://baddogzz.github.io/2020/01/16/Unity-Grass-02/借宵。

好了,拜拜矾削。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豁护,隨后出現(xiàn)的幾起案子哼凯,更是在濱河造成了極大的恐慌,老刑警劉巖楚里,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件断部,死亡現(xiàn)場離奇詭異,居然都是意外死亡班缎,警方通過查閱死者的電腦和手機蝴光,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來达址,“玉大人蔑祟,你說我怎么就攤上這事〕吝耄” “怎么了疆虚?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我径簿,道長罢屈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任篇亭,我火速辦了婚禮缠捌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘译蒂。我一直安慰自己曼月,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布蹂随。 她就那樣靜靜地躺著十嘿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岳锁。 梳的紋絲不亂的頭發(fā)上绩衷,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音激率,去河邊找鬼咳燕。 笑死乒躺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曹货。 我是一名探鬼主播讳推,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼礼饱!你這毒婦竟也來了究驴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蝴韭,失蹤者是張志新(化名)和其女友劉穎跑慕,沒想到半個月后摧找,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牢硅,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年综苔,在試婚紗的時候發(fā)現(xiàn)自己被綠了如筛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡杨刨,死狀恐怖妖胀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赚抡,我是刑警寧澤纠屋,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站赁遗,受9級特大地震影響族铆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一刚夺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧创橄,春花似錦莽红、人聲如沸邦邦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽黔龟。三九已至滥玷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惑畴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工陷虎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留倒得,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓谊路,卻偏偏與公主長得像菩彬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子骗灶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容