owned this note
owned this note
Published
Linked with GitHub
# Bevy's rendering-dev core principles
Writing a renderer has many tradeoffs.
Bevy's standard rendering setup cannot aim to satisfy everyone. Instead, we've chosen to focus on creating a flexible renderer while making sure that basic functionality works well out-of-the-box.
To help you understand the tradeoffs we've made (and guide further development), we've written a list of core principles that we use to determine the direction of Bevy's rendering features.
This list is aspirational: aiming to capture our design philosophy and goals, not describe the state of the renderer as it exists today.
- General purpose
- Bevy's renderer should be useful to a broad range of users, styles and applications: from pixel art to stylized 2D to high-end PBR to CAD visualizations.
- While Bevy's core audience is game devs, we care about supporting a wide range of use cases across the engine, including in rendering. It's okay to use game-focused examples and concepts in our learning and marketing material, but creative coders, artists, VJs, scientists, simulation makers and more are first-class users of Bevy's renderer too.
- Empowering
- As the foreword of the Rust Book says, ["the Rust programming language is fundamentally about empowerment: no matter what kind of code you are writing now, Rust empowers you to reach farther, to program with confidence in a wider variety of domains than you did before."][1]. The same is true for Bevy's renderer.
- Common tasks and simple changes should be easy: without a lot of boilerplate, advanced knowledge or jargon.
- User experience matters, especially when adding new features. We need to consider the UX of both the new feature itself, and how it interacts with other existing features.
- Ultimately, we can't add all of the advanced features every user might want. Instead, Bevy's renderer should be seen as a toolbox, empowering them to build exactly what they need to the specifications.
- Modular
- Users should be able to use only the parts of the renderer they want; including none of it at all.
- For example, defining a scene should not depend on the renderer used to render that scene. Users should be able to replace parts of the renderer without having to also change how they define a scene.
- Cross platform
- As part of its goals to serve a broad audience of devs and users, Bevy aims to support a wide range of operating systems, devices and hardware capability.
- The details of the platforms we currently support is given in our [platform tier policy](NOT YET WRITTEN).
- Whenever possible, we attempt to detect device limitations programatically via feature detection, and degrade gracefully.
- While we aim to support each feature on every device it can run on, we are not bound by the lowest-common-denominator. Both high-end and low-end features can be worth adding, even if they can't or shouldn't be used everywhere.
- Easy to maintain
- Despite Bevy's ambition, it is ultimately powered by a relatively small team of volunteers.
- Keeping on top of tech debt, limiting the inclusion of niche features, automating testing and keeping a clean, well-documented code base are all essential for stretching out time and effort further.
- Use standards
- Bevy relies on standards whenever possible. When making new features, we try to use existing standards instead of making a new competing standard.
- For example, instead of making our own rendering hardware abstraction we used wgpu/webgpu.
- For shaders we are embracing wgsl and it's ecosystem.
- For scene definitions we support glTF with many extensions.
- Similarly, we aim to use modern, industry-standard techniques: learning from other renderers, implementing papers, and only reinventing the wheel when results are clearly better.
- Performant
- Like the rest of Bevy, we aim to balance performance improvements with a user-centric focus on usability, stability and features.
- We care most about performance under realistic loads: not empty scenes or comically large stress tests.
- Performance isn't just FPS: stuttering, RAM and VRAM usage, loading times and more must all be considered holistically.
- Our architecture should make things "fast by default", and expose and explain tuning knobs to speed up scenarios.
- As a last resort, we should support users who want to rewrite and finetune bits of our rendering infrastructure to meet their exact performance needs, through the use of a thoughtful modular architecture.
[1]: <https://doc.rust-lang.org/book/foreword.html>