Automated Asset Capture Engine for FiveM (Clothing, Vehicles & Objects)
Hey everyone,
I’ve been working on a way to automate asset thumbnails for my own projects because doing it manually was a massive headache. I ended up building a standalone “Capture Engine” that handles the entire pipeline from clothing and appearance overlays to vehicles and world props and I’m releasing it for free for anyone who needs a solid workflow.
It’s built to be framework-independent and focuses on performance, especially when dealing with massive libraries.
How it works
Isolation: It teleports the entity to a dedicated void with auto-lighting and dynamically sized green screens (separated for peds, vehicles, and objects). No world shadows or interference.
Smart Sequencing: It cycles through every drawable/texture, 12 appearance overlay categories, vehicle classes, and world props. I added a Texture Streaming Guard so it won’t take a photo until the asset is 100% loaded.
Advanced Orbit Camera: Completely redesigned camera with roll, height, and FOV controls. Features 18 expanded camera presets where you can save specific angles per category, and the engine will apply them automatically.
Chroma Key (Server-side) & Head-Hide: Instead of heavy native dependencies like Sharp or Canvas, it uses a custom algorithm with pngjs to handle transparency on the server. We also added a Head-Hide sphere for ultra-clean body-only captures.
HTTP API (Port 3959): Serves your shots via a REST API with CORS enabled. Fetch manifests and images directly into your NUI/React apps without Lua proxying. Includes new exports like getVehiclePhotoURL() and getObjectPhotoURL().
Technical Specs
Stability: Includes a batching system with garbage collection to prevent crashes during 2000+ item sessions.
Standalone: Works on QBCore, ESX, QBox, or whatever custom framework you’re using.
Tabbed UI & Workflow: Features a virtualized UI with 4 category tabs, a built-in Vehicle Color Picker, and a Re-capture mode. Also includes quick commands (/shotcar, /shotprop) for instant captures without opening the full UI.
I built this to be a reliable tool for the community. Feel free to check the source or open a PR if you have ideas to improve it.
Thanks for the video and the work Need the transparent bg so i’ found another way to convert them, dont take that muche time to be honest
Anyway, if i can suggest an idea : Would be a great thing if we could put the character invisible (with an option box for example), to let us shot the items only, like watches without arms, earrings, etc..
I think that it’s the only thing that miss a little in your amazing work
The HTTP server is gone. Captures now travel as native FiveM latent events, finish faster, and run on hosts that block inbound ports.
Architecture change
The bundled Node.js HTTP listener on 127.0.0.1:3959 has been removed. Capture uploads now use TriggerLatentServerEvent and land on an onNet handler. The script no longer binds a TCP port, so it runson hosts that block
inbound ports (locked-down VPS, Docker, shared panels) without any firewall configuration.
Performance
Capture loops finish faster. The client used to wait for each HTTP upload to return before moving to the next frame. Now it fires a latent event and continues immediately, while the server processesthe queue in
parallel. A full clothing batch that took several minutes before runs through quicker on the same hardware.
Idle resmon cost down from 0.01ms to under 0.001ms. The input thread used to poll every frame; it now sleeps when no capture, preview, or wardrobe is open.
No more multipart parsing on the server. Captures decode directly from a base64 payload, skipping the chunked body and boundary handling that the HTTP path required.
New Features
Configurable head chroma mask: Customize.HeadMask is now a list of spheres, each with its own offset, size, and optional rotation. Stack multiple shapes to mask head, jaw, and neck independentlywithout one big sphere
clipping clothing.
Latent throttle config: Customize.LatentRate (default 8 MB/s) controls the upload throttle for captures. Raise it for 4K source frames if the upload queue starts to lag.
Server-side ACE check: when Customize.AceRestricted = true, the server rejects capture and bucket events from players who lack command.shotmaker. Closes the gap where the slash command was gatedbut the underlying
events were not.
Fixes
Unsaved captures flipping 180° from the preview. The unsaved branch was using preset.defaultAngleH instead of the current orbit state and rotating the ped through ReapplyRotation, producing animage that looked
nothing like what the user just framed. The unsaved branch now reads the current orbit state and skips the ped rotation on presets that already set defaultAngleH.
Players falling through the map after capture or wardrobe closes.RestoreFullAppearance now pre-streams collision around the original coords and waits for HasCollisionLoadedAroundEntity beforeunfreezing the ped.
attempt to compare number with nil from CreateCaptureCamera. Orbit locals (orbitDist, orbitAngleH, others) are declared at the top of the file so functions defined earlier can read them.
Breaking Changes
exports['uz_AutoShot']:getManifestURL() removed.
exports['uz_AutoShot']:getServerPort() removed.
Customize.BackendURL removed from Customize.lua.
All GET /api/* HTTP routes removed (/api/manifest, /api/exists, /api/stats).
If you were only using the cfx-nui photo URL exports (getPhotoURL, getVehiclePhotoURL, getObjectPhotoURL, getShotsBaseURL, getPhotoFormat), nothing changes for you. These are unchanged.
Congratulations on the free script, excellent work!
To improve, I think everyone would like a webp format without a background and the possibility of completely removing the avatar from photos, like fivem-greenscrener does.