Sfoglia il codice sorgente

Updating with a subdiv algorithm. It seems too expensive

Panagiotis Christopoulos Charitos 12 anni fa
parent
commit
b2f4d321b1
3 ha cambiato i file con 159 aggiunte e 23 eliminazioni
  1. 89 13
      shaders/MsCommonTessc.glsl
  2. 51 5
      shaders/MsCommonTesse.glsl
  3. 19 5
      shaders/MsCommonVert.glsl

+ 89 - 13
shaders/MsCommonTessc.glsl

@@ -1,15 +1,16 @@
 #pragma anki include "shaders/MsBsCommon.glsl"
 
-layout(vertices = 3) out;
+layout(vertices = 1) out;
 
 // Varyings in
 in highp vec3 vPosition[];
 in highp vec2 vTexCoords[];
-#if PASS_COLOR
 in mediump vec3 vNormal[];
+#if PASS_COLOR
 in mediump vec4 vTangent[];
 #endif
 
+#if 0
 // Varyings out
 out highp vec3 tcPosition[];
 out highp vec2 tcTexCoords[];
@@ -17,25 +18,100 @@ out highp vec2 tcTexCoords[];
 out mediump vec3 tcNormal[];
 out mediump vec4 tcTangent[];
 #endif
+#endif
+
+struct OutPatch
+{
+	vec3 pos030;
+	vec3 pos021;
+	vec3 pos012;
+	vec3 pos003;
+	vec3 pos102;
+	vec3 pos201;
+	vec3 pos300;
+	vec3 pos210;
+	vec3 pos120;
+	vec3 pos111;
+
+	vec2 texCoord[3];
+	vec3 normal[3];
+#if PASS_COLOR
+	vec4 tangent[3];
+#endif
+};
+
+out patch OutPatch tcPatch;
+
+// Project point to plane
+vec3 projectToPlane(vec3 point, vec3 planePoint, vec3 planeNormal)
+{
+	vec3 v = point - planePoint;
+	float pen = dot(v, planeNormal);
+	vec3 d = pen * planeNormal;
+	return (point - d);
+} 
+
+// Calculate control points
+void calcPositions()
+{
+	// The original vertices stay the same
+	tcPatch.pos030 = vPosition[0];
+	tcPatch.pos003 = vPosition[1];
+	tcPatch.pos300 = vPosition[2];
+
+	// edges are names according to the opposing vertex
+	vec3 edgeB300 = tcPatch.pos003 - tcPatch.pos030;
+	vec3 edgeB030 = tcPatch.pos300 - tcPatch.pos003;
+	vec3 edgeB003 = tcPatch.pos030 - tcPatch.pos300;
+
+	// Generate two midpoints on each edge
+	tcPatch.pos021 = tcPatch.pos030 + edgeB300 / 3.0;
+	tcPatch.pos012 = tcPatch.pos030 + edgeB300 * 2.0 / 3.0;
+	tcPatch.pos102 = tcPatch.pos003 + edgeB030 / 3.0;
+	tcPatch.pos201 = tcPatch.pos003 + edgeB030 * 2.0 / 3.0;
+	tcPatch.pos210 = tcPatch.pos300 + edgeB003 / 3.0;
+	tcPatch.pos120 = tcPatch.pos300 + edgeB003 * 2.0 / 3.0;
+
+	tcPatch.pos021 = 
+		projectToPlane(tcPatch.pos021, tcPatch.pos030, tcPatch.normal[0]);
+	tcPatch.pos012 =
+		projectToPlane(tcPatch.pos012, tcPatch.pos003, tcPatch.normal[1]);
+	tcPatch.pos102 = 
+		projectToPlane(tcPatch.pos102, tcPatch.pos003, tcPatch.normal[1]);
+	tcPatch.pos201 = 
+		projectToPlane(tcPatch.pos201, tcPatch.pos300, tcPatch.normal[2]);
+	tcPatch.pos210 = 
+		projectToPlane(tcPatch.pos210, tcPatch.pos300, tcPatch.normal[2]);
+	tcPatch.pos120 = 
+		projectToPlane(tcPatch.pos120, tcPatch.pos030, tcPatch.normal[0]);
+
+	// Handle the center
+	vec3 center = (tcPatch.pos003 + tcPatch.pos030 + tcPatch.pos300) / 3.0;
+	tcPatch.pos111 = (tcPatch.pos021 + tcPatch.pos012 + tcPatch.pos102 +
+		tcPatch.pos201 + tcPatch.pos210 + tcPatch.pos120) / 6.0;
+	tcPatch.pos111 += (tcPatch.pos111 - center) / 2.0;
+} 
 
 #define tessellatePositionNormalTangentTexCoord_DEFINED
 void tessellatePositionNormalTangentTexCoord(
 	in float tessLevelInner, 
 	in float tessLevelOuter)
 {
-	tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
-	tcTexCoords[gl_InvocationID] = vTexCoords[gl_InvocationID];
+	for(int i = 0 ; i < 3 ; i++) 
+	{		
+		tcPatch.texCoord[i] = vTexCoords[i];
+		tcPatch.normal[i] = vNormal[i];
 #if PASS_COLOR
-	tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
-	tcTangent[gl_InvocationID] = vTangent[gl_InvocationID];
+		tcPatch.tangent[i] = vTangent[i];
 #endif
-
-	if(gl_InvocationID == 0) 
-	{
-		gl_TessLevelInner[0] = tessLevelInner;
-		gl_TessLevelOuter[0] = tessLevelOuter;
-		gl_TessLevelOuter[1] = tessLevelOuter;
-		gl_TessLevelOuter[2] = tessLevelOuter;
 	}
+
+	calcPositions();
+
+	// Calculate the tessellation levels
+	gl_TessLevelOuter[0] = tessLevelOuter;
+	gl_TessLevelOuter[1] = tessLevelOuter;
+	gl_TessLevelOuter[2] = tessLevelOuter;
+	gl_TessLevelInner[0] = tessLevelInner;
 }
 

+ 51 - 5
shaders/MsCommonTesse.glsl

@@ -1,15 +1,38 @@
 layout(triangles, equal_spacing, ccw) in;
 
 // Varyings in
+#if 0
 in highp vec3 tcPosition[];
 in highp vec2 tcTexCoords[];
 #if PASS_COLOR
 in mediump vec3 tcNormal[];
 in mediump vec4 tcTangent[];
 #endif
+#endif
+
+struct OutPatch
+{
+	vec3 pos030;
+	vec3 pos021;
+	vec3 pos012;
+	vec3 pos003;
+	vec3 pos102;
+	vec3 pos201;
+	vec3 pos300;
+	vec3 pos210;
+	vec3 pos120;
+	vec3 pos111;
+
+	vec2 texCoord[3];
+	vec3 normal[3];
+#if PASS_COLOR
+	vec4 tangent[3];
+#endif
+};
+
+in patch OutPatch tcPatch;
 
 // Varyings out
-out highp vec3 tePosition;
 out highp vec2 teTexCoords;
 #if PASS_COLOR
 out mediump vec3 teNormal;
@@ -23,12 +46,35 @@ out mediump vec4 teTangent;
 void subdivPositionNormalTangentTexCoord(in mat4 mvp, in mat3 normalMat)
 {
 #if PASS_COLOR
-	teNormal = normalize(normalMat * INTERPOLATE(tcNormal));
-	teTangent = INTERPOLATE(tcTangent);
+	teNormal = normalize(normalMat * INTERPOLATE(tcPatch.normal));
+	teTangent = INTERPOLATE(tcPatch.tangent);
 	teTangent.xyz = normalize(normalMat * teTangent.xyz);
 #endif
 
-	teTexCoords = INTERPOLATE(tcTexCoords);
+	teTexCoords = INTERPOLATE(tcPatch.texCoord);
+
+	float u = gl_TessCoord.x;
+	float v = gl_TessCoord.y;
+	float w = gl_TessCoord.z;
+
+	float uPow3 = pow(u, 3);
+	float vPow3 = pow(v, 3);
+	float wPow3 = pow(w, 3);
+	float uPow2 = pow(u, 2);
+	float vPow2 = pow(v, 2);
+	float wPow2 = pow(w, 2);
+
+	vec3 pos = 
+		tcPatch.pos300 * wPow3
+		+ tcPatch.pos030 * uPow3
+		+ tcPatch.pos003 * vPow3
+		+ tcPatch.pos210 * 3.0 * wPow2 * u 
+		+ tcPatch.pos120 * 3.0 * w * uPow2 
+		+ tcPatch.pos201 * 3.0 * wPow2 * v 
+		+ tcPatch.pos021 * 3.0 * uPow2 * v 
+		+ tcPatch.pos102 * 3.0 * w * vPow2 
+		+ tcPatch.pos012 * 3.0 * u * vPow2 
+		+ tcPatch.pos111 * 6.0 * w * u * v;
 
-	gl_Position = mvp * vec4(INTERPOLATE(tcPosition), 1.0);
+	gl_Position = mvp * vec4(pos, 1.0);
 }

+ 19 - 5
shaders/MsCommonVert.glsl

@@ -4,8 +4,12 @@
 /// @{
 layout(location = 0) in highp vec3 position;
 layout(location = 3) in highp vec2 texCoord;
-#if PASS_COLOR
+
+#if PASS_COLOR || TESSELLATION
 layout(location = 1) in mediump vec3 normal;
+#endif
+
+#if PASS_COLOR
 layout(location = 2) in mediump vec4 tangent;
 #endif
 /// @}
@@ -18,8 +22,11 @@ out highp vec2 vTexCoords;
 flat out uint vInstanceId;
 #endif
 
-#if PASS_COLOR
+#if PASS_COLOR || TESSELLATION
 out mediump vec3 vNormal;
+#endif
+
+#if PASS_COLOR
 out mediump vec4 vTangent;
 out mediump vec3 vVertPosViewSpace; ///< For env mapping. AKA view vector
 #endif
@@ -50,16 +57,23 @@ void writePositionTexCoord(in mat4 mvp)
 #define writePositionNormalTangentTexCoord_DEFINED
 void writePositionNormalTangentTexCoord(in mat4 mvp, in mat3 normalMat)
 {
-#if PASS_COLOR
-#	if TESSELLATION
+
+#if TESSELLATION
+
 	// Passthrough
 	vNormal = normal;
+#	if PASS_COLOR
 	vTangent = tangent;
-#	else
+#	endif
+
+#else
+
+#	if PASS_COLOR
 	vNormal = normalMat * normal;
 	vTangent.xyz = normalMat * tangent.xyz;
 	vTangent.w = tangent.w;
 #	endif
+
 #endif
 
 	writePositionTexCoord(mvp);