HLSL GLSL CG着色語言比較

轉自:http://blog.csdn.net/pizi0475/article/details/6574700

摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU編程與CG語言之陽春白雪下里巴人”

 

    In the last year I have never had to write a single HLSL/GLSL shader. Bottom line, I can’t think of any reason NOT to use CG.

    shader language,稱爲着色語言,shade在英語是陰影、顏色深淺的意思,Wikipedia上對shader language的解釋爲“The job of a surface shading procedure is to choose a color for each pixel on a surface, incorporating any variations in color of the surface itself and the effects of lights that shine on the surface(Marc Olano)”,即,shader language基於物體本身屬性和光照條件,計算每個像素的顏色值。

    實際上這種解釋具有明顯的時代侷限性,在GPU編程發展的早期,shader language的提出目標是加強對圖形處理算法的控制,所以對該語言的定義亦針對於此。但隨着技術的進步,目前的shader language早已經用於通用計算研究。

    shader language被定位爲高級語言,如,GLSL的全稱是“High Level Shading Language”,Cg語言的全稱爲“C for Graphic”,並且這兩種shader language的語法設計非常類似於C語言。不過高級語言的一個重要特性是“獨立於硬件”,在這一方面shader language暫時還做不到,shader language完全依賴於GPU構架,這一特徵在現階段是非常明顯的!任意一種shader language都必須基於圖形硬件,所以GPU編程技術的發展本質上還是圖形硬件的發展。在shader language存在之前,展示基於圖形硬件的編程能力只能靠低級的彙編語言。

    目前,shader language的發展方向是設計出在便捷性方面可以和C++/JAVA相比的高級語言,“賦予程序員靈活而方便的編程方式”,並“儘可能的控制渲染過程”同時“利用圖形硬件的並行性,提高算法的效率”。Shader language目前主要有3種語言:基於OpenGL的GLSL,基於Direct3D的HLSL,還有NVIDIA公司的Cg 語言。

    本章的目的是闡述shader language的基本原理和運行流程,首先從硬件的角度對Programmable Vertex Processor(可編程頂點處理器,又稱爲頂點着色器)和 Programmable Fragment Processor(可編程片斷處理器,又稱爲片斷着色器)的作用進行闡述,然後在此基礎上對vertex program和fragment program進行具體論述,最後對GLSL、HLSL和Cg進行比較。

3.1 Shader Language原理

    使用shader language編寫的程序稱之爲shader program(着色程序)。着色程序分爲兩類:vertex shader program(頂點着色程序)和fragment shader program(片斷着色程序)。爲了清楚的解釋頂點着色和片斷着色的含義,我們首先從闡述GPU上的兩個組件:Programmable Vertex Processor(可編程頂點處理器,又稱爲頂點着色器)和 Programmable Fragment Processor(可編程片斷處理器,又稱爲片斷着色器)。文獻[2]第1.2.4節中論述到:

    The vertex and Fragment processing broken out into programmable units. The Programmable vertex processor is the hardware unit that runs your Cg Vertex programs, whereas the programmable fragment processor is the unit that runs your Cg fragment programs.

    這段話的含義是:頂點和片段處理器被分離成可編程單元,可編程頂點處理器是一個硬件單元,可以運行頂點程序,而可編程片段處理器則是一個可以運行片段程序的單元。

頂點和片段處理器都擁有非常強大的並行計算能力,並且非常擅長於矩陣(不高於4階)計算,片段處理器還可以高速查詢紋理信息(目前頂點處理器還不行,這是頂點處理器的一個發展方向)。

如上所述,頂點程序運行在頂點處理器上,片段程序運行在片段處理器上,哪麼它們究竟控制了GPU渲染的哪個過程。圖 8展示了可編程圖形渲染管線。

 

着色語言比較,以及HLSL VS GLSL VS CG - 童童 - lee_shutong 的GPU博客

    對比上一章圖 3。中的GPU渲染管線,可以看出,頂點着色器控制頂點座標轉換過程;片段着色器控制像素顏色計算過程。這樣就區分出頂點着色程序和片段着色程序的各自分工:Vertex program負責頂點座標變換;Fragment program負責像素顏色計算;前者的輸出是後者的輸入。

    圖 9展示了現階段可編程圖形硬件的輸入/輸出。輸入寄存器存放輸入的圖元信息;輸出寄存器存放處理後的圖元信息;紋理buffer存放紋理數據,目前大多數的可編程圖形硬件只支持片段處理器處理紋理;從外部宿主程序輸入的常量放在常量寄存器中;臨時寄存器存放着色程序在執行過程中產生的臨時數據。

 

