{
  "path": "/VRChat/avatar-optimisation-in-unity",
  "site": "at://did:plc:z5udahlpedl5my5bjmvxbz5u/site.standard.publication/3ml7auuhba627",
  "tags": [
    "VRChat",
    "Unity"
  ],
  "$type": "site.standard.document",
  "title": "Avatar Optimisation in Unity",
  "content": {
    "text": "\n> **Work in Progress**\n> This page is work in progress... I may add or change parts of this page in the future. [Reply to the Bluesky thread to leave suggestions!](https://bsky.app/profile/yernemm.xyz/post/3mjfos32jx22a)\n# Intro\n\nThis guide is not intended to cover the very basics of uploading a VRChat avatar, there's a lot of resources out there for this already. It assumes you're already familiar with getting a base model into Unity, making changes to it, and uploading it to VRChat.\n\nThis guide mainly covers optimisation in Unity directly using non-destructive tools. Although with some avatars, this may not be enough. In those cases, you may need to edit the model directly in Blender, which is not covered in this guide.\n\nThis guide also only covers methods I have personally tried. Whilst there's a lot of other tools out there, I will only suggest them here if I actually use them for some of my avatars (unless stated otherwise).\n\n> **A note on performance ratings.**\n> VRChat's performance rating system is not perfect, but it does decide how optimised your avatar appears to be and decides who gets to see it. There's a lot you can do to actually make your avatar perform better for others beyond just improving your rating. Things like complex animator controllers and heavy shaders will hurt your performance but they're not included in the rating, so it's possible to have an avatar that's technically very unoptimised which still maintains a good rating.\n> \n> That being said, this guide mainly aims to tackle the basics to ensuring your avatar isn't very poor so others in public instances and events can actually see it. More in-depth optimisation techniques are beyond the scope of this guide.\n\n## Non-Destructive Workflow\n\nMost things I do in my workflow are non-destructive. You can refer to a list of Unity tools for optimisation below, these are generally non-destructive.\n\n\n\n# General Tips\n\n**One outfit per upload.**\n\nWhilst it's cool to be able to switch / mix match outfits on the fly, nothing's stopping you from just uploading multiple versions of your avatar. Toggling parts of your outfit on and off is usually fine (although this can limit how much you can optimise), but you don't need to put everything on a single upload. You can keep all outfit variations of your avatar in the same project, even the same scene, so it's better to manage outfits through separate uploads.\n\n# Common Performance Issues\n\n## Too many skinned meshes\n\nAvatars are often made up of several different objects, or meshes. Having many of these meshes is bad for performance. Skinned meshes are heavier on performance than regular meshes as they have additional data, like weight painting and blendshapes. A lot of avatars are split into several meshes to make it easier to customise parts of the avatar or switch outfits, but it's better for your final upload to combine as many of these meshes as possible.\n### Tools:\n* [d4rkAvatarOptimizer](https://github.com/d4rkc0d3r/d4rkAvatarOptimizer) \n### Fix:\nSimply adding d4rk's avatar optimizer to your avatar with its default settings is usually enough to resolve this. It has an option to combine skinned meshes into a single mesh. Keep in mind that you cannot usually combine skinned meshes which can be turned on/off by toggles, although you can try the \"Use Shader Toggles\" option if the regular merging is not enough.\n\n\n\nYou can also manually delete any unused objects from your avatar.\n\n## Texture memory / VRAM usage too high\n\nMany avatars have default texture settings set way too high. This is even more of an issue with some prefabs that may use 4k textures for tiny details. A good general rule I like to follow is no higher than 4K resolution for anything atlassed (e.g. when a whole avatar or entire outfit uses a single main texture). No higher than 2K resolution for non-atlassed textures, like a hoodie or hair.\n\nBut you can change this on a case-by-case basis. Pick the smallest resolution that still looks good. And if your texture memory is still too high, consider lowering further even if your avatar looks a little bit pixelated.\n### Tools:\n* [Thry's Avatar Performance Tools](https://github.com/Thryrallo/VRC-Avatar-Performance-Tools)\n### Fix 1: Lowering Texture Resolution\nThis tool will list all the textures on your avatars and has some one-click fixes to change the compression method which reduces the memory usage. \n\n \n\nAdditionally, you can use it to find the textures taking up the most memory. Generally, 4K textures are unnecessary unless they have some fine detail or are atlassed for a large part of your avatar. Lower the texture size in Unity for all your least important textures first.\n\nThe evaluator will also suggest changing the compression type for some of your textures *(DXT1 button in example below)*, you can generally do this for all suggested textures without a noticeable visual impact.\n\n\n\n### Fix 2: Removing unused / unimportant textures\n\nThis can be a bit more extreme so you may only really need to do this if the first fix isn't enough.\n\nYou can go over your material and remove some less important texture. For instance, the normal map will add some visual depth to your material but in extreme cases, you may consider removing it if it doesn't add much to your avatar.\n\n\n\nAdditionally, some shaders may reuse the same type of texture in multiple places. If you made a custom texture and assigned it as your base colour, ensure that you also replace all other instances of the original texture in the material. Sometimes, you may accidentally leave a large texture in your shader that isn't contributing to anything.\n\n### Tip: Use Decals\n\nIf you want to reduce the texture resolution for something like an outfit whilst keeping the graphic on it crisp, you can use decals if your shader supports it. This way, you can reduce the quality of the overall texture whilst adding a small extra texture which only contains the high-quality logo or image.\n\nYou can also use this to apply cool effects, like making it spin with Audiolink or hue shift. The main downside is that the image will not be visible with fallback shaders or on Quest.\n\n*Example of adding a logo to a T-shirt using a Poiyomi decal.*\n\n\n\n### Tip: Use Repeating Detail Textures\n\nSome textures, especially for clothing, may feature a repeating pattern. You can use a repeating detail texture depending on your shader.\n## Too many polygons\n\nThis is a classic issue to run into. Whether you have high poly unoptimised outfits or your base model itself is unoptimised to begin with.\n\nThere's two main ways to fix it:\n* Removing hidden / unnecessary geometry\n* Decimating / simplifying your mesh.\n\n### Tools:\n* [Anatawa12’s Avatar Optimizer](https://vpm.anatawa12.com/avatar-optimizer/en/) - Specifically the remove by box and remove by blendshape options.\n* 💸[Polytool](https://markcreator.gumroad.com/l/Polytool) - I have not tested this one myself, but it is supposed to simplify / decimate the mesh.\n* [Meshia Mesh Simplification](https://ramtype0.github.io/Meshia.MeshSimplification/docs/en/installation.html) - Free asset for reducing the mesh quality to stay within polycount limits.\n\n### Fix 1: Removing hidden parts of the mesh\n\nUsing AAO Remove Mesh By BlendShape from Anatawa12's Avatar Optimizer\n\n\n\nMany base models have blendshapes for hiding parts of the body. With this tool, you can completely delete parts that are hidden by clothing, which reduces your polycount.\n\n \n\n*Example: Removing the arm that would normally be hidden under some clothing*\n\n\n\n\n\nYou can also use AAO Remove Mesh By Box to hide everything inside a box, if blendshapes aren't quite set up the way you need them\n\n\n\n*Hiding the legs underneath the socks using Remove Mesh By Box*\n\n\n\n### Fix 2: Reduce mesh quality\n\nOnce you have removed the hidden parts of the mesh, you can go ahead and reduce the quality of anything that remains to get you under the limit.\n\nFor this, I use [Meshia](https://ramtype0.github.io/Meshia.MeshSimplification/docs/en/installation.html) as it's free and works pretty well. Just add the Meshia object to your avatar and adjust the sliders until it looks good. In this example, I set my polygon target to 77,000 as it doesn't account for the tris removed from the previous step, so the final result will actually be below 70,000.\n\nYou can also configure it to not touch important meshes, like the face.\n\n\n\n\n\n## Too many physbone components\n\nIn many cases, physbones can be merged into one root physbone or removed entirely.\n\nYou can use [Anatawa12’s Avatar Optimizer](https://vpm.anatawa12.com/avatar-optimizer/en/)'s Merge Physbone component to create a root physbone. This works well with things like hair on some avatars.\n\n\n\n# Other Info / Reference\n\n## Limits\n\n*As of 2026-04-13*\n\n[Refer to the official limits docs here.](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#pc-limits)\n\n### PC Limits\n\n|Avatar Quality|Excellent|Good|Medium|Poor|\n|---|---|---|---|---|\n|Triangles|32,000|70,000|70,000|70,000|\n|Bounds Size[1](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-1)|2.5m x 2.5m x 2.5m|4m x 4m x 4m|5m x 6m x 5m|5m x 6m x 5m|\n|Texture Memory|40 MB|75 MB|110 MB|150 MB|\n|Skinned Meshes|1|2|8|16|\n|Basic Meshes|4|8|16|24|\n|Material Slots|4|8|16|32|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Components|4|8|16|32|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Affected Transforms|16|64|128|256|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Colliders|4|8|16|32|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Collision Check Count|32|128|256|512|\n|[Contacts](https://creators.vrchat.com/common-components/contacts)|8|16|24|32|\n|[Constraint](https://creators.vrchat.com/common-components/constraints) Count|100|250|300|350|\n|[Constraint](https://creators.vrchat.com/common-components/constraints) Depth|20|50|80|100|\n|Animators|1|4|16|32|\n|Bones|75|150|256|400|\n|Lights|0|0|0|1|\n|Particle Systems|0|4|8|16|\n|Total Particles Active|0|300|1000|2500|\n|Mesh Particle Active Polys|0|1000|2000|5000|\n|Particle Trails Enabled|False|False|True|True|\n|Particle Collision Enabled|False|False|True|True|\n|Trail Renderers|1|2|4|8|\n|Line Renderers|1|2|4|8|\n|Cloths|0|1|1|1|\n|Total Cloth Vertices|0|50|100|200|\n|Physics Colliders|0|1|8|8|\n|Physics Rigidbodies|0|1|8|8|\n|Audio Sources|1|4|8|8|\n\n### Mobile Limits\n\n|Avatar Quality|Excellent|Good|Medium|Poor|\n|---|---|---|---|---|\n|Triangles|7,500|10,000|15,000|20,000|\n|Bounds Size[1](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-1)|2.5m x 2.5m x 2.5m|4m x 4m x 4m|5m x 6m x 5m|5m x 6m x 5m|\n|Texture Memory|10 MB|18 MB|25 MB|40 MB|\n|Skinned Meshes|1|1|2|2|\n|Basic Meshes|1|1|2|2|\n|Material Slots|1|1|2|4|\n|Animators|1|1|1|2|\n|Bones|75|90|150|150|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Components[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|0|4|6|8|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Affected Transforms[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|0|16|32|64|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Colliders[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|0|4|8|16|\n|[PhysBones](https://creators.vrchat.com/common-components/physbones) Collision Check Count[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|0|16|32|64|\n|[Contacts](https://creators.vrchat.com/common-components/contacts)[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|2|4|8|16|\n|[Constraint](https://creators.vrchat.com/common-components/constraints) Count[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|30|60|120|150|\n|[Constraint](https://creators.vrchat.com/common-components/constraints) Depth[2](https://creators.vrchat.com/avatars/avatar-performance-ranking-system/#user-content-fn-2)|5|15|35|50|\n|Particle Systems|0|0|0|2|\n|Total Particles Active|0|0|0|200|\n|Mesh Particle Active Polys|0|0|0|400|\n|Particle Trails Enabled|False|False|False|True|\n|Particle Collision Enabled|False|False|False|True|\n|Trail Renderers|0|0|0|1|\n|Line Renderers|0|0|0|1|\n\n# Suggestions\n\nReply to the linked Bluesky thread to leave a comment under this page with any additional suggestions!",
    "$type": "at.markpub.markdown",
    "flavor": "GFM"
  },
  "description": "Methods to optimise VRChat avatars without leaving the Unity editor.",
  "publishedAt": "2026-05-06T17:52:20.128Z",
  "textContent": "Work in Progress\nThis page is work in progress... I may add or change parts of this page in the future. Reply to the Bluesky thread to leave suggestions!\nIntro\n\nThis guide is not intended to cover the very basics of uploading a VRChat avatar, there's a lot of resources out there for this already. It assumes you're already familiar with getting a base model into Unity, making changes to it, and uploading it to VRChat.\n\nThis guide mainly covers optimisation in Unity directly using non-destructive tools. Although with some avatars, this may not be enough. In those cases, you may need to edit the model directly in Blender, which is not covered in this guide.\n\nThis guide also only covers methods I have personally tried. Whilst there's a lot of other tools out there, I will only suggest them here if I actually use them for some of my avatars (unless stated otherwise).\n\nA note on performance ratings.\nVRChat's performance rating system is not perfect, but it does decide how optimised your avatar appears to be and decides who gets to see it. There's a lot you can do to actually make your avatar perform better for others beyond just improving your rating. Things like complex animator controllers and heavy shaders will hurt your performance but they're not included in the rating, so it's possible to have an avatar that's technically very unoptimised which still maintains a good rating.\n\nThat being said, this guide mainly aims to tackle the basics to ensuring your avatar isn't very poor so others in public instances and events can actually see it. More in-depth optimisation techniques are beyond the scope of this guide.\n\nNon-Destructive Workflow\n\nMost things I do in my workflow are non-destructive. You can refer to a list of Unity tools for optimisation below, these are generally non-destructive.\n\nGeneral Tips\n\nOne outfit per upload.\n\nWhilst it's cool to be able to switch / mix match outfits on the fly, nothing's stopping you from just uploading multiple versions of your avatar. Toggling parts of your outfit on and off is usually fine (although this can limit how much you can optimise), but you don't need to put everything on a single upload. You can keep all outfit variations of your avatar in the same project, even the same scene, so it's better to manage outfits through separate uploads.\n\nCommon Performance Issues\n\nToo many skinned meshes\n\nAvatars are often made up of several different objects, or meshes. Having many of these meshes is bad for performance. Skinned meshes are heavier on performance than regular meshes as they have additional data, like weight painting and blendshapes. A lot of avatars are split into several meshes to make it easier to customise parts of the avatar or switch outfits, but it's better for your final upload to combine as many of these meshes as possible.\nTools:\nd4rkAvatarOptimizer \nFix:\nSimply adding d4rk's avatar optimizer to your avatar with its default settings is usually enough to resolve this. It has an option to combine skinned meshes into a single mesh. Keep in mind that you cannot usually combine skinned meshes which can be turned on/off by toggles, although you can try the \"Use Shader Toggles\" option if the regular merging is not enough.\n\nYou can also manually delete any unused objects from your avatar.\n\nTexture memory / VRAM usage too high\n\nMany avatars have default texture settings set way too high. This is even more of an issue with some prefabs that may use 4k textures for tiny details. A good general rule I like to follow is no higher than 4K resolution for anything atlassed (e.g. when a whole avatar or entire outfit uses a single main texture). No higher than 2K resolution for non-atlassed textures, like a hoodie or hair.\n\nBut you can change this on a case-by-case basis. Pick the smallest resolution that still looks good. And if your texture memory is still too high, consider lowering further even if your avatar looks a little bit pixelated.\nTools:\nThry's Avatar Performance Tools\nFix 1: Lowering Texture Resolution\nThis tool will list all the textures on your avatars and has some one-click fixes to change the compression method which reduces the memory usage. \n\n \n\nAdditionally, you can use it to find the textures taking up the most memory. Generally, 4K textures are unnecessary unless they have some fine detail or are atlassed for a large part of your avatar. Lower the texture size in Unity for all your least important textures first.\n\nThe evaluator will also suggest changing the compression type for some of your textures (DXT1 button in example below), you can generally do this for all suggested textures without a noticeable visual impact.\n\nFix 2: Removing unused / unimportant textures\n\nThis can be a bit more extreme so you may only really need to do this if the first fix isn't enough.\n\nYou can go over your material and remove some less important texture. For instance, the normal map will add some visual depth to your material but in extreme cases, you may consider removing it if it doesn't add much to your avatar.\n\nAdditionally, some shaders may reuse the same type of texture in multiple places. If you made a custom texture and assigned it as your base colour, ensure that you also replace all other instances of the original texture in the material. Sometimes, you may accidentally leave a large texture in your shader that isn't contributing to anything.\n\nTip: Use Decals\n\nIf you want to reduce the texture resolution for something like an outfit whilst keeping the graphic on it crisp, you can use decals if your shader supports it. This way, you can reduce the quality of the overall texture whilst adding a small extra texture which only contains the high-quality logo or image.\n\nYou can also use this to apply cool effects, like making it spin with Audiolink or hue shift. The main downside is that the image will not be visible with fallback shaders or on Quest.\n\nExample of adding a logo to a T-shirt using a Poiyomi decal.\n\nTip: Use Repeating Detail Textures\n\nSome textures, especially for clothing, may feature a repeating pattern. You can use a repeating detail texture depending on your shader.\nToo many polygons\n\nThis is a classic issue to run into. Whether you have high poly unoptimised outfits or your base model itself is unoptimised to begin with.\n\nThere's two main ways to fix it:\nRemoving hidden / unnecessary geometry\nDecimating / simplifying your mesh.\n\nTools:\nAnatawa12’s Avatar Optimizer - Specifically the remove by box and remove by blendshape options.\n💸Polytool - I have not tested this one myself, but it is supposed to simplify / decimate the mesh.\nMeshia Mesh Simplification - Free asset for reducing the mesh quality to stay within polycount limits.\n\nFix 1: Removing hidden parts of the mesh\n\nUsing AAO Remove Mesh By BlendShape from Anatawa12's Avatar Optimizer\n\nMany base models have blendshapes for hiding parts of the body. With this tool, you can completely delete parts that are hidden by clothing, which reduces your polycount.\n\n \n\nExample: Removing the arm that would normally be hidden under some clothing\n\nYou can also use AAO Remove Mesh By Box to hide everything inside a box, if blendshapes aren't quite set up the way you need them\n\nHiding the legs underneath the socks using Remove Mesh By Box\n\nFix 2: Reduce mesh quality\n\nOnce you have removed the hidden parts of the mesh, you can go ahead and reduce the quality of anything that remains to get you under the limit.\n\nFor this, I use Meshia as it's free and works pretty well. Just add the Meshia object to your avatar and adjust the sliders until it looks good. In this example, I set my polygon target to 77,000 as it doesn't account for the tris removed from the previous step, so the final result will actually be below 70,000.\n\nYou can also configure it to not touch important meshes, like the face.\n\nToo many physbone components\n\nIn many cases, physbones can be merged into one root physbone or removed entirely.\n\nYou can use Anatawa12’s Avatar Optimizer's Merge Physbone component to create a root physbone. This works well with things like hair on some avatars.\n\nOther Info / Reference\n\nLimits\n\nAs of 2026-04-13\n\nRefer to the official limits docs here.\n\nPC Limits\n\n|Avatar Quality|Excellent|Good|Medium|Poor|\n|---|---|---|---|---|\n|Triangles|32,000|70,000|70,000|70,000|\n|Bounds Size1|2.5m x 2.5m x 2.5m|4m x 4m x 4m|5m x 6m x 5m|5m x 6m x 5m|\n|Texture Memory|40 MB|75 MB|110 MB|150 MB|\n|Skinned Meshes|1|2|8|16|\n|Basic Meshes|4|8|16|24|\n|Material Slots|4|8|16|32|\n|PhysBones Components|4|8|16|32|\n|PhysBones Affected Transforms|16|64|128|256|\n|PhysBones Colliders|4|8|16|32|\n|PhysBones Collision Check Count|32|128|256|512|\n|Contacts|8|16|24|32|\n|Constraint Count|100|250|300|350|\n|Constraint Depth|20|50|80|100|\n|Animators|1|4|16|32|\n|Bones|75|150|256|400|\n|Lights|0|0|0|1|\n|Particle Systems|0|4|8|16|\n|Total Particles Active|0|300|1000|2500|\n|Mesh Particle Active Polys|0|1000|2000|5000|\n|Particle Trails Enabled|False|False|True|True|\n|Particle Collision Enabled|False|False|True|True|\n|Trail Renderers|1|2|4|8|\n|Line Renderers|1|2|4|8|\n|Cloths|0|1|1|1|\n|Total Cloth Vertices|0|50|100|200|\n|Physics Colliders|0|1|8|8|\n|Physics Rigidbodies|0|1|8|8|\n|Audio Sources|1|4|8|8|\n\nMobile Limits\n\n|Avatar Quality|Excellent|Good|Medium|Poor|\n|---|---|---|---|---|\n|Triangles|7,500|10,000|15,000|20,000|\n|Bounds Size1|2.5m x 2.5m x 2.5m|4m x 4m x 4m|5m x 6m x 5m|5m x 6m x 5m|\n|Texture Memory|10 MB|18 MB|25 MB|40 MB|\n|Skinned Meshes|1|1|2|2|\n|Basic Meshes|1|1|2|2|\n|Material Slots|1|1|2|4|\n|Animators|1|1|1|2|\n|Bones|75|90|150|150|\n|PhysBones Components2|0|4|6|8|\n|PhysBones Affected Transforms2|0|16|32|64|\n|PhysBones Colliders2|0|4|8|16|\n|PhysBones Collision Check Count2|0|16|32|64|\n|Contacts2|2|4|8|16|\n|Constraint Count2|30|60|120|150|\n|Constraint Depth2|5|15|35|50|\n|Particle Systems|0|0|0|2|\n|Total Particles Active|0|0|0|200|\n|Mesh Particle Active Polys|0|0|0|400|\n|Particle Trails Enabled|False|False|False|True|\n|Particle Collision Enabled|False|False|False|True|\n|Trail Renderers|0|0|0|1|\n|Line Renderers|0|0|0|1|\n\nSuggestions\n\nReply to the linked Bluesky thread to leave a comment under this page with any additional suggestions!"
}