在計算機圖形學領域,用計算機處理圖形資訊我們最先接觸的通常是使用
opengl
和d3d
這些圖形程式設計介面,這些通常稱為固定管線的程式設計,也就是程式設計師不直接操縱可程式設計的
gpu,在常見的
opengl
的程式設計管線中,底層為我們設定了固定的渲染過程,程式設計師控制的只是這個過程中的各種引數。但是在有些情況下,尤其是硬體效能突飛猛進的今天,為了得到更好的效果,得到對圖形計算更好的控制,就需要自己對
gpu進行程式設計,這也就是可程式設計的圖形渲染,這些用於對
gpu的程式設計介面就是
gpu語言,cg是
nvidia
開發的針對
nvdia
圖形處理器的硬體程式語言,它的全程是
c for graph
,也就是影象的
c語言,因為它和
c的文法很相似,所以有了
c語言的基礎,學習
cg將是很輕鬆的事情。以下是我學習的
cg語言的一些心得。
現代計算機處理圖形主要依靠圖形處理單元(
gpu)來完成,在
gpu上渲染圖形的整個過程就是圖形渲染管線,整個管線的輸入是最初的描述圖元的資料,輸出是螢幕上每個畫素的顏色,一切圖形學的處理過程都在這個管線中進行。
常見的gpu
的渲染管線的具體內容如下
注意這個圖中的每個操作是有嚴格的先後順序之分的。
在過去,在我們簡單的使用
opengl
或者到到
d3d進行圖形繪製時,底層自動按照上述順序為我們生成圖形,我們在
opengl
中做的只是調節其中各個「引數」,但是資料走的通路是一樣的,這稱為固定渲染管線。
gpu主要包括頂點處理器和片段處理器,在第三代顯示卡(
geforce3
)之後,
gpu的頂點處理器可以進行程式設計,也就是上圖中的頂點變換部分可以被控制,在***顯示卡(
geforcefx
)之後gpu
的片段處理器可以進行程式設計,也就是插值
紋理取樣
著色這一過程可以進行程式設計,現在我們可以自行調控上述兩個紅色部分的工作流程,而不必沿著固定渲染管線,這就叫做可程式設計的圖形渲染。
當然cg
語言也要依託於
opengl
和d3d
這些圖形硬體的藉口,因為上圖中的藍色部分仍需他們來做,只是紅色部分我們可以不再用
opnegl
來寫和控制,另外諸如向硬體傳送和接受資料也需要他們,
cg語言的作用只是在
opnegl
中控制上述兩個紅色方塊中的處理過程。
在頂點處理器中執行的程式叫做頂點程式,頂點程式的作用也就是進行頂點變化,在圖形渲染管線中,它可以做三件事,一是將輸入的物體的區域性座標轉化成最終的剪裁座標,二是生成每個頂點的紋理座標,三是產生每個頂點的顏色。所以在乙個頂點程式中,允許的輸入有位置資訊(這個位置是區域性座標),頂點顏色(在
opengl
中繪製頂點時指定的),法向資訊,
n個紋理座標(在
opengl
中指定的),輸出通常有位置、顏色、
n個紋理座標,不輸出的有預設值。
也就是我們可以直接掌控的頂點的屬性有這三個:
1剪裁座標系的位置:這個位置的值只有在-1在
1之間才能被看見,也就是x為
1的點恰好落在渲染視窗的最右邊的線上,而剪裁座標的
z值就是深度值,可以直接控制這個座標來控制圖形的繪製於隱藏及其他集合變化等。
projection matrix*modelview matrix *
區域性座標
=剪裁座標
2顏色就是每個頂點最終的著色
3紋理座標通常就是我們去直接控制每個頂點的紋理座標。但是更重要的是這裡的紋理座標通常不儲存紋理,而是乙個大的「快取器」,它通常用來儲存每個頂點的其他屬性(如發向或其他任何想儲存的和每個頂點有關的)然後傳入給片段處理器進行處理。如我們要在片段處理器中每個頂點的法向進行差值做
phone shading
,這時就要先在頂點處理器中將法向裝入乙個紋理中傳給片段程式。通常紋理的數量由
opengl
和硬體決定。
在片段處理器中執行的程式稱作片段程式,片段程式的作用其實說到底只有乙個,就是為已經光柵化的每乙個片段產生它的顏色。對於片段程式,它的輸入只有紋理資訊,輸出也只有顏色資訊。當然輸入的紋理資訊可以封裝其他的可以被光柵化的資訊(如位置、法向等),我們可以根據不同的需要和紋理取樣來直接控制每個片段的最終顏色。
通常cg
程式需要依附於
opengl
與d3d
程式使用,在
opengl
中的典型使用方式如下:
1建立乙個
cg上下文
context = cgcreatecontext(); 2
設定profile(每個頂點或片段程式各需要乙個)
mycgvertexprofile=cgglgetlatestprofile(cg_gl_vertex); 3
動態的編譯cg程式
vertexprogram=cgcreateprogramfromfile(context,cg_source,"v_shadowmap.cg",mycgvertexprofile,"vshadowmap",null); 4
載入編譯好的cg程式
cgglloadprogram(vertexprogram);
在使用cg程式之前都要先繫結這個
cg程式
cgglbindprogram(vertexprogram)
每次在使用cg程式之前要啟用這個profile
cgglenableprofile(mycgfragmentprofile);
使用之後要讓這個profile失效
cggldisableprofile
(mycgvertexprofile)
動態的改變cg 程式中的uniform引數:在cg程式中的uniform引數是指可以再外部動態改變的輸入引數,改變這個引數的語法有很多,常用的有
首先用paramtex0
=cggetnamedparameter(fragprogram,"tex0");得到cg程式fragprogram
的tex0這個uniform引數,
再用cgglsettextureparameter
(paramtex0,textureobj)
、cgsetparameter4fv
(paramtex0,accelar)等函式改變這個引數,最後用cgupdateprogramparameters
(fragprogram)來更新這個cg程式。
什麼時候呼叫cg程式?
在乙個opengl的環境中通常在什麼時候cg程式被執行呢,也就是說該在哪個地方呼叫cgglenableprofile
()讓cg程式起作用呢?答案是每次再opengl進行實際上的繪製時cg程式在管線中起作用,opengl的繪製通常是用glbegin
(gl_quads)……
glend()
或glutsolidsphear()等方式進行的,所以我們在這些語句前啟用呼叫cgglenableprofile,再繪製之後取消啟用cggldisableprofile
()。可程式設計的圖形渲染相比固定管線的渲染的優勢是不用多說的,它交給程式設計師更多的空間去發揮,去自由的操縱圖形的處理過程,通常他可以做到在固定管線程式設計中難以實現甚至根本無法實現的效果,還可以大大加速渲染的效率,因為指令在
gpu上的執行速度比在
cpu上要快的多的多。所以從渲染效果和效率上講我們都盡量使用可程式設計的圖形渲染。
《thecg tutorial
》一書中為我們實現了很多
cg 程式的例項,可以自己嘗試實現一下,包括
phone shading
、動畫、環境貼圖、
、fog
等,當然所有的你想實現的效果都可以用
cg 來實現,關鍵看你的想象空間和程式設計能力了。
Cg程式設計入門編(OpenGL)
原註 b alex d angelo alexz fusionindustries.com 譯 川流不息 huawenguang hotmail.com 未經本人同意,不能用於商業用途。一 概述 本文的程式中,結合opengl和glut在屏冪中畫了乙個立方體,程式中加入了cg著色程式 listing...
Cg程式設計入門編(OpenGL)
cg 你好!cg程式設計入門編 opengl 原註 b alex d angelo alexz fusionindustries.com 譯 川流不息 huawenguang hotmail.com 未經本人同意,不能用於商業用途。一 概述 本文的程式中,結合opengl和glut在屏冪中畫了乙個立...
shader程式設計之Cg基本語法
struct name abs num 絕對值 三角函式 cross a,b 兩個向量的叉積 determinant m 矩陣的行列式 dot a,b 兩個向量的點積 floor x 向下取整 lerp a,b,f 在a,b之間線性插值 log2 x 以2為底的x的對數 mul m,n 矩陣x矩陣,...