閱讀656 返回首頁    go 汽車大全


字體(字符)的渲染方法

最近開始在啃Game Programming Gem 8.裏麵有一些不錯的文章,及時咀嚼及時反思 記錄於此。

一直以為字體渲染是件簡單的事 ,因為電腦上這麼多字體顯示麼,但是今天看了這文章才知道3D技術裏的字體渲染是兩回事。平時win裏麵看到的文字這些基本都是通過GDI在cpu上運算繪製(或者也加入了顯卡繪製)的,不過在3D遊戲裏麵看到的字體包括GUI等則不是這個流程的,它們都跟其他圖形的渲染一樣,都是一些多邊形,經過渲染管線在顯卡上繪製的,跟多邊形的渲染時一樣的,甚至有時是一個比較耗的過程。

       通常字體的渲染有兩種方式:

     1 是把turetype字頭的每個字符圖像(英文稱glyph)編碼為三角形集合,然後就想渲染三角形一樣在屏幕上渲染,這通常會帶來大量的渲染數據。

     2 把所有的字符畫在一張貼圖上,然後在渲染的時候,每個字符就是一個正方形(倆三角形),然後編碼每個找到合適的貼圖坐標給這個正方形貼圖,使得貼的圖就是那個大字符圖上這個字符的圖像,這種方法需要為每個字符預先編碼他們的貼圖坐標。顯然這種方法更好一些,三角數目會少很多。

     一般的字符渲染包括GUI的渲染一樣都是采用第二種方法嗎,但是他有一些效率不高的地方,比如字符可能會要經常變化,那麼向管線要頻繁提交定點數據。因此針對這個就有一些優化的餘地:

    1.將對顯存back buffer的lock方式設為discard方式,這種方式是D3D支持的一種方式,一種解決CPU的提交和GPU的渲染對backbuffer的訪問衝突的策略,正常情況當cpu提交給gpu的backbuffer要對其修改時,如果發現這塊緩存恰巧正在gpu用於渲染給前緩存,那麼提交會被打回,也就是這幀渲染不成功,會卡幀,這個discard標記在頻繁的vertex buffer提交時使用,它的意思是如果發現這塊緩存恰巧正在gpu用於渲染給前緩存,那麼標記這個緩存為valid,這時GPU會立即將這片緩存重建,並且會馬上允許cpu的提交,並渲染。這會最大化的允許CPU對字體這種字符GUI這種可能頻繁變化VB的物體的提交。

  2.正常包括字符數據的vb(vertex buffer)要包括位置、貼圖坐標、顏色信息。但是其實不用每次都提交這麼多信息,可以把一個估計的最大的字符串的VB用一個流通道a(D3D的stream channel)提交,每次變化字符時隻要提交一個唯位移或者合並縮放信息到另一個通道b就行了。也就是頻繁提交的隻是B通道的較少的數據。

  3還可以利用D3D的instance技術,即把字符做成instance 那麼每次更改字符信息,隻提交字符的位置就行了,當然23都要使用shader實現。

  4.有時為了實現字符或GUI的上下層效果,需要有一個層數的信息,這個可以利用位置向量的z支來表示。

  5.為了節省渲染資源提高效率,字符和GUI這種不涉及到3D變換的表層物件,通常直接提交的是clip空間的坐標,屏幕坐標XY對應的剪裁坐標計算公式為cx=-1+x*(2/screen_width)  cy=1-y*(2/screen_height).在D3D的固定管線中就等於直接提D3DFVF_XYZRHW格式的vb,他不執行定點變換。

最後更新:2017-04-02 15:15:07

  上一篇:go 一個關於高考的"黑客"故事:用2B鉛筆"注入"閱卷係統
  下一篇:go 大數據趨勢下,服務風暴必將來臨