动态镶嵌LOD表面裂纹伪影

时间:2014-11-06 13:46:27

标签: opengl opengl-4 tessellation

我使用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;
  */
}

}

我怀疑边缘水平的插值可能是错误的(参见水平方法),或者这个评估不应该在屏幕空间中完成?

另一个重要的注意事项是,如果表面与观察者完全正交,则没有裂缝。当表面旋转时,它们开始出现。 enter image description here

0 个答案:

没有答案