d4rkc0d3r / d4rkAvatarOptimizer

d4rkpl4y3r's VRChat Avatar 3.0 optimizer
MIT License
368 stars 16 forks source link
vrchat vrchat-avatars vrchat-tool

d4rkAvatarOptimizer

d4rkpl4y3r's VRChat avatar 3.0 optimizer that aims to reduce skinned mesh & material count.

How to Use

  1. Add the d4rkAvatarOptimizer component to your avatar root. It should go on the same object that your VRC Avatar Descriptor is on.
  2. Upload the avatar to vrc. The optimizations will be applied before upload automatically with the default settings.

Alternatively you can click the "Create Optimized Copy" button to create a new avatar with optimized materials and meshes. That way you can test the optimized version in editor to validate it works properly before uploading it. If everything works correctly you can then upload that optimized copy.

Installation

To install the optimizer with VCC you need to add the url https://d4rkc0d3r.github.io/vpm-repos/main.json as a custom repository.

  1. Click here
  2. Allow the redirect to open with VCC
  3. VCC should now be open with a dialog asking you to add the repository
  4. Click I understand, Add Repository in the popup after reading its contents

After that you can add and update the optimizer like any other packages in your VCC projects.

Presets

Basic

This preset only uses optimizations that don't affect the behavior of the avatar.

Expect the following behavior changes (reduced due to NaNimation toggles):

Why my Shader Pink?

Shaders can do a lot of weird things, therefore the optimizer is bound to fail on some of them. Here is a couple things you could try:

It is also nice to make a bug report with the broken shaders so I can fix it for the future.
To do that you need to bundle up the optimized .mat, .shader & .cginc files. You can do that by right clicking on d4rkAvatarOptimizer/TrashBin in the project view under Packages and selecting Show in Explorer. A window with the folder selected should open. Go inside the folder and put the files into a .zip file. You don't need to include the .asset files as they can be very large and don't help when debugging the shaders.
Once you have done that make a bug report on the issue tracker where you can attach the .zip file.

Show TrashBin in Explorer

UI Options Documentation

There are also some settings to tweak the optimization. You can read about their effects in more detail here:

Example Screenshot

Apply on Upload

Automatically applies the optimizer to the avatar before uploading it to vrc. This is non destructive, the avatar in your scene will stay as it is.

Write Properties as Static Values

This is very similar to what some shaders call locking in or baking. If you use this option you should disable the locking in or baking feature of your shader.

When enabled the optimizer will replace the uniform parameter definitions with a static value on all materials.
For example uniform float4 _Color; will get changed to static float4 _Color = float4(1, 0, 1, 1);
This enables the shader compiler to do more constant folding and thus making the shader run faster.
Unfortunately the shader compiler is allowed to ignore NaNs while doing that so if a shader is not made with that in mind this might cause some issues.

Merge Skinned Meshes

The optimizer tries to merge different skinned meshes together.
This usually means meshes which always get animated in the same way will get merged.
Skinned meshes that are on different layers (eg UIMenu) from each other will not get merged.
Skinned meshes that are disabled and have no animation to turn them on will get deleted.

Use Shader Toggles

Merges meshes even if their material properties get animated differently or if they get toggled separately from each other.
This will add logic to the shaders to ensure everything works correctly. Some shaders might not work correctly with this option enabled.
Can't merge meshes that have any tessellation or surface shaders.

Forces on Write Properties as Static Values if enabled.

Shader Toggles will not work with blocked shaders or projectors.

NaNimation Toggles

Merges meshes even if they get toggled separately from each other.
This will add an extra bone per original mesh that gets added to each vertex with a very low weight. This bones scale will be animated to NaN to toggle the mesh off.

Unlike the Use Shader Toggles option this does not require the shaders to be changed.
It also doesn't have the problems of projectors and blocked shaders not understanding the toggles.

It can't merge meshes that use a WD ON workflow when they are off by default unless the toggles are simple enough that they can get optimized by Optimize FX Layer.

Allow 3 Bone Skinning

Allows NaNimation Toggles to be used on meshes that use 4 bone weights on some vertices reducing the skinning quality to only 3 effective bone weights.

You can see which meshes use 4 bone weights in the debug info section under Mesh Bone Weight Stats. Any mesh that shows index 3 being used will be affected by reduced skinning quality if it has toggle animations.

Keep Default Enabled State

Stops meshes that are enabled by default from getting merged with meshes that are disabled by default and vice versa.

This is useful to not look weird with blocked animations in case of NaNimation toggles. With this disabled and animations blocked all merged meshes will be visible.

Merge Static Meshes as Skinned

Automatically converts static meshes to skinned meshes so that they can be merged with other meshes and have their materials merged as well. This only happens if the static mesh has materials that can be merged with materials from the skinned mesh it tries to get merged into.
Does not convert meshes on the UIMenu layer since they are mostly used for computation.

