嗚嗚喔學習筆記: 3月 2021

搜尋此網誌

2021年3月5日 星期五

Unity TextMeshPro 查看筆記

簡介 : 


支援SDF

支援各種標籤,圖文混排,3D字體,陰影,光影..等等

支援多Font混排( Drawcall++ )


SDF(Signed Distance Field) 簡單來說就是 因為記得邊界距離資訊 , 在拉近放大文字時不會變得糊糊的。 ( 相比Bitmap )

優勢: 1. 減少字集貼圖大小 (順便解決BestFit占用圖集問題)

- BestFit 開啟時 Unity在計算最適合的字體大小過程中, 計算過程中產生的字體都會寫進Texture裡,很浪費空間。

2. Outline 頂點數較小 (4倍)

- Unity本身Outline會多畫4次在文字後面,頂點數也會多4倍。

TMF使用SDF算法則不會增加頂點數,計算直接在Fragment階段做了。

劣勢: 動態生成計算慢。 (極限約20字)


SDF 產圖算法簡介:

step 1. 透過ttf 產出大字體


step 2. 分辨字體邊緣內外 & 計算與邊緣距離 & 線性塞進 alpha 得到小圖

具體數據大概是長這樣子的 如下圖:


step 3. 

     Shader 原理很簡單 alpha超過0.5 -> 外界 , alpha 小魚0.5 -> 內界
    或是用內插會更圓滑一點


Shader 改成:

fixed4 frag(v2f IN) : SV_Target

{

if (color.a < 0.5)

color.a = 0.0;

else

color.a = 1.0;

}

or


color.a = smoothstep(_DistanceMark - _SmoothDelta, _DistanceMark + _SmoothDelta, distance);



//--------------------------------------------------------------


多國語言做法  :


支援 dyniamc SDFAA ( 主要是中文字太多需要用 )

SamplingPointSize : 越高越精細。佔用空間越大。

Multi Atlas Textures : Atlas不夠塞,會幫產新的。


一個 ".ttf " = 一個以上Atlas 不可合併Drawcall。

一個 ".ttf " 如果字不夠塞可產多個Atlas ( 1 Atlas = 1 Drawcall & 記憶體++)  

多個 ".ttf " 可以混用,設定先後順序即可。


坑: 原本Unity的 TextMesh & UIText 在沒有字集的情況下會抓,裝置內的Font來用。

( 比如阿語&韓文 )

目前可抓內建Font List來用,但要開發者自行篩選,還要Runtime產Font,不太可行。



建議:

1.一個Static字集放常用單字 + 一個 dyniamc SDFAA 字集動態生成當備用。

2.確保韓文跟阿語都能正常,要把字集都塞進 同張 .ttf 裡 & 所有語言要測試過沒缺字。 ( 因為沒有抓系統預設Font的功能 )


//--------------------------------------------------------------


效能測試:


Unity 2018.4.2f1 && TextMeshPro 1.5.0


sumsumg

預產圖集(2000單) (SDFAA)

耗時6187ms 

mono:256KB

totol:4097KB ( 3張 1024*1024 atlas )


預產圖集(2000單) (Smooth)

耗時6002ms 

mono:272KB

totol:2976KB ( 3張 1024*1024 atlas )



samsung Galaxy Tab 4 7.0 ( opengl 2.0)

20 (中文字)

200 (中文字)

2000 (中文字)

mono (預先產圖

0KB

0KB

2800KB

mono (產圖 & 塞字

0KB

4KB

3392KB

mono (直接設值

56KB

3016KB

卡死


samsung Galaxy Tab 4 7.0 ( opengl 2.0)

20 (中文字)

200 (中文字)

2000 (中文字)

預先產圖 ( ms )

21

31

157

產圖&塞字 ( ms )

34

114

4316

直接塞字 ( ms )

97

1707

卡死


Htc u11+ ( opengl 3.0)

20 (中文字)

200 (中文字)

2000 (中文字)

預先產圖 ( ms )

20

20

51

產圖&塞字 ( ms )

15

54

1239

直接塞字 ( ms )

49

662

卡死


建議:

常用的能產的先產,加入載入。

如要塞字也先產圖在塞字 會比直接塞字好。

直接塞字記憶體會爆炸..直接卡死。(要再看 Source Code查原因



坑: 貼圖字越多時,產新字就越久 ( 20字/每次 )

samsung Galaxy Tab 4 7.0 ( opengl 2.0)

實測在 (250字/每張圖) 以內可以維持30fps : 

建議設定 font size : 32 , atlas : 512*512


阿語注意:


要下載下面插件 ( For TMP 的阿語偛件 )

https://github.com/mnarimani/RTLTMPro


問題

1. /n 不支援

2. 連接處會有點斷掉


未來:

可以看SourceCode 也可以改。但不開源要自己維護。

//--------------------------------------------------------------




參考連結: 

https://zhuanlan.zhihu.com/p/26217154

https://medium.com/codememo/spark-ar-%E5%AF%A6%E4%BD%9C-sdf-shader-%E4%B8%8A-b0864938df3b

https://www.jianshu.com/p/c466e8b2c854

https://zhuanlan.zhihu.com/p/91689792

https://forum.unity.com/threads/can-i-change-textmeshpro-dynamic-font-atlas-size-in-runtime.674275/

Unity Anti-aliasing shader (SDF)


SDF Genarater

Signed Distance Fields February 18th, 2009

http://www.klayge.org/docs/klayge%E4%B8%AD%E7%9A%84%E5%AD%97%E4%BD%93%E7%B3%BB%E7%BB%9F/#ref_9


https://blog.csdn.net/seizeF/article/details/104657900

SDF演算法參考:

http://www.codersnotes.com/notes/signed-distance-fields/

https://prideout.net/blog/distance_fields/



Unity UIParticle 查看筆記

 UIParticle 查看筆記


GitHub位置 :

https://github.com/mob-sakai/ParticleEffectForUGUI


Default

RenderMode 不設定Overlay , 這做法只是讓UI變3D方式渲染
如果要穿插 UI 要當改Z position 這樣做不太現實 , 也會影響Batch


RenderTexture 

原理: 

1. 將Particle 設定指定的Layer 

2. 再把Camera 設定只看那個Layer

3. Camera 指定Target Texture 畫進去

4. 用RawImage 指定該Textrue 並顯示。


Convert particle to UIVertex

有錯誤 & 有各種奇怪GC 不裡他


Baking mesh(UIParticle)Unity 2018.2 Above

原理 : 

ParticleSystemRenderer.BakeMesh > 抓出Mesh

canvasRenderer.SetMesh (_mesh);

canvasRenderer.SetTexture (mainTexture);

PS : 不需額外Canvas,RenderTextrue,無GC

Canvas to sort

原理:

猜分多個Canvas 設立Order 

如果UI跟特效穿插 , Batch機制會被打亂


結論 : 

2018.2 以上使用 Baking mesh 做法

以下使用RenderTexture做法