Swap Avatar Materials from the VRChat Expressions Menu

A material swap replaces the material assigned to one renderer slot. Use it for two complete, fixed appearances such as a default jacket and an alternate jacket, a matte and emissive version, or two authored texture sets.

The menu changes a Bool parameter. The FX Animator selects the default or alternate Animation Clip, and each clip holds one material reference in the same renderer slot.

Two-Material Swap

Bind one renderer slot to a default material and an alternate material through two reversible FX states.

  1. Identify the renderer and exact material slot index.
  2. Record one clip for each material without capturing unrelated properties.
  3. Connect both clips to a Bool Toggle and test every supported platform version.
Material assets and renderer slots are different counts

Avatar Performance Rank counts material slots on Renderer components. Replacing the material assigned to one existing slot does not create another slot, but every platform build still needs suitable materials, textures, and shaders for the appearances it can display.

Video Walkthrough

Use DedZedOffishal's video for the Unity demonstration and the renderer-slot checklist below while building the swap.

Creator: DedZedOffishal
Video: Material Swap | VRC Avatars for Dummies

Use a Swap for Fixed Appearances

Intended control Implementation
Default or alternate material Bool material swap
Several named material presets Int states or a preset menu
Continuous hue value Float animation or Radial Puppet
Show or hide the entire mesh Object toggle
Choose exactly one outfit Exclusive parameter logic

A two-state swap is most useful when each material has a deliberately authored combination of textures and shader settings.

Identify the Renderer Slot

Select the target Mesh Renderer or Skinned Mesh Renderer and inspect its Materials list:

Body (Skinned Mesh Renderer)
├── Element 0: Skin_Default
├── Element 1: Eyes_Default
└── Element 2: Jacket_Default   ← swap this slot

Write down:

Field Example
Renderer path Avatar/Body
Renderer type Skinned Mesh Renderer
Slot index Element 2
Default material Jacket_Default
Alternate material Jacket_Alt

The index matters. Recording a material in Element 1 when the jacket is Element 2 changes the wrong submesh.

Prepare Both Materials

Create or assign the two material assets before recording:

Material Purpose
Jacket_Default Uploaded default appearance
Jacket_Alt Alternate menu-selected appearance

Confirm each material directly on the renderer:

  1. Assign Jacket_Default to the target slot and inspect the avatar.
  2. Assign Jacket_Alt to the same slot and inspect the avatar again.
  3. Restore the material that should be active in the uploaded default.

Check the full visible result, including texture assignment, surface mode, culling, and any renderer-specific behavior supplied by the selected shader.

Record the Material Clips

Create:

  • Jacket_Default.anim
  • Jacket_Alt.anim

Select the avatar root before opening Unity's Animation window. This keeps the material binding relative to the Animator that will play the FX controller.

Record only the target renderer slot:

Clip Element 2 material
Jacket_Default.anim Jacket_Default
Jacket_Alt.anim Jacket_Alt

After recording, inspect both clips and remove unintended bindings. Neither clip should contain accidental Transform, GameObject active-state, blend shape, or unrelated material-slot keys.

Renderer paths and slot indices are part of the binding

Renaming or re-parenting the renderer can break the recorded path. Reordering the renderer's Materials list can make the same binding affect a different submesh. Verify both clips after either hierarchy or slot-order changes.

Create the FX State Machine

VRChat assigns material swaps and other non-transform visual effects to the FX Playable Layer.

Add this Bool to the FX Animator Controller:

Field Value
Name Appearance/JacketAlt
Type Bool
Default False

Create a dedicated Animator layer:

Entry
  └── Jacket Default ───────────► Jacket Alternate
       Appearance/JacketAlt=true

      Jacket Alternate ─────────► Jacket Default
       Appearance/JacketAlt=false

Assign the clips:

State Motion
Jacket Default Jacket_Default.anim
Jacket Alternate Jacket_Alt.anim

Set Jacket Default as the layer's default state for this off-by-default example.

Configure Both Transitions

Default → Alternate

Has Exit Time: disabled
Transition Duration: 0
Condition: Appearance/JacketAlt == true

Alternate → Default

Has Exit Time: disabled
Transition Duration: 0
Condition: Appearance/JacketAlt == false

A material reference changes discretely, so the transition does not need a blend. Both transitions are required so the Animator can respond whenever the Bool changes.

Add the Expression Parameter

In the VRC Expression Parameters asset assigned to the avatar, add:

Field Value
Name Appearance/JacketAlt
Type Bool
Default False
Saved On when the wearer should retain the selection
Synced On when other users should receive the selected state

