日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

1.3:Render Pipeline and GPU Pipeline

發(fā)布時(shí)間:2025/3/19 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1.3:Render Pipeline and GPU Pipeline 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章著作權(quán)歸作者所有。轉(zhuǎn)載請(qǐng)聯(lián)系作者,并在文中注明出處,給出原文鏈接。
本系列原更新于作者的github博客,這里給出鏈接。

在學(xué)習(xí)SubShader之前,我們有必要對(duì) Render Pipeline (渲染流水線)和 GPU Pipeline (圖形硬件流水線)有一個(gè)比較細(xì)致的了解。這是一篇干貨,內(nèi)容主要參考了《Unity Shader入門精要》、《Real-Time Rendering》以及眾多博客,其中加入了一些個(gè)人的見解,里面涉及到的知識(shí)能夠?yàn)槲覀円院蟮腟hader編寫提供指導(dǎo)。有錯(cuò)誤的地方歡迎聯(lián)系指正。

什么是流水線

在第0章我們簡(jiǎn)單地提到了渲染流水線的大概過程。但是,只知道大概過程會(huì)給我們以后的學(xué)習(xí)帶來(lái)疑惑,所以我們還是要熟悉整個(gè)渲染的流程。在這之前,我們首先要清楚Pipeline(流水線)是什么。我們都知道,工廠的生產(chǎn)都是基于流水線的,那為什么我們會(huì)選擇使用這種模式呢?我們先回到傳統(tǒng)模式,假設(shè)一件商品需要經(jīng)過四道工序完成,而這四道工序都由同一個(gè)工人去完成。顯然,工序是拓?fù)溆行虻?#xff0c;也就是說(shuō),我們必須嚴(yán)格按照1-2-3-4的順序進(jìn)行,在計(jì)算機(jī)上,這對(duì)應(yīng)著串行計(jì)算,這也就意味著,上一道工序如果沒有完成,我們便永遠(yuǎn)無(wú)法開展下一步的工作,這無(wú)疑是低效的。在注重效率的現(xiàn)代社會(huì),最重要的協(xié)作方式肯定是各司其職,所有人在同一個(gè)時(shí)間段完成不同的工作,再把各自的階段產(chǎn)物遞交給下一道工序的執(zhí)行者,這對(duì)應(yīng)著計(jì)算機(jī)的并行計(jì)算。因?yàn)楦髯载?fù)責(zé)了自己擅長(zhǎng)的工作,在時(shí)間上又是同時(shí)開展的,效率顯然遠(yuǎn)遠(yuǎn)高過傳統(tǒng)方式。值得慶幸的是,GPU(圖形顯卡)的特長(zhǎng)正是并行計(jì)算。

渲染流水線是怎樣運(yùn)作的

了解了流水線模式的好處之后,可能會(huì)有這樣的疑問:為什么渲染也需要用到流水線呢?這是因?yàn)殇秩竟ぷ饕彩怯扇舾呻A段組成的。接下來(lái)我們將深入流水線中看看渲染的實(shí)質(zhì)。在《Real-Time Rendering》一書中,作者把渲染流程分為了三個(gè)概念階段,分別是Application Stage(應(yīng)用階段)Geometry Stage(幾何階段)Rasterizer Stage(光柵化階段),這也是目前被廣泛認(rèn)可的一種描述。

應(yīng)用階段

在應(yīng)用階段,我們需要準(zhǔn)備好場(chǎng)景數(shù)據(jù),如視角位置,光照設(shè)置,但最重要的輸出是Render Primitives(渲染圖元),這一階段在CPU中完成,對(duì)應(yīng)到Unity中就是我們需要在場(chǎng)景中擺放Light,設(shè)置Main Camera,擺放游戲物體,設(shè)置好所有的參數(shù)。

幾何階段

