Hello people. It’s been weeks I have started to work on luminance-1.0.0. For a brief recap, luminance is a graphics crate that I originally created in Haskell, when I ripped it off from a demoscene engine called quaazar in order to make and maintain tiner packages. The Rust port was my first Rust project and it became quickly the default language I would develop graphics applications in.
So if you’re interested, yes, luminance in Haskell still exists but I maintain it for strictly minimal support (i.e. support compiler bumps, for instance). The default and official language to use, if you’re interested by luminance, is Rust.
Another important thing I have to explain is the current feature list of luminance and what it’s going to be soon. Currently, luminance’s goals are (according to the documentation):
That’s the current situaton. A very important other aspect is that luminance was designed, in the first place, to be backend agnostic. I quickly decided not to go this way and stick to a simpler design with OpenGL only.
A comparison between luminance and other famous crates is available here.
However, I have — again! — changed my mind. Today, I want to have a system of backend in luminance. Maybe not something as complex and complete as the gfx-rs project, but something that will allow those backends:
I really do not target Metal, DirectX12 nor any other graphics backend you might have in mind. However, if you think it’s possible to do so, then we should discuss about it. Nevertheless, as I said above, luminance is need-driven: as I don’t need DirectX12, I will not work on it unless someone REALLY needs it and provides a PR (or at least enough for me to work on it… including beers).
luminance-1.0.0 will ship… as soon as possible. The current feature set is huge, though:
"std"
feature-gate. This will help use luminance with specific contexts, especially
for demoscene or size-limited devices. Currently, the work on no_std
has been saved for later
as I had hit a bug last time I checked.Tess
interface. Now, a TessBuilder
must be used. This allows for three major
enhancements:
unsafe
traits easily, without writing any unsafe
code. Among those:
Vertex
trait, used to create vertex types.Semantics
trait, used to create vertex semantics types.UniformInterface
trait, used to create shader uniform interfaces.macro_rules
are removed.GL33
driver
for OpenGL 3.3, a GL40
, GL44
, GL45
etc., but you can also have WebGL
and VK10
.Tess
— instead of using the current method with GPU Buffer<_>
. This was
asked by several people and I just couldn’t ignore such an interesting and useful feature!TriangleFan
or LineStrip
and “cut” a primitive if an index is equal to a given value. This
is very useful for implementing terrains, quadrics or a lot of other nice things.Vertex
type and the order
in which the fields appear in the struct
defines the bindings the GPU will present to
shaders… but it’s the user responsibility to tell how the shader will fetch those attributes.
This can lead to very wrong situations in which, for instance, the GPU present the normal
attribute as having the index 4
but the shader tries to fetch them on index 2
. Vertex
semantics fix this situation by adding an intermediate layer both the user and the GPU (i.e. via
luminance) must speak: semantics. Semantics are user-defined and none is hardcoded in
luminance. As soon as a type uses vertex semantics, all the type system knows how to forward
that information to shaders and what shaders should do to fetch them. The other bonus, ultra
cool thing is that shaders and memory buffers now compose way better: since vertex semantics
define a sort of namespace, you will never have two shaders using the same index for different
semantics (unless you use completely different vertex semantics type). A very cool feature I’m
proud of and that I will detail in a future article / luminance tutorial.You might be wondering “Woah, this is such a big feature set. A lot of things are coming! Why not having split the feature set into several releases?”, and that’s a good question.
Lately, I’ve been feeling on-and-off about everything I do on my spare-time on the FOSS level. I have several crates I care about and sometimes people show up and start asking for features and/or bug fixes. This takes some time and after a long day of work, I sometimes feel that I just want to hack on things I like, play my electric guitar, go to swim or wakeboard or just spend time with people I care about and love.
Currently, luminance — even though it has an unexpected amount of downloads! — is not a famous crate. People nowadays talk about crates living in a higher-level stack, such as ggez, gfx, amethyst, piston, etc. I don’t communicate a lot about luminance because of, mostly, two things:
I guess Haskellers will get the second point. ;)
My own philosophy about software and especially my own software is that it should have a top-tier
quality, both in terms of API design, elegance, type safety, performance and documentation. The
front documentation of warmy is a good example of something I continuously
seek, because good documentation helps my future myself to read the code and public interface but
also for onboarding people. Lots of projects — especially in professional industries — suffer from
knowledge bubbles, in which just a bunch (often only one!) of people know about A
and B
and
when someone joins in, they’re lost and have to ask questions. As an engineer, I always write
everything I know in whatever source-of-truth the company I’m in can offer (it can be a Confluence
server; a git repository; a wiki; whatever) because sharing knowledge and writing processes is key
in engineering — also, pro tip: I highly value that when interviewing candidates!
But the more I advance and grow up, the more things I learn and the more things I master. And as I master new things, I tend to get used to them. And the “mental effort” it requires tends to slowly disappear. I remember when I tried (hard!) to wrap my finger around what a profunctor is, or what free monads or even natural transformations are and how to use them. It was hard. As a friend of mine (@lucasdicciocio) perfectly summarized it some times ago, when we learn something as a beginner, we struggle. But people who master those concepts struggle even harder when trying to learn the next concepts at hand. And I’m not an exception. Today, free monads are something I know (even though I don’t use them; it’s a myth! it’s a trap! :D) and I feel like I’m not legitimate to talk about them because they feel easy — and it’s normal, since I’ve learned them. But I see new things to learn, new hard things that I know I’ll be struggling with for a while. And now it feeds the imposter syndrom. You know, when you’re 20, you feel like you know a lot of things (and you likely do) and that you’re pretty confident with your skill base. Today, I’m 27, and I feel like I will always be a rookie, because there is always something I don’t know to struggle with. And I find that very exciting. Of course, I don’t project that on others, which is soooo paradoxal: I don’t expect a newcomer to tell me what a fundep is or know lifetime elision rules in Rust. But I guess I have a very very strict way to judge my knowledge. I still haven’t figured out if it’s a good thing or if it’s not.
I’ve been told that talking about what I do, what I think, what I know and my engineering philosophy should help with this kind of questioning. So I decided to use that blog article to share some thoughts about the next release of luminance that took me so much of my spare-time (but happily!) and to talk a bit about myself. I know a lot of people in the Rust and Haskell community don’t know me, but I also know lots of other folks do know me, in both communities. I hope my little vent will give people some relief — maybe you too have a similar experience? Please share your comments on the Reddit thread this article is post in.
As always, stick doing awesome things and spend your spare-time wisely. Spend time with the ones you love and do the things you hecking love too!
Keep the vibes!