Advertisement
Zgragselus

Use the GeForce ... Luke

Apr 21st, 2024
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.68 KB | None | 0 0
  1. #pragma kernel Main
  2.  
  3. struct Sample
  4. {
  5. float4 vertex;
  6. };
  7.  
  8. struct Vertex
  9. {
  10. float3 Position;
  11. float3 Normal;
  12. float2 TexCoord;
  13. };
  14.  
  15. StructuredBuffer<Sample> _Source;
  16. StructuredBuffer<float2> _Segments;
  17. RWStructuredBuffer<Vertex> _VertexBuffer;
  18. RWStructuredBuffer<uint> _IndexBuffer;
  19. RWStructuredBuffer<float4> _Debug;
  20. uint _NumSamples;
  21. uint _NumSegments;
  22. float _Thickness;
  23. float _Strain;
  24. float4 _UVScale;
  25.  
  26. #define QUATERNION_IDENTITY float4(0.0f, 0.0f, 0.0f, 1.0f);
  27. #define PI 3.14159265359f
  28.  
  29. float4 QuaternionMultiply(float4 q1, float4 q2)
  30. {
  31. return float4(
  32. q2.xyz * q1.w + q1.xyz * q2.w + cross(q1.xyz, q2.xyz),
  33. q1.w * q2.w - dot(q1.xyz, q2.xyz)
  34. );
  35. }
  36.  
  37. float3 QuaternionRotateVector(float3 v, float4 r)
  38. {
  39. float4 r_c = r * float4(-1.0f, -1.0f, -1.0f, 1.0f);
  40. return QuaternionMultiply(r, QuaternionMultiply(float4(v, 0.0f), r_c)).xyz;
  41.  
  42. }
  43.  
  44. float4 QuaternionRotateAngleAxis(float angle, float3 axis)
  45. {
  46. float sn = sin(angle * 0.5f);
  47. float cs = cos(angle * 0.5f);
  48. return float4(axis * sn, cs);
  49. }
  50.  
  51. float4 QuaternionFromTo(float3 from, float3 to)
  52. {
  53. float4 q;
  54. float d = dot(from, to);
  55. if (d < -0.995f)
  56. {
  57. float3 right = float3(1.0f, 0.0f, 0.0f);
  58. float3 up = float3(0.0f, 1.0f, 0.0f);
  59. float3 tmp = cross(up, from);
  60. if (length(tmp) < 0.0001f)
  61. {
  62. tmp = cross(right, from);
  63. }
  64. tmp = normalize(tmp);
  65. q = QuaternionRotateAngleAxis(PI, tmp);
  66. }
  67. else if (d > 0.995f)
  68. {
  69. q = QUATERNION_IDENTITY;
  70. }
  71. else
  72. {
  73. q.xyz = cross(from, to);
  74. q.w = 1.0f + d;
  75. q = normalize(q);
  76. }
  77.  
  78. return q;
  79. }
  80.  
  81. groupshared float3 _Origin[32];
  82. groupshared float3 _Tangent[32];
  83. groupshared float3 _Normal[32];
  84. groupshared float3 _Binormal[32];
  85. groupshared float _VCoord[32];
  86.  
  87. [numthreads(32,16,1)]
  88. void Main(uint3 id : SV_DispatchThreadID, uint3 gid : SV_GroupThreadID)
  89. {
  90. // Process only the valid samples
  91. if (id.x < _NumSamples)
  92. {
  93. if (id.y == 0)
  94. {
  95. // Default basis
  96. float3 origin = float3(0.0f, 0.0f, 0.0f);
  97. float3 tangent = float3(0.0f, 0.0f, 1.0f);
  98. float3 normal = float3(0.0f, 1.0f, 0.0f);
  99. float3 binormal = float3(-1.0f, 0.0f, 0.0f);
  100.  
  101. // Build frame basis for sample
  102. int next = min(id.x + 1, _NumSamples - 1);
  103. int prev = max(int(id.x) - 1, 0);
  104.  
  105. float3 nextVertex = (_Source[next].vertex.xyz - _Source[id.x].vertex.xyz);
  106. float3 prevVertex = (_Source[id.x].vertex.xyz - _Source[prev].vertex.xyz);
  107. float3 newTangent = normalize(nextVertex + prevVertex);
  108.  
  109. // Compute rotated basis and store in groupshared memory
  110. float4 rotation = QuaternionFromTo(tangent, newTangent);
  111. _Normal[gid.x] = QuaternionRotateVector(normal, rotation);
  112. _Binormal[gid.x] = QuaternionRotateVector(binormal, rotation);
  113. _Tangent[gid.x] = newTangent;
  114.  
  115. _Origin[gid.x] = _Source[id.x].vertex.xyz;
  116.  
  117. _VCoord[gid.x] = _UVScale.w + _UVScale.y * (_Source[id.x].vertex.w / _Strain);
  118.  
  119. //_Debug[id.x] = float4(rotation.x, rotation.y, rotation.z, rotation.w);
  120. _Debug[id.x] = float4(_VCoord[gid.x], 0.0f, 0.0f, 0.0f);
  121. }
  122. }
  123.  
  124. GroupMemoryBarrierWithGroupSync();
  125.  
  126. uint VerticesPerSection = _NumSegments + 1;
  127.  
  128. if (id.x < _NumSamples && id.y < VerticesPerSection)
  129. {
  130. float3 norm = (_Segments[gid.y].x * _Normal[gid.x] + _Segments[gid.y].y * _Binormal[gid.x]) * _Thickness;
  131.  
  132. _VertexBuffer[id.x * VerticesPerSection + id.y].Position = _Origin[gid.x] + norm;
  133. _VertexBuffer[id.x * VerticesPerSection + id.y].Normal = norm;
  134. _VertexBuffer[id.x * VerticesPerSection + id.y].TexCoord = float2(float(gid.y) / float(_NumSegments) * _UVScale.x, _VCoord[gid.x]);
  135.  
  136. }
  137.  
  138. if (id.x < _NumSamples - 1 && id.y < _NumSegments)
  139. {
  140. _IndexBuffer[(id.x * _NumSegments + id.y) * 6 + 0] = id.x * VerticesPerSection + id.y;
  141. _IndexBuffer[(id.x * _NumSegments + id.y) * 6 + 1] = id.x * VerticesPerSection + id.y + 1;
  142. _IndexBuffer[(id.x * _NumSegments + id.y) * 6 + 2] = (id.x + 1) * VerticesPerSection + id.y;
  143.  
  144. _IndexBuffer[(id.x * _NumSegments + id.y) * 6 + 3] = id.x * VerticesPerSection + id.y + 1;
  145. _IndexBuffer[(id.x * _NumSegments + id.y) * 6 + 4] = (id.x + 1) * VerticesPerSection + id.y + 1;
  146. _IndexBuffer[(id.x * _NumSegments + id.y) * 6 + 5] = (id.x + 1) * VerticesPerSection + id.y;
  147. }
  148. }
  149.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement