MsCommonTessc.glsl 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #pragma anki include "shaders/MsBsCommon.glsl"
  2. layout(vertices = 3) out;
  3. #define IID gl_InvocationID
  4. // In
  5. in vec3 vPosition[];
  6. in vec2 vTexCoords[];
  7. in mediump vec3 vNormal[];
  8. #if PASS_COLOR
  9. in mediump vec4 vTangent[];
  10. #endif
  11. #if INSTANCE_ID_FRAGMENT_SHADER
  12. flat in uint vInstanceId[];
  13. #endif
  14. // Out
  15. out vec3 tcPosition[];
  16. out vec2 tcTexCoord[];
  17. out vec3 tcNormal[];
  18. #if PASS_COLOR
  19. out vec4 tcTangent[];
  20. #endif
  21. #if INSTANCE_ID_FRAGMENT_SHADER
  22. struct CommonPatch
  23. {
  24. uint instanceId;
  25. };
  26. #endif
  27. struct PNPatch
  28. {
  29. vec3 pos021;
  30. vec3 pos012;
  31. vec3 pos102;
  32. vec3 pos201;
  33. vec3 pos210;
  34. vec3 pos120;
  35. vec3 pos111;
  36. };
  37. #define pos030 tcPosition[0]
  38. #define pos003 tcPosition[1]
  39. #define pos300 tcPosition[2]
  40. struct PhongPatch
  41. {
  42. vec3 terms[3];
  43. };
  44. out patch PNPatch pnPatch;
  45. out patch PhongPatch phongPatch;
  46. #if INSTANCE_ID_FRAGMENT_SHADER
  47. out patch CommonPatch commonPatch;
  48. #endif
  49. // Project point to plane
  50. vec3 projectToPlane(vec3 point, vec3 planePoint, vec3 planeNormal)
  51. {
  52. vec3 v = point - planePoint;
  53. float pen = dot(v, planeNormal);
  54. vec3 d = pen * planeNormal;
  55. return (point - d);
  56. }
  57. // Calculate control points
  58. void calcPositions()
  59. {
  60. // The original vertices stay the same
  61. pos030 = vPosition[0];
  62. pos003 = vPosition[1];
  63. pos300 = vPosition[2];
  64. // edges are names according to the opposing vertex
  65. vec3 edgeB300 = pos003 - pos030;
  66. vec3 edgeB030 = pos300 - pos003;
  67. vec3 edgeB003 = pos030 - pos300;
  68. // Generate two midpoints on each edge
  69. pnPatch.pos021 = pos030 + edgeB300 / 3.0;
  70. pnPatch.pos012 = pos030 + edgeB300 * 2.0 / 3.0;
  71. pnPatch.pos102 = pos003 + edgeB030 / 3.0;
  72. pnPatch.pos201 = pos003 + edgeB030 * 2.0 / 3.0;
  73. pnPatch.pos210 = pos300 + edgeB003 / 3.0;
  74. pnPatch.pos120 = pos300 + edgeB003 * 2.0 / 3.0;
  75. pnPatch.pos021 = projectToPlane(
  76. pnPatch.pos021, pos030, tcNormal[0]);
  77. pnPatch.pos012 = projectToPlane(
  78. pnPatch.pos012, pos003, tcNormal[1]);
  79. pnPatch.pos102 = projectToPlane(
  80. pnPatch.pos102, pos003, tcNormal[1]);
  81. pnPatch.pos201 = projectToPlane(
  82. pnPatch.pos201, pos300, tcNormal[2]);
  83. pnPatch.pos210 = projectToPlane(
  84. pnPatch.pos210, pos300, tcNormal[2]);
  85. pnPatch.pos120 = projectToPlane(
  86. pnPatch.pos120, pos030, tcNormal[0]);
  87. // Handle the center
  88. vec3 center = (pos003 + pos030 + pos300) / 3.0;
  89. pnPatch.pos111 = (pnPatch.pos021 + pnPatch.pos012 + pnPatch.pos102 +
  90. pnPatch.pos201 + pnPatch.pos210 + pnPatch.pos120) / 6.0;
  91. pnPatch.pos111 += (pnPatch.pos111 - center) / 2.0;
  92. }
  93. vec3 calcFaceNormal(in vec3 v0, in vec3 v1, in vec3 v2)
  94. {
  95. return normalize(cross(v1 - v0, v2 - v0));
  96. }
  97. float calcEdgeTessLevel(in vec3 n0, in vec3 n1, in float maxTessLevel)
  98. {
  99. vec3 norm = normalize(n0 + n1);
  100. float tess = (1.0 - norm.z) * (maxTessLevel - 1.0) + 1.0;
  101. return tess;
  102. }
  103. /*float calcEdgeTessLevel(in vec2 p0, in vec2 p1, in float maxTessLevel)
  104. {
  105. float dist = distance(p0, p1) * 10.0;
  106. return dist * (maxTessLevel - 1.0) + 1.0;
  107. }*/
  108. // Given the face positions in NDC caclulate if the face is front facing or not
  109. bool isFaceFrontFacing(in vec2 posNdc[3])
  110. {
  111. vec2 a = posNdc[1] - posNdc[0];
  112. vec2 b = posNdc[2] - posNdc[1];
  113. vec2 c = a.xy * b.yx;
  114. return (c.x - c.y) > 0.0;
  115. }
  116. // Check if a single NDC position is outside the clip space
  117. bool posOutsideClipSpace(in vec2 posNdc)
  118. {
  119. bvec2 compa = lessThan(posNdc, vec2(-1.0));
  120. bvec2 compb = greaterThan(posNdc, vec2(1.0));
  121. return all(bvec4(compa, compb));
  122. }
  123. // Check if a face in NDC is outside the clip space
  124. bool isFaceOutsideClipSpace(in vec2 posNdc[3])
  125. {
  126. return any(bvec3(
  127. posOutsideClipSpace(posNdc[0]),
  128. posOutsideClipSpace(posNdc[1]),
  129. posOutsideClipSpace(posNdc[2])));
  130. }
  131. void setSilhouetteTessLevels(in mat3 normalMat, in float maxTessLevel)
  132. {
  133. // Calculate the normals in view space
  134. vec3 nv[3];
  135. for(int i = 0; i < 3; i++)
  136. {
  137. nv[i] = normalMat * vNormal[i];
  138. }
  139. gl_TessLevelOuter[0] = calcEdgeTessLevel(nv[1], nv[2], maxTessLevel);
  140. gl_TessLevelOuter[1] = calcEdgeTessLevel(nv[2], nv[0], maxTessLevel);
  141. gl_TessLevelOuter[2] = calcEdgeTessLevel(nv[0], nv[1], maxTessLevel);
  142. gl_TessLevelInner[0] = (gl_TessLevelOuter[0] + gl_TessLevelOuter[1]
  143. + gl_TessLevelOuter[2]) / 3.0;
  144. }
  145. void setConstantTessLevels(in float maxTessLevel)
  146. {
  147. gl_TessLevelOuter[0] = maxTessLevel;
  148. gl_TessLevelOuter[1] = maxTessLevel;
  149. gl_TessLevelOuter[2] = maxTessLevel;
  150. gl_TessLevelInner[0] = maxTessLevel;
  151. }
  152. void discardPatch()
  153. {
  154. gl_TessLevelOuter[0] = 0.0;
  155. gl_TessLevelOuter[1] = 0.0;
  156. gl_TessLevelOuter[2] = 0.0;
  157. gl_TessLevelInner[0] = 0.0;
  158. }
  159. // Check if a face is visible
  160. bool isFaceVisible(in mat4 mvp)
  161. {
  162. // Calculate clip positions
  163. vec2 clip[3];
  164. for(int i = 0 ; i < 3 ; i++)
  165. {
  166. vec4 v = mvp * vec4(vPosition[i], 1.0);
  167. clip[i] = v.xy / v.w;
  168. }
  169. // Check the face orientation and clipping
  170. return isFaceFrontFacing(clip) && !isFaceOutsideClipSpace(clip);
  171. }
  172. float calcPhongTerm(int ivId, int i, vec3 q)
  173. {
  174. vec3 qMinusP = q - vPosition[i];
  175. return q[ivId] - dot(qMinusP, vNormal[i]) * vNormal[i][ivId];
  176. }
  177. // This function is part of the point-normal tessellation method
  178. #define tessellatePNPositionNormalTangentTexCoord_DEFINED
  179. void tessellatePNPositionNormalTangentTexCoord(
  180. in float maxTessLevel,
  181. in mat4 mvp,
  182. in mat3 normalMat)
  183. {
  184. float tessLevel = 0.0;
  185. // Calculate the face normal in view space
  186. vec3 faceNorm = calcFaceNormal(vPosition[0], vPosition[1], vPosition[2]);
  187. faceNorm = (normalMat * faceNorm);
  188. if(faceNorm.z >= 0.0)
  189. {
  190. // The face is front facing
  191. for(int i = 0 ; i < 3 ; i++)
  192. {
  193. tcTexCoord[i] = vTexCoords[i];
  194. tcNormal[i] = vNormal[i];
  195. #if PASS_COLOR
  196. tcTangent[i] = vTangent[i];
  197. #endif
  198. }
  199. calcPositions();
  200. // Calculate the tessLevel. It's 1.0 when the normal is facing the cam
  201. // and maxTessLevel when it's facing away. This gives high tessellation
  202. // on silhouettes
  203. tessLevel = (1.0 - faceNorm.z) * (maxTessLevel - 1.0) + 1.0;
  204. }
  205. gl_TessLevelOuter[0] = tessLevel;
  206. gl_TessLevelOuter[1] = tessLevel;
  207. gl_TessLevelOuter[2] = tessLevel;
  208. gl_TessLevelInner[0] = tessLevel;
  209. }
  210. #define tessellatePhongPositionNormalTangentTexCoord_DEFINED
  211. void tessellatePhongPositionNormalTangentTexCoord(
  212. in float maxTessLevel,
  213. in mat4 mvp,
  214. in mat3 normalMat)
  215. {
  216. if(IID == 0)
  217. {
  218. if(isFaceVisible(mvp))
  219. {
  220. setSilhouetteTessLevels(normalMat, maxTessLevel);
  221. }
  222. else
  223. {
  224. discardPatch();
  225. }
  226. }
  227. tcPosition[IID] = vPosition[IID]; // Do that here to trick the barrier
  228. barrier();
  229. if(gl_TessLevelOuter[0] > 0.0)
  230. {
  231. tcTexCoord[IID] = vTexCoords[IID];
  232. tcNormal[IID] = vNormal[IID];
  233. #if PASS_COLOR
  234. tcTangent[IID] = vTangent[IID];
  235. #endif
  236. phongPatch.terms[IID][0] = calcPhongTerm(IID, 0, vPosition[1])
  237. + calcPhongTerm(IID, 1, vPosition[0]);
  238. phongPatch.terms[IID][1] = calcPhongTerm(IID, 1, vPosition[2])
  239. + calcPhongTerm(IID, 2, vPosition[1]);
  240. phongPatch.terms[IID][2] = calcPhongTerm(IID, 2, vPosition[0])
  241. + calcPhongTerm(IID, 0, vPosition[2]);
  242. }
  243. }
  244. #define tessellateDispMapPositionNormalTangentTexCoord_DEFINED
  245. void tessellateDispMapPositionNormalTangentTexCoord(
  246. in float maxTessLevel,
  247. in mat4 mvp,
  248. in mat3 normalMat)
  249. {
  250. if(IID == 0)
  251. {
  252. if(isFaceVisible(mvp))
  253. {
  254. setSilhouetteTessLevels(normalMat, maxTessLevel);
  255. #if INSTANCE_ID_FRAGMENT_SHADER
  256. commonPatch.instanceId = vInstanceId[0];
  257. #endif
  258. }
  259. else
  260. {
  261. discardPatch();
  262. }
  263. }
  264. tcPosition[IID] = vPosition[IID];
  265. tcTexCoord[IID] = vTexCoords[IID];
  266. tcNormal[IID] = vNormal[IID];
  267. #if PASS_COLOR
  268. tcTangent[IID] = vTangent[IID];
  269. #endif
  270. }