Repository navigation
Releases: M0Rf30/lactea
Releases · M0Rf30/lactea
Release list
v0.2.2
Added
- web: browser showcase on GitHub Pages (#20): playlist, drag-and-drop presets and textures, file / microphone / synthetic audio
Fixed
- web: the wasm32 build no longer hangs on the motion-vector UV readback under WebGPU; it uses the CPU warp UVs
Full changelog: CHANGELOG.md
v0.2.1
Fixed
- md2: BeatDrop shader inputs ported from source: BeatDrop's
include.fxprelude, separatesampler_fft(1024x2) andsampler_wave(480x2) textures, host vars and FFT coefficients blended over soft cuts - hlsl: the remaining
include.fxaliases (aspect_sd,SAMPLER*D,texture*D,trunc,tex1d,texcube) - capi: no dead-code warning for
VulkanState::formaton Apple targets
Full changelog: CHANGELOG.md
v0.2.0
Breaking
- lactea:
Engine::newreturnsResult<Engine, EngineError>(it sanitises the config: mesh clamp, size and fps of at least 1);Engine::resizereturnsResult<(), EngineError>andEngine::set_mesh_sizeResult<[u32; 2], EngineError>, both keep the old size on failure - lactea-render:
Renderer::new,resizeandset_mesh_sizereturnRenderError::Invalidfor a size beyond the device'smax_texture_dimension_2dor a mesh beyond 300 cells - lactea-render:
noise::generateandgen_noise_voltake&CompatRules;CompatRulesgainsmax_rand_slot,rand_filter_raw_name,noisevol_row_stride,shader_time_wrap,md2_shader_inputs,md2_input_vars(the struct is#[non_exhaustive]) - lactea-capi:
LacteaCompatis anint32_twithLACTEA_COMPAT_{PROJECTM,MILKDROP2,MILKDROP3,AUTO}constants instead of an enum; an unknown value makeslactea_createreturn NULL;lactea_set_fps(0)and a non-finitepreset_durationareInvalidArgument - lactea-preset:
ParseErrorgainsTooLarge,BinaryDataandNoKeys;Flavor::ProjectMnow rejects presets over 1 MiB, with a NUL byte, or without a key line, like projectM (the MilkDrop 2 flavour is unchanged) - lactea-jpeg: the
imagefallback for JPEGs stb rejects is gone (thejpegfeature of the C API and the CLI is removed); such files now fail to decode, as in projectM - lactea-hlsl:
Optionsgainsrand_max_slotandrand_strict_name - lactea-render, lactea-app, lactea-capi: wgpu is built without default features (
std,parking_lot,wgslplus one backend per platform); the OpenGL ES / WebGL backend is the opt-inglesfeature oflactea-render,lactea-appandlactea-capi - lactea-abi:
serdeis an optional feature (enabled bylactea-cliandlactea-compare) - web example:
resize()returnsResult<(), JsValue>
Added
- sprites: projectM user sprites:
Engine::{sprite_create, sprite_destroy, sprite_destroy_all, sprite_count, sprite_ids, set_max_sprites, max_sprites, sprite_var, set_sprite_var},lactea_preset::parse_user_spriteand the C APIlactea_sprite_*; during a soft cut they are drawn after the blend onto the output andburngoes into both presets - playlist:
lactea_playlist_*, a C API for everyprojectm_playlist_*call (a connected playlist loads files and answers the engine's switch requests);lactea_host::PlaylistFs::{add_path, insert_path}andscan_presets,.prjmaccepted wherever presets are scanned - api:
Engine::burn_texture/lactea_burn_texture_rgba,Engine::reload_textures/lactea_reset_textures,lactea::VCS_VERSION/lactea_vcs_version,lactea_set_log_callback/lactea_set_log_level(alogfacade bridge),lactea_set_texture_load_callback - md2: BeatDrop inputs under
Compat::MilkDrop2:mousex mousey mousedown mouseclick,ctrllt ctrlrt ctrldn ctrlupandyear .. totalsecondsexpression variables, shader_c14/_c15/_c16,Engine::{set_date_time, clear_date_time, set_ctrl_keys, monitor}and their C exports, and BeatDrop's shader FFT (lactea_audio::BeatDropShaderFft,sampler_fft/sampler_wave,get_fft*,get_wave) - engine:
PresetControl::preset_duration_sampledandEngine::set_loaded_preset_duration:progressruns over the sampled display time once a host reports it (the C API and the app do) - hlsl:
wrapped_hlsl(kind, user, md3, projectm)andrand_slot - eel:
Context::try_run - host: new crate
lactea-host(directory textures with an optional decode cache, image / media / WAV decode, GPU setup, preset scanning) shared by the C API, the CLI and the app; new unpublished cratelactea-testutil(shared GPU test helpers) - render:
readback_rgba8is public
Changed
- render: projectM-flavour shaders write alpha 1.0 (
MilkdropShader.cpp:468); thenoisevol_*textures use projectM'sz * sizeslice stride (noisevol_row_stride);_c2.xis the raw time under MilkDrop 2 (projectM and MilkDrop 3 wrap it modulo 10000,shader_time_wrap) - engine: one
randNNparser for samplers andtexsize_randNN, slot range 15 (projectM) / 99 (MilkDrop 2); the pool prefix filter reads the raw sampler name in projectM mode (a quality prefix defeats it) and the peeled name in MilkDrop 2 - engine: the first rendered frame has
dt = 0;set_fps(0)is ignored; a transition of duration 0 reports progress 1 - audio: non-finite PCM samples read as 0 (MD3: ±inf saturates, NaN is 0) and a non-finite volume sensitivity is ignored
- app: the preset browser runs on
PlaylistandPresetControl(the app's Random can repeat the current preset, asPlaylist's pick does; seeded display-time draws differ from before); textures come fromlactea_host::DirTexturesin projectM scan order (directory order, then path) and.ddsfiles are indexed;--duration,--transition-durationand--duration-randmust be finite and at most 1e9 s;ResetRequiredrebuilds the audio decoder from the new default track; symphonia is built with an explicit format list - jpeg: decoding is bounded to 2 GiB, allocations are fallible, and a frame without a scan is an error
- wav: a short
fmtchunk is an error - perf: release builds use fat LTO and strip symbols and wgpu keeps one backend per platform (the
fdrenderrelease binary shrinks from 87 MB to 7.3 MB); per-frame wave, overlay, motion-vector, border and vertex buffers are reused, blit and blur bind groups are cached, and the MD3 spectrum FFT is cached - refactor:
lactea-render'srenderer.rsis split intorenderer/{mod, pipelines, uv_readback, orchestrate, passes, fixed, burn}.rs; the MD2 and MD3 blend patterns sharegen_plasma(engine/blend_patterns.rs); wave, shader-snippet and sprite-fragment helpers are shared
Fixed
- engine:
Engine::newno longer panics on a zero size or a tiny mesh (an MD2 soft cut with mesh[3, 5]used to) - eel: parse paths no longer panic;
Context::runreturns 0 for a foreign program andContext::get/set,GlobalMemory::reg/set_regignore foreign variables and out-of-range registers;megabuf/gmegabufblocks are allocated on first write - render: a zero-width
volume_alpha_modis a step, not NaN; the MD2 main wave and its raw geometry return nothing for fewer than 576 samples; the MD2 shape border gate is> 0; byte-length and read-back arithmetic usesusize/u64 - preset:
SpriteName=is read after its own key, not after the first= - capi: the read-back buffer is released on every error path; the
lactea_set_texture_dirextension list and theLacteaConfig::compatdocumentation are corrected - sprites: a user sprite over a soft cut is no longer distorted by the transition
Full changelog: CHANGELOG.md
v0.1.2
Added
- md3: MilkDrop 3 (3.37) support behind
Compat::MilkDrop3:.milk2double presets, 30 MD3 blend patterns, preset sprites (11 blend modes, layers, GIF),get_fft/ mouse /q33-q64shader inputs, the ns-eel2 expression dialect, wave modes 0-16, 500-side shapes,.wave/.shapeimport and export, auto hard-cut modes 1-7 (#7) - md3: the
_mxd3qxa.._d/_mxd3qsa.._caudio-envelope / beat-latch shader uniforms (and theMXD3QX1..16/MXD3QS1..12prelude macros) are computed per frame instead of being undeclared (#11) - app:
--compat autois the default: MD3 files are detected by content, and a preset falls back to MilkDrop 2 when projectM fails to compile its shaders (#9) - app:
--shader-override-warp/--shader-override-comp HANDLE=FILE, as infdrender(#11)
Changed
- perf: output-identical renderer and VM work, 22-47 % fewer instructions (#9)
- md2: code lines are joined without a separator, as in MilkDrop 2 (#7)
Fixed
- lactea: in auto compat, a preset whose shader projectM cannot translate is retried under MilkDrop 2 (#10)
- md3: robustness fixes and projectM fidelity fixes (#9)
Full changelog: CHANGELOG.md
Lactea 0.1.1
First public release of Lactea (0.1.1: 0.1.0 crates were published but its Windows build failed, so this is the first release with binaries), a pure-Rust MilkDrop 2 / projectM-compatible music visualizer on wgpu (Vulkan, Metal, DX12, GL, WebGPU).
Matches the projectM reference on 99.8 % of the 4169 comparable presets of the projectM preset collection (method and details in docs/fidelity.md).
Highlights
- Embeddable engine (
lactea): renders into any wgpu texture the host provides. No windows, audio devices or filesystem access in the library; presets, textures and PCM come in as bytes. - projectM or MilkDrop 2 semantics (
Compat::ProjectM, default, orCompat::MilkDrop2). - Soft preset transitions (projectM's six blend shaders), playlist, preset lock, beat-driven hard cuts, runtime mesh / fps / duration changes, idle preset.
- Shaders: MilkDrop HLSL (ps_2 / ps_3 +
include.fx) translated to WGSL; 1422 of 1423 corpus shaders. - Expressions: ns-eel2 / projectm-eval compatible VM, bitwise equal to projectm-eval and faster.
- Standalone app (
lactea): PipeWire "what you hear" capture (cpal elsewhere), audio file playback, preset browsing, fullscreen, soft cuts. - C API (
lactea-capi): render to an RGBA8 buffer or into a hostVkImage; cbindgen headerlactea.h. - WebAssembly: the engine builds for
wasm32-unknown-unknownand runs on WebGPU.
Crates
| crate | |
|---|---|
lactea |
engine |
lactea-render |
wgpu MilkDrop 2 frame pipeline |
lactea-preset |
.milk parser |
lactea-eel |
expression language |
lactea-hlsl |
HLSL → WGSL |
lactea-audio |
audio analysis |
lactea-jpeg |
stb_image-exact JPEG decoder |
lactea-abi |
shared contract |
[dependencies]
lactea = "0.1"Downloads
| asset | contents |
|---|---|
lactea-v0.1.1-linux-x86_64.tar.gz |
lactea app (PipeWire + cpal), liblactea_capi.so/.a, lactea.h, desktop file, icon |
lactea-v0.1.1-windows-x86_64.zip |
lactea.exe (cpal), lactea_capi.dll/.lib, lactea.h |
lactea-v0.1.1-macos-arm64.tar.gz |
lactea app (cpal), liblactea_capi.dylib/.a, lactea.h |
SHA256SUMS |
checksums |
Windows and macOS builds are produced by CI but have not been tested on real machines yet; reports welcome.
Known limitations
- Vulkan interop in the C API is not available on Apple platforms.
- A handful of presets still differ from projectM by single pixels or float precision; see Open items.
Full changelog: CHANGELOG.md
