Expand description
A “GPU driven” renderer with a focus on simplicity and ease of use. Backed by WebGPU.
Shaders are written in Rust using rust-gpu.
All data is staged on the GPU using a slab allocator.
§Hello triangle
First you must create a crate::context::Context.
use renderling::Context;
// create a headless context with dimensions 100, 100.
let ctx = Context::headless(100, 100);Then create a stage to place your camera, geometry, materials and lights.
use renderling::stage::Stage;
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 place values and arrays of values
directly onto the GPU. Those values can be modified on the CPU and
synchronization will happen during
Stage::render. These values are called
Hybrids and
HybridArrays.
use renderling::slab::{Hybrid, HybridArray};
let an_f32: Hybrid<f32> = stage.new_value(1337.0);
let an_array_of_tuples: HybridArray<(f32, u32, bool)> =
stage.new_array([(0.0, 0, false), (1.0, 1, true)]);In order to render, we need to “stage” a
Renderlet, which is a bundle of rendering
resources. We do this in the same way we “staged” an_f32 above.
But first we’ll need a Camera and some vertices
of Vertex organized as triangles with
counter-clockwise winding.
use renderling::{
camera::Camera,
stage::{Renderlet, Vertex},
};
let camera = stage.new_value(Camera::default_ortho2d(100.0, 100.0));
let vertices = stage.new_array([
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 = stage.new_value(Renderlet {
camera_id: camera.id(),
vertices_array: vertices.array(),
..Default::default()
});This gives us triangle, which is a Hybrid<Renderlet>. We can now pass
triangle to the stage to draw each frame using
Stage::add_renderlet.
Finally, we get the next frame from the context with
Context::get_next_frame, render to it using
Stage::render and then present the
frame with Frame::present.
stage.add_renderlet(&triangle);
let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = frame.read_image().unwrap();
frame.present();Saving img should give us this:

§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.
😀☕
Modules§
- atlas
- Texture atlas.
- bits
- Helpers for bitwise operations.
- bloom
- Physically based bloom.
- camera
- Camera projection, view and utilities.
- color
- Color utils.
- convolution
- Convolution shaders.
- cubemap
- Render pipelines and layouts for creating cubemaps.
- ibl
- Resources for image based lighting.
- math
- Mathematical helper types and functions.
- pbr
- “Physically based” types and functions.
- prelude
- A prelude, meant to be glob-imported.
- skybox
- Skybox shaders and CPU code.
- slab
- GPU and CPU slab allocation.
- stage
- GPU staging area.
- texture
- Wrapper around
wgpu::Texture. - tonemapping
- Tonemapping from an HDR texture to SDR.
- transform
- Decomposed 3d transform.
- tutorial
- A tutorial module for the renderling crate.
Macros§
- println
- A wrapper around
std::printlnthat is a noop on the GPU.
Structs§
- Context
- Contains the adapter, device, queue and
RenderTarget. - Frame
- Represents the current frame of a render target.
- Frame
Texture View - A thin wrapper over
wgpu::TextureViewreturned byFrame::view. - Render
Target - Either a surface or a texture.