Wednesday, 17 August 2016

Avatar Complexity Oddities

Linden Labs has rolled out their new "Avatar Complexity" in their most recent viewer code, and most third party viewers have either already followed suit or will do so very soon. In testing it, I've discovered some very counter-intuitive aspects to it that all creators should be aware of.

What is Avatar Complexity?

This is a new evaluation that a viewer does of each avatar it has to display for you, and loosely speaking it gives you a general measuring guide for how difficult it is for a graphics card to display that person on your screen. Basic "Ruth" has a complexity of 1000. As you add some hair, clothing, shoes, jewellery, etc, the avatar becomes progressively more difficult for the viewer to draw, and the complexity value rises.

The exact calculation used (currently) can be found in the LindenLab documentation here as can instructions for how to see your values in-world.

The new viewer code has a sort of "scene culling slider" which checks the complexity of each avatar before drawing it for you. If the complexity is too high, it draws it as a very simple (and ugly!) jelly blob instead. The only exception is your own avatar...you will always appear fully rendered on your screen no matter how insanely high your complexity value is.

This "too high" cut-off value depends on the graphics setting you use, so if you have a fairly new graphics card you're likely able to run in Ultra graphics mode and only avatars with a complexity in excess of 350k will be turned to goo. If you have a somewhat older or less powerful card and can only run in Very High or High graphics mode, that number drops down towards 200k. For very underpowered cards running in Medium graphics mode, it's closer to 100k. There is a slider that allows you to override the cutoff, either raising or lowering it as desired.

Note that this has absolutely zero impact on the region simulator you're in. The data all gets sent to each viewer and this in no way reduces the server load. All it does is provide a mechanism for increasing your own personal viewer's frame rates if there are a lot of very complex avatars in the same region you're in.

My suspicion is that Linden Labs was sick and tired of hearing how laggy their region servers are when in many cases it's simply the user's graphics card incapable of sustaining a decent frame rate when there scene gets complex. Now they can point to a number and say "see, that avatar is way too complex so it's their fault and the lag is only due to your graphics card's performance, not our region." And that's true in many cases.

I also suspect they hope that by having these number visible to users, it will put some pressure on creators to be somewhat more prudent when making things. As a merchant you'll be able to point to your amazing new Product X and boast about how low a complexity value it has. If that means creators are making more efficient products (mesh in particular) then so much the better.

That's the theory. In practice, though...

A Number is Only Meaningful if it's Accurate

Here's the funny thing about using metrics: they're only as accurate as the method you use to calculate those numbers. The initial implementation of the Linden Lab viewer calculation isn't, or at least not when it comes to mesh.

Without getting into specifics (yet) I can assure you that the numbers you'll see in viewer are incorrectly misrepresenting the complexity of meshes. I'll assume that they're in the right general ballpark for a single prim or sculpty, but there's definitely something weird happening when it comes to mesh, causing it produce some artificially high values depending on how it has been created and textured.

As a general Opensim user, you should be aware of this before you start pointing fingers at someone and criticizing them for creating or wearing something that's too complex. Sure, maybe they are. But maybe they aren't and it's simply the viewer miscalculating the value.

Some Details

Let me give you an example:

My own in-world body is an all-mesh one. In Blender it's just under 30k triangles (15k verts) which is just a little under 4x as complex as the basic Ruth avatar (roughly 8k triangles/4k verts). Yes, it's definitely going to be harder for a graphics card to render so I fully expect it to carry a not-insignificant complexity value. It also uses 7 different materials (arms, legs, torso, face, lips, eyes, eyelashes) which is two more than the SL avatar uses, although the actual texture count is comparable...I simply break it up into more pieces for my own convenience.

Here's where it gets strange.

When I first uploaded it as a single mesh and put the textures on it, it reported as having a complexity of just over 30,728. I was expecting it to be somewhat high, but not that high. After some reading and experimentation, I discovered that the culprit was the 252 triangles of my eyelashes which use a texture that has an alpha (transparency). If you refer to my calculation link above, you'll see that having an alpha results in a 4x multiplier being applied to it and it seemed that the entire mesh was being hit with this penalty instead of only the portion of it that was using the eyelash texture.

I did a second upload, this time with the eyelashes as one object and everything else as a separate object. After putting the identical textures on it to my first test, suddenly my reported complexity was down to 13,796.

There is absolutely no different between them in terms of the work required by the viewer or your graphics card to draw either of them on the screen. They're 100% identical.

And it gets even stranger because next I broke my entire body into pieces, uploading each as a separate object, then wearing them all. Again, completely identical in all respects, but now the complexity was being reported as 10,364.

So the viewer is reporting three rather wildly different numbers for what are in all respects identical in terms of the metric they're supposedly supplying.

Which one is right? More importantly, which one is useful?

[Side note: just before you say I'm crazy to be wearing a body with 10k complexity, try putting on your favourite flexi-prim hair. I bet that more than half of the hair styles being commonly worn in the metaverse are over 20k which is double what my body is....]

From a simulator and asset-server point of view, the single-mesh object of the complete avatar is far, far more efficient. It's one request and one block of data to send. As the mesh is progressively broken up into more and more pieces, the burden on the simulator increases because each piece is a separate call to the asset server and a separate send to the viewer. Further, for the viewer to animate the avatar it has to move each of those mesh pieces separately on its own "rig" bound to the body, so (to a very small degree) it's actually more work for the viewer to have more pieces to have to do this for. And yet that complexity values being show reflect the opposite.

The exact same issue applies to all mesh objects that you might wear so that includes clothing or even unrigged mesh items. If it has a texture with an alpha, glow, bump map, or specular map (or basic glossyness setting) the penalty is applied to the entire object.

The Take-Away

There is already a Jira in Linden Labs' system to have them review this, and hopefully they'll adjust the code to have it only affect the actual surfaces (triangles) with that texture on them.

Until they do, though, you should be aware that some avatars are going to be reporting some much higher values than they really ought to be, so temper your criticisms of the wearer or creator, at least for the time being.

For the creator, it's a tougher call. Right now if you work with mesh, you'll get the lowest values by breaking up your work at least into 1 object per material and make it a linkset. You can get even lower by going wild and breaking it up into hundreds of little pieces to get even lower values. However, by doing so you'll be adding to the load of region simulators that are often already under strain, so perhaps find some happy middle ground and pass the word around that you shouldn't believe the numbers just yet....