Page 10 of 18

Re: Post-0.10.0 feature wishlist

Posted: Mon Mar 07, 2016 9:25 pm
by zorg
spill wrote:...
I guess we could also replace all the functions relating to Sources with just

Code: Select all

Source:set(playing=true, volume=1.0, loop=false, data=<something>,...)
and similarly everything else; who wouldn't just love calling

Code: Select all

love.graphics.primitive('rectangle',0,0,10,10)
? :D (yes im sarcastic please dont take me serious)

Re: Post-0.10.0 feature wishlist

Posted: Mon Mar 07, 2016 9:33 pm
by Nixola
Particle systems have a LOT of :set* functions. I also think that a setProperties function would make it much simpler.

Re: Post-0.10.0 feature wishlist

Posted: Mon Mar 07, 2016 9:51 pm
by slime
That just swaps function calls for table fields, without changing the number of things you need to set or what you're able to do with particle systems.

Re: Post-0.10.0 feature wishlist

Posted: Mon Mar 07, 2016 10:03 pm
by s-ol
If you want it you could write a function that turns {key = value} tables into :setKey(value) calls with ease:

Code: Select all

function setAll(subject, table)
  for k, v in pairs(table) do
    if type(v) == "table" then
      subj["set"..k](subj, unpack(v))
    else
       subj["set"..k](subj, v)
    end
  end
end
As usual; untested, written on mobile

Re: Post-0.10.0 feature wishlist

Posted: Tue Mar 08, 2016 12:02 am
by spill
S0lll0s wrote:If you want it you could write a function that turns {key = value} tables into :setKey(value) calls with ease:

Code: Select all

function setAll(subject, table)
  for k, v in pairs(table) do
    if type(v) == "table" then
      subj["set"..k](subj, unpack(v))
    else
       subj["set"..k](subj, v)
    end
  end
end
As usual; untested, written on mobile
Heh, I did pretty much exactly that in one of my projects.
slime wrote:That just swaps function calls for table fields, without changing the number of things you need to set or what you're able to do with particle systems.
Yeah, I think it's an incremental improvement because it reduces the amount of duplicated code a bit. The problem I have with the current API is that you have to pour a bucket of data through a hundred pinholes, instead of one bucket-sized hole.

Maybe a better major overhaul suggestion would be to remove particle systems entirely and change SpriteBatch to allow removal and relative insertion. SpriteBatch already does efficient batched draw calls like ParticleSystem does, and it's not hard to implement your own (mostly) efficient batched updates by iterating over a list of particles and updating them with inlined logic. Right now, SpriteBatch doesn't support single-sprite removal or arbitrary insertion order, which is the biggest reason I see to use the existing ParticleSystem instead of rolling your own using a SpriteBatch. You'd sacrifice a little brevity by requiring users to write their own particle logic, but you wouldn't be locking people into an arbitrary API-defined set of particle behaviors. This would also make it much easier to write custom 3rd party particle libraries that could emulate the basic presets of the current system, or define new presets, like particles that bounce when they reach a certain y value, etc.

Re: Post-0.10.0 feature wishlist

Posted: Tue Mar 08, 2016 12:55 am
by slime
The reason there's no removal (aside from Spritebatch:set(index, 0,0,0,0,0), which will stop a sprite from rendering) or insertion in SpriteBatches is because the data in a spritebatch is effectively an array, and you can't remove from or insert into an an array without moving a lot of data. Insert and remove methods would be more expensive than you'd expect.

You can already mimic particle systems with a spritebatch, by clearing and re-adding all active particles to the batch before drawing. That's basically what a particle system does internally when you draw it (albeit without crossing the Lua/C barrier). Particle systems don't do any "sprite removal" or "sprite insertion" in their internal sprite batches at all.

Re: Post-0.10.0 feature wishlist

