Skip to content

manthrax/three-vat

Repository files navigation

three-vat

three-vat is a Three.js runtime library for importing and playing Houdini-style Vertex Animation Textures in the browser, with an included Blender exporter and demo harness.

The goal is to provide a robust, practical VAT pipeline for Three.js:

  • loading sidecar metadata plus mesh/texture assets from disk
  • patching standard Three.js materials with VAT deformation via onBeforeCompile
  • supporting instancing with per-instance time offsets and speed multipliers
  • covering multiple VAT variants: soft body, dynamic mesh/fluid, rigid body, particles, and an OpenVAT sample
  • authoring new compatible VAT datasets from Blender with the bundled exporter

Demo: https://manthrax.github.io/three-vat/

Demo screenshot

Philosophy

The core idea is to make VAT playback feel like a normal part of a Three.js pipeline, not a sidecar experiment that requires replacing everything with custom shaders.

In practice, that means:

  • preserving standard Three.js material workflows as much as possible
  • supporting multiple VAT flavors behind one runtime model
  • aiming for compatibility with Houdini-style VAT3 asset conventions
  • leaving room for Blender-authored exports that target the same runtime contract

This repo includes the runtime, a Blender exporter, sample assets, and a browser demo/testbed because the goal is an end-to-end workflow, not just an isolated viewer.

Repo shape

  • index.html is the standalone demo app and scene setup
  • VATLoader.js loads metadata, mesh assets, and VAT textures
  • VATEffect.js injects shader logic into Three.js materials
  • vat_export.py is a Blender addon/exporter for generating compatible VAT assets
  • blender_vat.blend is the sample authoring scene that includes the exporter script
  • public/examples contains sample datasets for each supported variant
  • the demo doubles as a visual regression harness for the included example VATs

Quick start

npm install
npm run dev

Build for the GitHub Pages-style deployment target:

npm run build

Preview the production build locally:

npm run preview

Runtime usage

The demo uses the loader/effect pair like this:

import { VATLoader } from './VATLoader.js';
import { VATEffect } from './VATEffect.js';

const assets = await VATLoader.load('examples/', 'vat3_softBody');
const vat = new VATEffect(assets, { camera });

scene.add(vat.mesh);

vat.speed = 1.0;
vat.time = 0.0;
vat.setEnabled(true);

For instanced playback, the runtime supports per-instance offsets and rate variation:

vat.setInstanceTimeOffset(index, offsetInSeconds);
vat.setInstanceSpeedScale(index, speedMultiplier);

Supported asset conventions

The loader expects a folder per asset under public/examples/<assetName>/.

Standard Houdini-style export

Expected files typically look like:

  • <assetName>_data.json
  • <assetName>_mesh.glb or legacy *_mesh.fbx for the older demo assets
  • <assetName>_pos.exr or .png
  • <assetName>_rot.exr or .png when the variant needs rotation/normal data
  • optional _col, _lookup, _pos2, _col2

OpenVAT sample

The repo also contains an OpenVAT-style sample (Cube_vat) with a slightly different naming/layout convention:

  • metadata is read from <baseName>-remap_info.json
  • the mesh is read from <baseName>.glb
  • the primary position texture is read from <assetName>.exr

VAT variants in this repo

Dynamic mesh / fluid

  • legacy samples may use a lookup texture indirection path
  • current Blender-packed exports use a generated triangle-soup carrier mesh plus packed position/rotation atlases
  • positions come from _pos
  • rotations/normals come from _rot
  • dynamic topology may use _lookup or the newer packed-atlas path depending on metadata

See docs/dynamic-mesh-export.md for the current packed dynamic-mesh export/runtime contract.

Soft body

  • standard indexed or unindexed deforming mesh
  • texture width corresponds to vertex count
  • texture height corresponds to frame count
  • positions come from _pos
  • orientation/normal data comes from _rot

Particles

  • texture width corresponds to maximum particle count
  • positions come from _pos
  • this sample also uses _col as the particle/albedo texture
  • the runtime can billboard particles and vary playback per instance

Rigid body

  • chunk transforms are sampled per frame
  • pivots are reconstructed from mesh UV channels when present
  • positions come from _pos
  • rotations come from _rot

Dynamic mesh / fluid

  • supports changing topology over time
  • the render mesh is a generated triangle-soup carrier rather than a stable authored bind mesh
  • positions come from _pos
  • rotations / normals come from _rot
  • some assets use a lookup indirection texture, while current Blender exports can also use the packed-atlas path described in docs/dynamic-mesh-export.md

Blender exporter

vat_export.py registers a Blender sidebar panel named VAT Exporter and can export:

  • dynamic / fluid mesh
  • soft body
  • rigid body / chunk animation
  • particles

The exporter writes Houdini-style sidecar JSON plus EXR/PNG textures and supports:

  • auto-inferring asset name and VAT mode from the current selection
  • exporting from a selected effect root for fluid, soft body, rigid body, and particles
  • optional PNG or EXR texture output
  • adjustable texture width for atlas packing
  • scene-FPS sampling by default, with optional custom export FPS resampling
  • a panel summary showing estimated output sizes and the last generated files

The sample Blender scene blender_vat.blend is included as the starting point for authoring new VATs with the bundled exporter.

For the current dynamic mesh / fluid export details, see docs/dynamic-mesh-export.md.

Status

The runtime is already useful as a practical reference implementation and the exporter is far enough along to generate working soft body, dynamic mesh/fluid, particle, and rigid body samples from Blender. The project is still evolving, so expect the API, exporter details, and asset conventions to keep getting refined as the public surface gets cleaned up.

What this repo is today

  • a Three.js VAT runtime that supports multiple Houdini-style VAT3 variants
  • a Blender exporter for generating compatible VAT datasets
  • a sample scene plus exporter script for authoring and iterating on new effects
  • a browser demo that also acts as a regression suite for the included examples

Roadmap

  • tighten the loader/runtime API into a more library-shaped public surface
  • document the asset contract more formally per VAT variant
  • improve Blender exporter compatibility with Houdini-style VAT3 conventions
  • expand sample coverage and validation across soft body, rigid body, particles, and dynamic mesh/fluid workflows
  • reduce special-case handling between legacy samples, current samples, and OpenVAT-style inputs

References

This implementation was informed by:

by Thrax

About

threejs houdini vat3 vat2 loader, instancer

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages