in vec2 vertPosition; out vec2 uv; uniform vec3 headPos; uniform int batchSize; struct particle_t { vec4 positionAndSize; vec4 velocity; vec4 padding2; // for LÖVR's limited ShaderBlock type :( vec4 padding3; // for LÖVR's limited ShaderBlock type :( }; layout(std430) buffer particleData { float reloadFlag; particle_t particles[]; }; vec4 position(mat4 projection, mat4 transform, vec4 vertex) { int index = gl_VertexID / 4 + gl_InstanceID * batchSize; particle_t particle = particles[index]; vec3 pos = particle.positionAndSize.xyz; float size = particle.positionAndSize.w; uv = vertPosition * 0.5 + 0.5; vec3 forward = normalize(pos - headPos); vec3 right = normalize(cross(forward, vec3(0, 1, 0))); vec3 up = cross(right, forward); vec3 offset = mat2x3(up, right) * (vertPosition * size); return projection * transform * vec4(pos + offset, 1.0); }