FrameGraph: multi-valued task properties #17247
Draft
+219
−24
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a PoC, intended to gather feedback on this feature (is it useful? How can it best be implemented? etc.).
Feature
Currently, properties in tasks are simple properties, such as
public numCascades: number;
in theFrameGraphCascadedShadowGeneratorTask
class.The idea is to be able to set a value for a property based on a condition. Of course, we could do this in user code:
This is a bit tedious, and the code can quickly become cluttered with numerous conditions if the frame graph has a high degree of variability (some parts of the graph can depend on the engine type, others on globalQuality, shadowQuality, ... parameters, etc.).
In this PoC, I suggest adding an additional variable
numCascadesMulti
, which allows you to define the property as follows:When the graph is built, all multi properties of all tasks are parsed and evaluated: the first entry that returns true will set its value as the property value.
In this way, the variations are closely linked to the property and are clearly part of the graph itself, rather than additional code.
In addition, a new property
public available?: () => boolean;
has been added to the task class: if the property is defined and the function returns false, everything behaves as if the task were not in the task list: it will neither be built nor executed.Example of use
Let's imagine that we want to display volumetric lighting only if the globalQuality parameter is set to “high”:
Without the PR:
With the PR:
When you change the value of globalQuality, in the first case, you must reset the frame graph and re-execute the function that creates it. In the second case, you just need to execute
frameGraph.build()
. Furthermore, I think the code is more readable in the second case, and even more so if additional conditions are added to the code.Implementation
You must use a decorator to indicate that a property must have a corresponding “multi” property:
The decorator creates the
numCascadesMulti
property. However, in order for the property to be available in IntelliSense, I had to declare it in the class:I don't know if there's a way to make it available via IntelliSense without having to add this declaration...
The generator can take an additional parameter, which is the name of the “setter” function, a function that will be called when the property changes (in case you need to execute additional code when this happens):
Note that there are no breaking changes,
numCascades
still exists, and if you assign a value to it, this value takes precedence over what you might have assigned tonumCascadesMulti
: the setter fornumCascades
deletes theFrameGraphTaskProperty
instance created whennumCascadesMulti
was first accessed.