使用opengl编程实现一个三维渲染实体_Unity Shader学习随记_01_渲染流水线
什么是Shader?它和Material(材質)的關系
Shader,中文翻譯:著色器,是可編程圖形管線的算法片段
Shader實際上就是一小段程序,它負責將輸入的頂點數據以指定的方式和輸入的貼圖或者顏色等組合起來,然后輸出。繪圖單元可以依據這個輸出來將圖像繪制到屏幕上。輸入的貼圖或者顏色等,加上對應的Shader,以及對Shader的特定的參數設置,將這些內容打包儲存在一起,得到的就是一個Material(材質)。之后,我們便可以將材質賦予三維物體來進行渲染(輸出)了。
Material(材質)包含Texture Mapping(貼圖),Texture Mapping(貼圖)包含紋理 Texture。紋理是最基本的數據輸入單位,游戲領域基本上都用的是位圖。此外還有程序化生成的紋理 Procedural Texture。貼圖的英語 Map 其實包含了另一層含義就是“映射”。其功能就是把紋理通過 UV 坐標映射到3D 物體表面。貼圖包含了除了紋理以外其他很多信息,比方說 UV 坐標、貼圖輸入輸出控制等等。
材質是一個數據集,主要功能就是給渲染器提供數據和光照算法。貼圖就是其中數據的一部分,根據用途不同,貼圖也會被分成不同的類型,比方說 Diffuse Map,Specular Map,Normal Map 和 Gloss Map 等等。另外一個重要部分就是光照模型 Shader ,用以實現不同的渲染效果。
材質好比引擎最終使用的商品,Shader好比是生產這種商品的加工方法,而貼圖就是原材料。
渲染流水線
渲染流水線的概念:渲染流程(Shader只是渲染流水線中的一個可編程算法片段)。主要就是將流程中各階段階段的輸出,輸入到下一階段進行工作并輸出到下一階段。例如,片段著色器會將在頂點著色器內進行了坐標變換的頂點數據輸入進來拓展成多邊形
渲染流水線的工作任務在于由一個三維場景出發、生成(或者說渲染)一張二維圖像。換句話說,計算機需要從一系列的頂點數據、紋理等信息出發,把這些信息最終轉換成一張人眼可以看到的圖像。
《Real-Time Rendering,Third Edition》書中將整個渲染流程分成3個階段:應用階段(Application Stage)、幾何階段(Geometry Stage)、光柵化階段(Rasterizer Stage)
應用階段(Application Stage):由應用主導,通常由CPU負責實現
渲染流水線的起始點是CPU,即應用階段。應用階段大致可分為下面三個階段:
1、把數據加載到顯存中
2、設置渲染狀態
3、調用Draw Call
這一階段最重要的輸出是渲染所需的幾何信息,即渲染圖元(rendering primitives)
通俗來講, 渲染圖元可以是點、線、三角面等。這些渲染圖元將會被傳遞給下一個階段——幾何階段。
1、把數據加載到顯存中。(場景數據,粗粒度剔除......)
渲染所需的數據都要從硬盤加載到系統內存,然后網格和紋理等數據又被加載到顯存。
2、設置渲染狀態
定義了場景中的網格是怎么被渲染的 (使用哪個shader ,材質,光源屬性等)
3、調用Draw Call
Draw Call就是一個命令。他的發起方是CPU,接收方是GPU。
這個命令僅僅會指向一個需要被渲染的圖元列表,而且不會再包含任何材質信息,上個階段已經完成了。
給定一個Draw Call后GPU根據渲染狀態,如材質紋理著色器等和所有輸入的頂點數據來進行計算,最終輸出成屏幕上顯示的像素。
Draw Call這個概念在游戲中可以經常聽到,它有很多別名,DP,批次,說的都是它,都是一會事情。在游戲中經常出現批次很多的性能問題。
舉個例子:場景中有兩個桶,如果是分別導入的,就是兩個Draw Call。如果是合并之后導入的,就是一個Draw Call。
批次太多會導致CPU性能開銷過大,一般來說有兩種解決辦法。
(1)合批,就是把能合并的都合并起來,盡量減少Draw Call。(肯定有不能合并的,比如場景中的一個大樹和主角,還有好多渲染狀態啊透明啊之類的)
(2)instance,GPU硬件算法。使用與大量需要重復繪制的模型,比如草地。但是instance是有上限的,并且只能減少Draw Call,對于增加的面數來說是無解的。
幾何階段(Geometry Stage):這一階段通常在GPU上進行。
幾何階段處理所有和我們要繪制的幾何相關的事情。
例如決定需要繪制的圖元是什么,怎樣繪制它們,在哪里繪制他們。
幾何階段和每個渲染圖元打交道,進行逐頂點、逐多邊形的操作。該階段可進一步被分解為更小的流水線階段。
幾何階段的另一個重要的任務是把頂點坐標變換道屏幕空間中,再交給光柵器進行處理。
這一階段會將輸出屏幕空間的二維頂點坐標、每個頂點對應的深度值、著色等相關信息傳遞給下個階段。
頂點著色——>投影——>裁剪——>屏幕映射
·頂點著色
1、通過坐標轉換,從模型空間轉換到齊次裁剪空間
首先頂點著色階段拿到的頂點坐標數據都是位于模型空間的,要經過模型轉換將這些坐標數據轉換到世界空間。接著為了方便后面的投影和裁剪,需要將坐標數據從世界空間轉換到攝像機空間(攝像機位置為原點,x軸指向右方,y指向上方,z軸是背離攝像機朝向的方向),這稱為視圖轉換。
視點變換對相機和模型對影響2、確定模型上頂點處材質的光照效果。將模型頂點的位置變換到齊次裁剪坐標系下,進行輸出后再由硬件做透視排除法得到歸一化(NDC)的設備坐標。
- 投影
主要使用兩種投影方法:正交投影、透視投影
正交投影(左),透視投影(右)為了最大化控制性能消耗,需要將那些不在攝像機范圍內或是被遮擋的物體裁剪掉,不被渲染。這一階段也是將模型從三維空間投影二維空間的過程。
模型空間——>攝像機空間——>歸一化坐標——>0-1之外的部分裁減掉
- 屏幕映射
這一階段最主要是將三維坐標系(x,y,z)下的每個幾何圖元坐標轉換到二維(x,y)屏幕空間。
又一個需要引起注意的地方是,OpenGL和DirectX的屏幕坐標系之間存在著差異,OpenGL把屏幕的左下角當成最小的窗口坐標值,而DirectX則定義了屏幕的左上角位最小的窗口坐標值。
光柵化階段(Rasterizer Stage):這一階段在GPU上運行
這一階段會使用上一階段傳遞的數據來產生屏幕上的像素,然后渲染出最終的圖像。
光柵化階段的任務主要是決定每個渲染圖元中的那些像素應該被繪制在屏幕上。
他需要對上階段的到的逐頂點數據進行插值,然后再進行逐像素處理。
與幾何階段類似,光柵化階段又可以分為更小的流水線階段:三角形設置、三角形遍歷、片元著色器、逐片元操作
總結
以上是生活随笔為你收集整理的使用opengl编程实现一个三维渲染实体_Unity Shader学习随记_01_渲染流水线的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python全栈开发总结_python全
- 下一篇: c# 通过字体对话框获取字体名称和字体大