查看: 4203|回复: 0
打印 上一主题 下一主题

[经验分享] 什么是骨骼权重

[复制链接]
ZackD    

715

主题

22

听众

4万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
26224
精华
17

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2013-9-26 15:40:23 |只看该作者 |倒序浏览
什么是骨骼权重:
骨骼权重在蒙皮网格中使用,举个例子来说,手腕关节运动时,受到2块主要骨骼的影响,手腕关节可以看作蒙皮网格中的顶点,在Unity中一个顶点最多受4块骨骼的影响,每块骨骼的影响程度有一个百分比,即骨骼权重,所有骨骼权重相加为1. 每个顶点会保存一个影响该顶点的变换数组,这些变换是当前骨骼相对于父对象的变换。利用递归的方式来得到每块骨骼在世界坐标系下的位置,详细关于这些变换的原理,还望从网上找找资料看。

下面这个脚本代码来自官方手册,这里做一下解析,明白了这个代码,以后使用蒙皮网格,操作骨骼权重就不成问题了:

using UnityEngine;
using System.Collections;
public class UseMeshBoneWeight : MonoBehaviour {
             public Texture2D tex2D;
void Start() {
  gameObject.AddComponent<Animation>();
  gameObject.AddComponent<SkinnedMeshRenderer>();
  SkinnedMeshRenderer renderer = GetComponent<SkinnedMeshRenderer>();
  Mesh mesh = new Mesh();
  mesh.vertices = new Vector3[] {new Vector3(-1, 0, 0), new Vector3(1, 0, 0), new Vector3(-1, 5, 0), new Vector3(1, 5, 0)};//该平面在xy所在的平面
  mesh.uv = new Vector2[] {new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1)};//纹理坐标的左下角为(0,0)
  mesh.triangles = new int[] {0, 1, 2, 1, 3, 2};//右手螺旋,判断面的朝向
  mesh.RecalculateNormals();//重新计算法向量,
  renderer.material = new Material(Shader.Find(" Diffuse"));
  BoneWeight[] weights = new BoneWeight[4];
//这里只用到了2块骨骼,也就是说网格的所有顶点最多受2块骨骼的影响
  weights[0].boneIndex0 = 0;//顶点0 使用的骨骼变换索引为0  可见每个顶点只受到一块骨骼的影响
//所以 当这块影响它的骨骼 的变换发生变化,该顶点将受到影响,这是只有一块骨骼,所以,骨骼变换到
//什么地方,该顶点就从原来的位置×(骨骼变换所使用的矩阵)=现在的位置
  weights[0].weight0 = 1;//权重为1 即完全使用骨骼变换 不需按比例缩放变换
  weights[1].boneIndex0 = 0;
  weights[1].weight0 = 1;
  weights[2].boneIndex0 = 1;
  weights[2].weight0 = 1;
  weights[3].boneIndex0 = 1;
  weights[3].weight0 = 1;
  mesh.boneWeights = weights;
  Transform[] bones = new Transform[2];//这里的变换就是上面的变换索引指向的地方
  Matrix4x4[] bindPoses = new Matrix4x4[2];
  bones[0] = new GameObject("Lower").transform;
  bones[0].parent = transform;
  bones[0].localRotation = Quaternion.identity;
  bones[0].localPosition = Vector3.zero;
  bindPoses[0] = bones[0].worldToLocalMatrix * transform.localToWorldMatrix;
  bones[1] = new GameObject("Upper").transform;
  bones[1].parent = transform;
  bones[1].localRotation = Quaternion.identity;
  bones[1].localPosition = new Vector3(0, 5, 0);
  bindPoses[1] = bones[1].worldToLocalMatrix * transform.localToWorldMatrix;
  mesh.bindposes = bindPoses;//绑定姿势数组是BoneWeight指定的索引的变换矩阵
  renderer.bones = bones;//这个用来渲染蒙皮网格的Bone用 当骨骼移动的时候 受该骨骼影响的顶点就会应用bindPoses中设定的变换矩阵,这个变换矩阵会和顶点原来的变换位置做乘积
  renderer.sharedMesh = mesh;
                        renderer.material.SetTexture("_MainTex", tex2D);
  AnimationCurve curve = new AnimationCurve();
  curve.keys = new Keyframe[] {new Keyframe(0, 0, 0, 0), new Keyframe(1, 3, 0, 0), new Keyframe(2, 0.0F, 0, 0)};//Keyframe的4个参数为,时间点,该时间点位置的曲线
                        //值 进切线 出切线
  AnimationClip clip = new AnimationClip();
  clip.SetCurve("Lower", typeof(Transform), "m_LocalPosition.z", curve);
  animation.AddClip(clip, "test");
                        animation["test"].wrapMode = WrapMode.PingPong;
  animation.Play("test");
}
}

使用 新建一个GameObject 空的  将该代码附加到该GameObject上,运行 ,可以 在代码中添加材质的纹理
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-23 15:46 , Processed in 0.132740 second(s), 30 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部