最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

UnityShader系列之1:基礎(chǔ)篇

2018-10-16 20:08 作者:皮皮關(guān)做游戲  | 我要投稿

作者:朔宇


大家好,從這期開始我會(huì)開一個(gè)講shader的新系列。想深入學(xué)習(xí)的童鞋們不要錯(cuò)過了。

流水線

  • 在了解什么是渲染流水線前先看一下現(xiàn)實(shí)生活中的流水線。

流水線是一種工業(yè)上的生產(chǎn)方式,每一個(gè)生產(chǎn)單位只專注處理一個(gè)片段的工作。 比如一個(gè)制造手機(jī)的工廠,一臺(tái)手機(jī)的制造流程可以分為四個(gè)步驟:

第一步,制作外殼;

第二步,制作屏幕模組;

第三步,制作主板;

第四步,組裝手機(jī)并進(jìn)行產(chǎn)品包裝。

注:這里只是舉例,并不代表真實(shí)的手機(jī)生產(chǎn)步驟

在沒有流水線時(shí),只有在每臺(tái)手機(jī)四個(gè)工序完成后才能開始制作下一臺(tái),這是非常耗時(shí)的。 如果我們加入流水線,雖然制作一臺(tái)手機(jī)任需要四個(gè)步驟,但不需要從頭到尾完成全部步驟,而是每個(gè)步驟由專人來完成,所有步驟并行進(jìn)行。 使用流水線的好處在于可以提高單位時(shí)間的生產(chǎn)量。


渲染流水線

  • 流水線的概念同樣可以用于計(jì)算機(jī)的圖像渲染中。計(jì)算機(jī)需要從一系列的頂點(diǎn)數(shù)據(jù)、紋理等信息出發(fā),把這些信息最終轉(zhuǎn)換成一張人眼可以觀察到的圖像。這個(gè)工作通常有CPU和GPU共同完成


  • 渲染流水線通常分為三個(gè)階段:應(yīng)用階段 ———> 幾何階段 ————> 光柵化階段


  1. 應(yīng)用階段: 這個(gè)階段有應(yīng)用主導(dǎo),通常由CPU負(fù)責(zé)實(shí)現(xiàn)。這一階段開發(fā)者有三個(gè)主要任務(wù),首先,需要準(zhǔn)備好場景數(shù)據(jù)(攝相機(jī)位置、視錐體、模型和光源等)。其次,為了提高渲染性能,需要做粗粒度的剔除工作。最后,需要設(shè)置好每個(gè)模型的渲染狀態(tài)(使用的材質(zhì)、使用的紋理、使用的Shader等)這一階段最重要的輸出是渲染所需的幾何信息,即渲染圖元。

  2. 幾何階段:幾何階段主要用于處理所有和我們繪制的幾何相關(guān)的事情。幾何階段負(fù)責(zé)和每個(gè)渲染圖元打交道,進(jìn)行逐頂點(diǎn)、逐多邊形的操作。這個(gè)階段可以進(jìn)一步分成更小的流水線階段。幾何階段的一個(gè)重要任務(wù)就是把頂點(diǎn)坐標(biāo)變換到屏幕空間中,再交給光柵器進(jìn)行處理。

  3. 光柵化階段: 這一階段會(huì)使用上個(gè)階段傳遞的數(shù)據(jù)來產(chǎn)生屏幕上的像素,并渲染出最終的圖像。


CPU和GPU之間的通信

  • 渲染流水線的起點(diǎn)是CPU,即應(yīng)用階段。大致可分為三個(gè)階段:

  1. 把數(shù)據(jù)加載到顯存中:所有渲染所需的數(shù)據(jù)都需要從硬盤中加載到系統(tǒng)內(nèi)存,然后,網(wǎng)格和紋理等數(shù)據(jù)又被加載到顯存。

  2. 設(shè)置渲染狀態(tài):這些狀態(tài)定義了場景中的網(wǎng)格如何被渲染。

  3. 調(diào)用Draw Call:Draw Call實(shí)際上就是一個(gè)命令,它的發(fā)起方是CPU,接收方是GPU,這個(gè)命令僅僅會(huì)指向一個(gè)需要被渲染的圖元列表,而不會(huì)再包含任何材質(zhì)信息。 當(dāng)給定一個(gè)Draw Call時(shí),GPU就會(huì)根據(jù)渲染狀態(tài)和所有輸入的頂點(diǎn)數(shù)據(jù)來進(jìn)行計(jì)算,最終輸出成屏幕上顯示的像素。

