圖形編程歷史
渲染流水線
目前最新的可編程圖形硬件支持功能:
- 支持頂點和片段的可編程能力
- 支持IEEE32位的浮點運算(IEEE32是國際電工委員會置頂的浮點書表示方式,主要內容是用四個字節來表示浮點數,可以表示的數據的負數范圍是(-22)128~-2127,2^-127~22^128)
- 支持四元向量和四階矩陣
- 提供分支和循環的控制語句
- 具有高帶寬的內存處理能力
- 支持1D,2D,3D的紋理查詢和使用能力,而且速度非常快
- 支持繪制到紋理功能
渲染流水線
-
含義
: 計算機需要從一系列的頂點數據、紋理等信息出發、生成(或者說渲染)一張二維圖像的過程。 - 渲染流程分為三個階段
-
應用程序階段
:(CPU)-
準備數據
eg.攝像機的位置、?視椎體、場景中的模型和光源等等 -
culling
粗粒度剔除 eg.將不可見的物體剔除 -
輸出
輸出渲染所需的幾何信息(點、線、三角面),即渲染圖元
。
-
-
幾何階段
:(GPU)-
處理?渲染圖元
進行逐頂點、逐多邊形的操作。頂點坐標轉換到屏幕空間。 -
輸出
屏幕空間的二維頂點坐標、每個頂點對應的深度值、著色等相關信息。
-
-
光柵化階段?
:(GPU)- 對上階段的數據進行插值,再進行逐像素的處理。
-
CPU與GPU之間的通信
-
CPU?流水線
(即應用階段)- 把數據加載到顯存里
- 設置渲染狀態
- 調用Draw Call(發起方是CPU,接收方是GPU)
-
GPU流水線
(即幾何階段和光柵化階段)
[圖片上傳失敗...(image-260204-1513936425700)] - ?
頂點著色器
: 必選,可編程,通常用于實現頂點坐標的變換,?計算頂點顏色。 -
曲面細分著色器
:可選,用于細分圖元。 -
幾何著色器
:可選,用于逐圖元的著色操作,或者用于產生更多的圖元。 -
裁剪
: 可配置,將不是攝像機視野中的頂點裁剪掉。 -
屏幕映射
: 不可編程,不可配置。把每個圖元的坐標轉換到屏幕坐標系。 -
三角設置
和三角形遍歷
階段都是固定函數的階段。 -
片元著色器
:可編程,用于?實現逐片元的著色操作。 -
逐片元操作
: 可配置,eg.顏色修改,深度緩,沖進行混合等。
三種語言:
- OpenGl的GLSL
- Direct3D的HLSL
- NVIDIA的CG(CG編寫的可同時兼容?OpenGL和Direct平臺)
GPU流水線的兩個重要階段
-
頂點著色器
- 輸入: GPU前端模塊提取圖元信息(頂點位置,法線向量,紋理坐標(uv))等。
- 操作: 頂點坐標空間轉換,法向量空間轉換,光照計算等(現在光照計算一般在片段著色器,比較細),然后將計算好的數據傳入指定寄存器中。
-
片元著色器
- 輸入:頂點著色器傳入的數據。
- 操作:光照計算,uv擾動,紋理采樣等,最后輸出當前片段的顏色給光柵化階段(片段著色器是對每個獨立的顏色進行操作的)。
數學基礎
推薦《3D數學基礎:圖形與游戲開發》
CG語言基礎
- CG語言的特性:
Cg是一種類C的語言,他沿用了大量的C語言特性,但是也有不同之處。Cg語言是腳本性語言,不能編譯,調試和斷點;并且Cg語言的主要用途是繪制像素顏色到屏幕上,他不能處理文字類的內容。Cg語言對單精度浮點的數據類型是非常敏感的;Cg語言因為GPU的并發特性所以導致Cg語言的所有執行過程是并發式的; - CG語法
- 基礎數據類型 :
- float : 32位浮點數據
float _Angle = 1.0
- half : 16位浮點數據
half _Angle = 1.0
- int : 32位整形數據
int _Angle = 1
- fixed : 12位浮點數據
fixed _Angle = 1
- bool : ?布爾數據,用于判斷
if(_Angle == 0) { colors = diffuses.rgb; }
- Sampler 紋理對象,6類 : Sampler,sampler1D,sampler2D,sampler3D,samplerCUBE和samplerRECT
sample2D _Diffuse;
- float : 32位浮點數據
- 特殊的數據類型
- 向量 : 一共擁有4種維度的向量,1-4之間
float3 a = float3(0,1,2);
- 矩陣 : 行和列都不得大于4和不得小于1
float2*2 a = {sin@,0,1,3};
矩陣在賦值的時候一定要人為的分開行與行之間的關系,但是程序只認識順序的賦值
- 數組 : 因為CG是顯卡操作語,沒有內存,所以聲明的時候要制定大小
float2 b[2]; int arrayLen = b.length; // 結果是2 float m[3][4]; arrayLen = m.length;// 結果是3; arrayLen = m[1].length;// 結果是4;
- 結構體 : 數據封裝作用
struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; };
- 表達式和控制語句
- 關系操作符 :<,>,<=,>=,!=,==,
- 邏輯操作符 :&&,||,!
- 數學操作符 :+,—,*,/,%
- 移位操作符 :>>
int2 a = int2(0.0,0.0); int2 b = a>>1;
- Swizzle操作符:
float4(a, b, c, d).xyz 等價于 float3(a, b, c)
- 控制流語句 :if ,if-else while ,for,break
- 點操作?符:只針對向量和結構
v2f o; o.pos = UnityObjectToClipPos(v.vertex);
- 點操作?符:只針對向量和結構
- 行參修飾詞:
- in: 表示當前行參是只能輸入的;
- out:表示當前行參用來輸出數據的;
- inout: 表示可以進行輸入和輸出;
- 離散數據圖元信息:
uniform
- 只讀性,只要標有uniform標簽的變量,這個變量我們就不能初始化也不能修改其內容;
- 使用范圍特性,只能存在于入口函數的行參上或者是全局的變量身上;
- 他只能支持引擎向著色器傳入的數據,不能向外提交數據;
- 向量 : 一共擁有4種維度的向量,1-4之間
- 語義
[圖片上傳失敗...(image-525f9a-1513936425700)]
- 基礎數據類型 :