filly
filly is a Python 3D renderer for glTF scenes, built on Google Filament.
Filly can load a glTF model, light it, pose it, and render it. You get the result as a NumPy image, or filly draws it into an OpenGL texture that your own window shows. Your program keeps control of the window and of frame timing, so filly fits into applications that already own a display loop, such as PsychoPy experiments or pyglet, moderngl, and zengl programs.
"Wooden Playground Horse" by Batuhan13, CC BY 4.0. See attribution.
Install
You can install filly from PyPI or build it from source.
It needs Python 3.10 or later, Windows or Linux on x86_64, and an OpenGL 4.1 driver. On Linux, offscreen rendering works without a display. macOS is not supported at this time.
Render an image
import filly
from PIL import Image # only to save the image
with filly.Renderer() as renderer:
scene = renderer.create_scene()
horse = scene.load("examples/assets/wooden_playground_horse.glb")
horse.apply_animation(0, 1.25) # a pose from its spring animation
scene.camera = renderer.create_camera()
scene.camera.frame(horse, direction=(-1, -0.3, -1))
scene.add_directional_light(direction=(-1, -1, -2), intensity=100_000)
target = renderer.create_render_target(width=800, height=600)
renderer.render(scene, target)
Image.fromarray(target.read()).save("horse.png") # (600, 800, 4) uint8 RGBA
Draw in a PsychoPy window
filly renders into a texture that PsychoPy draws directly, with no copy through the CPU.
from psychopy import core, visual
from filly.integrations.psychopy import HostTarget, create_renderer
win = visual.Window((1024, 768), units="pix")
renderer = create_renderer(win) # shares the window's OpenGL context
scene = renderer.create_scene()
horse = scene.load("examples/assets/wooden_playground_horse.glb")
scene.camera = renderer.create_camera()
scene.camera.frame(horse)
scene.add_directional_light(direction=(-1, -1, -2), intensity=100_000)
target = HostTarget(renderer, win, width=512, height=512)
stim = target.create_image_stim()
clock = core.Clock()
while clock.getTime() < 3:
horse.apply_animation(0, clock.getTime())
renderer.render(scene, target)
stim.draw()
win.flip()
renderer.close()
win.close()
Close the renderer before the window. The same pattern works with a pyglet, moderngl, or zengl window.
Features
- glTF 2.0: GLB and glTF files, skinning, morph targets, animation, material variants, and the common material extensions, such as clearcoat, sheen, transmission, and iridescence. See asset compatibility.
- Cameras and lights: perspective and orthographic cameras, camera framing, and directional, sun, point, and spot lights with optional shadows. Image-based lighting comes from an HDR panorama or prefiltered KTX files.
- Stimuli from arrays: textures and meshes from NumPy arrays, updated in place each frame, for gratings, noise, or deforming shapes.
- Predictable output: sRGB (default) or linear. Effects such as antialiasing, fog, and bloom are off until you enable them. With default settings, the same scene gives the same pixels on every frame.
- Several views per frame: each
render()call can take its own camera and viewport, for example for side-by-side stereo. - Picking: find the model, node, and world position under a pixel of a rendered frame, for example where a participant clicked. See picking.
- Browsers: the same core compiles to WebAssembly for WebGL2. It renders into a texture that the page's own renderer draws, such as PIXI in PsychoJS. See the web build.
Examples
See the examples/ folder.
| Example | Shows |
|---|---|
screenshot.py |
The animation above (--gif), or a still image, rendered offscreen. |
psychopy_shared.py |
A model in a PsychoPy window with all the bells and whistles. Pass your own GLB path. |
psychopy_stress.py |
Repeated PsychoPy trials, with frame timing and memory reports. See measure timing. |
pyglet_shared.py, moderngl_shared.py, zengl_shared.py |
The same (minus the bells and whistles) in other OpenGL hosts. |
drifting_grating.py |
A texture updated every frame on a tilted plane. |
stereo.py |
Two cameras side by side in one window. |
shapes.py |
Generated and deforming meshes. |
pick.py |
Click a model in a pyglet window: picking, with the hit node, point, and latency. --auto clicks by itself. |
Documentation
- Tutorial: render an image
- How-to guides: build and test, use PsychoPy, use other OpenGL hosts, measure timing, profile a frame, compare with Filament's viewer, use filly in a web page
- Reference: API, performance, validation, sample assets, upstream Filament issues
- Explanation: design and limits, filly and Filament, tested assumptions, material precompilation, the web build
License
filly is released under the MIT License.
It links Filament (Apache 2.0),
meshoptimizer (MIT),
libwebp (BSD), and
cgltf (MIT). Their licenses are installed with the package.
The sample model filly.samples.SUZANNE is modified from Suzanne by Norbert Nopper (UX3D), from
the Khronos glTF Sample Assets, under CC0 1.0.
Metadata
Release files for filly 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| filly-0.2.0.tar.gz | 6.4 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| filly-0.2.0-cp312-abi3-win_amd64.whl | CPython 3.12 | abi3 | Windows x86-64 | Details |
| filly-0.2.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | abi3 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| filly-0.2.0-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
| filly-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| filly-0.2.0-cp310-cp310-win_amd64.whl | CPython 3.10 | CPython 3.10 | Windows x86-64 | Details |
| filly-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.10 | CPython 3.10 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
Total release size: 23.5 MB
Release files / filly-0.2.0.tar.gz
| Download URL | filly-0.2.0.tar.gz |
|---|---|
| Size | 6.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc48dd8ba879dab83e15e5fa85211c724e994537a72678cfd5a929714d60ab9e
|
|
BLAKE2b-256 checksum How to use checksums |
2e1a0828f6f245ceb7c49348bebdca50685032c680c4c3ff7ef67c5bb2acade0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / filly-0.2.0-cp312-abi3-win_amd64.whl
| Download URL | filly-0.2.0-cp312-abi3-win_amd64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.12 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
7554066c76f3da57830cf847d4b03385bbe84fabe084fd08aec2c3a1e8d86e2a
|
|
BLAKE2b-256 checksum How to use checksums |
d45d6d655e23dc8365ac817d8a9300ca6180a494dc95dd8df2a2c7a48c2dc75b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / filly-0.2.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | filly-0.2.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
9f7fb38e8f9708d79695c699d4389a2d6424543613b6e7363a07df2f0492597a
|
|
BLAKE2b-256 checksum How to use checksums |
df88f82bc9303804b7c82c03c7a7203741b99e2461adfe7282b02446089dcf27
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / filly-0.2.0-cp311-cp311-win_amd64.whl
| Download URL | filly-0.2.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
59c85a088ab1c7937c381d5a5c37530ffaaa10a16e4fc6aeab9d4106013356d2
|
|
BLAKE2b-256 checksum How to use checksums |
0f7ab00ce4ef07bccca1b1c66b2ef9b1d8bef2fbaa62c932ef4903393df9fce2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / filly-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | filly-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
e991c0c87e8083669dd7cde6f71742bf9e1e2a6d7a9c7d1774043722e8cd8fd3
|
|
BLAKE2b-256 checksum How to use checksums |
c75e65243f7e0635e2727251cb50900c84a1f17cf3740214285de89fcfad1e56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / filly-0.2.0-cp310-cp310-win_amd64.whl
| Download URL | filly-0.2.0-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c41e09705418a4ea79f1547ae74ad8f4b72a4e2e7fe8bea42e30fd09cb1aa041
|
|
BLAKE2b-256 checksum How to use checksums |
a18b2a157253d953eec978fee2faad1f16e5cf52908fa23336a8dd2a8b395195
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / filly-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | filly-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
9a24ec3ba6ff2da61b3e060a74a787b17d3804dd93dd3ea61f85ba92e33b2b85
|
|
BLAKE2b-256 checksum How to use checksums |
d67bba7529172a8e5cea0458d8f6b55da3ab0b14d42230e8a86edd7f2e16539f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log