目录
文章目录
OpenGL的Tessellation学习
在官方文档中搜索了TCS和TES的配置方法
链接:Tessellation Evaluation Shader - OpenGL Wiki (khronos.org)
Tessellation Control Shader - OpenGL Wiki (khronos.org)
总结如下:
1. Tessellation介绍
硬件曲面细分被设置在顶点染色器和几何染色器之间。
曲面细分包括三个部分:
- 细分控制器(可编程)
- 细分生成器(固定)
- 细分评估器(可编程)
细分的具体流程是:
- VS将patch发送给TCS
- TCS对patch中的CP(control point)控制点进行分析,根据某种算法得到TL(tessellation level)细分级别;也可以增加或减少CP。
- TCS将TL发送给TPG进行细分,将patch发送给TES
- TPG根据TCS发来的TL和TES发来的type(一般是点或三角形)进行细分,然后得到细分后的新点的topotaxy拓扑关系
- TPG将topotaxy发送给TES,TES根据某种算法将新生成的点融入到原始patch中
- TES按vertex为单位发送给下一级
2. OpenGL示例
使用OpenGL编写了曲面细分例子,可以深入理解曲面细分每个模块的功能:
Github大佬的代码,拿来学习一下。参考代码原地址
2.1 Tessellation Control Shader
基于OpenGL创建一个简单的TCS:
#version 460 core //OpenGL版本4.60 layout(vertices = 4) out; //表示TCS输出的patch size为4 void main(void) { if(gl_InvocationID == 0) { gl_TessLevelInner[0] = 6; //TCS的必要任务 可编程的计算TL gl_TessLevelOuter[0] = 2; gl_TessLevelOuter[1] = 6; gl_TessLevelOuter[2] = 6; } gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; //TCS有权力对patch内的Points操作 }
2.2 Tessellation Evaluation Shader
基于OpenGL创建一个简单的TES:
#version 460 core //OpenGL版本为4.60 layout (triangles ,equal_spacing) in; //配置输入patch为三角形,输出也为三角形,抽象细分模式为等距细分 uniform mat4 u_model_matrix; //模型矩阵 uniform mat4 u_view_matrix; //视图矩阵 uniform mat4 u_projection_matrix; //投影矩阵 void main(void) { //using the barycentric coordinates from TPG vec4 pos = gl_in[0].gl_Position * gl_TessCoord.x + gl_in[1].gl_Position * gl_TessCoord.y + gl_in[2].gl_Position * gl_TessCoord.z ; gl_Position = u_projection_matrix * u_view_matrix * u_model_matrix * pos; }
可配置部分:
layout(param1, param2, ...) in;
补丁类型:
isolines
:输入patch
是平行线的矩形块,输出是一系列行
triangles
:输入是三角形,输出是一系列三角形
quads
:输入是四边形,输出是一系列三角形必选
细分间距:
equal_spacing
:生成图块中的顶点之间的距离相等。
fractional_even_spacing:TL
为偶数时,会生成偶数个片段,某两个片段间添加顶点生成奇数个片段。
fractional_odd_spacing
:TL为奇数时,会生成奇数个片段,某两个片段间添加顶点生成偶数个片段。缺省是默认
equal_spacing
。基元排序:
cw
:顺时针排序
ccw
:逆时针排序缺省是默认
ccw
。强制修改输出图元类型:
point_mode
3. 演示
3.1 TCS的TL演示
gl_TessLevelInner[0] = 6;
gl_TessLevelOuter[0] = 2;
gl_TessLevelOuter[1] = 3;
gl_TessLevelOuter[2] = 4;
gl_TessLevelInner[0] = 5;
gl_TessLevelOuter[0] = 4;
gl_TessLevelOuter[1] = 3;
gl_TessLevelOuter[2] = 2;
3.2 TES的layout配置
layout (triangles ,equal_spacing) in; //TES设置
//输入一个三角形,输出等距细分的三角形
/TCS设置
gl_TessLevelInner[0] = 6; //
gl_TessLevelOuter[0] = 6; //边0细分为6节
gl_TessLevelOuter[1] = 6; //边1细分为6节
gl_TessLevelOuter[2] = 6; //边2细分为6节
layout (triangles , fractional_odd_spacing) in;
//若TL为偶数,添加顶点造成奇数的效果
//如图,TL设置为6,6,6,6
//增加顶点形成了7,7,7,7的细分效果
layout (triangles ,equal_spacing ,point_mode) in;
//输入为三角形。输出为点