v0.19.0

Edit

LÖVR v0.19.0, codename Forbidden Jorts, was released on June 7th, 2026. This version has been 478 days in the making, with 684 commits from 11 authors.

The main highlights of this release are:

Raytracing

LÖVR supports GPU ray tracing now! Shaders can shoot rays into the world and get back hit info, using it to implement lighting effects like shadows or ambient occlusion. Here's a ray traced ambient occlusion effect:

Left: unlit. Middle: ray traced ambient occlusion. Right: combined.

A new Raytracer object holds a collection of Mesh and Model objects that the rays can hit. Dynamic geometry and animated models are supported. Most Vulkan GPUs support the necessary ray tracing features, even some mobile GPUs like the one in the Quest 3!

Spatial Audio

The audio module was almost completely rewritten for v0.19.0! SteamAudio is included by default now, along with a bunch of new features, better performance, and API improvements across the board.

SteamAudio

SteamAudio was previously available as an audio spatializer, but wasn't included by default because it was closed source and its file size was huge. However, SteamAudio was open sourced recently, so it can be shipped with LÖVR by default now! LÖVR also upgraded to the latest version of SteamAudio and exposed more of its features.

AudioMesh

There's a new AudioMesh object that defines the geometry that audio bounces off of in the scene, influencing reverb and occlusion effects. Audio meshes replace the old lovr.audio.setGeometry function. Compared to the old method, audio meshes can have multiple materials, and they can also be added, removed, and repositioned dynamically.

Ambisonic Sounds

It's now possible to play ambisonic sounds from WAV files. These are 3D soundfields that support rotation, binaural spatialization, and reverb. They're a great way to add immersive 360 audio all around the listener using a single audio source, instead of creating, positioning, and mixing dozens of individual ones.

Improved Reverb

There are lots of new conf.lua options to configure the type of reverb, the max number of rays and bounces used during ray tracing, and the max duration of the reverb tail. LÖVR also computes reverb on a background thread, allows choosing between per-source and listener-centric reverb, and supports changing the reverb volume for each Source independently.

Binaural Spatialization

lovr.audio.setHRTF let you specify a custom SOFA file to use for binaural audio spatialization.

Binaural audio spatialization is now a continuous value between 0 and 1 instead of a boolean. This makes it possible to smoothly transition between stereo audio and binaurally spatialized audio, useful for objects close to the listener.

Miscellaneous

Controller Models

lovr.headset.newModel can load animated controller models now using the new XR_EXT_render_model OpenXR extension. Calling lovr.headset.animate is all that's needed to animate the controller to match the button state:

There's also a lovr.modelschanged event, called when new models are available or old ones are no longer needed.

Microgestures

Quest added support for "microgestures" which are performed by swiping the thumb along the index finger. This is exposed as a virtual dpad on each hand.

HDR Displays

LÖVR has experimental support for HDR displays on Windows and macOS. Set t.graphics.hdr = true in conf.lua to request an HDR10 window, and use lovr.graphics.isHDR to check if it was supported.

On the left, an SDR image of a triangle with Rec709 color primaries. On the right, an HDR image of a triangle with Rec2020 primaries, rendered with t.graphics.hdr = true. The one on the right will only look correct on an HDR display.

Currently, LÖVR doesn't do any automatic color space conversion for you -- you are expected to write PQ-encoded Rec2020 colors to the window texture. There are some new shader helpers like linearToPQ and sRGBToRec2020 to help out with converting sRGB colors to HDR.

Error Screen

The menacing error screen has been upgraded into a fancy new stack trace explorer. It supports viewing source code and inspecting variables for entries in the stack trace. It works in VR too!

Multithreading

This version adds a new coroutine-based task system in the lovr.task module. Tasks make it easy to run expensive work on background threads without blocking the main thread. This is useful for things like asset loading, GPU readbacks, physics updates, map generation, or any other CPU-intensive logic.

Tasks use the same Lua scope as the main thread, and their code looks synchronous despite running work on background threads. They're more "ergonomic" than managing Thread and Channel objects.

Here's a simple example that loads a Model in the background and assigns it to the model variable once it's ready (possibly several frames later):

lovr.task.start(function()
  model = lovr.graphics.newModel('teapot.glb')
end)

See the Tasks guide for a full explanation of how it works.

Rendering

The graphics module is thread-safe now! Pass objects can be record draws on any thread, and multiple Pass objects can be recorded in parallel. Also, graphics objects like Texture, Model, and Shader can be created on any thread now.

Internals

LÖVR internally multithreads a few things too now, including:

Model Improvements

There were some important improvements to the Model API:

A model with a lightmap

Luau

LÖVR supports Luau as an additional option for the Lua implementation to use, alongside PUC Lua and LuaJIT. Luau is very close to Lua 5.1, but comes with some nice benefits like:

Crucially, Luau has a mascot:

See the Luau guide for the full details about Luau support in LÖVR.

Vectors

The vector API has been reworked significantly, addressing several long-standing pain points:

There were some unavoidable breaking changes here. Briefly,

To ease porting, this gist implements the old vector API using tables.

See vector and quaternion for more details about the new API.

WebGPU

WebGPU is NOT supported yet, but there's been a lot of work on the WebGPU renderer recently and it's getting very close! Here, have a screenshot of LÖVR running in a browser, as a treat:

Other Stuff

Community

Changelog

Add

General

Audio

Data

Graphics

Headset

Math

Physics

System

Thread

Change

Fix

Deprecate

Remove