對于需要渲染的每一幀,CPU 將處理如下工作:
1.檢查場景中所有物體,判斷其是否需要被渲染。物體需要是否需要被渲染要滿足一系列的條件,例如其是否在攝像機的視錐體中等。不會被渲染的物體被稱為被剔除(culled)。
2.收集并排序所有需要渲染的物體相關信息并整理為通常所說的draw calls命令。一個draw call 包含了一個網(wǎng)格(mesh) 數(shù)據(jù)以及如何對其進行渲染的數(shù)據(jù)。例如,將會需要使用哪個紋理(texture)等等。在某些情況下,使用同一組設置信息的物體可能被組合起來成為一個draw call。將不同物體的數(shù)據(jù)合并為一個draw call 的過程稱為batching。
3.為每一個draw call 創(chuàng)建一個通常所說的“批次”(batch)的數(shù)據(jù)包。Batch 中有時候可能包含draw call 之外的數(shù)據(jù)。
對于每個包含了draw call 的batch,CPU 將繼續(xù)如下工作:
1.CPU可能會發(fā)送一些命令用于變更GPU 一系列渲染相關的變量,這些變量被統(tǒng)稱為渲染狀態(tài)(render state),這些命令本身就是通常所說的SetPass call。一個SetPass call 告知GPU 哪些設置將被用于渲染下一個網(wǎng)格。僅當下一個需要被渲染的網(wǎng)格需要變更渲染狀態(tài)的時候才需要發(fā)送。
2.CPU 發(fā)送draw call 給GPU。Draw call 指示GPU 使用最近發(fā)送的SetPass Call 所提供的設置來渲染特定的網(wǎng)格。
3.在有些情況下,一個batch 可能需要多于一個的pass。Pass 是著色器(shader)代碼中的一節(jié),一個新的pass 需要對render state 進行變更。對于batch 中的每一個pass,CPU 將發(fā)送一個新的SetPass call 并且再次發(fā)送draw call。
GPU 在渲染流程中主要做如下工作:
1.按照CPU 的發(fā)送順序處理渲染任務。
2.如果當前的任務是個SetPass call,GPU 更新render state。
3.如果當前的任務是個draw call,GPU 渲染該mesh。此過程按照shader 代碼的不同段落分步有序進行,此過程較為復雜,簡單來說,其中一段稱為頂點著色器(vertex shader)的代碼告知GPU 如何處理網(wǎng)格的頂點,另一段稱為片段著色器(fragment shader)的代碼告知GPU 如何繪制每一個像素。
4.重復上述工作直至CPU 下發(fā)的所有任務均被GPU 處理完畢。
在Unity 的渲染進程中包含三種類型的線程:
1.main thread:絕大多數(shù)CPU 任務在main thread 中完成,包括一些渲染任務。
2.render thread:用于向GPU 發(fā)送命令的特殊線程。
3.worker thread:每個worker thread 用于完成一個獨立的任務,如culling 等。
注:并非所有平臺都支持多線程渲染,目前WebGL 還不支持這個特性。