* Optimize Shader LineDictionary with Variable-Length 3-Streams This commit completely reorganizes the string dictionary compression pipeline used by compiled Material Text Chunks and improves matinfo dictionary output. 1. Multi-Base Variable-Length Scaling: We replaced the static 16-bit indices overhead with a bounded payload. Now, indices scale dynamically: - 0 to 239 evaluate in 1 byte. - 240 to 3584 leverage 0xF0-0xFD escapes evaluating in 2 bytes. - 3584+ are locked behind a 0xFF marker to 3 bytes. This natively eradicated the massive monolithic lengths and zero-padding issues previously dominating shader packages. 2. Variable-Length 3-Stream Decoding: To solve the Zstandard/Zlib entropy fragmentation that conventionally plagues interleaved variable byte lengths (which previously inflated our `filament.aar` boundary constraint by +2KB), we segregated the encoded payloads. By grouping high-entropy string boundaries into a `Base Stream` and isolating offset digits inside an `Extension Stream`, predictive LZ77 ZIP sliding-windows perfectly map over both arrays independently without disruption. 3. Optimize Numeric Stream using LEB128 Prior to this change, numerical suffixes split from shader variables (e.g., `param_1024` -> `param_` + `1024`) were fed back into the localized String Dictionary. Because high-frequency numbers were assigned disjointed localized IDs per shader variant, LZ77 failed to cross-reference their repetitive structures across shipped `.aar` archives, fracturing compression sequences. This patch implements a unified 3-Stream topology. It extracts numerical primitives (< 32768) away from the baseline String Dictionary, writing them into an isolated, contiguous LEB128 array. By using a dedicated `[254]` Escape Token within the primary stream, numerical variables maintain exact 1-byte (`< 128`) or 2-byte (`>= 128`) geometric layouts across all permutations. The resulting deterministic alignment guarantees that Zlib sliding windows can deduplicate highly repetitive variables across the entire application binary block. 4. We use the ShaderStage information to create distinct index ranges, which further help use 1-byte indices. Verification Metrics: `filament-android.aar`: -7,938 B `gltfio-android.aar`: -290,939 B `libfilament.a`: -18,464 B * Optimize shader dictionary by decoding '_' for numeric literals Most numbers extracted from the shader text are preceded by an underscore (e.g., from `_`, `hp_copy_`), which previously caused standalone `_` strings to heavily pollute the LineDictionary. This change removes the standalone `_` from the dictionary index: - `MaterialChunk` rehydrates the `_` prefix when decoding these numeric literals. This frees up dictionary indices, yielding massive byte savings across uncompressed binaries (e.g., -28.4 KB for volume_masked.filamat). * Optimize ShaderMinifier to strip explicit spacing Spirv-cross outputs GLSL with explicit spacing around generic operators (e.g., ` = `, `, `, ` ) * `). This padding consumes a significant amount of uncompressed bytes across large ubershaders. By applying targeted string replacements at the end of the `ShaderMinifier` pass, we strip this extraneous padding down to its raw tokens (e.g., `a=b`, `a,b`, `a*b`). This optimization preserves isolating spaces where valuable, ensuring line-dictionary tokens (such as raw `=` or `,`) remain deduplicated instead of fusing into unpredictable variables. Impact: This saves roughly ~9.1 KB in `libfilament.a` and ~3.2 KB in `volume_masked.filamat` uncompressed, with proportional gains across the downstream LZ4 compressed archives.
Filament
Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
Download
Download Filament releases to access stable builds. Filament release archives contains host-side tools that are required to generate assets.
Make sure you always use tools from the same release as the runtime library. This is particularly
important for matc (material compiler).
If you'd rather build Filament yourself, please refer to our build manual.
Android
Android projects can simply declare Filament libraries as Maven dependencies:
repositories {
// ...
mavenCentral()
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.70.1'
}
Here are all the libraries available in the group com.google.android.filament:
iOS
iOS projects can use CocoaPods to install the latest release:
pod 'Filament', '~> 1.70.1'
Documentation
- Filament, an in-depth explanation of real-time physically based rendering, the graphics capabilities and implementation of Filament. This document explains the math and reasoning behind most of our decisions. This document is a good introduction to PBR for graphics programmers.
- Materials, the full reference
documentation for our material system. This document explains our different material models, how
to use the material compiler
matcand how to write custom materials. - Material Properties, a reference sheet for the standard material model.
Examples
Features
APIs
- Native C++ API for Android, iOS, Linux, macOS and Windows
- Java/JNI API for Android
- JavaScript API
Backends
- OpenGL 4.1+ for Linux, macOS and Windows
- OpenGL ES 3.0+ for Android and iOS
- Metal for macOS and iOS
- Vulkan 1.0 for Android, Linux, macOS, and Windows
- WebGPU for Android, Linux, macOS, and Windows
- WebGL 2.0 for all browsers supporting it
Rendering
- Clustered forward renderer
- Cook-Torrance microfacet specular BRDF
- Lambertian diffuse BRDF
- Custom lighting/surface shading
- HDR/linear lighting
- Metallic workflow
- Clear coat
- Anisotropic lighting
- Approximated translucent (subsurface) materials
- Cloth/fabric/sheen shading
- Normal mapping & ambient occlusion mapping
- Image-based lighting
- Physically-based camera (shutter speed, sensitivity and aperture)
- Physical light units
- Point lights, spot lights, and directional light
- Specular anti-aliasing
- Point, spot, and directional light shadows
- Cascaded shadows
- EVSM, PCSS, DPCF, or PCF shadows
- Transparent shadows
- Contact shadows
- Screen-space ambient occlusion
- Screen-space reflections
- Screen-space refraction
- Global fog
- Dynamic resolution (with support for AMD FidelityFX FSR)
Post processing
- HDR bloom
- Depth of field bokeh
- Multiple tone mappers: PBR Neutral, AgX, generic (customizable), ACES, filmic, etc.
- Color and tone management: luminance scaling, gamut mapping
- Color grading: exposure, night adaptation, white balance, channel mixer, shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.
- TAA, FXAA, MSAA
- Screen-space lens flares
glTF 2.0
-
Encodings
- Embeded
- Binary
-
Primitive Types
- Points
- Lines
- Line Loop
- Line Strip
- Triangles
- Triangle Strip
- Triangle Fan
-
Animation
- Transform animation
- Linear interpolation
- Morph animation
- Sparse accessor
- Skin animation
- Joint animation
-
Extensions
- KHR_draco_mesh_compression
- KHR_lights_punctual
- KHR_materials_clearcoat
- KHR_materials_dispersion
- KHR_materials_emissive_strength
- KHR_materials_ior
- KHR_materials_pbrSpecularGlossiness
- KHR_materials_sheen
- KHR_materials_specular
- KHR_materials_transmission
- KHR_materials_unlit
- KHR_materials_variants
- KHR_materials_volume
- KHR_mesh_quantization
- KHR_texture_basisu
- KHR_texture_transform
- EXT_meshopt_compression
Rendering with Filament
Native Linux, macOS and Windows
You must create an Engine, a Renderer and a SwapChain. The SwapChain is created from a
native window pointer (an NSView on macOS or a HWND on Windows for instance):
Engine* engine = Engine::create();
SwapChain* swapChain = engine->createSwapChain(nativeWindow);
Renderer* renderer = engine->createRenderer();
To render a frame you must then create a View, a Scene and a Camera:
Camera* camera = engine->createCamera(EntityManager::get().create());
View* view = engine->createView();
Scene* scene = engine->createScene();
view->setCamera(camera);
view->setScene(scene);
Renderables are added to the scene:
Entity renderable = EntityManager::get().create();
// build a quad
RenderableManager::Builder(1)
.boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }})
.material(0, materialInstance)
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertexBuffer, indexBuffer, 0, 6)
.culling(false)
.build(*engine, renderable);
scene->addEntity(renderable);
The material instance is obtained from a material, itself loaded from a binary blob generated
by matc:
Material* material = Material::Builder()
.package((void*) BAKED_MATERIAL_PACKAGE, sizeof(BAKED_MATERIAL_PACKAGE))
.build(*engine);
MaterialInstance* materialInstance = material->createInstance();
To learn more about materials and matc, please refer to the
materials documentation.
To render, simply pass the View to the Renderer:
// beginFrame() returns false if we need to skip a frame
if (renderer->beginFrame(swapChain)) {
// for each View
renderer->render(view);
renderer->endFrame();
}
For complete examples of Linux, macOS and Windows Filament applications, look at the source files
in the samples/ directory. These samples are all based on libs/filamentapp/ which contains the
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
For more information on how to prepare environment maps for image-based lighting please refer to BUILDING.md.
Android
See android/samples for examples of how to use Filament on Android.
You must always first initialize Filament by calling Filament.init().
Rendering with Filament on Android is similar to rendering from native code (the APIs are largely
the same across languages). You can render into a Surface by passing a Surface to the
createSwapChain method. This allows you to render to a SurfaceTexture, a TextureView or
a SurfaceView. To make things easier we provide an Android specific API called UiHelper in the
package com.google.android.filament.android. All you need to do is set a render callback on the
helper and attach your SurfaceView or TextureView to it. You are still responsible for
creating the swap chain in the onNativeWindowChanged() callback.
iOS
Filament is supported on iOS 11.0 and above. See ios/samples for examples of using Filament on
iOS.
Filament on iOS is largely the same as native rendering with C++. A CAEAGLLayer or CAMetalLayer
is passed to the createSwapChain method. Filament for iOS supports both Metal (preferred) and
OpenGL ES.
Assets
To get started you can use the textures and environment maps found respectively in
third_party/textures and third_party/environments. These assets are under CC0 license. Please
refer to their respective URL.txt files to know more about the original authors.
Environments must be pre-processed using
cmgen or
using the libiblprefilter library.
How to make contributions
Please read and follow the steps in CONTRIBUTING.md. Make sure you are familiar with the code style.
Directory structure
This repository not only contains the core Filament engine, but also its supporting libraries and tools.
android: Android libraries and projectsfilamat-android: Filament material generation library (AAR) for Androidfilament-android: Filament library (AAR) for Androidfilament-utils-android: Extra utilities (KTX loader, math types, etc.)gltfio-android: Filament glTF loading library (AAR) for Androidsamples: Android-specific Filament samples
art: Source for various artworks (logos, PDF manuals, etc.)assets: 3D assets to use with sample applicationsbuild: CMake build scriptsdocs: Documentationmath: Mathematica notebooks used to explore BRDFs, equations, etc.
filament: Filament rendering engine (minimal dependencies)backend: Rendering backends/drivers (Vulkan, Metal, OpenGL/ES)
ide: Configuration files for IDEs (CLion, etc.)ios: Sample projects for iOSlibs: Librariesbluegl: OpenGL bindings for macOS, Linux and Windowsbluevk: Vulkan bindings for macOS, Linux, Windows and Androidcamutils: Camera manipulation utilitiesfilabridge: Library shared by the Filament engine and host toolsfilaflat: Serialization/deserialization library used for materialsfilagui: Helper library for Dear ImGuifilamat: Material generation libraryfilamentapp: SDL2 skeleton to build sample appsfilameshio: Tiny filamesh parsing library (see alsotools/filamesh)geometry: Mesh-related utilitiesgltfio: Loader for glTF 2.0ibl: IBL generation toolsimage: Image filtering and simple transformsimageio: Image file reading / writing, only intended for internal usematdbg: DebugServer for inspecting shaders at run-time (debug builds only)math: Math librarymathio: Math types support for output streamsutils: Utility library (threads, memory, data structures, etc.)viewer: glTF viewer library (requires gltfio)
samples: Sample desktop applicationsshaders: Shaders used byfilamatandmatcthird_party: External libraries and assetsenvironments: Environment maps under CC0 license that can be used withcmgenmodels: Models under permissive licensestextures: Textures under CC0 license
tools: Host toolscmgen: Image-based lighting asset generatorfilamesh: Mesh converterglslminifier: Minifies GLSL source codematc: Material compilermatedit: Material editor for compiled materialsmatinfoDisplays information about materials compiled withmatcmipgenGenerates a series of miplevels from a source imagenormal-blending: Tool to blend normal mapsresgenAggregates binary blobs into embeddable resourcesroughness-prefilter: Pre-filters a roughness map from a normal map to reduce aliasingspecular-color: Computes the specular color of conductors based on spectral data
web: JavaScript bindings, documentation, and samples
License
Please see LICENSE.
Disclaimer
This is not an officially supported Google product.





