]>
Witch of Git - lovr-particles/blob - main.lua
b931f2f434f2b67d966ff1a944f1ddbf34f42ad9
1 local mat4
= lovr
.math
.mat4
3 local nParticles
= 2 ^
14
5 local batches
= nParticles
/ batchSize
14 features
= lovr
.graphics
.getFeatures()
15 shaders
.particles
= lovr
.graphics
.newShader("shaders/particles.vert", "shaders/particles.frag")
17 blocks
.particles
= lovr
.graphics
.newShaderBlock("compute", {
18 -- Reading a value seems to work around whatever the rendering glitch
19 -- was. So we include this flag so we only have to ask for a single
20 -- value, instead of having to copy a large array. Still, annoying :(
21 -- For reference, see issue comment at:
22 -- https://github.com/bjornbytes/lovr/issues/211#issuecomment-580985010
24 particles
= {"mat4", nParticles
},
25 }, { readable
= true })
26 shaders
.particles
:sendBlock('particleData', blocks
.particles
)
27 shaders
.particles
:send("batchSize", batchSize
)
29 meshes
.particle
= makeParticleMesh(batchSize
)
31 compute
.particles
= lovr
.graphics
.newComputeShader("shaders/particles.comp")
32 compute
.particles
:sendBlock('particleData', blocks
.particles
)
33 compute
.particles
:send("dt", 0.01)
35 local xr
, yr
, zr
= range(-1, 1), range(1, 3), range(-2, 0)
36 local sr
, vr
= range(0.005, 0.01), range(-0.05, 0.05)
37 local initial
= initialParticleData(nParticles
, xr
, yr
, zr
, sr
, vr
)
38 blocks
.particles
:send("particles", initial
)
43 local x
, y
, z
= lovr
.headset
.getPose("head")
44 lovr
.graphics
.compute(compute
.particles
, batches
)
45 -- Read the buffer to force SSBO synch of some sort.
46 blocks
.particles
:read("reloadFlag")
47 shaders
.particles
:send("headPos", {x
, y
, z
})
49 lovr
.graphics
.setColor(0.6, 0.1, 0)
50 lovr
.graphics
.setShader(nil)
51 for _
, hand
in ipairs(lovr
.headset
.getHands()) do
52 local x
, y
, z
, a
, ax
, ay
, az
= lovr
.headset
.getPose(hand
)
53 lovr
.graphics
.cube("fill", x
, y
, z
, 0.1, a
, ax
, ay
, az
)
56 withDepthTest("lequal", false, function()
57 lovr
.graphics
.setColor(1, 1, 1)
58 lovr
.graphics
.setShader(shaders
.particles
)
59 meshes
.particle
:draw(mat4(), batches
)
63 function makeParticleMesh(size
)
64 local format = { {'vertPosition', 'float', 2}, }
67 local insert
= table.insert
68 for chunk
= 1, size
do
69 insert(verts
, { 1, 1})
70 insert(verts
, { 1, -1})
71 insert(verts
, {-1, -1})
72 insert(verts
, {-1, 1})
73 local base
= 4 * (chunk
- 1)
74 insert(vertMap
, 3 + base
)
75 insert(vertMap
, 2 + base
)
76 insert(vertMap
, 1 + base
)
77 insert(vertMap
, 4 + base
)
78 insert(vertMap
, 3 + base
)
79 insert(vertMap
, 1 + base
)
81 local mesh
= lovr
.graphics
.newMesh(format, verts
, "triangles", "static")
82 mesh
:setVertexMap(vertMap
)
86 function range(min, max)
87 local scale
= max - min
89 return min + lovr
.math
.random() * scale
93 function initialParticleData(size
, xRange
, yRange
, zRange
, sRange
, vRange
)
95 local insert
= table.insert
98 xRange(), yRange(), zRange(), sRange(),
99 vRange(), vRange(), vRange(), 1,
107 function withDepthTest(compareMode
, write, callback
)
108 local oldComp
, oldWrite
= lovr
.graphics
.getDepthTest()
109 lovr
.graphics
.setDepthTest(compareMode
, write)
111 lovr
.graphics
.setDepthTest(oldComp
, oldWrite
)