Permalink
Browse files

0.2 WIP candidate

Breaking changes/removals:

*NOTE: Make sure to back up all VFX graphs prior to install!* Graphs will probably break, and likely need to be fully rebuilt.

- Refactored all blocks and nodes. Instead of many different properties among the different steps, Fluid and SolverData VFX types are sent instead. This helps to reduce node clutter substantially
- Properties are no longer exposed by default. Instead, they are easily editable within the graph. Users can still expose individual properties, or entire fluids
- Simulation scale has been removed (fixed at 1.0, likely to be fully deleted later). This is no longer needed due to the VFX graph's improved handling of transforms
- Verlet integration is now the new default (see below). Physical properties for fluids will likely need to be adjusted slightly, but this change should help overall stability

Additions:

- Added additional integration methods–Stormer-Verlet and Velocity Verlet (#3). Also tweaked the Semi-implcit Euler integration to also integrate positons
- Implemented optional external force solvers, and built-in gravity (#2)
- The default FluvioFX graph now has a bunch of helpful sticky notes to help get started

Fixes:

- Particles no longer require a lifetime/alive attribute in order to be compatible with FluvioFX

Misc. changes:

- Updated solver to use the built-in mass attribute in preparation for multi-fluid simulation (#8)
- Added FluvioFX templates as a part of the install process
- Moved ReflectionHelpers to its own assembly to get rid of duplicate code
- Minor README updates
  • Loading branch information...
lmontoute committed Jan 15, 2019
1 parent 70e6d3b commit 46784b8079194b0be698ffc3ac720d5a2d466789
Showing with 8,966 additions and 4,743 deletions.
  1. +141 −42 Editor/Blocks/CalculateForces.cs
  2. +70 −81 Editor/Blocks/DensityPressure.cs
  3. +0 −58 Editor/Blocks/ExternalForces.cs
  4. +12 −0 Editor/Blocks/FluvioFXBlock.cs
  5. +15 −3 Editor/Blocks/{ClearData.cs → InitializeSolver.cs}
  6. 0 Editor/Blocks/{ClearData.cs.meta → InitializeSolver.cs.meta}
  7. +15 −36 Editor/Blocks/IntegrateParticles.cs
  8. +26 −24 Editor/Blocks/NeighborSearch.cs
  9. +12 −14 Editor/Blocks/{IndexGrid.cs → SpacePartitioning.cs}
  10. 0 Editor/Blocks/{IndexGrid.cs.meta → SpacePartitioning.cs.meta}
  11. +74 −77 Editor/Blocks/SurfaceNormal.cs
  12. +8 −0 Editor/Integrators.meta
  13. +21 −0 Editor/Integrators/IntegrationMode.cs
  14. +1 −1 Editor/{Blocks/ExternalForces.cs.meta → Integrators/IntegrationMode.cs.meta}
  15. +139 −0 Editor/Integrators/Integrator.cs
  16. +11 −0 Editor/Integrators/Integrator.cs.meta
  17. +18 −0 Editor/Integrators/SemiImplicitEuler.cs
  18. +11 −0 Editor/Integrators/SemiImplicitEuler.cs.meta
  19. +19 −0 Editor/Integrators/VelocityVerlet.cs
  20. +11 −0 Editor/Integrators/VelocityVerlet.cs.meta
  21. +30 −0 Editor/Integrators/Verlet.cs
  22. +11 −0 Editor/Integrators/Verlet.cs.meta
  23. +2 −2 Editor/Kernels/Poly6Kernel.cs
  24. +12 −1 Editor/Kernels/SmoothingKernel.cs
  25. +2 −14 Editor/MenuItems/FluvioFXMenuItems.cs
  26. +48 −54 Editor/Operators/{SolverParameters.cs → FluidToSolverData.cs}
  27. 0 Editor/Operators/{SolverParameters.cs.meta → FluidToSolverData.cs.meta}
  28. +53 −59 Editor/ShaderPostprocessor/ShaderPostprocessor.cs
  29. +7,955 −3,822 Editor/Templates/Fluid Particle System.vfx
  30. +2 −1 Editor/Thinksquirrel.FluvioFX.Editor.asmdef
  31. +8 −0 Editor/Types.meta
  32. +60 −0 Editor/Types/Fluid.cs
  33. +11 −0 Editor/Types/Fluid.cs.meta
  34. +28 −0 Editor/Types/SolverData.cs
  35. +11 −0 Editor/Types/SolverData.cs.meta
  36. +5 −1 Editor/Utils/FluvioFXAttribute.cs
  37. +6 −0 Editor/Utils/FluvioSettings.cs
  38. +11 −0 Editor/Utils/FluvioSettings.cs.meta
  39. +14 −1 Editor/Utils/PackageInfo.cs
  40. +0 −422 Editor/Utils/ReflectionHelpers.cs
  41. +0 −11 Editor/Utils/ReflectionHelpers.cs.meta
  42. +49 −9 Install/FluvioFXInstall.cs
  43. +3 −1 Install/Thinksquirrel.FluvioFX.Install.asmdef
  44. +4 −4 README.md
  45. +8 −0 ReflectionHelpers.meta
  46. +5 −2 {Install → ReflectionHelpers}/ReflectionHelpers.cs
  47. 0 {Install → ReflectionHelpers}/ReflectionHelpers.cs.meta
  48. +14 −0 ReflectionHelpers/Thinksquirrel.FluvioFX.ReflectionHelpers.asmdef
  49. +7 −0 ReflectionHelpers/Thinksquirrel.FluvioFX.ReflectionHelpers.asmdef.meta
  50. +3 −3 Shaders/FluvioCompute.cginc
@@ -8,87 +8,186 @@
using UnityEngine.Experimental.VFX;

namespace Thinksquirrel.FluvioFX.Editor.Blocks
{
[VFXInfo(category = "FluvioFX")]
class CalculateForces : FluvioFXBlock
{
[VFXInfo(category = "FluvioFX/Solver")]
class CalculateForces : FluvioFXBlock
{
[VFXSetting]
public bool SurfaceTension = true;
[VFXSetting]
public bool Turbulence = true;
[VFXSetting]
public bool Gravity = true;
[VFXSetting]
public bool BuoyancyForce = true;

public override string name
{
public override string name
get
{
get
{
return "Calculate Forces";
}
return "Calculate Forces";
}
public override IEnumerable<VFXAttributeInfo> attributes
}
public override IEnumerable<VFXAttributeInfo> attributes
{
get
{
get
yield return new VFXAttributeInfo(VFXAttribute.Position, VFXAttributeMode.Read);
if (hasLifetime)
{
yield return new VFXAttributeInfo(VFXAttribute.Alive, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(VFXAttribute.Position, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(VFXAttribute.Velocity, VFXAttributeMode.Read);
// yield return new VFXAttributeInfo(FluvioFXAttribute.NeighborCount, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(FluvioFXAttribute.DensityPressure, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(FluvioFXAttribute.Force, VFXAttributeMode.ReadWrite);
}
yield return new VFXAttributeInfo(VFXAttribute.Velocity, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(VFXAttribute.Mass, VFXAttributeMode.Read);
// yield return new VFXAttributeInfo(FluvioFXAttribute.NeighborCount, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(FluvioFXAttribute.DensityPressure, VFXAttributeMode.Read);
if (SurfaceTension)
{
yield return new VFXAttributeInfo(FluvioFXAttribute.Normal, VFXAttributeMode.Read);
}
if (Turbulence)
{
yield return new VFXAttributeInfo(
FluvioFXAttribute.VorticityTurbulence,
VFXAttributeMode.ReadWrite);
}
yield return new VFXAttributeInfo(FluvioFXAttribute.Force, VFXAttributeMode.ReadWrite);
}
#pragma warning disable 649
public class InputProperties
}

private IEnumerable<string> defines
{
get
{
[Tooltip("Controls the mass of each fluid particle.")]
public float ParticleMass = 7.625f;
[Tooltip("Controls the artificial viscosity force of the fluid.")]
public float Viscosity = 2.0f;
public Vector4 KernelSize = Vector4.one;
public Vector4 KernelFactors = Vector4.one;
public Texture2D FluvioSolverData;
public Vector2 FluvioSolverDataSize;
if (SurfaceTension)
{
yield return "#define FLUVIO_SURFACE_TENSION_ENABLED 1";
}

if (Turbulence)
{
yield return "#define FLUVIO_TURBULENCE_ENABLED 1";
}

if (Gravity)
{
yield return "#define FLUVIO_GRAVITY_ENABLED 1";
}

if (BuoyancyForce)
{
yield return "#define FLUVIO_BUOYANCY_FORCE_ENABLED 1";
}
}
#pragma warning restore 649
public override string source => $@"
float3 dist, density, f;
}

public override string source => $@"
{string.Join("\n", defines)}
float3 dist, f, invNeighborDensity;
float scalar;
#ifdef FLUVIO_INDEX_GRID
uint neighborIndex;
for (uint j = 0; j < neighborCount; ++j)
{{
neighborIndex = GetNeighborIndex(FluvioSolverData, FluvioSolverDataSize, index, j);
neighborIndex = GetNeighborIndex(solverData_Tex, solverData_TexSize, index, j);
#else
float distLenSq;
for (uint neighborIndex = 0; neighborIndex < nbMax; ++neighborIndex)
{{
if (index == neighborIndex) continue;
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Alive, "neighborAlive", "neighborIndex")}
if (!neighborAlive) continue;
{(hasLifetime ? FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Alive, "neighborAlive", "neighborIndex") : "")}
{(hasLifetime ? "if (!neighborAlive) continue;" : "")}
#endif

{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Position, "neighborPosition", "neighborIndex")}
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Mass, "neighborMass", "neighborIndex")}
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Velocity, "neighborVelocity", "neighborIndex")}
{FluvioFXAttribute.GetLoadAttributeCode(this, FluvioFXAttribute.DensityPressure, "neighborDensityPressure", "neighborIndex")}
{FluvioFXAttribute.GetLoadAttributeCode(
this,
FluvioFXAttribute.DensityPressure,
"neighborDensityPressure",
"neighborIndex")}

dist = position - neighborPosition;
#ifndef FLUVIO_INDEX_GRID
distLenSq = dot(dist, dist);
if (distLenSq >= KernelSize.y) continue;
if (distLenSq >= solverData_KernelSize.y) continue;
#endif

density = neighborDensityPressure.x;
invNeighborDensity = 1.0f / neighborDensityPressure.x;

// Pressure term
scalar = ParticleMass * (densityPressure.z + neighborDensityPressure.z) / (max(density, FLUVIO_EPSILON) * 2.0f);
f = SpikyCalculateGradient(dist, KernelFactors.y, KernelSize.x);
scalar = neighborMass
* (densityPressure.z + neighborDensityPressure.z) / (neighborDensityPressure.x * 2.0f);
f = SpikyCalculateGradient(dist, solverData_KernelFactors.y, solverData_KernelSize.x);
f *= scalar;

force -= f;

// Viscosity term
scalar = ParticleMass
* ViscosityCalculateLaplacian(dist, KernelFactors.z, KernelSize.z, KernelSize.x)
* (1.0f / max(density, FLUVIO_EPSILON));
scalar = neighborMass
* ViscosityCalculateLaplacian(
dist,
solverData_KernelFactors.z,
solverData_KernelSize.z,
solverData_KernelSize.x)
* invNeighborDensity;

f = (neighborVelocity - velocity) / KernelSize.w;
f *= scalar * Viscosity;
f = (neighborVelocity - velocity) / solverData_KernelSize.w;
f *= scalar * solverData_Fluid_Viscosity;

force += f;
}}";

#ifdef FLUVIO_SURFACE_TENSION_ENABLED
// Surface tension term (external)
if (normal.w > FLUVIO_PI && normal.w < FLUVIO_PI * 2.0f)
{{
scalar = neighborMass
* Poly6CalculateLaplacian(dist, solverData_KernelFactors.x, solverData_KernelSize.y)
* solverData_Fluid_SurfaceTension
* invNeighborDensity;

f = normal.xyz * scalar;

force -= f;
}}
#endif

#ifdef FLUVIO_TURBULENCE_ENABLED
// Turbulence term (external)
{(Turbulence
? FluvioFXAttribute.GetLoadAttributeCode(
this,
FluvioFXAttribute.VorticityTurbulence,
"neighborVorticityTurbulence",
"neighborIndex")
: "")}
if (vorticityTurbulence.w >= solverData_Fluid_TurbulenceProbability && neighborVorticityTurbulence.w < solverData_Fluid_TurbulenceProbability)
{{
scalar = neighborMass
* ViscosityCalculateLaplacian(
dist,
solverData_KernelFactors.z,
solverData_KernelSize.z,
solverData_KernelSize.x)
* invNeighborDensity;

vorticityTurbulence = scalar * (neighborVorticityTurbulence - vorticityTurbulence);
f = clamp_len(FLUVIO_TURBULENCE_CONSTANT * cross(dist, vorticityTurbulence.xyz), FLUVIO_MAX_SQR_VELOCITY_CHANGE * mass);

force += f;
}}
#endif
}}

#ifdef FLUVIO_GRAVITY_ENABLED
// Gravity term (external)
force += solverData_Gravity;
#endif

#ifdef FLUVIO_BUOYANCY_FORCE_ENABLED
// Buoyancy term (external)
force += solverData_Gravity * solverData_Fluid_BuoyancyCoefficient * (densityPressure.x - solverData_Fluid_Density);
#endif";
}
}
@@ -1,81 +1,70 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.VFX;
using UnityEngine;
using UnityEngine.Experimental.VFX;

