#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 orientationSpeedDecay; 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; // material stuff layout(location = 1) out struct { uint textureIndex; // location = 1 } OutFlat; 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 = particle.orientationSpeedDecay.x; // float angle = atan (normalized.y, normalized.x); vec2 particleScaleData = particle.scaleAndDecay.xz; // x and y mat3 rotate = mat3 (1.0f); rotate[0][0] = cos(angle); rotate[0][1] = sin(angle); rotate[1][0] = -sin(angle); rotate[1][1] = cos(angle); vec3 particlePos = rotate * vertexPos; vec3 viewRight = normalize (vec3 (cameraData.viewMat[0][0], cameraData.viewMat[1][0], cameraData.viewMat[2][0])); vec3 viewUp = normalize(vec3 (cameraData.viewMat[0][1], cameraData.viewMat[1][1], cameraData.viewMat[2][1])); particlePos = particle.position.xyz + (viewRight * particlePos.x * particleScaleData.x) + (viewUp * particlePos.y * particleScaleData.y); OutFlat.textureIndex = particle.textureIndex; gl_Position = cameraData.vpMat * vec4(particlePos, 1.0f); }