【计算机动画】蒙皮笔记

最近刚开始接触计算机动画,一片空白,尝试做了一下3D蒙皮,发现数学真是差得难以想象,矩阵的什么的全部忘记了,真是接下来该恶补一下基础了……

在这里把遇到的几个问题记录一下。

主要参考书目:《计算机动画算法与技术》《3D游戏》(英国人写的书已经绝版了)《3D游戏引擎设计——实时计算机图形学应用方法》

关节就是一个变换矩阵,在层次储存中,一般会从根节点开始一层层的储存关节矩阵:

所以每个关节储存的矩阵都是建立根关节之上的。

以3个关节为例,转换如下:

—(T0世界矩阵)—>Link0—(T1相对Link0的Link1转换,相对旋转R0)—>Link1—(T1.1相对Link1的Link1.1转换,相对旋转R1)—>Link1.1

另外每个关节的变换无非就是旋转加平移。

故,设有一在Link1.1的坐标中有顶点V,那么将其转换到世界坐标V‘就是:

V‘ = T0*T1*R1*T1.1*R1*V(这里使用列向量)

这个其实就是将局部坐标中的顶点通过这一系列的矩阵变换到世界坐标中。

在蒙皮顶点混合的时候由于我写的程序还是相当蛋疼的,我为了方便导入把一个模型拆成了3个模型,然后把三个模型一一变换到世界空间,这样免去从模型空间到骨骼空间的计算,但是在混合的时候需要根据骨骼来装换顶点到对应的骨骼空间,这些东西都在shader中计算完成。

#version 410 core
layout (location = 2) in vec4 a_position;
layout (location = 3) in vec4 a_weight;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 b1_matrix;
uniform mat4 b2_matrix;
uniform mat4 b3_matrix;
uniform int bone;

//骨骼长度
float bone_len = 47.2441f;

void main()
{
    vec4 new_a_position = a_position;
    vec4 new_a_position1 = a_position;
    //向上偏移的顶点
    new_a_position.y += bone_len;
    //向下偏移的顶点
    new_a_position1.y -= bone_len;

    //对不同的骨骼做不同的变换
    switch(bone)
    {
        case 1:
            gl_Position = proj_matrix*mv_matrix*(a_weight.x*b1_matrix*a_position+a_weight.y*b2_matrix*new_a_position1);
            break;
        case 2:
            gl_Position = proj_matrix*mv_matrix*(a_weight.x*b1_matrix*new_a_position+a_weight.y*b2_matrix*a_position+a_weight.z*b3_matrix*new_a_position1);
            break;
        case 3:
            gl_Position = proj_matrix*mv_matrix*(a_weight.y*b2_matrix*new_a_position+a_weight.z*b3_matrix*a_position);
            break;
        default:

            break;
    }

}

然后是截图:

混合顶点后

时间: 2024-10-16 22:51:08

【计算机动画】蒙皮笔记的相关文章

【计算机动画】蒙皮实验

最近学习计算机动画,看书千万遍都不如动手做一遍,实现了一下完整的人物蒙皮,遇到一些问题,现在把完整的实现过程记一下. 理论在前一篇已经讲完了,前面也实现了基本的关节动画,现在要实现的是,使用3Dmax建立一个完整的模型,然后使用它来进行蒙皮. 我的基础工具写的不是很完善,为了不分心去写其他的东西,就用了一些很可笑的数据储存方式和各种硬编码,见怪不怪,以后空了去整理. 我定义了一个结构体叫做Boxman,里面存放的东西包括: 关节树 关节旋转矩阵 mesh引用 存放各个关节到世界变换的矩阵 硬编码

《The CG Tutorial》阅读笔记——动画 Animation

这段时间阅读了英文版的NVidia官方的<The CG Tutorial>,通过它来学习基本的图形学知识和着色器编程. 在此做一个阅读记录. 动画 Animation 一.基于时间的运动 Movement in Time 实现动画渲染,需要应用程序对时间进行监测,并将它作为一个全局变量传递给着色器. 尽量在GPU上使用顶点着色器执行动画计算是一种高效的动画实现方式,它能够释放CPU,让CPU处理更多的复杂计算,比如碰撞检测,人工智能与游戏玩法. 二.一个做脉冲运动的对象 A Pulsating

基本实现蒙皮模拟

今天把蒙皮模拟算法实现了. 具体方法是加载此前算出的权重矩阵,每个内部点都是表面点的加权平均. 于是求解的时候唯一的未知数就是参数p了. 这次牛顿法能够模拟,但是同之前不带权重的模拟算法一样,模拟过程中无法收敛到全局极值点. 出问题的是这根棒. 控制这根棒的参数有两个,一个是弯曲大小,另一个是弯曲方向. 当强制令弯曲方向不起作用是,能够正常模拟,结果如上图. 当让弯曲方向参数起作用时,结果如下,模型不弯曲. 检查原因,发现牛顿法模拟的过程中,首步的梯度.Hessian.以及求出的参数增量如下:

【Unity Shaders】学习笔记——SurfaceShader(七)法线贴图

[Unity Shaders]学习笔记——SurfaceShader(七)法线贴图 转载请注明出处:http://www.cnblogs.com/-867259206/p/5627565.html 写作本系列文章时使用的是Unity5.3. 写代码之前: 当然啦,如果Unity都没安装的话肯定不会来学Unity Shaders吧? 阅读本系列文章之前你需要有一些编程的概念. 在VS里面,Unity Shaders是没有语法高亮显示和智能提示的,VS党可以参考一下这篇文章使代码高亮显示,也可以下载

Unity3D 骨骼动画原理学习笔记

最近研究了一下游戏中模型的骨骼动画的原理,做一个学习笔记,便于大家共同学习探讨. ps:最近改bug改的要死要活,博客写的吭哧吭哧的~ 首先列出学习参考的前人的文章,本文较多的参考了其中的表述: 1.骨骼动画详解 :http://blog.csdn.net/ccx1234/article/details/6641944,不过这篇文章的原文已经被csdn封了:D,可以看看对应的转载的文章也行 2.OpenGL10-骨骼动画原理篇:http://www.cnblogs.com/zhanglitong

【安全牛学习笔记】

弱点扫描 ╋━━━━━━━━━━━━━━━━━━━━╋ ┃发现弱点                                ┃ ┃发现漏洞                                ┃ ┃  基于端口五福扫描结果版本信息(速度慢)┃ ┃  搜索已公开的漏洞数据库(数量大)      ┃ ┃  使用弱点扫描器实现漏洞管理            ┃ ╋━━━━━━━━━━━━━━━━━━━━╋ [email protected]:~# searchsploit Usage:

51CTO持续更新《通哥的运维笔记》

<通哥的运维笔记>将持续在51CTO网站更新,希望大家多多关注.互相学习,后期,我将会退出<通哥的运维笔记>系列视频教程,希望带给大家最大的收获,帮助大家更好的学习.进步.<通哥的运维笔记>主要从linux系统管理.虚拟化.cloudstack云平台以及网络管理之CCNA.CCNP.CCIE,等等方面深入讲解.

WPF笔记整理 - Bitmap和BitmapImage

项目中有图片处理的逻辑,因此要用到Bitmap.而WPF加载的一般都是BitmapImage.这里就需要将BitmapImage转成Bitmap 1. 图片的路径要用这样的,假设图片在project下的Images目录,文件名XXImage.png. pack://application:,,,/xxx;component/Images/XXImage.png 2. 代码: Bitmap bmp = null; var image = new BitmapImage(new Uri(this.X

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中