GPU流水線

  • 當(dāng)GPU從CPU得到渲染命令后,就會(huì)進(jìn)行一系列的流水線操作,最終把圖元渲染到屏幕上(就是上邊的調(diào)用Draw Call)


  • 對(duì)于渲染流水線中的后兩個(gè)階段(幾何階段和光柵化階段)開發(fā)者無法擁有絕對(duì)的控制權(quán),其實(shí)現(xiàn)的載體是GPU。GPU通過實(shí)現(xiàn)流水線化,大大加快了渲染速度,雖然我們無法完全控制這兩個(gè)階段的實(shí)現(xiàn)細(xì)節(jié),但其向開發(fā)者開放了很多控制權(quán)。

圖中展示了不同流水線階段以及它們的可配執(zhí)性和可編程性


頂點(diǎn)著色器

  • 頂點(diǎn)著色器是流水線的第一個(gè)階段,它的輸入來自于CPU。頂點(diǎn)著色器的處理單位是頂點(diǎn),輸入進(jìn)來的每個(gè)頂點(diǎn)都會(huì)調(diào)用一次頂點(diǎn)著色器。頂點(diǎn)著色器本身不可以創(chuàng)建或銷毀任何頂點(diǎn),并無法得到頂點(diǎn)與頂點(diǎn)之間的關(guān)系


  • 頂點(diǎn)著色器是完全可編程的,它通常用于實(shí)現(xiàn)頂點(diǎn)的坐標(biāo)變換和逐頂點(diǎn)光照。坐標(biāo)變換:就是對(duì)頂點(diǎn)的坐標(biāo)進(jìn)行某種變換—把頂點(diǎn)坐標(biāo)從模型空間轉(zhuǎn)換到齊次裁剪空間。我們可以通過坐標(biāo)變換來模擬水面、面料等。

曲面細(xì)分著色器

  • 是一個(gè)可選的著色器,主要用于細(xì)分圖元。

幾何著色器

  • 是一個(gè)可選的著色器,可用于執(zhí)行逐圖元的著色操作,或者被用于產(chǎn)生更多的圖元。

裁剪

  • 這一階段是可配置的。目的是把那些不在視野內(nèi)的頂點(diǎn)裁剪掉,并剔除某些三角形圖元的面片。

一個(gè)圖元與攝像機(jī)視野的關(guān)系有3種:完全在視野內(nèi)、部分在視野內(nèi)、完全在視野外。

  1. 完全在視野內(nèi)的圖元會(huì)繼續(xù)傳遞給下一個(gè)流水線階段

  2. 完全在視野外的圖元不會(huì)繼續(xù)向下傳遞

  3. 部分在視野內(nèi)的圖元需要做裁剪處理和頂點(diǎn)著色器不同的是,這一步是不可編程的。我們無法通過編程來控制裁剪的過程,而是硬件上的固定操作。

屏幕映射

  • 這一階段是不可配置和編程的,負(fù)責(zé)把每個(gè)圖元的坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)。

這一步輸入的坐標(biāo)仍然是三維坐標(biāo)系下的坐標(biāo)。屏幕映射的任務(wù)是把每個(gè)圖元的x和y坐標(biāo)轉(zhuǎn)換到屏幕坐標(biāo)系下。

屏幕映射得到的屏幕坐標(biāo)決定了這個(gè)頂點(diǎn)對(duì)應(yīng)屏幕上哪個(gè)像素以及距離這個(gè)像素的距離。一個(gè)需要注意的地方,屏幕坐標(biāo)系在OpenGL和DirectX中,OpenGL把屏幕左下角當(dāng)作最小的窗口坐標(biāo)值,DirectX則在屏幕左上角為最小窗口坐標(biāo)值。


