Module bevy_hanabi::graph::expr
source · Expand description
Expression API
This module contains the low-level Expression API, designed to produce highly customizable modifier behaviors through a code-first API focused on runtime and serialization. For asset editing, the higher-level Node API offers an easier-to-use abstraction built on top of the Expression API.
§Modules and expressions
A particle effect is composed of a series Modifier
s decribing how to
initialize and update (simulate) the particles of the effect. Choosing which
modifier to add to an effect provides the user some limited level of
customizing. However modifiers alone cannot provide enough customizing to
build visual effects. For this reason, modifier inputs can be further
customized with expressions. An expression produces a value which is
assigned to the input. That value can be constant, in which case it will be
hard-coded into the generated WGSL shader, for performance reasons.
Alternatively, that value can vary based on other quantities, like an effect
property, a particle attribute, or some built-in simulation variable like
the simulation time.
An expression is represented by the Expr
enum. Expressions can be
combined together to form more complex expression; for example, the Add
expression computes the sum between two other expressions. Expr
represents a form of abstraction over the actual WGSL shader code, and is
generally closely related to the actual expressions of the WGSL language
itself.
An expression often refers to other expressions. However, Expr
as an
enum cannot directly contain other Expr
, otherwise the type would become
infinitely recursive. Instead, each expression is stored into a Module
and indexed by an ExprHandle
, a non-zero index referencing the
expression inside the module. This indirection avoids the recursion issue.
This means all expressions are implicitly associated with a unique module,
and care must be taken to not mix exressions from different modules.
Each EffectAsset
contains a single Module
storing all the Expr
used in all its modifiers.
§Kinds of expressions
Expressions can be grouped into various kinds, for the sake of comprehension:
- Literal expressions represent a constant, which will be hard-coded into
the final WGSL shader code. Expressions like
1.42
orvec3<f32>(0.)
are literal expressions in WGSL, and are represented by aLiteralExpr
. - Built-in expressions represent specific built-in values provided by the
simulation context. For example, the current simulation time is a built-in
expression accessible from the shader code of any visual effect to animate
it. A built-in expression is represented by a
BuiltInExpr
. - Attribute expressions represent the value of an attribute of a particle. A
typical example is the particle position, represented by
Attribute::POSITION
, which can be obtained as an expression through anAttributeExpr
. - Property expressions represent the value of a visual effect property, a
quantity assigned by the user on the CPU side and uploaded each frame into
the GPU for precise per-frame control over an effect. It’s represented by
a
PropertyExpr
. - Unary and binary operations are expressions taking one or two operand expressions and transforming them. A typical example is the Add operator, which takes two operand expressions and produces their sum.
§Building expressions
The fundamental way to build expressions is to directly write them into a
Module
itself. The Module
type contains various methods to create
new expressions and immediately write them.
let mut module = Module::default();
// Build and write a literal expression into the module.
let expr = module.lit(3.42);
Due to the code-first nature of the Expression API however, that approach
can be very verbose. Instead, users are encouraged to use an ExprWriter
,
a simple utility to build expressions with a shortened syntax. Once an
expression is built, it can be written into the underlying Module
. This
approach generally makes the code more readable, and is therefore highly
encouraged, but is not mandatory.
// Create a writer owning a new Module
let mut w = ExprWriter::new();
// Build a complex expression: max(3.42, properties.my_prop)
let expr = w.lit(3.42).max(w.prop("my_prop"));
// Finalize the expression and write it into the Module. The returned handle can
// be assign to a modifier input.
let handle = expr.expr();
// Finish using the writer and recover the Module with all written expressions
let module = w.finish();
Structs§
- Expression representing the value of an attribute of a particle.
- Expression for getting built-in quantities related to the effect system.
- Expression to cast an expression to another type.
- Handle of an expression inside a given
Module
. - Expression writer.
- A literal constant expression like
3.0
orvec3<f32>(1.0, 2.0, 3.0)
. - Container for expressions.
- Expression representing the value of a property of an effect.
- Intermediate expression from an
ExprWriter
.
Enums§
- Binary operator.
- Built-in operators.
- Language expression producing a value.
- Ternary operator.
- Unary operator.
Traits§
- Evaluation context for transforming expressions into WGSL code.