BloomPlugin (HDR Bloom)
Bloom Plugin adds a high-quality HDR bloom post-processing effect that creates glowing halos around bright areas in the scene, simulating the way real cameras capture bright light sources.
The BloomPlugin implements a multi-pass Gaussian blur technique that extracts bright areas from the rendered scene based on a threshold, blurs them progressively at multiple resolutions, and composites the result back onto the original image for a realistic glow effect.
Features
- HDR Bloom: Properly handles High Dynamic Range values for realistic bloom
- Multi-Pass Blurring: Uses progressive downsampling and upsampling for efficient, high-quality blur
- Threshold Control: Configurable brightness threshold and soft threshold for smooth transitions
- Adjustable Intensity: Control the strength of the bloom effect
- Radius & Power Controls: Fine-tune the spread and falloff of the glow
- Per-Material Control: Enable or disable bloom for individual materials
- Background Bloom: Optional bloom effect on the scene background
- Configurable Iterations: Adjust quality vs performance with iteration count
- Debug Mode: Visualize the bloom buffer for tuning
- GBuffer Integration: Respects material flags for selective bloom rendering
Installation
This plugin is part of the @threepipe/webgi-plugins package:
npm install @threepipe/webgi-pluginsBasic Setup
import {ThreeViewer} from 'threepipe'
import {BloomPlugin} from '@threepipe/webgi-plugins'
const viewer = new ThreeViewer({
canvas: document.getElementById('canvas'),
msaa: false,
maxHDRIntensity: 8, // Maximum HDR intensity for bloom
})
// Add the bloom plugin
const bloom = viewer.addPluginSync(new BloomPlugin())
// Configure basic settings
bloom.pass.intensity = 0.5
bloom.pass.threshold = 1.5With this setup, any bright areas in your scene (above the threshold) will have a glowing bloom effect.
Configuration
Intensity & Threshold
Control which areas bloom and how strong the effect is:
const bloomPass = bloom.pass
// Intensity: strength of the bloom effect (0-3)
bloomPass.intensity = 0.5 // Subtle bloom
bloomPass.intensity = 2.0 // Strong bloom
// Threshold: minimum brightness for bloom (0-2)
bloomPass.threshold = 1.0 // Only very bright areas bloom
bloomPass.threshold = 0.5 // More areas bloom
// Soft Threshold: smooth transition (0-1)
bloomPass.softThreshold = 0.5 // Smooth falloff
bloomPass.softThreshold = 0.0 // Sharp cutoffThe threshold determines which pixels contribute to bloom:
- Lower threshold: More areas glow, including moderately bright surfaces
- Higher threshold: Only the brightest lights and reflections glow
- Soft threshold: Creates smooth transitions at the threshold boundary
Quality Settings
Adjust the quality and performance of the bloom effect:
// Iterations: more iterations = higher quality but slower (2-7)
bloomPass.bloomIterations = 4 // Balanced (default)
bloomPass.bloomIterations = 7 // Highest quality
bloomPass.bloomIterations = 2 // Fastest
// Radius: controls the spread of the blur (0-1)
bloomPass.radius = 0.6 // Default
bloomPass.radius = 0.3 // Tighter bloom
bloomPass.radius = 0.9 // Wider bloom
// Power: controls the falloff curve (0.2-10)
bloomPass.power = 1.0 // Linear (default)
bloomPass.power = 2.0 // More concentrated in center
bloomPass.power = 0.5 // More spread outHigher iterations provide smoother, more realistic bloom but impact performance. Adjust based on your target hardware.
Background Bloom
Control whether the scene background receives bloom:
// Enable bloom on the background
bloomPass.backgroundBloom = true
// Useful when you have a bright HDR environment
await viewer.setEnvironmentMap('bright_sunset.hdr', {
setBackground: true,
})Per-Material Control
Enable or disable bloom for specific materials:
import {BloomPlugin} from '@threepipe/webgi-plugins'
// Disable bloom for a specific material
material.userData[BloomPlugin.PluginType] = {
enable: false
}
// Or use the helper method
BloomPlugin.AddBloomData(material, {
enable: true // or false
})
// This material will now participate (or not) in bloom
material.setDirty()This is useful for:
- Disabling bloom on UI elements
- Excluding certain objects from the glow effect
- Creating selective bloom for specific materials only
Advanced Usage
HDR Workflow Integration
Bloom works best with HDR rendering and proper tonemapping:
import {ThreeViewer} from 'threepipe'
import {BloomPlugin} from '@threepipe/webgi-plugins'
const viewer = new ThreeViewer({
canvas: document.getElementById('canvas'),
msaa: false,
rgbm: false, // Use true HDR rendering
maxHDRIntensity: 16, // Support higher brightness values
})
const bloom = viewer.addPluginSync(new BloomPlugin())
// Configure tonemap plugin for HDR
const tonemap = viewer.getPluginSync('Tonemap')
if (tonemap) {
tonemap.exposure = 1.0
tonemap.toneMapping = 'ACESFilmic'
}
// Bloom will now properly handle HDR values
bloom.pass.threshold = 2.0 // Threshold in HDR space
bloom.pass.intensity = 1.0Debug Mode
Visualize the bloom buffer to understand which areas are contributing:
// Show only the bloom buffer
bloom.pass.bloomDebug = true
// This displays the extracted and blurred bright areas
// Useful for tweaking threshold and intensityIn debug mode, you'll see:
- White/bright areas: Contributing to bloom
- Black areas: Below threshold
- Use this to fine-tune your threshold settings
Combining with Other Effects
Bloom works well with other post-processing effects:
import {ThreeViewer, SSAAPlugin} from 'threepipe'
import {
BloomPlugin,
TemporalAAPlugin,
SSReflectionPlugin
} from '@threepipe/webgi-plugins'
const viewer = new ThreeViewer({
canvas: document.getElementById('canvas'),
msaa: false,
plugins: [SSAAPlugin]
})
// Add effects in order
const bloom = viewer.addPluginSync(new BloomPlugin())
const taa = viewer.addPluginSync(new TemporalAAPlugin())
const ssr = viewer.addPluginSync(new SSReflectionPlugin())
// Bloom is applied before screen passes
// Works seamlessly with TAA and SSRDynamic Intensity Control
Animate bloom intensity for dramatic effects:
import {PopmotionPlugin, EasingFunctions} from 'threepipe'
const popmotion = viewer.getOrAddPluginSync(PopmotionPlugin)
// Pulse bloom intensity
popmotion.animate({
from: 0.5,
to: 2.0,
repeat: Infinity,
repeatType: 'reverse',
duration: 2000,
ease: EasingFunctions.easeInOutSine,
onUpdate: (v) => {
bloom.pass.intensity = v
},
})Emissive Materials for Bloom
Create materials that glow by setting their emissive properties:
import {PhysicalMaterial, Color} from 'threepipe'
const glowMaterial = new PhysicalMaterial()
// Set emissive color and intensity
glowMaterial.emissive = new Color(0xff6600)
glowMaterial.emissiveIntensity = 3.0 // Higher values bloom more
// The emissive parts will now bloom
object.material = glowMaterialEmissive materials are perfect for:
- Light sources (lamps, screens, buttons)
- Glowing sci-fi elements
- Neon signs and displays
- Energy effects
How It Works
The BloomPlugin operates through multiple rendering passes:
Prefilter Pass: Extracts bright areas above the threshold
- Reads the rendered scene
- Applies threshold and soft threshold filtering
- Outputs only bright pixels to a half-resolution target
Downsampling Passes: Progressive blur at multiple resolutions
- Each iteration reduces resolution by 2x
- Applies Gaussian blur weights
- Creates a blur pyramid (e.g., 1/2, 1/4, 1/8, 1/16 resolution)
- Configurable iterations (2-7 passes)
Upsampling Passes: Combine blurred layers
- Processes blur pyramid in reverse order
- Upsamples and additively blends each level
- Uses weighted blending based on radius and power settings
Composite Pass: Blend bloom with original scene
- Adds the final bloom buffer to the original render
- Preserves HDR values
- Applies intensity scaling
This multi-resolution approach provides efficient, high-quality bloom with minimal performance impact.
Performance Considerations
- Iteration Count: Primary performance factor - fewer iterations = better performance
- Resolution: Bloom uses half-resolution buffers to save memory
- Threshold: Higher thresholds = less area to process = better performance
- Half Float Textures: Uses 16-bit float textures for efficiency
- Temp Target Pooling: Reuses temporary render targets to minimize allocation
Tips for optimization:
- Start with
bloomIterations: 4and adjust as needed - Use higher thresholds (1.5-2.0) for performance-critical applications
- Disable bloom on materials that don't need it
- Consider disabling
backgroundBloomif not needed
Use Cases
The BloomPlugin is ideal for:
- Realistic Lighting: Simulating camera bloom from bright light sources
- Sci-Fi Scenes: Glowing energy effects, holograms, and futuristic interfaces
- Product Visualization: Highlighting metallic and reflective surfaces
- Automotive Rendering: Enhancing chrome, headlights, and polished surfaces
- Jewelry & Watches: Creating sparkle and shine on precious materials
- Game Environments: Adding atmospheric glow to lamps, screens, and effects
- Architectural Visualization: Realistic lighting from windows and fixtures
Common Patterns
Subtle Realistic Bloom
For photorealistic scenes:
bloom.pass.threshold = 1.5
bloom.pass.softThreshold = 0.5
bloom.pass.intensity = 0.3
bloom.pass.bloomIterations = 5
bloom.pass.radius = 0.6Strong Stylized Bloom
For artistic or sci-fi scenes:
bloom.pass.threshold = 0.8
bloom.pass.softThreshold = 0.7
bloom.pass.intensity = 2.0
bloom.pass.bloomIterations = 6
bloom.pass.radius = 0.8
bloom.pass.power = 1.5Performance-Optimized Bloom
For mobile or low-end devices:
bloom.pass.threshold = 1.8
bloom.pass.intensity = 0.5
bloom.pass.bloomIterations = 3
bloom.pass.radius = 0.5Dependencies
- GBufferPlugin (required): Provides material flags for selective bloom rendering
Troubleshooting
Bloom too subtle or not visible:
- Ensure scene has HDR values (
maxHDRIntensity> 1) - Lower the threshold value
- Increase intensity
- Check if materials have emissive properties
Bloom too strong or blown out:
- Increase threshold
- Decrease intensity
- Reduce emissive intensity on materials
- Adjust soft threshold for smoother falloff
Performance issues:
- Reduce
bloomIterations(try 3-4) - Increase threshold to bloom fewer areas
- Disable bloom on unnecessary materials
- Reduce canvas resolution with
renderScale
Examples
Check out these examples to see the plugin in action:
- Bloom Plugin - Basic bloom setup and configuration
- Velocity Buffer Plugin - Bloom combined with TAA
See Also
- TemporalAAPlugin - Anti-aliasing that works well with bloom
- SSReflectionPlugin - Screen-space reflections for realistic lighting
- TonemapPlugin - HDR tonemapping for proper bloom exposure
- GBufferPlugin - Required dependency for material flags
