True. To think of it, it was a silly convenience feature.
I think at least almost everything is, including stageName and sort. Only isMergeable is a “design-time parameter” - maybe it shouldn’t be a property.
OTOH, isMergeable interacts with sort, which is a property. My first reaction would be to eliminate isMergeable, and let sort=0 declare a new render pass, but that wouldn’t work in the case with lens flare and bloom. Both are non-mergeable, belong in the same logical stage, yet must have different sort values so that both can be enabled at the same time.
So yeah, let’s return to this later
They provide information to FilterPipeline controlling the options needed for renderSceneInto(), and to FilterStage controlling the creation of the compositing shader.
The flag merge logic takes in the metadata defined for the same texture by all enabled filters, and determines what that means “as a whole”. Explicitly: in the case of FilterStage, the metadata from each individual filter controls the parameter list of the filter’s own Cg function call, and the merged metadata controls the parameter list of the compositing fshader. FilterPipeline needs only the merged metadata, for determining which scene textures and which aux bits are needed.
CustomInputMetadata is simpler; it just lists the custom input names and types needed by each filter. It is used by FilterStage. Again, the metadata from each individual filter controls the parameter list of the filter’s own Cg function call, and the merged data is used in constructing the parameter list of the compositing fshader.
In TextureInputMetadata, a filter can currently request the following:
- needTexpix = pixel size is required by the filter’s Cg function (for this texture).
- internalOnly = this is a scene texture needed in the shaders of the filter’s internal stages (so FilterPipeline must provide this texture), but the filter’s compositing Cg function does not need it.
- metaOnly = the filter’s Cg function wants the metadata for this texture, i.e. texcoord (and texpix, if needTexpix is True), but does not need the actual texture. This is useful in some special cases, e.g. in ScanlinesFilter. Be aware also that due to StageInitializationFilter, the current pixel’s up-to-date color is always available in the “pixcolor” variable - so if a filter wanted e.g. only that and texcoord (for whatever reason; e.g. for applying vignetting), it could set metaOnly to avoid passing the unused k_txcolor to the filter function.
The thisAndThatOnly flags are used to eliminate shader inputs that would not be used, resulting in a faster shader.
(I’m also considering adding needTexpad similarly to needTexpix, but we’ll see.)
True. I was speaking of triggering FilterStage- and FilterPipeline-level reconfigures from inside the filter, but with your suggestion below, that is no longer needed.
Usually true, but there are special cases.
See params1.y in AmbientOcclusionFilter - it contains a step parameter that depends on both “amount” and “numsamples”. This saves an instruction in the shader, as it gets a precomputed step value as input. Here “numsamples” is a compile-time parameter (to make SSAO work with the arbfp1 profile), but “amount” is a run-time parameter.
Hence params1.y behaves like a “hybrid type” parameter: the shader input “params1” must be updated whenever “amount” changes (like usual), but also when the shader is recompiled (unlike usual).
Currently, it already does something like this, by setting the _needsCompile flag at the appropriate level of the hierarchy.
But I’ll need to reconsider where such flags should live - there are changes requiring only a local recompile (of the internal shaders), changes requiring a FilterStage-level recompile (affecting code synthesis of the compositing fshader), and changes requiring a FilterPipeline-level recompile (e.g. filters being added/removed, or a filter being moved to a different stageName).
However, due to how FilterManager works, it is currently not possible to support FilterStage-level recompiles, anyway. So, maybe either FilterManager should be modified (so that it would be possible to clean up only some buffers by reference; but then it would also require a system to let the caller modify the buffer sort order - and FilterPipeline doesn’t really want to do that), or this system should be simplified so that there are only Filter-level and FilterPipeline-level reconfigures.
This is very elegant! Thank you!
(But what about updating stageName and sort? Does the task manager run in its own thread? If it does, there is a possible race condition here, unless we store those parameters in a single property as a tuple.)
Mm, yes, that should be fine.
(Although a detail: to conform to the old API, the set***() method must update all configuration parameters of the filter.)
Yes and yes.
BloomFilter and AmbientOcclusionFilter already hit me with some surprises, so when the framework is 90% done, it may be time to try to port the new filters over to it and see if any new features are needed
(Also, I think that the new filters need to be prepared relatively quickly after the framework is done, in order not to delay the release of 1.9.0.)