Updated PN-Triangles tessellation shader demo

This commit is contained in:
saschawillems 2016-05-21 16:01:48 +02:00
parent 3f06ef81fb
commit 459dbbc5a1
16 changed files with 374 additions and 464 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -14,7 +14,7 @@ layout (binding = 0, rgba8) uniform writeonly image2D resultImage;
#define SPHERECOUNT 3
#define SHADOW 0.5
#define RAYBOUNCES 1
#define REFLECTIONSTRENGTH 0.25
#define REFLECTIONSTRENGTH 0.4
struct Camera {
vec3 pos;
@ -47,7 +47,7 @@ float lightSpecular(vec3 normal, vec3 lightDir)
{
vec3 viewVec = normalize(ubo.camera.pos);
vec3 halfVec = normalize(lightDir + viewVec);
return pow(clamp(dot(normal, halfVec), 0.0, 1.0), 16.0);
return pow(clamp(dot(normal, halfVec), 0.0, 1.0), 32.0);
}
// Primitives
@ -206,19 +206,19 @@ void main()
spheres[0].pos = vec3(-2.25, 1.0, 0.0);
spheres[0].r = 1.0;
spheres[0].material.diffuse = vec3(1.0, 0.0, 0.0);
spheres[0].material.specular = vec3(1.0, 1.0, 1.0);
spheres[0].material.specular = vec3(2.0);
spheres[1].id = 3;
spheres[1].pos = vec3(0.0, 2.5, 0.0);
spheres[1].r = 1.0;
spheres[1].material.diffuse = vec3(0.0, 0.0, 1.0);
spheres[1].material.specular = vec3(1.0, 1.0, 1.0);
spheres[1].material.specular = vec3(2.0);
spheres[2].id = 4;
spheres[2].pos = vec3(2.25, 1.0, 0.0);
spheres[2].r = 1.0;
spheres[2].material.diffuse = vec3(0.0, 1.0, 0.0);
spheres[2].material.specular = vec3(1.0, 1.0, 1.0);
spheres[2].material.specular = vec3(2.0);
ivec2 dim = imageSize(resultImage);
vec2 uv = vec2(gl_GlobalInvocationID.xy) / dim;

View file

@ -8,6 +8,11 @@ layout (location = 1) in vec2 inUV;
layout (location = 0) out vec2 outUV;
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
outUV = inUV;

View file

@ -13,8 +13,9 @@ layout (location = 0) out vec4 outFragColor;
void main()
{
vec3 N = normalize(inNormal);
vec3 L = normalize(vec3(0.0, 2.0, 2.0));
vec3 L = normalize(vec3(0.0, -4.0, 4.0));
vec4 color = texture(samplerColorMap, inUV);
vec3 color = texture(samplerColorMap, inUV).rgb;
outFragColor.rgb = vec3(clamp(max(dot(N,L), 0.0), 0.15, 1.0)) * color;
}
outFragColor.rgb = vec3(clamp(max(dot(N,L), 0.0), 0.2, 1.0)) * color.rgb * 1.5;
}

View file

@ -10,6 +10,11 @@ layout (location = 2) in vec2 inUV;
layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec2 outUV;
out gl_PerVertex
{
vec4 gl_Position;
};
void main(void)
{
gl_Position = vec4(inPos.xyz, 1.0);

View file

@ -35,118 +35,52 @@ layout(location = 6) out PnPatch outPatch[3];
float wij(int i, int j)
{
return dot(gl_in[j].gl_Position.xyz - gl_in[i].gl_Position.xyz, inNormal[i]);
return dot(gl_in[j].gl_Position.xyz - gl_in[i].gl_Position.xyz, inNormal[i]);
}
float vij(int i, int j)
{
vec3 Pj_minus_Pi = gl_in[j].gl_Position.xyz
- gl_in[i].gl_Position.xyz;
vec3 Ni_plus_Nj = inNormal[i]+inNormal[j];
return 2.0*dot(Pj_minus_Pi, Ni_plus_Nj)/dot(Pj_minus_Pi, Pj_minus_Pi);
}
void main()
{
// get data
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
outUV[gl_InvocationID] = inUV[gl_InvocationID];
// set base
float P0 = gl_in[0].gl_Position[gl_InvocationID];
float P1 = gl_in[1].gl_Position[gl_InvocationID];
float P2 = gl_in[2].gl_Position[gl_InvocationID];
float N0 = inNormal[0][gl_InvocationID];
float N1 = inNormal[1][gl_InvocationID];
float N2 = inNormal[2][gl_InvocationID];
// compute control points
outPatch[gl_InvocationID].b210 = (2.0*P0 + P1 - wij(0,1)*N0)/3.0;
outPatch[gl_InvocationID].b120 = (2.0*P1 + P0 - wij(1,0)*N1)/3.0;
outPatch[gl_InvocationID].b021 = (2.0*P1 + P2 - wij(1,2)*N1)/3.0;
outPatch[gl_InvocationID].b012 = (2.0*P2 + P1 - wij(2,1)*N2)/3.0;
outPatch[gl_InvocationID].b102 = (2.0*P2 + P0 - wij(2,0)*N2)/3.0;
outPatch[gl_InvocationID].b201 = (2.0*P0 + P2 - wij(0,2)*N0)/3.0;
float E = ( outPatch[gl_InvocationID].b210
+ outPatch[gl_InvocationID].b120
+ outPatch[gl_InvocationID].b021
+ outPatch[gl_InvocationID].b012
+ outPatch[gl_InvocationID].b102
+ outPatch[gl_InvocationID].b201 ) / 6.0;
float V = (P0 + P1 + P2)/3.0;
outPatch[gl_InvocationID].b111 = E + (E - V)*0.5;
outPatch[gl_InvocationID].n110 = N0+N1-vij(0,1)*(P1-P0);
outPatch[gl_InvocationID].n011 = N1+N2-vij(1,2)*(P2-P1);
outPatch[gl_InvocationID].n101 = N2+N0-vij(2,0)*(P0-P2);
// set tess levels
gl_TessLevelOuter[gl_InvocationID] = ubo.tessLevel;
gl_TessLevelInner[0] = ubo.tessLevel;
}
/*
struct PnPatch
{
float barycentric[7];
float normals[3];
};
layout (binding = 0) uniform UBO
{
float tessLevel;
} ubo;
layout (vertices = 3) out;
layout (location = 0) in vec3 inNormal[];
layout (location = 1) in vec2 inUV[];
layout (location = 0) out vec3 outNormal[3];
layout (location = 1) out PnPatch outPatch[3];
float dotPosNormW(int i, int j)
{
return dot(gl_in[j].gl_Position.xyz - gl_in[i].gl_Position.xyz, inNormal[i]);
}
float dotPosNormV(int i, int j)
{
vec3 deltaPos = gl_in[j].gl_Position.xyz - gl_in[i].gl_Position.xyz;
return 2.0 * dot(deltaPos, inNormal[i] + inNormal[j]) / dot(deltaPos, deltaPos);
vec3 Pj_minus_Pi = gl_in[j].gl_Position.xyz
- gl_in[i].gl_Position.xyz;
vec3 Ni_plus_Nj = inNormal[i]+inNormal[j];
return 2.0*dot(Pj_minus_Pi, Ni_plus_Nj)/dot(Pj_minus_Pi, Pj_minus_Pi);
}
void main()
{
// get data
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
outUV[gl_InvocationID] = inUV[gl_InvocationID];
float pos[3] = float[](gl_in[0].gl_Position[gl_InvocationID], gl_in[1].gl_Position[gl_InvocationID], gl_in[2].gl_Position[gl_InvocationID]);
float normal[3] = float[](inNormal[0][gl_InvocationID], inNormal[1][gl_InvocationID], inNormal[2][gl_InvocationID]);
// Calculate control points
outPatch[gl_InvocationID].barycentric[0] = (2.0 * pos[0] + pos[1] - dotPosNormW(0,1) * normal[0]) / 3.0;
outPatch[gl_InvocationID].barycentric[1] = (2.0 * pos[1] + pos[0] - dotPosNormW(1,0) * normal[1]) / 3.0;
outPatch[gl_InvocationID].barycentric[2] = (2.0 * pos[1] + pos[2] - dotPosNormW(1,2) * normal[1]) / 3.0;
outPatch[gl_InvocationID].barycentric[3] = (2.0 * pos[2] + pos[1] - dotPosNormW(2,1) * normal[2]) / 3.0;
outPatch[gl_InvocationID].barycentric[4] = (2.0 * pos[2] + pos[0] - dotPosNormW(2,0) * normal[2]) / 3.0;
outPatch[gl_InvocationID].barycentric[5] = (2.0 * pos[0] + pos[2] - dotPosNormW(0,2) * normal[0]) / 3.0;
// set base
float P0 = gl_in[0].gl_Position[gl_InvocationID];
float P1 = gl_in[1].gl_Position[gl_InvocationID];
float P2 = gl_in[2].gl_Position[gl_InvocationID];
float N0 = inNormal[0][gl_InvocationID];
float N1 = inNormal[1][gl_InvocationID];
float N2 = inNormal[2][gl_InvocationID];
float E = 0.0;
for (int i = 0; i < outPatch[gl_InvocationID].barycentric.length(); ++i)
{
E += outPatch[gl_InvocationID].barycentric[i];
}
E /= 6.0;
float V = (pos[0] + pos[1] + pos[2])/3.0;
outPatch[gl_InvocationID].barycentric[6] = E + (E - V) * 0.5;
outPatch[gl_InvocationID].normals[0] = normal[0] + normal[1] - dotPosNormV(0, 1) * (pos[1] - pos[0]);
outPatch[gl_InvocationID].normals[1] = normal[1] + normal[2] - dotPosNormV(1, 2) * (pos[2] - pos[1]);
outPatch[gl_InvocationID].normals[2] = normal[2] + normal[0] - dotPosNormV(2, 0) * (pos[0] - pos[2]);
// compute control points
outPatch[gl_InvocationID].b210 = (2.0*P0 + P1 - wij(0,1)*N0)/3.0;
outPatch[gl_InvocationID].b120 = (2.0*P1 + P0 - wij(1,0)*N1)/3.0;
outPatch[gl_InvocationID].b021 = (2.0*P1 + P2 - wij(1,2)*N1)/3.0;
outPatch[gl_InvocationID].b012 = (2.0*P2 + P1 - wij(2,1)*N2)/3.0;
outPatch[gl_InvocationID].b102 = (2.0*P2 + P0 - wij(2,0)*N2)/3.0;
outPatch[gl_InvocationID].b201 = (2.0*P0 + P2 - wij(0,2)*N0)/3.0;
float E = ( outPatch[gl_InvocationID].b210
+ outPatch[gl_InvocationID].b120
+ outPatch[gl_InvocationID].b021
+ outPatch[gl_InvocationID].b012
+ outPatch[gl_InvocationID].b102
+ outPatch[gl_InvocationID].b201 ) / 6.0;
float V = (P0 + P1 + P2)/3.0;
outPatch[gl_InvocationID].b111 = E + (E - V)*0.5;
outPatch[gl_InvocationID].n110 = N0+N1-vij(0,1)*(P1-P0);
outPatch[gl_InvocationID].n011 = N1+N2-vij(1,2)*(P2-P1);
outPatch[gl_InvocationID].n101 = N2+N0-vij(2,0)*(P0-P2);
// set tess levels
gl_TessLevelOuter[gl_InvocationID] = ubo.tessLevel;
gl_TessLevelInner[0] = ubo.tessLevel;
}
*/
}

