openfx icon indicating copy to clipboard operation
openfx copied to clipboard

Deterministic per-frame RNG

Open gregcotten opened this issue 1 year ago • 10 comments

I'm just stubbing this issue for now, but some context:

One of our plugins uses kOfxPropTime to seed its RNG so we can do deterministically random things per-frame so when render is called on that frame, the frame looks the same, every time. kOfxPropTime isn't necessarily unique, and could be repeated for multiple clips depending on how the host uses it. It would be useful to have some sort of "per plugin instance" way of seeding the RNG, so that randomness is calculated as a combination of the plugin instance's unique ID and the current kOfxPropTime.

I have also considered storing some sort of secret property on the plugin instance that defaults to 0 but then is immediately replaced with a random number if its value is 0, but that behavior is kind of weird and probably most hosts implementations of copying parameters from one plugin instance to another would simply copy the random number I generated over to another instance, which is not desired.

Has anyone thought about how one might do this without adding anything to OpenFX?

gregcotten avatar Jun 09 '24 16:06 gregcotten

Quite a few plug-ins have needed things like this over the years, but it's usually done with a visible seed parameter that's initialised to a random number. The reason you want a visible parameter is so that the user can set it manually to get an identical, predictable effect. If you want the user to be able to "roll the dice" to get random looks, you could include a re-seed button.

john-paulsmith avatar Jul 02 '24 16:07 john-paulsmith

Quite a few plug-ins have needed things like this over the years, but it's usually done with a visible seed parameter that's initialised to a random number. The reason you want a visible parameter is so that the user can set it manually to get an identical, predictable effect. If you want the user to be able to "roll the dice" to get random looks, you could include a re-seed button.

For sure! We have a checkbox for "automatic" RNG mode that can be unchecked to reveal the underlying seed parameter. Unfortunately still the pitfall of hosts naively copying this parameter around when duplicating instances of the plugin when the user likely doesn't want this parameter copied still arise! There doesn't really seem to be much for the plugin to do here to mitigate things like that.

Also, in a "progressive disclosure" sense, I'd rather the user not have to manually manage the seed until they know they need to - our plugin should "do the right thing" until then. Just looking for a creative solution that allows for the plugin user to not have to worry about two plugin instances having identical RNG until they actually want that to happen.

gregcotten avatar Jul 02 '24 16:07 gregcotten

Quite a few plug-ins have needed things like this over the years, but it's usually done with a visible seed parameter that's initialised to a random number. The reason you want a visible parameter is so that the user can set it manually to get an identical, predictable effect. If you want the user to be able to "roll the dice" to get random looks, you could include a re-seed button.

Just circling back... What steps are you using to initialize a property with a random number? On instance creation I check to see if the property is set to 0, and if so, set it to a random value. Some hosts don't seem to like this behavior of setting a property during instance creation, though...

gregcotten avatar Mar 18 '25 16:03 gregcotten

Well the header comment on paramSetValue() says

paramSetValue should only be called from within a ::kOfxActionInstanceChanged or interact action

so I'm not sure what the correct way for a plugin to set values on new instances is.

barretpj avatar Mar 20 '25 10:03 barretpj

I think Resolve may be the only one to unofficially support setting a param during instance creation.

It's not a perfect solution though, since I don't want the RNG seed to be copied over if a user simply copy/pasted the plugin onto another clip.

gregcotten avatar Mar 20 '25 12:03 gregcotten

Would adding an integer ID to clips make sense? Or even explicitly calling it a RNG seed or something?

Could also be useful if you have written multiple plugins to work cooperatively if assigned the same RNG seed value.

gregcotten avatar Mar 20 '25 13:03 gregcotten

I'm in favor of either adding a unique instance ID property to the effect that can be used as a hash, OR introduce a new integer parameter hint that indicates its a seed. Then the host can do the hashing on it's side. I prefer the unique ID property on the effect since there are other uses for it.

fxtech avatar Mar 20 '25 13:03 fxtech

So "unique" would mean it's not copied when the effect is copied and pasted, and it's not retained when the effect is split on the timeline?

barretpj avatar Mar 20 '25 14:03 barretpj

Right - each effect "instance" would get its own ID. I'm sure many (all) hosts already have some kind of identifier or GUID for each instance. It would just be an issue of exposing that in some standard way.

fxtech avatar Mar 20 '25 14:03 fxtech

I'm happy to say that in Baselight I'm now calling instanceChanged after createInstance, and this fixes the issue with setValueAtTime during create.

barretpj avatar Apr 01 '25 15:04 barretpj

closing this in favor of a broader fix: https://github.com/AcademySoftwareFoundation/openfx/issues/203

gregcotten avatar Jun 16 '25 20:06 gregcotten