- TypeScript 91.1%
- CSS 5.7%
- JavaScript 3.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
It is on the marketplace now, so say so and give the install command rather than describing where to look for it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
| .forgejo/workflows | ||
| .vscode | ||
| docs/superpowers/specs | ||
| media | ||
| scripts | ||
| src | ||
| test | ||
| .gitignore | ||
| .vscodeignore | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| esbuild.mjs | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
FBX Viewer for VS Code
Open an .fbx file and see it the way Blender or Unity would show it — materials,
textures, hierarchy, animation, and the coordinate system the file actually declares.
Most FBX previews render a grey blob. This one reads the parts of the format that other viewers skip.
What it does
Renders the file, not an approximation of it
- Material colours, specular, emissive, and transparency as authored
- External textures resolved off disk the way a DCC importer resolves them:
case-insensitively, across sibling folders, and tolerant of an extension that no
longer matches what shipped (
Wall.TGAnext towall.png) - Embedded textures, plus TGA and DDS, which
TextureLoadercannot decode alone GlobalSettings.UpAxisandUnitScaleFactorapplied, so a Z-up file stands upright and reported dimensions are in metres — three.js's ownFBXLoaderdiscards both
Tells you what is in there
- Scene hierarchy with per-node triangle counts, transforms, and visibility toggles
- Material list with colour swatches, map slots, and which meshes use each one
- File panel: exporter, FBX version, declared axes, unit scale, bounds, load time
- Attachment points — the
socket_*empties a modular kit uses — drawn in the viewport with labels, and listed in the inspector - Missing textures reported by name and slot instead of silently rendering white
Five shading modes and three lighting rigs
| Shading | |
|---|---|
| Shaded | Materials as authored |
| Shaded + Wire | Both at once |
| Wire | Topology only |
| Normals | Surface normals as colour — flipped faces become obvious |
| UV | Checker pattern — stretching and seams become obvious |
| Lighting | |
|---|---|
| Studio | Image-based lighting with ACES tone mapping, like a material preview |
| Unity | Directional sun plus hemisphere ambient, like Unity's default scene |
| Flat | No lighting at all — the raw authored colour |
Attach your own textures
Plenty of kits ship untextured and get coloured downstream, which makes a faithful preview a grey blob. So you can supply the images yourself:
- Drag an image onto the model — it becomes the base colour of whichever material you dropped it on.
- Drag onto a specific slot in the Materials tab, or click browse… next to it, to fill normal, roughness, metalness, emissive, ambient occlusion, or opacity.
- clear removes an assignment and puts the original back.
Assignments are remembered per model, keyed by material name, so they survive closing and reopening the file. They are stored in workspace state — nothing is written to the FBX, ever. FBX Viewer: Forget All Assigned Textures wipes them.
Drops work from the OS file manager and from VS Code's own explorer. PNG, JPEG, WebP, BMP, GIF, TGA and DDS are all accepted.
Animation
Clip selector, timeline scrubber, playback speed, loop toggle, and a skeleton overlay for skinned meshes.
Folder gallery
Right-click any folder → Open FBX Gallery for a thumbnail grid of every FBX underneath it. Thumbnails render lazily through a single shared WebGL context, so a folder with hundreds of models stays responsive. Click a tile to open it.
Installing
From the Extensions view in VS Code, search for FBX Viewer — or from the command line:
code --install-extension FiLL.fbx-viewer
marketplace.visualstudio.com/items?itemName=FiLL.fbx-viewer
To build it yourself instead:
npm install
npm run package # produces fbx-viewer.vsix
code --install-extension fbx-viewer.vsix
Every tagged version is also attached as a .vsix to its
Forgejo release.
Then open any .fbx file. To go back to a hex or text view, use
Open With… from the editor tab context menu.
If VS Code opens .fbx as "binary" instead
VS Code will show "There are multiple default editors available for the resource"
when another installed extension also claims .fbx — some 3D-preview extensions
register the pattern at the same priority, and VS Code refuses to pick between them,
falling back to the binary editor.
Click Keep FBX Viewer on that notification, or run
FBX Viewer: Make Default Editor for .fbx Files from the command palette. That
writes workbench.editorAssociations["*.fbx"] = "fbxViewer.editor" and settles it
permanently. FBX Viewer: Stop Being the Default Editor for .fbx Files undoes it.
The extension never writes that setting on its own.
Keyboard
| Key | |
|---|---|
F |
Frame the whole model |
W |
Toggle wireframe |
G |
Toggle grid |
L |
Cycle lighting preset |
I |
Toggle inspector |
Space |
Play/pause animation |
| Click | Select a mesh |
| Double-click a node | Frame that node |
Settings
All under fbxViewer.*. The ones worth knowing about:
| Setting | Default | |
|---|---|---|
lighting.preset |
studio |
studio, unity, or flat |
lighting.exposure |
1 |
Tone mapping exposure |
lighting.shadows |
false |
Shadow casting; costs performance on heavy scenes |
background |
theme |
theme, transparent, or any CSS colour |
upAxis |
auto |
auto reads the file; y, z, or off override it |
applyUnitScale |
true |
Apply UnitScaleFactor so bounds read in metres |
materials.convertToPhysical |
true |
Phong → physically based under studio/unity |
textures.searchDirectories |
textures, Textures, ../textures, … |
Where to look for external textures |
textures.searchDepth |
3 |
How deep to walk below the model directory |
sockets.pattern |
^(socket|attach|mount|snap)[_.-]|[_.-]socket$ |
What counts as an attachment point |
gallery.maxFiles |
500 |
Cap on gallery listing size |
maxFileSizeMb |
256 |
Confirm before opening anything larger |
performance.maxPixelRatio |
2 |
Cap on device pixel ratio — the biggest lever on fill rate |
performance.adaptiveResolution |
true |
Render softer while the camera moves, sharp when it stops |
performance.showStats |
false |
Overlay frame time, draw calls, triangles, and the GPU in use |
If it feels slow
Turn on fbxViewer.performance.showStats first — guessing at performance is how you
end up optimising the wrong thing. The overlay reports frame time, draw calls, triangle
count, the current pixel ratio, and the GPU string the driver hands back.
If that string mentions SwiftShader, llvmpipe, or "basic render", VS Code is rendering
in software and no amount of tuning here will help; check that hardware acceleration is
on (code --status shows a GPU section). Otherwise, lower performance.maxPixelRatio
— on a 4K display, dropping from 2 to 1 quarters the number of pixels shaded.
Changing upAxis, applyUnitScale, or sockets.pattern takes effect on the next
open; everything else applies immediately.
Development
npm install
npm run watch # esbuild in watch mode
npm run typecheck
npm test # vitest
npm run package # vsix
npm run icon # regenerate media/icon.png
Press F5 in VS Code to launch an Extension Development Host.
Layout
src/
shared/ protocol, FBX header parsing, texture matching — no VS Code, no three.js
extension/ custom editor, gallery panel, config, disk access
webview/
viewer/ three.js: scene, loading, lighting, materials, animation
ui/ DOM only, renders from a SceneReport
gallery/ offscreen thumbnail renderer
test/ vitest; corpus test runs against a real model library when present
The extension host and the webview share exactly one file,
src/shared/protocol.ts — every message crossing the
boundary is in that discriminated union, so a shape change breaks the build on both
sides rather than at runtime.
Tests
npm test runs unit tests over the header parser, the texture matcher, and the axis
maths, all against fixtures generated in code.
test/corpus.test.ts additionally parses an entire real model library headlessly and
asserts that every file yields geometry. Point it somewhere with FBX_CORPUS:
FBX_CORPUS=/path/to/models npm test
Without it, that suite skips and says so.
Releasing
Pushing a v* tag runs .forgejo/workflows/release.yml,
which builds the .vsix once and ships that same file to both the Forgejo release
and the Visual Studio Marketplace — so the two are byte for byte identical.
npm version 0.2.2 --no-git-tag-version
# add the matching "## [0.2.2]" section to CHANGELOG.md
git commit -am "release: 0.2.2"
git tag v0.2.2
git push --follow-tags
The workflow stops before building if the tag disagrees with package.json, if the
changelog has no section for that version, or if the marketplace token is missing —
a half-published release is worse than no release.
One-time setup
| What | Where |
|---|---|
VSCE_PAT secret |
Repository → Settings → Actions → Secrets. An Azure DevOps PAT with Marketplace → Manage scope, from the account owning the publisher |
| Publisher | The publisher field in package.json must be a publisher you own at marketplace.visualstudio.com/manage |
OVSX_PAT secret |
Optional. An open-vsx.org token, for the registry VSCodium, Gitpod and Cursor install from. The step is skipped when it is unset |
RUNNER_LABEL variable |
Optional. Defaults to ubuntu-latest; set it if your runner registered a different label |
GITHUB_TOKEN is injected by Forgejo automatically and needs no setup.
Known limits
- FBX only. No OBJ, glTF, or Collada.
- Read-only. Nothing is written back to the model.
- FBX 6100 ASCII files parse through three.js's loader, but their material coverage is weaker than 7.x — the format simply carries less.
- The gallery renders one thumbnail at a time by design. A folder of very heavy models will fill in gradually.
Licence
MIT — see LICENSE.