PDA

View Full Version : So where's an example tessellation shader?



JoshKlint
04-09-2011, 08:58 PM
I've got my engine set up to handle tessellation shaders. I can't seem to find a GLSL example anywhere. Where can I find one?

JoshKlint
04-10-2011, 01:30 AM
I can't find the example I used now, but when I got it, I got it pretty quickly:
http://leadwerks.com/werkspace/uploads/1299536611/gallery_1_1_191468.png

YarUnderoaker
04-10-2011, 05:12 AM
No time has come for tessellation, Carmack still use OpenGL 2.1 xD

James A.
04-10-2011, 04:38 PM
Here are some explanations/examples i have found.

http://prideout.net/blog/?p=48
http://codeflow.org/entries/2010/nov/07/opengl-4-tessellation/

YarUnderoaker
04-11-2011, 06:25 AM
Shaders from TessMark :whistle:

/////////////////////////////// Vertex shader
#version 400 core
in vec4 In_Position;
in vec4 In_Normal;
in vec4 In_UV;
uniform mat4 WorldMatrix;
uniform mat3 NormalMatrix;
uniform float UVScale;
out vec4 Color_VS_CS;
out vec4 Normal_VS_CS;
out vec4 UVMap_VS_CS;
void main()
{
gl_Position = WorldMatrix * In_Position;
UVMap_VS_CS = In_UV * UVScale;
Normal_VS_CS = WorldMatrix * vec4(In_Normal.xyz, 0.0);
Color_VS_CS = Normal_VS_CS;
Color_VS_CS.w = 1.0;
}

//////////////////////////////// Fragment shader

#version 400 core
out vec4 Out_Color;
in vec4 lightDir1;
in vec4 lightDir2;
in vec4 eyeVec;
in vec2 texcoord;
uniform sampler2D diffuseMap;
uniform sampler2D bumpMap;
uniform sampler2D normalMap;
uniform vec4 light0_diffuse;
uniform vec4 light1_diffuse;
uniform vec4 mat_specular;
void main()
{
vec3 diffuseColor = texture(diffuseMap, texcoord).xyz;
vec3 bump = texture(bumpMap, texcoord).xyz;
vec3 bN = normalize(texture(normalMap, texcoord).xyz * 2.0 - 1.0);
vec4 light0_ambient = vec4(0.1, 0.1, 0.1, 1.0);
vec4 light0_specular = vec4(0.9, 0.9, 0.9, 1.0);
vec4 light1_ambient = vec4(0.1, 0.1, 0.1, 1.0);
vec4 light1_specular = vec4(0.9, 0.9, 0.9, 1.0);
vec4 matAmbient = vec4(0.4, 0.4, 0.4, 1.0);
vec4 matDiffuse = vec4(0.8, 0.8, 0.9, 1.0);
vec3 final_color = vec3(0.0, 0.0, 0.0);
vec3 L = normalize(lightDir1.xyz);
final_color += (light0_ambient.rgb * matAmbient.rgb) * diffuseColor.xyz;
float lambertTerm = clamp(dot(bN,L), 0.0, 1.0);
final_color += (light0_diffuse.rgb * matDiffuse.rgb) * lambertTerm * diffuseColor.xyz;
float matShininess = mat_specular.a;
vec3 E = normalize(eyeVec.xyz);
vec3 R = reflect(-L, bN);
float specular = pow(max(dot(R, E), 0.0), matShininess);
final_color += (light0_specular.rgb * mat_specular.rgb) * specular * lambertTerm * bump.x;
L = normalize(lightDir2.xyz);
final_color += (light1_ambient.rgb * matAmbient.rgb) * diffuseColor.xyz;
lambertTerm = clamp(dot(bN,L), 0.0, 1.0);
final_color += (light1_diffuse.rgb * matDiffuse.rgb) * lambertTerm * diffuseColor.xyz;
E = normalize(eyeVec.xyz);
R = reflect(-L, bN);
specular = pow(max(dot(R, E), 0.0), matShininess);
final_color += (light1_specular.rgb * mat_specular.rgb) * specular * lambertTerm * bump.x;
Out_Color = vec4(final_color.xyz, 1.0);
}

//////////////////////////////// Evaluation shader

#version 400 core
layout(triangles, equal_spacing, ccw) in;
in vec4 Colors_CS_ES[];
in vec4 Normal_CS_ES[];
in vec4 UVMap_CS_ES[];
patch in vec3 f3B210;
patch in vec3 f3B120;
patch in vec3 f3B021;
patch in vec3 f3B012;
patch in vec3 f3B102;
patch in vec3 f3B201;
patch in vec3 f3B111;
patch in vec3 f3N110;
patch in vec3 f3N011;
patch in vec3 f3N101;
uniform mat4 WorldMatrix;
uniform mat4 ViewProjectionMatrix;
uniform mat4 ViewMatrix;
uniform sampler2D bumpMap;
uniform sampler2D normalMap;
uniform vec4 light0_diffuse;
uniform vec4 light1_diffuse;
uniform vec4 mat_specular;
uniform float bumpScale;
out vec4 color;
out vec3 normal;
out vec4 lightDir1;
out vec4 lightDir2;
out vec4 eyeVec;
out vec2 texcoord;
vec4 interpolate(in vec4 v0, in vec4 v1, in vec4 v2, in vec4 v3)
{
vec4 a = mix(v0, v1, gl_TessCoord.x);
vec4 b = mix(v3, v2, gl_TessCoord.x);
return mix(a, b, gl_TessCoord.y);
}
void main()
{
float u = gl_TessCoord.x;
float v = gl_TessCoord.y;
float w = gl_TessCoord.z;
color = vec4(0);
color += u * Colors_CS_ES[0];
color += v * Colors_CS_ES[1];
color += w * Colors_CS_ES[2];
texcoord = vec2(0);
texcoord += w * UVMap_CS_ES[0].xy;
texcoord += u * UVMap_CS_ES[1].xy;
texcoord += v * UVMap_CS_ES[2].xy;
vec4 bump = texture(bumpMap, texcoord);
float fU = gl_TessCoord.x;
float fV = gl_TessCoord.y;
float fW = gl_TessCoord.z;
float fUU = fU * fU;
float fVV = fV * fV;
float fWW = fW * fW;
float fUU3 = fUU * 3.0f;
float fVV3 = fVV * 3.0f;
float fWW3 = fWW * 3.0f;
vec4 pos;
pos.w = 1.0;
pos.xyz = gl_in[0].gl_Position.xyz * fWW * fW +
gl_in[1].gl_Position.xyz * fUU * fU +
gl_in[2].gl_Position.xyz * fVV * fV +
f3B210 * fWW3 * fU +
f3B120 * fW * fUU3 +
f3B201 * fWW3 * fV +
f3B021 * fUU3 * fV +
f3B102 * fW * fVV3 +
f3B012 * fU * fVV3 +
f3B111 * 6.0f * fW * fU * fV;
normal = Normal_CS_ES[0].xyz * fWW +
Normal_CS_ES[1].xyz * fUU +
Normal_CS_ES[2].xyz * fVV +
f3N110 * fW * fU +
f3N011 * fU * fV +
f3N101 * fW * fV;
vec3 N = normalize(normal.xyz);
pos.xyz += N * bump.x * bumpScale;
gl_Position = ViewProjectionMatrix * pos;
vec3 T;
vec3 B;
vec4 v1 = WorldMatrix * vec4(0.0, 0.0, 1.0, 0.0);
vec4 v2 = WorldMatrix * vec4(0.0, 1.0, 0.0, 0.0);
vec3 c1 = cross(N, v1.xyz);
vec3 c2 = cross(N, v2.xyz);
if (length(c1) > length(c2))
T = c1;
else
T = c2;
B = cross(N, T);
T = normalize(vec3(ViewMatrix * vec4(T.xyz, 0.0)));
B = normalize(vec3(ViewMatrix * vec4(B.xyz, 0.0)));
N = normalize(vec3(ViewMatrix * vec4(N.xyz, 0.0)));
vec4 vVertex = ViewMatrix * pos;
eyeVec = -vVertex;
vec4 l1 = vec4(-20.0, -20.0, 20.0, 1.0);
vec4 l2 = vec4(20.0, 20.0, 20.0, 1.0);
vec3 lp1 = vec3(ViewMatrix * l1);
vec3 lp2 = vec3(ViewMatrix * l2);
vec3 tmpVec;
vec3 lVec = lp1 - vVertex.xyz;
tmpVec.x = dot(lVec, T);
tmpVec.y = dot(lVec, B);
tmpVec.z = dot(lVec, N);
lightDir1.xyz = tmpVec;
lVec = lp2 - vVertex.xyz;
tmpVec.x = dot(lVec, T);
tmpVec.y = dot(lVec, B);
tmpVec.z = dot(lVec, N);
lightDir2.xyz = tmpVec;
vec3 vVec = -vVertex.xyz;
tmpVec.x = dot(vVec, T);
tmpVec.y = dot(vVec, B);
tmpVec.z = dot(vVec, N);
eyeVec.xyz = tmpVec;
}

/////////////////////////////////// Control shader

#version 400 core
layout(vertices = 3) out;
uniform float tessLevelOuter;
uniform float tessLevelInner;
uniform mat4 ViewMatrix;
in vec4 Color_VS_CS[];
in vec4 Normal_VS_CS[];
in vec4 UVMap_VS_CS[];
out vec4 Colors_CS_ES[];
out vec4 Normal_CS_ES[];
out vec4 UVMap_CS_ES[];
patch out vec3 f3B210;
patch out vec3 f3B120;
patch out vec3 f3B021;
patch out vec3 f3B012;
patch out vec3 f3B102;
patch out vec3 f3B201;
patch out vec3 f3B111;
patch out vec3 f3N110;
patch out vec3 f3N011;
patch out vec3 f3N101;
void main()
{
gl_TessLevelOuter[0] = tessLevelOuter;
gl_TessLevelOuter[1] = tessLevelOuter;
gl_TessLevelOuter[2] = tessLevelOuter;
gl_TessLevelInner[0] = tessLevelInner;
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
Colors_CS_ES[gl_InvocationID] = Color_VS_CS[gl_InvocationID];
Normal_CS_ES[gl_InvocationID] = Normal_VS_CS[gl_InvocationID];
UVMap_CS_ES[gl_InvocationID] = UVMap_VS_CS[gl_InvocationID];
vec3 f3B003 = gl_in[0].gl_Position.xyz;
vec3 f3B030 = gl_in[1].gl_Position.xyz;
vec3 f3B300 = gl_in[2].gl_Position.xyz;
vec3 f3N002 = Normal_VS_CS[0].xyz;
vec3 f3N020 = Normal_VS_CS[1].xyz;
vec3 f3N200 = Normal_VS_CS[2].xyz;
f3B210 = ( ( 2.0f * f3B003 ) + f3B030 - ( dot( ( f3B030 - f3B003 ), f3N002 ) * f3N002 ) ) / 3.0f;
f3B120 = ( ( 2.0f * f3B030 ) + f3B003 - ( dot( ( f3B003 - f3B030 ), f3N020 ) * f3N020 ) ) / 3.0f;
f3B021 = ( ( 2.0f * f3B030 ) + f3B300 - ( dot( ( f3B300 - f3B030 ), f3N020 ) * f3N020 ) ) / 3.0f;
f3B012 = ( ( 2.0f * f3B300 ) + f3B030 - ( dot( ( f3B030 - f3B300 ), f3N200 ) * f3N200 ) ) / 3.0f;
f3B102 = ( ( 2.0f * f3B300 ) + f3B003 - ( dot( ( f3B003 - f3B300 ), f3N200 ) * f3N200 ) ) / 3.0f;
f3B201 = ( ( 2.0f * f3B003 ) + f3B300 - ( dot( ( f3B300 - f3B003 ), f3N002 ) * f3N002 ) ) / 3.0f;
vec3 f3E = ( f3B210 + f3B120 + f3B021 + f3B012 + f3B102 + f3B201 ) / 6.0f;
vec3 f3V = ( f3B003 + f3B030 + f3B300 ) / 3.0f;
f3B111 = f3E + ( ( f3E - f3V ) / 2.0f );
float fV12 = 2.0f * dot( f3B030 - f3B003, f3N002 + f3N020 ) / dot( f3B030 - f3B003, f3B030 - f3B003 );
f3N110 = normalize( f3N002 + f3N020 - fV12 * ( f3B030 - f3B003 ) );
float fV23 = 2.0f * dot( f3B300 - f3B030, f3N020 + f3N200 ) / dot( f3B300 - f3B030, f3B300 - f3B030 );
f3N011 = normalize( f3N020 + f3N200 - fV23 * ( f3B300 - f3B030 ) );
float fV31 = 2.0f * dot( f3B003 - f3B300, f3N200 + f3N002 ) / dot( f3B003 - f3B300, f3B003 - f3B300 );
f3N101 = normalize( f3N200 + f3N002 - fV31 * ( f3B003 - f3B300 ) );
}

The Little Body
04-15-2011, 12:50 PM
Have you please a very more basic example that display the first levels of a Sierpinski triangle with a tesselation shader for example ?

The Little Body
04-15-2011, 03:16 PM
For example, how adapt this basic sample found at http://www.cis.scu.edu.tw/~chiang/course/CG/ProgramNotes/SourceProgram/gasket2.c for to use tesselation shaders for the handle of triangle subdivisions ?

gcc gasket2.c -o gasket2 -lGL -lm -lglut -lGLU


/* gasket2.c */

/* E. Angel, Interactive Computer Graphics */
/* A Top-Down Approach with OpenGL, Third Edition */
/* Addison-Wesley Longman, 2003 */

/* Recursive subdivision of triangle to form Sierpinski gasket */

#include <GL/glut.h>

typedef float point2[2];

/* initial triangle */

point2 v[]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}};

int n;

void triangle( point2 a, point2 b, point2 c)

/* display one triangle */
{
glBegin(GL_TRIANGLES);
glVertex2fv(a);
glVertex2fv(b);
glVertex2fv(c);
glEnd();
}

void divide_triangle(point2 a, point2 b, point2 c, int m)
{

/* triangle subdivision using vertex numbers */

point2 v0, v1, v2;
int j;
if(m>0)
{
for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2;
for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2;
for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2;
divide_triangle(a, v0, v1, m-1);
divide_triangle(c, v1, v2, m-1);
divide_triangle(b, v2, v0, m-1);
}
else(triangle(a,b,c)); /* draw triangle at end of recursion */
}


void display(void)
{


glClear(GL_COLOR_BUFFER_BIT);
divide_triangle(v[0], v[1], v[2], n);
glFlush();
}

void myinit()
{

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-2.0, 2.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glClearColor (1.0, 1.0, 1.0, 1.0);
glColor3f(0.0,0.0,0.0);
}

void
main(int argc, char **argv)
{
n=4;
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize(500, 500);
glutCreateWindow("3D Gasket");
glutDisplayFunc(display);
myinit();
glutMainLoop();
}

arekkusu
04-16-2011, 11:31 AM
You don't need tessellation shaders to hardware-accelerate that.
You can do it with geometry shaders and transform feedback, circa 2007:
http://developer.download.nvidia.com/SDK/10.5/opengl/samples.html#transform_feedback_fractal

The Little Body
04-16-2011, 05:21 PM
Thanks, Arekkusu

The difference between Tesselation and Geometry shaders is that tesselation shaders have a fixed number of vertex in output and geometry shaders doesn't have this limitation ?

Or the difference between this two types of shaders is about another thing ?

For Geometry shaders, I have found a tutorial that seem me very good at http://cirl.missouri.edu/gpu/glsl_lessons/glsl_geometry_shader/index.html
=> when I see how is make the Geometry shader into this tuto, I think that I can make alls computations on it (n is only equal to 4 so with a little chance, alls the 4 iterations can perhaps to be "unfactorised" and all this contained into a single Geometry shader)

The Little Body
04-16-2011, 05:55 PM
After some reading, I begin with geometry shader (that I don't find very hard to understand) and see after (but very very after) with tesselation shaders (because this seem me really more difficult to handle) :)

Sv3nni
09-25-2011, 12:59 AM
This one is quite easy to understand:
http://forums.nvidia.com/index.php?showtopic=210979

aqnuep
09-25-2011, 01:42 AM
You don't need tessellation shaders to hardware-accelerate that.
You can do it with geometry shaders and transform feedback, circa 2007:
http://developer.download.nvidia.com/SDK/10.5/opengl/samples.html#transform_feedback_fractal
You just forgot that geometry shaders have not been designed for tessellation thus they handle it very slowly as geometry shaders are usually output bound if used incorrectly.

I don't say it is not possible to use it for tessellation but it is not efficient for that, especially on GL3 class hardware.