#version 460 core 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; }; struct ParticleData { vec4 position; vec4 rotation; vec4 velocity; vec4 acceleration; vec4 scaleAndDecay; float life; uint textureIndex; }; layout (set = 0, binding = 0) uniform GenericDataBuffer { GenericData data; } genericDataBuffer; layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; mat4 projMat; } cameraData; // output buffer not needed layout (std430, set = 2, binding = 2) coherent restrict buffer ParticlesOutputBuffer { ParticleData data[]; } outputParticles; layout (std430, set = 2, binding = 4) coherent restrict buffer IndicesData { uint indices[]; }; // between shader stages layout(location = 0) out struct { vec2 uv; // location = 0 } Out; vec2 CreateQuad (in uint vertexID) { uint b = 1 << vertexID; return vec2 ((0x3 & b) != 0, (0x9 & b) != 0); } void main() { // Create a quad and its texture coordinates Out.uv = CreateQuad (gl_VertexIndex); vec3 vertexPos = vec3 (Out.uv - vec2(0.5f), 0.0f); ParticleData particle = outputParticles.data[indices[gl_InstanceIndex]]; vec3 normalized = normalize (particle.velocity.xyz); float angle = atan (normalized.y, normalized.x); vec2 particleScaleData = particle.scaleAndDecay.xz; // x and y mat4 localModel = mat4 (1.0f); localModel[0][0] = particleScaleData.x; localModel[1][1] = particleScaleData.y; mat4 rotate = mat4(1.0f); rotate[0][0] = cos(angle); rotate[0][1] = sin(angle); rotate[1][0] = -sin(angle); rotate[1][1] = cos(angle); localModel = rotate * localModel; localModel[3] = vec4 (particle.position.xyz, 1.0f); gl_Position = cameraData.vpMat * localModel * vec4(vertexPos, 1.0f); }