跪拜 Guibai
← All articles
Three.js · WebGL · Vue.js

Click-to-Select Parts on a 3D GLTF Model with Three.js and Vue

By Tony费 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Raycaster-based part selection is the standard interaction pattern for WebGL product configurators, maintenance training sims, and digital twins. This walkthrough bundles the full loop — picking, highlighting, name mapping, and cleanup — into a single Vue component that can be dropped into any project loading multi-part GLTF models.

Summary

A complete Vue component loads a missile-launcher GLTF model and wires up a Raycaster to detect clicks on individual sub-meshes. Each click restores the previously selected part to its original material, then turns the newly clicked mesh semi-transparent red. A hardcoded name map translates internal mesh names like `defaultMaterial_9` into human-readable labels shown in an overlay panel.

The implementation covers the full lifecycle: model loading with GLTFLoader, orbit controls for camera movement, coordinate conversion from screen space to NDC for the raycaster, and a disposal routine that tears down geometries, materials, the renderer, and controls to prevent memory leaks when the component unmounts.

Because the model’s sub-parts carry distinct `name` properties, the same pattern works on any multi-mesh GLTF asset — industrial equipment, mechanical assemblies, or architectural models — without modifying the source file.

Takeaways
Raycaster is the only universal method for click-selecting individual meshes in a Three.js scene.
Screen coordinates must be converted to normalized device coordinates (-1 to 1) before passing them to `raycaster.setFromCamera`.
GLTF models composed of multiple sub-meshes expose a `name` property on each mesh, which can be mapped to application-level labels.
Each new click must first reset the previously selected mesh’s material (color and opacity) before applying the highlight to the current one.
A full disposal routine — traversing the scene to dispose geometries and materials, then destroying the renderer, controls, and animation loop — prevents GPU memory leaks when the component unmounts.
Conclusions

The hardcoded name-to-label map (`defaultMaterial_9` → 'Missile Body') is brittle; any model re-export that changes internal mesh names will break the mapping silently. A more robust approach would store metadata in GLTF extras or a sidecar JSON.

The highlight logic directly mutates the original mesh material’s color and opacity, which means the original material state is lost unless explicitly saved beforehand. For models with complex PBR materials, a separate highlight material or an outline pass would preserve the original look.

Binding `document.onclick` globally instead of scoping the listener to the canvas means clicks outside the 3D viewport still trigger the raycaster, which is wasteful and risks unintended interactions with other UI elements.

Concepts & terms
Raycaster
A Three.js class that projects a ray from the camera through a screen point into the 3D scene and returns an array of intersected objects, ordered by distance. It is the standard method for mouse-picking 3D objects.
Normalized Device Coordinates (NDC)
A coordinate system used by WebGL where the visible screen maps to a cube from -1 to 1 on the X and Y axes. Mouse pixel coordinates must be converted to NDC before they can be used with a Raycaster.
GLTFLoader
Three.js’s built-in loader for the GL Transmission Format (glTF/GLB), an open standard for transmitting 3D scenes and models. It parses the file and returns a `scene` object containing the model’s mesh hierarchy.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