Skip to content
| Marketplace
Sign in
Visual Studio Code>Visualization>3D Model LensNew to Visual Studio Code? Get it now.
3D Model Lens

3D Model Lens

Gyuha Shin

|
49 installs
| (0) | Free
View glTF / GLB / STL models and measure their dimensions inside VS Code
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

3D Model Lens

A VS Code extension for viewing 3D models and reading their size honestly. Built on Babylon.js.

Open a .gltf, .glb or .stl file and the viewer opens in place — distances on demand, and nothing invented along the way.

Measuring a model: the navigation cube, three distances with vertex snap, and the viewer panel's Measure tab

Supported formats

Format Notes
.gltf Resolves external .bin and texture references
.glb Binary container
.stl ASCII / binary

Click a file and the viewer opens. To see it as text, use Reopen Editor With… → Text Editor.

Model unit

Pick the unit from the Unit dropdown in the panel's Measure tab. The default Auto shows meters for glTF/GLB (the spec defines it that way) and plain numbers with no label for STL — the STL format has no unit field, so we cannot claim it is millimeters. Your chosen unit is remembered per file, so reopening the same STL restores it. The unit changes only the displayed label; no geometry is transformed ("1 model unit = 1 of this unit").

Axes are never called "width × height × depth". They are labeled X / Y / Z only, because the glTF loader's coordinate-system conversion and the Z-up convention in CAD-origin files would make those names wrong half the time.

The bounding-box readout is gone as of 0.7.0. Earlier versions showed the model's X / Y / Z size at the top of the panel. It is no longer displayed anywhere — the value is still computed, but only the camera framing uses it. Set decimal places for measurement labels under Display → Decimals.

The viewer panel

The panel sits in the top-right corner and is split into three tabs — Measure, Display and Debug. One is always open, and the tab you left open is restored when you come back to the file. Playback controls for animated models are not a tab: they sit in a fixed row directly under the coloured stripe, and appear only for files that have animation groups.

Hide the whole panel (and the navigation cube with it) from the editor title bar or 3D Model Lens: Toggle Panel.

Measurement

Turn on measure mode with the Enabled checkbox in the panel's Measure tab (or the measure icon in the editor title bar, or 3D Model Lens: Toggle Measure Mode from the command palette — all three stay in sync), then pick two points on the surface to create one distance. You can still drag to orbit while in measure mode — movement past a threshold does not place a measurement point.

  • Vertex snap (on by default): snaps to the nearest of the three vertices of the triangle you clicked. This is what you need to measure corner and edge dimensions accurately. To see where the vertices are, open the Babylon Inspector and turn on Wireframe on the model's material — note that the Inspector renders continuously, so the idle render gate stays off while it is open.
  • Measurement lines are drawn through the model so they stay visible, and the point markers sit in a screen overlay at a fixed size — they neither swell as you zoom in nor shrink away on a distant pick, whether the part is 5 mm or 5 m across.
  • Measurements accumulate in a list. Click an entry to select it, ✕ to remove one, Clear all to remove them all.
  • Changing the unit also refreshes the labels of measurements you already made.
  • Measurements are session-scoped — closing the tab discards them. They are not saved to a file.
  • You can measure while the Inspector is open.

Angles, surface area, and volume are not supported — see deliberate omissions.

Navigation

Drag to orbit, right-drag to pan, scroll to zoom. Arrow keys do the same as dragging, with Alt for zoom and Ctrl/Cmd for pan.

The navigation cube in the top-left corner shows which way you are looking and takes you somewhere in one click. Its six labelled faces and eight corners are click targets; the four arrows around it turn the view 90° at a time, and the small button at its lower right returns to the opening view. Every destination arrives level, so clicking a face is also how you straighten a tilted view.

Number keys jump to the same destinations, so you can reach a view without aiming at the cube:

Key View Key View
0 Opening view (also resets zoom and pan) 4 Back
1 Top 5 Left
2 Front 6 Bottom
3 Right

Each face of the cube names its key in its tooltip. Keyboard input — number keys and arrow keys alike — goes to the viewer only while the 3D area has focus, so click the model once after switching tabs; this keeps the viewer from swallowing keystrokes meant for the editor beside it. Number keys with a modifier (Ctrl, Alt, Shift, Cmd) are left alone so your own shortcuts keep working.

The same bracket from three viewpoints: front, right, and the opening view, reached with the number keys 2, 3 and 0

At the cube's lower left, a small X/Y/Z triad points along the world axes — the same axes measurements are labelled with. The letters are drawn on the lines, so the axes stay readable without relying on their colours.

Reading the shape

Flat-shaded parts — STL files especially — often come out as one near-uniform tone, because the default studio lighting arrives from every direction at once and a diffuse surface lit evenly barely changes with the angle it faces. Three checkboxes under Display exist to fix that. All three are off by default and none of them changes the geometry or your measurements — only how it is drawn.

The same STL bracket four times: with no aids it is one flat tone; Axis lighting tints each direction differently; Edges outlines every crease; Normal colors paints each face by the way it points