三角形設(shè)置

  • 由這一步開始進(jìn)入光柵化階段。

上一階段輸出的信息是屏幕坐標(biāo)系下的頂點(diǎn)位置以及和它們相關(guān)的其他信息,如深度值、法線方向、視角方向等。

光柵化階段的目標(biāo):

1.計(jì)算每個(gè)圖元覆蓋了哪些像素

2.為這些像素計(jì)算它們的顏色

三角形設(shè)置作為光柵化的第一個(gè)階段,會(huì)計(jì)算出光柵化一個(gè)三角網(wǎng)格所需要的信息。上一階段的輸出是三角網(wǎng)格的頂點(diǎn),如果想得到整個(gè)三角網(wǎng)格的覆蓋情況,就必須計(jì)算每條邊上的像素坐標(biāo),為了計(jì)算邊界像素的坐標(biāo)信息,我們就需要得到三角形邊界的表示方式。這樣一個(gè)得到三角形邊界表示方式的過程就是三角形設(shè)置。

它的輸出是為下一個(gè)階段做準(zhǔn)備


三角形遍歷

  • 三角形遍歷階段將會(huì)檢查每個(gè)像素是否被一個(gè)三角網(wǎng)格所覆蓋。如果被覆蓋,就會(huì)生成一個(gè)片元。而這樣一個(gè)找到哪些像素被三角網(wǎng)格覆蓋的過程,就是三角形遍歷,這個(gè)階段也被稱為掃描變換。

三角形遍歷階段會(huì)根據(jù)上一個(gè)階段的計(jì)算結(jié)果來判斷一個(gè)三角網(wǎng)格覆蓋了哪些像素,并使用三角網(wǎng)格三個(gè)頂點(diǎn)的頂點(diǎn)信息對(duì)整個(gè)覆蓋區(qū)域的像素進(jìn)行插值。

這一步的輸出就是得到一個(gè)片元序列。一個(gè)片元并不是真正意義上的像素,而是包含了很多狀態(tài)的幾何,這些狀態(tài)用于計(jì)算每個(gè)像素的最終顏色


片元著色器

  • 片元著色器是另一個(gè)非常重要的可編程著色器階段,在DirectX中,片元著色器被稱為像素著色器。

片元著色器的輸入就是上一階段對(duì)頂點(diǎn)信息插值得到的結(jié)果,更具體點(diǎn)說,是根據(jù)從頂點(diǎn)著色器中輸出的數(shù)據(jù)插值得到的。而其的輸出是一個(gè)或者多個(gè)顏色值。

這一階段可以完成很多重要的渲染技術(shù),如紋理采樣,但是它的局限在于,它僅可以影響單個(gè)片元。

逐片元操作

  • 這是渲染流水線的最后一步,這一步驟的目的是:合并

這一階段有幾個(gè)主要任務(wù):

  1. 決定每個(gè)片元的可見性。這涉及了深度測試、模板測試等

  2. 如果一個(gè)片元通過了所有的測試,就需要把這個(gè)片元的顏色值和已經(jīng)存儲(chǔ)在顏色緩沖區(qū)中的顏色進(jìn)行合并,或者說是混合。這一階段是高度可配置性的

  • 這個(gè)階段首先需要解決每個(gè)片元的可見性問題。這需要進(jìn)行一系列的測試。片元 ——> 模版測試 ——> 深度測試 ——> 混合 ——> 顏色緩沖區(qū)

深度測試和模版測試的簡化流程圖

模板測試

如果開啟了模板測試,GPU會(huì)首先讀取模板緩沖區(qū)中該片元位置的模板值,然后將該值和讀取到的參考值(可以開發(fā)者自己指定)進(jìn)行比較,開發(fā)者可以設(shè)定成小于時(shí)舍棄或者大于等于時(shí)舍棄該片元。

模板測試通常用于限制渲染的區(qū)域,另外模板測試還有別的高級(jí)用法,如渲染陰影,輪廓渲染。?

