GpuParticlesGass.ankiprog 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. // This shader does a particle simulation for gasses
  6. #pragma anki mutator ANKI_WAVE_SIZE 16 32 64
  7. #pragma anki technique comp
  8. #include <AnKi/Shaders/GpuParticlesCommon.hlsl>
  9. // clang-format off
  10. #pragma anki struct AnKiParticleEmitterProperties
  11. # pragma anki member F32 m_minParticleLife 1.0
  12. # pragma anki member F32 m_maxParticleLife 1.0
  13. # pragma anki member Vec3 m_minGravityDirection 0.0 -1.0 0.0
  14. # pragma anki member Vec3 m_maxGravityDirection 0.0 -1.0 0.0
  15. # pragma anki member F32 m_minGravityMagnitude 9.8
  16. # pragma anki member F32 m_maxGravityMagnitude 9.8
  17. # pragma anki member F32 m_minMass 1.0
  18. # pragma anki member F32 m_maxMass 1.0
  19. # pragma anki member F32 m_minInitialSize 1.0
  20. # pragma anki member F32 m_maxInitialSize 1.0
  21. # pragma anki member F32 m_minFinalSize 1.0
  22. # pragma anki member F32 m_maxFinalSize 1.0
  23. # pragma anki member F32 m_minInitialAlpha 1.0
  24. # pragma anki member F32 m_maxInitialAlpha 1.0
  25. # pragma anki member F32 m_minFinalAlpha 1.0
  26. # pragma anki member F32 m_maxFinalAlpha 1.0
  27. # pragma anki member Vec3 m_minStartingPosition 0.0 0.0 0.0
  28. # pragma anki member Vec3 m_maxStartingPosition 0.0 0.0 0.0
  29. #pragma anki struct_end
  30. // clang-format on
  31. #define GRAVITY_PROP ParticleProperty::kUserDefined0
  32. #define ALPHA_PROP ParticleProperty::kUserDefined1 // Initial alpha, final alpha, current alpha
  33. #define SIZE_PROP ParticleProperty::kUserDefined2 // Initial size, final size
  34. struct ParticleInterface
  35. {
  36. AnKiParticleEmitterProperties m_props;
  37. void initAnKiParticleEmitterProperties(GpuSceneParticleEmitter2 emitter)
  38. {
  39. const AnKiParticleEmitterProperties props = loadAnKiParticleEmitterProperties(g_gpuScene, emitter.m_particleEmitterPropertiesOffset);
  40. m_props = props;
  41. }
  42. void initializeParticle(GpuSceneParticleEmitter2 emitter, Mat3x4 emitterTrf, Bool makeAlive, out Vec3 particlePosition, out F32 particleScale)
  43. {
  44. const F32 m = getRandomRange(m_props.m_minMass, m_props.m_maxMass);
  45. Vec3 g = normalize(getRandomRange(m_props.m_minGravityDirection, m_props.m_maxGravityDirection));
  46. g = mul(emitterTrf, Vec4(g, 0.0));
  47. g = normalize(g); // Because the emitter's trf might have scale
  48. g *= getRandomRange(m_props.m_minGravityMagnitude, m_props.m_maxGravityMagnitude);
  49. const F32 dt = 1.0 / 60;
  50. const Vec3 v = g * dt;
  51. const Vec3 x = getRandomRange(m_props.m_minStartingPosition, m_props.m_maxStartingPosition) + emitterTrf.getTranslationPart().xyz;
  52. // Store
  53. writeProp(emitter, ParticleProperty::kVelocity, v);
  54. writeProp(emitter, ParticleProperty::kLifeFactor, makeAlive ? 0.0 : 1.0);
  55. writeProp(emitter, ParticleProperty::kMaxLife, getRandomRange(m_props.m_minParticleLife, m_props.m_maxParticleLife));
  56. writeProp(emitter, ParticleProperty::kPosition, x);
  57. writeProp(emitter, ParticleProperty::kPreviousPosition, x);
  58. writeProp(emitter, ParticleProperty::kMass, m);
  59. writeProp(emitter, GRAVITY_PROP, Vec4(g, 0.0));
  60. const F32 initialAlpha = getRandomRange(m_props.m_minInitialAlpha, m_props.m_maxInitialAlpha);
  61. const F32 finalAlpha = getRandomRange(m_props.m_minFinalAlpha, m_props.m_maxFinalAlpha);
  62. writeProp(emitter, ALPHA_PROP, Vec4(initialAlpha, finalAlpha, initialAlpha, 0.0));
  63. const F32 initialSize = getRandomRange(m_props.m_minInitialSize, m_props.m_maxInitialSize);
  64. const F32 finalSize = getRandomRange(m_props.m_minFinalSize, m_props.m_maxFinalSize);
  65. writeProp(emitter, SIZE_PROP, Vec4(initialSize, finalSize, 0.0, 0.0));
  66. writeProp(emitter, ParticleProperty::kScale, Vec3(initialSize, initialSize, initialSize));
  67. particlePosition = x;
  68. particleScale = initialSize;
  69. }
  70. void simulateParticle(GpuSceneParticleEmitter2 emitter, F32 lifeFactor, out Vec3 particlePosition, out F32 particleScale)
  71. {
  72. const F32 m = readProp<F32>(emitter, ParticleProperty::kMass);
  73. const Vec3 g = readProp<Vec4>(emitter, GRAVITY_PROP).xyz;
  74. const Vec3 F = m * g;
  75. Vec3 v = readProp<Vec3>(emitter, ParticleProperty::kVelocity);
  76. Vec3 x = readProp<Vec3>(emitter, ParticleProperty::kPosition);
  77. const Vec3 prevX = x;
  78. SimulationArgs args;
  79. args.init();
  80. args.m_checkCollision = false;
  81. simulatePhysics(F, m, g_consts.m_dt, v, x, args);
  82. // Write
  83. writeProp(emitter, ParticleProperty::kVelocity, v);
  84. const F32 maxLife = readProp<F32>(emitter, ParticleProperty::kMaxLife);
  85. writeProp(emitter, ParticleProperty::kLifeFactor, lifeFactor + g_consts.m_dt / maxLife);
  86. writeProp(emitter, ParticleProperty::kPosition, x);
  87. writeProp(emitter, ParticleProperty::kPreviousPosition, prevX);
  88. const Vec4 sizeProp = readProp<Vec4>(emitter, SIZE_PROP);
  89. const F32 scale = lerp(sizeProp.x, sizeProp.y, lifeFactor);
  90. writeProp(emitter, ParticleProperty::kScale, Vec3(scale, scale, scale));
  91. const Vec4 alphaProp = readProp<Vec4>(emitter, ALPHA_PROP);
  92. const F32 alpha = lerp(alphaProp.x, alphaProp.y, lifeFactor);
  93. writeProp(emitter, ALPHA_PROP, Vec4(alphaProp.x, alphaProp.y, alpha, 0.0));
  94. particlePosition = x;
  95. particleScale = scale;
  96. }
  97. };
  98. [numthreads(ANKI_WAVE_SIZE, 1, 1)] void main(COMPUTE_ARGS)
  99. {
  100. ParticleInterface iface;
  101. particleMain(svDispatchThreadId.x, svGroupIndex, iface);
  102. }