本篇在講什么 OpenGL藍(lán)寶書第八章學(xué)習(xí)筆記之曲面細(xì)分 本篇適合什么 適合初學(xué)OpenGL的小白 本篇需要什么 對(duì)C++語法有簡(jiǎn)單認(rèn)知 對(duì)OpenGL有簡(jiǎn)單認(rèn)知 最好是有OpenGL超級(jí)寶典藍(lán)寶書 依賴Visual Studio編輯器 本篇的特色 具有全流程的圖文教學(xué) 重實(shí)踐,輕理論,快速上手 提供全流程的源碼內(nèi)容 |
![]() ★提高閱讀體驗(yàn)★ ?? ? 一級(jí)標(biāo)題 ???? ? 二級(jí)標(biāo)題 ???? ? 三級(jí)標(biāo)題 ???? ? 四級(jí)標(biāo)題 ?? |
? 曲面細(xì)分
在第三章管線的學(xué)習(xí)當(dāng)中我們已經(jīng)對(duì)細(xì)分曲面階段有了一定的了解,這一章節(jié)我們?cè)趯?duì)其進(jìn)行一遍系統(tǒng)一點(diǎn)的學(xué)習(xí)
細(xì)分曲面位于頂點(diǎn)著色器和幾何著色器之間,分為了三個(gè)階段分別是曲面細(xì)分控制著色器(TCS)、固定功能型曲面細(xì)分引擎以及曲面細(xì)分評(píng)估著色器(TES)
曲面細(xì)分控制著色器負(fù)責(zé)生成3項(xiàng)數(shù)據(jù)
- 生成單個(gè)面片的內(nèi)外曲面細(xì)分因子
- 生成單個(gè)輸出控制點(diǎn)的位置和其他屬性
- 生成單個(gè)面片的用戶定義的變量
曲面細(xì)分引擎將確定大基元如何拆分成小基元
曲面細(xì)分評(píng)估著色器接受上二者傳遞的數(shù)據(jù)、處理后輸出至基元裝配
? 曲面細(xì)分基元模式
曲面細(xì)分模式用于確定怎么拆分基元的,拆分的方式有三種分別是四邊形、三角形或等值線,下面我們挨個(gè)看個(gè)例子
注:
以下所有示例均摘自O(shè)penGL超級(jí)寶典配套資源代碼tessmodes
,可自行查看
注:
以下示例均設(shè)置默認(rèn)頂點(diǎn)和片元著色器,文中不在累述
? 使用四邊形拆分基元
下方是一個(gè)簡(jiǎn)單的使用四邊形拆分基元的曲面細(xì)分控制著色器和曲面細(xì)分評(píng)估著色器的例子
- 曲面細(xì)分控制著色器
# version 420 core
layout (vertices = 4) out;
void main(void)
{
if(gl_InvocationID == 0)
{
gl_TessLevelInner[0] = 9.0;
gl_TessLevelInner[1] = 7.0;
gl_TessLevelOuter[0] = 3.0;
gl_TessLevelOuter[1] = 5.0;
gl_TessLevelOuter[2] = 3.0;
gl_TessLevelOuter[3] = 5.0;
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
- 曲面細(xì)分控制著色器
# version 420 core
layout (quads) in;
void main(void)
{
vec4 p1 = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);
vec4 p2 = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, gl_TessCoord.x);
gl_Position = mix(p1, p2, gl_TessCoord.y);
}
上述著色器運(yùn)行后的效果如下圖所示
我們簡(jiǎn)單介紹一下著色器代碼中比較重要的部分
要點(diǎn)1:
gl_TessLevelInner
用來控制內(nèi)部細(xì)分的等級(jí)
要點(diǎn)2:gl_TessLevelOuter
用來控制外部細(xì)分的等級(jí)
要點(diǎn)3:layout (quads) in
四邊形模式的特殊限定符
我們可以很明顯的看出來外部邊被分成了5-3-5-3,對(duì)應(yīng)著我們上部分gl_TessLevelOuter
設(shè)置的細(xì)分等級(jí)
我們也可以很明顯的看出來內(nèi)部被分成了9*7的區(qū)域,對(duì)應(yīng)著我們上部分gl_TessLevelInner
設(shè)置的細(xì)分等級(jí)
? 使用三角形的曲面細(xì)分
同理我們先看一下著色器代碼和最終的顯示效果
- 曲面細(xì)分控制著色器
# version 420 core
layout (vertices = 3) out;
void main(void)
{
if (gl_InvocationID == 0)
{
gl_TessLevelInner[0] = 5.0;
gl_TessLevelOuter[0] = 8.0;
gl_TessLevelOuter[1] = 8.0;
gl_TessLevelOuter[2] = 8.0;
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
- 曲面細(xì)分控制著色器
# version 420 core
layout (triangles) in;
void main(void)
{
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +
(gl_TessCoord.y * gl_in[1].gl_Position) +
(gl_TessCoord.z * gl_in[2].gl_Position);
}
上述著色器運(yùn)行后的效果如下圖所示
我們簡(jiǎn)單介紹一下著色器代碼中比較重要的部分
要點(diǎn)1:
gl_TessLevelInner
數(shù)組的第一個(gè)元素,該級(jí)別應(yīng)用于曲面細(xì)分三角形的整個(gè)內(nèi)部區(qū)域
要點(diǎn)2:gl_TessLevelOuter
數(shù)組的前三個(gè)元素用于設(shè)置三角形三條邊的曲面細(xì)分因子
要點(diǎn)3:layout (triangles) in
三角形模式的特殊限定符
我們可以很明顯的看出來三條邊都被分成了8分,對(duì)應(yīng)著我們上部分gl_TessLevelOuter
設(shè)置的細(xì)分等級(jí)
下圖依次展示了gl_TessLevelInner
內(nèi)部細(xì)分等級(jí)2-5的效果,細(xì)分等級(jí)越大,內(nèi)部細(xì)分的越復(fù)雜
? 使用等值線的曲面細(xì)分
同理我們先看一下著色器代碼和最終的顯示效果
- 曲面細(xì)分控制著色器
# version 420 core
layout (vertices = 4) out;
void main(void)
{
if (gl_InvocationID == 0)
{
gl_TessLevelOuter[0] = 5.0;
gl_TessLevelOuter[1] = 5.0;
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
- 曲面細(xì)分控制著色器
# version 420 core
layout (isolines) in;
void main(void)
{
float r = (gl_TessCoord.y + gl_TessCoord.x / gl_TessLevelOuter[0]);
float t = gl_TessCoord.x * 2.0 * 3.14159;
gl_Position = vec4(sin(t) * r, cos(t) * r, 0.5, 1.0);
}
上述著色器運(yùn)行后的效果如下圖所示
我們簡(jiǎn)單介紹一下著色器代碼中比較重要的部分
要點(diǎn)1:
gl_TessLevelInner
不在使用
要點(diǎn)2:gl_TessLevelOuter
的前兩個(gè)分量中的兩個(gè)外部曲面細(xì)分因子分別用于確定線條數(shù)量以及每條線上的線段數(shù)量
要點(diǎn)3:layout (isolines) in
等值線模式的特殊限定符
? 曲面細(xì)分點(diǎn)模式
使用point_model
布局限定符,可將生成的頂點(diǎn)按照獨(dú)立點(diǎn)進(jìn)行渲染
- 曲面細(xì)分控制著色器
# version 420 core
layout (triangles, point_mode) in;
void main(void)
{
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +
(gl_TessCoord.y * gl_in[1].gl_Position) +
(gl_TessCoord.z * gl_in[2].gl_Position);
}
? 曲面細(xì)分子分段模式
在一定情況下我們可以調(diào)整對(duì)已生成基元的邊緣的分段方式,下面介紹一下幾種分段方式的效果和特定布局限定符
? 等間距模式
使用限定符equal_spacing
,在著色器中的寫法如下,效果就是邊緣等分,如下圖
layout (triangles, equal_spacing) in;
? 分段長(zhǎng)度模式
使用限定符fractional_even_spacing
或fractional_odd_spacing
,在著色器中的寫法如下,效果就是根據(jù)情況對(duì)邊緣進(jìn)行不等分,如下圖
layout (triangles, fractional_even_spacing) in;
layout (triangles, fractional_odd_spacing) in;
? 控制環(huán)繞順序
使用以下布局限定符指定順時(shí)針環(huán)繞順序
layout (cw) in;
要指定曲面細(xì)分引擎所生成的基元環(huán)繞順序是逆時(shí)針,需要添加此限定符
layout (ccw) in;
? 數(shù)據(jù)在曲面細(xì)分著色器之間的傳遞
曲面細(xì)分控制著色器的輸入和輸出都用數(shù)組表示,輸入數(shù)組的尺寸根據(jù)每個(gè)面片中的控制點(diǎn)數(shù)量確定,通過調(diào)用以下函數(shù)設(shè)置
glPatchParameteri(GL_PATCH_VERTICES,n);
注:
表示每個(gè)面片的頂點(diǎn)數(shù)量。默認(rèn)情況下,每個(gè)面片的頂點(diǎn)數(shù)量為3
曲面細(xì)分控制著色器的輸出也是數(shù)組,但其尺寸通過著色器前方的頂點(diǎn)輸出布局限定符設(shè)置
某些簡(jiǎn)單的渲染流程可以不包含
曲面細(xì)分控制著色器,當(dāng)不存在曲面細(xì)分控制著色器時(shí),所有內(nèi)外部曲面細(xì)分等級(jí)
的默認(rèn)值為1.0
??赏ㄟ^調(diào)用glPatchParameterfv()
更改此設(shè)置,其原型為文章來源:http://www.zghlxwxcb.cn/news/detail-471612.html
void glPatchParameterfv (GLenum pnameconst GLfloat * values);
? 推送
- Github
https://github.com/KingSun5
? 結(jié)語
若是覺得博主的文章寫的不錯(cuò),不妨關(guān)注一下博主,點(diǎn)贊一下博文,另博主能力有限,若文中有出現(xiàn)什么錯(cuò)誤的地方,歡迎各位評(píng)論指摘。文章來源地址http://www.zghlxwxcb.cn/news/detail-471612.html
到了這里,關(guān)于OpenGL超級(jí)寶典第八章學(xué)習(xí)筆記:基元處理之曲面細(xì)分的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!