Limelight
Limelight is a WebGL2
wrapper with a focus on making high-performance WebAssembly graphics code easier to write and maintain.
demo.mov
Specifically, limelight
:
- Provides a functional interface that abstracts away the statefulness of WebGL. It accomplishes this by using a shadow GPU that tracks the GPU's state, diffs it with the desired state, and sends only the necessary instructions to WebGL.
- Provides abstractions for buffers and uniforms that defer GPU data transfer until the next draw cycle.
- Provides a typed interface to uniforms and buffers, and automatically generates bindings between shader attributes and Rust
struct
s through a derive macro. - Provides an interface for transforms like zoom and pan through
limelight-transform
. - Provides 2D shape primitives like circles and lines through
limelight-primitives
.
Getting started
This example uses limelight-primitives
and limelight-yew
to construct a basic, static image made from circles and rectangles.
use anyhow::Result;
use limelight::{renderer::Drawable, Renderer};
use limelight_primitives::{Circle, CircleLayer, Rect, RectLayer};
use limelight_yew::{LimelightComponent, LimelightController};
struct Primitives {
rects: RectLayer,
circles: CircleLayer,
}
impl LimelightController for Primitives {
fn draw(
&mut self,
renderer: &mut Renderer,
_ts: f64,
) -> Result
{
self.rects.
draw(renderer)?;
self.circles.
draw(renderer)?;
Ok(
false)
}
}
impl
Default
for
Primitives {
fn
default() ->
Self {
let rects
= RectLayer
::
new();
let circles
= CircleLayer
::
new();
rects.
buffer().
set_data(
vec![
Rect {
lower_right: [
0.4,
0.1],
upper_left: [
-
0.8,
0.2],
color: palette
::named
::TOMATO.
into(),
},
Rect {
lower_right: [
0.4,
0.25],
upper_left: [
-
0.6,
0.5],
color: palette
::named
::SLATEBLUE.
into(),
},
]);
circles.
buffer().
set_data(
vec![
Circle {
position: [
0.,
0.25],
radius:
0.2,
color: palette
::named
::WHITE.
into(),
},
Circle {
position: [
0.,
0.25],
radius:
0.1,
color: palette
::named
::ORANGERED.
into(),
},
]);
Primitives { rects, circles }
}
}
fn
main() {
console_error_panic_hook
::
set_once();
wasm_logger
::
init(wasm_logger
::Config
::
default());
yew
::
start_app
::
>();
}