UE4 SPH实现
实现方法
关于使用UE的Niagara粒子系统进行SPH水模拟参考资料
链接: 基于Niagara的SPH可交互流体特效
链接: 【教程】 UE/Niagara SPH水模拟—P1粒子
链接: [UnrealOpenDay2020]幻觉的艺术 - Niagara模拟框架一览
链接: SPH算法简介(三): 光滑核函数
目前查到的资料对部分代码API解释相对较少,资料也不易搜索,因此此处记录一下github上源代码实现,方便理解
NeighborGrid3D
- SimulationToUnit
将坐标归一化[0,1],实质为一个向量与归一化矩阵的乘积
void {FunctionName}(float3 In_Simulation, float4x4 In_SimulationToUnitTransform, out float3 Out_Unit)
{
Out_Unit = mul(float4(In_Simulation, 1.0),In_SimulationToUnitTransform).xyz;
}
- UnitToIndex
输入归一化坐标,返回坐标所在格子的[x,y,z]坐标
void {FunctionName}(float3 In_Unit, out int Out_IndexX, out int Out_IndexY, out int Out_IndexZ)
{
int3 Out_IndexTmp = round(In_Unit * {NumCellsName} - .5);
Out_IndexX = Out_IndexTmp.x;
Out_IndexY = Out_IndexTmp.y;
Out_IndexZ = Out_IndexTmp.z;
}
- GetNumCells
返回x,y,z方向的格子数 - MaxNeighborsPerCell(out int Out_MaxNeighborsPerCell)
返回每个格子最大粒子数量 - IndexToLinear(int In_IndexX, int In_IndexY, int In_IndexZ, int In_Neighbor, out int Out_Linear)
将格子的[x,y,z]位置坐标转化为线性位置坐标
void {FunctionName}(int In_IndexX, int In_IndexY, int In_IndexZ, out int Out_Linear)
{
Out_Linear = In_IndexX + In_IndexY * {NumCellsName}.x + In_IndexZ * {NumCellsName}.x * {NumCellsName}.y;
}
- SetParticleNeighborCount(int In_Index, int In_Increment, out int PreviousNeighborCount)
输入格子的线性位置坐标In_Index,返回之前的粒子数,并且此格子粒子数+=In_Increment - NeighborGridIndexToLinear(int In_IndexX, int In_IndexY, int In_IndexZ, int In_Neighbor, out int Out_Linear);
输入格子的Index,格子中当前粒子的次序,返回当前粒子的Index
void {FunctionName}(int In_IndexX, int In_IndexY, int In_IndexZ, int In_Neighbor, out int Out_Linear)
{
Out_Linear = In_Neighbor + In_IndexX * {MaxNeighborsPerCellName}
+ In_IndexY * {MaxNeighborsPerCellName}*{NumCellsName}.x
+ In_IndexZ * {MaxNeighborsPerCellName}*{NumCellsName}.x*{NumCellsName}.y;
}
- SetParticleNeighbor(int In_Index, int In_ParticleNeighborIndex, out int Out_Ignore)
根据粒子的Index设置粒子ID
void {FunctionName}(int In_Index, int In_ParticleNeighborIndex, out int Out_Ignore)
{
{OutputParticleNeighbors}[In_Index] = In_ParticleNeighborIndex;
Out_Ignore = 0;
}