MSTRINGIFY( cbuffer UpdateSoftBodiesCB : register( b0 ) { unsigned int numNodes; unsigned int startFace; unsigned int numFaces; float epsilon; }; // Node indices for each link StructuredBuffer g_triangleVertexIndexSet : register( t0 ); StructuredBuffer g_vertexPositions : register( t1 ); StructuredBuffer g_vertexTriangleCount : register( t2 ); RWStructuredBuffer g_vertexNormals : register( u0 ); RWStructuredBuffer g_vertexArea : register( u1 ); RWStructuredBuffer g_triangleNormals : register( u2 ); RWStructuredBuffer g_triangleArea : register( u3 ); [numthreads(128, 1, 1)] void ResetNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) { if( DTid.x < numNodes ) { g_vertexNormals[DTid.x] = float4(0.0f, 0.0f, 0.0f, 0.0f); g_vertexArea[DTid.x] = 0.0f; } } [numthreads(128, 1, 1)] void UpdateSoftBodiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) { int faceID = DTid.x + startFace; if( DTid.x < numFaces ) { int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ]; int nodeIndex0 = triangleIndexSet.x; int nodeIndex1 = triangleIndexSet.y; int nodeIndex2 = triangleIndexSet.z; float3 node0 = g_vertexPositions[nodeIndex0].xyz; float3 node1 = g_vertexPositions[nodeIndex1].xyz; float3 node2 = g_vertexPositions[nodeIndex2].xyz; float3 nodeNormal0 = g_vertexNormals[nodeIndex0].xyz; float3 nodeNormal1 = g_vertexNormals[nodeIndex1].xyz; float3 nodeNormal2 = g_vertexNormals[nodeIndex2].xyz; float vertexArea0 = g_vertexArea[nodeIndex0]; float vertexArea1 = g_vertexArea[nodeIndex1]; float vertexArea2 = g_vertexArea[nodeIndex2]; float3 vector0 = node1 - node0; float3 vector1 = node2 - node0; float3 faceNormal = cross(vector0.xyz, vector1.xyz); float triangleArea = length(faceNormal); nodeNormal0 = nodeNormal0 + faceNormal; nodeNormal1 = nodeNormal1 + faceNormal; nodeNormal2 = nodeNormal2 + faceNormal; vertexArea0 = vertexArea0 + triangleArea; vertexArea1 = vertexArea1 + triangleArea; vertexArea2 = vertexArea2 + triangleArea; g_triangleNormals[faceID] = float4(normalize(faceNormal), 0.f); g_vertexNormals[nodeIndex0] = float4(nodeNormal0, 0.f); g_vertexNormals[nodeIndex1] = float4(nodeNormal1, 0.f); g_vertexNormals[nodeIndex2] = float4(nodeNormal2, 0.f); g_triangleArea[faceID] = triangleArea; g_vertexArea[nodeIndex0] = vertexArea0; g_vertexArea[nodeIndex1] = vertexArea1; g_vertexArea[nodeIndex2] = vertexArea2; } } [numthreads(128, 1, 1)] void NormalizeNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) { if( DTid.x < numNodes ) { float4 normal = g_vertexNormals[DTid.x]; float area = g_vertexArea[DTid.x]; int numTriangles = g_vertexTriangleCount[DTid.x]; float vectorLength = length(normal); g_vertexNormals[DTid.x] = normalize(normal); g_vertexArea[DTid.x] = area/float(numTriangles); } } );