Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: PN-AEN Triangles GLSL

Threaded View

  1. #1
    Junior Member Newbie
    Join Date
    Jun 2012
    Posts
    5

    PN-AEN Triangles GLSL

    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.
    Click image for larger version. 

Name:	Untitled.jpg 
Views:	305 
Size:	45.8 KB 
ID:	794

    I think that code is unnecessary but if someone want to look at it here it is:
    TCS
    Code :
    #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
    Code :
    #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.
    Last edited by blackbee; 06-27-2012 at 12:14 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •