# Help with Phong Tessellation

This topic is 3045 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I extracted the shader text from the executable in the demo at http://perso.telecom-paristech.fr/~boubek/papers/PhongTessellation/ but I don't see how p0-p3 are computed... and wouldn't they be different per triangle? Why send them as uniforms... Also, not sure what quadID is, though quadMode specifies triangle or quad and alpha is the depth value mentioned in the paper. The other thing not clear is how to actually subdivide; this shader only outputs the position, and looks like the demo executable uses OpenMesh for subdivision.
uniform vec3 n0, n1, n2, n3, p0, p1, p2, p3;
uniform float alpha;

varying vec4 P;
varying vec3 N;

vec3 project(vec3 p, vec3 c, vec3 n)
{
return p - dot(p - c, n) * n;
}

vec3 PhongGeometry(float u, float v, float w)
{
vec3 p = w * p0 + u * p1 + v * p2;
vec3 c0 = project(p, p0, n0);
vec3 c1 = project(p, p1, n1);
vec3 c2 = project(p, p2, n2);
vec3 q = w * c0 + u * c1 + v * c2;
vec3 r = mix(p, q, alpha);
return r;
}

vec3 bilinearInterpolation(float w, float u, vec3 p0, vec3 p1, vec3 p2, vec3 p3)
{
return u * (w * p0 + (1.0 - w) * p1) + (1.0 - u) * (w * p3 + (1.0 - w) * p2);
}

vec3 quadPhongGeometry(float u, float v, float w)
{
vec3 p;
if (quadID == 0) p = bilinearInterpolation(u, v, p0, p1, p2, p3);
else p = bilinearInterpolation(u, v, p2, p3, p0, p1);
vec3 c0 = project(p, p0, n0);
vec3 c1 = project(p, p1, n1);
vec3 c2 = project(p, p2, n2);
vec3 c3 = project(p, p3, n3);
vec3 q;
if (quadID == 0) q = bilinearInterpolation(u, v, c0, c1, c2, c3);
else q = bilinearInterpolation(u, v, c2, c3, c0, c1);
vec3 r = mix(p, q, alpha);
return r;
}

vec3 evalPos(float u, float v, float w)
{
else return PhongGeometry(u, v, w);
}

vec3 PhongNormal(float u, float v, float w)
{
return normalize(w * n0 + u * n1 + v * n2);
}

vec3 quadPhongNormal(float u, float v, float w)
{
if (quadID == 0) return normalize(bilinearInterpolation(u, v, n0, n1, n2, n3));
return normalize(bilinearInterpolation(u, v, n2, n3, n0, n1));
}

vec3 evalNormal(float u, float v, float w)
{
return PhongNormal(u, v, w);
}

void main(void)
{
float u = gl_Vertex.y;
float v = gl_Vertex.z;
float w = gl_Vertex.x;
gl_Vertex = vec4(evalPos(u, v, w), gl_Vertex.w);
gl_Normal = evalNormal(u, v, w);
P = gl_Vertex;
N = gl_Normal;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}

##### Share on other sites
Looks like the subdivision is done by replacing the original triangles with tessellated ones from a database, from a previous publication: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch05.html
The gl_Vertex holds the barycentric coordinates, and the uniforms are the original triangle positions (and normals). But this means that each original triangle to be refined would incur a separate uniform update and draw call...
Is there a way to avoid this if a geometry shader is used to subdivide? Or maybe something with instancing and uniform buffers?

1. 1
Rutin
26
2. 2
3. 3
4. 4
JoeJ
18
5. 5
gaxio
11

• 14
• 22
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631763
• Total Posts
3002194
×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!