Jet README

The project's README from github.com/CubeCoders/Jet. As one markdown file: README.md.

Jet logo

Jet

Jet is a dependency-free, fixed-function 3D software rasteriser written in C++17. It targets embedded hardware with limited CPU and memory, including ESP32 and STM32, and also runs on desktop PCs and Raspberry Pi.

Jet uses integer arithmetic in the rasterisation hot path and native 16-bit RGB565 colour for output to embedded displays. It supports flat-shaded, lit and textured geometry for low-poly games and visualisations.

On an ESP32-S3, Jet reaches a peak throughput of 70,000 triangles/second (flat-shaded). The demo below runs at a 480×320 output resolution and 60 FPS using half-width, interlaced field buffers. Throughput varies with scene complexity, triangle size and enabled rendering features.

Community

Share projects and get help on the Discord server.

Demo

A Wipeout-style game running on an ESP32-S3 at 60 FPS:

Jet on ESP32-S3: 60 FPS Wipeout-style demo

Feature highlights

Compile-time switches in JetConfig.hpp let you disable features to reduce CPU, RAM and flash usage. See src/JetConfig.example.hpp for the available options.

Rendering

Lighting

Post-FX

Tooling

2D Sprites

Sprite2D draws overlays after render(). It supports textured or solid-colour fills, colour-key transparency, alpha and additive blending, integer upscaling, and zOrder-based draw order. On HALF_WIDTH_BUFFERS builds, sprites are composited at full output resolution during display scanout.

Particles

ParticleSystem uses a fixed pool and renders through the rasteriser after scene->render(). It includes spark and water-splash emitters, distance culling, and configurable emitter counts and particle lifetimes.

Lens flare

LensFlare projects a directional light source to screen space and positions a sprite chain along the axis between the sun and screen centre. Fade speed, per-element axis offset (axisT), alpha, blend mode and integer scale are configurable. It can use a pick slot for sun occlusion testing; with MAX_PICK_QUERIES = 0, the sun is treated as unobstructed.

Getting started

Your application provides the framebuffer, display driver and main loop. Add Jet as a CMake subdirectory or ESP-IDF component, provide a JetConfig.hpp on your include path (copy and customise src/JetConfig.example.hpp), then call scene->render() once per frame.

For ESP-IDF, depend on it as you would any other component:

# main/idf_component.yml
dependencies:
  jet: "*"

Minimal example

Allocate colour and depth buffers, add a camera, lights and a cube, then render each frame:

#include "Jet.hpp"
using namespace Renderer;

// 320x240 RGB565 colour buffer + matching Z-buffer.
constexpr int W = 320, H = 240;
uint16_t color[W * H];
uint16_t depth[ZBUFFER_STRIDE(W) * H];

int main() {
    Scene  scene(color, depth, W, H);
    scene.setBackcolor(0x0000);          // RGB565 clear colour (black)
    scene.setClearBuffer(true);

    Camera camera;
    camera.setPosition(0, 0, -500);      // world units
    camera.setFOV(75, W);
    camera.nearPlane = 16;
    camera.farPlane  = 8192;
    scene.setCamera(&camera);

    DirectionalLight sun(Vector3{45, 35, 0}, Color{255, 245, 220}, 220);
    AmbientLight     amb(Color{40, 48, 64});
    scene.setDirectionalLight(&sun);
    scene.setAmbientLight(&amb);

    Material red(0xF800);                // RGB565: bright red
    red.shadingMode = ShadingMode::GOURAUD;

    Object* cube = Primitives::createCube(200, 200, 200, &red);
    cube->setPosition(0, 0, 200);
    scene.addObject(cube);

    // Per-frame: rotate, render, push the buffer to your display.
    for (;;) {
        cube->rotate(0, 1, 0);           // 1 degree per frame around Y
        scene.render();                  // colour buffer now contains the frame
        // pushToDisplay(color, W, H);   // <-- you provide this
    }
}

Documentation

The API reference is generated from the Doxygen comments in src/.

To build the docs locally (requires doxygen and optionally graphviz):

cd components/Jet/src
doxygen Doxyfile
# output: components/Jet/src/docs/html/index.html

GitHub Actions publishes the documentation on pushes to the default branch.

Licensing

Jet is distributed under the MIT License. The full text is in LICENSE.

You can use, modify and distribute Jet in open-source or closed-source projects, including commercial products, without a separate licence or fee. Include the copyright and permission notices as required by the MIT License.

Contributing

Submit bug reports, fixes, examples and documentation improvements through issues or pull requests on the official repository.

Before your first contribution, please read CONTRIBUTING.md. Contributions are accepted under the MIT License; no separate Contributor Licence Agreement is required.


Jet is a CubeCoders project.

Jet (CubeCoders/Jet)

Searching Database…

531 ·GitHub
Что это?Jet — это крошечный программный 3D-растеризатор с фиксированным набором функций на C++17, без внешних зависимостей, созданный для встраиваемых чипов с малым объёмом CPU и RAM, таких как ESP32 и STM32; он также работает на настольных ПК и Raspberry Pi.
Это готовый игровой движок или библиотека, на которой я напишу свой рендерер?Это библиотека, а не движок: ваше приложение предоставляет фреймбуфер, драйвер дисплея и главный цикл, а для отрисовки сцены в каждом кадре нужно просто вызвать scene->render().
Как добавить его в свой проект?Добавьте Jet как поддиректорию CMake или компонент ESP-IDF, скопируйте src/JetConfig.example.hpp в JetConfig.hpp в свой include-путь, настройте его под себя, а затем вызывайте scene->render() из собственного цикла.
В чём подвох — он заменит видеокарту?Нет — Jet рендерит на процессоре через конвейер с фиксированным набором функций, без аппаратного ускорения, поэтому реальная производительность зависит от сложности вашей сцены, размера треугольников и включённых возможностей.
Могу ли я использовать его в коммерческом проекте?Да — Jet распространяется по лицензии MIT, так что его можно использовать в проектах с открытым или закрытым кодом, включая коммерческие продукты, без отдельной лицензии или оплаты; нужно лишь сохранить уведомления об авторских правах и разрешениях.
Почему целочисленная математика и 16-битный RGB565 вместо чисел с плавающей запятой?Потому что цель — микроконтроллеры и небольшие встраиваемые дисплеи: Jet выполняет целочисленные вычисления в самом горячем участке растеризации и выдаёт нативный 16-битный RGB565, что подходит для ограниченных ресурсов CPU и памяти чипов вроде ESP32.
Есть ли поддержка эффектов постобработки?Да — CRT-сканлайны и cel-shading работают без дополнительного буфера, а FXAA, bloom, размытие в движении, хроматическая аберрация и пикселизация доступны как буферизованные эффекты на платформах с большим объёмом RAM.
Конвейер полностью фиксированный, или я могу добавить свои эффекты?Конвейер с фиксированным набором функций, но есть точка входа для пользовательских шейдеров, чтобы его расширять, а также специальные режимы вроде WATERREFLECT для анимированной воды и ADDITIVE для неоновых вывесок и ореолов взрывов.
Можно ли урезать его для совсем маленького устройства?Да — переключатели времени компиляции в JetConfig.hpp позволяют отключать возможности, чтобы снизить расход CPU, RAM и флеш-памяти; скопируйте src/JetConfig.example.hpp и выключите то, что ваша плата не потянет.
What are similar projects?NoGraphicsAPI, Marlin, bgfx, raylib, mongoose, coyopedal, assimp, WoWee
Creator
CubeCoders
Size
8.2 MB
Stars
531
Updated
CommitSep 25
Age
5mo
Commits · 90 Days