You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A lot of existing GLSL/HLSL shaders make use of mutable variables in ways that are convenient, but maybe not essential to their semantics. In broad strokes, there are two cases:
"Local" mutation used to compute a value incrementally from sub-terms.
"Global" mutation used to modify a logical quantity like "position" or "normal" over the course of a shader.
The "local" case is stuff like:
float4 sum = 0.0;
sum += firstThing();
sum += secondThing();
and:
float4 foo = someFunction();
foo.xyz *= foo.a;
In general, we can re-write such component declarations into bigger expressions, or so that they use Spire's support for statement initialization. This is usually mechanical, so I expect most programmers could be trained to write in the Spire-like style.
On the flip side, this kind of local mutation seems really easy for a system like Spire to support (it is basically just what Shade Trees had). If we think of sum or foo above like a variable, that points to a specific shader-graph node, then the subsequent assignment operations can be seen as just creating new shader graph nodes and then pointing the variable at a new node. This same basic logic could be extended to support simple cases of conditional assignment.
The "global" case is more interesting, and probably also more challenging. A lot of large GLSL/HLSL shaders work along the lines of collecting most/all of the shading state into a single struct, and then passing that struct as an inout parameter to one or more functions that will read-modify-write it along the chain.
Within the Spire formulation, these steps along the chain might best be implemented as modules. We already have support for the output of one module to become the input to another module (so if A outputs normal and B expects normal as input, it can get it implicitly). The missing thing right now is that if we want a module that takes normal as input and produces normal as output, we have to carefully manage the names, and do the module wiring more explicitly.
I suspect (but am not sure) that it is reasonable to extend the intuition of the "local" case to the global one, and allow for modules that conceptually have inout parameters. The order of using declarations for modules represents a logical "order of execution" (here referring to the order of execution of shader-graph-building code, and not the runtime code), so that the shader author would still be in control of the final result (just as if they had called a bunch of functions that perform read-modify-write operations in order).
I'm a bit nervous about all of the above, but I also know that porting existing shader code that makes heavy use of mutation tends to result in ugly idioms (lots of distinct names for the same concept), if the target language doesn't support some kind of idiomatic mutation construct.
The text was updated successfully, but these errors were encountered:
A lot of existing GLSL/HLSL shaders make use of mutable variables in ways that are convenient, but maybe not essential to their semantics. In broad strokes, there are two cases:
The "local" case is stuff like:
and:
In general, we can re-write such component declarations into bigger expressions, or so that they use Spire's support for statement initialization. This is usually mechanical, so I expect most programmers could be trained to write in the Spire-like style.
On the flip side, this kind of local mutation seems really easy for a system like Spire to support (it is basically just what Shade Trees had). If we think of
sum
orfoo
above like a variable, that points to a specific shader-graph node, then the subsequent assignment operations can be seen as just creating new shader graph nodes and then pointing the variable at a new node. This same basic logic could be extended to support simple cases of conditional assignment.The "global" case is more interesting, and probably also more challenging. A lot of large GLSL/HLSL shaders work along the lines of collecting most/all of the shading state into a single
struct
, and then passing that struct as aninout
parameter to one or more functions that will read-modify-write it along the chain.Within the Spire formulation, these steps along the chain might best be implemented as modules. We already have support for the output of one module to become the input to another module (so if
A
outputsnormal
andB
expectsnormal
as input, it can get it implicitly). The missing thing right now is that if we want a module that takesnormal
as input and producesnormal
as output, we have to carefully manage the names, and do the module wiring more explicitly.I suspect (but am not sure) that it is reasonable to extend the intuition of the "local" case to the global one, and allow for modules that conceptually have
inout
parameters. The order ofusing
declarations for modules represents a logical "order of execution" (here referring to the order of execution of shader-graph-building code, and not the runtime code), so that the shader author would still be in control of the final result (just as if they had called a bunch of functions that perform read-modify-write operations in order).I'm a bit nervous about all of the above, but I also know that porting existing shader code that makes heavy use of mutation tends to result in ugly idioms (lots of distinct names for the same concept), if the target language doesn't support some kind of idiomatic mutation construct.
The text was updated successfully, but these errors were encountered: