Hi.
I’ve been doing some work regarding tessellation techniques for smoothing meshes. Plain PN Triangle was pretty easy to implement but I have quite a problem with PN-AEN Triangles. I’ve searched over the net looking for implementation in GLSL but I’ve found nothing. I hope you will help me understand if this can or cannot be done in GLSL.
I wont describe all PN-AEN T. but explain what doesn’t seems to work…
First…is it possible for TCS to pass further into pipeline only 3 vertices insteed of 9 defined in patch? I’m aware of “layout(vertices = 3) out” but from what I can tell, when I set TES to triangles it consumes all 9 vertices from patch and makes 3 triangles instead of wanting 1. I can check this by using gl_PrimitiveID in TES. I have indices like this for eg.:
1,2,3, - those I want to see as triangle
4,5,6,7,8,9, - those are control points only for calculations (end of first patch)
10,11,12, - triangle
13,14,15,16,17,18 - calculations (end of second patch)
I can see triangle (10,11,12,) only when (gl_PrimitiveID <= 3) - so 4,5,6 and 7,8,9 also make triangles (I can sometimes see them as artifacts - flying on screen)
Second… does gl_InvocationID have the same order in patches as they were send to memory? From above where second patch had verts 10,11,12,13,14,15,16,17,18 is it right to assume that the first vert in this patch: 10 will have gl_Invocation: 1, next 11 - 2, 12 - 3, and so on? If not is there other way around to make them like this? I really need this so I’ve tested it and it seems that sometimes it is not consistent - for 108 indices (12 triangles, rest are control points) it fails for 2 triangles. Like in the image.
[ATTACH=CONFIG]218[/ATTACH]
I think that code is unnecessary but if someone want to look at it here it is:
TCS
#version 400
struct CP
{
vec3 Pos[3];
vec3 Nor[2];
};
//------------------------------
layout(vertices = 3) out;
in vec3 vPosition[];
in vec3 vNormal[];
out CP cp[];
patch out vec3 center;
uniform float TessLevelInner;
uniform float TessLevelOuter;
#define ID gl_InvocationID
void main()
{
// for vert ID=0 use control points 3,4 (1 ID - 5,6; 2 ID - 7,8)
int IDnext = (ID + 1) % 3;
int IDadd = (ID * 2) + 3;
int IDaddNext = IDadd + 1;
vec3 P1i = vPosition[ID];
vec3 P2i = vPosition[IDnext];
vec3 N1i = normalize(vNormal[ID]);
vec3 N2i = normalize(vNormal[IDnext]);
vec3 P1o = vPosition[IDadd];
vec3 P2o = vPosition[IDaddNext];
vec3 N1o = normalize(vNormal[IDadd]);
vec3 N2o = normalize(vNormal[IDaddNext]);
vec3 posIns;
vec3 posOut;
cp[ID].Pos[0] = P1i;
posIns = (2 * P1i + P2i - dot(P2i - P1i, N1i) * N1i) / 3;
posOut = (2 * P1o + P2o - dot(P2o - P1o, N1o) * N1o) / 3;
cp[ID].Pos[1] = (posIns + posOut) / 2;
posIns = (2 * P2i + P1i - dot(P1i - P2i, N2i) * N2i) / 3;
posOut = (2 * P2o + P1o - dot(P1o - P2o, N2o) * N2o) / 3;
cp[ID].Pos[2] = (posIns + posOut) / 2;
float r12 = 2 * dot(P2i - P1i, N1i + N2i) / dot(P2i - P1i, P2i - P1i);
r12+= 2 * dot(P2o - P1o, N1o + N2o) / dot(P2o - P1o, P2o - P1o);
r12/=2;
cp[ID].Nor[0] = N1i;
cp[ID].Nor[1] = N1i + N2i - r12 * (P2i - P1i);
gl_TessLevelOuter[ID] = TessLevelOuter;
barrier();
if (ID == 0)
{
vec3 E = (cp[0].Pos[1] + cp[0].Pos[2] +
cp[1].Pos[1] + cp[1].Pos[2] +
cp[2].Pos[1] + cp[2].Pos[2]) / 6;
vec3 V = (vPosition[0] + vPosition[1] + vPosition[2]) / 3;
center = E + (E - V) / 2;
gl_TessLevelInner[0] = TessLevelInner;
}
}
TES
#version 400
struct CP
{
vec3 Pos[3];
vec3 Nor[2];
};
layout(triangles, equal_spacing, ccw) in;
in CP cp[];
patch in vec3 center;
out vec3 tePosition;
out vec3 tePatchDistance;
uniform mat4 Projection;
uniform mat4 Modelview;
void main()
{
if(gl_PrimitiveID % 3 == 0)
{
float u = gl_TessCoord.x;
float v = gl_TessCoord.y;
float w = gl_TessCoord.z;
vec3 pos = cp[0].Pos[0]*w*w*w + cp[1].Pos[0]*u*u*u + cp[2].Pos[0]*v*v*v +
cp[0].Pos[1]*w*w*u*3 + cp[0].Pos[2]*w*u*u*3 + cp[1].Pos[1]*u*u*v*3 +
cp[1].Pos[2]*u*v*v*3 + cp[2].Pos[1]*v*v*w*3 + cp[2].Pos[2]*v*w*w*3 +
center * u*v*w*6;
tePatchDistance = gl_TessCoord;
tePosition = pos;
gl_Position = Projection * Modelview * vec4(tePosition, 1);
}
else
gl_Position = vec4(0);
}
by if(gl_PrimitiveID % 3 == 0) I can prevent (control points) triangles from showing.