• 能不畫就不畫 // occlusion culling / LOD
  • 能不更新就不更新
  • 能簡化就簡化 // LOD
  • 能一次畫的不要分多次畫 // batching / instancing / indirect drawing
  • 相似的東西在一起畫 // sorting
  • 能非同步的非同步
  • 能並行的並行
  • 能預計算的預計算
  • 能給GPU算的給GPU算
  • 時間經常可以用空間換
  • 多讀書,演算法本身也可以優化
  • 再不行可以降解析度渲染再拉大
  • 實在不行了就砍效果砍功能


謝邀。

這個問題問得很大。真要寫絕對夠出一本書,甚至是一系列。

所以這裡就精神論一下,只談優化思路。

首先,渲染的最終目的是出圖。從這個角度出發:

無論是多大解析度,像素數總是有限的。所謂出圖,就是確定每個像素的顏色取值。

顯然,渲染性能反比於為了確定一個像素的顏色所需要進行的平均工作量。因此,必須想辦法減少渲染單一像素的開銷:

  1. 首先渲染方程決定了計算的複雜度。從而會影響性能。在滿足畫面品質要求的情況下,使用儘可能簡單的渲染方程,或者儘可能對方程當中相對固定的部分進行預計算,可以減少計算複雜度;
  2. 減少影響特定像素顏色的因素的個數,這是另外一個重要的點。比如,當場景當中有半透明物體的時候,對於其所覆蓋的像素,我們不僅要計算半透明物體的顏色,還需要計算其後面的物體的顏色才能確定最終顏色。另外,對於帶有強鏡面反射性質的物體表面,我們還要考慮其所反射的物體的顏色才能確定其最終顏色。這些都是巨大的性能損耗;

除了單一像素渲染的開銷之外,另外一個對性能有重大影響的方面就是渲染的並行度。理論上,如果一幀畫面的所有像素都是同時並行渲染的,那麼渲染時間應該只是由其中工作量最大的那個像素決定,而與畫面的解析度無關。

但是事實上顯然不是這樣。這是因為無論是CPU、還是GPU、亦或是作為數據提供和存儲的場地的內存,它們的帶寬都不是無限的。所以組成一幅畫面的數據只能夠按照一定的大小一批一批地進入渲染管道,直至渲染完成。

因為CPU/GPU/內存的帶寬資源都是有限且固定不變的,所以根據渲染數據流對三者帶寬的消耗情況,會在不同的地方出現瓶頸。一般來說,CPU的帶寬最小,所以諸如貼圖等對數據帶寬要求很高的數據對象,最好不要流過CPU。我們要將控制流和數據流分開,讓CPU主要專註在控制流上,而讓數據流盡量不要通過CPU。

GPU的帶寬一般相較於CPU在10倍以上。且GPU的後端就是顯示輸出,所以我們必須讓數據流經過GPU。但是,GPU當中流過的數據流其實也有好幾種:

  1. 頂點和索引數據流(元數據流)
  2. 貼圖和渲染對象(RT)數據流

而且,由於GPU當中的渲染管線是按照VS-PS這樣的方式,後段的貼圖和渲染對象數據流其實受制於前段的頂點與索引數據流,所以兩者的比例關係就會對性能產生很大的影響。

由於當代GPGPU當中共用一套處理核心來處理這兩種數據流,這就使得GPGPU在對頂點和索引數據流的處理能力與對貼圖和渲染數據流的處理能力之間有著某種比例關係。比如,在採用Triangle-Strip方式來描述模型的時候,從第三個頂點起,每處理一個頂點就會生成一個三角面。而三角面會被Rasterlizer離散成為一定數量的像素,然後進行像素顏色的計算。

當三角面很大的時候,一個三角面會離散出很多個像素。這可能會使得貼圖和渲染對象(RT)數據流流量猛增,但是反過來壓迫頂點和索引數據流的處理,使其不能達到飽和處理能力;而頂點和索引數據流的處理受到壓迫,最終又會使得GPU無法在短時間內攢齊足夠的像素投入後端渲染,從而導致性能的低下;

而當三角面很小的時候,一個三角面可能只能離散出很少的幾個像素。為了充分利用GPU和內存的處理帶寬,GPU可能不得不等待更多的三角面的離散完成,湊齊足夠的像素數才能進入後段的處理。這同樣會導致性能的低下。

所以我們要控制好三角面的大小,也就是控制好頂點與像素的比例。對於較遠處的模型要通過LOD等方式避免產生大量的小三角形。

貼圖在內存上的排布同樣十分重要。GPGPU雖然帶寬很高,但是對內存的訪問延遲也很大。所以當貼圖沒有被緩存在GPGPU的L1/L2緩存當中的時候,會引起相當顯著的等待數據的情況。為了充分利用L1/L2緩存所提供的低延遲特性,我們應該安排好貼圖的以下幾個方面:

  1. 避免不必要的過大的貼圖。因為大的貼圖所需要的存儲空間很大無法保持或者長期保持在L1/L2緩存當中;
  2. 盡量避免對貼圖或者RT的隨機訪問。因為這會打亂L1/L2當中的數據有效性,導致頻繁的L1/L2失效
  3. 採用方便GPU定址的方式重排貼圖。比如採用Tile模式,而不是Linear模式
  4. 對貼圖採用壓縮,減少傳輸/存儲帶寬


Real-Time Rendering Resources


直接看《 real time rendering 4th 》中關於性能調優的章節。

ps 還有一本專門關於視頻遊戲優化的書籍,也可以參考下。《video game optimization》


1.盡量不去渲染看不到的對象,越早剔除越好

2.盡量減少渲染狀態的變化,比如把使用相同材質或紋理的對象放在一起渲染

3.能用低精度不用高精度

4.盡量批量提交,減少call draw的調用次數

5.能開硬體加速就用硬體加速


謝邀

列舉一下一些很基礎的點吧,我平時遇到的問題。

在渲染過程中,不要動態創建新對象,盡量不要用複雜的容器進行搜索

儘可能的使用並行,如cpu的多線程或計算著色器

對三維物體進行處理,過於遠的物體不必繪製出它每一個頂點,背部可以cull

盡量在VS中計算所需要的參數,而不是放在PS中。如果它能夠在CPU計算好,並且不會再改變,考慮通過uniform傳入。如果和頂點相關,考慮作為頂點數據傳入,如骨骼信息

繪製時可以先計算在frustum內有哪些對象,它之外的對象不可見,所以不用繪製

使用一些數據結構來管理場景,如Bsp

使用高效的內存池來分配對象

使用simd指令來代替常規的矩陣向量運算,它會帶來一定的性能提升

更多可以看看 @Milo Yip 的遊戲引擎架構。

另外我這裡也有自己寫的一個玩具可供參考。

http://www.github.com/froser/gamemachine


謝邀。

如果3D Object比較多,可以採用GPU 並行計算進行渲染提高計算效率。

發佈於 2018-12-24繼續瀏覽內容知乎發現更大的世界打開Chrome繼續BitDragonflyBitDragonflyOpenGL

很多想當然優化都是負優化..或者對於軟繪製來說才算優化!

例如不渲染照相機後面.你就需要判斷.討巧點的引入各種樹數據結構.但是你要知道這些都是佔用cpu的.興許不優化都喂不飽gpu呢..

不要提前優化才是王道!

至於優化方法上面已經都說了....


很多想當然優化都是負優化..或者對於軟繪製來說才算優化!

例如不渲染照相機後面.你就需要判斷.討巧點的引入各種樹數據結構.但是你要知道這些都是佔用cpu的.興許不優化都喂不飽gpu呢..

不要提前優化才是王道!

至於優化方法上面已經都說了....


shader的話,學習一下cuda,然後就會很了解shader優化了。


推薦閱讀:
相关文章