Merge Different Property Materials

Merges materials with the same shader where properties can have different values. If they do have different values the values will get written to a constant buffer. Material IDs get written to uv.w and used to access the correct value from that cbuffer.

If your shader has a "lock in" or "bake" feature, make sure to not use it with this optimizer if you have "Write Properties as Static Values" enabled. Locked in shaders will have different actual shaders for each material, so they can't be combined. "Write Properties as Static Values" will take over the job of locking in the shaders.

Can't merge materials if:

Forces on "Write Properties as Static Values" if enabled.

Merge Same Dimension Textures

Merges materials if they use different textures if their width, height & compression format match. Creates a Texture2DArray from the original textures.

Can't merge materials if:

Tries to merge layers that are only doing toggles into a direct blend tree. You can read about this technique here.

Toggles are layers that:

Multi toggles are layers that:

In addition to the selected optimizations there are some optimizations that are always performed:

Mesh & Material Merge Preview

In this detailed view the resulting meshes are separated by spaces. Materials that get merged together are indented. In the example you can see 3 resulting meshes. You can also see that Body/FaceSkin and Body/Eyes get merged into one material while Body/FaceAlpha is still its own material.

Show FX Layer Merge Result

In this section you can see which layers in the FXLayer could get merged or deleted. The VRChat performance rank icon is used to indicate if a layer could be optimized:

The option Show Detailed Errors will show you the reasons why the optimizer rejected a layer from being optimized.

Debug Info

Shows debug information about how the optimizer is understanding the avatar.

Unparsable Materials

Shows all materials that can't be parsed by the optimizer.
These materials stop the meshes they are in from getting merged with other meshes. It also disables the Write Properties as Static Values from getting applied to them.

Unmergable Materials

Shows all materials that can't be merged if their properties differ.
These materials could be parsed but use shader features that the optimizer can't handle. This stops the meshes they are in from getting merged with other meshes. Neither can they be merged with other materials that have different properties.

Unmergable Texture Materials

Shows all materials that can't be merged if their textures differ.
These materials use shader features that prevent the optimizer from merging textures into a Texture2DArray.

Crunched Textures

Shows all textures that got crunch compressed. Crunch compressed textures can't be merged into Texture2DArrays and as such can prevent materials from being merged.

NonBC5 Normal Maps

Shows all textures that are used as normal maps but don't use the BC5 compression format. BC5 normal maps have higher quality than DXT5 & BC7 normal maps while using the same amount of VRAM.

Unmergable NaNimation by Animations

Shows all meshes that can't be merged with NaNimation toggles because they are missing either the on or off animation in a layer.
This usually happens when using a WD ON workflow. In that case switching to a WD OFF workflow is recommended as it allows for more optimizations.

Locked in Materials

Shows all materials that have a "lock in" or "bake" feature enabled which the optimizer detected. If you want to merge these materials you need to disable the "lock in" or "bake" feature.
The optimizer might not detect all forms of "lock in" or "bake" so you might need to check some materials manually.

Unlocked Materials

Shows all materials that have a "lock in" or "bake" feature disabled which the optimizer detected.
With the Write Properties as Static Values option disabled you need to make sure to lock in or bake your materials in this list before optimization.

Penetrators

Shows all meshes that the optimizer detected as DPS or TPS penetrators. If you have some that are not listed here you should add them to the exclusion list. If you don't your penetrators might get merged with other meshes which would always show them to other players if they have your shaders blocked.

Same Ratio Blend Shapes

Shows all blend shapes that are animated in the same ratio and will get merged together. The first number of each merged group should always be 100 as that is the base value the others get compared to. In the final mesh the first blend shape will be the one the others get merged into.

Mesh Bone Weight Stats

Shows how many vertices have non-zero weight for each bone weight index. Also shows maximum and medium weight per bone weight index.

Phys Bone Dependencies

For each phys bone component this shows all components that use the affected transforms of the phys bone. Also lists all animations that animate the m_Enabled property.
Any phys bones listed here that have exactly one skinned mesh renderer listed in its list will add an animation curve to the animations that animate the SkinnedMeshRenderer enabled or its game object active flag if the Disable Phys Bones When Unused option is enabled.

Unused Components

Shows all components that will get deleted by "Delete Unused Components".

Always Disabled Game Objects

Shows all game objects that are disabled and never get enabled by animations.

Material Swaps

Shows all materials that can be swapped into a material slot with an animation.
Any material slot affected by a material swap animation can't be merged with other material slots. Thus you should try to use material swap animations as little as possible to make full use of the optimizer.

Animated Material Property Paths

Shows all material properties with their game object path that are animated.

Game Objects with Toggle Animation

Shows all game objects that have a toggle animation in the fx layer.

Unmoving Bones

Shows all bones that are not moved by animations, eye look settings, phys bone components or constraints.