LightPlayer is a work-in-progress application for controlling visual effects on the esp32c6 microcontroller using GLSL shaders.
GLSL shaders are used to define the visual effects, which are just-in-time (JIT) compiled to native RISC-V code on the target device.
The architecture is client-server, designed for headless operation on unattended devices, controlled from a web UI, native app, or by api.
To run the demo project:
# Clone the repo
git clone https://github.com/Yona-Appletree/lp2025.git
cd lp2025
# Initialize your development environment
scripts/dev-init.sh
# Run the demo
just demo
# Run other examples
just demo -- <example-name>To flash firmware, push the examples/basic project over USB serial, and run it on real hardware:
just demo-esp32c6-hostYou need an ESP32-C6 board connected by USB, the RISC-V target installed (the recipe runs install-rv32-target), and espflash on your PATH for flashing.
Wiring (GPIO is hardcoded today): connect a WS2812-class addressable strip (or other device driven the same way) to GPIO 18 as the data line—not the pin field in examples/basic/src/strip.output/node.json, which the firmware does not use yet. The firmware initializes a buffer for 256 LEDs; the basic demo mapping uses 241 pixels, which fits in that limit.
For an empty flash and firmware only (no project push), use just demo-esp32c6-standalone.
To get started with development:
-
Initialize the development environment:
scripts/dev-init.sh
This will:
- Check for required tools (Rust, Cargo, rustup, just, oxipng)
- Verify Rust version meets minimum requirements (1.90.0+)
- Install the RISC-V target (
riscv32imac-unknown-none-elf) if needed - Set up git hooks (pre-commit hook runs
just check)
-
Required tools:
- Rust toolchain (1.90.0 or later) - Install Rust
just- Task runner:cargo install justor via package manageroxipng- Lossless PNG optimizer for Studio story image baselines:cargo install oxipngorbrew install oxipng
-
Common development commands:
just fci- Fix, check, build, and test the whole project. Do this before you submit a PR.just fci-app- Fix, check, build, and test the application.just fci-glsl- Fix, check, build, and test the GLSL compiler.
See just --list for all available commands.
Developer-facing command-line tools for creating projects, running the dev server, inspecting
compiler/runtime behavior, and managing checked-in hardware manifests. lp-cli is intended to run
from a LightPlayer source checkout and may assume repository paths such as
lp-core/lpc-shared/boards; it is not currently a deployable end-user command-line product.
Hardware manifests can be browsed and edited with:
cargo run -p lp-cli -- hardware manifestGPIO label calibration is host-driven. Flash the simple calibration firmware, attach a scope to the board label you want to identify, then run the CLI loop:
just fwtest-gpio-calibrate-esp32c6
cargo run -p lp-cli -- hardware calibrate esp32c6 --board seeed/xiao-esp32-c6 --port serial:autoDuring calibration, Enter means no/next, y records the visible board label for the active HAL
GPIO, p goes back one candidate, and q quits with resume state under target/hardware-calibration.
fw-coreCore firmware abstractions (serial I/O, transport, logging infrastructure)fw-emuFirmware that runs in the RISC-V32 emulator for testing without hardwarefw-testsIntegration tests for firmware (emulator-based testing and USB serial tests)fw-esp32ESP32 firmware
USB serial integration tests verify firmware behavior with real hardware:
# Run USB serial tests (requires connected ESP32)
cargo test --package fw-tests --features test_usb -- --ignored
# Run with debug output
DEBUG=1 cargo test --package fw-tests --features test_usb -- --ignoredSee lp-fw/fw-tests/README.md for more details.
lp-engineCore rendering engine that executes shaders and manages nodes (fixtures, textures, outputs)lp-engine-clientClient forlp-engine, handling state sync and local project viewlp-serverServer that manages projects and handles client connectionslp-clientAsync client library for communicating withlp-server. Manages filesystem sync and project management.lp-modelData models and API definitions for projects, nodes, and server communicationlp-sharedShared utilities for filesystem, logging, time, and transport
Full layout and commands: lp-shader/README.md.
lps-frontendGLSL → LPIR (via naga)lpirLightPlayer IR definitionslpvm-nativeLPIR → custom RV32 machine code (default on-device JIT)lpvm-craneliftLPIR → Cranelift → RISC-V machine code (reference backend)lpvm-wasmLPIR → WASM (browser /wasm.q32filetests)lps-q32Fixed-point Q16.16 types:Q32scalar,Vec2Q32–Vec4Q32,Mat2Q32–Mat4Q32, component-wise math helpers, constant encoding for compilerlps-sharedShared type and function-signature shapes for tests / exec helperslps-diagnosticsError codes, spans,GlslErrorlpvmRuntime values and literal parsing (usesglslparser fork where needed)lps-builtin-idsGenerated enum of builtin function IDslps-builtinsRust functions used by the generated code: fixed-point math, glsl builtins, lygia-inspired library of native glsl functionslps-builtins-emu-appRISC-V guest for running tests linked against builtinslps-builtins-gen-appCode generator for builtin function boilerplatelps-filetestsCollection of tests for GLSL spec compliance and correctnesslps-filetests-gen-appGenerator for repetitive filetests (vector, matrices)lps-filetests-appFiletest runner binarylpfn-impl-macroMacros for builtin function implementations
lp-riscv-emuRISC-V 32-bit emulator used for testing and developmentlp-riscv-emu-sharedShared types between emulator host and guestlp-riscv-emu-guestGuest-side runtime for emulated environmentlp-riscv-emu-guest-test-appTest application for emulator guestlp-riscv-instRISC-V instruction encoding/decoding utilities (no_std)lp-riscv-elfELF file loading and linking utilities (std required)
examples/Example LightPlayer projectsdocs/Documentation, plans, and design notesscripts/Build scripts and development utilities
LightPlayer would not be possible without the amazing work of these projects:
- Cranelift - Fast, secure compiler
backend (forked to support 32-bit RISC-V and
no_std) - Naga - Shader IR and
glsl-inGLSL frontend (used bylps-frontend) - pp-rs - GLSL preprocessor fork, patched in
[patch.crates-io]in the workspaceCargo.tomlso nagaglsl-inworks onno_stdtargets - glsl-parser - GLSL parser ( forked for spans)
- Lygia - Shader library (source for lpfn built-in functions)
- DirectXShaderCompiler - HLSL compiler ( compiler architecture inspiration)
- esp-hal - Pure Rust ESP32 bare metal HAL (used for ESP32 firmware)
- GLSL Specification - GLSL language reference
- RISC-V Instruction Set Manual - RISC-V architecture documentation
- RISC-V ELF psABI Specification - RISC-V ABI documentation
... and many more not listed. Thank you to everyone in the open source community for your work.
Special thanks to @SeanConnell for his support and guidance throughout the development of the project.
LightPlayer-owned code is licensed under the GNU Affero General Public License version 3 or later
(AGPL-3.0-or-later). See LICENSE for the full license text.
Third-party code, vendored forks, and dependencies remain under their own licenses.
Contributions are accepted under the terms in CONTRIBUTING.md.