從上一階段獲取到圖元信息后,幾何階段會(huì)進(jìn)行所有和幾何相關(guān)的工作,決定哪些圖元需要被繪制,需要怎樣繪制,在哪里繪制。處理之后,我們會(huì)得到每個(gè)頂點(diǎn)在二維屏幕空間的坐標(biāo),以及各頂點(diǎn)的深度、顏色信息,這些會(huì)被傳輸?shù)焦鈻呕A段。這一階段通常在GPU上進(jìn)行。

純CPU的渲染流水線通常稱為軟渲染,即用軟件模擬硬件進(jìn)行渲染操作。

光柵化階段

這一階段通常也在GPU進(jìn)行,這個(gè)時(shí)候,渲染已經(jīng)接近尾聲。利用上一階段得到的數(shù)據(jù),我們可以在GPU的插值寄存器中進(jìn)行插值運(yùn)算得到足夠數(shù)量的像素信息,并最終確定逐像素確認(rèn),哪些像素應(yīng)該顯示在屏幕上。

CPU和GPU之間的通信

我們可以看到,應(yīng)用階段的數(shù)據(jù)在CPU中,這些數(shù)據(jù)是怎樣傳輸給GPU進(jìn)行幾何階段的操作呢?

在CPU中,所有和渲染有關(guān)的數(shù)據(jù)都會(huì)進(jìn)入顯存中,這是因?yàn)轱@卡對(duì)于顯存的訪問速度更快,隨后,CPU會(huì)設(shè)置一些渲染狀態(tài),最后,CPU會(huì)調(diào)用Draw Call。Draw Call是一個(gè)CPU調(diào)度命令,它會(huì)指定那些需要被渲染的圖元并通知GPU,這些被指定的數(shù)據(jù)會(huì)通過數(shù)據(jù)總線傳輸?shù)紾PU中。Draw Call其實(shí)就是調(diào)用圖形編程語(yǔ)言(如DX,GL,Cg)的接口,通過這一層抽象與硬件層打交道。

數(shù)據(jù)總線是計(jì)算機(jī)內(nèi)部各設(shè)備之間交換設(shè)備的一個(gè)通道,既然是通道,那么它肯定有傳輸速度的上限,頻繁地提交Draw Call會(huì)導(dǎo)致CPU過載,這也是一個(gè)常見的性能瓶頸。

GPU流水線

應(yīng)用階段進(jìn)行的計(jì)算都是為硬件層的渲染做準(zhǔn)備,這個(gè)階段結(jié)束后,就正式進(jìn)入了GPU的流水線中。在一些比較老的GPU中采用的是固定渲染流水線,這也就意味著所有的操作都是受限的,我們只能做一些簡(jiǎn)單的配置。隨著硬件設(shè)備的發(fā)展,現(xiàn)代的圖形顯卡幾乎都支持可編程渲染流水線,定制化程度得到了提高。固定渲染流水線已經(jīng)逐漸被淘汰了,這里不對(duì)其展開說(shuō)明,下面主要了解一下可編程渲染管線的各個(gè)階段:

Vertex Shader(頂點(diǎn)著色器)

頂點(diǎn)著色器是完全可編程的。輸入其中的每一個(gè)頂點(diǎn)都會(huì)調(diào)用一次頂點(diǎn)著色器,它無(wú)法創(chuàng)建和銷毀頂點(diǎn),也無(wú)法獲取頂點(diǎn)之間的關(guān)系,但這一特性適合用來(lái)進(jìn)行高速的并行計(jì)算。輸入頂點(diǎn)著色器的有頂點(diǎn)的位置信息,法線信息,切線信息等。它的主要工作是進(jìn)行坐標(biāo)變換和頂點(diǎn)光照計(jì)算最終得到Normalized Device Coordinates(NDC,歸一化的設(shè)備坐標(biāo))。這個(gè)坐標(biāo)通常會(huì)在光柵化后傳遞給片元著色器進(jìn)行處理。但是頂點(diǎn)著色器的作用遠(yuǎn)不止于此,輸入頂點(diǎn)的法線、切線等信息也會(huì)在這一步進(jìn)行處理,比如生成副切線,把頂點(diǎn)轉(zhuǎn)換到切線空間進(jìn)行計(jì)算,或者進(jìn)行法線外擴(kuò),實(shí)現(xiàn)描邊效果。

