问题描述
我使用 openGL 中的细分控制/评估着色器为未来的地形渲染实现了一个简单的基于距离的 LOD。令人惊讶的是,我的输出中仍然出现裂缝(T 型连接)... 着色器代码是
uniform mat4 pvmM;
uniform vec4 u_camerapos;
#ifdef TESSELATION_CONTROL_SHADER
layout(vertices = 4) out;
unsigned int dist(vec3 p1,vec3 p2,vec3 p3)
{
float d=distance((p1+p2)/2.0,p3); // precise float d=(...)
if (d<1.5) return 64;
if (d<2.5) return 32;
if (d<3) return 16;
if (d<4) return 8;
if (d<5) return 4;
if (d<6) return 2;
return 1;
}
void main() {
if (gl_InvocationID == 0){
gl_TessLevelOuter[0] = dist( gl_in[3].gl_Position.xyz,gl_in[0].gl_Position.xyz,u_camerapos.xyz);
gl_TessLevelOuter[1] = dist( gl_in[0].gl_Position.xyz,gl_in[1].gl_Position.xyz,u_camerapos.xyz);
gl_TessLevelOuter[2] = dist( gl_in[1].gl_Position.xyz,gl_in[2].gl_Position.xyz,u_camerapos.xyz);
gl_TessLevelOuter[3] = dist( gl_in[2].gl_Position.xyz,gl_in[3].gl_Position.xyz,u_camerapos.xyz);
float mean=floor((gl_TessLevelOuter[0]+gl_TessLevelOuter[1]+gl_TessLevelOuter[2]+gl_TessLevelOuter[3])/4.0);
gl_TessLevelInner[0] = int(mean);
gl_TessLevelInner[1] = int(mean);
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
#endif
#ifdef TESSELATION_EVALUATION_SHADER
void main() {
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 = pvmM*mix(p1,p2,gl_TessCoord.y);
}
#endif
使用蟒蛇: 使用
生成顶点和索引blocksz=8
vertices=np.array([(x,z) for z in range(blocksz) for x in range(blocksz)],dtype='f4')
vertices=vertices-np.array([blocksz/2,blocksz/2])
faces= np.array([(x+z*blocksz,x+1+z*blocksz,x+(z+1)*blocksz,x+1+(z+1)*blocksz ) for z in range(blocksz-1) for x in range(blocksz-1) ],dtype='i4')
并使用
绘制glDrawElements(GL_PATCHES,count,GL_UNSIGNED_SHORT,None)
在下图中,
你可以看到结果。一些 T 型接头出现在 x 轴(左右,例如第一列和最后一列)上,但从未出现在 z 轴(顶部引导)上。虚拟相机用红点表示,其位置以uniform传递。
其余的都按预期工作。 知道我误解了什么吗?
解决方法
好的,发现错误。 生成索引数组(面)时,我使用了错误的绕组(与 GL_QUAD_STRIP 的绕组相同)。正确的面数组应该是:
faces= np.array([(x+z*blocksz,x+1+z*blocksz,x+1+(z+1)*blocksz,x+(z+1)*blocksz ) for z in range(blocksz-1) for x in range(blocksz-1) ],dtype='i4')
然后,在 tess 评估着色器中(注意翻转点 2 和 3
vec4 p1 = mix(gl_in[0].gl_Position,gl_in[1].gl_Position,gl_TessCoord.x);
vec4 p2 = mix(gl_in[3].gl_Position,gl_in[2].gl_Position,gl_TessCoord.x);