]> Witch of Git - lovr-particles/blob - main.lua
Add velocities and padding to the particle data
[lovr-particles] / main.lua
1 local mat4 = lovr.math.mat4
2
3 local nParticles = 2 ^ 16
4 local batchSize = 128
5 local batches = nParticles / batchSize
6
7 local features
8 local shaders = {}
9 local blocks = {}
10 local meshes = {}
11
12 function lovr.load()
13 features = lovr.graphics.getFeatures()
14 shaders.particles = lovr.graphics.newShader("shaders/particles.vert", "shaders/particles.frag")
15 blocks.particles = lovr.graphics.newShaderBlock("compute", {
16 particles = {"mat4", nParticles},
17 }, { readable = true, writable = true })
18 shaders.particles:sendBlock('particleData', blocks.particles)
19 shaders.particles:send("batchSize", batchSize)
20 meshes.particle = makeParticleMesh(batchSize)
21 local initial = initialParticleData(nParticles, range(-2, 2), range(0, 4), range(-2, 2), range(0.005, 0.01))
22 blocks.particles:send("particles", initial)
23 end
24
25 function lovr.draw()
26 lovr.graphics.clear()
27 local x, y, z = lovr.headset.getPose("head")
28 shaders.particles:send("headPos", {x, y, z})
29
30 lovr.graphics.setColor(0.6, 0.1, 0)
31 lovr.graphics.setShader(nil)
32 for _, hand in ipairs(lovr.headset.getHands()) do
33 local x, y, z, a, ax, ay, az = lovr.headset.getPose(hand)
34 lovr.graphics.cube("fill", x, y, z, 0.1, a, ax, ay, az)
35 end
36
37 withDepthTest("lequal", false, function()
38 lovr.graphics.setColor(1, 1, 1)
39 lovr.graphics.setShader(shaders.particles)
40 meshes.particle:draw(mat4(), batches)
41 end)
42 end
43
44 function makeParticleMesh(size)
45 local format = { {'vertPosition', 'float', 2}, }
46 local verts = {}
47 local vertMap = {}
48 local insert = table.insert
49 for chunk = 1, size do
50 insert(verts, { 1, 1})
51 insert(verts, { 1, -1})
52 insert(verts, {-1, -1})
53 insert(verts, {-1, 1})
54 local base = 4 * (chunk - 1)
55 insert(vertMap, 3 + base)
56 insert(vertMap, 2 + base)
57 insert(vertMap, 1 + base)
58 insert(vertMap, 4 + base)
59 insert(vertMap, 3 + base)
60 insert(vertMap, 1 + base)
61 end
62 local mesh = lovr.graphics.newMesh(format, verts, "triangles", "static")
63 mesh:setVertexMap(vertMap)
64 return mesh
65 end
66
67 function range(min, max)
68 local scale = max - min
69 return function()
70 return min + lovr.math.random() * scale
71 end
72 end
73
74 function initialParticleData(size, xRange, yRange, zRange, sRange)
75 local particles = {}
76 local insert = table.insert
77 for i = 1, size do
78 insert(particles, {
79 xRange(), yRange(), zRange(), sRange(),
80 xRange(), yRange(), zRange(), 1,
81 0, 0, 0, 0,
82 0, 0, 0, 0,
83 })
84 end
85 return particles
86 end
87
88 function withDepthTest(compareMode, write, callback)
89 local oldComp, oldWrite = lovr.graphics.getDepthTest()
90 lovr.graphics.setDepthTest(compareMode, write)
91 callback()
92 lovr.graphics.setDepthTest(oldComp, oldWrite)
93 end