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_stdhas been saved for later as I had hit a bug last time I checked.
Tessinterface. Now, a
TessBuildermust be used. This allows for three major enhancements:
unsafetraits easily, without writing any
unsafecode. Among those:
Vertextrait, used to create vertex types.
Semanticstrait, used to create vertex semantics types.
UniformInterfacetrait, used to create shader uniform interfaces.
GL33driver for OpenGL 3.3, a
GL45etc., but you can also have
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!
LineStripand “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.
Vertextype and the order in which the fields appear in the
structdefines 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
4but 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
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!