着色語言比較,以及HLSL VS GLSL VS CG - 童童 - lee_shutong 的GPU博客

3.2 Vertex Shader Program

    Vertex shader program(頂點着色程序)和Fragment shader program(片斷着色程序)分別被Programmable Vertex Processor(可編程頂點處理器)和 Programmable Fragment Processo(可編程片斷處理器)所執行。

    頂點着色程序從GPU前端模塊(寄存器)中提取圖元信息(頂點位置、法向量、紋理座標等),並完成頂點座標空間轉換、法向量空間轉換、光照計算等操作,最後將計算好的數據傳送到指定寄存器中;然後片斷着色程序從中獲取需要的數據,通常爲“紋理座標、光照信息等”,並根據這些信息以及從應用程序傳遞的紋理信息(如果有的話)進行每個片斷的顏色計算,最後將處理後的數據送光柵操作模塊。

圖 10展示了在頂點着色器和像素着色器的數據處理流程。在應用程序中設定的圖元信息(頂點位置座標、顏色、紋理座標等)傳遞到vertex buffer中;紋理信息傳遞到texture buffer中。其中虛線表示目前還沒有實現的數據傳遞。當前的頂點程序還不能處理紋理信息,紋理信息只能在片斷程序中讀入。

頂點着色程序與片斷着色程序通常是同時存在,相互配合,前者的輸出作爲後者的輸入。不過,也可以只有頂點着色程序。如果只有頂點着色程序,那麼只對輸入的頂點進行操作,而頂點內部的點則按照硬件默認的方式自動插值。例如,輸入一個三角面片,頂點着色程序對其進行phong光照計算,只計算三個頂點的光照顏色,而三角面片內部點的顏色按照硬件默認的算法(Gourand明暗處理或者快速phong明暗處理)進行插值,如果圖形硬件比較先進,默認的處理算法較好(快速phong明暗處理),則效果也會較好;如果圖形硬件使用Gourand明暗處理算法,則會出現馬赫帶效應(條帶化)。

而片斷着色程序是對每個片斷進行獨立的顏色計算,並且算法由自己編寫,不但可控性好,而且可以達到更好的效果。

    由於GPU對數據進行並行處理,所以每個數據都會執行一次shader程序程序。即,每個頂點數據都會執行一次頂點程序;每個片段都會執行一次片段程序。

 

着色語言比較,以及HLSL VS GLSL VS CG - 童童 - lee_shutong 的GPU博客

3.3 Fragment Shader Program

    片斷着色程序對每個片斷進行獨立的顏色計算,最後輸出顏色值的就是該片段最終顯示的顏色。可以這樣說,頂點着色程序主要進行幾何方面的運算,而片段着色程序主要針對最終的顏色值進行計算。

片段着色程序還有一個突出的特點是:擁有檢索紋理的能力。對於GPU而言,紋理等價於數組,這意味着,如果要做通用計算,例如數組排序、字符串檢索等,就必須使用到片段着色程序。讓頂點着色器也擁有檢索紋理的能力,是目前的一個研究方向。

    附:什麼是片斷?片斷和像素有什麼不一樣?所謂片斷就是所有的三維頂點在光柵化之後的數據集合,這些數據還沒有經過深度值比較,而屏幕顯示的像素都是經過深度比較的。

3.4 CG VS GLSL VS HLSL

    Shader language目前有3種主流語言:基於OpenGL的GLSL(OpenGL Shading Language,也稱爲GLslang),基於Direct3D的HLSL(High Level Shading Language),還有NVIDIA公司的Cg (C for Graphic)語言。

    GLSL與HLSL分別提基於OpenGL和Direct3D的接口,兩者不能混用,事實上OpenGL和Direct3D一直都是冤家對頭,曹操和劉備還有一段和平共處的甜美時光,但OpenGL和Direct3D各自的東家則從來都是爭鬥不休。爭鬥良久,既然沒有分出勝負,那麼必然是兩敗俱傷的局面。

首先ATI系列顯卡對OpenGL擴展支持不夠,例如我在使用OSG(Open Scene Graphic)開源圖形引擎時,由於該引擎完全基於OpenGL,導致其上編寫的3D仿真程序在較老的顯卡上常常出現紋理無法顯示的問題。其次GLSL 的語法體系自成一家,而HLSL和Cg語言的語法基本相同,這就意味着,只要學習HLSL和Cg中的任何一種,就等同於學習了兩種語言。不過OpenGL 畢竟圖形API的曾經領袖,通常介紹OpenGL都會附加上一句“事實上的工業標準”,所以在其長期發展中積累下的用戶羣龐大,這些用戶當然會選擇 GLSL學習。此外,GLSL繼承了OpenGL的良好移植性,一度在unix等操作系統上獨領風騷(已是曾經的往事)。

    微軟的HLSL移植性較差,在windows平臺上可謂一家獨大,可一出自己的院子(還好院子夠大),就是落地鳳凰不如雞。這一點在很大程度上限制了 HLSL的推廣和發展。目前HLSL多半都是用於遊戲領域。我可以負責任的斷言,在Shader language領域,HLSL可以憑藉微軟的老本成爲割據一方的諸侯,但,決不可能成爲君臨天下的霸主。這和微軟現在的局面很像,就是一個被帶刺鮮花簇擁着的大財主,富貴已極,寸步難行。

    上面兩個大佬打的很熱烈,在這種情況下可以用一句俗話來形容,“鷸蚌相爭,漁翁得利”。NVIDIA是現在當之無愧的顯卡之王(尤其在AMD兼併ATI之後),是GPU編程理論的奠基者,GeForce系列顯卡早已深入人心,它推出的Cg語言已經取得了巨大的成功,生生形成了三足鼎立之勢。NVIDIA公司深通廣告之道,目前最流行的GPU編程精粹一書就出自該公司,書中不但介紹了大量的GPU前沿知識,最重要的是大部分都用Cg語言實現。憑藉該系列的書籍,NVIDIA不光確定了在青年學子間的學術地位,而且成功的推廣了Cg語言。我本人就是使用Cg語言進行研發,基於如下理由:

    其一,Cg是一個可以被OpenGL和Direct3D廣泛支持的圖形處理器編程語言。 Cg語言和OpenGL、DirectX並不是同一層次的語言,而是OpenGL和DirectX的上層,即,Cg程序是運行在OpenGL和 DirectX標準頂點和像素着色的基礎上的;

    其二,Cg語言是Microsoft和NVIDIA相互協作在標準硬件光照語言的語法和語義上達成了一致,文獻[1]在1.3.1節的標題就是 “Microsoft and NVIDIA’s Collaboration to Develop Cg and HLSL”,所以,HLSL和Cg其實是同一種語言(參見Cg教程_可編程實時圖形權威指南29頁的致謝部分)。很多時候,你會發現用HLSL寫的代碼可以直接當中Cg代碼使用。也就是說,cg基於知識聯盟(Microsoft和NVIDIA),且擁有跨平臺性,選擇cg語言是大勢所趨。有心的讀者,可以注意市面上當前的GPU編程方面的書籍,大都是基於CG語言的。(附:Microsoft和NVIDIA聯手推出Cg,應該是一種經濟和技術上的雙贏,通過這種方式聯手打擊GLSL)

    此外,Cg,即C for graphics,用於圖形的C語言,這其實說明了當時設計人員的一個初衷,就是“讓基於圖形硬件的編程變得和C語言編程一樣方便,自由”。正如C++和 Java的語法是基於C的,cg語言本身也是基於C語言的。如果您使用過C、C++、Java其中任意一個,那麼Cg的語法也是比較容易掌握的。Cg語言極力保留了C語言的大部分語義,力圖讓開發人員從硬件細節中解脫出來,Cg同時擁有高級語言的好處,如代碼的易重用性,可讀性提高等。使用cg還可以實現動畫驅動、通用計算(排序、查找)等功能。

在曾經的一段時間中有一種流言:NVIDIA將要拋棄Cg語言。並且在網上關於Cg、GLSL、HLSL的優劣討論中,Cg的跨平臺性也受到過廣泛的質疑。我在2007年12月參加朱幼虹老師OSG培訓班時,他曾專門對Cg、GLSL、HLSL進行了比較,說道:儘管目前還有一些關於Cg和GLSL之間的爭議,不過主流的3D圖形廠家都開始支持Cg語言。市場經濟的選擇可以說明一切,時間可以明辨真僞,到2009年末,Cg語言不但沒有被拋棄,而且越來越受歡迎。

    我在OGRE官方論壇上,搜索過有關使用Cg和GLSL的討論帖子,套用其中一個帖子的結尾語來結束本章:

    In the last year I have never had to write a single HLSL/GLSL shader. Bottom line, I can’t think of any reason NOT to use CG.

發佈了176 篇原創文章 · 獲贊 62 · 訪問量 160萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章