Paper · 2022-06-17 · cs.CV, cs.AI
TAVA: Template-free Animatable Volumetric Actors
Builds an animatable neural actor from multi-view images and a tracked skeleton, with no body template. A canonical-space radiance field is skinned with learned blend weights plus a non-linear offset; root finding maps samples back to canonical space. Author-reported: 33.11 PSNR on ZJU-Mocap novel views, 30.69 on unseen poses, about 2x lower correspondence error than baselines on animals.
Neural radiance field (NeRF) and variantsDynamic neural radiance fieldLinear blend skinningneural-renderingarticulated-avatarsskinningnovel-pose-synthesisdense-correspondence
arXivPDFCodeMarkdown12 min read
AI-compiled by claude-haiku-5-5 on 2026-11-08, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
To make a realistic, animatable model of a person or animal, the usual route is to fit it to a body template, a 3D scan or a hand-built rig. This paper skips the template. It learns the model from multi-view images of one subject plus the subject's tracked skeleton, and it builds a 3D volume that stores what the subject looks like in a neutral reference pose.
The model also learns how each point of the volume moves when the skeleton moves. When a new frame is drawn, each point along each camera ray is moved back to where it came from in the reference pose, its colour and density are read there, and the usual volume-rendering sum turns those values into a pixel. The same lookup links pixels in different views and poses to one shared reference point, so the model can also say which pixel in one picture shows the same spot as a pixel in another picture.
The authors test it on four human subjects from a public motion-capture dataset and on two synthetic animals. They also build validation sets whose poses are unlike the training poses, which is harder than the usual split.
TL;DR
- Template-free animatable neural volume: a canonical-space radiance field plus learned skinning weights, an extra non-linear offset term, and an inverse map found by root finding.
- Renders by taking, for each sample, up to K candidate canonical points and keeping the one with the highest density; a learned ambient-occlusion term depends on pose.
- Author-reported: better than the template-free baselines on ZJU-Mocap and on the animals, close to the template-based methods on ZJU-Mocap, and about 2x more accurate pixel correspondences on the animals.
- The released repository implements a Broyden-type solver instead of the Newton update in the paper, and its default config turns off the two bone losses. Read "Paper vs code" before reimplementing.
Problem
Template-based animatable models (for example SMPL-based methods) need a body template, and they do not apply to other creatures §4.2. Template-free neural methods need no template, but the representation is usually conditioned directly on pose, so they generalise poorly to poses that were not in training §1, §4.2. Previous ZJU-Mocap splits put almost identical poses in both the training and the validation sets, which hides this weakness §4.1. Finally, the compared baselines do not establish pixel correspondences across poses and views natively §4.2; TAVA gets them from the canonical space §3.5.
Method
TAVA has three parts: a canonical representation of the actor §3.2, a skinning-based deformation with an inverse map computed by root finding §3.3, and volumetric rendering with a pose-dependent ambient-occlusion term §3.4. Correspondences come for free from the canonical coordinates §3.5. Training uses an image loss plus two auxiliary losses on the bones §3.6.
Preliminaries. Mip-NeRF integrates the radiance field over a Gaussian per sample, and rendering accumulates colour along a ray with transmittance weights §3.1, eq. 1. The image loss is a squared error per ray §3.1, eq. 2.
Canonical representation §3.2, eq. 3. The colour and density network
F_Θr maps a canonical point and its covariance to colour and density. It takes
no view direction, because the actor is treated as Lambertian. A second network
F_Θs maps a canonical point to B+1 skinning weights: one per bone plus one
for background (empty space).
Forward deformation §3.3.1, eq. 4, eq. 5. A point moves by linear blend
skinning, where each bone transform is weighted by the skinning weight, and the
background weight multiplies the identity so that empty space stays put. A second
network F_Θ∆ adds a learned, pose-dependent offset on top, intended for muscles
and clothing.
Inverse deformation by root finding §3.3.2, eq. 6, eq. 7. Rendering needs,
for each view-space sample x_v, the canonical point x_c that the forward map
sends to x_v. The paper solves f(x_c) = 0 numerically eq. 6 with an
iterative update eq. 7 (written as Newton's method). Each sample gets K
initial guesses, taken from the inverse rigid transforms of its K nearest bones
(K = 5 in the paper). Gradients with respect to the skinning and offset networks
come from implicit differentiation, which is derived in app. A.
Rendering §3.4. For each sample, the canonical colour c*_i, density
σ*_i and ambient occlusion a*_i are queried at each converged candidate. The
ambient occlusion head F_Θa is the only part conditioned on pose P, so the
canonical geometry and appearance stay pose-independent. The sample takes the
values of the candidate with the highest density. The emitted colour is the
candidate colour multiplied by the occlusion value, and the density is the
candidate density. For samples where root finding fails (the paper reports 1% to
8% of samples), the paper interpolates from valid neighbours along the ray. It
reports that this works slightly better than setting the density to zero.
Correspondences §3.5. Rendering also accumulates the canonical coordinates along each ray with the same weights. Two pixels from different views or poses are matched when their accumulated canonical coordinates are nearest neighbours.
Training loss §3.6. L = L_im + λ L_w + β L_∆, with λ = 1.0 and β = 0.1 in
all experiments. L_w pushes the skinning weights of samples on the bones
towards one-hot vectors of their bone. L_∆ pushes the offsets on those samples
towards zero. Both are mean squared errors.
# Render one ray [§3.4] [eq. 1] [§3.3.2] [§3.4]
# Input: samples x_v (N, 3); covariances; pose P; trained model
# Output: pixel colour (3,)
def render_ray(samples, covariances, pose):
# Find up to K canonical candidates for every sample [§3.3.2]
candidates, converged = root_find(samples, pose) # (N, K, 3), (N, K)
# Query colour, density and occlusion in canonical space [§3.4]
colours, densities, occlusion = canonical_query(candidates, pose)
# Keep the candidate with the largest density [§3.4]
best = argmax(densities * converged, axis=1) # (N,)
colours = pick(colours, best) * pick(occlusion, best)
densities = pick(densities, best)
# Fill samples where no candidate converged from valid neighbours [§3.4]
colours, densities = interpolate_failed(colours, densities, converged)
# Standard volume rendering along the ray [eq. 1]
return volume_render(colours, densities, samples)# Root finding for one sample [§3.3.2] [eq. 6] [eq. 7]
# Input: view-space point x_v (3,); initial canonical guess x_c (3,); pose P
# Output: canonical point, or None if it does not converge
def solve_canonical(x_v, x_c, pose):
for step in range(max_steps):
# residual f(x_c) = forward(x_c) - x_v [eq. 6]
residual = forward(x_c, pose) - x_v
if norm(residual) < tolerance:
return x_c
# Newton update with the 3x3 Jacobian [eq. 7]
# (the released code uses a Broyden update; see Paper vs code)
jacobian = forward_jacobian(x_c, pose)
x_c = x_c - inverse(jacobian) @ residual
return NoneHyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
Canonical colour/density MLP F_Θr | 8 layers, 256 hidden units | app. C | Positional encoding: 10-degree integrated encoding, as in Mip-NeRF |
Occlusion MLP F_Θa | 1 layer, 128 hidden units | app. C | Attached to layer 8 of F_Θr; input is the pose |
Offset MLP F_Θ∆ | 4 layers, 128 hidden units | app. C | 4-degree positional encoding on the input coordinates |
| Samples per ray | 64 coarse, 64 fine | app. C | Mip-NeRF volume-rendering settings |
Candidates per sample K | 5 nearest bones | §3.3.2 | Background candidate is extra (see Paper vs code) |
| Loss weights λ, β | 1.0, 0.1 | §3.6 | Used for all experiments in the paper |
| Root-finding failure rate | 1% to 8% of view-space points | §3.4 | Observed rate, not a setting |
| Pose clustering | K-Medoids, K = 10 clusters | §4.1 app. B | Out-of-distribution set is the most distant cluster |
| Test split | one random continuous chunk of frames | §4.1 app. B | Size not stated in the paper; the code uses 1/10 of frames (see Paper vs code) |
| In-distribution validation | 2:1 train to validation split within each remaining cluster | §4.1 app. B | Code holds out 1/3 of each cluster |
| Views, ZJU-Mocap | 4 training, 17 test | §4.1 | Protocol from prior ZJU work |
| Views, animals | 10 training, 10 test | §4.1 | Random views |
| Correspondence evaluation | 2000 image pairs, 800 x 800 px | §4.2 | Out-of-distribution poses, ground-truth mesh |
| Not stated | optimiser, learning rate, batch size, number of steps, skinning network size | The code gives them, see Paper vs code |
Results
Author-reported. Setup: ZJU-Mocap subjects 313, 315, 377 and 386 §4.1, and two synthetic Blender animals (Hare and Wolf) §4.1. Metrics are PSNR and SSIM for image quality, and P2P (pixel error in px) for correspondence. The baselines are Animatable-NeRF and NeuralBody (SMPL-based, official code) and NARF, A-NeRF and Pose-NeRF (template-free, re-implemented in the same code base) §4.2.
ZJU-Mocap tab. 1:
| Method | Novel view PSNR / SSIM | Novel pose, in-dist. PSNR / SSIM | Novel pose, OOD PSNR / SSIM |
|---|---|---|---|
| Animatable-NeRF (SMPL) | 30.75 / 0.971 | 29.34 / 0.966 | 28.67 / 0.961 |
| NeuralBody (SMPL) | 33.91 / 0.983 | 33.43 / 0.984 | 30.33 / 0.969 |
| Pose-NeRF (template-free) | 31.88 / 0.975 | 32.09 / 0.976 | 28.43 / 0.954 |
| A-NeRF (template-free) | 32.45 / 0.978 | 32.65 / 0.978 | 30.41 / 0.967 |
| NARF (template-free) | 32.94 / 0.980 | 33.21 / 0.980 | 30.60 / 0.968 |
| TAVA (this paper) | 33.11 / 0.981 | 33.35 / 0.981 | 30.69 / 0.969 |
Synthetic animals tab. 2:
| Method | Novel view PSNR / SSIM | Novel pose, in-dist. PSNR / SSIM / P2P | Novel pose, OOD PSNR / SSIM / P2P |
|---|---|---|---|
| Pose-NeRF | 23.40 / 0.974 | 21.93 / 0.941 / 197.11 | 16.62 / 0.925 / 88.85 |
| A-NeRF | 31.26 / 0.976 | 31.22 / 0.977 / 31.52 | 25.66 / 0.967 / 19.04 |
| NARF | 36.55 / 0.988 | 36.65 / 0.988 / 9.28 | 30.92 / 0.982 / 8.46 |
| TAVA (this paper) | 37.30 / 0.991 | 37.45 / 0.991 / 4.30 | 35.77 / 0.990 / 3.38 |
Ablation on ZJU-Mocap tab. 3 (PSNR / SSIM):
| Variant | Novel view | Novel pose, in-dist. | Novel pose, OOD |
|---|---|---|---|
without non-linear offset Δ_v | 31.86 / 0.974 | 32.19 / 0.975 | 30.56 / 0.965 |
| without occlusion (pose-dependent colour instead) | 32.94 / 0.980 | 33.20 / 0.980 | 30.57 / 0.968 |
| root-finding failures: density set to zero instead of interpolation | 33.02 / 0.980 | 33.31 / 0.981 | 30.72 / 0.969 |
| full model | 33.11 / 0.981 | 33.35 / 0.981 | 30.69 / 0.969 |
Baseline re-implementation check on ZJU subject 313 app. D, PSNR / SSIM: the authors' re-implementation of A-NeRF scores higher than its official code on all three columns (32.14 / 0.976 against 28.36 / 0.945 for novel view), and the same holds for NARF on the in-distribution and novel-view columns. For NARF, the official code is slightly better on OOD PSNR (28.10 against 28.05).
On ZJU-Mocap, NeuralBody has the higher PSNR and SSIM for novel views and in-distribution poses. TAVA's advantage is on OOD PSNR (30.69 against 30.33), with SSIM tied at 0.969. The authors say the ZJU results are comparable to the template-based methods §4.2.
Paper vs code
Official repository facebookresearch/tava, commit a9576801e81aebcf242588be39315e27f915894e
(BSD-3-Clause), linked from the abstract. The repository is the authors' own
(Meta, the affiliation of several authors) and covers training, evaluation and the
animal data. The shipped configs are a good guide to the paper's settings, but
several values differ.
- Root solver. The paper writes Newton's method §3.3.2, eq. 7. The code uses Broyden's method with inverse-Jacobian updates, at most 50 steps, a convergence threshold of 1e-5 and a divergence threshold of 1, and it keeps the iterate with the smallest residual snarf.py.
- Candidates. The paper uses K = 5 bones §3.3.2. The code always adds an identity (background) candidate, so there are K + 1 = 6 by default snarf.py snarf.py.
- Bone losses are off by default. The paper uses λ = 1.0 and β = 0.1
§3.6. The default dynamic config sets both bone-loss multipliers to 0.0
mipnerf_dyn.yaml. The documented ZJU command sets
loss_bone_w_mult=1.0andloss_bone_offset_mult=0.1experiment.md, and the documented animal command sets onlyloss_bone_w_mult=1.0and turns the offset network off experiment.md. - Coarse-level loss. The code adds the coarse-level squared error with weight 0.1 to the fine-level loss mipnerf_dyn.yaml trainer.py. The paper's loss has no coarse term.
- Bone sample ranges. The skinning-weight loss samples points at 10% to 90% of each bone, which excludes the joints snarf.py. The offset loss samples 0% to 100% snarf.py, and a comment there says the paper's own code sampled in world space, which the authors call unintended. The paper does not state either sampling rule.
- Pose input. The paper does not state the pose representation for the occlusion head. In the default (legacy) setting, the ZJU loader uses a 78-dim vector: 72 axis-angle body values, 3 global rotation values and 3 translation values zju_loader.py zju.yaml. A comment in the loader says the paper uses axis-angles; the paper text itself does not say so. A non-legacy option uses 6D rotations, marked "not verified".
- Occlusion activation. The occlusion head is passed through a sigmoid mipnerf_dyn.py mipnerf_dyn.py. The paper does not name an activation.
- Density and colour activations. Softplus on density with bias −1, and a sigmoid on colour with padding 0.001 on both sides mipnerf.py. Not stated in the paper.
- Skinning network. Four layers of width 128 on a degree-4 encoding snarf.py. The logits are scaled by 5 before the softmax snarf.py snarf.py. Neither detail is in the paper.
- Canonical and world range masks. Candidates farther than 0.3 from the canonical bones are dropped snarf.py zju.yaml. Samples within 0.3 of the bones in world space are kept for rendering mipnerf_dyn.py mipnerf_dyn.py. The paper mentions neither.
- Interpolation of failures. Implemented as described: failed samples are filled from valid neighbours along the ray mipnerf_dyn.py.
- Pose clustering. The paper uses V2V distance on the full ground-truth mesh §4.1. The code subsamples every 100th vertex clustering.py, uses a fixed seed per subject zju_parser.py, and clusters with PAM K-Medoids on a precomputed distance matrix clustering.py. The test chunk is 1/10 of the frames in the code clustering.py, which the paper does not state. The in-distribution split holds out 1/3 of each cluster, a 2:1 split clustering.py.
- Optimiser and schedule (not in the paper). Adam, learning rate 5e-4 decaying log-linearly to 5e-6 over 300 000 steps, with a warm-up delay of 2 500 steps starting at 1% of the rate trainer.py _basic.yaml. 1024 rays per batch on ZJU, with images resized by 0.5 zju.yaml.
- Evaluation size. The documentation says the paper evaluates 100 images per set benchmark.md. The paper does not state the number of evaluation images for PSNR and SSIM.
- Searches: the repository was found through the abstract link. No other official code was looked for.
Pitfalls
- Equation 1 has a sign typo. The printed transmittance term reads
1 - exp(σδ). The standard form, and the one in the code, is1 - exp(-σδ)mipnerf.py. - Root finding is the cost centre. Each sample needs up to K + 1 candidates, each run through an iterative solver with Jacobians of the forward map. The search runs without gradients, and gradients are then injected with the implicit-function formula snarf.py. Expect the per-ray cost to scale with K.
- Failures are silent. Roughly 1% to 8% of view-space points fail §3.4. Their density is interpolated, so a mis-set convergence or divergence threshold changes the image without an error.
- Do not leave the bone losses off. With the default config they are disabled and the skinning weights are not forced to be one-hot. The documented runs enable them.
- Occlusion can be switched off only for pictures, not for scores. Turning it off at test time gives brighter-than-ground-truth images, so it cannot be compared with the ground truth §4.3. The reported metrics keep it on. For the animals, occlusion and the offset term are switched off for training and test §4.2. Do not mix the two settings.
- Out-of-distribution is hard for every method. On ZJU-Mocap the paper reports a drop of 0.67 to 2.66 dB from in-distribution to OOD poses, and it attributes the drop to pose-dependent shading that all methods still learn §4.2. The animal drop is larger for the baselines (1.68 to 5.73 dB) than for TAVA.
- Dataset caveats. The authors report camera calibration errors and varying exposure in ZJU-Mocap that hurt every method, found after submission app. F.
- Requirements beyond the method. Training needs a tracked skeleton per frame and multi-view images §1. The code also reads foreground masks, and the ZJU parser marks a band around the mask border as ignored zju_parser.py.
Lineage
- Builds on: NeRF and Mip-NeRF for the radiance field and integrated encoding
§3.1; SNARF (cited as
chen2021snarf) for the root-finding inverse map and its implicit gradients §3.3.2; a background identity bone from HumanNeRF (cited asweng2022humannerf) §3.3.1. - Compared against: NARF, A-NeRF and Pose-NeRF (template-free); Animatable-NeRF and NeuralBody (SMPL-based) §4.2.
- Superseded by: not stated in this wiki.
Source and license
Adapted from “TAVA: Template-free Animatable Volumetric Actors” by Ruilong Li, Julian Tanke, Minh Vo, Michael Zollhofer, Jurgen Gall, Angjoo Kanazawa, Christoph Lassner (arXiv:2206.08929), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/facebookresearch/tava at commit a9576801e81a (BSD-3-Clause). Any quoted code is shown under that license.