Cg編程

在計算機圖形學領域,用計算機處理圖形信息我們最先接觸的通常是使用opengl和d3d這些圖形編程接口,這些通常稱爲固定管線的編程,也就是程序員不直接操縱可編程的GPU,在常見的opengl的編程管線中,底層爲我們設定了固定的渲染過程,程序員控制的只是這個過程中的各種參數。但是在有些情況下,尤其是硬件性能突飛猛進的今天,爲了得到更好的效果,得到對圖形計算更好的控制,就需要自己對GPU進行編程,這也就是可編程的圖形渲染,這些用於對GPU的編程接口就是GPU語言,CG是NVIDIA開發的針對NVDIA圖形處理器的硬件編程語言,它的全程是C for graph,也就是圖像的C語言,因爲它和c的文法很相似,所以有了c語言的基礎,學習cg將是很輕鬆的事情。以下是我學習的Cg語言的一些心得。

 

1圖形渲染管線

現代計算機處理圖形主要依靠圖形處理單元(GPU)來完成,在GPU上渲染圖形的整個過程就是圖形渲染管線,整個管線的輸入是最初的描述圖元的數據,輸出是屏幕上每個像素的顏色,一切圖形學的處理過程都在這個管線中進行。

常見的Gpu的渲染管線的具體內容如下

 

注意這個圖中的每個操作是有嚴格的先後順序之分的。

 

在過去,在我們簡單的使用opengl或者到到d3d進行圖形繪製時,底層自動按照上述順序爲我們生成圖形,我們在opengl中做的只是調節其中各個“參數”,但是數據走的通路是一樣的,這稱爲固定渲染管線。

Gpu主要包括頂點處理器和片段處理器,在第三代顯卡(GEforce3)之後,gpu的頂點處理器可以進行編程,也就是上圖中的頂點變換部分可以被控制,在第四代顯卡(GEForceFX)之後gpu的片段處理器可以進行編程,也就是插值 紋理採樣 着色這一過程可以進行編程,現在我們可以自行調控上述兩個紅色部分的工作流程,而不必沿着固定渲染管線,這就叫做可編程的圖形渲染。

當然cg語言也要依託於opengl和d3d這些圖形硬件的藉口,因爲上圖中的藍色部分仍需他們來做,只是紅色部分我們可以不再用opnegl來寫和控制,另外諸如向硬件發送和接受數據也需要他們,cg語言的作用只是在opnegl中控制上述兩個紅色方塊中的處理過程。

 

2頂點程序

在頂點處理器中執行的程序叫做頂點程序,頂點程序的作用也就是進行頂點變化,在圖形渲染管線中,它可以做三件事,一是將輸入的物體的局部座標轉化成最終的剪裁座標,二是生成每個頂點的紋理座標,三是產生每個頂點的顏色。所以在一個頂點程序中,允許的輸入有位置信息(這個位置是局部座標),頂點顏色(在opengl中繪製頂點時指定的),法向信息,n個紋理座標(在opengl中指定的),輸出通常有位置、顏色、n個紋理座標,不輸出的有默認值。

也就是我們可以直接掌控的頂點的屬性有這三個:

1剪裁座標系的位置:這個位置的值只有在-1在1之間才能被看見,也就是x爲1的點恰好落在渲染窗口的最右邊的線上,而剪裁座標的z值就是深度值,可以直接控制這個座標來控制圖形的繪製於隱藏及其他集合變化等。

Projection Matrix*Modelview Matrix *局部座標=剪裁座標

2顏色就是每個頂點最終的着色

3紋理座標通常就是我們去直接控制每個頂點的紋理座標。但是更重要的是這裏的紋理座標通常不存儲紋理,而是一個大的“緩存器”,它通常用來存儲每個頂點的其他屬性(如發向或其他任何想存儲的和每個頂點有關的)然後傳入給片段處理器進行處理。如我們要在片段處理器中每個頂點的法向進行差值做phone shading,這時就要先在頂點處理器中將法向裝入一個紋理中傳給片段程序。通常紋理的數量由opengl和硬件決定。

3片段程序

    在片段處理器中執行的程序稱作片段程序,片段程序的作用其實說到底只有一個,就是爲已經光柵化的每一個片段產生它的顏色。對於片段程序,它的輸入只有紋理信息,輸出也只有顏色信息。當然輸入的紋理信息可以封裝其他的可以被光柵化的信息(如位置、法向等),我們可以根據不同的需要和紋理採樣來直接控制每個片段的最終顏色。

4 Cg程序在C/C++環境中的使用

通常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()。

5 一些例子

可編程的圖形渲染相比固定管線的渲染的優勢是不用多說的,它交給程序員更多的空間去發揮,去自由的操縱圖形的處理過程,通常他可以做到在固定管線編程中難以實現甚至根本無法實現的效果,還可以大大加速渲染的效率,因爲指令在gpu上的運行速度比在cpu上要快的多的多。所以從渲染效果和效率上講我們都儘量使用可編程的圖形渲染。

《theCg Tutorial》一書中爲我們實現了很多cg 程序的實例,可以自己嘗試實現一下,包括phone shading、動畫、環境貼圖、bumpe mapping、fog等,當然所有的你想實現的效果都可以用cg 來實現,關鍵看你的想象空間和編程能力了。


轉載自:http://blog.csdn.net/leonwei/article/details/4583045

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章