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

分享

GLSL

 LVADDIE 2015-08-04

在GLSL中,subroutine是這樣一種機(jī)制:它根據(jù)某個(gè)變量的值把一個(gè)函數(shù)調(diào)用和一個(gè)函數(shù)定義集合中的某一個(gè)函數(shù)定義綁定起來。在很多方面它和C語言中的函數(shù)指針類似。一個(gè)全局變量充當(dāng)指針,用來調(diào)用函數(shù)。可以在OpenGL中設(shè)置這個(gè)變量的值,這樣可以把它和多個(gè)函數(shù)定義中的一個(gè)綁定起來。subroutine中的函數(shù)定義不一定要同名,但是必須要有同等數(shù)量和相同類型的參數(shù)以及相同的返回類型

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

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


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


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


下面介紹使用subroutines的步驟。

我們?cè)趘ertex shader中進(jìn)行subroutines的定義。

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

subroutine vec3 shadeModelType( vec4 position, vec3 normal);

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

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

subroutine uniform shadeModelType shadeModel;

這個(gè)變量充當(dāng)了函數(shù)指針的作用,它在OpenGL應(yīng)用程序中將會(huì)被賦值為兩個(gè)可能的函數(shù)之一。

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

它們都有一個(gè)前綴是:

subroutine( shadeModelType )

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

  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)函數(shù)調(diào)用

在vertex shader的main函數(shù)中,我們使用subroutine的uniform變量shadeModel來調(diào)用定義的兩個(gè)函數(shù)。

LightIntensity = shadeModel( eyePosition, eyeNorm );

這樣,根據(jù)uniform變量shadeModel的值,這個(gè)調(diào)用會(huì)被綁定到上述我們定義的兩個(gè)函數(shù)之一。

(5)給subroutine uniform變量賦值。

分兩步進(jìn)行。

1、使用glGetSubroutineIndex函數(shù)查詢每個(gè)subroutine函數(shù)的索引。

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

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);

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

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

這里只需要設(shè)置一個(gè)值,我們?cè)O(shè)置的是索引為0 的那么subroutine uniform變量。

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

接下來進(jìn)行渲染就可以得出相應(yīng)的效果了。


要進(jìn)行另外一種效果的渲染只需調(diào)用下面函數(shù):

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);

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

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

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


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


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


下面介紹使用subroutines的步驟。

我們?cè)趘ertex shader中進(jìn)行subroutines的定義。

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

subroutine vec3 shadeModelType( vec4 position, vec3 normal);

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

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

subroutine uniform shadeModelType shadeModel;

這個(gè)變量充當(dāng)了函數(shù)指針的作用,它在OpenGL應(yīng)用程序中將會(huì)被賦值為兩個(gè)可能的函數(shù)之一。

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

它們都有一個(gè)前綴是:

subroutine( shadeModelType )

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

  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)函數(shù)調(diào)用

在vertex shader的main函數(shù)中,我們使用subroutine的uniform變量shadeModel來調(diào)用定義的兩個(gè)函數(shù)。

LightIntensity = shadeModel( eyePosition, eyeNorm );

這樣,根據(jù)uniform變量shadeModel的值,這個(gè)調(diào)用會(huì)被綁定到上述我們定義的兩個(gè)函數(shù)之一。

(5)給subroutine uniform變量賦值。

分兩步進(jìn)行。

1、使用glGetSubroutineIndex函數(shù)查詢每個(gè)subroutine函數(shù)的索引。

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

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);

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

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

這里只需要設(shè)置一個(gè)值,我們?cè)O(shè)置的是索引為0 的那么subroutine uniform變量。

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

接下來進(jìn)行渲染就可以得出相應(yīng)的效果了。


要進(jìn)行另外一種效果的渲染只需調(diào)用下面函數(shù):

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);

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

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

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


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


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


下面介紹使用subroutines的步驟。

我們?cè)趘ertex shader中進(jìn)行subroutines的定義。

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

subroutine vec3 shadeModelType( vec4 position, vec3 normal);

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

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

subroutine uniform shadeModelType shadeModel;

這個(gè)變量充當(dāng)了函數(shù)指針的作用,它在OpenGL應(yīng)用程序中將會(huì)被賦值為兩個(gè)可能的函數(shù)之一。

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

它們都有一個(gè)前綴是:

subroutine( shadeModelType )

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

  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)函數(shù)調(diào)用

在vertex shader的main函數(shù)中,我們使用subroutine的uniform變量shadeModel來調(diào)用定義的兩個(gè)函數(shù)。

LightIntensity = shadeModel( eyePosition, eyeNorm );

這樣,根據(jù)uniform變量shadeModel的值,這個(gè)調(diào)用會(huì)被綁定到上述我們定義的兩個(gè)函數(shù)之一。

(5)給subroutine uniform變量賦值。

分兩步進(jìn)行。

1、使用glGetSubroutineIndex函數(shù)查詢每個(gè)subroutine函數(shù)的索引。

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

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &adsIndex);

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

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

這里只需要設(shè)置一個(gè)值,我們?cè)O(shè)置的是索引為0 的那么subroutine uniform變量。

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

接下來進(jìn)行渲染就可以得出相應(yīng)的效果了。


要進(jìn)行另外一種效果的渲染只需調(diào)用下面函數(shù):

glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &diffuseIndex);

再進(jìn)來渲染過程即可。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多