Posted: Tue Mar 08, 2016 1:06 am
by s-ol
@Spill you cannot do that since the graphics interface (opengl) requires the data be in an array (a SpriteBatch is basically a VBO: https://en.wikipedia.org/wiki/Vertex_Buffer_Object).

edit: what the hell? am I hallucinating or was that post removed just now?

Re: Post-0.10.0 feature wishlist

Posted: Tue Mar 08, 2016 1:37 am
by spill
S0lll0s wrote:@Spill you cannot do that since the graphics interface (opengl) requires the data be in an array (a SpriteBatch is basically a VBO: https://en.wikipedia.org/wiki/Vertex_Buffer_Object).
How do ParticleSystems do efficient batch rendering? I was skimming through the source code and I saw that they're internally stored as a doubly linked list (the way random insertion is implemented is really clever by the way), but I don't see the drawing code anywhere in ParticleSystem.cpp. I kind of assumed that SpriteBatch could use the same storage/rendering techniques that ParticleSystem does, which allows for constant-time insertion/removal.
S0lll0s wrote:edit: what the hell? am I hallucinating or was that post removed just now?
No, you're not hallucinating. I deleted it because I wanted to recheck my facts.

Anyway, is insertion/removal efficiency the only criticism of my proposal? Because I'm pretty sure it would be possible to make an implementation with good performance. For example, you could store the data in an array with gaps (that have alpha = 0) and use the gaps to coalesce the insertions and removals, so the memory layout might look like: [X1,X2,X3,_,_,_,X4,X5,X6,_,_,_,...,Xn] and inserting Y after X2 would cause the memory layout to look like [X1,X2,Y,X3,_,_,X4,X5,X6,_,_,_,...,Xn], and removing Y would similarly not shift very many of the values. If you removed or added enough things, it would propagate a shift to adjacent chunks, but I'm pretty sure you could balance it so that it would be amortized constant insertion/removal time from arbitrary points. Or you could just have a linked list of blocks size K, so that there are N/K OpenGL draw calls per SpriteBatch, but insertion/removal is O(K) instead of O(N). Both of these cause OpenGL to do a little bit more work, but it sounds like it would improve the drawing performance of ParticleSystems.

Re: Post-0.10.0 feature wishlist

Posted: Tue Mar 08, 2016 2:24 am
by slime
spill wrote:
S0lll0s wrote:@Spill you cannot do that since the graphics interface (opengl) requires the data be in an array (a SpriteBatch is basically a VBO: https://en.wikipedia.org/wiki/Vertex_Buffer_Object).
How do ParticleSystems do efficient batch rendering? I was skimming through the source code and I saw that they're internally stored as a doubly linked list (the way random insertion is implemented is really clever by the way), but I don't see the drawing code anywhere in ParticleSystem.cpp. I kind of assumed that SpriteBatch could use the same storage/rendering techniques that ParticleSystem does, which allows for constant-time insertion/removal.
Sprite batches already render in the exact same way particle systems do – as a straight array with a single draw call. The internal representation of particles is separate from the per-vertex particle sprite data that's drawn. The former has a ton of stuff that's useless for the latter, including velocity, acceleration, etc., and reducing the number of draw calls is very important for rendering performance and GPU utilization.

https://bitbucket.org/rude/love/src/8d4 ... tem.cpp-87

That code effectively does the same thing as:

Code: Select all

spritebatch:clear()

local particle = particles.start
while particle ~= nil do
    spritebatch:add(particle.x, particle.y, ...)
    particle = particle.next
end

love.graphics.draw(spritebatch)
spill wrote:I'm pretty sure you could balance it so that it would be amortized constant insertion/removal time from arbitrary points. Or you could just have a linked list of blocks size K, so that there are N/K OpenGL draw calls per SpriteBatch, but insertion/removal is O(K) instead of O(N). Both of these cause OpenGL to do a little bit more work, but it sounds like it would improve the drawing performance of ParticleSystems.
I think you overestimate the importance of algorithmic time compared to real-world factors like cache misses (which are in the ballpark of 200 cycles per cache miss!), draw call overhead, and GPU underutilization due to few vertices per draw call. :)

To put things into perspective: on many mobile GPUs, you will have trouble staying at 60fps if you have even a few hundred draw calls per frame. That is a big reason why single-draw-call sprite batches (such as SpriteBatches as well as the ParticleSystem code, and Text objects in 0.10) are so important.


Getting back on topic with a related issue: it might be nice to have multiple particle emitters per particle system, which again would all be batched together when drawing it.

Re: Post-0.10.0 feature wishlist

Posted: Tue Mar 08, 2016 8:30 am
by Fenrir
I vote for improved particles with a bit of physics! I would love to be able to set colliders to my particles to make them bounce on the ground for instance. :)