Advertisement
Guest User

CustomTessellation.hlsl

a guest
Jun 27th, 2022
2,495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.76 KB | None | 0 0
  1.  
  2. #if defined(SHADER_API_D3D11) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) || defined(SHADER_API_VULKAN) || defined(SHADER_API_METAL) || defined(SHADER_API_PSSL)
  3. #define UNITY_CAN_COMPILE_TESSELLATION 1
  4. # define UNITY_domain domain
  5. # define UNITY_partitioning partitioning
  6. # define UNITY_outputtopology outputtopology
  7. # define UNITY_patchconstantfunc patchconstantfunc
  8. # define UNITY_outputcontrolpoints outputcontrolpoints
  9. #endif
  10.  
  11.  
  12.  
  13. // The structure definition defines which variables it contains.
  14. // This example uses the Attributes structure as an input structure in
  15. // the vertex shader.
  16.  
  17. // vertex to fragment struct
  18. struct Varyings
  19. {
  20. float4 color : COLOR;
  21. float3 normal : NORMAL;
  22. float4 vertex : SV_POSITION;
  23. float2 uv : TEXCOORD0;
  24. float4 noise : TEXCOORD1;
  25. };
  26.  
  27.  
  28. // tessellation data
  29. struct TessellationFactors
  30. {
  31. float edge[3] : SV_TessFactor;
  32. float inside : SV_InsideTessFactor;
  33. };
  34.  
  35. // Extra vertex struct
  36. struct ControlPoint
  37. {
  38. float4 vertex : INTERNALTESSPOS;
  39. float2 uv : TEXCOORD0;
  40. float4 color : COLOR;
  41. float3 normal : NORMAL;
  42. };
  43.  
  44. // the original vertex struct
  45. struct Attributes
  46. {
  47. float4 vertex : POSITION;
  48. float3 normal : NORMAL;
  49. float2 uv : TEXCOORD0;
  50. float4 color : COLOR;
  51.  
  52. };
  53.  
  54. // tessellation variables, add these to your shader properties
  55. float _Tess;
  56. float _MaxTessDistance;
  57.  
  58. // info so the GPU knows what to do (triangles) and how to set it up , clockwise, fractional division
  59. // hull takes the original vertices and outputs more
  60. [UNITY_domain("tri")]
  61. [UNITY_outputcontrolpoints(3)]
  62. [UNITY_outputtopology("triangle_cw")]
  63. [UNITY_partitioning("fractional_odd")]
  64. //[UNITY_partitioning("fractional_even")]
  65. //[UNITY_partitioning("pow2")]
  66. //[UNITY_partitioning("integer")]
  67. [UNITY_patchconstantfunc("patchConstantFunction")]
  68. ControlPoint hull(InputPatch<ControlPoint, 3> patch, uint id : SV_OutputControlPointID)
  69. {
  70. return patch[id];
  71. }
  72.  
  73. TessellationFactors UnityCalcTriEdgeTessFactors (float3 triVertexFactors)
  74. {
  75. TessellationFactors tess;
  76. tess.edge[0] = 0.5 * (triVertexFactors.y + triVertexFactors.z);
  77. tess.edge[1] = 0.5 * (triVertexFactors.x + triVertexFactors.z);
  78. tess.edge[2] = 0.5 * (triVertexFactors.x + triVertexFactors.y);
  79. tess.inside = (triVertexFactors.x + triVertexFactors.y + triVertexFactors.z) / 3.0f;
  80. return tess;
  81. }
  82.  
  83. // fade tessellation at a distance
  84. float CalcDistanceTessFactor(float4 vertex, float minDist, float maxDist, float tess)
  85. {
  86. float3 worldPosition = mul(unity_ObjectToWorld, vertex).xyz;
  87. float dist = distance(worldPosition, _WorldSpaceCameraPos);
  88. float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0);
  89.  
  90. return f * tess;
  91. }
  92.  
  93. TessellationFactors DistanceBasedTess(float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess)
  94. {
  95. float3 f;
  96. f.x = CalcDistanceTessFactor(v0, minDist, maxDist, tess);
  97. f.y = CalcDistanceTessFactor(v1, minDist, maxDist, tess);
  98. f.z = CalcDistanceTessFactor(v2, minDist, maxDist, tess);
  99.  
  100. return UnityCalcTriEdgeTessFactors(f);
  101. }
  102.  
  103.  
  104.  
  105. float UnityCalcEdgeTessFactor (float3 wpos0, float3 wpos1, float edgeLen)
  106. {
  107. // distance to edge center
  108. float dist = distance (0.5 * (wpos0+wpos1), _WorldSpaceCameraPos);
  109. // length of the edge
  110. float len = distance(wpos0, wpos1);
  111. // edgeLen is approximate desired size in pixels
  112. float f = max(len * _ScreenParams.y / (edgeLen * dist), 1.0);
  113. return f;
  114. }
  115.  
  116.  
  117. float UnityDistanceFromPlane (float3 pos, float4 plane)
  118. {
  119. float d = dot (float4(pos,1.0f), plane);
  120. return d;
  121. }
  122.  
  123.  
  124. // Returns true if triangle with given 3 world positions is outside of camera's view frustum.
  125. // cullEps is distance outside of frustum that is still considered to be inside (i.e. max displacement)
  126. bool UnityWorldViewFrustumCull (float3 wpos0, float3 wpos1, float3 wpos2, float cullEps)
  127. {
  128. float4 planeTest;
  129.  
  130. // left
  131. planeTest.x = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) +
  132. (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) +
  133. (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f );
  134. // right
  135. planeTest.y = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) +
  136. (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) +
  137. (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f );
  138. // top
  139. planeTest.z = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) +
  140. (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) +
  141. (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f );
  142. // bottom
  143. planeTest.w = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) +
  144. (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) +
  145. (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f );
  146.  
  147. // has to pass all 4 plane tests to be visible
  148. return !all (planeTest);
  149. }
  150.  
  151.  
  152. // Desired edge length based tessellation:
  153. // Approximate resulting edge length in pixels is "edgeLength".
  154. // Does not take viewing FOV into account, just flat out divides factor by distance.
  155. TessellationFactors UnityEdgeLengthBasedTess (float4 v0, float4 v1, float4 v2, float edgeLength)
  156. {
  157. float3 pos0 = mul(unity_ObjectToWorld,v0).xyz;
  158. float3 pos1 = mul(unity_ObjectToWorld,v1).xyz;
  159. float3 pos2 = mul(unity_ObjectToWorld,v2).xyz;
  160. TessellationFactors tess;
  161. tess.edge[0] = UnityCalcEdgeTessFactor (pos1, pos2, edgeLength);
  162. tess.edge[1] = UnityCalcEdgeTessFactor (pos2, pos0, edgeLength);
  163. tess.edge[2] = UnityCalcEdgeTessFactor (pos0, pos1, edgeLength);
  164. tess.inside = (tess.edge[0] + tess.edge[1] + tess.edge[2]) / 3.0f;
  165. return tess;
  166. }
  167.  
  168.  
  169. // Same as UnityEdgeLengthBasedTess, but also does patch frustum culling:
  170. // patches outside of camera's view are culled before GPU tessellation. Saves some wasted work.
  171. TessellationFactors UnityEdgeLengthBasedTessCull (float4 v0, float4 v1, float4 v2, float edgeLength, float maxDisplacement)
  172. {
  173. float3 pos0 = mul(unity_ObjectToWorld,v0).xyz;
  174. float3 pos1 = mul(unity_ObjectToWorld,v1).xyz;
  175. float3 pos2 = mul(unity_ObjectToWorld,v2).xyz;
  176. TessellationFactors tess;
  177.  
  178. if (UnityWorldViewFrustumCull(pos0, pos1, pos2, maxDisplacement))
  179. {
  180. tess.edge[0] = 0.0f;
  181. tess.edge[1] = 0.0f;
  182. tess.edge[2] = 0.0f;
  183. tess.inside = 0.0f;
  184. }
  185. else
  186. {
  187. tess.edge[0] = UnityCalcEdgeTessFactor (pos1, pos2, edgeLength);
  188. tess.edge[1] = UnityCalcEdgeTessFactor (pos2, pos0, edgeLength);
  189. tess.edge[2] = UnityCalcEdgeTessFactor (pos0, pos1, edgeLength);
  190. tess.inside = (tess.edge[0] + tess.edge[1] + tess.edge[2]) / 3.0f;
  191. }
  192. return tess;
  193. }
  194.  
  195. TessellationFactors patchConstantFunction(InputPatch<ControlPoint, 3> patch)
  196. {
  197. float minDist = 2.0;
  198. float maxDist = _MaxTessDistance + minDist;
  199. TessellationFactors f;
  200.  
  201. // distance based tesselation
  202. return DistanceBasedTess(patch[0].vertex, patch[1].vertex, patch[2].vertex, minDist, maxDist, _Tess);
  203.  
  204. // continious tesselation based on _Tess being the edge length
  205. // return UnityEdgeLengthBasedTess(patch[0].vertex, patch[1].vertex, patch[2].vertex, _Tess);
  206. // continious tesselation based on _Tess being the edge length, with camrea culling
  207. // return UnityEdgeLengthBasedTessCull(patch[0].vertex, patch[1].vertex, patch[2].vertex, _Tess, _MaxTessDistance);
  208.  
  209. }
  210.  
  211. #define Interpolate(fieldName) v.fieldName = \
  212. patch[0].fieldName * barycentricCoordinates.x + \
  213. patch[1].fieldName * barycentricCoordinates.y + \
  214. patch[2].fieldName * barycentricCoordinates.z;
  215.  
  216.  
  217.  
  218. // second vertex, copy to shader
  219. //Varyings vert(Attributes input)
  220. //{
  221. // Varyings output;
  222. // // put your vertex manipulation here , ie: input.vertex.xyz += distortiontexture
  223. // output.vertex = TransformObjectToHClip(input.vertex.xyz);
  224. // output.color = input.color;
  225. // output.normal = input.normal;
  226. // output.uv = input.uv;
  227. // return output;
  228. //}
  229.  
  230.  
  231.  
  232. // domain, copy to shader
  233. //[UNITY_domain("tri")]
  234. //Varyings domain(TessellationFactors factors, OutputPatch<ControlPoint, 3> patch, float3 barycentricCoordinates : SV_DomainLocation)
  235. //{
  236. // Attributes v;
  237. //
  238. //
  239. // Interpolate(vertex)
  240. // Interpolate(uv)
  241. // Interpolate(color)
  242. // Interpolate(normal)
  243. //
  244. // return vert(v);
  245. //}
  246.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement