22 months agoImplement compute-shader simulation of particles!
Cassie Jones [Sat, 1 Feb 2020 05:15:45 +0000 (00:15 -0500)]
Implement compute-shader simulation of particles!

This uses a workaround for the previously mentioned shader glitch in
order to use the compute shaders successfully. Bjorn notes that reading
from an SSBO makes rendering start working properly. In order to
*hopefully* make this cheaper, I add a variable to the buffer that's
intended for only reading like this, which ends up being sufficient to
fix the behavior of the whole buffer.

The discussion comment with the workaround:
> Reading data out of the buffer (print(block:read('value')[1])) after
> the compute also fixes it, I suspect maybe because it maps the buffer.

For simulation, this updates the positions with the velocity, and
applies uniform quadratic drag to the particles.

22 months agoAdd basic compute simulation (disabled)
Cassie Jones [Fri, 31 Jan 2020 12:48:01 +0000 (07:48 -0500)]
Add basic compute simulation (disabled)

We want to use a compute shader to update the particle states.
Unfortunately, they don't want to be updated. If you uncomment the line
that runs the compute shader, all the particles turn into a glitchy
mess. Committing this code for reproducability's sake.

22 months agoAdd velocities and padding to the particle data
Cassie Jones [Fri, 31 Jan 2020 10:13:41 +0000 (05:13 -0500)]
Add velocities and padding to the particle data

For now I'm using 2 vec4 of padding because LÖVR's ShaderBlock API
doesn't know about struct types or non-square matrices, and I need a
type which can hold 2 vec4, so I just pretend I'm sending a mat4 and
receive it as a struct of 4 vec4 on the shader side.

22 months agoRender lots of particles with SSBOs!
Cassie Jones [Fri, 31 Jan 2020 07:35:09 +0000 (02:35 -0500)]
Render lots of particles with SSBOs!

We generate particle batch meshes with a fixed chunk of quads at the
origin, and then dispatch instances of that batch. The vertex shader
fetches from a shader storage buffer of particle info by using the
instance ID (between batches) and the vertex ID (within batches), using
the batch size. We need to run these in batches because GPUs process
instances somewhat serially, so if you have a tiny instance you're
wasting a bunch of spare compute instead of running nicely in parallel.
Having smaller instances than the full particle size helps with avoiding
rendering lots of hidden particles if you're using dynamic particle
counts, and also gives smaller data uploads (although that's not
particularly significant, since they're static buffers of geometry).

The shaders do billboarding based on head position rather than the
projection matrices so they don't visibly move when you rotate your
head: projection-based billboards look really bad in VR it turns out.

22 months agoInitial commit, stymied by LÖVR bugs
Cassie Jones [Thu, 30 Jan 2020 21:28:55 +0000 (16:28 -0500)]
Initial commit, stymied by LÖVR bugs

This adds a main test program and a simple (currently broken) sprite
billboarding shader. It doesn't have much going on, because I'm running
into a LÖVR bug with sending compute ShaderBlock data on Oculus Quest.