{"id":10855,"date":"2026-08-19T10:36:22","date_gmt":"2026-08-19T05:06:22","guid":{"rendered":"https:\/\/pheonixsolutions.com\/blog\/?p=10855"},"modified":"2026-08-24T22:34:11","modified_gmt":"2026-08-24T17:04:11","slug":"how-we-shrunk-a-3d-avatar-by-91-without-losing-visual-quality","status":"publish","type":"post","link":"https:\/\/pheonixsolutions.com\/blog\/how-we-shrunk-a-3d-avatar-by-91-without-losing-visual-quality\/","title":{"rendered":"How We Shrunk a 3D Avatar by 91% Without Losing Visual Quality"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>From 21.4 MB to 1.89 MB:<\/strong> a practical look at optimising 3D characters for mobile applications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A 3D character can look perfect and still be far too expensive for a mobile app.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We started with a <strong>21.4 MB GLB<\/strong> asset containing a <strong>character, textures, skeleton, and 20 animations<\/strong>. After optimisation, the asset was reduced to just <strong>1.89 MB<\/strong> &#8211; a <strong>91% reduction<\/strong> &#8211; while preserving the <strong>character, animations, and visual appearance<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Challenge<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An initial audit revealed:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Metric<\/th><th>Initial Value<\/th><\/tr><\/thead><tbody><tr><td>File size<\/td><td>21.4 MB<\/td><\/tr><tr><td>Triangles<\/td><td>54,510<\/td><\/tr><tr><td>Vertices<\/td><td>31,953<\/td><\/tr><tr><td>Textures<\/td><td>2 \u00d7 4096\u00d74096 PNG<\/td><\/tr><tr><td>Bones<\/td><td>24<\/td><\/tr><tr><td>Animations<\/td><td>20<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The biggest surprise was the textures.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two 4K textures accounted for approximately <strong>18.2 MB<\/strong> &#8211; around <strong>85% of the entire asset<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That gave us our biggest optimisation opportunity.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Optimise Textures First<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The first major improvement came from reducing unnecessary texture data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Removed a redundant emissive texture.<\/li>\n\n\n\n<li>Reused the base-colour texture where appropriate.<\/li>\n\n\n\n<li>Reduced the main texture from 4096\u00d74096 to 2048\u00d72048.<\/li>\n\n\n\n<li>Removed an unnecessary alpha dependency.<\/li>\n\n\n\n<li>Enabled single-sided rendering for the closed character mesh.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The result:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>21.4 MB \u2192 3.22 MB<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And we had not removed a single triangle yet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Reduce Geometry Without Breaking Animation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original character contained <strong>54,510 triangles<\/strong>, significantly more than our mobile target.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using Blender&#8217;s Decimate modifier, we reduced the geometry to exactly <strong>15,000 triangles<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The vertex count dropped from <strong>31,953 to 10,774<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But reducing polygons is only useful when the animation continues to work correctly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We verified that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>UV coordinates remained intact.<\/li>\n\n\n\n<li>Skinning data was preserved.<\/li>\n\n\n\n<li>Vertex groups remained valid.<\/li>\n\n\n\n<li>The character still deformed correctly.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This matters because a model can look fine in a rest pose and still fall apart once animation begins.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Test in Motion, Not Just in the Viewport<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Rest-pose validation is not enough.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We tested the character in demanding poses, including squats and push-ups, and inspected the silhouette around the knees, elbows, and shoulders.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We also re-checked the final GLB to confirm that all <strong>20 animations<\/strong> were still present with their original durations.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>An optimisation is successful only when the asset is smaller and still behaves correctly.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">4. Watch the Hidden Pipeline Assumptions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">During optimisation, changing the Blender scene from <strong>24 fps to 30 fps<\/strong> caused animations to play <strong>25% faster<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The geometry was fine. The textures were fine. The problem was timing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The solution was to restore 24 fps and document it as a pipeline requirement.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Small pipeline assumptions can create surprisingly large runtime problems.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Final Result<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Metric<\/th><th>Before<\/th><th>After<\/th><\/tr><\/thead><tbody><tr><td><strong>File size<\/strong><\/td><td>21.4 MB<\/td><td><strong>1.89 MB<\/strong><\/td><\/tr><tr><td>Triangles<\/td><td>54,510<\/td><td>15,000<\/td><\/tr><tr><td>Vertices<\/td><td>31,953<\/td><td>10,774<\/td><\/tr><tr><td>Textures<\/td><td>2 \u00d7 4096\u00d74096<\/td><td>1 \u00d7 2048\u00d72048<\/td><\/tr><tr><td>Bones<\/td><td>24<\/td><td>24<\/td><\/tr><tr><td>Animations<\/td><td>20<\/td><td>20<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">The Result<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>91% smaller. Same character. Same animations. No visible difference.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Key Lessons<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Measure First<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Analyse the exact asset that reaches the device rather than relying on the source project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Optimise the Biggest Bottleneck First<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In this case, textures accounted for most of the file size.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Set a Clear Geometry Budget<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Don&#8217;t carry unnecessary polygons onto a mobile device.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Validate Animation After Every Major Change<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A smaller mesh is useless if it breaks when it moves.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Keep the Optimisation Reversible<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Preserve the original high-quality asset so you can create different versions for different platforms later.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Document Pipeline Assumptions<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Frame rate, scale, coordinate systems, and other seemingly small settings can affect the final result.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Bigger Picture<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">AI-generated 3D assets make it easier than ever to create detailed characters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But <strong>generation and optimisation are two different problems<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An asset designed to look impressive in a preview is not automatically ready for a mobile application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The goal isn&#8217;t simply to make a model smaller.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The goal is to find the best balance between <strong>visual quality, performance, memory usage, and application size<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this case, that meant taking a <strong>21.4 MB asset<\/strong> and turning it into a <strong>1.89 MB production-ready asset<\/strong> without sacrificing the experience.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Measure. Optimise. Validate. Repeat.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Is 15,000 triangles a universal limit?<\/strong><br>No. It is a mobile-oriented budget. The right number depends on the device, scene complexity, and how many characters are rendered simultaneously.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Will reducing a 4K texture to 2K always reduce visual quality?<\/strong><br>Not necessarily. The practical impact depends on how large the character appears on the target screen. Testing on the actual device is the best validation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can 3D asset optimisation be automated?<\/strong><br>Much of the process can be scripted, including texture processing, mesh optimisation, and validation. Visual deformation testing is still harder to automate reliably.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From 21.4 MB to 1.89 MB: a practical look at optimising 3D characters for mobile applications. A 3D character can [&hellip;]<\/p>\n","protected":false},"author":541,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":["post-10855","post","type-post","status-publish","format-standard","hentry","category-uncategorized","psol-cat-uncategorized"],"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/phn2x7-2P5","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/10855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/users\/541"}],"replies":[{"embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=10855"}],"version-history":[{"count":1,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/10855\/revisions"}],"predecessor-version":[{"id":11001,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/10855\/revisions\/11001"}],"wp:attachment":[{"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=10855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=10855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pheonixsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=10855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}