FluidCS11_DensityCS_Simple.hlsl 5.2 KB

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