88 lines
2.1 KiB
GLSL
88 lines
2.1 KiB
GLSL
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
|
|
|
#include "./Flax/Common.hlsl"
|
|
|
|
#ifndef SORT_MODE
|
|
#define SORT_MODE 0
|
|
#endif
|
|
|
|
// Primary constant buffer
|
|
META_CB_BEGIN(0, Data)
|
|
float3 ViewPosition;
|
|
uint ParticleCounterOffset;
|
|
uint ParticleStride;
|
|
uint ParticleCapacity;
|
|
uint PositionOffset;
|
|
uint CustomOffset;
|
|
float4x4 PositionTransform;
|
|
META_CB_END
|
|
|
|
// Particles data buffer
|
|
ByteAddressBuffer ParticlesData : register(t0);
|
|
|
|
// Output sorting keys buffer (index + key)
|
|
struct Item
|
|
{
|
|
float Key;
|
|
uint Value;
|
|
};
|
|
RWStructuredBuffer<Item> SortingKeys : register(u0);
|
|
|
|
float GetParticleFloat(uint particleIndex, int offset)
|
|
{
|
|
return asfloat(ParticlesData.Load(particleIndex * ParticleStride + offset));
|
|
}
|
|
|
|
float3 GetParticleVec3(uint particleIndex, int offset)
|
|
{
|
|
return asfloat(ParticlesData.Load3(particleIndex * ParticleStride + offset));
|
|
}
|
|
|
|
// Sorting keys generation shader
|
|
META_CS(true, FEATURE_LEVEL_SM5)
|
|
META_PERMUTATION_1(SORT_MODE=0)
|
|
META_PERMUTATION_1(SORT_MODE=1)
|
|
META_PERMUTATION_1(SORT_MODE=2)
|
|
[numthreads(1024, 1, 1)]
|
|
void CS_Sort(uint3 dispatchThreadId : SV_DispatchThreadID)
|
|
{
|
|
uint index = dispatchThreadId.x;
|
|
uint particlesCount = min(ParticlesData.Load(ParticleCounterOffset), ParticleCapacity);
|
|
if (index >= particlesCount)
|
|
return;
|
|
|
|
// TODO: maybe process more than 1 particle at once and pre-sort them?
|
|
|
|
#if SORT_MODE == 0
|
|
|
|
// Sort particles by depth to the view's near plane
|
|
float3 particlePosition = GetParticleVec3(index, PositionOffset);
|
|
float4 position = mul(float4(particlePosition, 1.0f), PositionTransform);
|
|
float sortKey = position.w;
|
|
|
|
#elif SORT_MODE == 1
|
|
|
|
// Sort particles by distance to the view's origin
|
|
float3 particlePosition = GetParticleVec3(index, PositionOffset);
|
|
float4 position = mul(float4(particlePosition, 1.0f), PositionTransform);
|
|
float3 direction = ViewPosition - position.xyz;
|
|
float sortKey = dot(direction, direction);
|
|
|
|
#elif SORT_MODE == 2
|
|
|
|
// Sort particles by the custom attribute
|
|
float sortKey = GetParticleFloat(index, CustomOffset);
|
|
|
|
#else
|
|
|
|
#error Unknown sorting mode!
|
|
|
|
#endif
|
|
|
|
// Write sorting index-key pair
|
|
Item item;
|
|
item.Key = sortKey;
|
|
item.Value = index;
|
|
SortingKeys[index] = item;
|
|
}
|