Advanced Rendering Techniques
Filament provides advanced rendering capabilities for demanding real-time graphics applications. This guide covers screen-space reflections, dynamic resolution scaling, instancing, and custom render targets.Screen Space Reflections (SSR)
SSR provides real-time reflections by tracing rays in screen space, ideal for wet surfaces and polished materials.Enabling SSR
samples/material_sandbox.cpp:355,579
Screenshot Description: A glossy floor reflecting the scene above it, with reflections that accurately match the geometry and fade at grazing angles. Notice how reflections are limited to what’s visible on screen.
SSR Limitations
- Only reflects what’s visible on screen
- Cannot reflect off-screen objects
- Performance intensive at high quality
- Best combined with IBL for complete reflections
SSR Best Practices
- Combine with IBL: Use SSR for nearby reflections, IBL for distant ones
- Adjust roughness: SSR works best on smooth surfaces (low roughness)
- Limit distance: Keep maxDistance low to avoid artifacts
- Fade at edges: SSR naturally fades at screen edges
Dynamic Resolution Scaling
Dynamic resolution adjusts rendering resolution in real-time to maintain target frame rate.Configuration
How It Works
- Monitor frame time each frame
- If frame time exceeds target, reduce resolution
- If frame time is below target, increase resolution
- Smoothly interpolate between scales
Use Cases
- Maintaining 60fps on variable hardware
- Mobile devices with thermal throttling
- VR applications requiring consistent frame rates
- Adaptive quality based on scene complexity
Hardware Instancing
Render thousands of similar objects efficiently using GPU instancing.Basic Instancing
Thehybrid_instancing.cpp sample demonstrates efficient instance rendering:
samples/hybrid_instancing.cpp
Screenshot Description: Thousands of small cubes rendered simultaneously, each with unique position and rotation, demonstrating efficient GPU instancing rendering 10,000+ objects at 60fps.
Advanced Instance Attributes
You can pass per-instance data beyond transforms:Custom Render Targets
Therendertarget.cpp sample shows how to render to custom textures for effects like mirrors or security cameras.
Creating a Render Target
samples/rendertarget.cpp
Render Target Use Cases
- Mirrors and Portals: Render scene from different viewpoint
- Security Cameras: In-world camera feeds
- Minimap: Top-down view of the scene
- Post-Processing: Custom effects chains
- Shadow Maps: (Filament handles this internally)
Multiple Windows
Themultiple_windows.cpp sample demonstrates rendering to multiple windows simultaneously:
samples/multiple_windows.cpp
Stereoscopic Rendering
Thehellostereo.cpp sample shows VR/AR stereoscopic rendering:
samples/hellostereo.cpp
Screenshot Description: Side-by-side stereo view showing slightly offset perspectives for left and right eyes, ready for VR headset display.
Asynchronous Resource Loading
Thehelloasync.cpp sample demonstrates non-blocking resource loading:
samples/helloasync.cpp
Depth Testing & Stencil
Thedepthtesting.cpp sample shows advanced depth and stencil operations:
samples/depthtesting.cpp
Point Sprites
Thepoint_sprites.cpp sample demonstrates efficient particle rendering:
samples/point_sprites.cpp
Screenshot Description: Thousands of glowing particles rendered as point sprites, creating a particle system effect with minimal geometry overhead.
View Layers
Control which renderables appear in which views:Layer Use Cases
- UI Layer: Render UI separately from world
- Mirrors: Different layer for reflected objects
- Debugging: Toggle debug visualization on/off
- Optimization: Cull objects based on view type
Culling Optimization
Frame Graph & Custom Passes
While Filament manages the frame graph internally, you can customize rendering order:Material Variations
Thematerialinstancestress.cpp sample tests material instance performance:
samples/materialinstancestress.cpp
Screenshot Description: A stress test scene showing hundreds of spheres, each with unique material parameters, demonstrating efficient material instance management.
Heightfield Rendering
Theheightfield.cpp sample shows efficient terrain rendering:
samples/heightfield.cpp
Screenshot Description: A procedurally generated terrain with smooth hills and valleys, efficiently rendered using a heightfield mesh with normal map details.
Performance Best Practices
Rendering Performance
- Batch Draw Calls: Use instancing for similar objects
- Minimize State Changes: Sort by material, then by mesh
- Frustum Culling: Provide tight bounding boxes
- LOD Systems: Use lower detail at distance
- Occlusion Culling: Remove hidden objects early
Memory Optimization
- Share Resources: Reuse materials and textures
- Compress Textures: Use ETC2, ASTC, or BC formats
- Stream Assets: Load/unload based on visibility
- Instance Data: Use instancing instead of duplicating geometry
Mobile Considerations
- Reduce Draw Calls: Critical on mobile GPUs
- Lower Texture Resolution: Use mipmaps effectively
- Simplify Shaders: Avoid complex material graphs
- Disable Expensive Effects: SSAO, SSR on low-end devices
Related Samples
gltf_instances.cpp- glTF instancing demonstrationsuzanne.cpp- Advanced material and AO techniquesviewtest.cpp- Multiple view configuration testingvbotest.cpp- Vertex buffer optimization patterns