Hello,
I want to know the boneWeights and boneIndices for each vertex of a skeletalMesh
Thanks.
I found the answer myself.
Here is how:
- First you need to get the target mesh.
- Then get the vertices.
- After that we need to loop them, and use the index of the iteration to get the boneIndices and boneWeights of each vertex.
- Now we have a uint8 value, we need to access the data inside this byte buffer.
- We will cast this vertex.InfluenceBones[0] to Int, where index 0 for the first bone index and 1 for the second and so on for 3 and 4.
- Now for boneWeights, almost the same for the previous step.
- Firstly, we will cast vertex.InfluencesWeights[0] to Int then cast it to double and divide it with 255.0
where index 0 for the first bone index and 1 for the second and so on for 3 and 4.
â255.0â is the maximum number of each byte in that buffer
I used this method, but I got error bone index. The same FBX, many vertices bone index is 0(rootBone), but in Unity, no any vertices bone index is 0(rootBone)
How did you do it? The GetSkeletalMeshResource method doesnât even exist in the Unreal Engine
In 4.27 and 5.0+ I use this:
FSkeletalMeshLODRenderData& LODData = Mesh->SkeletalMesh->GetResourceForRendering()->LODRenderData[0];
FSkinWeightVertexBuffer* SkinWeightBuffer = &lodd.SkinWeightVertexBuffer;
TArray <FSkinWeightInfo> SkinWeightInfo;
SkinWeightBuffer->GetSkinWeights(SkinWeightInfo);
Note that you will still need to map the bone indices from SkinWeightInfo to their corresponding bone index inside the SkeletalMeshâs BoneMap such as:
int32 BoneIndex = SkinWeightBuffer.GetBoneIndex(vertexindex, 0);
int32 ActualBone = LODData.RenderSections[0].BoneMap[BoneIndex];
FName BoneName = SKMesh->GetBoneName(ActualBone);
Each entry in the SkinWeightInfo array corresponds to a mesh vertex
Are you sure on the variable definitions and bond index limits?
What used to work originally is probably been increased by at least one order of magnitude since they released metahumans.
Not that limiting the index to a smaller value is incorrect. Matrer of fact it can never go out of index.
The original solution is also wrong.
You canât cast to int and then cast to double without loosing precision.
In the realm of animation you need that precision.
Seems to me that the /255 part claiming its the maximum byte means that the wrong math is being used for it entierly.
Then again, it does depend on what value is in fact store by the index.
The point is, if you divide 1.5 by 255 it isnât the same as dividing 1 by 255.
And thatâs basically what the code above would do.
Many game engines store the skin weights as a byte for optimization and memory reasons. Its essentially a normalized float between 0-1. There is going to be almost no benefit visually to storing them in higher precision.
In the above code he is just normalizing it back to the 0-1 scale. But ya right, casting to a float would be good enough, no reason to use double.
Your model however has a high fidelity and DCCs usually support much higher precision for a simple float.
The problem with unreal looking like trash comparatively to any DCC is the precision it can support (which is fairly low and gets truncated as well).
And yes, thats 100% because of optimization - but it is 2025, maybe we can actually step things up so that LOD0 on characters match DCCs a bit closerâŚ
Just not the way its shown above⌠the problem starts with the import of the data from FBX to engine assetâŚ
Nobody would be able to tell the difference visually.
Its not really worth the cost of doubling memory usage for such a minor thing. Remember that DCC is not real time, game engines are though.
Everyone is able to see the difference.
If you havenât, you are either blind or not looking.
Either way, your post in no way helps or furthers the conversation, if anything, it hinders it.
Its not âgood enoughâ, particularly when the engine literally wastes rendering overhead on BS like nanite. The extra cost is much better spent in doing skeletal meshes appropriately.
One can always build from source, and also force Double Quaternions - but then, you made it clear you arenât even aware of the base issue or are unable to see it in the first place - which does beg the question as to wtf you are posting in this thread for, but I digressâŚ