Add Collision (Global SDF) particle module

This commit is contained in:
Wojciech Figat
2022-03-28 13:39:20 +02:00
parent bcc4a2c0a4
commit 3a9edabd03
7 changed files with 106 additions and 47 deletions

View File

@@ -1475,6 +1475,12 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode*
// Not supported
break;
}
// Collision (Global SDF)
case 336:
{
// Not supported
break;
}
#undef COLLISION_BEGIN
#undef COLLISION_INPUTS_FETCH

View File

@@ -616,7 +616,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
auto position = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::ReadWrite);
auto param = findOrAddGlobalSDF();
String wsPos = position.Value;
if (((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local)
if (IsLocalSimulationSpace())
wsPos = String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), wsPos);
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
_writer.Write(
@@ -666,13 +666,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
case 330:
{
COLLISION_BEGIN();
auto planePositionBox = node->GetBox(5);
auto planeNormalBox = node->GetBox(6);
const Value planePosition = GetValue(planePositionBox, 8).AsVector3();
const Value planeNormal = GetValue(planeNormalBox, 9).AsVector3();
const Value planePosition = GetValue(node->GetBox(5), 8).AsVector3();
const Value planeNormal = GetValue(node->GetBox(6), 9).AsVector3();
_writer.Write(
TEXT(
" {{\n"
@@ -699,13 +694,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
case 331:
{
COLLISION_BEGIN();
auto spherePositionBox = node->GetBox(5);
auto sphereRadiusBox = node->GetBox(6);
const Value spherePosition = GetValue(spherePositionBox, 8).AsVector3();
const Value sphereRadius = GetValue(sphereRadiusBox, 9).AsFloat();
const Value spherePosition = GetValue(node->GetBox(5), 8).AsVector3();
const Value sphereRadius = GetValue(node->GetBox(6), 9).AsFloat();
_writer.Write(
TEXT(
" {{\n"
@@ -735,13 +725,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
case 332:
{
COLLISION_BEGIN();
auto boxPositionBox = node->GetBox(5);
auto boxSizeBox = node->GetBox(6);
const Value boxPosition = GetValue(boxPositionBox, 8).AsVector3();
const Value boxSize = GetValue(boxSizeBox, 9).AsVector3();
const Value boxPosition = GetValue(node->GetBox(5), 8).AsVector3();
const Value boxSize = GetValue(node->GetBox(6), 9).AsVector3();
_writer.Write(
TEXT(
" {{\n"
@@ -786,15 +771,9 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
case 333:
{
COLLISION_BEGIN();
auto cylinderPositionBox = node->GetBox(5);
auto cylinderHeightBox = node->GetBox(6);
auto cylinderRadiusBox = node->GetBox(7);
const Value cylinderPosition = GetValue(cylinderPositionBox, 8).AsVector3();
const Value cylinderHeight = GetValue(cylinderHeightBox, 9).AsFloat();
const Value cylinderRadius = GetValue(cylinderRadiusBox, 10).AsFloat();
const Value cylinderPosition = GetValue(node->GetBox(5), 8).AsVector3();
const Value cylinderHeight = GetValue(node->GetBox(6), 9).AsFloat();
const Value cylinderRadius = GetValue(node->GetBox(7), 10).AsFloat();
_writer.Write(
TEXT(
" {{\n"
@@ -842,13 +821,8 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
case 334:
{
COLLISION_BEGIN();
auto surfaceThicknessBox = node->GetBox(5);
const Value surfaceThickness = GetValue(surfaceThicknessBox, 8).AsFloat();
const Value surfaceThickness = GetValue(node->GetBox(5), 8).AsFloat();
const auto sceneDepthTexture = findOrAddSceneTexture(MaterialSceneTextures::SceneDepth);
_writer.Write(
TEXT(
" {{\n"
@@ -929,7 +903,51 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" }}\n"
), position.Value, velocity.Value, mass.Value, param.ShaderName, attractionSpeed.Value, attractionForce.Value, stickDistance.Value, stickForce.Value);
break;
}
}
// Collision (Global SDF)
case 336:
{
COLLISION_BEGIN();
auto param = findOrAddGlobalSDF();
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
const Char* format = IsLocalSimulationSpace()
? TEXT(
" {{\n"
" // Collision (Global SDF)\n"
" float3 nextPos = {0} + {1} * DeltaTime;\n"
" nextPos = mul(float4(nextPos, 1), WorldMatrix).xyz;\n"
" float dist = SampleGlobalSDF({10}, {10}_Tex, nextPos);\n"
" if (dist < {5})\n"
" {{\n"
" {0} = mul(float4({0}, 1), WorldMatrix).xyz;\n"
" float3 n = normalize(SampleGlobalSDFGradient({10}, {10}_Tex, {0}, dist));\n"
" {0} += n * -dist;\n"
" {0} = mul(float4({0}, 1), InvWorldMatrix).xyz;\n"
COLLISION_LOGIC()
" }}\n"
)
: TEXT(
" {{\n"
" // Collision (Global SDF)\n"
" float3 nextPos = {0} + {1} * DeltaTime;\n"
" float dist = SampleGlobalSDF({10}, {10}_Tex, nextPos);\n"
" if (dist < {5})\n"
" {{\n"
" float3 n = normalize(SampleGlobalSDFGradient({10}, {10}_Tex, {0}, dist));\n"
" {0} += n * -dist;\n"
COLLISION_LOGIC()
" }}\n"
);
_writer.Write(format,
// 0-4
positionAttr.Value, velocityAttr.Value, ageAttr.Value, invert, sign,
// 5-9
radius.Value, roughness.Value, elasticity.Value, friction.Value, lifetimeLoss.Value,
// 10
param.ShaderName
);
break;
}
#undef COLLISION_BEGIN
#undef COLLISION_LOGIC

View File

@@ -427,14 +427,10 @@ void ParticleEmitterGPUGenerator::ProcessGroupParticles(Box* box, Node* node, Va
}
// Particle Position (world space)
case 212:
{
value = AccessParticleAttribute(node, TEXT("Position"), ParticleAttribute::ValueTypes::Vector3, AccessMode::Read);
if (((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local)
{
if (IsLocalSimulationSpace())
value = writeLocal(VariantType::Vector3, String::Format(TEXT("mul(float4({0}, 1), WorldMatrix).xyz"), value.Value), node);
}
break;
}
// Random Float Range
case 213:
{

View File

@@ -156,6 +156,16 @@ private:
{
return box->HasConnection() ? eatBox(box->GetParent<Node>(), box->FirstConnection()) : Value::Zero;
}
bool IsLocalSimulationSpace() const
{
return ((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::Local;
}
bool IsWorldSimulationSpace() const
{
return ((ParticleEmitterGraphGPU*)_graphStack.Peek())->SimulationSpace == ParticlesSimulationSpace::World;
}
};
#endif

View File

@@ -430,12 +430,13 @@ public:
USE_ATTRIBUTE(Position, Vector3, 0);
break;
}
// Collision (plane/sphere/box/cylinder/depth)
// Collision (plane/sphere/box/cylinder/depth/Global SDF)
case GRAPH_NODE_MAKE_TYPE(15, 330):
case GRAPH_NODE_MAKE_TYPE(15, 331):
case GRAPH_NODE_MAKE_TYPE(15, 332):
case GRAPH_NODE_MAKE_TYPE(15, 333):
case GRAPH_NODE_MAKE_TYPE(15, 334):
case GRAPH_NODE_MAKE_TYPE(15, 336):
{
USE_ATTRIBUTE(Position, Vector3, 0);
USE_ATTRIBUTE(Velocity, Vector3, 1);