Crates.io | shades |
lib.rs | shades |
version | 0.4.0 |
source | src |
created_at | 2021-01-18 00:19:11.387552 |
updated_at | 2022-07-19 14:46:36.435941 |
description | An EDSL for shading languages |
homepage | https://github.com/phaazon/shades |
repository | https://github.com/phaazon/shades |
max_upload_size | |
id | 343320 |
size | 173,314 |
This crate provides an EDSL to build shaders, leveraging the Rust compiler (rustc
) and its type system to ensure
soundness and typing. Because shaders are written in Rust, this crate is completely language agnostic: it can in theory
target any shading language – the current tier-1 language being GLSL. The EDSL allows to statically type shaders
while still generating the actual shading code at runtime.
In typical graphics libraries and engines, shaders are opaque strings – either hard-coded in the program, read from a file at runtime, constructed via fragments of strings concatenated with each others, etc. The strings are passed to the graphics drivers, which will compile and link the code at runtime. It is the responsibility of the runtime (i.e. the graphics library, engine or the application) to check for errors and react correctly. Shading languages can also be compiled off-line, and their bytecode is then used at runtime (c.f. SPIR-V).
For a lot of people, this has proven okay for decades and even allowed live coding: because the shading code is loaded at runtime, it is possible to re-load, re-compile and re-link it every time a change happens. However, this comes with a non-negligible drawbacks:
dlopen
, dlsym
, etc. It’s more work but it’s possible. And
Rust can do it too.The author (@phaazon) of this crate thinks that shading code is still code, and that it should be treated as such. It’s easy to see the power of live-coding / reloading, but it’s more important to provide a shading code that is statically proven sound and with less bugs that without the static check. Also, as stated above, using a compiled approach doesn’t prevent from writing a relocatable object, compiled isolated and reload this object, providing roughly the same functionality as live-coding.
Important note: this crate does its best to catch semantic bugs at compile-time via
rustc
. However, it might still lack opportunities to catch all semantic bugs. If you find such a case, please feel free to open an issue to as that is considered a bug / regression.
Another important point is the choice of using an EDSL. Some people would argue that Rust has other interesting and powerful ways to achieve the same goal. It is important to notice that this crate doesn’t provide a compiler to compile Rust code to a shading language. Instead, it provides a Rust crate that will still generate the shading code at runtime. Other alternatives would be using a proc-macro. Several crates who do this:
glsl! { /* here */ }
) and get it compiled and check at runtime. It’s still
GLSL, though, and the possibilities of runtime combinations are much less than an EDSL.core
library.If you like type systems, languages and basically hacking compilers (writing code for your compiler to generate the runtime code!), then it’s likely you’ll like this crate. Among all the features you will find:
bool
, f32
or [T; N]
.Vertex
and returning another object, that will be passed to the next stage.rustc
. For instance, assigning a bool
to a f32
in your shader code will trigger a
rustc
error.π
constant. This
situation is fixed so you will never have to write π
decimals by yourself anymore.The crate is, as of nowadays, still very experimental. Here’s a list of things you might dislike about the crate:
for
loop in GLSL is written
with a much more convoluted way with this crate. The generated code is the same, but it is correctly more verbose via
this crate.