Toggle What it does
Axis lighting Lights the model from the three axes with contrasting colours, so faces pointing different ways come out in different hues. Not a realistic render — the point is that direction becomes visible. STL only: it works by adding diffuse light, and glTF/GLB materials are metallic by default, where diffuse light changes nothing and the model only gets darker. The checkbox is locked on those files.
Edges Draws a line along every crease, meaning an edge where the two faces meeting it differ in direction by more than about 18°. Disabled on very dense models, where finding those edges would freeze the viewer.
Normal colors Paints each face by the direction it points and ignores lighting entirely. The strongest of the three and the least realistic; it hides the model's own materials while it is on and restores them when you turn it off.

Because Normal colors paints faces directly, lighting has no effect while it is on — the Axis lighting checkbox is locked (but keeps its setting) until you turn it back off.

Inspector

Toggle the Babylon Inspector from the Debug tab's checkbox, the editor title bar icon, or the command palette (3D Model Lens: Toggle Inspector). It shows the node hierarchy, materials, textures, and rendering state — and your measurements stay put while you use it.

The Babylon Inspector open beside the model, with measurements still visible

The Inspector is heavy (React + FluentUI), so it lives in a separate chunk that loads only when you turn it on — viewing a model alone neither downloads nor parses it.

Because this is a read-only viewer, node and GUI editors are not supported. Pressing those buttons inside the Inspector says so (this also removed roughly 10 MB and several external CDN dependencies).

Settings

Setting Default Description
modelLens.background theme Viewer background mode. theme follows the VS Code editor background color; light (#ffffff) and dark (#1f1f1f) pin it regardless of the theme. Changing it from the viewer panel saves it here.
modelLens.grid true Show the ground grid in the viewer. Toggling it from the viewer panel saves it here and applies to every open viewer immediately.
modelLens.axisLighting false Light the model from three axes with contrasting colours so faces pointing different ways read differently. STL only — glTF/GLB materials are metallic by default, where added diffuse light has no effect. Toggling it from the viewer panel saves it here and applies to every open viewer immediately.
modelLens.edges false Draw a line along every crease. Toggling it from the viewer panel saves it here and applies to every open viewer immediately.
modelLens.normalColors false Paint each face by the direction it points, ignoring lighting. Toggling it from the viewer panel saves it here and applies to every open viewer immediately.
modelLens.inspectorOnStart false Start with the Inspector open when a model is opened. Toggling Open on start in the Debug tab saves it here.
modelLens.unit auto Initial unit for measurements. auto means m for glTF/GLB and no label for STL. Changeable per file from the Measure tab, and that choice is remembered.
modelLens.decimals 3 Decimal places on measurement labels (0–10). Changing it from Display → Decimals saves it here and applies to every open viewer immediately.

Resources

A 3D viewer burns GPU even while sitting still, so two things prevent that.

  • Rendering stops when idle. If nothing has changed among the camera, measurements, and display settings, no frame is drawn. While you look at a stationary model, GPU work is zero. Any interaction redraws immediately. While the Inspector is open we render continuously, because its fps counter and gizmos depend on the render loop.
  • Background tabs are not kept alive. We let VS Code destroy the webview of a hidden tab (we do not use retainContextWhenHidden), so WebGL contexts do not pile up with the number of open tabs. The only live 3D context is the viewer you can see.

The cost is a reload delay when you switch back to a tab. In exchange, measurements, camera position, display toggles, and measure mode are all restored, so your work is not interrupted (restarting VS Code clears them).

Whether clicking model files in a row reuses a single tab is decided by VS Code's workbench.editor.enablePreview setting (default true — a single click reuses the tab).

No external network access

Model loading, environment lighting (IBL), and the Inspector all use only local resources bundled with the extension. The webview CSP structurally blocks outbound requests with default-src 'none', and npm run check:bundle watches for new external dependencies creeping into the build output.

What this extension does not do

Each omission is deliberate, and each has a reason. (click to expand)
  • No OBJ / OFF / PLY / PCD / XYZ. They fall outside Babylon's built-in loaders, and point clouds have a fundamentally different measurement UX.
  • No angle measurement. Reusing the picking, snapping, and label infrastructure from distance measurement makes this cheap to add later, so it is left as follow-up work.
  • Measurements are not saved to a file. Designing a sidecar file format is a separate piece of work.
  • No volume / surface area. On non-watertight meshes, volume produces a meaningless number. Showing a plausible wrong answer is worse than having no feature at all.
  • The bounding box is never called "width × height × depth". It is labeled X / Y / Z only. Because of the glTF loader's coordinate-system conversion and the Z-up convention in CAD-origin files, those names would be wrong half the time.
  • No meshopt compression or KTX2 / Basis textures. Their decoders fetch from external CDNs, which the webview CSP blocks. Draco-compressed meshes are supported with a decoder bundled in the extension.
  • STL axes are used exactly as the file states them. Babylon swaps STL's Y and Z by default (STL is Z-up, Babylon is Y-up), but then the file says Z=30 while the viewer displays Y=30. In a measurement tool that is a lie, so we accept the cost of Z-up CAD files appearing to lie on their side.
  • Textures referenced through ../. The webview's allowed resource roots are limited to the extension directory, the workspace folder, and the model file's own directory. That limit is better than opening the filesystem root.

Contributing

Build commands, the three-layer verification strategy, and how to run the extension locally are in CONTRIBUTING.md.

Changelog

See CHANGELOG.md.

License

MIT. See NOTICE for third-party attributions.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft