小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

GLSL

 LVADDIE 2015-07-17

在GLSL中,subroutine是這樣一種機制:它根據某個變量的值把一個函數調用和一個函數定義集合中的某一個函數定義綁定起來。在很多方面它和C語言中的函數指針類似。一個全局變量充當指針,用來調用函數??梢栽贠penGL中設置這個變量的值,這樣可以把它和多個函數定義中的一個綁定起來。subroutine中的函數定義不一定要同名,但是必須要有同等數量和相同類型的參數以及相同的返回類型

Subroutines提供了在運行時刻不用切換著色器或者是重新編譯或者是使用if判斷就能選擇不同實現功能的方法。例如,一個著色器里面可以實現多種算法用來在場景中渲染不同的對象。當渲染場景的時候,我們可以通過改變subroutines的全局變量的值來選擇合適的渲染算法而不是去通過切換著色器或者是使用條件判斷來實現。

注意:由于性能在著色器中越來越重要,所以避免條件判斷或著色器切換是很有必要的。有了subroutines,我們就能夠在不增加計算負載的情況下實現條件判斷和著色器切換的功能。


下面用一個例子來進行說明。在這個例子中,采用subroutine渲染了兩次茶壺。分別采用不同的光照模型。第一次用ADS(ambient,diffuse,specular)模型進行渲染,第二次只用diffuse模型渲染。一個subroutine全局變量用來選擇渲染算法。下面兩幅圖可以看出效果的對比。


左邊是ADS模型渲染效果,右邊是diffuse模型渲染效果。


下面介紹使用subroutines的步驟。

我們在vertex shader中進行subroutines的定義。

(1)首先是定義subroutine類型:

subroutine vec3 shadeModelType( vec4 position, vec3 normal);

上面的代碼定義了一個新的subroutine類型,其名字是shadeModelType。其語意和函數原型很類似。它定義了一個名字,一個參數列表和返回類型,參數名不是必須的。

(2)緊接著我們定義一個上述類型的uniform變量shadeModel:

subroutine uniform shadeModelType shadeModel;

這個變量充當了函數指針的作用,它在OpenGL應用程序中將會被賦值為兩個可能的函數之一。

(3)定義兩個函數,作為subroutine的一部分。

它們都有一個前綴是:

subroutine( shadeModelType )

其意味著函數和subroutine類型匹配。我們使用這個前綴定義了兩個函數:

  1. subroutine( shadeModelType )  
  2. vec3 phongModel( vec4 position, vec3 norm )  
  3. {  
  4.     vec3 s = normalize(vec3(Light.Position - position));  
  5.     vec3 v = normalize(-position.xyz);  
  6.     vec3 r = reflect( -s, norm );  
  7.     vec3 ambient = Light.La * Material.Ka;  
  8.     float sDotN = max( dot(s,norm), 0.0 );  
  9.     vec3 diffuse = Light.Ld * Material.Kd * sDotN;  
  10.     vec3 spec = vec3(0.0);  
  11.     if( sDotN > 0.0 )  
  12.         spec = Light.Ls * Material.Ks *  
  13.                pow( max( dot(r,v), 0.0 ), Material.Shininess );  
  14.   
  15.     return ambient + diffuse + spec;  
  16. }  
  17.   
  18. subroutine( shadeModelType )  
  19. vec3 diffuseOnly( vec4 position, vec3 norm )  
  20. {  
  21.     vec3 s = normalize( vec3(Light.Position - position) );  
  22.     return  
  23.         Light.Ld * Material.Kd * max( dot(s, norm), 0.0 );  
  24. }  
(4)函數調用

在vertex shader的main函數中,我們使用subroutine的uniform變量shadeModel來調用定義的兩個函數。

LightIntensity = shadeModel( eyePosition, eyeNorm );

這樣,根據uniform變量shadeModel的值,這個調用會被綁定到上述我們定義的兩個函數之一。

(5)給subroutine uniform變量賦值。

分兩步進行。

