3DS File Documentation
Summary
A .3ds file is a 3D Studio Mesh: Autodesk's old binary 3D model format storing mesh geometry, materials, cameras, lights, and keyframe animation. Introduced in 1990 for DOS-based 3D Studio, it survives as a widely readable interchange format (MIME image/x-3ds). Open one free in Blender, MeshLab, or the browser viewer 3DViewer.net; convert to .stl to 3D print it or to OBJ/FBX for modern pipelines.
Technical details
| Feature | Value |
|---|---|
| Full name | 3D Studio Mesh |
| File extension | .3ds |
| MIME type | image/x-3ds |
| Format type | Binary, chunk-based 3D mesh/scene format |
| Developer | Autodesk (originally The Yost Group / 3D Studio for DOS) |
| Introduced | 1990 (3D Studio for DOS); native until 3D Studio MAX 1.0, 1996 |
| Open standard | No — proprietary, but widely reverse-engineered |
| Byte order | Little-endian |
| Chunk header | 2-byte chunk ID + 4-byte length (6 bytes) |
| Magic number | 4D 4D (0x4D4D, MAIN3DS primary chunk) at offset 0 |
| Vertex precision | 32-bit floats |
| Stores | Meshes, UVs, materials, cameras, lights, keyframe animation |
| Name limit | Object/material names capped at 10 characters (DOS legacy) |
| Limitations | No sub-objects, PBR materials, or modern shaders |
| Native successor | .max (full 3ds Max scene) |
| Related extensions | .max, .obj, .fbx, .dae, .stl, .prj |
| Free tools | Blender, MeshLab, FBX Review, 3DViewer.net |
| Note | Nintendo 3DS game ROMs also use .3ds — an unrelated file type |
What is a 3DS file?
The .3ds extension is the native file format of Autodesk 3D Studio, the DOS-based 3D modelling and animation program first released in 1990. When 3D Studio was replaced by 3D Studio MAX in 1996 (whose native scene format is .max), .3ds did not disappear. It survived as a lightweight, almost universally readable interchange format for 3D meshes, which is why it still turns up in asset libraries, game tools, and old model archives decades later.
Technically a 3DS file is binary and chunk-based: a tree of nested records, each tagged with an ID and a length, storing mesh geometry (vertices, faces, UV coordinates), materials, cameras, lights, and keyframe animation. Because the format dates to the DOS era it has hard limits: vertex coordinates are 32-bit floats, object and material names are capped at ten characters, and there is no concept of sub-objects, modern shaders, or physically based materials. Those constraints are why newer pipelines prefer FBX, OBJ, or glTF, and why .3ds is now mostly a legacy import/export option that remains useful precisely because nearly every 3D application can read it.
The chunk: a 2-byte ID and a 4-byte length
Everything in a 3DS file is a chunk. A chunk is a 6-byte header followed by its data and any child chunks. The first two bytes are the chunk ID; the next four are a little-endian 32-bit length giving the size of the entire chunk, header included.
struct Chunk {
uint16 id; // bytes 0-1: chunk identifier, e.g. 0x4D4D
uint32 length; // bytes 2-5: total bytes of this chunk incl. children
byte data[]; // payload, which may itself contain nested chunks
};
Because the length covers the chunk and all of its descendants, a reader that meets an unknown ID simply adds length to the current offset and continues — unknown chunks are skipped cleanly. That single rule is what lets a modern importer read a 3DS written by 1990s software, and it is why the format forms a tree rather than a flat record list. All multi-byte values are little-endian.
The chunk hierarchy: MAIN3DS, EDIT3DS and KEYF3DS
The chunks nest into a fixed hierarchy. The whole file is wrapped in the primary chunk MAIN3DS (ID 0x4D4D), which is why every 3DS file begins with the bytes 4D 4D. Inside it sit a version chunk, the 3D editor chunk that holds all the scene data, and optionally the keyframer chunk that holds animation.
0x4D4D MAIN3DS primary chunk (whole file)
├─ 0x0002 M3D_VERSION file version integer
├─ 0x3D3D EDIT3DS the 3D editor: all meshes, materials, lights
│ ├─ 0xAFFF MAT_ENTRY a material definition
│ └─ 0x4000 EDIT_OBJECT a named object
│ ├─ 0x4100 OBJ_TRIMESH triangle mesh
│ │ ├─ 0x4110 POINT_ARRAY vertex list
│ │ ├─ 0x4120 FACE_ARRAY face (triangle) list
│ │ ├─ 0x4140 TEX_VERTS UV coordinates
│ │ └─ 0x4160 MESH_MATRIX local transform
│ ├─ 0x4600 N_DIRECT_LIGHT a light
│ └─ 0x4700 N_CAMERA a camera
└─ 0xB000 KEYF3DS keyframe animation data
The EDIT3DS chunk (0x3D3D) is the heart of the file: it contains one EDIT_OBJECT (0x4000) per named object, plus the material definitions. The KEYF3DS chunk (0xB000) is separate and holds the animation track, so a static mesh file simply omits it. This separation is why a 3DS with no animation is smaller and why a viewer that ignores 0xB000 still shows the geometry correctly.
Inside a mesh: vertices, faces and UVs
A single mesh lives in an OBJ_TRIMESH chunk (0x4100) built from parallel arrays. POINT_ARRAY (0x4110) starts with a 16-bit vertex count, then that many triples of 32-bit floats giving the X, Y, Z of each vertex. FACE_ARRAY (0x4120) starts with a 16-bit face count, then that many faces, each four 16-bit values: three vertex indices plus a face-info flag holding edge-visibility bits.
TEX_VERTS (0x4140) supplies one UV coordinate pair per vertex for texture mapping, and MESH_MATRIX (0x4160) stores the object's local-to-world transform as a 4×3 matrix. A crucial detail: the 3DS format does not store per-vertex or per-face normals. A reader must compute them from the face winding, which is exactly why old 3DS models so often display with black or inside-out faces — the normals are reconstructed, and any inconsistency in the original winding shows up as flipped shading.
Material definitions and texture maps
Materials are defined once in MAT_ENTRY chunks (0xAFFF) under the editor chunk and referenced by name from each mesh. A material entry holds a name string (the ten-character limit applies here), ambient, diffuse, and specular colour chunks, a shininess value, and optional texture-map chunks (0xA200 for the diffuse map) that name an external image file. Because the texture is referenced by filename rather than embedded, a 3DS shared without its accompanying image files loads with the geometry and colours but missing textures — a frequent surprise when opening a downloaded asset.
3DS versus MAX: why you cannot recover a scene
It is tempting to treat .3ds and .max as two spellings of the same thing, but they are fundamentally different. A .3ds is a flat, baked mesh: the geometry as triangles, with basic materials. A .max is the full 3ds Max scene, storing modifier stacks, construction history, parametric objects, scene settings, and editor state that a mesh never contained. 3ds Max can import a .3ds and then Save As a .max, but that only wraps the imported triangles in a new scene; the original authoring history cannot be reconstructed from a format that never held it. For modern engines, exporting to FBX (which carries meshes, materials, rigs, and animation) or OBJ (a simple universal mesh) is the usual path.
Is your .3ds a model or a Nintendo 3DS game?
The same extension is used, coincidentally, for dumped Nintendo 3DS game cartridges. The two are entirely unrelated. A 3D-model .3ds from an asset library is usually a few hundred kilobytes and begins with the bytes 4D 4D; it opens in Blender or MeshLab. A game ROM is typically hundreds of megabytes and runs only in a Nintendo 3DS emulator, not in any 3D modeller. The file size and origin tell them apart immediately, and nothing in this page's mesh tooling applies to the game file.
References
- Paul Bourke — 3D Studio File Format (.3ds) chunk reference
- Wikipedia — .3ds (3D Studio file format)
- Blender Manual — Import/Export (Autodesk 3DS)
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.