// Copyright Epic Games, Inc. All Rights Reserved. #include "/Engine/Private/Common.ush" #include "NiagaraRibbonCommon.ush" Buffer SortedIndices; StructuredBuffer InputAccumulation; RWBuffer OutputTangentsAndDistances; #if HAS_RIBBON_ID RWBuffer OutputMultiRibbonIndices; #endif #if RIBBONS_WANTS_AUTOMATIC_TESSELLATION RWBuffer OutputTessellationStats; #endif RWBuffer OutputSegments; [numthreads(THREADGROUP_SIZE, 1, 1)] void RibbonAggregationApply(uint3 DispatchThreadId : SV_DispatchThreadID) { const uint TotalNumParticles = GetTotalNumParticles(); const uint RawParticleID = DispatchThreadId.x; if (RawParticleID < TotalNumParticles) { OutputTangentsAndDistances[4 * RawParticleID + 3] = InputAccumulation[RawParticleID].RibbonDistance; // deal with the masking of invalid segments that has been inserted into the OutputSegments during initialization if (OutputSegments[RawParticleID] != INDEX_NONE) { OutputSegments[RawParticleID] = InputAccumulation[RawParticleID].SegmentCount - 1; } #if HAS_RIBBON_ID OutputMultiRibbonIndices[RawParticleID] = InputAccumulation[RawParticleID].MultiRibbonCount - 1; #endif #if RIBBONS_WANTS_AUTOMATIC_TESSELLATION #if RIBBON_HAS_TWIST const uint TessellationBaseOffset = RawParticleID * 5; #else const uint TessellationBaseOffset = RawParticleID * 3; #endif // RIBBON_HAS_TWIST OutputTessellationStats[TessellationBaseOffset + 0] = InputAccumulation[RawParticleID].TessTotalLength; OutputTessellationStats[TessellationBaseOffset + 1] = InputAccumulation[RawParticleID].TessAvgSegmentLength; OutputTessellationStats[TessellationBaseOffset + 2] = InputAccumulation[RawParticleID].TessAvgSegmentAngle; #if RIBBON_HAS_TWIST OutputTessellationStats[TessellationBaseOffset + 3] = InputAccumulation[RawParticleID].TessTwistAvgAngle; OutputTessellationStats[TessellationBaseOffset + 4] = InputAccumulation[RawParticleID].TessTwistAvgWidth; #endif // RIBBON_HAS_TWIST #endif // RIBBONS_WANTS_AUTOMATIC_TESSELLATION } }