← Back to projects

Body Scan Render Process

Year : 2020
Category : Prototyping & PoC
Body Scan Render Process
Generative Pipeline Real-Time Rendering AI Body Scanning Synthwave Aesthetic Unity VFX Graph Point Cloud FFmpeg Headless Linux Retail Innovation

Body Scan Render Process (Decathlon DX × Treedy's)

Client: Decathlon  |  Technical Partner (body scanning): Treedy's (now SIZED)  |  Location: Decathlon DX, innovation lab store (Villeneuve d'Ascq)  |  Studio: Crafteke  |  Role: Real-Time Development & Generative Pipeline (Unity / VFX Graph)

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

Narrative Intent: make the visitor feel their own body becoming a glowing, digital material, a direct nod to the cyberpunk imagery of body scanning.
Challenge: turn a raw point cloud (CSV export from the Treedy's scanner) into a clean, smooth particle animation, produced quickly for each visitor, without a costly live real-time render.
Solution: the point cloud is encoded into a texture (position map) read by a VFX Graph in Unity, which instantiates one particle per scanned point. Unity was chosen for how fast it loads the 3D model and its ability to produce frame-by-frame renders at very high speed: the video isn't played live for the visitor, but generated at accelerated speed, frame by frame, then the frames are compiled back into a looping video via FFmpeg. The whole pipeline runs headless on a dedicated Linux machine to maximize render speed (Linux side developed by Stephan Sturges).

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".