From f0c335d837a2a3f48161c9d4020a7d2d8bcb7077 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Fri, 31 Jan 2020 05:13:41 -0500 Subject: [PATCH] Add velocities and padding to the particle data MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. --- README.md | 8 ++++++++ main.lua | 19 ++++++++++++------- shaders/particles.frag | 3 ++- shaders/particles.vert | 15 ++++++++++++--- 4 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7693d1b --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Particles :D + +I've never used compute shaders before, and so I wanted to play with them +since I had watched some YouTube videos about them, and LÖVR had a really +convenient API for use them. + +This uses Shader Storage Buffers for transferring particle data, and for +simulating particle physics with compute shaders! diff --git a/main.lua b/main.lua index 78b666d..a9476a9 100644 --- a/main.lua +++ b/main.lua @@ -13,13 +13,13 @@ function lovr.load() features = lovr.graphics.getFeatures() shaders.particles = lovr.graphics.newShader("shaders/particles.vert", "shaders/particles.frag") blocks.particles = lovr.graphics.newShaderBlock("compute", { - particleData = {"vec4", nParticles}, + particles = {"mat4", nParticles}, }, { readable = true, writable = true }) - shaders.particles:sendBlock('particleDataBuffer', blocks.particles) + shaders.particles:sendBlock('particleData', blocks.particles) shaders.particles:send("batchSize", batchSize) meshes.particle = makeParticleMesh(batchSize) local initial = initialParticleData(nParticles, range(-2, 2), range(0, 4), range(-2, 2), range(0.005, 0.01)) - blocks.particles:send("particleData", initial) + blocks.particles:send("particles", initial) end function lovr.draw() @@ -35,7 +35,7 @@ function lovr.draw() end withDepthTest("lequal", false, function() - lovr.graphics.setColor(0, 0.5, 1) + lovr.graphics.setColor(1, 1, 1) lovr.graphics.setShader(shaders.particles) meshes.particle:draw(mat4(), batches) end) @@ -72,12 +72,17 @@ function range(min, max) end function initialParticleData(size, xRange, yRange, zRange, sRange) - local positions = {} + local particles = {} local insert = table.insert for i = 1, size do - insert(positions, {xRange(), yRange(), zRange(), sRange()}) + insert(particles, { + xRange(), yRange(), zRange(), sRange(), + xRange(), yRange(), zRange(), 1, + 0, 0, 0, 0, + 0, 0, 0, 0, + }) end - return positions + return particles end function withDepthTest(compareMode, write, callback) diff --git a/shaders/particles.frag b/shaders/particles.frag index 67f73bb..5c0f85d 100644 --- a/shaders/particles.frag +++ b/shaders/particles.frag @@ -1,7 +1,8 @@ in vec2 uv; +in vec4 particleColor; vec4 color(vec4 graphicsColor, sampler2D image, vec2 _uv) { float alpha = 1.0 - (distance(uv, vec2(0.5)) * 2.0); graphicsColor.a *= alpha; - return graphicsColor; + return graphicsColor * particleColor; } diff --git a/shaders/particles.vert b/shaders/particles.vert index d5ca089..b40c094 100644 --- a/shaders/particles.vert +++ b/shaders/particles.vert @@ -1,13 +1,22 @@ in vec2 vertPosition; out vec2 uv; +out vec4 particleColor; uniform vec3 headPos; uniform int batchSize; -layout(std430) buffer particleDataBuffer { vec4 particleData[]; }; +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 { particle_t particles[]; }; vec4 position(mat4 projection, mat4 transform, vec4 vertex) { int index = gl_VertexID / 4 + gl_InstanceID * batchSize; - vec3 pos = particleData[index].xyz; - float size = particleData[index].w; + particle_t particle = particles[index]; + vec3 pos = particle.positionAndSize.xyz; + float size = particle.positionAndSize.w; + particleColor = particle.velocity; uv = vertPosition * 0.5 + 0.5; vec3 forward = normalize(pos - headPos); -- 2.47.0