Overview
The Texture class supports 2D textures, 3D textures, cube maps, and mip mapping. Textures are GPU resources created using the Texture::Builder and destroyed by calling Engine::destroy(const Texture*).
Texture Types
Filament supports several texture types:
- 2D Textures: Standard image textures
- 3D Textures: Volumetric textures
- Cube Maps: Six-sided environment textures
- 2D Array Textures: Arrays of 2D textures
- External Textures: Platform-specific external images (camera, video)
Builder
The Builder class is used to construct Texture objects.
Constructor
Creates a new Texture::Builder instance.
Dimension Methods
width
Builder& width(uint32_t width) noexcept
Specifies the width in texels of the texture.
Width of the texture in texels (default: 1, doesn’t need to be power-of-two)
Returns: Reference to this Builder for chaining calls.
height
Builder& height(uint32_t height) noexcept
Specifies the height in texels of the texture.
Height of the texture in texels (default: 1, doesn’t need to be power-of-two)
Returns: Reference to this Builder for chaining calls.
depth
Builder& depth(uint32_t depth) noexcept
Specifies the depth in texels of the texture.
Depth of the texture in texels (default: 1, doesn’t need to be power-of-two)
Returns: Reference to this Builder for chaining calls.
The depth controls the number of layers in a 2D array texture. Values greater than 1 effectively create a 3D texture. This Texture must use Sampler::SAMPLER_3D or Sampler::SAMPLER_2D_ARRAY.
Mipmap and Sampling
levels
Builder& levels(uint8_t levels) noexcept
Specifies the number of mip map levels.
Number of mipmap levels for this texture
Returns: Reference to this Builder for chaining calls.
This creates a mip-map pyramid. The maximum number of levels a texture can have is such that max(width, height, depth) / 2^MAX_LEVELS = 1.
samples
Builder& samples(uint8_t samples) noexcept
Specifies the number of samples used for MSAA (Multisample Anti-Aliasing).
Number of samples for this texture
Returns: Reference to this Builder for chaining calls.
Calling this method implicitly indicates the texture is used as a render target. This method should not be used with other semantically conflicting methods like setImage. For array textures, this enables multiview.
sampler
Builder& sampler(Sampler target) noexcept
Specifies the type of sampler to use.
Returns: Reference to this Builder for chaining calls.
Sampler (SamplerType) enum values:
SAMPLER_2D - 2D texture sampler
SAMPLER_2D_ARRAY - 2D texture array sampler
SAMPLER_CUBEMAP - Cubemap sampler
SAMPLER_EXTERNAL - External texture sampler (platform-specific)
SAMPLER_3D - 3D texture sampler
Builder& format(InternalFormat format) noexcept
Specifies the internal format of this texture.
Format of the texture’s texels
Returns: Reference to this Builder for chaining calls.
The internal format specifies how texels are stored (which may be different from how they’re specified in setImage()). InternalFormat specifies both the color components and the data type used.
Common InternalFormat (TextureFormat) values:
R8 - 8-bit red channel
RG8 - 8-bit red and green channels
RGB8 - 8-bit RGB
RGBA8 - 8-bit RGBA
R16F - 16-bit float red channel
RG16F - 16-bit float RG
RGB16F - 16-bit float RGB
RGBA16F - 16-bit float RGBA
R32F - 32-bit float red channel
RG32F - 32-bit float RG
RGB32F - 32-bit float RGB
RGBA32F - 32-bit float RGBA
DEPTH16 - 16-bit depth
DEPTH24 - 24-bit depth
DEPTH32F - 32-bit float depth
DEPTH24_STENCIL8 - 24-bit depth + 8-bit stencil
DEPTH32F_STENCIL8 - 32-bit float depth + 8-bit stencil
Compressed formats:
EAC_R11 - ETC2 R11 compression
EAC_RG11 - ETC2 RG11 compression
ETC2_RGB8 - ETC2 RGB8 compression
ETC2_RGBA8 - ETC2 RGBA8 compression
DXT1_RGB - DXT1/BC1 RGB compression
DXT1_RGBA - DXT1/BC1 RGBA compression
DXT3_RGBA - DXT3/BC2 RGBA compression
DXT5_RGBA - DXT5/BC3 RGBA compression
usage
Builder& usage(Usage usage) noexcept
Specifies if the texture will be used as a render target attachment.
Returns: Reference to this Builder for chaining calls.
Usage (TextureUsage) enum values (can be combined):
DEFAULT - Default usage
COLOR_ATTACHMENT - Texture can be used as a color attachment
DEPTH_ATTACHMENT - Texture can be used as a depth attachment
STENCIL_ATTACHMENT - Texture can be used as a stencil attachment
UPLOADABLE - Texture data can be updated
SAMPLEABLE - Texture can be sampled from
SUBPASS_INPUT - Texture can be used as subpass input
BLIT_SRC - Texture can be used as blit source
BLIT_DST - Texture can be used as blit destination
PROTECTED - Texture uses protected memory
If the texture is potentially rendered into, it may require a different memory layout, which needs to be known during construction.
swizzle
Builder& swizzle(Swizzle r, Swizzle g, Swizzle b, Swizzle a) noexcept
Specifies how a texture’s channels map to color components.
Texture channel for red component
Texture channel for green component
Texture channel for blue component
Texture channel for alpha component
Returns: Reference to this Builder for chaining calls.
Swizzle (TextureSwizzle) enum values:
CHANNEL_0 - Use channel 0 (red)
CHANNEL_1 - Use channel 1 (green)
CHANNEL_2 - Use channel 2 (blue)
CHANNEL_3 - Use channel 3 (alpha)
ZERO - Use constant 0
ONE - Use constant 1
Texture swizzling is only supported if isTextureSwizzleSupported() returns true.
Special Textures
external
Builder& external() noexcept
Creates an external texture. The content must be set using setExternalImage().
Returns: Reference to this Builder for chaining calls.
If the Sampler is set to SAMPLER_EXTERNAL, external() is implied. Generally YUV formats must use SAMPLER_EXTERNAL.
import
Builder& import(intptr_t id) noexcept
Specifies a native texture to import as a Filament texture.
Backend-specific texture identifier (GLuint for OpenGL, MTLTexture for Metal)
Returns: Reference to this Builder for chaining calls.
This method should be used as a last resort. This API is subject to change or removal. With Metal, use CFBridgingRetain to transfer ownership to Filament.
Asynchronous Creation
async
Builder& async(
backend::CallbackHandler* handler,
AsyncCompletionCallback callback = nullptr,
void* user = nullptr
) noexcept
Specifies a callback that will execute once the resource’s data has been fully allocated within GPU memory.
Handler to dispatch the callback or nullptr for the default handler
Function to be called upon completion of asynchronous creation
Custom data passed as second argument to the callback
Returns: Reference to this Builder for chaining calls.
To use this method, the engine must be configured for asynchronous operation. This method and external() are mutually exclusive.
build
Texture* build(Engine& engine)
Creates the Texture object and returns a pointer to it.
Reference to the filament::Engine to associate this Texture with
Returns: Pointer to the newly created Texture object.
Example:
Texture* texture = Texture::Builder()
.width(512)
.height(512)
.levels(9) // log2(512) + 1
.format(Texture::InternalFormat::RGBA8)
.sampler(Texture::Sampler::SAMPLER_2D)
.build(*engine);
Static Methods
isTextureFormatSupported
static bool isTextureFormatSupported(
Engine& engine,
InternalFormat format
) noexcept
Returns whether a backend supports a particular format.
Returns: true if the format is supported.
isTextureFormatMipmappable
static bool isTextureFormatMipmappable(
Engine& engine,
InternalFormat format
) noexcept
Returns whether a backend supports mipmapping of a particular format.
Returns: true if the format supports mipmaps.
isTextureFormatCompressed
static bool isTextureFormatCompressed(InternalFormat format) noexcept
Returns whether a particular format is compressed.
Returns: true if the format is compressed.
isProtectedTexturesSupported
static bool isProtectedTexturesSupported(Engine& engine) noexcept
Returns whether this backend supports protected textures.
Returns: true if protected textures are supported.
isTextureSwizzleSupported
static bool isTextureSwizzleSupported(Engine& engine) noexcept
Returns whether a backend supports texture swizzling.
Returns: true if texture swizzling is supported.
static bool validatePixelFormatAndType(
InternalFormat internalFormat,
Format format,
Type type
) noexcept
Returns whether a combination of texture format, pixel format and type is valid.
Returns: true if the combination is valid.
getMaxTextureSize
static size_t getMaxTextureSize(Engine& engine, Sampler type) noexcept
Returns the maximum size in texels of a texture of the given type.
Returns: Maximum texture size (at least 2048 for 2D textures, 256 for 3D textures).
getMaxArrayTextureLayers
static size_t getMaxArrayTextureLayers(Engine& engine) noexcept
Returns the maximum number of layers supported by texture arrays.
Returns: Maximum number of layers (at least 256).
Instance Methods
Dimension Getters
getWidth
size_t getWidth(size_t level = BASE_LEVEL) const noexcept
Returns the width of a 2D or 3D texture level.
Texture level (default is 0)
Returns: Width in texels of the specified level, clamped to 1.
For SAMPLER_EXTERNAL textures, dimensions are unknown and this always returns whatever was set on the Builder.
getHeight
size_t getHeight(size_t level = BASE_LEVEL) const noexcept
Returns the height of a 2D or 3D texture level.
Texture level (default is 0)
Returns: Height in texels of the specified level, clamped to 1.
getDepth
size_t getDepth(size_t level = BASE_LEVEL) const noexcept
Returns the depth of a 3D texture level.
Texture level (default is 0)
Returns: Depth in texels of the specified level, clamped to 1.
getLevels
size_t getLevels() const noexcept
Returns the maximum number of levels this texture can have.
Returns: Maximum number of levels.
Property Getters
getTarget
Sampler getTarget() const noexcept
Returns this texture’s Sampler as set by Builder::sampler().
Returns: The texture’s sampler type.
InternalFormat getFormat() const noexcept
Returns this texture’s InternalFormat as set by Builder::format().
Returns: The texture’s internal format.
Setting Image Data
setImage (3D/Array)
void setImage(
Engine& engine,
size_t level,
uint32_t xoffset,
uint32_t yoffset,
uint32_t zoffset,
uint32_t width,
uint32_t height,
uint32_t depth,
PixelBufferDescriptor&& buffer
) const
Updates a sub-image of a 3D texture or 2D texture array for a level.
Engine this texture is associated with
Level to set the image for (must be less than getLevels())
Left offset of the sub-region to update
Bottom offset of the sub-region to update
Depth offset of the sub-region to update
Width of the sub-region to update
Height of the sub-region to update
Depth of the sub-region to update
buffer
PixelBufferDescriptor&&
required
Client-side buffer containing the image to set
For cubemaps, they are treated like a 2D array of six layers. The buffer’s Texture::Format must match getFormat().
Simplified 2D overloads:
void setImage(Engine& engine, size_t level,
PixelBufferDescriptor&& buffer) const
void setImage(Engine& engine, size_t level,
uint32_t xoffset, uint32_t yoffset,
uint32_t width, uint32_t height,
PixelBufferDescriptor&& buffer) const
Example:
std::vector<uint8_t> imageData(512 * 512 * 4);
// ... fill imageData ...
texture->setImage(*engine, 0,
Texture::PixelBufferDescriptor(
imageData.data(),
imageData.size(),
Texture::Format::RGBA,
Texture::Type::UBYTE
)
);
setImageAsync
AsyncCallId setImageAsync(
Engine& engine,
size_t level,
uint32_t xoffset,
uint32_t yoffset,
uint32_t zoffset,
uint32_t width,
uint32_t height,
uint32_t depth,
PixelBufferDescriptor&& buffer,
backend::CallbackHandler* handler,
AsyncCompletionCallback callback,
void* user = nullptr
) const
Asynchronous version of setImage().
Handler to dispatch the callback or nullptr for the default handler
callback
AsyncCompletionCallback
required
Function to be called upon completion
Custom data passed to the callback
Returns: An AsyncCallId that can be used to cancel the operation.
To use this method, the engine must be configured for asynchronous operation.
Simplified 2D overloads:
AsyncCallId setImageAsync(Engine& engine, size_t level,
PixelBufferDescriptor&& buffer,
backend::CallbackHandler* handler,
AsyncCompletionCallback callback,
void* user = nullptr) const
AsyncCallId setImageAsync(Engine& engine, size_t level,
uint32_t xoffset, uint32_t yoffset,
uint32_t width, uint32_t height,
PixelBufferDescriptor&& buffer,
backend::CallbackHandler* handler,
AsyncCompletionCallback callback,
void* user = nullptr) const
External Textures
setExternalImage (with handle)
void setExternalImage(Engine& engine, ExternalImageHandleRef image) noexcept
Specifies the external image to associate with this Texture.
Engine this texture is associated with
image
ExternalImageHandleRef
required
Opaque handle to a platform-specific image created using Platform APIs
External images have many restrictions: only LOD 0 supported, only nearest/linear filtering, size/format defined by the external image, only CLAMP_TO_EDGE wrap mode.
setExternalImage (legacy)
void setExternalImage(Engine& engine, void* image) noexcept
Legacy method to specify the external image.
Engine this texture is associated with
Platform-specific image (eglImageOES on Android, CVPixelBufferRef on iOS)
On iOS, supported pixel formats include kCVPixelFormatType_32BGRA and kCVPixelFormatType_420YpCbCr8BiPlanarFullRange.
setExternalImage (with plane)
void setExternalImage(Engine& engine, void* image, size_t plane) noexcept
Specifies the external image and plane to associate with this Texture.
Engine this texture is associated with
Plane index of the external image
This is useful for planar formats like YUV. Multiple Filament textures can be bound to different planes of the same external image.
Example:
textureY->setExternalImage(*engine, pixelBuffer, 0); // Y plane
textureUV->setExternalImage(*engine, pixelBuffer, 1); // UV plane
setExternalStream
void setExternalStream(Engine& engine, Stream* stream) noexcept
Specifies the external stream to associate with this Texture.
Engine this texture is associated with
A Stream object or nullptr
This Texture must use Sampler::SAMPLER_EXTERNAL. External streams can be video or camera streams.
Mipmap Generation
generateMipmaps
void generateMipmaps(Engine& engine) const noexcept
Generates all the mipmap levels automatically.
Engine this texture is associated with
This requires the texture to have a color-renderable format and usage set to BLIT_SRC | BLIT_DST. This Texture must NOT use SAMPLER_3D.
Creation Status
isCreationComplete
bool isCreationComplete() const noexcept
Checks if the resource has finished creation.
Returns: true if the resource is fully created and ready for use.
If the resource creation was initiated asynchronously, this returns true only after all related asynchronous tasks are complete. For normally created resources, this always returns true.
Pixel Buffer Descriptor
using PixelBufferDescriptor = backend::PixelBufferDescriptor;
Describes the geometry and format of a pixel buffer.
Constructor:
PixelBufferDescriptor(
void const* buffer,
size_t size,
Format format,
Type type,
uint32_t alignment = 1,
uint32_t left = 0,
uint32_t top = 0,
uint32_t stride = 0,
Callback callback = nullptr,
void* user = nullptr
)
Format (PixelDataFormat) enum values:
R - Red channel only
RG - Red and green channels
RGB - RGB channels
RGBA - RGBA channels
DEPTH_COMPONENT - Depth data
DEPTH_STENCIL - Depth and stencil data
ALPHA - Alpha channel only
Type (PixelDataType) enum values:
UBYTE - Unsigned 8-bit integer
BYTE - Signed 8-bit integer
USHORT - Unsigned 16-bit integer
SHORT - Signed 16-bit integer
UINT - Unsigned 32-bit integer
INT - Signed 32-bit integer
HALF - 16-bit float
FLOAT - 32-bit float
UINT_10F_11F_11F_REV - Packed RGB (10/11/11 bits)
USHORT_565 - Packed RGB (5/6/5 bits)
Example Usage
Creating and Loading a 2D Texture
#include <filament/Engine.h>
#include <filament/Texture.h>
// Create texture
Texture* texture = Texture::Builder()
.width(512)
.height(512)
.levels(9) // Full mipchain
.format(Texture::InternalFormat::RGBA8)
.sampler(Texture::Sampler::SAMPLER_2D)
.usage(Texture::Usage::SAMPLEABLE | Texture::Usage::UPLOADABLE)
.build(*engine);
// Prepare pixel data
std::vector<uint8_t> pixels(512 * 512 * 4);
// ... fill pixels with image data ...
// Upload base level
texture->setImage(*engine, 0,
Texture::PixelBufferDescriptor(
pixels.data(),
pixels.size(),
Texture::Format::RGBA,
Texture::Type::UBYTE
)
);
// Generate mipmaps
texture->generateMipmaps(*engine);
// Cleanup
engine->destroy(texture);
Creating a Cubemap
Texture* cubemap = Texture::Builder()
.width(512)
.height(512)
.levels(1)
.format(Texture::InternalFormat::RGB16F)
.sampler(Texture::Sampler::SAMPLER_CUBEMAP)
.build(*engine);
// Upload each face (6 faces total)
for (int face = 0; face < 6; face++) {
std::vector<uint16_t> faceData = // ... load face data ...
cubemap->setImage(*engine, 0,
0, 0, face, // xoffset, yoffset, zoffset (face index)
512, 512, 1, // width, height, depth
Texture::PixelBufferDescriptor(
faceData.data(),
faceData.size() * sizeof(uint16_t),
Texture::Format::RGB,
Texture::Type::HALF
)
);
}