mikera / clisk

The Clojure Image Synthesis Kit
281 stars 13 forks source link

Seed setting for repeatability #14

Open nodename opened 8 years ago

nodename commented 8 years ago

This is like Issue #10 but my need is for it to behave properly in a multithreaded environment.

I believe that Issue 10 is solved in the single-threaded case by writing

(seed-simplex-noise! seed)
(plasma)

and the like. I'm obtaining seed from

(.nextLong (mikera.util.Random.))

I hope that's reasonable.

In the case where multiple threads may be evaluating noise expressions at the same time, though, it's possible that another thread can get in and set the seed differently (affecting the static variables of the Perlin or Simplex class that the noise functions rely on) before the noise function runs.

This has indeed been happening frequently in the Clevolution app.

I think the most direct solution may be to put the relevant variables in an instance rather than as statics in the classes for the multithreaded case.

But you may have a more elegant solution.

(To make matters worse, it appears that in the case of turbulate the func passed in may also be a noise function that uses the Simplex class, thus requiring a pushdown stack of seeds and their affected variables.)

mikera commented 8 years ago

So if I understand correctly, you want to be able to provide a seed parameter to the plasma or related noise functions?

Setting on a per-thread basis is tricky anyway since clisk already defaults to using concurrency for rendering (with a pmap)

nodename commented 8 years ago

Yes, I want each invocation of a noise function to use the seed value I've given it, and not to use any effects from any conflicting seed value. (Not quite the same as per-thread basis)

Does the pmap in the rendering incur any interference between the invoking thread and another thread invoking the pmap? It doesn't seem to me that it would. I mean, they're not going to step on each other's pmap threads, are they?