Setup Post Processing

The <model-viewer-effects> library addon for <model-viewer> provides you with a easy-to-use postprocessing workflow for spicing up your models.
The list of currently support effects is: SMAA, FXAA, Pixelate, Outline, Glitch, SSAO, Bloom (Global/Selective), and Color Grade.

In order to avoid package collisions, you will be required to add an import-map for the Three.js package, and use the module version of <model-viewer>.

Safari does not support import maps, the following script will make your code work universally:

Bring Three.js from any cdn - cdnjs, unpkg, or jsdelivr:

Now import the <model-viewer> module version which doesn't package three, and the <model-viewer-effects> addon:

Setting up post-processing effects is as simple as adding an <effect-composer> component inside your <model-viewer> element. From here, simply add any of the supported effects inside the <effect-composer>.
See the API Reference for a list of all supported effects.

The Effects API

Effect Composer

The <effect-composer> component has two main properties: render-mode and msaa.

The default value for renderMode is 'performance'. By switching to 'quality', the <effect-composer> will use high-precision linear buffers for rendering, allowing for HDR-like workflows, at a performance cost. renderMode can only be set once, before the Effect Composer instantiates. Updating it after that is not possible.
Note: the default 'performance' renderMode is prone to banding in dark scenes, which is especially noticeable with <bloom-effect>.

msaa uses a performant algorithm for anti-aliasing on WebGL2 enabled browsers. Set this to a factor of 2 to enable - it is disabled by default.
Note: msaa may introduce visual artifacts when used with depth-based effects such as <ssao-effect>, in which case it would be preferred to use the <smaa-effect>.


All Effects are reactive components, so all properties can be changed during runtime. This example demonstrates the BlendMode API, which allows you to blend effects like you would layers in Photoshop. We use a <color-grade-effect>, which allows you to alter the look of your model.

Color Grading

The default tonemapping provided by <model-viewer> is Aces Filmic tonemapping, which provides the most pleasing image, similar to Filament's gltf-viewer. However the this tonemapping is not applied to <model-viewer-effects> postprocessing. To overcome this, it is recommended to always add the <color-grade-effect> at the end of your postprocess pipeline, which similarly sets the default tonemapping to Aces Filmic.
The example below showcases the rendering difference with and without the <color-grade-effect> when <bloom-effect> is applied, as well as allows you to select any of the other tonemapping modes.

Selective Effects

Some of the implemented effects are selective and may be applied to only certain meshes in your model. Currently, this is exclusive to <selective-bloom-effect> and <outline-effect>. The default behavior for selective effects is to use the default selection provided by the <effect-composer>, which contains a set of all meshes in the model.
By providing an array of mesh names to the selection attribute, you may enable the effects only for those meshes.
This example demonstrates the application of the <selective-bloom-effect> exclusively to Meshes with an emissive material:

Combining Effects

<model-viewer-effects> will attempt to join as many of your effects as possible into a single EffectPass, which has a significant performance benefit as opposed to keeping all the effects in separates Passes. Effects can be disabled by setting the blend-mode to skip.
It is recommended to follow the official Postprocessing Wiki for best practices in combining effects. The <model-viewer-effects> handles effect compatibility issues by placing incompatible effects in a separate Pass.

Custom Effects

Using the addPass() method on the <effect-composer>, you can add custom PostProcessing effects that are not provided by the base library. If you would like to implement your own effects from scratch, refer to the Postprocessing Wiki.

If your Pass requires the scene or camera instance, they are set automatically. Similarly, if any of the effects in the pass require a normalBuffer or selection, you can access them from the <effect-composer>.
If any property of your effect changes, you must call the queueRender() method so that the <effect-composer> knows to re-render with your new changes.

Note: If your pass uses the normalBuffer, you must specify as such in the addPass method, as the normals are disabled by default unless they are used. Similarly, if your pass requires to be re-rendered each frame, you must pass the requireDirtyRender parameter.