SHADE_Y3/Assets/Shaders/ParticleEmit_CS.glsl

117 lines
2.4 KiB
GLSL

#version 450
layout(local_size_x = 128) in;
struct EmitterParameters
{
vec4 angularMin;
vec4 angularMax;
vec4 lifeAndSizeRange; // min life, max life, min size, max size
}
struct ParticleData
{
vec4 position;
vec4 rotation;
vec4 velocity;
vec4 acceleration;
vec4 scaleAndDecay;
float life;
uint textureIndex;
}
struct GenericData
{
//! Delta time
float dt;
//! Elapsed time of the application
float elapsedTime;
//! Viewport width of the scene (excluding imgui, that means smaller than window)
uint viewportWidth;
//! Ditto but for height
uint viewportHeight;
};
layout (set = 0, binding = 0) uniform GenericDataBuffer
{
GenericData data;
} genericDataBuffer;
layout (std430, set = 2, binding = 0) readonly buffer EmitterBuffer
{
EmitterParameters data;
} emitterParams;
layout (std430, set = 2, binding = 1) coherent restrict buffer ParticlesInputBuffer
{
ParticleData data[];
} inputParticles;
// output buffer not needed
// layout (std430, set = 2, binding = 2) coherent restrict buffer ParticlesOutputBuffer
// {
// ParticleData data[];
// } outputParticles;
layout (std430, set = 2, binding = 3) coherent restrict buffer ParticlesFreelistBuffer
{
int freeCount;
int freeIndices[];
} freelist;
// push constants
layout(std140, push_constant) uniform EmitterPushConstant
{
vec4 emitterPosition;
uint emissionCount;
} emitterPushConstant;
uint pcg_hash(uint seed)
{
uint state = seed * 747796405u + 2891336453u;
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
}
// Used to advance the PCG state.
uint rand_pcg(inout uint rng_state)
{
uint state = rng_state;
rng_state = rng_state * 747796405u + 2891336453u;
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
}
// Advances the prng state and returns the corresponding random float.
float rand(inout uint state)
{
uint x = rand_pcg(state);
state = x;
return float(x)*uintBitsToFloat(0x2f800004u);
}
void main()
{
uint emitterInvocationIndex = gl_GlobalInvocationID.x;
if (emitterInvocationIndex >= emitterPushConstant.emissionCount)
return;
int freelistIndex = atomicAdd (freelist.freeCount, -1) - 1;
if (freelistIndex < 0)
atomicAdd (freelist.freeCount, 1);
ParticleData particle;
int index = freelist.freeIndices[freelistIndex];
particle.position = emitterPosition;
particle.life = emitterParams.10.0f;
particles[index] = particle;
}