2013年4月6日 星期六

OpenGL基本瞭解(四) (GLSL基本資料)

GLSL - OpenGL Shading Language 也稱作 GLslang,是一個以C語言為基礎的高階著色語言。它是由 OpenGL ARB 所建立,提供開發者對繪圖管線更多的直接控制,而無需使用彙編語言或硬體規格語言。

隨著近年來繪圖卡的進步, 已在渲染管線中的頂點(vertex)和片斷(fragment)層次中,加入更具彈性的新功能。 達到在這個層次中,使用片斷和頂點著色器的可編程性。
最初這個功能是以組合語言撰寫著色器來達到的。組合語言對開發者的使用是不直觀而複雜的。OpenGL ARB 建立了 OpenGL 著色語言,為 GPU 的程式設計提供更加直觀的方法,當維護開放標準的時候,就有助於帶動 OpenGL 的歷史。
最初 OpenGL 1.5 是以擴充形式引入,後來 OpenGL ARBOpenGL 2.0 核心中正式納入 GLSL。自 1992 年建立的OpenGL 1.0 起,OpenGL 2.0 是第一個 OpenGL 的大修改版。
使用 GLSL 有如下好處:
  • 具有跨平台的相容性,包括 MacintoshWindowsLinux 等作業系統。
  • 所有支援 OpenGL 著色語言的繪圖卡,都可以用來編寫著色器。
  • 允許廠商為特定的繪圖卡產生最佳化的代碼。
// 以上轉貼自  wiki   http://zh.wikipedia.org/wiki/GLSL


OpenGL的GLSL基本編寫

資料參考聯結
GLSL Language Specification, Version 4.20.11
OpenGL Fragment Shader Specification
OpenGL Vertex Shader Specification
OpenGL Shader Objects Specification
The official OpenGL website

電子書  OpenGL Shading Language Third Edition



有兩個檔案來分別對應 GL_VERTEX_SHADERGL_FRAGMENT_SHADER

以是基本範例
//檔案vertex.v.glsl  for GL_VERTEX_SHADER
//attribute vec2 coord2d; 
 
// attribute: 變數修飾語之一, 代表會從應用程式傳入(input)的變數.
// vec4: 代表包含有 4 個元素的向量
// 
// 頂點的位置
attribute vec4 Position;  // attribute 代表唯讀的變數

// 頂點的原始顏色
attribute vec4 SourceColor; 


// varying: 變數修飾語之一, 代表會從 vertex shader(目前這個檔案) 
//          傳遞(output)到 fragment shader 的變數
varying vec4 DestinationColor; 
 
void main(void) 
{                        
 //gl_Position = vec4(coord2d, 0.0, 1.0); 
// 將頂點的原始顏色(SourceColor)設定給要傳給 fragment shader 
    // 的顏色(DestinationColor), OpenGL 會用內插法來計算其值. 
    DestinationColor = SourceColor; 
    
    // gl_Position: 在 vertex shader 中必須設定的內建輸出變數,
    //                        代表每個頂點最終的位置.
    //
    // 在此設為原始的位置.
    gl_Position = Position;  
}
 
 
//檔案fragment.f.glsl  for  GL_FRAGMENT_SHADER

// varying: 變數修飾語之一, 代表會從 vertex shader
//          傳遞(input)到 fragment shader(目前這個檔案)的變數.
//          而且必須與在 vetex shader 中所定義的變數一致.  否則會回報compile error
//
// lowp: 代表使用最低的精密度(可提升效能). (medp: 中精密度; highp: 高 精密度)
//
varying lowp vec4 DestinationColor;
 

void main(void) 
{        
 //gl_FragColor[0] = gl_FragCoord.x/640.0;
 //gl_FragColor[1] = gl_FragCoord.y/480.0;
 //gl_FragColor[2] = 0.5;
 //gl_FragColor[3] = floor(mod(gl_FragCoord.y, 2.0));
  
 // gl_FragColor: 在 fragment shader 中必須設定的內建輸出變數,
    //               代表每個像素最終的顏色.
    //
    // 在此設為由 fragment shader 傳入的顏色, 再經由 OpenGL 內插(interpolated)求值. 
  gl_FragColor = DestinationColor;  //也可分別設定如前五行所設
};
 
參考網頁 
http://itouchs.blogspot.tw/2012/06/opengl-es-20-tutorial-part-1-2.html 
 
備註: vertex shader 會傳給 fragment shader 每個頂點的顏色值, 而當 
          fragment shader 要決定某個像素的顏色時, 會利用內插法來計算.  
 
 
 
 
 
 
 
常用資料形態 
參考網頁 

In GLSL, the types vec2, vec3, and vec4 represent 2D, 3D, and 4D floating-point vectors. (There are also types for integer and boolean vectors, which are not discussed here.) Vector variables are defined as you would expect if C, C++ or Java had these types:
vec2 a2DVector;
vec3 three_dimensional_vector;
vec4 vector4;

The data types for floating-point 2×2, 3×3, and 4×4 matrices are: mat2, mat3, and mat4:
mat2 m2x2;
mat3 linear_mapping;
mat4 trafo;
 
 
 
Shader-Centric View of OpenGL (VS = Vertex Shader, FS = Fragment
      Shader)”.
 
 



 
 
 Floating-point Precision in 3rd Generation Devices
 
 
