Cookies for analytics and advertising
We use cookies for analytics and advertising, both sent to Google. Refusing changes nothing you can see.Read the privacy page
Converting PLY to glTF prepares a scanned mesh for a browser-based viewer, where a PLY will not load at all. Read the trade before you start: the per-vertex colour that is usually the reason a scan was saved as PLY is not carried across, so what arrives on the page is the shape without the surface.
Up to 100 files at once. Mixed formats are fine.
They convert one after another and download together as a ZIP.
PLY to GLTF
No browser renders PLY. Navigating to one downloads it, and there is no element, attribute or built-in viewer that will show it. glTF is the format the web settled on for 3D — three.js, Babylon.js and `<model-viewer>` all load it as their first choice — so putting a scan in front of a visitor means converting it first.
That is a routing decision rather than a quality one. The PLY is not a worse file; it is a file for a different room. Scanners, CloudCompare, MeshLab and every geometry-processing library speak it fluently, and none of that helps when the requirement is a page somebody opens on a phone.
This has to be said first because it decides whether to continue. A photogrammetry or structured-light capture is stored as PLY largely because the format holds `red`, `green` and `blue` properties on every vertex, which is how a scan carries its appearance without needing a texture atlas. The reader here takes `x`, `y` and `z` and ignores every other property, and the writer emits positions and indices only.
So a capture of a painted ceramic arrives in the viewer as untextured grey. For a geometric scan — a replacement part, a mould, a dimension check — that is exactly right and nothing has been lost. For a museum artefact or a product, the colour was the point, and this conversion produces something worse than the source in the only respect the audience will notice. If that is your case, the route is an export with a baked texture from the scanning software or MeshLab, not a geometry conversion.
Scanners produce points before they produce surfaces, and a PLY holding vertices with no face element is a point cloud. The conversion stops with the reason stated: "This PLY is a point cloud: it holds points but no faces. Turning points into a surface is reconstruction rather than conversion, and needs a modelling tool."
That is a refusal rather than a failure, and it is the honest answer — reconstruction involves choices about smoothing, depth and hole filling that change the result substantially, and no converter should be making them silently. MeshLab’s Screened Poisson Surface Reconstruction is the usual route and takes a few minutes; most scanning applications will also export a reconstructed mesh directly. Convert that.
Raw captures are dense by design: a handheld scanner routinely produces one to five million triangles for an object the size of a shoe, because the mesh is derived from the sample rate rather than from what the shape needs. A web page has a very different budget — a model that loads promptly on a mid-range phone and holds a frame rate is measured in tens of thousands of triangles, not millions.
Decimate before converting, not after. MeshLab’s Quadric Edge Collapse Decimation with a target face count, or Blender’s Decimate modifier, both preserve silhouette well and take one pass. Aim at a number and check it visually at the size the model will actually appear on the page; a scan reduced by ninety-five per cent is frequently indistinguishable at 600 pixels wide. Doing it first also makes every step afterwards faster, including this one.
One mesh, one primitive, mode 4. The positions become a `VEC3` float accessor and the indices a `SCALAR` unsigned-integer accessor, with a buffer view for each and a single buffer holding both. The position accessor carries `min` and `max`, which the specification requires and which viewers use to frame the model — a file without them opens zoomed to nothing in several of them.
Those six bounds numbers are also the fastest sanity check available. Open the JSON, read the min and max off the position accessor, and you have the bounding box in the source’s units without loading anything. If the model is a thousand times larger or smaller than you expected, or is sitting nowhere near the origin, that is where you find out.
This conversion produces one self-contained file, because a conversion produces one download and a `.gltf` with a `.bin` beside it would be two. The vertex data is therefore base64-encoded into a data URI on the buffer, and base64 costs four characters for every three bytes — about thirty-three per cent — on top of pretty-printed JSON with two-space indentation.
For a file you are going to open in an editor that is a fair price. For a file a visitor downloads it is not, and the GLB conversion produces the same geometry as one binary file with no encoding overhead. Use glTF when you want to read the accessors, validate the document or hand it to `gltf-transform`; use GLB when the destination is a page.
Some sources on this site are welded on the way in — an STL stores three unshared vertices per triangle and would otherwise produce a file four times larger than it needs to be. A PLY already stores an indexed vertex list, so the positions and faces are carried across as they were.
The vertex count in the glTF therefore matches the count in the PLY header, which makes the conversion easy to verify. It also means any duplicates the scanner or the reconstruction left in place come through. Faces with more than three corners are fan-triangulated, which is correct for the convex quads reconstruction produces and can misbehave on a concave polygon — rare in scan data, and worth knowing if the mesh came from a modelling package instead.
PLY declares no unit and no orientation. glTF declares no unit either, though its whole ecosystem assumes one unit is one metre and every viewer is Y-up. Scanning software is not consistent about either — millimetres are common, Z-up is common, and some tools centre the model while others leave it wherever the capture happened to be.
So expect to rotate and scale on arrival, and do it in the viewer’s own scene rather than by editing the file, which keeps the source honest. In `<model-viewer>` an `orientation` attribute and a `scale` attribute settle it in two lines; in three.js it is two calls on the loaded object. Establish the numbers once against a dimension you can verify in the source and record them, because every scan out of the same device will need the same pair.
Since the glTF has no material, everything the visitor sees comes from the viewer’s lighting. Flat grey under a single light reads as a blob; the same mesh under an environment map with some ambient occlusion reads as a carved object, and that difference is entirely in the page rather than in the file.
`<model-viewer>` ships neutral environment lighting and a `shadow-intensity` attribute that costs one line and does most of the work. In three.js an environment map plus a hemisphere light is the equivalent. Because the converted mesh carries no vertex normals, the viewer computes them, which produces faceted shading on a decimated scan — usually desirable, since it shows the surface; add smooth shading in the viewer if you would rather it did not.
In this browser tab, by plain JavaScript. No WebAssembly module is fetched, nothing is uploaded, there is no account and no daily allowance. The network tab during a conversion is how to check that rather than this sentence.
Scans are an unusually sensitive category. A capture of a museum artefact is frequently under an agreement about where the data may go, a capture of a person is biometric in everything but name, and a scan of a component is somebody’s design. The free limit is 100 MB per file, which is a large decimated mesh and a small raw one — another reason to reduce before converting.
| PLY | GLTF | |
|---|---|---|
| Full name | Polygon File Format | GL Transmission Format |
| File extension | .ply | .gltf |
| Media type | model/ply | model/gltf+json |
| First published | 1994 | 2015 |
| Published by | Stanford University | Khronos Group |
| Specification | — | glTF 2.0 |
| Licensing | Open standard | Open standard |
| Standing today | Current | Current |
| Opens in a browser | No browser | No browser |
| Considered instead | OBJ, STL | GLB, OBJ |
Blender reads both PLY and GLTF, so there is a way to check the result against the original without a second tool.
The two are aimed at different work: PLY at scanning and moving data between programs, GLTF at the web and handing a finished file over. That is worth weighing before converting, because the reason one exists is usually the reason the other is awkward.
GLTF comes from Khronos Group and dates from 2015, specified as glTF 2.0. Blender, three.js and Babylon.js all read it.
PLY was published in 1994 and GLTF in 2015. The older one is generally the safer file to hand to somebody; the newer one usually does the job in fewer bytes.
No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.
No. Per-vertex colour is the usual reason a scan is stored as PLY, and only x, y and z are read. The glTF arrives as untextured grey geometry, which is a real loss for a photographic capture and no loss at all for a geometric one.
Then the file holds points and no faces, which is what a scanner produces before reconstruction. Turning points into a surface is reconstruction rather than conversion — do it in MeshLab with screened Poisson, or in your scanning software, and convert the resulting mesh.
GLB for delivery. This glTF embeds its buffer as base64, which is about a third larger than the same bytes stored binary, and a GLB is one request with no data URI. Take the glTF when you want to read or edit the JSON.
Far fewer than a scan produces. Raw captures routinely run into millions of triangles, and a page meant to load on a phone wants a small fraction of that. Decimate in MeshLab or Blender before converting rather than after.
Only by luck. glTF viewers are Y-up and scanners rarely agree on an orientation, so expect to rotate. Neither format records a scale either, so a scan in millimetres will be a thousand units tall in a viewer that expects metres.
No. The PLY is read and the glTF written by JavaScript in this tab, with no upload and no engine download. Captures of artefacts and of people are exactly the material that should not be passing through a third party.