深度測試

如果一個(gè)片元幸運(yùn)的通過了模板測試,那么就會(huì)進(jìn)行深度測試,如果開啟了深度深度,GPU就會(huì)把該片的深度值和已經(jīng)存在于深度緩沖區(qū)中的深度值進(jìn)行比較,這個(gè)比較函數(shù)也是由開發(fā)者設(shè)定的,可以選擇大于此值時(shí)舍棄也可以選擇小于等于此值時(shí)舍棄。

但通常這個(gè)比較函數(shù)是小于等于的關(guān)系,這是因?yàn)槲覀兾覀兛傁胫伙@示出離攝像機(jī)最近的物體,而那些被其他物體遮擋的片元就不需要出現(xiàn)在屏幕上。和模板測試不同的是,如果一個(gè)片元沒有通過深度測試,他就沒有權(quán)利修改深度緩沖區(qū)中的值。而如果通過了測試,開發(fā)者可以通開啟/關(guān)閉深度寫入來決定是否要利用這個(gè)片元的深度值覆蓋緩沖區(qū)中的值。

合并

我們所討論的渲染過程是一個(gè)物體接著一個(gè)物體渲染到屏幕上,而每個(gè)像素的顏色信息被存儲(chǔ)在一個(gè)名為顏色緩沖的地方,因此當(dāng)我們執(zhí)行這次渲染時(shí),顏色緩沖中往往已經(jīng)有了上次渲染的顏色結(jié)果,那么我們是使用這次渲染得到的顏色完全覆蓋掉之前的結(jié)果,還是進(jìn)行其他處理,這就是合并需要解決的問題。

對(duì)于不透明物體,開發(fā)者可以關(guān)閉混合操作,這樣片元著色器計(jì)算得到的顏色值就會(huì)直接覆蓋掉顏色緩沖區(qū)中的像素值。但對(duì)于半透明的物體,我們就需要開啟混合操作來讓這個(gè)物體看起來是半透明的。混合操作是高度可配置的,開發(fā)者可以選擇開啟/關(guān)閉混合功能。

如果開啟了,GPU會(huì)取出源顏色和目標(biāo)顏色,將兩種顏色進(jìn)行混合。源顏色是指片元著色器得到的顏色值,而目標(biāo)顏色則是已經(jīng)存在于顏色緩沖區(qū)中的顏色值。


總結(jié)

真正實(shí)現(xiàn)渲染流水線的過程遠(yuǎn)比描述的要復(fù)雜,但Unity為我們封裝了很多功能,我們只需要在一個(gè)Unity Shader設(shè)置一些輸入、編寫頂點(diǎn)著色器和片元著色器、設(shè)置一些狀態(tài),就可以實(shí)現(xiàn)大部分屏幕效果。在最新的unity3D中還集成了Shader藍(lán)圖工具供開發(fā)者使用和學(xué)習(xí)。

在接下來的文章中,我們會(huì)通過實(shí)際的例子,來進(jìn)行更加詳細(xì)的UnityShader了解及學(xué)習(xí)。


想系統(tǒng)學(xué)習(xí)游戲開發(fā)的童鞋,歡迎訪問?http://levelpp.com/? ? ? ????????

游戲開發(fā)攪基QQ群:869551769? ? ? ? ??????

微信公眾號(hào):皮皮關(guān)

UnityShader系列之1:基礎(chǔ)篇的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
鲁山县| 阿拉善盟| 靖西县| 洱源县| 洛川县| 太和县| 定安县| 镇平县| 芒康县| 南宁市| 灌阳县| 长寿区| 贡山| 饶阳县| 齐齐哈尔市| 兴海县| 邳州市| 新龙县| 白山市| 东安县| 清河县| 土默特左旗| 麟游县| 安庆市| 常州市| 黄骅市| 佛坪县| 云和县| 南丹县| 台南市| 登封市| 红河县| 会理县| 冀州市| 江永县| 平远县| 陆良县| 四子王旗| 凤冈县| 宁海县| 乌拉特前旗|