我使用OpenGL 4.0及其Tessellation阶段来动态细分几何体。我的输入几何体是索引三角形的平面网格。在TCS中,我根据对象的屏幕空间距离定义细分的级别。实际上,这部分代码基于this文章,该文章使用四边形,而我使用三角形。
结果,如下图所示,显示原始三角形边缘的裂缝(来自VBO)。我确定问题出现在TCS代码中,因为如果我删除动态tess级别计算,问题是走了。
这是我的TCS代码:
//MVP is model view projection matrix
vec4 project(vec4 vertex){
vec4 result = MVP * vertex;
result /= result.w;
return result;
}
vec2 screen_space(vec4 vertex){
///The clamp must be in range of the vertex NDS min/max value
return (clamp(vertex.xy, -1.5, 1.5)+1) * (screen_size*0.5);
}
float level(vec2 v0, vec2 v1){
return clamp(distance(v0, v1)/lod_factor, 1, TESS_LEVEL);
}
bool offscreen(vec4 vertex){
if(vertex.z < -0.5){
return true;
}
return any(
lessThan(vertex.xy, vec2(-1.3)) ||
greaterThan(vertex.xy, vec2(1.3))
);
}
void main()
{
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
if ( gl_InvocationID == 0 ) {
vec4 v0 = project(gl_in[0].gl_Position);
vec4 v1 = project(gl_in[1].gl_Position);
vec4 v2 = project(gl_in[2].gl_Position);
if(all(bvec3(
offscreen(v0),
offscreen(v1),
offscreen(v2)
))){
gl_TessLevelInner[0] = 0;
gl_TessLevelOuter[0] = 0;
gl_TessLevelOuter[1] = 0;
gl_TessLevelOuter[2] = 0;
}else{
vec2 ss0 = screen_space(v0);
vec2 ss1 = screen_space(v1);
vec2 ss2 = screen_space(v2);
float e0 = level(ss0, ss1);
float e1 = level(ss1, ss2);
float e2 = level(ss2, ss0);
gl_TessLevelInner[0] = mix(e0,e1,0.5);
gl_TessLevelOuter[0] = e0;
gl_TessLevelOuter[1] = e1;
gl_TessLevelOuter[2] = e2;
}
/*
//if I set just this ,it works ok.
gl_TessLevelInner[0] = TESS_LEVEL;
gl_TessLevelOuter[0] = TESS_LEVEL;
gl_TessLevelOuter[1] = TESS_LEVEL;
gl_TessLevelOuter[2] = TESS_LEVEL;
*/
}
}
我怀疑边缘水平的插值可能是错误的(参见水平方法),或者这个评估不应该在屏幕空间中完成?
另一个重要的注意事项是,如果表面与观察者完全正交,则没有裂缝。当表面旋转时,它们开始出现。