|
|
@@ -1,10 +1,12 @@
|
|
|
#pragma anki include "shaders/MsBsCommon.glsl"
|
|
|
|
|
|
-layout(vertices = 1) out;
|
|
|
+layout(vertices = 3) out;
|
|
|
|
|
|
-// Varyings in
|
|
|
-in highp vec3 vPosition[];
|
|
|
-in highp vec2 vTexCoords[];
|
|
|
+#define IID gl_InvocationID
|
|
|
+
|
|
|
+// In
|
|
|
+in vec3 vPosition[];
|
|
|
+in vec2 vTexCoords[];
|
|
|
in mediump vec3 vNormal[];
|
|
|
#if PASS_COLOR
|
|
|
in mediump vec4 vTangent[];
|
|
|
@@ -14,18 +16,19 @@ flat in uint vInstanceId[];
|
|
|
#endif
|
|
|
|
|
|
// Out
|
|
|
-struct CommonPatch
|
|
|
-{
|
|
|
- vec3 positions[3];
|
|
|
- vec2 texCoord[3];
|
|
|
- vec3 normal[3];
|
|
|
+out vec3 tcPosition[];
|
|
|
+out vec2 tcTexCoord[];
|
|
|
+out vec3 tcNormal[];
|
|
|
#if PASS_COLOR
|
|
|
- vec4 tangent[3];
|
|
|
+out vec4 tcTangent[];
|
|
|
#endif
|
|
|
+
|
|
|
#if INSTANCE_ID_FRAGMENT_SHADER
|
|
|
+struct CommonPatch
|
|
|
+{
|
|
|
uint instanceId;
|
|
|
-#endif
|
|
|
};
|
|
|
+#endif
|
|
|
|
|
|
struct PNPatch
|
|
|
{
|
|
|
@@ -38,9 +41,9 @@ struct PNPatch
|
|
|
vec3 pos111;
|
|
|
};
|
|
|
|
|
|
-#define pos030 positions[0]
|
|
|
-#define pos003 positions[1]
|
|
|
-#define pos300 positions[2]
|
|
|
+#define pos030 tcPosition[0]
|
|
|
+#define pos003 tcPosition[1]
|
|
|
+#define pos300 tcPosition[2]
|
|
|
|
|
|
struct PhongPatch
|
|
|
{
|
|
|
@@ -49,7 +52,9 @@ struct PhongPatch
|
|
|
|
|
|
out patch PNPatch pnPatch;
|
|
|
out patch PhongPatch phongPatch;
|
|
|
+#if INSTANCE_ID_FRAGMENT_SHADER
|
|
|
out patch CommonPatch commonPatch;
|
|
|
+#endif
|
|
|
|
|
|
// Project point to plane
|
|
|
vec3 projectToPlane(vec3 point, vec3 planePoint, vec3 planeNormal)
|
|
|
@@ -64,39 +69,38 @@ vec3 projectToPlane(vec3 point, vec3 planePoint, vec3 planeNormal)
|
|
|
void calcPositions()
|
|
|
{
|
|
|
// The original vertices stay the same
|
|
|
- commonPatch.pos030 = vPosition[0];
|
|
|
- commonPatch.pos003 = vPosition[1];
|
|
|
- commonPatch.pos300 = vPosition[2];
|
|
|
+ pos030 = vPosition[0];
|
|
|
+ pos003 = vPosition[1];
|
|
|
+ pos300 = vPosition[2];
|
|
|
|
|
|
// edges are names according to the opposing vertex
|
|
|
- vec3 edgeB300 = commonPatch.pos003 - commonPatch.pos030;
|
|
|
- vec3 edgeB030 = commonPatch.pos300 - commonPatch.pos003;
|
|
|
- vec3 edgeB003 = commonPatch.pos030 - commonPatch.pos300;
|
|
|
+ vec3 edgeB300 = pos003 - pos030;
|
|
|
+ vec3 edgeB030 = pos300 - pos003;
|
|
|
+ vec3 edgeB003 = pos030 - pos300;
|
|
|
|
|
|
// Generate two midpoints on each edge
|
|
|
- pnPatch.pos021 = commonPatch.pos030 + edgeB300 / 3.0;
|
|
|
- pnPatch.pos012 = commonPatch.pos030 + edgeB300 * 2.0 / 3.0;
|
|
|
- pnPatch.pos102 = commonPatch.pos003 + edgeB030 / 3.0;
|
|
|
- pnPatch.pos201 = commonPatch.pos003 + edgeB030 * 2.0 / 3.0;
|
|
|
- pnPatch.pos210 = commonPatch.pos300 + edgeB003 / 3.0;
|
|
|
- pnPatch.pos120 = commonPatch.pos300 + edgeB003 * 2.0 / 3.0;
|
|
|
+ pnPatch.pos021 = pos030 + edgeB300 / 3.0;
|
|
|
+ pnPatch.pos012 = pos030 + edgeB300 * 2.0 / 3.0;
|
|
|
+ pnPatch.pos102 = pos003 + edgeB030 / 3.0;
|
|
|
+ pnPatch.pos201 = pos003 + edgeB030 * 2.0 / 3.0;
|
|
|
+ pnPatch.pos210 = pos300 + edgeB003 / 3.0;
|
|
|
+ pnPatch.pos120 = pos300 + edgeB003 * 2.0 / 3.0;
|
|
|
|
|
|
pnPatch.pos021 = projectToPlane(
|
|
|
- pnPatch.pos021, commonPatch.pos030, commonPatch.normal[0]);
|
|
|
+ pnPatch.pos021, pos030, tcNormal[0]);
|
|
|
pnPatch.pos012 = projectToPlane(
|
|
|
- pnPatch.pos012, commonPatch.pos003, commonPatch.normal[1]);
|
|
|
+ pnPatch.pos012, pos003, tcNormal[1]);
|
|
|
pnPatch.pos102 = projectToPlane(
|
|
|
- pnPatch.pos102, commonPatch.pos003, commonPatch.normal[1]);
|
|
|
+ pnPatch.pos102, pos003, tcNormal[1]);
|
|
|
pnPatch.pos201 = projectToPlane(
|
|
|
- pnPatch.pos201, commonPatch.pos300, commonPatch.normal[2]);
|
|
|
+ pnPatch.pos201, pos300, tcNormal[2]);
|
|
|
pnPatch.pos210 = projectToPlane(
|
|
|
- pnPatch.pos210, commonPatch.pos300, commonPatch.normal[2]);
|
|
|
+ pnPatch.pos210, pos300, tcNormal[2]);
|
|
|
pnPatch.pos120 = projectToPlane(
|
|
|
- pnPatch.pos120, commonPatch.pos030, commonPatch.normal[0]);
|
|
|
+ pnPatch.pos120, pos030, tcNormal[0]);
|
|
|
|
|
|
// Handle the center
|
|
|
- vec3 center = (commonPatch.pos003 + commonPatch.pos030
|
|
|
- + commonPatch.pos300) / 3.0;
|
|
|
+ vec3 center = (pos003 + pos030 + pos300) / 3.0;
|
|
|
pnPatch.pos111 = (pnPatch.pos021 + pnPatch.pos012 + pnPatch.pos102 +
|
|
|
pnPatch.pos201 + pnPatch.pos210 + pnPatch.pos120) / 6.0;
|
|
|
pnPatch.pos111 += (pnPatch.pos111 - center) / 2.0;
|
|
|
@@ -146,6 +150,59 @@ bool isFaceOutsideClipSpace(in vec2 posNdc[3])
|
|
|
posOutsideClipSpace(posNdc[2])));
|
|
|
}
|
|
|
|
|
|
+void setSilhouetteTessLevels(in mat3 normalMat, in float maxTessLevel)
|
|
|
+{
|
|
|
+ // Calculate the normals in view space
|
|
|
+ vec3 nv[3];
|
|
|
+ for(int i = 0; i < 3; i++)
|
|
|
+ {
|
|
|
+ nv[i] = normalMat * vNormal[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ gl_TessLevelOuter[0] = calcEdgeTessLevel(nv[1], nv[2], maxTessLevel);
|
|
|
+ gl_TessLevelOuter[1] = calcEdgeTessLevel(nv[2], nv[0], maxTessLevel);
|
|
|
+ gl_TessLevelOuter[2] = calcEdgeTessLevel(nv[0], nv[1], maxTessLevel);
|
|
|
+ gl_TessLevelInner[0] = (gl_TessLevelOuter[0] + gl_TessLevelOuter[1]
|
|
|
+ + gl_TessLevelOuter[2]) / 3.0;
|
|
|
+}
|
|
|
+
|
|
|
+void setConstantTessLevels(in float maxTessLevel)
|
|
|
+{
|
|
|
+ gl_TessLevelOuter[0] = maxTessLevel;
|
|
|
+ gl_TessLevelOuter[1] = maxTessLevel;
|
|
|
+ gl_TessLevelOuter[2] = maxTessLevel;
|
|
|
+ gl_TessLevelInner[0] = maxTessLevel;
|
|
|
+}
|
|
|
+
|
|
|
+void discardPatch()
|
|
|
+{
|
|
|
+ gl_TessLevelOuter[0] = 0.0;
|
|
|
+ gl_TessLevelOuter[1] = 0.0;
|
|
|
+ gl_TessLevelOuter[2] = 0.0;
|
|
|
+ gl_TessLevelInner[0] = 0.0;
|
|
|
+}
|
|
|
+
|
|
|
+// Check if a face is visible
|
|
|
+bool isFaceVisible(in mat4 mvp)
|
|
|
+{
|
|
|
+ // Calculate clip positions
|
|
|
+ vec2 clip[3];
|
|
|
+ for(int i = 0 ; i < 3 ; i++)
|
|
|
+ {
|
|
|
+ vec4 v = mvp * vec4(vPosition[i], 1.0);
|
|
|
+ clip[i] = v.xy / v.w;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check the face orientation and clipping
|
|
|
+ return isFaceFrontFacing(clip) && !isFaceOutsideClipSpace(clip);
|
|
|
+}
|
|
|
+
|
|
|
+float calcPhongTerm(int ivId, int i, vec3 q)
|
|
|
+{
|
|
|
+ vec3 qMinusP = q - vPosition[i];
|
|
|
+ return q[ivId] - dot(qMinusP, vNormal[i]) * vNormal[i][ivId];
|
|
|
+}
|
|
|
+
|
|
|
// This function is part of the point-normal tessellation method
|
|
|
#define tessellatePNPositionNormalTangentTexCoord_DEFINED
|
|
|
void tessellatePNPositionNormalTangentTexCoord(
|
|
|
@@ -165,10 +222,10 @@ void tessellatePNPositionNormalTangentTexCoord(
|
|
|
|
|
|
for(int i = 0 ; i < 3 ; i++)
|
|
|
{
|
|
|
- commonPatch.texCoord[i] = vTexCoords[i];
|
|
|
- commonPatch.normal[i] = vNormal[i];
|
|
|
+ tcTexCoord[i] = vTexCoords[i];
|
|
|
+ tcNormal[i] = vNormal[i];
|
|
|
#if PASS_COLOR
|
|
|
- commonPatch.tangent[i] = vTangent[i];
|
|
|
+ tcTangent[i] = vTangent[i];
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
@@ -186,94 +243,71 @@ void tessellatePNPositionNormalTangentTexCoord(
|
|
|
gl_TessLevelInner[0] = tessLevel;
|
|
|
}
|
|
|
|
|
|
-float calcTerm(int ivId, int i, vec3 q)
|
|
|
-{
|
|
|
- vec3 qMinusP = q - vPosition[i];
|
|
|
- return q[ivId] - dot(qMinusP, vNormal[i]) * vNormal[i][ivId];
|
|
|
-}
|
|
|
-
|
|
|
#define tessellatePhongPositionNormalTangentTexCoord_DEFINED
|
|
|
void tessellatePhongPositionNormalTangentTexCoord(
|
|
|
in float maxTessLevel,
|
|
|
in mat4 mvp,
|
|
|
in mat3 normalMat)
|
|
|
{
|
|
|
- // Calculate clip positions
|
|
|
- vec2 clip[3];
|
|
|
- for(int i = 0 ; i < 3 ; i++)
|
|
|
- {
|
|
|
- vec4 v = mvp * vec4(vPosition[i], 1.0);
|
|
|
- clip[i] = v.xy / v.w;
|
|
|
- }
|
|
|
-
|
|
|
- // Check the face orientation and clipping
|
|
|
- if(isFaceFrontFacing(clip) && !isFaceOutsideClipSpace(clip))
|
|
|
+ if(IID == 0)
|
|
|
{
|
|
|
- // The face is front facing and inside the clip space
|
|
|
-
|
|
|
- for(int i = 0 ; i < 3 ; i++)
|
|
|
+ if(isFaceVisible(mvp))
|
|
|
{
|
|
|
- commonPatch.positions[i] = vPosition[i];
|
|
|
- commonPatch.texCoord[i] = vTexCoords[i];
|
|
|
- commonPatch.normal[i] = vNormal[i];
|
|
|
-#if PASS_COLOR
|
|
|
- commonPatch.tangent[i] = vTangent[i];
|
|
|
-#endif
|
|
|
-
|
|
|
- phongPatch.terms[i][0] =
|
|
|
- calcTerm(i, 0, vPosition[1]) + calcTerm(i, 1, vPosition[0]);
|
|
|
- phongPatch.terms[i][1] =
|
|
|
- calcTerm(i, 1, vPosition[2]) + calcTerm(i, 2, vPosition[1]);
|
|
|
- phongPatch.terms[i][2] =
|
|
|
- calcTerm(i, 2, vPosition[0]) + calcTerm(i, 0, vPosition[2]);
|
|
|
+ setSilhouetteTessLevels(normalMat, maxTessLevel);
|
|
|
}
|
|
|
-
|
|
|
- // Calculate the normals in view space
|
|
|
- vec3 nv[3];
|
|
|
- for(int i = 0; i < 3; i++)
|
|
|
+ else
|
|
|
{
|
|
|
- nv[i] = normalMat * vNormal[i];
|
|
|
+ discardPatch();
|
|
|
}
|
|
|
-
|
|
|
- gl_TessLevelOuter[0] = calcEdgeTessLevel(nv[1], nv[2], maxTessLevel);
|
|
|
- gl_TessLevelOuter[1] = calcEdgeTessLevel(nv[2], nv[0], maxTessLevel);
|
|
|
- gl_TessLevelOuter[2] = calcEdgeTessLevel(nv[0], nv[1], maxTessLevel);
|
|
|
- gl_TessLevelInner[0] = 1.0;
|
|
|
- gl_TessLevelInner[0] = (gl_TessLevelOuter[0] + gl_TessLevelOuter[1]
|
|
|
- + gl_TessLevelOuter[2]) / 3.0;
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ tcPosition[IID] = vPosition[IID]; // Do that here to trick the barrier
|
|
|
+
|
|
|
+ barrier();
|
|
|
+
|
|
|
+ if(gl_TessLevelOuter[0] > 0.0)
|
|
|
{
|
|
|
- gl_TessLevelOuter[0] = 0.0;
|
|
|
- gl_TessLevelOuter[1] = 0.0;
|
|
|
- gl_TessLevelOuter[2] = 0.0;
|
|
|
- gl_TessLevelInner[0] = 0.0;
|
|
|
+ tcTexCoord[IID] = vTexCoords[IID];
|
|
|
+ tcNormal[IID] = vNormal[IID];
|
|
|
+#if PASS_COLOR
|
|
|
+ tcTangent[IID] = vTangent[IID];
|
|
|
+#endif
|
|
|
+
|
|
|
+ phongPatch.terms[IID][0] = calcPhongTerm(IID, 0, vPosition[1])
|
|
|
+ + calcPhongTerm(IID, 1, vPosition[0]);
|
|
|
+ phongPatch.terms[IID][1] = calcPhongTerm(IID, 1, vPosition[2])
|
|
|
+ + calcPhongTerm(IID, 2, vPosition[1]);
|
|
|
+ phongPatch.terms[IID][2] = calcPhongTerm(IID, 2, vPosition[0])
|
|
|
+ + calcPhongTerm(IID, 0, vPosition[2]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
#define tessellateDispMapPositionNormalTangentTexCoord_DEFINED
|
|
|
void tessellateDispMapPositionNormalTangentTexCoord(
|
|
|
in float maxTessLevel,
|
|
|
in mat4 mvp,
|
|
|
in mat3 normalMat)
|
|
|
{
|
|
|
- for(int i = 0 ; i < 3 ; i++)
|
|
|
+ if(IID == 0)
|
|
|
{
|
|
|
- commonPatch.positions[i] = vPosition[i];
|
|
|
- commonPatch.texCoord[i] = vTexCoords[i];
|
|
|
- commonPatch.normal[i] = vNormal[i];
|
|
|
-#if PASS_COLOR
|
|
|
- commonPatch.tangent[i] = vTangent[i];
|
|
|
-#endif
|
|
|
- }
|
|
|
+ if(isFaceVisible(mvp))
|
|
|
+ {
|
|
|
+ setSilhouetteTessLevels(normalMat, maxTessLevel);
|
|
|
|
|
|
#if INSTANCE_ID_FRAGMENT_SHADER
|
|
|
- commonPatch.instanceId = vInstanceId[0];
|
|
|
+ commonPatch.instanceId = vInstanceId[0];
|
|
|
#endif
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ discardPatch();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- gl_TessLevelOuter[0] = maxTessLevel;
|
|
|
- gl_TessLevelOuter[1] = maxTessLevel;
|
|
|
- gl_TessLevelOuter[2] = maxTessLevel;
|
|
|
- gl_TessLevelInner[0] = maxTessLevel;
|
|
|
+ tcPosition[IID] = vPosition[IID];
|
|
|
+ tcTexCoord[IID] = vTexCoords[IID];
|
|
|
+ tcNormal[IID] = vNormal[IID];
|
|
|
+#if PASS_COLOR
|
|
|
+ tcTangent[IID] = vTangent[IID];
|
|
|
+#endif
|
|
|
}
|