1、使用glGetSubroutineIndex函數查詢每個subroutine函數的索引。

  1. GLuint adsIndex = glGetSubroutineIndex( programHandle,  
  2.         GL_VERTEX_SHADER,  
  3.         "phongModel" );  
  4. GLuint diffuseIndex = glGetSubroutineIndex(programHandle,  
  5.         GL_VERTEX_SHADER,  
  6.         "diffuseOnly");  
第一個參數是程序的句柄。第二個是著色器。第三個是subroutine的名字。查詢到的索引存儲在兩個GLuint型的值中。
2、為了選擇合適的subroutine函數,我們需要給subroutine uniform變量shadeModel賦值。采用如下函數調用實現:

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);

這個函數可以一次設置多個uniform變量值。第一個參數指定著色階段。第二個是要設定的uniform變量的數量。這里只需要設置一個uniform變量的值。

如果要設置多個,那么第三個參數應該是個數組,通常數組中的第i個元素賦值給subroutine uniform變量中索引為i的那個。

這里只需要設置一個值,我們設置的是索引為0 的那么subroutine uniform變量。

注意:OpenGL中,uniform 變量的索引默認就是從0開始的。如果有多個變量需要設置,可以用 glGetSubroutineUniformLocation()查詢。 

接下來進行渲染就可以得出相應的效果了。


要進行另外一種效果的渲染只需調用下面函數:

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);

再進來渲染過程即可。在GLSL中,subroutine是這樣一種機制:它根據某個變量的值把一個函數調用和一個函數定義集合中的某一個函數定義綁定起來。在很多方面它和C語言中的函數指針類似。一個全局變量充當指針,用來調用函數??梢栽贠penGL中設置這個變量的值,這樣可以把它和多個函數定義中的一個綁定起來。subroutine中的函數定義不一定要同名,但是必須要有同等數量和相同類型的參數以及相同的返回類型

Subroutines提供了在運行時刻不用切換著色器或者是重新編譯或者是使用if判斷就能選擇不同實現功能的方法。例如,一個著色器里面可以實現多種算法用來在場景中渲染不同的對象。當渲染場景的時候,我們可以通過改變subroutines的全局變量的值來選擇合適的渲染算法而不是去通過切換著色器或者是使用條件判斷來實現。

注意:由于性能在著色器中越來越重要,所以避免條件判斷或著色器切換是很有必要的。有了subroutines,我們就能夠在不增加計算負載的情況下實現條件判斷和著色器切換的功能。


下面用一個例子來進行說明。在這個例子中,采用subroutine渲染了兩次茶壺。分別采用不同的光照模型。第一次用ADS(ambient,diffuse,specular)模型進行渲染,第二次只用diffuse模型渲染。一個subroutine全局變量用來選擇渲染算法。下面兩幅圖可以看出效果的對比。


左邊是ADS模型渲染效果,右邊是diffuse模型渲染效果。


下面介紹使用subroutines的步驟。

我們在vertex shader中進行subroutines的定義。

(1)首先是定義subroutine類型:

subroutine vec3 shadeModelType( vec4 position, vec3 normal);

上面的代碼定義了一個新的subroutine類型,其名字是shadeModelType。其語意和函數原型很類似。它定義了一個名字,一個參數列表和返回類型,參數名不是必須的。

(2)緊接著我們定義一個上述類型的uniform變量shadeModel:

subroutine uniform shadeModelType shadeModel;

這個變量充當了函數指針的作用,它在OpenGL應用程序中將會被賦值為兩個可能的函數之一。

(3)定義兩個函數,作為subroutine的一部分。

它們都有一個前綴是:

subroutine( shadeModelType )

