Fix invalid particle attributes access inside emitter function

#1640
This commit is contained in:
Wojtek Figat
2023-10-12 17:55:49 +02:00
parent 8af2f458d7
commit 5b5f43714e
3 changed files with 14 additions and 1 deletions

View File

@@ -7,7 +7,7 @@
#include "Engine/Graphics/RenderTask.h"
#define GET_VIEW() auto mainViewTask = MainRenderTask::Instance && MainRenderTask::Instance->LastUsedFrame != 0 ? MainRenderTask::Instance : nullptr
#define ACCESS_PARTICLE_ATTRIBUTE(index) (context.Data->Buffer->GetParticleCPU(context.ParticleIndex) + context.Data->Buffer->Layout->Attributes[node->Attributes[index]].Offset)
#define ACCESS_PARTICLE_ATTRIBUTE(index) (context.Data->Buffer->GetParticleCPU(context.ParticleIndex) + context.Data->Buffer->Layout->Attributes[context.AttributesRemappingTable[node->Attributes[index]]].Offset)
#define GET_PARTICLE_ATTRIBUTE(index, type) *(type*)ACCESS_PARTICLE_ATTRIBUTE(index)
void ParticleEmitterGraphCPUExecutor::ProcessGroupParameters(Box* box, Node* node, Value& value)
@@ -436,9 +436,19 @@ void ParticleEmitterGraphCPUExecutor::ProcessGroupParticles(Box* box, Node* node
auto* functionOutputNode = &graph->Nodes[function->Outputs[outputIndex]];
Box* functionOutputBox = functionOutputNode->TryGetBox(0);
// Setup particle attributes remapping (so particle data access nodes inside the function will read data at proper offset, see macro ACCESS_PARTICLE_ATTRIBUTE)
byte attributesRemappingTable[PARTICLE_ATTRIBUTES_MAX_COUNT];
Platform::MemoryCopy(attributesRemappingTable, context.AttributesRemappingTable, sizeof(attributesRemappingTable));
for (int32 i = 0; i < graph->Layout.Attributes.Count(); i++)
{
const ParticleAttribute& e = graph->Layout.Attributes[i];
context.AttributesRemappingTable[i] = context.Data->Buffer->Layout->FindAttribute(e.Name, e.ValueType);
}
// Evaluate the function output
context.GraphStack.Push(graph);
value = functionOutputBox && functionOutputBox->HasConnection() ? eatBox(nodeBase, functionOutputBox->FirstConnection()) : Value::Zero;
Platform::MemoryCopy(context.AttributesRemappingTable, attributesRemappingTable, sizeof(attributesRemappingTable));
context.GraphStack.Pop();
break;
}

View File

@@ -133,6 +133,8 @@ void ParticleEmitterGraphCPUExecutor::Init(ParticleEmitter* emitter, ParticleEff
context.ViewTask = effect->GetRenderTask();
context.CallStackSize = 0;
context.Functions.Clear();
for (int32 i = 0; i < PARTICLE_ATTRIBUTES_MAX_COUNT; i++)
context.AttributesRemappingTable[i] = i;
}
bool ParticleEmitterGraphCPUExecutor::ComputeBounds(ParticleEmitter* emitter, ParticleEffect* effect, ParticleEmitterInstance& data, BoundingBox& result)

View File

@@ -119,6 +119,7 @@ struct ParticleEmitterGraphCPUContext
class SceneRenderTask* ViewTask;
Array<ParticleEmitterGraphCPU*, FixedAllocation<32>> GraphStack;
Dictionary<VisjectExecutor::Node*, ParticleEmitterGraphCPU*> Functions;
byte AttributesRemappingTable[PARTICLE_ATTRIBUTES_MAX_COUNT]; // Maps node attribute indices to the current particle layout (used to support accessing particle data from function graph which has different layout).
int32 CallStackSize = 0;
VisjectExecutor::Node* CallStack[PARTICLE_EMITTER_MAX_CALL_STACK];
};