Body Scan Render Process (Decathlon DX × Treedy's)
Design of an automated rendering pipeline turning a visitor's body scan into an animated visual souvenir: a looping video of their own point cloud, in a synthwave aesthetic inherited from the cyberpunk wave of the time.
Vision & Concept
Decathlon integrated, inside Decathlon DX (its members-only lab store where the retailer trials retail innovations under real conditions before any wider rollout), a body scanner from Treedy's, an AI-assisted technology delivering exact measurements of a fully clothed person for in-store clothing sales assistance.
- Beyond the measurement: the idea was to turn a purely utilitarian scan (clothing-size measurement) into a memorable experience, giving the visitor a digital "souvenir" of their visit.
- Art direction: the raw point cloud from the scan is staged in a synthwave/cyberpunk aesthetic, in tune with the visual wave dominant at the time, with a glowing silhouette progressively taking shape out of the dark.
Context & Production Challenges
- One scan, one souvenir, per visitor: each pass through the scanner had to generate an individual render, with no manual intervention and without slowing down store traffic.
- Quality render, no live real-time budget: producing a smooth, polished animation per visitor ruled out a classic interactive render; the solution needed to produce a large number of frames very fast, fully autonomously.
- Client delivery: the final render (looping video) was sent to Treedy's by email, for them to hand off to Decathlon.
Technical Pipeline Breakdown
Scan (CSV) → Position Map → Particles → Video
The generated position map: each pixel encodes an XYZ position, hence the RGB noise (expected, this isn't a standard color texture).
Code excerpt: BuildPositionMap(), the prime-step twist
// The point count never fills a perfect square exactly, so there are // always leftover pixels at the end of the texture. Rather than leaving // them empty or naively duplicating the last points (visible clump of // overlapping particles on screen), we loop back over the point cloud // with a prime step. Coprime with the array size, it spreads the // duplicates pseudo-randomly across the whole texture instead of // stacking them in one spot. Texture2D BuildPositionMap(List<Vector3> positions) { int pointCount = positions.Count; int width = Mathf.CeilToInt(Mathf.Sqrt(pointCount)); Texture2D positionMap = new Texture2D(width, width, TextureFormat.RGBAHalf, false); positionMap.filterMode = FilterMode.Point; int sequentialIndex = 0; int wrapIndex = 0; const int primeStep = 132049; // prime step for (int y = 0; y < width; y++) { for (int x = 0; x < width; x++) { int index = sequentialIndex < pointCount ? sequentialIndex : wrapIndex % pointCount; Vector3 p = positions[index]; positionMap.SetPixel(x, y, new Color(p.x, p.y, p.z)); sequentialIndex++; wrapIndex += primeStep; } } positionMap.Apply(false, true); return positionMap; }
Context: A Long-Standing Collaboration with Treedy's
This project is part of an ongoing relationship with Treedy's, for whom I had already worked on two prior R&D efforts:
- Training-data simulation engine: development in Unity and Houdini of a synthetic image generation engine, used to train their body-recognition AI model.
- Garment simulation (R&D with VUB): in partnership with a VUB researcher, generation of synthetic garment-simulation data to extract the body silhouette underneath clothing, the R&D foundation of what Treedy's has since productized as "naked-net".