FluidCS11_BuildGridIndicesCS.hlsl 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
  2. // CHECK: threadId
  3. // CHECK: bufferLoad
  4. // CHECK: bufferStore
  5. //--------------------------------------------------------------------------------------
  6. // File: FluidCS11.hlsl
  7. //
  8. // Copyright (c) Microsoft Corporation. All rights reserved.
  9. //--------------------------------------------------------------------------------------
  10. //--------------------------------------------------------------------------------------
  11. // Smoothed Particle Hydrodynamics Algorithm Based Upon:
  12. // Particle-Based Fluid Simulation for Interactive Applications
  13. // Matthias Müller
  14. //--------------------------------------------------------------------------------------
  15. //--------------------------------------------------------------------------------------
  16. // Optimized Grid Algorithm Based Upon:
  17. // Broad-Phase Collision Detection with CUDA
  18. // Scott Le Grand
  19. //--------------------------------------------------------------------------------------
  20. struct Particle
  21. {
  22. float2 position;
  23. float2 velocity;
  24. };
  25. struct ParticleForces
  26. {
  27. float2 acceleration;
  28. };
  29. struct ParticleDensity
  30. {
  31. float density;
  32. };
  33. cbuffer cbSimulationConstants : register( b0 )
  34. {
  35. uint g_iNumParticles;
  36. float g_fTimeStep;
  37. float g_fSmoothlen;
  38. float g_fPressureStiffness;
  39. float g_fRestDensity;
  40. float g_fDensityCoef;
  41. float g_fGradPressureCoef;
  42. float g_fLapViscosityCoef;
  43. float g_fWallStiffness;
  44. float4 g_vGravity;
  45. float4 g_vGridDim;
  46. float3 g_vPlanes[4];
  47. };
  48. //--------------------------------------------------------------------------------------
  49. // Fluid Simulation
  50. //--------------------------------------------------------------------------------------
  51. #define SIMULATION_BLOCK_SIZE 256
  52. //--------------------------------------------------------------------------------------
  53. // Structured Buffers
  54. //--------------------------------------------------------------------------------------
  55. RWStructuredBuffer<Particle> ParticlesRW : register( u0 );
  56. StructuredBuffer<Particle> ParticlesRO : register( t0 );
  57. RWStructuredBuffer<ParticleDensity> ParticlesDensityRW : register( u0 );
  58. StructuredBuffer<ParticleDensity> ParticlesDensityRO : register( t1 );
  59. RWStructuredBuffer<ParticleForces> ParticlesForcesRW : register( u0 );
  60. StructuredBuffer<ParticleForces> ParticlesForcesRO : register( t2 );
  61. RWStructuredBuffer<unsigned int> GridRW : register( u0 );
  62. StructuredBuffer<unsigned int> GridRO : register( t3 );
  63. RWStructuredBuffer<uint2> GridIndicesRW : register( u0 );
  64. StructuredBuffer<uint2> GridIndicesRO : register( t4 );
  65. //--------------------------------------------------------------------------------------
  66. // Grid Construction
  67. //--------------------------------------------------------------------------------------
  68. // For simplicity, this sample uses a 16-bit hash based on the grid cell and
  69. // a 16-bit particle ID to keep track of the particles while sorting
  70. // This imposes a limitation of 64K particles and 256x256 grid work
  71. // You could extended the implementation to support large scenarios by using a uint2
  72. float2 GridCalculateCell(float2 position)
  73. {
  74. return clamp(position * g_vGridDim.xy + g_vGridDim.zw, float2(0, 0), float2(255, 255));
  75. }
  76. unsigned int GridConstuctKey(uint2 xy)
  77. {
  78. // Bit pack [-----UNUSED-----][----Y---][----X---]
  79. // 16-bit 8-bit 8-bit
  80. return dot(xy.yx, uint2(256, 1));
  81. }
  82. unsigned int GridConstuctKeyValuePair(uint2 xy, uint value)
  83. {
  84. // Bit pack [----Y---][----X---][-----VALUE------]
  85. // 8-bit 8-bit 16-bit
  86. return dot(uint3(xy.yx, value), uint3(256*256*256, 256*256, 1));
  87. }
  88. unsigned int GridGetKey(unsigned int keyvaluepair)
  89. {
  90. return (keyvaluepair >> 16);
  91. }
  92. unsigned int GridGetValue(unsigned int keyvaluepair)
  93. {
  94. return (keyvaluepair & 0xFFFF);
  95. }
  96. [numthreads(SIMULATION_BLOCK_SIZE, 1, 1)]
  97. void main( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
  98. {
  99. const unsigned int G_ID = DTid.x; // Grid ID to operate on
  100. unsigned int G_ID_PREV = (G_ID == 0)? g_iNumParticles : G_ID; G_ID_PREV--;
  101. unsigned int G_ID_NEXT = G_ID + 1; if (G_ID_NEXT == g_iNumParticles) { G_ID_NEXT = 0; }
  102. unsigned int cell = GridGetKey( GridRO[G_ID] );
  103. unsigned int cell_prev = GridGetKey( GridRO[G_ID_PREV] );
  104. unsigned int cell_next = GridGetKey( GridRO[G_ID_NEXT] );
  105. if (cell != cell_prev)
  106. {
  107. // I'm the start of a cell
  108. GridIndicesRW[cell].x = G_ID;
  109. }
  110. if (cell != cell_next)
  111. {
  112. // I'm the end of a cell
  113. GridIndicesRW[cell].y = G_ID + 1;
  114. }
  115. }