Expand description
renderling
is a “GPU driven” renderer with a focus on simplicity and ease
of use, targeting WebGPU.
Shaders are written in Rust using rust-gpu
.
§Hello triangle
Here we’ll run through the classic “hello triangle”, which will display a colored triangle.
§Context creation
First you must create a [Context
].
The Context
holds the render target - either a native window, an HTML
canvas or a texture.
use renderling::{context::Context, stage::Stage, geometry::Vertex};
// create a headless context with dimensions 100, 100.
let ctx = futures_lite::future::block_on(Context::headless(100, 100));
[Context::headless
] creates a Context
that renders to a texture.
[Context::from_winit_window
] creates a Context
that renders to a native
window.
[Context::try_new_with_surface
] creates a Context
that renders to any
[wgpu::SurfaceTarget
].
See the renderling::context
module documentation for
more info.
§Staging resources
We then create a “stage” to place the camera, geometry, materials and lights.
let stage: Stage = ctx
.new_stage()
.with_background_color([1.0, 1.0, 1.0, 1.0])
// For this demo we won't use lighting
.with_lighting(false);
The Stage
is neat in that it allows you to “stage” data
directly onto the GPU. Those values can be modified on the CPU and
synchronization will happen during Stage::render
.
Use one of the many Stage::new_*
functions to stage data on the GPU:
Stage::new_camera
Stage::new_vertices
Stage::new_indices
Stage::new_material
Stage::new_primitive
- …and more
In order to render, we need to “stage” a
Primitive
, which is a bundle of rendering
resources, roughly representing a singular mesh.
But first we’ll need a list of Vertex
organized
as triangles with counter-clockwise winding. Here we’ll use the builder
pattern to create a staged Primitive
using our vertices.
We’ll also create a Camera
so we can see the stage.
let vertices = stage.new_vertices([
Vertex::default()
.with_position([0.0, 0.0, 0.0])
.with_color([0.0, 1.0, 1.0, 1.0]),
Vertex::default()
.with_position([0.0, 100.0, 0.0])
.with_color([1.0, 1.0, 0.0, 1.0]),
Vertex::default()
.with_position([100.0, 0.0, 0.0])
.with_color([1.0, 0.0, 1.0, 1.0]),
]);
let triangle_prim = stage
.new_primitive()
.with_vertices(vertices);
let camera = stage.new_camera().with_default_ortho2d(100.0, 100.0);
§Rendering
Finally, we get the next frame from the context with
[Context::get_next_frame
]. Then we render to it using Stage::render
and then present the frame with [Frame::present
].
let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = futures_lite::future::block_on(frame.read_image()).unwrap();
frame.present();
Here for our purposes we also read the rendered frame as an image.
Saving img
should give us this:
§Modifying resources
Later, if we want to modify any of the staged values, we can do so through
each resource’s struct, using set_*
, modify_*
and with_*
functions.
The changes made will be synchronized to the GPU at the beginning of the
next Stage::render
function.
§Removing and hiding primitives
To remove primitives from the stage, use Stage::remove_primitive
.
This will remove the primitive from rendering entirely, but the GPU
resources will not be released until all clones have been dropped.
If you just want to mark a Primitive
invisible, use
Primitive::set_visible
.
§Releasing resources
GPU resources are automatically released when all clones are dropped.
The data they occupy on the GPU is reclaimed during calls to
Stage::render
.
If you would like to manually reclaim the resources of fully dropped
resources without rendering, you can do so with
Stage::commit
.
§Ensuring resources are released
Keep in mind that many resource functions (like Primitive::set_material
for example) take another resource as a parameter. In these functions the
parameter resource is cloned and held internally. This is done to keep
resources that are in use from being released. Therefore if you want a
resource to be released, you must ensure that all references to it are
removed. You can use the remove_*
functions on many resources for this
purpose, like Primitive::remove_material
, for example, which would
remove the material from the primitive. After that call, if no other
primitives are using that material and the material is dropped from
user code, the next call to Stage::render
or Stage::commit
will
reclaim the GPU resources of the material to be re-used.
Other resources like Vertices
, Indices
, Transform
,
NestedTransform
and others can simply be dropped.
§Next steps
For further introduction to what renderling can do, take a tour of the
Stage
type, or get started with the manual.
§WARNING
This is very much a work in progress.
Your mileage may vary, but I hope you get good use out of this library.
PRs, criticisms and ideas are all very much welcomed at the repo.
😀☕
Re-exports§
pub extern crate glam;
Modules§
- atlas
- Texture atlas.
- bloom
- Physically based bloom.
- bvol
- Bounding volumes and culling primitives.
- camera
- Camera projection, view and utilities.
- color
- Color utils.
- context
- Rendering context initialization
- convolution
- Convolution shaders.
- cubemap
- Cubemap utilities.
- cull
- Compute based culling.
- debug
- Debug overlay.
- draw
- Handles queueing draw calls.
- geometry
- Types and functions for staging geometry.
- gltf
- GLTF support.
- internal
- Internal types and functions.
- light
- Lighting effects.
- linkage
- Provides convenient wrappers around renderling shader linkage.
- material
- Atlas images, used for materials. CPU and GPU.
- math
- Mathematical helper types and functions.
- pbr
- “Physically based” types and functions.
- primitive
- Mesh primitives
- sdf
- SDF functions for use in shaders.
- skybox
- Rendering skylines at infinite distances.
- stage
- Scene staging.
- sync
- GPU locks and atomics.
- texture
- Wrapper around [
wgpu::Texture
]. - tonemapping
- Tonemapping from an HDR texture to SDR.
- transform
- Decomposed 3d transforms and hierarchies.
- tutorial
- Shaders used in the contributor intro tutorial and in WASM tests.
- types
- Type level machinery.
- ui
- User interface rendering.
Macros§
- println
- A wrapper around
std::println
that is a noop on the GPU.