Community:ShaderMotion

From VRChat Wiki
(Redirected from Community:Shader Motion)
V · ECommunity-written content
The following was created by the community. It may contain material not directly endorsed by the VRChat team. To learn more, consider reading Contributing to the VRChat Wiki.

ShaderMotion is an open-source, shader-based motion-to-video codec for Unity humanoid avatars, originally developed by lox9973. It encodes the bone rotations of a humanoid avatar into colored blocks within a video frame, which can be transmitted via live-streaming platforms and decoded back into motion for playback on a different avatar. The core encoding and decoding system is written entirely in HLSL shader language.

ShaderMotion is designed for streaming full-body motion across VR platforms using live-streaming services. It is used in the VRChat community for live music performances, 3D films, and animation recording. Audiences watching a ShaderMotion-encoded video stream can see a 3D avatar performing the encoded motion in real time, and can move around the performer to view the performance from any angle.

Overview

ShaderMotion operates as a sender-receiver system:

  • The sender (recorder) converts the bone rotations of a humanoid avatar into a grid of color blocks embedded in a video frame.
  • The receiver (player) converts the color blocks back into bone rotations and applies them to a different avatar, enabling motion retargeting — the same motion can be played back on any humanoid avatar regardless of body proportions.

Because the motion data is encoded into a standard video stream, it can be transmitted using any video delivery method, including live-streaming platforms, pre-recorded video files, or in-world video players in VRChat.

Technical details

Encoding scheme

ShaderMotion uses a base-3 Gray curve as its encoding curve. The encoding maps a bounded real number (representing a bone angle) into RGB color values. The curve is chosen to be continuous, which avoids jitter from quantization errors during video compression.

The encoding process:

  1. Normalize the input angle from the range [-1, +1] to [0, 1].
  2. Apply a base-3 Gray curve with six dimensions to produce six values in [0, 1].
  3. Interpret the six values as two RGB colors in GRB order (green, red, blue), chosen because H.264 video compression encodes in YCrCb color space where the green axis provides the highest precision.

Frame layout

Each video frame is divided into an 80x45 grid of squares. Horizontally adjacent squares are paired into slots, producing a 40x45 matrix of real numbers between -1 and +1 per frame.

A humanoid avatar occupies the first three columns (slots 0-44, 45-89, and 90-134), with data assigned up to slot 129:

Slots Data
0-11 Hips position, rotation, and avatar scale
12-26 Spine, Chest, UpperChest, Neck, Head
27-44 Upper legs, lower legs, feet
45-68 Shoulders, upper arms, lower arms, hands
69-70 Toes
71-76 Eyes (Jaw deprecated)
90-129 All finger bones (left and right)

Most slots store swing-twist angles in XYZ order, scaled from [-180, +180] degrees to [-1, +1].

Hips encoding

The Hips bone is handled differently from other bones because it can both translate and rotate freely. Its position is scaled down by a factor of 2 and encoded into two parts approximating integral and fractional components. The rotation is represented as a rotation matrix (rather than swing-twist or quaternion) to avoid mathematical discontinuities.

The avatar scale (height of the Hips bone in T-pose) is encoded in the ratio of the lengths of the scaled y-axis and z-axis columns of the rotation matrix, enabling motion retargeting across avatars of different sizes.

Bone rotation

Bone rotation is computed from each bone's neutral pose (the "motorcycle pose" visible in Unity's muscle settings) relative to its parent bone. Rotations are expressed as swing-twist angles rather than Euler angles or quaternions, for compatibility with Unity's muscle system and for easier interpolation.

The resulting swing-twist angles correspond to Unity's animator muscle values, scaled by the bone's range limit.

Avatar setup

ShaderMotion provides two Unity addons for VRChat integration:

VRC Avatar Addon

The VRC Avatar Addon configures a VRChat avatar for ShaderMotion recording and playback. It supports Avatar 3.0 and Avatar 2.0, though Avatar 3.0 provides fuller functionality.

VRC World Addon

The VRC World Addon provides a sample VRCSDK3 world with a video player that drives a puppet avatar from a ShaderMotion-encoded video stream. This enables audiences to watch motion-captured performances in VRChat.

Animation export

ShaderMotion includes an AnimationRecorder tool that can export avatar motion as Unity .anim files. In the Unity editor, a C# MotionPlayer component drives an animator from the motion texture. While playing back a ShaderMotion-encoded video, the AnimationRecorder captures the resulting bone motion into an animation clip.

Exported .anim files can be used directly in Unity animator controllers. For use in other software, third-party conversion tools can convert them to .fbx format.

Streaming settings

The ShaderMotion documentation suggests the following OBS settings for live streaming ShaderMotion-encoded motion:

Setting Recommended value
Output resolution At least 640x360
Frame rate 60 FPS (lower frame rates are noticeable in VR)
Bitrate 400-800 Kbps (scale proportionally for higher resolution or FPS)
Color space 709
Color range Partial

Resources