Performance release. Figures for a 33 million triangle model with 7 subdivision levels on an M1 Pro laptop, measured on the merged release against 0.5 with the same benchmark (docs/performance.md): memory for the mesh, BVH and levels 156 -> 83 bytes per triangle (whole process 5.6 -> 3.4 GB); GPU memory 46 -> 15 bytes per triangle; orbit 20.6 -> 9.2 ms with 4x antialiasing, 14.8 -> 3.7 ms with Fast Navigation; a medium dab 11.9 -> 7.5 ms and a large one 78.5 -> 45 ms with the GPU upload; Mask / Paint dabs 5.6 / 7.0 -> 2.5 / 3.5 ms; opening the project 4.7 -> 2.1 s. The sections below were measured on each part's own branch; the merged figures differ a little (dabs on divided meshes are about 15% slower than on the brush branch alone, from the implicit adjacency that saves the memory).
Update check
- Once a day the app reads https://islandmed.github.io/SculptForge/latest.json (nothing about the user is sent)
and, when a newer version is out, shows a banner: What's new, Download, Later, Skip this version.
Help > Check for updates asks right away; Preferences > Updates turns it off.
SF_NO_UPDATE_CHECK=1turns it off for a run,-DSCULPTFORGE_UPDATE_CHECK=OFFat build time (the AUR package uses it).
Memory: sculpts with subdivision levels take half as much
- A divided sculpt takes about 90 bytes per triangle in memory instead of 160: a 33 million triangle model with its levels needs 3.0 GB instead of 5.3 GB, and a 100 million triangle one fits in 9 GB.
- Levels made by Divide store no triangles, quad pairs or vertex maps: they follow from the level below, and are generated when a level is entered. A level also no longer keeps its detail next to its positions (the detail is fitted to the positions when a lower level changes). The level stack went from 75 to 29 bytes per triangle.
- The mesh of such a level works out which vertices and triangles surround each vertex from the level's topology instead of storing those lists (62 -> 39 bytes per triangle for the sculpting mesh). Brushes, normals, undo and the renderer get exactly the same lists, so sculpting gives bit-identical results; working them out costs some speed: dabs on divided meshes are up to about 15% slower (large brushes at 33M: 3%).
- Divide goes to 100 million triangles and beyond: the limit follows the computer's memory (about 160 million on 32 GB) instead of a fixed 50 million.
- Opening a project no longer needs twice the scene's memory (the file is read straight into the meshes) and is about twice as fast (33M: 4.7 -> 2.1 s; the BVH is built while the levels load). Saving no longer copies the meshes first, and project files of divided sculpts are about 30% smaller.
- Lower Res after sculpting at the top level is faster (33M: 1.5 -> 0.9 s), and so is Divide (2.4 -> 1.4 s).
- Project format 6. Projects from 0.5 and earlier open as before (and get the savings); 0.5 can't open format 6 projects.
Fixed
- New Cube at some resolutions (13, 26 and others) left a few vertices along the cube's edges unwelded, so the mesh had small cracks there (the 33 million triangle benchmark sphere among them).
Performance
- Brushes on huge meshes are 2 to 3 times faster on the CPU: a radius 0.4 dab (a million vertices with X symmetry) on a 33M triangle sphere takes about 21 ms instead of 49 (39 instead of 63 with the GPU upload), Smooth and Move at that size 10 and 5 ms; a medium dab about 3.6 ms instead of 9 (6.5 instead of 11 with the upload), and undo of a big stroke about twice as fast. Results are still exactly the same with multithreading on or off; compared with 0.5 they differ only by rounding (a brush's area normal is summed over its vertices in index order) and where the two halves of a symmetric dab overlap (both now see the normals from before the dab).
- How: the BVH vertex query, the normal update and the refit keep their vertex and leaf sets as bitmaps listed in index order (the mesh's arrays are then read front to back), each thread marks a bitmap of its own, a dab refits the BVH leaves its query already found, normal updates prefetch the faces ahead, the undo record of a stroke is written in parallel, the Move brush runs each mirror in parallel, symmetric dabs update normals once where the mirrors overlap, and undo swaps positions in parallel. Small dabs stay on one thread.
- Less memory while sculpting: the per-vertex stamps of the BVH, the normal update and the stroke recorder (20 bytes per vertex, about 330 MB at 33M triangles) are bits now.
--bench-brushes TEXTruns only some benchmark rows; the benchmark measures Smooth and Move at a large radius.
Faster viewport
- Meshes are drawn in clusters of up to 4096 triangles (64-triangle runs sorted along a Morton curve). Each frame skips the clusters outside the view and, on closed meshes seen from outside, the clusters facing away (the GPU also skips the back faces left in the others); the rest go in one multi-draw with 16-bit indices. Orbiting a 33M triangle sphere with 4x antialiasing: 20.6 -> 8.7 ms; 104M: 19.6 ms.
- Vertices take 12 bytes on the GPU (28 before): positions on a 21-bit grid over the mesh, octahedral normals, square-root companded curvature. Polypaint is 8-bit (gamma encoded), the mask 8-bit, polygroups 16-bit. With the index and wireframe savings a mesh needs about 15 bytes per triangle on the GPU (46 before on meshes with quads, whose wireframe edges were always kept).
- Fast Navigation also draws big meshes as a motion proxy while the view moves: per cluster, the vertices snapped to a grid a few edges wide (seam vertices kept, so the proxy of a closed mesh is closed too), about a fifth of the triangles. 104M triangles orbit at about 100 fps. Built only for clusters that changed, when the view starts moving.
- The wireframe's edges are built when the wireframe is turned on, each edge once (they were always kept, every edge twice).
- First upload of a 33M mesh 701 -> 422 ms (indices and vertices written straight into mapped buffers while the layout is built); paint and mask dabs no longer re-send positions and normals.
sculptforge --benchreports GPU memory, triangles drawn after culling, the motion proxy, and orbiting with and without antialiasing;--bench-viewruns only the viewport's part.
Changed
- STL export is now in millimetres with Z up, as slicers expect: models used to arrive 1000 times too small
(0.44 mm instead of 44 cm) and lying on their back.
export_stltakesheight_mm=to scale to a print height, plusscale=andz_up=, and the status line gives the printed size. Opening an STL converts back, so downloaded print models come in upright and at their real size; STL files from 0.5 and earlier still open as saved.
Downloads
New here? install/ explains
which file to pick, or install with one command:
curl -fsSL https://raw.githubusercontent.com/islandmed/SculptForge/main/install/install.sh | sh (macOS / Linux),
irm https://raw.githubusercontent.com/islandmed/SculptForge/main/install/install.ps1 | iex (Windows PowerShell).
Each file is also attached without its version number (e.g. SculptForge-macos.dmg) so links to
releases/latest/download/... always get the newest build.
| Platform | File |
|---|---|
| Windows 10/11 (x64) | SculptForge-…-windows-x86_64.exe (installer) or .zip (portable) |
| macOS 11+ (Apple Silicon and Intel) | SculptForge-…-darwin-universal.dmg |
| Ubuntu / Debian / Mint / Pop!_OS | sculptforge_…_amd64.deb or …_arm64.deb |
| Fedora / RHEL / Rocky / Alma 8+ | sculptforge-…x86_64.rpm or …aarch64.rpm |
| Studio pipelines (VFX Reference Platform) | SculptForge-…-linux-…-vfx2026.tar.gz (GCC 14.2, glibc 2.28) or …-vfx2027.tar.gz (glibc 2.34), with the Python 3.13 module |
| Any Linux | SculptForge-…-linux-x86_64.AppImage or …-arm64.AppImage |
| Arch Linux | yay -S sculptforge (AUR) |
The builds are not code-signed yet. macOS: right-click the app → Open the first time.
Windows: if SmartScreen appears, choose More info → Run anyway. Checksums are in SHA256SUMS.txt.