涉及到坐標(biāo)變換,就繞不開矩陣和線性代數(shù),數(shù)學(xué)部分的內(nèi)容可以參考《3D數(shù)學(xué)基礎(chǔ):圖形與游戲開發(fā)》等圖書,或者參考3D數(shù)學(xué)概要。

Tessellation Shader(曲面細(xì)分著色器)& Geometry Shader(幾何著色器)

頂點(diǎn)著色器為了追求速度不得不舍棄一些操作,但這些舍棄的操作會(huì)在一定程度上影響畫面的美感。在硬件的支持下,便誕生了具有特異功能的曲面細(xì)分著色器和幾何著色器。這兩個(gè)著色器不可編程,但可以配置。

由于計(jì)算機(jī)的數(shù)據(jù)離散性,我們只能使用折線表示曲線,使用多平面表示曲面,如果粒度不夠,曲線和曲面就顯得沒那么平滑。而曲面細(xì)分著色器的作用就是解決這個(gè)問題:生成新的頂點(diǎn),“插入”到直線上或平面內(nèi),讓曲線和曲面顯得更圓滑。

而幾何著色器的優(yōu)勢(shì)在于它可以創(chuàng)建和銷毀頂點(diǎn)。但這些創(chuàng)建出來(lái)的頂點(diǎn)不是用于細(xì)分,而是用于擴(kuò)展;同時(shí),它也可以銷毀那些我們不想輸出到下一階段的頂點(diǎn)。

由于Shaderlab的高度封裝性,Unity對(duì)這兩種著色器的支持度比較低。

經(jīng)過若干著色器的計(jì)算篩選,頂點(diǎn)規(guī)模已經(jīng)基本確定了,接下來(lái)對(duì)頂點(diǎn)做最后的處理。

Clipping(裁剪)

由于我們輸出的不可能是整個(gè)空間,出于性能考慮,我們自然會(huì)想到,舍去那些不會(huì)出現(xiàn)在屏幕上的頂點(diǎn),這也就是裁剪。在這一階段,我們會(huì)把頂點(diǎn)變換到裁剪空間,裁剪空間是一個(gè)單位立方體空間,因此我們只需要判斷哪些線、面在立方體內(nèi),哪些在立方體外,即可知道我們真正需要處理的是哪些。特殊情況是,如果有一條直線或者一個(gè)平面部分可見,那么裁剪操作會(huì)在立方體邊界生成新的頂點(diǎn),取代那些不會(huì)出現(xiàn)的頂點(diǎn)。裁剪操作雖然不可編程,但是我們可以定制裁剪視錐,遠(yuǎn)近平面,視角大小等信息控制裁剪范圍,這一部分內(nèi)容也會(huì)在3D數(shù)學(xué)概要中有所體現(xiàn)。

Screen Mapping(屏幕映射)

現(xiàn)在我們已經(jīng)得到了屏幕內(nèi)的所有頂點(diǎn)信息,但它仍位于裁剪空間中,因此我們有必要把這些頂點(diǎn)映射到屏幕坐標(biāo)系。映射過程中使用了兩個(gè)維度的坐標(biāo)信息,而我們知道空間坐標(biāo)是一個(gè)三維信息,丟失的那一維我們并沒有真正地舍棄,而是將他作為頂點(diǎn)的深度信息,為以后的片元操作提供依據(jù)。

至此,概念流水線的幾何階段工作就結(jié)束了,我們回顧一下,上述階段,我們接收了頂點(diǎn)的原始信息,最終得到的是渲染所需的屏幕坐標(biāo),頂點(diǎn)深度值等信息。需要注意的是,在Shaderlab中編寫的頂點(diǎn)著色器包含了裁剪部分,這是因?yàn)榻酉聛?lái)這些頂點(diǎn)數(shù)據(jù)會(huì)被提交給光柵化階段,這一階段接受的輸入是裁剪空間下的信息。接下來(lái)是光柵化階段的工作了。

首先是光柵化以及插值過程,它包含了三角形設(shè)置和三角形遍歷,目的是計(jì)算圖元覆蓋的像素。

Triangle Setup(三角形設(shè)置)

計(jì)算三角形網(wǎng)格表示的數(shù)據(jù)。

Triangle Traversal(三角形遍歷)

這個(gè)階段接收的數(shù)據(jù)仍是頂點(diǎn)級(jí)別。這里是真正柵格化數(shù)據(jù)的階段,這個(gè)階段會(huì)逐像素檢查其是否有被三角形網(wǎng)格覆蓋,如果有,就生成一個(gè)片元。因此,它也被稱為掃描變換過程,覆蓋信息計(jì)算完成后,整個(gè)覆蓋區(qū)域會(huì)使用頂點(diǎn)信息進(jìn)行插值,生成像素級(jí)別的數(shù)據(jù),這些數(shù)據(jù)會(huì)傳遞到片元著色器中。

這些像素級(jí)別的數(shù)據(jù)仍然是以片元為載體的,并不真正對(duì)應(yīng)屏幕上的像素。

接下來(lái)是片元著色器環(huán)節(jié),也是第二個(gè)和最后一個(gè)完全可編程環(huán)節(jié)。

Fragment Shader(片元著色器)

在DirectX中,它也被稱為Pixel Shader(像素著色器),但個(gè)人感覺片元是更適合的名稱,因?yàn)檫@個(gè)階段的輸出并不會(huì)真正影響屏幕的像素顏色,接下來(lái)還有逐片元操作,對(duì)這些片元進(jìn)行篩選,以確定最終顯示的顏色。這一階段最重要的技術(shù)是紋理采樣。為了得到采樣結(jié)果,我們通常會(huì)在頂點(diǎn)著色器中計(jì)算每個(gè)頂點(diǎn)的紋理坐標(biāo),采樣器會(huì)根據(jù)這個(gè)坐標(biāo)采樣紋理數(shù)據(jù)。由于我們已經(jīng)在頂點(diǎn)著色器中計(jì)算好了每個(gè)頂點(diǎn)的顏色信息,也在上一階段得到了像素級(jí)別的插值顏色,因此現(xiàn)在我們只需要根據(jù)我們想實(shí)現(xiàn)的效果,做相應(yīng)的顏色計(jì)算即可。

Per-Fragment Operations(逐片元操作)

在DirectX中也稱為Output Merger(輸出合并)。這一階段具有高度的配置性。進(jìn)行到這里,渲染工作也基本完成了。經(jīng)過上一階段,我們得到了許多色彩斑斕的片元,是時(shí)候進(jìn)行最后的篩選了。在這一階段,我們會(huì)對(duì)每一個(gè)片元都進(jìn)行一系列的測(cè)試操作以及最終的混合操作,目的是確定這個(gè)片元是否可見,以及可見時(shí)它的顏色對(duì)應(yīng)的權(quán)重。測(cè)試主要有Stencil Test(模板測(cè)試)Depth Test(深度測(cè)試),在測(cè)試前,首先要判斷這個(gè)片元是否開啟了對(duì)應(yīng)的測(cè)試操作。在測(cè)試中,我們會(huì)利用對(duì)應(yīng)的緩沖和片元進(jìn)行比較,對(duì)應(yīng)的有Stencil Buffer(模板緩沖)Depth Buffer(深度緩沖)。通過了模板測(cè)試的片元會(huì)被保留,同時(shí)更改模板緩沖區(qū)的值,隨后進(jìn)行深度測(cè)試(假設(shè)這個(gè)片元同時(shí)開啟了兩種測(cè)試)。深度測(cè)試具有更高的配置性。即使這個(gè)片元通過了深度測(cè)試,我們也可以關(guān)閉深度寫入,讓這個(gè)片元的深度值不影響深度緩沖區(qū)。透明效果的實(shí)現(xiàn)離不開深度測(cè)試的高配置性。

