OpenGL10-骨骼动画原理篇(3)-Shader版本代码已经上传
视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440
接上一个例程OpenGL10-骨骼动画原理篇(2),对骨骼动画的基本原理做了介绍,接下来
要对之前做的工作做一个分析和优化,骨骼动画要做大量的数学计算,当一个模型的顶点
与骨骼的数量都很多的情况下,会消耗大量的cpu时间,接下来要做的事情就是对程序进行
优化,从上面的计算过程,可以得出,有两个地方的计算量比较大,首先是矩阵和顶点相乘
,其次是每一帧要插值新的骨骼出来,相对定点计算来讲,骨骼的插值计算量应该算是较小
的,一个人物模型少则1000个顶点,多则几千个顶点。因此我们优化就从定点的计算开始
当然,我们有三种方案,甚至更多(我只用其中的两个)。
一:使用CPU优化
二:使用Shader(glsl)优化
三:使用cuda或者OpenCL进行优化
先来看第一种,说道cpu优化,大家可能想到两件事情,一是从算法角度出发去优化算法,
二是使用使用更好的CPU指令进行优化,没错,我们就是要这样做,矩阵相乘的算法优化的空
间可能已经不大,但是我们采用SIMD指令集和对浮点运算做优化空间还是很大的。
SIMD:
(Single Instruction Multiple Data,单指令多数据流)能够复制多个操作数,并把它们打包
在大型寄存器的一组指令集,例:3DNow!、SSE。以同步方式,在同一时间内执行同一条指令。以
浮点计算来说,基本上可以到达四倍的加速比。因此采用SIMD可以大幅度的提高性能。cup上使用SIMD
指令:
- __m128 sse_mul_ps(__m128 v, __m128 const m[])
- {
- __m128 i0 = m[];
- __m128 i1 = m[];
- __m128 i2 = m[];
- __m128 i3 = m[];
- __m128 m0 = _mm_mul_ps(v, i0);
- __m128 m1 = _mm_mul_ps(v, i1);
- __m128 m2 = _mm_mul_ps(v, i2);
- __m128 m3 = _mm_mul_ps(v, i3);
- __m128 u0 = _mm_unpacklo_ps(m0, m1);
- __m128 u1 = _mm_unpackhi_ps(m0, m1);
- __m128 a0 = _mm_add_ps(u0, u1);
- __m128 u2 = _mm_unpacklo_ps(m2, m3);
- __m128 u3 = _mm_unpackhi_ps(m2, m3);
- __m128 a1 = _mm_add_ps(u2, u3);
- __m128 f0 = _mm_movelh_ps(a0, a1);
- __m128 f1 = _mm_movehl_ps(a1, a0);
- __m128 f2 = _mm_add_ps(f0, f1);
- return f2;
- }
采用Shader优化,将矩阵与顶点的计算工作放到丁点Shader中完成,这样做以后,cpu机会完全
的解放出来,计算量可以忽略不计。然而这种方案也有些弊端,我们知道shader中,不能像cpu中编写
c++代码那种去动态的申请空间,所有的工作必须提前分配好。看下面的shader实现代码:
- //! 必须提前分配足够大的空间
- uniform mat4 boneMatrices[];
- attribute vec4 weights;
- attribute vec4 matrixIndices;
- attribute vec4 numBones;
- void main( void )
- {
- vec4 index = matrixIndices;
- vec4 weight = weights;
- vec4 position = vec4( 0.0, 0.0, 0.0, 0.0 );
- for( float i = 0.0; i < numBones.x; i += 1.0 )
- {
- position = position + weight.x * (boneMatrices[int(index.x)] * gl_Vertex);
- index = index.yzwx;
- weight = weight.yzwx;
- }
- gl_Position = gl_ModelViewProjectionMatrix * position;
- }
这里不再针对shader做特别介绍,后面将补冲shader相关的例程
将矩阵数据传递给shader
- //! 使用shader计算顶点的位置
- glUseProgramObjectARB( _programObj );
- glUniformMatrix4fvARB( _boneMatrices_0, , false, frame._bone[].data());
- glUniformMatrix4fvARB( _boneMatrices_1, , false, frame._bone[].data());
将每一个定点的权重,矩阵的索引,以及矩阵的个数给shader:
- //! 传递权重
- fWeights[] = g_quadVertices[i * + x].weights[];
- fWeights[] = g_quadVertices[i * + x].weights[];
- glVertexAttrib4fvARB(_weights, fWeights );
- //! 传递索引
- fMatrixIndices[] = g_quadVertices[i * + x].matrixIndices[];
- fMatrixIndices[] = g_quadVertices[i * + x].matrixIndices[];
- glVertexAttrib4fvARB(_matrixIndices, fMatrixIndices );
- //! 传递数量
- fNumBones[] = g_quadVertices[i * + x].numBones;
- glVertexAttrib4fvARB(_numBones, fNumBones );
虽然有这样的缺点,但我们是可以避免的,采用的方式就是:根据动画的骨骼的数量,权重的数量去动态的
产生shader代码然后进行编译执行,这是一个解决方案,当然我们还有另外一个解决方式,就是首先预先分配
一些方案,例如当骨头数量小于32个的时候,我们调用一个shader,当在64一下的时候调用另外一个,在多一
点就调用128的 shader,....
第三种方案,对你的显卡有很高的要求,必须支持OpenCL或者cuda,才可以去使用他,当然OpenCL或者
cuda可以直接的访问OpenGL的数据,效率上来说与shader相当(我还没有进行这样的实现),有兴趣的可以进行
尝试。
CPU优化版本代码下载(稍后上传,敬请关注)
OpenGL10-骨骼动画原理篇(3)-Shader版本代码已经上传的更多相关文章
- Unity3D 骨骼动画原理学习笔记
最近研究了一下游戏中模型的骨骼动画的原理,做一个学习笔记,便于大家共同学习探讨. ps:最近改bug改的要死要活,博客写的吭哧吭哧的~ 首先列出学习参考的前人的文章,本文较多的参考了其中的表述: 1. ...
- OpenGL10-骨骼动画原理篇(2)
接上一篇的内容,上一篇,简单的介绍了,骨骼动画的原理,给出来一个 简单的例程,这一例程将给展示一个最初级的人物动画,具备多细节内容 以人走路为例子,当人走路的从一个站立开始,到迈出一步,这个过程是 一 ...
- OpenGL10-骨骼动画原理篇(1)
视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440 本例程展示如何建立骨骼动画,有些人叫蒙皮动画 定义如下: 当前 ...
- 跟bWAPP学WEB安全(PHP代码)--终结篇:文件目录遍历、文件上传、SSRF、CSRF、XXE、文件包含
前言 过年过的很不顺,家里领导和我本人接连生病,年前腊月29才都治好出院,大年初六家里的拉布拉多爱犬又因为细小医治无效离开了,没能过年回家,花了好多钱,狗狗还离世了.所以也就没什么心思更新博客.今天初 ...
- UEditor编辑器两个版本任意文件上传漏洞分析
0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...
- [转]UEditor编辑器两个版本任意文件上传漏洞分析
0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...
- [原创] linux 下上传 datapoint数据到yeelink 【golang版本】同时上传2个数据点
/* Create by sndnvaps<sndnvaps@gmail.com> * data: 2015-04-12* upload 2 datapoint to yeelink.ne ...
- 分布式版本控制系统Git-----2.上传至远程仓库之基础版
好,之前已经将文档下载下来了,但是我感觉还是将自己之前截的图放出来比较好,自己整理的,但是总不能放桌面上,时间久了也会忘得,索性放到博客上吧,也便于其他人查看,简直是百利而无一害啊.哈哈.来吧. 注意 ...
- JDFS:一款分布式文件管理实用程序第一篇(线程池、epoll、上传、下载)
一 前言 截止目前,笔者在博客园上面已经发表了3篇关于网络下载的文章,这三篇博客实现了基于socket的http多线程远程断点下载实用程序.笔者打算在此基础上开发出一款分布式文件管理实用程序,截止目前 ...
随机推荐
- js基础学习笔记(四)
4.1 什么是数组 我们知道变量用来存储数据,一个变量只能存储一个内容,存储多个值时,就需要用到数组. 数组是一个值的集合,每个值都有一个索引号,从0开始,每个索引都有一个相应的值,根据需要添加更多数 ...
- 笔记:CSS常用中文字体英文名称对照表
* 分类排序:中文名+英文名+Unicode+Unicode 2 Windows平台新细明体 PMingLiU \65B0\7EC6\660E\4F53 新细明体细明体 MingLiU \7EC6\6 ...
- Node开发文件上传系统及向七牛云存储和亚马逊AWS S3的文件上传
背景起,有奏乐: 有伟人曰:学习技能的最好途径莫过于理论与实践相结合. 初学Node这货时,每每读教程必会Fall asleep. 当真要开发系统时,顿觉精神百倍,即便踩坑无数也不失斗志. 因为同团队 ...
- 最大连续子序列 -- hdu -- 1231
http://acm.hdu.edu.cn/showproblem.php?pid=1231 最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Mem ...
- Linux内存子系统及常用调优参数
1>内存子系统 1>组件: slab allocator buddy system kswapd pdflush 2>虚拟化环境: PA:进程地址: HA:虚拟机地址: ...
- 老码农冒死揭开行业黑幕:如何编写无法维护的代码[ZZ]
下面是一篇有意思的"代码大全",可谓 逆软件工程. 老码农冒死揭开行业黑幕:如何编写无法维护的代码 原文如下 让自己稳拿铁饭碗 ;-) – Roedy Green(翻译版略有删节) ...
- subprocess.Popen 运行windows命令出现“句柄无效”报错的解决方法
在框架开发中遇到 subprocess执行多了,就会好句柄无效的问题,终于找到解决方案:如下,修改subprocess中的一点代码就好,也不知道这是不是Python 的bug因为,Python27时没 ...
- hdu 4325 Flowers(区间离散化)
http://acm.hdu.edu.cn/showproblem.php?pid=4325 Flowers Time Limit: 4000/2000 MS (Java/Others) Mem ...
- 四两拨千斤式的攻击!如何应对Memcache服务器漏洞所带来的DDoS攻击?
本文由 网易云发布. 近日,媒体曝光Memcache服务器一个漏洞,犯罪分子可利用Memcache服务器通过非常少的计算资源发动超大规模的DDoS攻击.该漏洞是Memcache开发人员对UDP协议支 ...
- Elasticsearch入门 + 基础概念学习
原文地址:https://www.cnblogs.com/shoufeng/p/9887327.html 目录 1 Elasticsearch概述 1.1 Elasticsearch是什么 1.2 E ...