Rendering and Passes
Shaderpass
Compared to other game engines, Ivy uses a slightly more complicated, though more flexible approach to rendering.
All rendereable entities, hereby referred to as objects have an associated shaderpass. A shaderpass holds a shader and describes at which point it will be rendered in the rendering pipelines.
Each node in the rendering shaderpass has an associated type of shaderpass which it will
render. For example, the ImageRenderer
will usually be set up to render
objects which have a Handle<ImagePass>
. The ImagePass
, wrapped in an opaque
resource handle, will describe the vulkan pipeline and layout used.
Note: The renderer usually expect the different shaderpasses to conform to a single pipeline layout due to descriptor binding.
Objects with meshes usually have a GeometryPass
attached to them, with the
mesh and/or material describing the specific properties like texture and
roughness.
Different objects which belong to the same shaderpass can have different values, I.e; different shaders, which for example can be used for wind affected foliage to be rendered along other objects in the same shaderpass, but different shaders.
The system also allows for multiple shaderpasses to be attached to the same entity,
allowing the entity to use different shaders for different shaderpasses. This high
customizability allows the same entity to use a textured albedo shader for
GeometryPass
, and a solid color for a hypothetical MinimapPass
. This can be
very useful in games where the same object may be required to be rendered
multiple times from different viewpoints.
A ShaderPass
is a type which wraps a Pipeline
and a PipelineLayout
, though
they can contain other info. The Rust type system is used for differentiating
between different kinds of passes.
For reducing boilerplate a convenience macro new_shaderpass
is provided for
easily creating one or more stronly typed shaderpass types.
Example:
#![allow(unused)] fn main() { use ivy::new_shaderpass; new_shaderpass! { pub struct MinimapPass; pub struct SolidPass; } }
In many cases though, the usage of the included GeometryPass
, ImagePass
,
TextPass
, and different post processing passes are enough.
Rendergraph
The rendering graph describes an acyclic graph of rendering nodes, which describe how the scene will be rendered. Each node describes its inputs and outputs, and dependencies will automatically be generated to ensure proper ordering and syncronization with paralellization using Vulkan.
ivy-presets
contain common rendergraph setups, such as for PBR rendering. It
is also possible to create your own rendergraph to tailor the rendering for your
game or application.
The following example shows the raw, unaided setup of a rendergraph rendering a simple unlit model to the screen.
#![allow(unused)] fn main() { {{ #include ../../../examples/rendergraph.rs }} }