In theory, there's no limit to the complexity of models that can be displayed. However, WebGL is hardware-accelerated, so the viewer's performance depends greatly on the machine displaying it. This is even more important to consider for mobile users.
Before a model or scene can be rendered, the viewer needs to download and prepare all the required assets. This is what happens during the Loading 3D Model screen as well as the first moments of rendering when higher-resolution textures are loaded (the blue loading bar across the top of the viewer - if you want to avoid this step, try the preload embed parameter).
All the texture images need to be downloaded, so using many high-resolution textures can greatly affect download time. We optimize texture file size after you publish a model, and we will never use a texture larger than 8192×8192 pixels. However, you should minimize the number of textures and the size of textures as much as possible.
The higher the vertex count / polygon count of your model, the longer it will take to download.
HDRi environments are large images, and if you are using one for the background or lighting (or both), it needs to be downloaded. A fixed image background also needs to be downloaded. A solid color background is the best, as it requires no download.
While not technically part of the "download", several scene optimization processes take place before the scene is rendered. This can greatly improve viewer performance. It usually does not take much time, but the more complex the scene, the longer this will take.
- Merge identical materials
- Merge meshes (geometries) that share the same material
- Simplify the scene graph
- Remove unused UVs
- Remove unused vertex colors
- Remove unused normals & tangents (this can also happen during processing in some cases)
- Channel pack textures (e.g. Diffuse and Metalness)
If you're having trouble with slow model viewing, bad frame rates, or browser crashes, the scene is probably too complex for your device or browser. There are many complexity factors that affect performance.
- Polygons / Vertices
- Shadows / Lighting
- Post-Processing Filters
A large number of materials is a significant bottleneck in rendering performance. Instead, you can use a single texture instead of many material colors.
Textures require a lot of VRAM to render, so the fewer textures you can use, the better. A 4096×4096 (4k) texture, for instance, can require ~50MB (50 MiB, actually) of memory. It adds up quickly with lots of meshes and big textures.
Keep in mind the size of a texture versus the final screen size of the object in question. It's unnecessary to use a large texture on an object that will appear very small on the screen. Rather than use many separate textures, you can use a texture atlas to pack the textures for different objects together. Check out the Polycount Wiki on the subject.
While there's no strict rule here, we've found that 4k resolution is a good limit for performance and compatibility. It's better to use a 4k texture than several 2k textures, but it could be better to use a few 4k textures rather than an 8k texture.
The more separate meshes/objects/geometries in your scene, the worse the model will perform. Ideally, there would be only one mesh for each material. This is a common issue with SketchUp models and CAD models. During processing, we also split large meshes into 65,536-vertex chunks, in order to support all graphics cards.
Polygons / Vertices
Decimating your models to reduce polygon count can be a good way to improve performance. In most cases, it's unnecessary to have a polycount in the millions. It's also possible to 'fake' a higher polycount with normal mapping. Here are some related tutorials:
The more bones you use in an animated skeleton, the more expensive it is to render the animation.
The total number of nodes in the scene graph roughly represents the overall complexity of the model, and includes common objects like nodes, transforms, meshes, and bones.
Rendering transparency is very expensive, depending on the type of transparency you use. From fastest to slowest: Mask, Dithered, Additive, Blending.
Shadows / Lighting
Rendering real time shadows from dynamic lights is expensive. Lights Attached to camera are problematic because they must be rendered every single frame as the camera moves. It's best to avoid Directional and Hemi lights casting shadows and attached to camera whenever possible.
Using Shadeless mode is faster than Lit mode because there are no light calculations needed.
Using a lot of post-processing filters can hurt performance. SSAO, Bloom, and DoF are particularly expensive.
All of these different complexity factors interact to influence the complexity of the scene and affect the viewer's performance. It's not an exact science, but here are some recommendations for model performance:
- As few materials as possible
- 50 geometries/meshes or less
- 10 textures or less, especially when they are 4k+
- 500,000 polygons or less
- Fewer than 35 bones per geometry
- Low scene complexity
- Avoid expensive transparency methods
- Avoid lights casting shadows when attached to the camera
- Consider using Shadeless mode when appropriate
Obviously, different models will have different requirements, but it's important to keep these points in mind, especially for large and complex scenes. Check out Unity's Performance Tips for more details.
Other common problems
Shaky model with cracks and seams
This shaking problem is caused by having very large (or very small) numbers as vertex coordinates. A solution is to reduce (or increase) the scale of the model before uploading. It can also be caused by overly precise vertex coordinates (floating point error), which can be fixed by rounding off coordinate values to a lower degree of accuracy. This can be particularly problematic for georeferenced models. It's best to change from a global coordinate system (like WGS84) to a local coordinate system.
A good solution is to recenter the model in its bounding box, which can be done in software like MeshLab.
- Open the model in MeshLab
- Go to Filters → Normals, Curvatures and Orientation → Transform: Translate, Center, set Origin
- Check Freeze Matrix and set the Transformation to Center on BBox
- Click Apply. You may see the model disappear - this is OK.
- Export the model as OBJ, make sure you have TexCoord enabled if you have textures.
- ZIP the OBJ + MTL + Texture and Re-Upload to Sketchfab
Flickering surfaces (Z-Fighting)
This problem is caused by overlapping faces. You should remove any overlapping surfaces from your model.