EDIT: This is almost entirely implemented now. The only remaining work left to do is to improve how we handle conflicting overrides activated simultaneously - refer to the bottom of this post for details.
Want a way to detect scenes based on active shaders or textures to set custom convergence and ini params.
We can already partially do this as a consequence of some existing features, but it's too limited to be generally useful. e.g. we can have a shader set an IniParam and clear it later on a Present call, but that only gives us scene detection in part of the frame, and doesn't give us the ability to change the convergence. It also doesn't integrate into the override code. This feature is now largely implemented.
Want to reuse the code in Override.cpp for this as much as possible
Allow the use of the existing transition code Done
Share the global undo with key bindings Done
An override should activate as soon as the shader/texture is encountered (or at the start of the next frame?) Done - activate at start of next frame
Override should deactivate on the present call if an entire frame (or more?) has passed without it being triggered again. Done - deactivates after one frame has passed without it being re-activated.
We want to be able to trigger scene detection from both [ShaderOverride] and [TextureOverride] sections. It would be a performance nightmare to check every single texture slot of every shader type on every draw call. I therefore intend to require something in the [ShaderOverride] section to enable texture scene detection from a specific slot, in much the same way we currently do for texture filtering. Edit: this is now supported since presets are triggered from command lists, be it shaderoverride, textureoverride or other.
Ideally, the syntax would be the same as in the [Key] sections, but there are some problems:
[ShaderOverride] sections already have x,y,z,w, etc for texture filtering, partner filtering, etc. that remain sticky
[ShaderOverride] sections already have "convergence" and "separation" settings that affect a single draw call
- ~~We could potentially do something to reuse these existing settings (if we have some way to specify a different duration), but some of the settings in [ShaderOverride] are now being processed as though they are instructions in sequential order, however the existing syntax in the [Key] sections don't fit with this as they have modifiers (like transition) on separate lines. We could make this work, but it would either be different syntax, or would be an exception to how everything else works in these sections.~~~~
The best way I can see to do this, is something like this: Edit: great minds think alike - this is the syntax we ended up using:
[ShaderOverrideSceneDetect]
preset = PresetSceneFoo
[PresetSceneFoo]
x = 1.0
convergence = 0.5
transition = 300
transition_type = cosine
release_transition = 100
release_transition_type = cosine
In this way, we are able to use the same syntax as the [Key] sections with no ambiguity. preset could potentially also refer to existing [Key] sections. The downside is we now have x,y,z,w,convergence & separation in both the ShaderOverride and the Preset section it refers to, that may appear similar at first glance, but are subtly different. Good documentation on the feature will be the key here.
Another problem to consider (that exists in pure key bindings as well, but until now we could largely get away with ignoring) is what happens if two overrides are activated simultaneously that both change a setting to different values. e.g. for convergence
- The global undo area is there to prevent this situation from permanently changing the convergence - once all overrides are deactivated it is guaranteed to return to the value it was before any overrides were activated.
- If a single override is activated then deactivated there is no problem.
- If all overrides set the same value there is no problem.
- activate A, activate B, deactivate B, deactivate A: Current behaviour is mostly sensible, but what if B shouldn't override A?
- activate A, activate B, deactivate A, deactivate B: Current behaviour is not ideal - after A is deactivated convergence will be set for A, but probably should be set for B.
In order to improve this I have two ideas:
- Maintain a list of active overrides. When an override is disabled, remove it from the list. If it was at the end of the list (Edit: Actually, if any of it's parameters were either active or being transitioned to), run a deactivate transition with targets found by walking the list backwards (note that different parameters may need to come from different entries in the list as not all overrides affect the same parameters). If the parameter is not found anywhere in the list, use the value from the global undo area.
- Assign a priority to overrides. This could allow an aiming override to always take priority over a scene detection (or vice versa).