View file

@ -20,9 +20,9 @@ struct PnPatch
layout (binding = 1) uniform UBO
{
mat4 projection;
mat4 model;
float tessAlpha;
mat4 projection;
mat4 model;
float tessAlpha;
} ubo;
layout(triangles, fractional_odd_spacing, ccw) in;
@ -38,142 +38,54 @@ layout(location = 1) out vec2 oTexCoord;
void main()
{
vec3 uvwSquared = uvw * uvw;
vec3 uvwCubed = uvwSquared * uvw;
vec3 uvwSquared = uvw * uvw;
vec3 uvwCubed = uvwSquared * uvw;
// extract control points
vec3 b210 = vec3(iPnPatch[0].b210, iPnPatch[1].b210, iPnPatch[2].b210);
vec3 b120 = vec3(iPnPatch[0].b120, iPnPatch[1].b120, iPnPatch[2].b120);
vec3 b021 = vec3(iPnPatch[0].b021, iPnPatch[1].b021, iPnPatch[2].b021);
vec3 b012 = vec3(iPnPatch[0].b012, iPnPatch[1].b012, iPnPatch[2].b012);
vec3 b102 = vec3(iPnPatch[0].b102, iPnPatch[1].b102, iPnPatch[2].b102);
vec3 b201 = vec3(iPnPatch[0].b201, iPnPatch[1].b201, iPnPatch[2].b201);
vec3 b111 = vec3(iPnPatch[0].b111, iPnPatch[1].b111, iPnPatch[2].b111);
// extract control points
vec3 b210 = vec3(iPnPatch[0].b210, iPnPatch[1].b210, iPnPatch[2].b210);
vec3 b120 = vec3(iPnPatch[0].b120, iPnPatch[1].b120, iPnPatch[2].b120);
vec3 b021 = vec3(iPnPatch[0].b021, iPnPatch[1].b021, iPnPatch[2].b021);
vec3 b012 = vec3(iPnPatch[0].b012, iPnPatch[1].b012, iPnPatch[2].b012);
vec3 b102 = vec3(iPnPatch[0].b102, iPnPatch[1].b102, iPnPatch[2].b102);
vec3 b201 = vec3(iPnPatch[0].b201, iPnPatch[1].b201, iPnPatch[2].b201);
vec3 b111 = vec3(iPnPatch[0].b111, iPnPatch[1].b111, iPnPatch[2].b111);
// extract control normals
vec3 n110 = normalize(vec3(iPnPatch[0].n110,
iPnPatch[1].n110,
iPnPatch[2].n110));
vec3 n011 = normalize(vec3(iPnPatch[0].n011,
iPnPatch[1].n011,
iPnPatch[2].n011));
vec3 n101 = normalize(vec3(iPnPatch[0].n101,
iPnPatch[1].n101,
iPnPatch[2].n101));
// extract control normals
vec3 n110 = normalize(vec3(iPnPatch[0].n110, iPnPatch[1].n110, iPnPatch[2].n110));
vec3 n011 = normalize(vec3(iPnPatch[0].n011, iPnPatch[1].n011, iPnPatch[2].n011));
vec3 n101 = normalize(vec3(iPnPatch[0].n101, iPnPatch[1].n101, iPnPatch[2].n101));
// compute texcoords
oTexCoord = gl_TessCoord[2]*iTexCoord[0]
+ gl_TessCoord[0]*iTexCoord[1]
+ gl_TessCoord[1]*iTexCoord[2];
// compute texcoords
oTexCoord = gl_TessCoord[2]*iTexCoord[0] + gl_TessCoord[0]*iTexCoord[1] + gl_TessCoord[1]*iTexCoord[2];
// normal
vec3 barNormal = gl_TessCoord[2]*iNormal[0]
+ gl_TessCoord[0]*iNormal[1]
+ gl_TessCoord[1]*iNormal[2];
vec3 pnNormal = iNormal[0]*uvwSquared[2]
+ iNormal[1]*uvwSquared[0]
+ iNormal[2]*uvwSquared[1]
+ n110*uvw[2]*uvw[0]
+ n011*uvw[0]*uvw[1]
+ n101*uvw[2]*uvw[1];
oNormal = ubo.tessAlpha*pnNormal + (1.0-ubo.tessAlpha)*barNormal;
// normal
// Barycentric normal
vec3 barNormal = gl_TessCoord[2]*iNormal[0] + gl_TessCoord[0]*iNormal[1] + gl_TessCoord[1]*iNormal[2];
vec3 pnNormal = iNormal[0]*uvwSquared[2] + iNormal[1]*uvwSquared[0] + iNormal[2]*uvwSquared[1]
+ n110*uvw[2]*uvw[0] + n011*uvw[0]*uvw[1]+ n101*uvw[2]*uvw[1];
oNormal = ubo.tessAlpha*pnNormal + (1.0-ubo.tessAlpha) * barNormal;
// compute interpolated pos
vec3 barPos = gl_TessCoord[2]*gl_in[0].gl_Position.xyz
+ gl_TessCoord[0]*gl_in[1].gl_Position.xyz
+ gl_TessCoord[1]*gl_in[2].gl_Position.xyz;
// compute interpolated pos
vec3 barPos = gl_TessCoord[2]*gl_in[0].gl_Position.xyz
+ gl_TessCoord[0]*gl_in[1].gl_Position.xyz
+ gl_TessCoord[1]*gl_in[2].gl_Position.xyz;
// save some computations
uvwSquared *= 3.0;
// save some computations
uvwSquared *= 3.0;
// compute PN position
vec3 pnPos = gl_in[0].gl_Position.xyz*uvwCubed[2]
+ gl_in[1].gl_Position.xyz*uvwCubed[0]
+ gl_in[2].gl_Position.xyz*uvwCubed[1]
+ b210*uvwSquared[2]*uvw[0]
+ b120*uvwSquared[0]*uvw[2]
+ b201*uvwSquared[2]*uvw[1]
+ b021*uvwSquared[0]*uvw[1]
+ b102*uvwSquared[1]*uvw[2]
+ b012*uvwSquared[1]*uvw[0]
+ b111*6.0*uvw[0]*uvw[1]*uvw[2];
// compute PN position
vec3 pnPos = gl_in[0].gl_Position.xyz*uvwCubed[2]
+ gl_in[1].gl_Position.xyz*uvwCubed[0]
+ gl_in[2].gl_Position.xyz*uvwCubed[1]
+ b210*uvwSquared[2]*uvw[0]
+ b120*uvwSquared[0]*uvw[2]
+ b201*uvwSquared[2]*uvw[1]
+ b021*uvwSquared[0]*uvw[1]
+ b102*uvwSquared[1]*uvw[2]
+ b012*uvwSquared[1]*uvw[0]
+ b111*6.0*uvw[0]*uvw[1]*uvw[2];
// final position and normal
vec3 finalPos = (1.0-ubo.tessAlpha)*barPos + ubo.tessAlpha*pnPos;
// final position and normal
vec3 finalPos = (1.0-ubo.tessAlpha)*barPos + ubo.tessAlpha*pnPos;
gl_Position = ubo.projection * ubo.model * vec4(finalPos,1.0);
}
/*
struct PnPatch
{
float barycentric[7];
float normals[3];
};
layout (binding = 1) uniform UBO
{
mat4 projection;
mat4 model;
float tessAlpha;
} ubo;
layout(triangles, equal_spacing, ccw) in;
layout(location = 0) in vec3 inNormal[];
layout(location = 1) in PnPatch inPatch[];
layout(location = 0) out vec3 outNormal;
void main()
{
vec3 uvwSquared = gl_TessCoord * gl_TessCoord;
vec3 uvwCubed = uvwSquared * gl_TessCoord;
// Get barycentric coordinates
vec3 barycentric[7];
for (int i = 0; i < barycentric.length(); ++i)
{
barycentric[i] = vec3(inPatch[0].barycentric[i], inPatch[1].barycentric[i], inPatch[2].barycentric[i]);
}
// Normal control points
vec3 normals[3];
for (int i = 0; i < normals.length(); ++i)
{
normals[i] = normalize(vec3(inPatch[0].normals[i], inPatch[1].normals[i], inPatch[2].normals[i]));
}
// Calculate normals
vec3 barNormal = gl_TessCoord[2] * inNormal[0] + gl_TessCoord[0] * inNormal[1] + gl_TessCoord[1] * inNormal[2];
vec3 pnNormal = inNormal[0] * uvwSquared[2]
+ inNormal[1] * uvwSquared[0]
+ inNormal[2] * uvwSquared[1]
+ normals[0] * gl_TessCoord[2] * gl_TessCoord[0]
+ normals[1] * gl_TessCoord[0] * gl_TessCoord[1]
+ normals[2] * gl_TessCoord[2] * gl_TessCoord[1];
outNormal = ubo.tessAlpha * pnNormal + (1.0-ubo.tessAlpha) * barNormal;
// Interpolate position
vec3 barPos = gl_TessCoord[2] * gl_in[0].gl_Position.xyz
+ gl_TessCoord[0] * gl_in[1].gl_Position.xyz
+ gl_TessCoord[1] * gl_in[2].gl_Position.xyz;
uvwSquared *= 3.0;
// PN positions
vec3 pnPos = gl_in[0].gl_Position.xyz * uvwCubed[2]
+ gl_in[1].gl_Position.xyz * uvwCubed[0]
+ gl_in[2].gl_Position.xyz * uvwCubed[1]
+ barycentric[0] * uvwSquared[2] * gl_TessCoord[0]
+ barycentric[1] * uvwSquared[0] * gl_TessCoord[2]
+ barycentric[5] * uvwSquared[2] * gl_TessCoord[1]
+ barycentric[2] * uvwSquared[0] * gl_TessCoord[1]
+ barycentric[4] * uvwSquared[1] * gl_TessCoord[2]
+ barycentric[3] * uvwSquared[1] * gl_TessCoord[0]
+ barycentric[6] * 6.0 * gl_TessCoord[0] * gl_TessCoord[1] * gl_TessCoord[2];
vec3 finalPos = (1.0 - ubo.tessAlpha) * barPos + ubo.tessAlpha * pnPos;
gl_Position = ubo.projection * ubo.model * vec4(finalPos, 1.0);
}
*/
}

Binary file not shown.

BIN
data/textures/deer.ktx Normal file

Binary file not shown.