The fragment shading language also defines the
    following built-in variables: 
gl_FragData[0]
gl_FragData is an array of output colors that has only one element. This exists in OpenGL ES only for compatibility reasons; use gl_FragColor instead.
gl_FragCoord
Input variable that contains window coordinates for the current fragment, which is useful for image processing.
gl_FrontFacing
Boolean input variable; true for front-facing primitives, false for back-faces. Use this to implement two-sided lighting.
gl_PointCoord
This is an input texture coordinate that's used only for point sprite rendering; we'll cover it in the section called “Rendering Confetti, Fireworks, and More: Point Sprites”.
 

2013年4月5日 星期五

OpenGL基本瞭解(三)


著色器 (Shader)  // 部分內容參考 http://cg2010studio.wordpress.com/2011/06/29/shader/


* 什麼是Shader?Shader可以翻譯為著色器,分為Vertex Shader & Pixel Shader ,即:頂點著色器和像素著色器。Shader主要指的是可編程管線的算法片段
* 什麼是管線?因為圖形渲染象流水線一樣的順序執行,所以形象說法,下文所涉及的處理pipeline就是這種東西。
需要注意的:關於老顯卡和新顯卡的區別是什麼?
* 以前老顯卡是不能編程的,所以叫固定管線。
* 詳細說明:以前固定管線時代,頂點的運算是固定不變的,就是坐標變換,比如投影到屏幕上的坐標換算,後來GPU出現了,頂點的運算就可以編程了,把這些操作頂點的算法叫shader。

The OpenGL ES assembly line


在OpenGL中,GLSL的shader使用的流程与C语言相似,每个shader类似一个C模块,首先需要单独编译(compile),然后一组编译好的shader连接(link)成一个完整程序。



 Early life of a vertex. Top row is conceptual; bottom row is OpenGL’s view

 

Last three stages of a vertex before rasterization(光柵)

 

1. Vertex Shader

* 什麼是Vertex?稱頂點,由於模型是由很多坐標點定義的,這些點就是Vertex。
* 什麼是Vertex Shader?用來改變物體模型外形,由於模型是由點構成的,因此改變點就是改變外形

2. Pixel Shader 

* 什麼是Pixel?稱像素,即一個像素點,像素點可以變化不同的顏色,由眾多的像素點就可以組成我們現在所見的電腦顯示內容。
* 什麼是Pixel Shader?當模型頂點變換完之後,需要填充顏色,這些填充算法是針對屏幕上的每個像素,所以叫Pixel Shader(像素著色器),以前這些內容是不能通過編程控制的,後來顯示卡的GPU出來後就可以編程控制了,因此這些算法叫piexl shader。
* 常見的毛髮效果渲染:遊戲引擎裡面,動物身上所渲染的一根根毛髮,就是用了Pixel Shader,因為毛髮這種是針對每個像素的,所以要用到Pixel shader。




shaderType是vertex shader或pixel shader中的一种,由常量GL_VERTEX_SHADER和GL_FRAGMENT_SHADER来表示——后者就是我们常说的pixel shader。


如果任何类型为GL_VERTEX_SHADER的shader对象连接到program,它将产生在“可编程顶点处理器”上可执行的程 序;

如果任何类型为GL_FRAGMENT_SHADER的shader对象连接到program,它将产生在“可编程片断处理器”上可执行的程序。 (=> PIXEL shader)


其他名詞

1. 固定功能的圖形處理流水線(fixed function graphics pipeline)

能夠實現Vertex Shader和Pixel Shader的顯卡的圖形處理流水線被稱作為是可編程的,相對而言,在此之前的圖形處理流水線被稱作為是固定功能(fixed function),下面是OpenGL圖形處理的一個簡圖:
完整的OpenGL圖形處理流水線為稱作為OpenGL機器(OpenGL machine,在OpenGL參考手冊上可以找到這份框架圖),就像一個電路圖一樣,上面有許許多多的開關,我們可以打開或者閉合這些開關,還可以設置 圖中各個處理單元的參數以控制處理的方法,但是無論如何整個系統的功能已經確定下來了,你只有使用或者不使用某些功能和控制某些功能的具體執行方法的權利 而無法實現自己定製的功能,所以這樣的圖形處理流水線被稱作為是固定功能的。(有實力的顯卡廠商在自己的OpenGL實現中添加了許多OpenGL擴展實 現了一些標準OpenGL規範所沒有的功能,現在有了可編程的圖形流水線,一般用戶也有機會實現一些自己定製的功能。)

2.Vertex Shader & Pixel Shader

雖然實現Vertex Shader和Pixel Shader功能的圖形流水線被稱作為是可編程的,但是實際上可編程的只有流水線的一部分,正如Vertex Shader 和Pixel Shader的字面意思一樣,現在可編程的部分只有處理頂點的和處理像素的單元。

Vertex ShaderPixel ShaderDirect3D)在不同的文檔裡面有不同的叫法,Nvidia在自己的OpenGL擴展中把Vertex Shader叫做Vertex Program、把Pixel Shader叫做Texture Shader,3D labs在自己提出一份OpenGL 2.0的提議裡面把這兩者分別叫做Vertex ShaderFragment(片元)Shader