Inspection lighting is different from cinematic lighting
A product viewer has a practical job: make the model understandable. The user needs to see silhouette, material roughness, edges, and scale. Heavy contrast may look beautiful in a hero render, but it can hide the exact details a viewer is supposed to inspect. Begin with a neutral lighting rig and add drama only after the object is readable.
A useful default rig has three layers. Hemisphere light creates a gentle base so shadowed areas are not pure black. A directional key light gives the object a main highlight and shape. A rim or back light separates the object from the background. This setup is simple, fast, and easy to explain in UI.
PBR materials need an environment
Many GLB files use MeshStandardMaterial or MeshPhysicalMaterial. These materials are designed for physically based rendering, which means roughness, metalness, and environment reflections affect the final look. If a metallic object looks dead, adding a bright point light may not solve the problem. It may need an environment map or at least a balanced studio setup.
For a lightweight static tool, start with direct lights and document the limitation. For a production configurator, add an HDR environment and expose intensity controls. The important design choice is to separate inspection mode from brand mode. Inspection mode should reveal the asset; brand mode can be more stylized.
Keep the background honest
Dark UIs are popular for 3D tools, but dark models on dark backgrounds need help. A subtle grid, a floor, or a rim light can keep the object from disappearing. The background should not compete with the model, but it should provide enough contrast to judge scale and orientation.
On mobile, highlights can compress quickly because the canvas is small and device brightness varies. Test the same lighting rig on a narrow viewport. If the object becomes a dark blob, the rig needs a stronger fill light or a background that is less close to the material color.
Expose presets, not every light property
A public tool does not need every possible light slider. It needs a few reliable presets: neutral studio, product glossy, clay inspection, and dark hero. Each preset can be a small set of intensities and positions. That is easier for users to compare and easier for search visitors to understand.
When a preset includes code, keep it short and copyable. The goal is not to replace learning; it is to give a working baseline that can be pasted into a Vite or vanilla Three.js scene.
Compare four lighting intentions
The preset tool keeps the model constant while changing the background, hemisphere light, direct lights, and exposure.
- Studio product
- Softbox neutral
- Dusk contrast
- Matte clay
Keep ambient and directional roles separate
A single strong light can make the front readable while crushing the unlit side.
scene.add(new THREE.DirectionalLight(0xffffff, 8));scene.add(new THREE.HemisphereLight(0xffffff, 0x263342, 1.7));
const key = new THREE.DirectionalLight(0xffffff, 2.8);
key.position.set(3, 4.5, 4);
scene.add(key);Color management baseline for PBR
Set renderer.outputColorSpace explicitly, keep base-color and emissive textures in the sRGB color space, and leave roughness, metalness, normal, and occlusion textures as non-color data. Check that baseline before changing light intensity: an incorrect texture interpretation can look like weak lighting, excessive exposure, or a broken material.
Tone mapping, exposure, direct lights, and environment reflections affect different parts of the final image. Hold the model and camera constant, compare one preset at a time, and use the same known material to separate a renderer configuration problem from an asset-specific problem.
Studio preset record
The default code is present in the page source before the live preview starts.
| Element | Recorded setting |
|---|---|
| Exposure | 1.0 |
| Background | #f2f6fb |
| Hemisphere intensity | 1.7 |
| Key / rim intensity | 2.8 / 1.2 |
Diagnose a black or flat GLB
Confirm the material pipeline before compensating with stronger lights.
- Render a known MeshStandardMaterial under the preset.
- Check renderer output color space and tone mapping.
- Confirm base-color textures use the correct color space.
- Add the project environment map, then retune direct lights.
Readable studio rig
scene.add(new THREE.HemisphereLight(0xf4efe4, 0x202020, 1.4));
const key = new THREE.DirectionalLight(0xffffff, 2.2);
key.position.set(4, 5, 3);
scene.add(key);
const fill = new THREE.DirectionalLight(0x88b7ff, 0.7);
fill.position.set(-3, 2, 4);
scene.add(fill);
const rim = new THREE.DirectionalLight(0x65d8c2, 1.2);
rim.position.set(-4, 3, -4);
scene.add(rim);
Sources and further reading
Update record
- : Rewritten around a reproducible demo, explicit test record, code comparison, and known platform limits.
- : Added a PBR color-management baseline and routed the consolidated color-management URL to the maintained lighting workflow.