namespace Thinksquirrel.FluvioFX.Editor.Blocks
{
[VFXInfo(category = "FluvioFX")]
class DensityPressure : FluvioFXBlock
{
public override string name
{
get
{
return "Density/Pressure";
}
}
public override IEnumerable<VFXAttributeInfo> attributes
{
get
{
yield return new VFXAttributeInfo(VFXAttribute.Alive, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(VFXAttribute.Position, VFXAttributeMode.Read);
// yield return new VFXAttributeInfo(FluvioFXAttribute.NeighborCount, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(FluvioFXAttribute.DensityPressure, VFXAttributeMode.Write);
}
}
#pragma warning disable 649
public class InputProperties
{
[Tooltip("Controls the mass of each fluid particle.")]
public float ParticleMass = 7.625f;
[Tooltip("Controls the overall density of the fluid.")]
public float Density = 998.29f;
[Tooltip("Controls the minimum density of any fluid particle. This can be used to help stabilize a low-viscosity fluid.")]
public float MinimumDensity = 499.145f;
[Tooltip("Controls the gas constant of the fluid, which in turn affects the pressure forces applied to particles.")]
public float GasConstant = 0.01f;
public Vector4 KernelSize = Vector4.one;
public Vector4 KernelFactors = Vector4.one;
public Texture2D FluvioSolverData;
public Vector2 FluvioSolverDataSize;
}
#pragma warning restore 649
public override string source => $@"
float3 dist;
float density = 0;
#ifdef FLUVIO_INDEX_GRID
uint neighborIndex;
for (uint j = 0; j < neighborCount; ++j)
{{
neighborIndex = GetNeighborIndex(FluvioSolverData, FluvioSolverDataSize, index, j);
#else
float distLenSq;
for (uint neighborIndex = 0; neighborIndex < nbMax; ++neighborIndex)
{{
if (index == neighborIndex) continue;
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Alive, "neighborAlive", "neighborIndex")}
if (!neighborAlive) continue;
#endif
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Position, "neighborPosition", "neighborIndex")}
dist = position - neighborPosition;
#ifndef FLUVIO_INDEX_GRID
distLenSq = dot(dist, dist);
if (distLenSq >= KernelSize.y) continue;
#endif
density += ParticleMass * Poly6Calculate(dist, KernelFactors.x, KernelSize.y);
}}
// Write to density/pressure texture
density = max(density, MinimumDensity);
densityPressure = float4(density, density, GasConstant * (density - Density), 0);";
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.VFX;
using UnityEngine;
using UnityEngine.Experimental.VFX;

namespace Thinksquirrel.FluvioFX.Editor.Blocks
{
[VFXInfo(category = "FluvioFX/Solver")]
class DensityPressure : FluvioFXBlock
{
public override string name
{
get
{
return "Calculate Density and Pressure";
}
}

public override IEnumerable<VFXAttributeInfo> attributes
{
get
{
yield return new VFXAttributeInfo(VFXAttribute.Position, VFXAttributeMode.Read);
if (hasLifetime)
{
yield return new VFXAttributeInfo(VFXAttribute.Alive, VFXAttributeMode.Read);
}
yield return new VFXAttributeInfo(VFXAttribute.Mass, VFXAttributeMode.Read);
// yield return new VFXAttributeInfo(FluvioFXAttribute.NeighborCount, VFXAttributeMode.Read);
yield return new VFXAttributeInfo(FluvioFXAttribute.DensityPressure, VFXAttributeMode.Write);
}
}
public override string source => $@"
float3 dist;
float density = 0;
#ifdef FLUVIO_INDEX_GRID
uint neighborIndex;
for (uint j = 0; j < neighborCount; ++j)
{{
neighborIndex = GetNeighborIndex(solverData_Tex, solverData_TexSize, index, j);
#else
float distLenSq;
for (uint neighborIndex = 0; neighborIndex < nbMax; ++neighborIndex)
{{
if (index == neighborIndex) continue;
{(hasLifetime ? FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Alive, "neighborAlive", "neighborIndex") : "")}
{(hasLifetime ? "if (!neighborAlive) continue;" : "")}
#endif
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Position, "neighborPosition", "neighborIndex")}
{FluvioFXAttribute.GetLoadAttributeCode(this, VFXAttribute.Mass, "neighborMass", "neighborIndex")}
dist = position - neighborPosition;
#ifndef FLUVIO_INDEX_GRID
distLenSq = dot(dist, dist);
if (distLenSq >= solverData_KernelSize.y) continue;
#endif
density += neighborMass * Poly6Calculate(dist, solverData_KernelFactors.x, solverData_KernelSize.y);
}}
// Write to density/pressure texture
density = max(density, solverData_Fluid_MinimumDensity);
densityPressure = float4(density, density, solverData_Fluid_GasConstant * (density - solverData_Fluid_Density), 0);";
}
}
Oops, something went wrong.

0 comments on commit 46784b8

Please sign in to comment.