經(jīng)過深度測(cè)試后我們會(huì)發(fā)現(xiàn),我們舍棄了許多片元,這樣也就意味著這些片元對(duì)應(yīng)的片元著色環(huán)節(jié)所做的一切都是徒勞。自然我們會(huì)想,能否將深度測(cè)試提前?答案是肯定的,這項(xiàng)技術(shù)被稱為Early-Z,它會(huì)在片元著色器之前進(jìn)行深度測(cè)試,但這并不意味著我們可以舍棄真正的深度測(cè)試環(huán)節(jié)。如果我們把深度測(cè)試提前,這些檢驗(yàn)結(jié)果可能會(huì)和片元著色器的某些操作發(fā)生沖突,這個(gè)時(shí)候我們就不得不放棄Early-Z,選擇傳統(tǒng)的深度測(cè)試。

通過測(cè)試的片元會(huì)來(lái)到最后一個(gè)環(huán)節(jié),Blend(混合),與之對(duì)應(yīng)的是顏色緩沖區(qū)。我們可以選擇開啟/關(guān)閉混合操作。對(duì)于不透明的物體,我們會(huì)關(guān)閉混合操作,這樣,這個(gè)片元的顏色會(huì)完全覆蓋掉顏色緩沖區(qū)的像素值;對(duì)于半透明物體,我們需要開啟混合選項(xiàng),以達(dá)到透明效果。這一階段也是高度配置的,我們可以自定義混合的比例。Photoshop的圖層混合模式的實(shí)現(xiàn)也是類似的操作。

GPU流水線之后

當(dāng)所有片元都經(jīng)過逐片元操作后,我們得到的顏色緩沖區(qū)就可以作為最終呈現(xiàn)在屏幕上的圖像了。但一般來(lái)說(shuō)我們會(huì)把這個(gè)顏色緩沖區(qū)的內(nèi)容輸出到Frame Buffer(幀緩沖)。這是因?yàn)楣鈻呕^程的進(jìn)度是不可知的,也就是說(shuō)有可能我們讀取的屏幕圖像還包含了部分上一幀的內(nèi)容(這個(gè)轉(zhuǎn)場(chǎng)很炫酷,但并不是我們希望看到的)。對(duì)應(yīng)的解決方案是,使用Double Buffer(雙緩沖)技術(shù),我們準(zhǔn)備兩個(gè)緩沖區(qū),一個(gè)用于當(dāng)前屏幕圖像顯示,一個(gè)用于幕后渲染下一幀的圖像。不僅如此,我們得到了幀緩沖后,還可以進(jìn)行Post-Processing(屏幕后處理),實(shí)現(xiàn)更豐富的視覺效果。

最后

我們已經(jīng)梳理了一遍GPU渲染的詳細(xì)過程,但由于抽象層(Shader Language)提供給我們的接口的區(qū)別,以及GPU為我們做的額外優(yōu)化,許多細(xì)節(jié)或者順序可能不盡相同,但也足以讓我們對(duì)計(jì)算機(jī)圖形學(xué)和渲染有比較清晰的認(rèn)識(shí)了,至少可以知道計(jì)算機(jī),或者說(shuō)硬件,在背后為我們做了些什么。

下面給出一張流水線對(duì)照?qǐng)D以供參考(打開圖片可查看原圖)。

在Shaderlab中,頂點(diǎn)和片元著色器可以通過插入CG/GLSL代碼塊實(shí)現(xiàn),剔除階段和逐片元操作則可以通過Tags和CommonState實(shí)現(xiàn)高度配置。

轉(zhuǎn)載于:https://www.cnblogs.com/Li-F/p/10635587.html

總結(jié)

以上是生活随笔為你收集整理的1.3:Render Pipeline and GPU Pipeline的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。