LÖVR
An open source Lua framework for building 3D games and VR experiences.
-
🕶
Great at VR Stuff
LÖVR has APIs for fast stereo rendering, controller input, hand tracking, haptics, audio spatialization, SDF fonts, 3D physics, foveated rendering, passthrough, and more.
-
🎈
Super Lightweight
The entire engine fits in a couple of MB and uses LuaJIT, a super fast Lua implementation. Projects are just folders with code and assets, organized however you want.
-
🤔
Beginner Friendly
You can write 3 lines of Lua and drag and drop a folder onto an exe to get a working 3D scene. Lua is a really simple language, making LÖVR great for learning and prototyping.
LÖVR can be used for game jams, commercial projects, tools, prototyping, education, and everything in between. The framework is really unopinionated, giving you the freedom and control to make whatever you want. LÖVR is also permissively licensed, so you can use and modify it as you wish.
Hardware Support
LÖVR is powered by OpenXR and Vulkan, so it's compatible with a wide variety of hardware and platforms. It can also simulate a VR headset using keyboard and mouse, so you don't need any VR hardware to get started.
And if you're not doing VR at all, it's easy to disable the VR parts and use LÖVR as a regular 3D game engine.
- 🕹
- HTC Vive
- Valve Index
- Quest 2/Pro/3/3S
- Oculus Rift (S)
- Windows MR
- Pico Neo 3
- Pico 4
- PSVR 2
- Magic Leap 2
- Ultraleap
- Keyboard/Mouse
- 🖥
- Windows
- macOS
- Linux
- Android
Sample Projects
-
Hello World
function lovr.draw(pass)
pass:text('hello', 0, 1.7, -1, .5)
end
-
Spinning Cube
function lovr.draw(pass)
local angle = lovr.headset.getTime()
pass:cube(0, 1.7, -1, .5, angle)
end
-
Tracked Hands
function lovr.draw(pass)
for i, hand in ipairs(lovr.headset.getHands()) do
local x, y, z = lovr.headset.getPosition(hand)
pass:sphere(x, y, z, .1)
end
end
-
Audio
function lovr.load()
song = lovr.audio.newSource('darude.ogg')
song:play()
end
-
Skybox
function lovr.load()
sky = lovr.graphics.newTexture('sky.hdr')
end
function lovr.draw(pass)
pass:skybox(sky)
end
-
3D Model
function lovr.load()
model = lovr.graphics.newModel('monkey.gltf')
end
function lovr.draw(pass)
pass:draw(model, 0, 2, -3, 2)
end