其意味著函數和subroutine類型匹配。我們使用這個前綴定義了兩個函數:

  1. subroutine( shadeModelType )  
  2. vec3 phongModel( vec4 position, vec3 norm )  
  3. {  
  4.     vec3 s = normalize(vec3(Light.Position - position));  
  5.     vec3 v = normalize(-position.xyz);  
  6.     vec3 r = reflect( -s, norm );  
  7.     vec3 ambient = Light.La * Material.Ka;  
  8.     float sDotN = max( dot(s,norm), 0.0 );  
  9.     vec3 diffuse = Light.Ld * Material.Kd * sDotN;  
  10.     vec3 spec = vec3(0.0);  
  11.     if( sDotN > 0.0 )  
  12.         spec = Light.Ls * Material.Ks *  
  13.                pow( max( dot(r,v), 0.0 ), Material.Shininess );  
  14.   
  15.     return ambient + diffuse + spec;  
  16. }  
  17.   
  18. subroutine( shadeModelType )  
  19. vec3 diffuseOnly( vec4 position, vec3 norm )  
  20. {  
  21.     vec3 s = normalize( vec3(Light.Position - position) );  
  22.     return  
  23.         Light.Ld * Material.Kd * max( dot(s, norm), 0.0 );  
  24. }  
(4)函數調用

在vertex shader的main函數中,我們使用subroutine的uniform變量shadeModel來調用定義的兩個函數。

LightIntensity = shadeModel( eyePosition, eyeNorm );

這樣,根據uniform變量shadeModel的值,這個調用會被綁定到上述我們定義的兩個函數之一。

(5)給subroutine uniform變量賦值。

分兩步進行。

1、使用glGetSubroutineIndex函數查詢每個subroutine函數的索引。

  1. GLuint adsIndex = glGetSubroutineIndex( programHandle,  
  2.         GL_VERTEX_SHADER,  
  3.         "phongModel" );  
  4. GLuint diffuseIndex = glGetSubroutineIndex(programHandle,  
  5.         GL_VERTEX_SHADER,  
  6.         "diffuseOnly");  
第一個參數是程序的句柄。第二個是著色器。第三個是subroutine的名字。查詢到的索引存儲在兩個GLuint型的值中。
2、為了選擇合適的subroutine函數,我們需要給subroutine uniform變量shadeModel賦值。采用如下函數調用實現:

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);

這個函數可以一次設置多個uniform變量值。第一個參數指定著色階段。第二個是要設定的uniform變量的數量。這里只需要設置一個uniform變量的值。

如果要設置多個,那么第三個參數應該是個數組,通常數組中的第i個元素賦值給subroutine uniform變量中索引為i的那個。

這里只需要設置一個值,我們設置的是索引為0 的那么subroutine uniform變量。

注意:OpenGL中,uniform 變量的索引默認就是從0開始的。如果有多個變量需要設置,可以用 glGetSubroutineUniformLocation()查詢。 

接下來進行渲染就可以得出相應的效果了。


要進行另外一種效果的渲染只需調用下面函數:

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);

再進來渲染過程即可。在GLSL中,subroutine是這樣一種機制:它根據某個變量的值把一個函數調用和一個函數定義集合中的某一個函數定義綁定起來。在很多方面它和C語言中的函數指針類似。一個全局變量充當指針,用來調用函數。可以在OpenGL中設置這個變量的值,這樣可以把它和多個函數定義中的一個綁定起來。subroutine中的函數定義不一定要同名,但是必須要有同等數量和相同類型的參數以及相同的返回類型

Subroutines提供了在運行時刻不用切換著色器或者是重新編譯或者是使用if判斷就能選擇不同實現功能的方法。例如,一個著色器里面可以實現多種算法用來在場景中渲染不同的對象。當渲染場景的時候,我們可以通過改變subroutines的全局變量的值來選擇合適的渲染算法而不是去通過切換著色器或者是使用條件判斷來實現。

注意:由于性能在著色器中越來越重要,所以避免條件判斷或著色器切換是很有必要的。有了subroutines,我們就能夠在不增加計算負載的情況下實現條件判斷和著色器切換的功能。


下面用一個例子來進行說明。在這個例子中,采用subroutine渲染了兩次茶壺。分別采用不同的光照模型。第一次用ADS(ambient,diffuse,specular)模型進行渲染,第二次只用diffuse模型渲染。一個subroutine全局變量用來選擇渲染算法。下面兩幅圖可以看出效果的對比。


左邊是ADS模型渲染效果,右邊是diffuse模型渲染效果。


下面介紹使用subroutines的步驟。

我們在vertex shader中進行subroutines的定義。

(1)首先是定義subroutine類型:

subroutine vec3 shadeModelType( vec4 position, vec3 normal);

上面的代碼定義了一個新的subroutine類型,其名字是shadeModelType。其語意和函數原型很類似。它定義了一個名字,一個參數列表和返回類型,參數名不是必須的。

(2)緊接著我們定義一個上述類型的uniform變量shadeModel:

subroutine uniform shadeModelType shadeModel;

這個變量充當了函數指針的作用,它在OpenGL應用程序中將會被賦值為兩個可能的函數之一。

(3)定義兩個函數,作為subroutine的一部分。

它們都有一個前綴是:

subroutine( shadeModelType )

其意味著函數和subroutine類型匹配。我們使用這個前綴定義了兩個函數:

  1. subroutine( shadeModelType )  
  2. vec3 phongModel( vec4 position, vec3 norm )  
  3. {  
  4.     vec3 s = normalize(vec3(Light.Position - position));  
  5.     vec3 v = normalize(-position.xyz);  
  6.     vec3 r = reflect( -s, norm );  
  7.     vec3 ambient = Light.La * Material.Ka;  
  8.     float sDotN = max( dot(s,norm), 0.0 );  
  9.     vec3 diffuse = Light.Ld * Material.Kd * sDotN;  
  10.     vec3 spec = vec3(0.0);  
  11.     if( sDotN > 0.0 )  
  12.         spec = Light.Ls * Material.Ks *  
  13.                pow( max( dot(r,v), 0.0 ), Material.Shininess );  
  14.   
  15.     return ambient + diffuse + spec;  
  16. }  
  17.   
  18. subroutine( shadeModelType )  
  19. vec3 diffuseOnly( vec4 position, vec3 norm )  
  20. {  
  21.     vec3 s = normalize( vec3(Light.Position - position) );  
  22.     return  
  23.         Light.Ld * Material.Kd * max( dot(s, norm), 0.0 );  
  24. }  
(4)函數調用

在vertex shader的main函數中,我們使用subroutine的uniform變量shadeModel來調用定義的兩個函數。

LightIntensity = shadeModel( eyePosition, eyeNorm );

這樣,根據uniform變量shadeModel的值,這個調用會被綁定到上述我們定義的兩個函數之一。

(5)給subroutine uniform變量賦值。

分兩步進行。

1、使用glGetSubroutineIndex函數查詢每個subroutine函數的索引。

  1. GLuint adsIndex = glGetSubroutineIndex( programHandle,  
  2.         GL_VERTEX_SHADER,  
  3.         "phongModel" );  
  4. GLuint diffuseIndex = glGetSubroutineIndex(programHandle,  
  5.         GL_VERTEX_SHADER,  
  6.         "diffuseOnly");  
第一個參數是程序的句柄。第二個是著色器。第三個是subroutine的名字。查詢到的索引存儲在兩個GLuint型的值中。
2、為了選擇合適的subroutine函數,我們需要給subroutine uniform變量shadeModel賦值。采用如下函數調用實現:

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);

這個函數可以一次設置多個uniform變量值。第一個參數指定著色階段。第二個是要設定的uniform變量的數量。這里只需要設置一個uniform變量的值。

如果要設置多個,那么第三個參數應該是個數組,通常數組中的第i個元素賦值給subroutine uniform變量中索引為i的那個。

這里只需要設置一個值,我們設置的是索引為0 的那么subroutine uniform變量。

注意:OpenGL中,uniform 變量的索引默認就是從0開始的。如果有多個變量需要設置,可以用 glGetSubroutineUniformLocation()查詢。 

接下來進行渲染就可以得出相應的效果了。


要進行另外一種效果的渲染只需調用下面函數:

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);

再進來渲染過程即可。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多