The name and Bool type must match the FX Animator parameter. A synced Bool uses one bit of synchronized custom-parameter memory.

Add the Expressions Menu Toggle

In the Expressions Menu assigned to the avatar, add:

Menu field Value
Name Alternate Jacket
Type Toggle
Parameter Appearance/JacketAlt

Activating the Toggle sets the Bool true; turning it off resets the Bool to false. Button and Toggle controls use VRChat's Playable synchronization mode.

Assign the Avatar Descriptor Assets

Select the avatar root and confirm:

Descriptor section Assignment
Expressions → Menu Menu containing Alternate Jacket
Expressions → Parameters Asset containing Appearance/JacketAlt
Playable Layers → FX Animator Controller containing the material-swap layer

Use an Animation Controller in the FX slot and do not reuse the same controller in multiple Playable Layers.

Align the Default Material

For the default jacket to load first:

Location Expected value
Renderer Element 2 in the prefab Jacket_Default
Expression Parameter Default False
FX Animator Bool default False
FX layer default state Jacket Default

If Saved is enabled, a stored wearer selection can override the Default when the avatar loads. Reset the avatar before judging a changed default material.

Configure PC and Mobile Versions

PC and mobile versions may require different material assets. Keep the behavior equivalent:

PC version Mobile version
Jacket_Default_PC Jacket_Default_Mobile
Jacket_Alt_PC Jacket_Alt_Mobile
Element 2 Corresponding jacket slot
Appearance/JacketAlt Bool Same list position and Bool type

Use materials and shaders supported by each target platform. VRChat's Android guidance notes that avatars do not have access to every shader or avatar component available on PC.

VRChat synchronizes cross-platform custom parameters by their position and type rather than their name. Use the same VRC Expression Parameters asset for both versions even when the animation clips reference different platform materials.

Review Material and Texture Costs

Check these statistics after the material variants are included:

Statistic What VRChat measures
Material Slots Slots on Renderer components; each slot corresponds to a submesh and draw call
Texture Memory Estimated memory used by the avatar's textures
Mesh Renderers Skinned and basic renderer component counts

Swapping the reference in one existing slot keeps the renderer at the same slot count. Adding extra slots to hold variants simultaneously increases the slot count and submesh work instead.

Review the built avatar's texture-memory result rather than judging it by download size. VRChat specifically warns that high-resolution textures can consume far more VRAM than their file size suggests.

Test the Swap

Use a private upload for every supported platform:

Test Expected result
Avatar loads Default material appears in the intended slot
Toggle turns on Alternate material appears immediately
Toggle turns off Default material returns immediately
Repeat five times Both transitions remain reversible
Inspect other submeshes Eyes, skin, and unrelated slots do not change
Open a mirror Mirror shows the selected material
Ask another user to observe Remote material agrees when Synced is enabled
Switch avatar and return Saved or Default behavior matches the parameter settings
Reset the avatar Default material returns
Test mobile build Mobile material and corresponding slot work
Open Avatar Stats Material-slot and texture-memory results are acceptable for the build

Troubleshooting

Help! The menu changes but the material does not.

Compare the Bool name in the menu, Expression Parameters asset, FX Animator parameter, and transitions. Then inspect whether the animation clips contain the intended renderer material binding.

Help! The wrong part of the mesh changes material.

Check the recorded material slot index against the renderer's current Materials list. A clip aimed at Element 1 cannot control a jacket currently assigned to Element 2.

Help! The Animation Clip reports a missing renderer.

The renderer was probably renamed or re-parented after recording. Restore its previous path or record the material reference again from the avatar root.

Help! The material starts in the wrong state.

Align the renderer's prefab material, Expression Parameter Default, FX Bool default, and FX layer default state. Reset the avatar if a Saved value is restoring the alternate state.

Help! The swap works only in one direction.

Add the missing reverse transition. The alternate state must return to the default state when Appearance/JacketAlt becomes false.

Help! The material is pink on mobile.

Inspect the material used by the mobile avatar version and replace it with a shader supported by that target. Confirm both the default and alternate mobile clips reference the mobile materials.

Help! Other users see the default material.

Enable Synced on the Bool and confirm the observer receives a platform version containing the corresponding alternate material clip and renderer slot.

Help! Texture memory increased after adding variants.

Inspect the textures referenced by both material variants and the built avatar's texture-memory total. Reduce unnecessary texture resolution or reuse suitable maps where the appearances allow it.

Official References

Continue with Avatar Materials

Topics: material swaps, renderer slots, FX Animator, avatar customization